mirror of
https://github.com/Combodo/iTop.git
synced 2026-03-06 17:44:12 +01:00
Compare commits
147 Commits
3.0.1-desi
...
2.7.7
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f70f95c119 | ||
|
|
53c50cf6fc | ||
|
|
f19d1472c5 | ||
|
|
eef00502cd | ||
|
|
0b1caac195 | ||
|
|
e900a44d47 | ||
|
|
a3de9fa898 | ||
|
|
8b0154cc62 | ||
|
|
1a225bf55b | ||
|
|
24d19cd8d6 | ||
|
|
c25a4a7346 | ||
|
|
20fb7b241f | ||
|
|
a0553e1195 | ||
|
|
f40141072a | ||
|
|
c759856a61 | ||
|
|
237b181eec | ||
|
|
48957fd2f0 | ||
|
|
8a99c37200 | ||
|
|
d388c3fd3d | ||
|
|
1b8e48539d | ||
|
|
104beff158 | ||
|
|
4712569a36 | ||
|
|
2392f4a902 | ||
|
|
a0f28a9098 | ||
|
|
6df622e8ed | ||
|
|
54eb9d081b | ||
|
|
9f60f27636 | ||
|
|
ba59643f52 | ||
|
|
01c02a75a8 | ||
|
|
f5b3e5f341 | ||
|
|
9b825cb529 | ||
|
|
3f326f0913 | ||
|
|
ec86bd246a | ||
|
|
aa90d5b6ab | ||
|
|
53d2129bd1 | ||
|
|
00e8c11ec2 | ||
|
|
617b6b991f | ||
|
|
b3ea1050eb | ||
|
|
ca98066d68 | ||
|
|
352f7c8675 | ||
|
|
df5d514c28 | ||
|
|
16663797b2 | ||
|
|
4099376472 | ||
|
|
6d3118d9e9 | ||
|
|
4c585614cd | ||
|
|
9674378c56 | ||
|
|
9e314ba77b | ||
|
|
cdd7dcdc5c | ||
|
|
34bed5ec4f | ||
|
|
3ea82e37d5 | ||
|
|
596c62aec8 | ||
|
|
265415030e | ||
|
|
3d26f28f9b | ||
|
|
0abec767e3 | ||
|
|
9fd10bd73e | ||
|
|
95dafc87c0 | ||
|
|
fe1790793e | ||
|
|
ddb95dc64e | ||
|
|
f6f9ee26e1 | ||
|
|
21faa92904 | ||
|
|
622f40c06c | ||
|
|
964134cb60 | ||
|
|
72f498a63b | ||
|
|
f9a1f68295 | ||
|
|
9b67b0b9d5 | ||
|
|
f798ef1d76 | ||
|
|
754946bf62 | ||
|
|
a6580e3cd8 | ||
|
|
da6621f2ff | ||
|
|
f2d42a7e56 | ||
|
|
d01e4b4a85 | ||
|
|
f57d1f1de3 | ||
|
|
a3f122184c | ||
|
|
16fcddc249 | ||
|
|
2a9c9be36a | ||
|
|
ca3aae23a1 | ||
|
|
4dd384e418 | ||
|
|
80e7313b24 | ||
|
|
183c3c1baf | ||
|
|
160c52fe81 | ||
|
|
5f0a820b4a | ||
|
|
03ef4246bf | ||
|
|
534e7cf59d | ||
|
|
e1645f6903 | ||
|
|
61a2d200b4 | ||
|
|
3d6bbe4029 | ||
|
|
44eda676a3 | ||
|
|
eac6f07823 | ||
|
|
424e2a5745 | ||
|
|
0ef4fee0b4 | ||
|
|
1d45eff9b0 | ||
|
|
8e97279401 | ||
|
|
932ef780fd | ||
|
|
59424c3126 | ||
|
|
562dd8fc21 | ||
|
|
cf745554fb | ||
|
|
e909eac98e | ||
|
|
5e42efc3ec | ||
|
|
eb1d56f439 | ||
|
|
644e1ac4f6 | ||
|
|
4c88dbd9ac | ||
|
|
11d2e62e67 | ||
|
|
58b27a9daa | ||
|
|
caf939bf58 | ||
|
|
8c217fdac9 | ||
|
|
6b80bbeaa2 | ||
|
|
134736dce5 | ||
|
|
4b870bcf1e | ||
|
|
dd8a4a0082 | ||
|
|
c2607c4223 | ||
|
|
1fb0911710 | ||
|
|
b348e0ff27 | ||
|
|
4646a05c7a | ||
|
|
c5527c106c | ||
|
|
5eac1b8730 | ||
|
|
0de15d040f | ||
|
|
c4ae94fd4c | ||
|
|
1e8818984e | ||
|
|
a023f73509 | ||
|
|
6f0e1a7f47 | ||
|
|
0ef9bb1a47 | ||
|
|
71ceedc4bb | ||
|
|
73c3c1249f | ||
|
|
88a10dba28 | ||
|
|
001e222f67 | ||
|
|
af8bcdc242 | ||
|
|
f4c7afc148 | ||
|
|
b19c73a36e | ||
|
|
5fe0d0b94f | ||
|
|
f8d435d5f3 | ||
|
|
f15ef36fd1 | ||
|
|
64b25c4daa | ||
|
|
d0ba0d193b | ||
|
|
8e6e2432d3 | ||
|
|
83ec19dfca | ||
|
|
6e619f2c35 | ||
|
|
163ba41e8d | ||
|
|
ec143c43db | ||
|
|
cacf0004a5 | ||
|
|
cb39541e2a | ||
|
|
b9ddadeb44 | ||
|
|
11e811cc4b | ||
|
|
e422adb0d0 | ||
|
|
e02d9f3f0e | ||
|
|
e831d66b76 | ||
|
|
6fa2d47780 | ||
|
|
e691454339 |
10
.gitignore
vendored
10
.gitignore
vendored
@@ -6,12 +6,6 @@
|
||||
# maintenance mode (N°2240)
|
||||
/.maintenance
|
||||
|
||||
# listing prevention in conf directory
|
||||
/conf/**
|
||||
!/conf/.htaccess
|
||||
!/conf/index.php
|
||||
!/conf/web.config
|
||||
|
||||
# composer reserver directory, from sources, populate/update using "composer install"
|
||||
vendor/*
|
||||
test/vendor/*
|
||||
@@ -19,6 +13,7 @@ test/vendor/*
|
||||
# all conf but listing prevention
|
||||
/conf/**
|
||||
!/conf/.htaccess
|
||||
!/conf/index.php
|
||||
!/conf/web.config
|
||||
|
||||
# all datas but listing prevention
|
||||
@@ -37,6 +32,9 @@ test/vendor/*
|
||||
!/log/index.php
|
||||
!/log/web.config
|
||||
|
||||
# PHPUnit cache file
|
||||
/test/.phpunit.result.cache
|
||||
|
||||
|
||||
# Jetbrains
|
||||
/.idea/**
|
||||
|
||||
@@ -50,14 +50,24 @@ foreach ($aDeniedButStillPresent as $sDir)
|
||||
continue;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
try {
|
||||
SetupUtils::rrmdir($sDir);
|
||||
echo "OK Remove denied test dir: '$sDir'\n";
|
||||
}
|
||||
catch (\Exception $e)
|
||||
{
|
||||
catch (\Exception $e) {
|
||||
echo "\nFAILED to remove denied test dir: '$sDir'\n";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
$aAllowedAndDeniedDirs = array_merge(
|
||||
$oiTopComposer->ListAllowedTestDir(),
|
||||
$oiTopComposer->ListDeniedTestDir()
|
||||
);
|
||||
$aExistingDirs = $oiTopComposer->ListAllTestDir();
|
||||
$aMissing = array_diff($aExistingDirs, $aAllowedAndDeniedDirs);
|
||||
if (false === empty($aMissing)) {
|
||||
echo "Some new tests dirs exists !\n"
|
||||
.' They must be declared either in the allowed or denied list in '.iTopComposer::class." (see N°2651).\n"
|
||||
.' List of dirs:'."\n".var_export($aMissing, true);
|
||||
}
|
||||
@@ -111,9 +111,9 @@ Our tests are located in the `test/` directory, containing a PHPUnit config file
|
||||
* Use the present tense ("Add feature" not "Added feature")
|
||||
* Use the imperative mood ("Move cursor to..." not "Moves cursor to...")
|
||||
* Limit the first line to 72 characters or less
|
||||
* Please start the commit message with an applicable emoji code (following the [Gitmoji guide](https://gitmoji.carloscuesta.me/)).
|
||||
Beware to use the code (for example `:bug:`) and not the character (🐛) as Unicode support in git clients is very poor for now...
|
||||
Emoji examples :
|
||||
* Please start the commit message with an applicable emoji code (following the [Gitmoji guide](https://gitmoji.dev/)).
|
||||
Beware to use the code (for example `:bug:`) and not the character (🐛) as Unicode support in git clients is very poor for now...
|
||||
Emoji examples :
|
||||
* 🌐 `:globe_with_meridians:` for translations
|
||||
* 🎨 `:art:` when improving the format/structure of the code
|
||||
* ⚡️ `:zap:` when improving performance
|
||||
|
||||
@@ -1083,11 +1083,11 @@ abstract class AbstractPageUIExtension implements iPageUIExtension
|
||||
/**
|
||||
* Implement this interface to add content to any enhanced portal page
|
||||
*
|
||||
* IMPORTANT! Experimental API, may be removed at anytime, we don't recommend to use it just now!
|
||||
*
|
||||
* @api
|
||||
* @package Extensibility
|
||||
* @since 2.4.0
|
||||
*
|
||||
* @since 2.4.0 interface creation
|
||||
* @since 2.7.0 change method signatures due to Silex to Symfony migration
|
||||
*/
|
||||
interface iPortalUIExtension
|
||||
{
|
||||
@@ -1160,7 +1160,11 @@ interface iPortalUIExtension
|
||||
}
|
||||
|
||||
/**
|
||||
* IMPORTANT! Experimental API, may be removed at anytime, we don't recommend to use it just now!
|
||||
* Extend this class instead of iPortalUIExtension if you don't need to overload all methods
|
||||
*
|
||||
* @api
|
||||
* @package Extensibility
|
||||
* @since 2.4.0
|
||||
*/
|
||||
abstract class AbstractPortalUIExtension implements iPortalUIExtension
|
||||
{
|
||||
|
||||
@@ -255,7 +255,7 @@ abstract class Dashlet
|
||||
catch(OqlException $e)
|
||||
{
|
||||
$oPage->add('<div class="dashlet-content">');
|
||||
$oPage->p($e->GetUserFriendlyDescription());
|
||||
$oPage->p(utils::HtmlEntities($e->GetUserFriendlyDescription()));
|
||||
$oPage->add('</div>');
|
||||
}
|
||||
catch(Exception $e)
|
||||
|
||||
@@ -1223,7 +1223,7 @@ class DesignerComboField extends DesignerFormField
|
||||
$sChecked = $this->defaultValue ? 'checked' : '';
|
||||
$sMandatory = $this->bMandatory ? 'true' : 'false';
|
||||
$sReadOnly = $this->IsReadOnly() ? 'disabled="disabled"' : '';
|
||||
if ($this->IsSorted())
|
||||
if ($this->IsSorted() )
|
||||
{
|
||||
asort($this->aAllowedValues);
|
||||
}
|
||||
@@ -1271,18 +1271,14 @@ class DesignerComboField extends DesignerFormField
|
||||
$sHtml .= "<option value=\"\">".$this->sNullLabel."</option>";
|
||||
}
|
||||
}
|
||||
foreach($this->aAllowedValues as $sKey => $sDisplayValue)
|
||||
{
|
||||
if ($this->bMultipleSelection)
|
||||
{
|
||||
foreach ($this->aAllowedValues as $sKey => $sDisplayValue) {
|
||||
if ($this->bMultipleSelection) {
|
||||
$sSelected = in_array($sKey, $this->defaultValue) ? 'selected' : '';
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
$sSelected = ($sKey == $this->defaultValue) ? 'selected' : '';
|
||||
}
|
||||
// Quick and dirty: display the menu parents as a tree
|
||||
$sHtmlValue = str_replace(' ', ' ', htmlentities($sDisplayValue, ENT_QUOTES, 'UTF-8'));
|
||||
$sHtmlValue = str_replace(' ', ' ', $sDisplayValue);
|
||||
$sHtml .= "<option value=\"".htmlentities($sKey, ENT_QUOTES, 'UTF-8')."\" $sSelected>$sHtmlValue</option>";
|
||||
}
|
||||
$sHtml .= "</select>";
|
||||
|
||||
@@ -283,6 +283,7 @@ class utils
|
||||
*
|
||||
* @since 2.5.2 2.6.0 new 'transaction_id' filter
|
||||
* @since 2.7.0 new 'element_identifier' filter
|
||||
* @since 2.7.7, 3.0.2, 3.1.0 N°4899 - new 'url' filter
|
||||
*/
|
||||
protected static function Sanitize_Internal($value, $sSanitizationFilter)
|
||||
{
|
||||
@@ -358,6 +359,11 @@ class utils
|
||||
$retValue = preg_replace('/[^a-zA-Z0-9_]/', '', $value);
|
||||
break;
|
||||
|
||||
// For URL
|
||||
case 'url':
|
||||
$retValue = filter_var($value, FILTER_SANITIZE_URL);
|
||||
break;
|
||||
|
||||
default:
|
||||
case 'raw_data':
|
||||
$retValue = $value;
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
{
|
||||
"name": "combodo/itop",
|
||||
"description": "IT Operations Portal",
|
||||
"type": "project",
|
||||
"license": "AGPLv3",
|
||||
"license": "AGPL-3.0-or-later",
|
||||
"require": {
|
||||
"php": ">=5.6.0",
|
||||
"php": ">=7.0.8",
|
||||
"ext-ctype": "*",
|
||||
"ext-dom": "*",
|
||||
"ext-gd": "*",
|
||||
@@ -10,18 +12,23 @@
|
||||
"ext-json": "*",
|
||||
"ext-mysqli": "*",
|
||||
"ext-soap": "*",
|
||||
"combodo/tcpdf": "6.3.5",
|
||||
"nikic/php-parser": "^3.1",
|
||||
"pear/archive_tar": "1.4.14",
|
||||
"pelago/emogrifier": "2.1.0",
|
||||
"combodo/tcpdf": "~6.4.4",
|
||||
"guzzlehttp/guzzle": "^6.5.8",
|
||||
"laminas/laminas-mail": "^2.11",
|
||||
"laminas/laminas-servicemanager": "^3.5",
|
||||
"league/oauth2-google": "^3.0",
|
||||
"nikic/php-parser": "~4.13.2",
|
||||
"pear/archive_tar": "~1.4.14",
|
||||
"pelago/emogrifier": "~3.1.0",
|
||||
"scssphp/scssphp": "1.0.6",
|
||||
"swiftmailer/swiftmailer": "5.4.12",
|
||||
"swiftmailer/swiftmailer": "~6.3.0",
|
||||
"symfony/console": "~3.4.47",
|
||||
"symfony/dotenv": "~3.4.47",
|
||||
"symfony/framework-bundle": "~3.4.47",
|
||||
"symfony/polyfill-php70": "1.*",
|
||||
"symfony/twig-bundle": "~3.4.47",
|
||||
"symfony/yaml": "~3.4.47"
|
||||
"symfony/yaml": "~3.4.47",
|
||||
"thenetworg/oauth2-azure": "^2.0",
|
||||
"twig/twig": "~1.42.5"
|
||||
},
|
||||
"require-dev": {
|
||||
"symfony/stopwatch": "~3.4.47",
|
||||
@@ -37,7 +44,7 @@
|
||||
},
|
||||
"config": {
|
||||
"platform": {
|
||||
"php": "5.6.0"
|
||||
"php": "7.0.8"
|
||||
},
|
||||
"vendor-dir": "lib",
|
||||
"preferred-install": {
|
||||
@@ -52,7 +59,8 @@
|
||||
"application",
|
||||
"sources/application",
|
||||
"sources/Composer",
|
||||
"sources/Controller"
|
||||
"sources/Controller",
|
||||
"sources/Core"
|
||||
],
|
||||
"exclude-from-classmap": [
|
||||
"core/dbobjectsearch.class.php",
|
||||
|
||||
1915
composer.lock
generated
1915
composer.lock
generated
File diff suppressed because it is too large
Load Diff
@@ -179,7 +179,7 @@ class ActionEmail extends ActionNotification
|
||||
protected function FindRecipients($sRecipAttCode, $aArgs)
|
||||
{
|
||||
$sOQL = $this->Get($sRecipAttCode);
|
||||
if (strlen($sOQL) == '') return '';
|
||||
if (strlen($sOQL) === 0) return '';
|
||||
|
||||
try
|
||||
{
|
||||
|
||||
@@ -230,7 +230,7 @@ abstract class AsyncTask extends DBObject
|
||||
$this->Set('remaining_retries', $this->GetMaxRetries($iErrorCode));
|
||||
}
|
||||
|
||||
$this->Set('last_error', $sErrorMessage);
|
||||
$this->SetTrim('last_error', $sErrorMessage);
|
||||
$this->Set('last_error_code', $iErrorCode); // Note: can be ZERO !!!
|
||||
$this->Set('last_attempt', time());
|
||||
|
||||
|
||||
@@ -63,22 +63,30 @@ class CMDBChangeOp extends DBObject
|
||||
|
||||
/**
|
||||
* Describe (as a text string) the modifications corresponding to this change
|
||||
*/
|
||||
*/
|
||||
public function GetDescription()
|
||||
{
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Safety net: in case the change is not given, let's guarantee that it will
|
||||
* be set to the current ongoing change (or create a new one)
|
||||
*/
|
||||
* Safety net:
|
||||
* * if change isn't persisted yet, use the current change and persist it if needed
|
||||
* * in case the change is not given, let's guarantee that it will be set to the current ongoing change (or create a new one)
|
||||
*
|
||||
* @since 2.7.7 3.0.2 3.1.0 N°3717 do persist the current change if needed
|
||||
*/
|
||||
protected function OnInsert()
|
||||
{
|
||||
if ($this->Get('change') <= 0)
|
||||
{
|
||||
$this->Set('change', CMDBObject::GetCurrentChange());
|
||||
$iChange = $this->Get('change');
|
||||
if (($iChange <= 0) || (is_null($iChange))) {
|
||||
$oChange = CMDBObject::GetCurrentChange();
|
||||
if ($oChange->IsNew()) {
|
||||
$oChange->DBWrite();
|
||||
}
|
||||
$this->Set('change', $oChange);
|
||||
}
|
||||
|
||||
parent::OnInsert();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -114,6 +114,26 @@ abstract class CMDBObject extends DBObject
|
||||
self::$m_oCurrChange = $oChange;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sUserInfo
|
||||
* @param string $sOrigin
|
||||
* @param \DateTime $oDate
|
||||
*
|
||||
* @throws \CoreException
|
||||
*
|
||||
* @since 2.7.7 3.0.2 3.1.0 N°3717 new method to reset current change
|
||||
*/
|
||||
public static function SetCurrentChangeFromParams($sUserInfo, $sOrigin = null, $oDate = null)
|
||||
{
|
||||
static::SetTrackInfo($sUserInfo);
|
||||
static::SetTrackOrigin($sOrigin);
|
||||
static::CreateChange();
|
||||
|
||||
if (!is_null($oDate)) {
|
||||
static::$m_oCurrChange->Set("date", $oDate);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Todo: simplify the APIs and do not pass the current change as an argument anymore
|
||||
// SetTrackInfo to be invoked in very few cases (UI.php, CSV import, Data synchro)
|
||||
@@ -145,6 +165,8 @@ abstract class CMDBObject extends DBObject
|
||||
* $oMyChange->Set("userinfo", 'this is done by ... for ...');
|
||||
* $iChangeId = $oMyChange->DBInsert();
|
||||
*
|
||||
* **warning** : this will do nothing if current change already exists !
|
||||
*
|
||||
* @see SetCurrentChange to specify a CMDBObject instance instead
|
||||
*
|
||||
* @param string $sInfo
|
||||
@@ -157,6 +179,8 @@ abstract class CMDBObject extends DBObject
|
||||
/**
|
||||
* Provides information about the origin of the change
|
||||
*
|
||||
* **warning** : this will do nothing if current change already exists !
|
||||
*
|
||||
* @see SetTrackInfo
|
||||
* @see SetCurrentChange to specify a CMDBObject instance instead
|
||||
*
|
||||
@@ -167,18 +191,15 @@ abstract class CMDBObject extends DBObject
|
||||
{
|
||||
self::$m_sOrigin = $sOrigin;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the additional information (defaulting to user name)
|
||||
*/
|
||||
protected static function GetTrackInfo()
|
||||
*/
|
||||
public static function GetTrackInfo()
|
||||
{
|
||||
if (is_null(self::$m_sInfo))
|
||||
{
|
||||
if (is_null(self::$m_sInfo)) {
|
||||
return CMDBChange::GetCurrentUserName();
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
return self::$m_sInfo;
|
||||
}
|
||||
}
|
||||
@@ -201,7 +222,8 @@ abstract class CMDBObject extends DBObject
|
||||
/**
|
||||
* Set to {@link $m_oCurrChange} a standard change record (done here 99% of the time, and nearly once per page)
|
||||
*
|
||||
* The CMDBChange is persisted so that it has a key > 0, and any new CMDBChangeOp can link to it
|
||||
* @since 2.7.7 3.0.2 3.1.0 N°3717 {@see CMDBChange} **will be persisted later** in {@see \CMDBChangeOp::OnInsert} (was done previously directly here)
|
||||
* This will avoid creating in DB CMDBChange lines without any corresponding CMDBChangeOp
|
||||
*/
|
||||
protected static function CreateChange()
|
||||
{
|
||||
@@ -209,7 +231,6 @@ abstract class CMDBObject extends DBObject
|
||||
self::$m_oCurrChange->Set("date", time());
|
||||
self::$m_oCurrChange->Set("userinfo", self::GetTrackInfo());
|
||||
self::$m_oCurrChange->Set("origin", self::GetTrackOrigin());
|
||||
self::$m_oCurrChange->DBInsert();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -509,7 +509,7 @@ class Config
|
||||
),
|
||||
'email_transport' => array(
|
||||
'type' => 'string',
|
||||
'description' => 'Mean to send emails: PHPMail (uses the function mail()) or SMTP (implements the client protocol)',
|
||||
'description' => 'Mean to send emails: PHPMail (uses the function mail()), SMTP (implements the client protocol) or SMTP_OAuth (connect to the server using OAuth 2.0)',
|
||||
'default' => "PHPMail",
|
||||
'value' => "PHPMail",
|
||||
'source_of_value' => '',
|
||||
|
||||
@@ -1880,7 +1880,7 @@ abstract class DBObject implements iDisplay
|
||||
$oTargetObj = MetaModel::GetObject($sTargetClass, $toCheck, false /*must be found*/, true /*allow all data*/);
|
||||
if (is_null($oTargetObj))
|
||||
{
|
||||
return "Target object not found ($sTargetClass::$toCheck)";
|
||||
return "Target object not found (".utils::HtmlEntities($sTargetClass).".::".utils::HtmlEntities($toCheck).")";
|
||||
}
|
||||
}
|
||||
if ($oAtt->IsHierarchicalKey())
|
||||
@@ -1889,7 +1889,7 @@ abstract class DBObject implements iDisplay
|
||||
$aValues = $oAtt->GetAllowedValues(array('this' => $this));
|
||||
if (!array_key_exists($toCheck, $aValues))
|
||||
{
|
||||
return "Value not allowed [$toCheck]";
|
||||
return "Value not allowed [". utils::HtmlEntities($toCheck)."]";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1903,7 +1903,7 @@ abstract class DBObject implements iDisplay
|
||||
$oTag->SetValues(explode(' ', $toCheck));
|
||||
} catch (Exception $e)
|
||||
{
|
||||
return "Tag value '$toCheck' is not a valid tag list";
|
||||
return "Tag value [". utils::HtmlEntities($toCheck)."] is not a valid tag list";
|
||||
}
|
||||
|
||||
return true;
|
||||
@@ -1931,7 +1931,7 @@ abstract class DBObject implements iDisplay
|
||||
$oTag->SetValues($aValues);
|
||||
} catch (Exception $e)
|
||||
{
|
||||
return "Set value '$toCheck' is not a valid set";
|
||||
return "Set value[". utils::HtmlEntities($toCheck)."] is not a valid set";
|
||||
}
|
||||
|
||||
return true;
|
||||
@@ -1951,7 +1951,7 @@ abstract class DBObject implements iDisplay
|
||||
{
|
||||
if (!array_key_exists($toCheck, $aValues))
|
||||
{
|
||||
return "Value not allowed [$toCheck]";
|
||||
return "Value not allowed [". utils::HtmlEntities($toCheck)."]";
|
||||
}
|
||||
}
|
||||
if (!is_null($iMaxSize = $oAtt->GetMaxSize()))
|
||||
@@ -1964,7 +1964,7 @@ abstract class DBObject implements iDisplay
|
||||
}
|
||||
if (!$oAtt->CheckFormat($toCheck))
|
||||
{
|
||||
return "Wrong format [$toCheck]";
|
||||
return "Wrong format [". utils::HtmlEntities($toCheck)."]";
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -1977,9 +1977,9 @@ abstract class DBObject implements iDisplay
|
||||
/**
|
||||
* check attributes together
|
||||
*
|
||||
* @overwritable-hook You can extend this method in order to provide your own logic.
|
||||
*
|
||||
* @return bool
|
||||
* @overwritable-hook You can extend this method in order to provide your own logic.
|
||||
*
|
||||
* @return true|string true if successful, the error description otherwise
|
||||
*/
|
||||
public function CheckConsistency()
|
||||
{
|
||||
|
||||
@@ -1203,8 +1203,10 @@ class DisplayableGraph extends SimpleGraph
|
||||
* @param float $xMax Right coordinate of the bounding box to display the graph
|
||||
* @param float $yMin Top coordinate of the bounding box to display the graph
|
||||
* @param float $yMax Bottom coordinate of the bounding box to display the graph
|
||||
*
|
||||
* @since 2.7.7 3.0.2 3.1.0 N°4985 $sComments param is no longer optional
|
||||
*/
|
||||
function RenderAsPDF(PDFPage $oPage, $sComments = '', $sContextKey, $xMin = -1, $xMax = -1, $yMin = -1, $yMax = -1)
|
||||
function RenderAsPDF(PDFPage $oPage, $sComments, $sContextKey, $xMin = -1, $xMax = -1, $yMin = -1, $yMax = -1)
|
||||
{
|
||||
$aContextDefs = static::GetContextDefinitions($sContextKey, false); // No need to develop the parameters
|
||||
$oPdf = $oPage->get_tcpdf();
|
||||
|
||||
@@ -24,38 +24,26 @@
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
Swift_Preferences::getInstance()->setCharset('UTF-8');
|
||||
use Combodo\iTop\Core\Email\EmailFactory;
|
||||
use Combodo\iTop\Core\Email\iEMail;
|
||||
|
||||
|
||||
define ('EMAIL_SEND_OK', 0);
|
||||
define ('EMAIL_SEND_PENDING', 1);
|
||||
define ('EMAIL_SEND_ERROR', 2);
|
||||
|
||||
class EMail
|
||||
class EMail implements iEMail
|
||||
{
|
||||
protected $oMailer;
|
||||
|
||||
// Serialization formats
|
||||
const ORIGINAL_FORMAT = 1; // Original format, consisting in serializing the whole object, inculding the Swift Mailer's object.
|
||||
// Did not work with attachements since their binary representation cannot be stored as a valid UTF-8 string
|
||||
// Did not work with attachements since their binary representation cannot be stored as a valid UTF-8 string
|
||||
const FORMAT_V2 = 2; // New format, only the raw data are serialized (base64 encoded if needed)
|
||||
|
||||
protected static $m_oConfig = null;
|
||||
protected $m_aData; // For storing data to serialize
|
||||
|
||||
public function LoadConfig($sConfigFile = ITOP_DEFAULT_CONFIG_FILE)
|
||||
{
|
||||
if (is_null(self::$m_oConfig))
|
||||
{
|
||||
self::$m_oConfig = new Config($sConfigFile);
|
||||
}
|
||||
}
|
||||
|
||||
protected $m_oMessage;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->m_aData = array();
|
||||
$this->m_oMessage = Swift_Message::newInstance();
|
||||
$this->SetRecipientFrom(MetaModel::GetConfig()->Get('email_default_sender_address'), MetaModel::GetConfig()->Get('email_default_sender_label'));
|
||||
$this->oMailer = EmailFactory::GetMailer();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -66,485 +54,97 @@ class EMail
|
||||
*/
|
||||
public function SerializeV2()
|
||||
{
|
||||
return serialize($this->m_aData);
|
||||
return $this->oMailer->SerializeV2();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Custom de-serialization method
|
||||
*
|
||||
* @param string $sSerializedMessage The serialized representation of the message
|
||||
*
|
||||
* @return \Email
|
||||
* @throws \ArchivedObjectException
|
||||
* @throws \CoreException
|
||||
* @throws \Symfony\Component\CssSelector\Exception\SyntaxErrorException
|
||||
*/
|
||||
static public function UnSerializeV2($sSerializedMessage)
|
||||
{
|
||||
$aData = unserialize($sSerializedMessage);
|
||||
$oMessage = new Email();
|
||||
|
||||
if (array_key_exists('body', $aData))
|
||||
{
|
||||
$oMessage->SetBody($aData['body']['body'], $aData['body']['mimeType']);
|
||||
}
|
||||
if (array_key_exists('message_id', $aData))
|
||||
{
|
||||
$oMessage->SetMessageId($aData['message_id']);
|
||||
}
|
||||
if (array_key_exists('bcc', $aData))
|
||||
{
|
||||
$oMessage->SetRecipientBCC($aData['bcc']);
|
||||
}
|
||||
if (array_key_exists('cc', $aData))
|
||||
{
|
||||
$oMessage->SetRecipientCC($aData['cc']);
|
||||
}
|
||||
if (array_key_exists('from', $aData))
|
||||
{
|
||||
$oMessage->SetRecipientFrom($aData['from']['address'], $aData['from']['label']);
|
||||
}
|
||||
if (array_key_exists('reply_to', $aData))
|
||||
{
|
||||
$oMessage->SetRecipientReplyTo($aData['reply_to']);
|
||||
}
|
||||
if (array_key_exists('to', $aData))
|
||||
{
|
||||
$oMessage->SetRecipientTO($aData['to']);
|
||||
}
|
||||
if (array_key_exists('subject', $aData))
|
||||
{
|
||||
$oMessage->SetSubject($aData['subject']);
|
||||
}
|
||||
|
||||
|
||||
if (array_key_exists('headers', $aData))
|
||||
{
|
||||
foreach($aData['headers'] as $sKey => $sValue)
|
||||
{
|
||||
$oMessage->AddToHeader($sKey, $sValue);
|
||||
}
|
||||
}
|
||||
if (array_key_exists('parts', $aData))
|
||||
{
|
||||
foreach($aData['parts'] as $aPart)
|
||||
{
|
||||
$oMessage->AddPart($aPart['text'], $aPart['mimeType']);
|
||||
}
|
||||
}
|
||||
if (array_key_exists('attachments', $aData))
|
||||
{
|
||||
foreach($aData['attachments'] as $aAttachment)
|
||||
{
|
||||
$oMessage->AddAttachment(base64_decode($aAttachment['data']), $aAttachment['filename'], $aAttachment['mimeType']);
|
||||
}
|
||||
}
|
||||
return $oMessage;
|
||||
}
|
||||
|
||||
protected function SendAsynchronous(&$aIssues, $oLog = null)
|
||||
{
|
||||
try
|
||||
{
|
||||
AsyncSendEmail::AddToQueue($this, $oLog);
|
||||
}
|
||||
catch(Exception $e)
|
||||
{
|
||||
$aIssues = array($e->GetMessage());
|
||||
return EMAIL_SEND_ERROR;
|
||||
}
|
||||
$aIssues = array();
|
||||
return EMAIL_SEND_PENDING;
|
||||
}
|
||||
|
||||
protected function SendSynchronous(&$aIssues, $oLog = null)
|
||||
{
|
||||
// If the body of the message is in HTML, embed all images based on attachments
|
||||
$this->EmbedInlineImages();
|
||||
|
||||
$this->LoadConfig();
|
||||
|
||||
$sTransport = self::$m_oConfig->Get('email_transport');
|
||||
switch ($sTransport)
|
||||
{
|
||||
case 'SMTP':
|
||||
$sHost = self::$m_oConfig->Get('email_transport_smtp.host');
|
||||
$sPort = self::$m_oConfig->Get('email_transport_smtp.port');
|
||||
$sEncryption = self::$m_oConfig->Get('email_transport_smtp.encryption');
|
||||
$sUserName = self::$m_oConfig->Get('email_transport_smtp.username');
|
||||
$sPassword = self::$m_oConfig->Get('email_transport_smtp.password');
|
||||
|
||||
$oTransport = Swift_SmtpTransport::newInstance($sHost, $sPort, $sEncryption);
|
||||
if (strlen($sUserName) > 0)
|
||||
{
|
||||
$oTransport->setUsername($sUserName);
|
||||
$oTransport->setPassword($sPassword);
|
||||
}
|
||||
break;
|
||||
|
||||
case 'Null':
|
||||
$oTransport = Swift_NullTransport::newInstance();
|
||||
break;
|
||||
|
||||
case 'LogFile':
|
||||
$oTransport = Swift_LogFileTransport::newInstance();
|
||||
$oTransport->setLogFile(APPROOT.'log/mail.log');
|
||||
break;
|
||||
|
||||
case 'PHPMail':
|
||||
default:
|
||||
$oTransport = Swift_MailTransport::newInstance();
|
||||
}
|
||||
|
||||
$oMailer = Swift_Mailer::newInstance($oTransport);
|
||||
|
||||
$aFailedRecipients = array();
|
||||
$this->m_oMessage->setMaxLineLength(0);
|
||||
$oKPI = new ExecutionKPI();
|
||||
try
|
||||
{
|
||||
$iSent = $oMailer->send($this->m_oMessage, $aFailedRecipients);
|
||||
if ($iSent === 0)
|
||||
{
|
||||
// Beware: it seems that $aFailedRecipients sometimes contains the recipients that actually received the message !!!
|
||||
IssueLog::Warning('Email sending failed: Some recipients were invalid, aFailedRecipients contains: '.implode(', ', $aFailedRecipients));
|
||||
$aIssues = array('Some recipients were invalid.');
|
||||
$oKPI->ComputeStats('Email Sent', 'Error received');
|
||||
return EMAIL_SEND_ERROR;
|
||||
}
|
||||
else
|
||||
{
|
||||
$aIssues = array();
|
||||
$oKPI->ComputeStats('Email Sent', 'Succeded');
|
||||
return EMAIL_SEND_OK;
|
||||
}
|
||||
}
|
||||
catch (Exception $e)
|
||||
{
|
||||
$oKPI->ComputeStats('Email Sent', 'Error received');
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reprocess the body of the message (if it is an HTML message)
|
||||
* to replace the URL of images based on attachments by a link
|
||||
* to an embedded image (i.e. cid:....)
|
||||
*/
|
||||
protected function EmbedInlineImages()
|
||||
{
|
||||
if ($this->m_aData['body']['mimeType'] == 'text/html')
|
||||
{
|
||||
$oDOMDoc = new DOMDocument();
|
||||
$oDOMDoc->preserveWhitespace = true;
|
||||
@$oDOMDoc->loadHTML('<?xml encoding="UTF-8"?>'.$this->m_aData['body']['body']); // For loading HTML chunks where the character set is not specified
|
||||
|
||||
$oXPath = new DOMXPath($oDOMDoc);
|
||||
$sXPath = '//img[@'.InlineImage::DOM_ATTR_ID.']';
|
||||
$oImagesList = $oXPath->query($sXPath);
|
||||
|
||||
if ($oImagesList->length != 0)
|
||||
{
|
||||
foreach($oImagesList as $oImg)
|
||||
{
|
||||
$iAttId = $oImg->getAttribute(InlineImage::DOM_ATTR_ID);
|
||||
$oAttachment = MetaModel::GetObject('InlineImage', $iAttId, false, true /* Allow All Data */);
|
||||
if ($oAttachment)
|
||||
{
|
||||
$sImageSecret = $oImg->getAttribute('data-img-secret');
|
||||
$sAttachmentSecret = $oAttachment->Get('secret');
|
||||
if ($sImageSecret !== $sAttachmentSecret)
|
||||
{
|
||||
// @see N°1921
|
||||
// If copying from another iTop we could get an IMG pointing to an InlineImage with wrong secret
|
||||
continue;
|
||||
}
|
||||
|
||||
$oDoc = $oAttachment->Get('contents');
|
||||
$oSwiftImage = new Swift_Image($oDoc->GetData(), $oDoc->GetFileName(), $oDoc->GetMimeType());
|
||||
$sCid = $this->m_oMessage->embed($oSwiftImage);
|
||||
$oImg->setAttribute('src', $sCid);
|
||||
}
|
||||
}
|
||||
}
|
||||
$sHtmlBody = $oDOMDoc->saveHTML();
|
||||
$this->m_oMessage->setBody($sHtmlBody, 'text/html', 'UTF-8');
|
||||
}
|
||||
return EmailFactory::GetMailer()::UnSerializeV2($sSerializedMessage);
|
||||
}
|
||||
|
||||
public function Send(&$aIssues, $bForceSynchronous = false, $oLog = null)
|
||||
{
|
||||
//select a default sender if none is provided.
|
||||
if(empty($this->m_aData['from']['address']) && !empty($this->m_aData['to'])){
|
||||
$this->SetRecipientFrom($this->m_aData['to']);
|
||||
}
|
||||
|
||||
if ($bForceSynchronous)
|
||||
{
|
||||
return $this->SendSynchronous($aIssues, $oLog);
|
||||
}
|
||||
else
|
||||
{
|
||||
$bConfigASYNC = MetaModel::GetConfig()->Get('email_asynchronous');
|
||||
if ($bConfigASYNC)
|
||||
{
|
||||
return $this->SendAsynchronous($aIssues, $oLog);
|
||||
}
|
||||
else
|
||||
{
|
||||
return $this->SendSynchronous($aIssues, $oLog);
|
||||
}
|
||||
}
|
||||
return $this->oMailer->Send($aIssues, $bForceSynchronous, $oLog);
|
||||
}
|
||||
|
||||
public function AddToHeader($sKey, $sValue)
|
||||
{
|
||||
if (!array_key_exists('headers', $this->m_aData))
|
||||
{
|
||||
$this->m_aData['headers'] = array();
|
||||
}
|
||||
$this->m_aData['headers'][$sKey] = $sValue;
|
||||
|
||||
if (strlen($sValue) > 0)
|
||||
{
|
||||
$oHeaders = $this->m_oMessage->getHeaders();
|
||||
switch(strtolower($sKey))
|
||||
{
|
||||
case 'return-path':
|
||||
$this->m_oMessage->setReturnPath($sValue);
|
||||
break;
|
||||
|
||||
default:
|
||||
$oHeaders->addTextHeader($sKey, $sValue);
|
||||
}
|
||||
}
|
||||
$this->oMailer->AddToHeader($sKey, $sValue);
|
||||
}
|
||||
|
||||
public function SetMessageId($sId)
|
||||
{
|
||||
$this->m_aData['message_id'] = $sId;
|
||||
|
||||
// Note: Swift will add the angle brackets for you
|
||||
// so let's remove the angle brackets if present, for historical reasons
|
||||
$sId = str_replace(array('<', '>'), '', $sId);
|
||||
|
||||
$oMsgId = $this->m_oMessage->getHeaders()->get('Message-ID');
|
||||
$oMsgId->SetId($sId);
|
||||
$this->oMailer->SetMessageId($sId);
|
||||
}
|
||||
|
||||
public function SetReferences($sReferences)
|
||||
{
|
||||
$this->AddToHeader('References', $sReferences);
|
||||
$this->oMailer->SetReferences($sReferences);
|
||||
}
|
||||
|
||||
public function SetBody($sBody, $sMimeType = 'text/html', $sCustomStyles = null)
|
||||
{
|
||||
if (($sMimeType === 'text/html') && ($sCustomStyles !== null))
|
||||
{
|
||||
$emogrifier = new \Pelago\Emogrifier($sBody, $sCustomStyles);
|
||||
$sBody = $emogrifier->emogrify(); // Adds html/body tags if not already present
|
||||
}
|
||||
$this->m_aData['body'] = array('body' => $sBody, 'mimeType' => $sMimeType);
|
||||
$this->m_oMessage->setBody($sBody, $sMimeType);
|
||||
$this->oMailer->SetBody($sBody, $sMimeType, $sCustomStyles);
|
||||
}
|
||||
|
||||
public function AddPart($sText, $sMimeType = 'text/html')
|
||||
{
|
||||
if (!array_key_exists('parts', $this->m_aData))
|
||||
{
|
||||
$this->m_aData['parts'] = array();
|
||||
}
|
||||
$this->m_aData['parts'][] = array('text' => $sText, 'mimeType' => $sMimeType);
|
||||
$this->m_oMessage->addPart($sText, $sMimeType);
|
||||
$this->oMailer->AddPart($sText, $sMimeType);
|
||||
}
|
||||
|
||||
public function AddAttachment($data, $sFileName, $sMimeType)
|
||||
{
|
||||
if (!array_key_exists('attachments', $this->m_aData))
|
||||
{
|
||||
$this->m_aData['attachments'] = array();
|
||||
}
|
||||
$this->m_aData['attachments'][] = array('data' => base64_encode($data), 'filename' => $sFileName, 'mimeType' => $sMimeType);
|
||||
$this->m_oMessage->attach(Swift_Attachment::newInstance($data, $sFileName, $sMimeType));
|
||||
$this->oMailer->AddAttachment($data, $sFileName, $sMimeType);
|
||||
}
|
||||
|
||||
public function SetSubject($sSubject)
|
||||
{
|
||||
$this->m_aData['subject'] = $sSubject;
|
||||
$this->m_oMessage->setSubject($sSubject);
|
||||
$this->oMailer->SetSubject($sSubject);
|
||||
}
|
||||
|
||||
public function GetSubject()
|
||||
{
|
||||
return $this->m_oMessage->getSubject();
|
||||
return $this->oMailer->GetSubject();
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper to transform and sanitize addresses
|
||||
* - get rid of empty addresses
|
||||
*/
|
||||
protected function AddressStringToArray($sAddressCSVList)
|
||||
{
|
||||
$aAddresses = array();
|
||||
foreach(explode(',', $sAddressCSVList) as $sAddress)
|
||||
{
|
||||
$sAddress = trim($sAddress);
|
||||
if (strlen($sAddress) > 0)
|
||||
{
|
||||
$aAddresses[] = $sAddress;
|
||||
}
|
||||
}
|
||||
return $aAddresses;
|
||||
}
|
||||
|
||||
public function SetRecipientTO($sAddress)
|
||||
{
|
||||
$this->m_aData['to'] = $sAddress;
|
||||
if (!empty($sAddress))
|
||||
{
|
||||
$aAddresses = $this->AddressStringToArray($sAddress);
|
||||
$this->m_oMessage->setTo($aAddresses);
|
||||
}
|
||||
$this->oMailer->SetRecipientTO($sAddress);
|
||||
}
|
||||
|
||||
public function GetRecipientTO($bAsString = false)
|
||||
{
|
||||
$aRes = $this->m_oMessage->getTo();
|
||||
if ($aRes === null)
|
||||
{
|
||||
// There is no "To" header field
|
||||
$aRes = array();
|
||||
}
|
||||
if ($bAsString)
|
||||
{
|
||||
$aStrings = array();
|
||||
foreach ($aRes as $sEmail => $sName)
|
||||
{
|
||||
if (is_null($sName))
|
||||
{
|
||||
$aStrings[] = $sEmail;
|
||||
}
|
||||
else
|
||||
{
|
||||
$sName = str_replace(array('<', '>'), '', $sName);
|
||||
$aStrings[] = "$sName <$sEmail>";
|
||||
}
|
||||
}
|
||||
return implode(', ', $aStrings);
|
||||
}
|
||||
else
|
||||
{
|
||||
return $aRes;
|
||||
}
|
||||
return $this->oMailer->GetRecipientTO($bAsString);
|
||||
}
|
||||
|
||||
public function SetRecipientCC($sAddress)
|
||||
{
|
||||
$this->m_aData['cc'] = $sAddress;
|
||||
if (!empty($sAddress))
|
||||
{
|
||||
$aAddresses = $this->AddressStringToArray($sAddress);
|
||||
$this->m_oMessage->setCc($aAddresses);
|
||||
}
|
||||
$this->oMailer->SetRecipientCC($sAddress);
|
||||
}
|
||||
|
||||
public function SetRecipientBCC($sAddress)
|
||||
{
|
||||
$this->m_aData['bcc'] = $sAddress;
|
||||
if (!empty($sAddress))
|
||||
{
|
||||
$aAddresses = $this->AddressStringToArray($sAddress);
|
||||
$this->m_oMessage->setBcc($aAddresses);
|
||||
}
|
||||
$this->oMailer->SetRecipientBCC($sAddress);
|
||||
}
|
||||
|
||||
public function SetRecipientFrom($sAddress, $sLabel = '')
|
||||
{
|
||||
$this->m_aData['from'] = array('address' => $sAddress, 'label' => $sLabel);
|
||||
if ($sLabel != '')
|
||||
{
|
||||
$this->m_oMessage->setFrom(array($sAddress => $sLabel));
|
||||
}
|
||||
else if (!empty($sAddress))
|
||||
{
|
||||
$this->m_oMessage->setFrom($sAddress);
|
||||
}
|
||||
$this->oMailer->SetRecipientFrom($sAddress, $sLabel);
|
||||
}
|
||||
|
||||
public function SetRecipientReplyTo($sAddress)
|
||||
{
|
||||
$this->m_aData['reply_to'] = $sAddress;
|
||||
if (!empty($sAddress))
|
||||
{
|
||||
$this->m_oMessage->setReplyTo($sAddress);
|
||||
}
|
||||
$this->oMailer->SetRecipientReplyTo($sAddress);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**
|
||||
* Extension to SwiftMailer: "debug" transport that pretends messages have been sent,
|
||||
* but just log them to a file.
|
||||
*
|
||||
* @package Swift
|
||||
* @author Denis Flaven
|
||||
*/
|
||||
class Swift_Transport_LogFileTransport extends Swift_Transport_NullTransport
|
||||
{
|
||||
protected $sLogFile;
|
||||
|
||||
/**
|
||||
* Sends the given message.
|
||||
*
|
||||
* @param Swift_Mime_Message $message
|
||||
* @param string[] $failedRecipients An array of failures by-reference
|
||||
*
|
||||
* @return int The number of sent emails
|
||||
*/
|
||||
public function send(Swift_Mime_Message $message, &$failedRecipients = null)
|
||||
{
|
||||
$hFile = @fopen($this->sLogFile, 'a');
|
||||
if ($hFile)
|
||||
{
|
||||
$sTxt = "================== ".date('Y-m-d H:i:s')." ==================\n";
|
||||
$sTxt .= $message->toString()."\n";
|
||||
|
||||
@fwrite($hFile, $sTxt);
|
||||
@fclose($hFile);
|
||||
}
|
||||
|
||||
return parent::send($message, $failedRecipients);
|
||||
}
|
||||
|
||||
public function setLogFile($sFilename)
|
||||
{
|
||||
$this->sLogFile = $sFilename;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Pretends messages have been sent, but just log them to a file.
|
||||
*
|
||||
* @package Swift
|
||||
* @author Denis Flaven
|
||||
*/
|
||||
class Swift_LogFileTransport extends Swift_Transport_LogFileTransport
|
||||
{
|
||||
/**
|
||||
* Create a new LogFileTransport.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
call_user_func_array(
|
||||
array($this, 'Swift_Transport_LogFileTransport::__construct'),
|
||||
Swift_DependencyContainer::getInstance()
|
||||
->createDependenciesFor('transport.null')
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new LogFileTransport instance.
|
||||
*
|
||||
* @return Swift_LogFileTransport
|
||||
*/
|
||||
public static function newInstance()
|
||||
{
|
||||
return new self();
|
||||
}
|
||||
}
|
||||
@@ -116,6 +116,18 @@ abstract class DOMSanitizer extends HTMLSanitizer
|
||||
{
|
||||
/** @var DOMDocument */
|
||||
protected $oDoc;
|
||||
/**
|
||||
* @var string Class to use for InlineImage static method calls
|
||||
* @used-by \Combodo\iTop\Test\UnitTest\Core\Sanitizer\HTMLDOMSanitizerTest::testDoSanitizeCallInlineImageProcessImageTag
|
||||
*/
|
||||
protected $sInlineImageClassName;
|
||||
|
||||
public function __construct($sInlineImageClassName = InlineImage::class)
|
||||
{
|
||||
parent::__construct();
|
||||
|
||||
$this->sInlineImageClassName = $sInlineImageClassName;
|
||||
}
|
||||
|
||||
abstract public function GetTagsWhiteList();
|
||||
|
||||
@@ -211,7 +223,7 @@ abstract class DOMSanitizer extends HTMLSanitizer
|
||||
// Recurse
|
||||
$this->CleanNode($oNode);
|
||||
if (($oNode instanceof DOMElement) && (strtolower($oNode->tagName) == 'img')) {
|
||||
InlineImage::ProcessImageTag($oNode);
|
||||
$this->sInlineImageClassName::ProcessImageTag($oNode);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -347,6 +359,30 @@ class HTMLDOMSanitizer extends DOMSanitizer
|
||||
'white-space',
|
||||
);
|
||||
|
||||
public function __construct($sInlineImageClassName = InlineImage::class)
|
||||
{
|
||||
parent::__construct($sInlineImageClassName);
|
||||
|
||||
// Building href validation pattern from url and email validation patterns as the patterns are not used the same way in HTML content than in standard attributes value.
|
||||
// eg. "foo@bar.com" vs "mailto:foo@bar.com?subject=Title&body=Hello%20world"
|
||||
if (!array_key_exists('href', self::$aAttrsWhiteList)) {
|
||||
// Regular urls
|
||||
$sUrlPattern = utils::GetConfig()->Get('url_validation_pattern');
|
||||
|
||||
// Mailto urls
|
||||
$sMailtoPattern = '(mailto:('.utils::GetConfig()->Get('email_validation_pattern').')(?:\?(?:subject|body)=([a-zA-Z0-9+\$_.-]*)(?:&(?:subject|body)=([a-zA-Z0-9+\$_.-]*))?)?)';
|
||||
|
||||
// Notification placeholders
|
||||
// eg. $this->caller_id$, $this->hyperlink()$, $this->hyperlink(portal)$, $APP_URL$, $MODULES_URL$, ...
|
||||
// Note: Authorize both $xxx$ and %24xxx%24 as the latter one is encoded when used in HTML attributes (eg. a[href])
|
||||
$sPlaceholderPattern = '(\$|%24)[\w-]*(->[\w]*(\([\w-]*?\))?)?(\$|%24)';
|
||||
|
||||
$sPattern = $sUrlPattern.'|'.$sMailtoPattern.'|'.$sPlaceholderPattern;
|
||||
$sPattern = '/'.str_replace('/', '\/', $sPattern).'/i';
|
||||
self::$aAttrsWhiteList['href'] = $sPattern;
|
||||
}
|
||||
}
|
||||
|
||||
public function GetTagsWhiteList()
|
||||
{
|
||||
return static::$aTagsWhiteList;
|
||||
@@ -372,30 +408,6 @@ class HTMLDOMSanitizer extends DOMSanitizer
|
||||
return static::$aStylesWhiteList;
|
||||
}
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
|
||||
// Building href validation pattern from url and email validation patterns as the patterns are not used the same way in HTML content than in standard attributes value.
|
||||
// eg. "foo@bar.com" vs "mailto:foo@bar.com?subject=Title&body=Hello%20world"
|
||||
if (!array_key_exists('href', self::$aAttrsWhiteList)) {
|
||||
// Regular urls
|
||||
$sUrlPattern = utils::GetConfig()->Get('url_validation_pattern');
|
||||
|
||||
// Mailto urls
|
||||
$sMailtoPattern = '(mailto:('.utils::GetConfig()->Get('email_validation_pattern').')(?:\?(?:subject|body)=([a-zA-Z0-9+\$_.-]*)(?:&(?:subject|body)=([a-zA-Z0-9+\$_.-]*))?)?)';
|
||||
|
||||
// Notification placeholders
|
||||
// eg. $this->caller_id$, $this->hyperlink()$, $this->hyperlink(portal)$, $APP_URL$, $MODULES_URL$, ...
|
||||
// Note: Authorize both $xxx$ and %24xxx%24 as the latter one is encoded when used in HTML attributes (eg. a[href])
|
||||
$sPlaceholderPattern = '(\$|%24)[\w-]*(->[\w]*(\([\w-]*?\))?)?(\$|%24)';
|
||||
|
||||
$sPattern = $sUrlPattern.'|'.$sMailtoPattern.'|'.$sPlaceholderPattern;
|
||||
$sPattern = '/'.str_replace('/', '\/', $sPattern).'/i';
|
||||
self::$aAttrsWhiteList['href'] = $sPattern;
|
||||
}
|
||||
}
|
||||
|
||||
public function LoadDoc($sHTML)
|
||||
{
|
||||
@$this->oDoc->loadHTML('<?xml encoding="UTF-8"?>'.$sHTML); // For loading HTML chunks where the character set is not specified
|
||||
|
||||
@@ -6,6 +6,8 @@
|
||||
*/
|
||||
|
||||
use PhpParser\Node\Expr\Assign;
|
||||
use PhpParser\Node\Expr\Variable;
|
||||
use PhpParser\Parser;
|
||||
use PhpParser\ParserFactory;
|
||||
use PhpParser\PrettyPrinter\Standard;
|
||||
|
||||
@@ -80,38 +82,49 @@ class iTopConfigParser
|
||||
* @param \PhpParser\Parser $oParser
|
||||
* @param $sConfig
|
||||
*
|
||||
* @return \Combodo\iTop\Config\Validator\ConfigNodesVisitor
|
||||
* @return void
|
||||
*/
|
||||
private function BrowseFile(\PhpParser\Parser $oParser, $sConfig)
|
||||
private function BrowseFile(Parser $oParser, $sConfig)
|
||||
{
|
||||
$prettyPrinter = new Standard();
|
||||
|
||||
try
|
||||
{
|
||||
try {
|
||||
$aNodes = $oParser->parse($sConfig);
|
||||
}
|
||||
catch (\Error $e)
|
||||
{
|
||||
catch (\Error $e) {
|
||||
$sMessage = Dict::Format('config-parse-error', $e->getMessage(), $e->getLine());
|
||||
$this->oException = new \Exception($sMessage, 0, $e);
|
||||
}
|
||||
|
||||
foreach ($aNodes as $oAssignation)
|
||||
{
|
||||
if (! $oAssignation instanceof Assign)
|
||||
{
|
||||
foreach ($aNodes as $sKey => $oNode) {
|
||||
// With PhpParser 3 we had an Assign node at root
|
||||
// In PhpParser 4 the root node is now an Expression
|
||||
|
||||
if (false === ($oNode instanceof \PhpParser\Node\Stmt\Expression)) {
|
||||
continue;
|
||||
}
|
||||
/** @var \PhpParser\Node\Stmt\Expression $oNode */
|
||||
|
||||
if (false === ($oNode->expr instanceof Assign)) {
|
||||
continue;
|
||||
}
|
||||
/** @var Assign $oAssignation */
|
||||
$oAssignation = $oNode->expr;
|
||||
|
||||
if (false === ($oAssignation->var instanceof Variable)) {
|
||||
continue;
|
||||
}
|
||||
if (false === ($oAssignation->expr instanceof PhpParser\Node\Expr\Array_)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$sCurrentRootVar = $oAssignation->var->name;
|
||||
if (!array_key_exists($sCurrentRootVar, $this->aVarsMap))
|
||||
{
|
||||
if (!array_key_exists($sCurrentRootVar, $this->aVarsMap)) {
|
||||
continue;
|
||||
}
|
||||
$aCurrentRootVarMap =& $this->aVarsMap[$sCurrentRootVar];
|
||||
|
||||
foreach ($oAssignation->expr->items as $oItem)
|
||||
{
|
||||
foreach ($oAssignation->expr->items as $oItem) {
|
||||
$sValue = $prettyPrinter->prettyPrintExpr($oItem->value);
|
||||
$aCurrentRootVarMap[$oItem->key->value] = $sValue;
|
||||
}
|
||||
|
||||
@@ -551,6 +551,13 @@ class LogChannels
|
||||
|
||||
const INLINE_IMAGE = 'InlineImage';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
* @since 3.0.1 N°4849
|
||||
* @since 2.7.7 N°4635
|
||||
*/
|
||||
const NOTIFICATIONS = 'notifications';
|
||||
|
||||
const PORTAL = 'portal';
|
||||
}
|
||||
|
||||
@@ -691,7 +698,7 @@ abstract class LogAPI
|
||||
|
||||
if (isset($sLogLevelMin[static::CHANNEL_DEFAULT]))
|
||||
{
|
||||
return $sLogLevelMin[$sChannel];
|
||||
return $sLogLevelMin[static::CHANNEL_DEFAULT];
|
||||
}
|
||||
|
||||
return static::LEVEL_DEFAULT;
|
||||
|
||||
@@ -2424,26 +2424,33 @@ fieldset .details>.field_container {
|
||||
|
||||
.selectize-dropdown,
|
||||
.selectize-input,
|
||||
.selectize-input input{
|
||||
font-size: 12px;
|
||||
}
|
||||
.selectize-input{
|
||||
padding: 2px 2px 0px 2px; /* padding-bottom = padding-top - item margin-bottom */
|
||||
border: 1px solid #ABABAB;
|
||||
border-radius: 0;
|
||||
.selectize-input input {
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.attribute-set-item.partial-code{
|
||||
color: transparentize($gray-darker, 0.4);
|
||||
background-color: lighten($gray-lighter, 5%);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.selectize-input {
|
||||
padding: 2px 2px 0px 2px; /* padding-bottom = padding-top - item margin-bottom */
|
||||
border: 1px solid #ABABAB;
|
||||
border-radius: 0;
|
||||
|
||||
.attribute-set-item.partial-code {
|
||||
color: transparentize($gray-darker, 0.4);
|
||||
background-color: lighten($gray-lighter, 5%);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&[data-attribute-type="AttributeDuration"] {
|
||||
.field_value_container {
|
||||
white-space: nowrap;
|
||||
}
|
||||
}
|
||||
}
|
||||
.one-col-details .details .field_container.field_small {
|
||||
div.field_label {
|
||||
|
||||
@@ -4,6 +4,8 @@
|
||||
* To view and modify this theme, visit http://jqueryui.com/themeroller/?scope=&folderName=custom-theme&bgImgOpacityError=18&bgImgOpacityHighlight=75&bgImgOpacityActive=65&bgImgOpacityHover=100&bgImgOpacityDefault=100&bgImgOpacityContent=100&bgImgOpacityHeader=35&cornerRadiusShadow=5px&offsetLeftShadow=-5px&offsetTopShadow=-5px&thicknessShadow=5px&opacityShadow=20&bgImgOpacityShadow=10&bgTextureShadow=flat&bgColorShadow=%23000000&opacityOverlay=50&bgImgOpacityOverlay=20&bgTextureOverlay=diagonals_thick&bgColorOverlay=%23666666&iconColorError=%23ffd27a&fcError=%23ffffff&borderColorError=%23cd0a0a&bgTextureError=diagonals_thick&bgColorError=%23b81900&iconColorHighlight=%231c94c4&fcHighlight=%23363636&borderColorHighlight=%23fed22f&bgTextureHighlight=flat&bgColorHighlight=%23ffe45c&iconColorActive=%23E87C1E&fcActive=%23E87C1E&borderColorActive=%23E87C1E&bgTextureActive=flat&bgColorActive=%23ffffff&iconColorHover=%23E87C1E&fcHover=%23E87C1E&borderColorHover=%23E87C1E&bgTextureHover=flat&bgColorHover=%23fde17c&iconColorDefault=%23F26522&fcDefault=%23555555&borderColorDefault=%23cccccc&bgTextureDefault=flat&bgColorDefault=%23f1f1f1&iconColorContent=%23222222&fcContent=%23333333&borderColorContent=%23dddddd&bgTextureContent=flat&bgColorContent=%23eeeeee&iconColorHeader=%23ffffff&fcHeader=%23ffffff&borderColorHeader=%23F26522&bgTextureHeader=flat&bgColorHeader=%23E87C1E&cornerRadius=0&fwDefault=bold&fsDefault=1.1em&ffDefault=Trebuchet%20MS%2CTahoma%2CVerdana%2CArial%2Csans-serif
|
||||
* Copyright jQuery Foundation and other contributors; Licensed MIT
|
||||
* The original css file has been scssized (through www.css2scss.com)
|
||||
*
|
||||
* Other modification done : replaced the `Alpha(` by `alpha(` to avoid warnings generated by SCSSPHP
|
||||
*/
|
||||
.ui-draggable-handle {
|
||||
-ms-touch-action: none;
|
||||
@@ -46,26 +48,27 @@
|
||||
}
|
||||
}
|
||||
.ui-helper-zfix {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
top: 0;
|
||||
left: 0;
|
||||
position: absolute;
|
||||
opacity: 0;
|
||||
filter: Alpha(Opacity=0);
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
top: 0;
|
||||
left: 0;
|
||||
position: absolute;
|
||||
opacity: 0;
|
||||
filter: alpha(Opacity=0);
|
||||
}
|
||||
.ui-front {
|
||||
z-index: 100;
|
||||
}
|
||||
.ui-state-disabled {
|
||||
cursor: default !important;
|
||||
pointer-events: none;
|
||||
opacity: .35;
|
||||
filter: Alpha(Opacity=35);
|
||||
background-image: none;
|
||||
.ui-icon {
|
||||
filter: Alpha(Opacity=35);
|
||||
}
|
||||
cursor: default !important;
|
||||
pointer-events: none;
|
||||
opacity: .35;
|
||||
filter: alpha(Opacity=35);
|
||||
background-image: none;
|
||||
|
||||
.ui-icon {
|
||||
filter: alpha(Opacity=35);
|
||||
}
|
||||
}
|
||||
.ui-icon {
|
||||
display: inline-block;
|
||||
@@ -86,14 +89,14 @@
|
||||
display: block;
|
||||
}
|
||||
.ui-widget-overlay {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: #666666 url($approot-relative + "css/ui-lightness/images/ui-bg_diagonals-thick_20_666666_40x40.png?v=" + $version) 50% 50% repeat;
|
||||
opacity: .5;
|
||||
filter: Alpha(Opacity=50);
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: #666666 url($approot-relative + "css/ui-lightness/images/ui-bg_diagonals-thick_20_666666_40x40.png?v=" + $version) 50% 50% repeat;
|
||||
opacity: .5;
|
||||
filter: alpha(Opacity=50);
|
||||
}
|
||||
.ui-resizable {
|
||||
position: relative;
|
||||
@@ -1069,14 +1072,14 @@ body {
|
||||
font-weight: bold;
|
||||
}
|
||||
.ui-priority-secondary {
|
||||
opacity: .7;
|
||||
filter: Alpha(Opacity=70);
|
||||
font-weight: normal;
|
||||
opacity: .7;
|
||||
filter: alpha(Opacity=70);
|
||||
font-weight: normal;
|
||||
}
|
||||
.ui-state-disabled {
|
||||
opacity: .35;
|
||||
filter: Alpha(Opacity=35);
|
||||
background-image: none;
|
||||
opacity: .35;
|
||||
filter: alpha(Opacity=35);
|
||||
background-image: none;
|
||||
}
|
||||
.ui-icon {
|
||||
background-image: url($approot-relative + "css/ui-lightness/images/ui-icons_222222_256x240.png?v=" + $version);
|
||||
@@ -1137,14 +1140,14 @@ body {
|
||||
font-weight: bold;
|
||||
}
|
||||
.ui-priority-secondary {
|
||||
opacity: .7;
|
||||
filter: Alpha(Opacity=70);
|
||||
font-weight: normal;
|
||||
opacity: .7;
|
||||
filter: alpha(Opacity=70);
|
||||
font-weight: normal;
|
||||
}
|
||||
.ui-state-disabled {
|
||||
opacity: .35;
|
||||
filter: Alpha(Opacity=35);
|
||||
background-image: none;
|
||||
opacity: .35;
|
||||
filter: alpha(Opacity=35);
|
||||
background-image: none;
|
||||
}
|
||||
.ui-icon {
|
||||
background-image: url($approot-relative + "css/ui-lightness/images/ui-icons_ffffff_256x240.png?v=" + $version);
|
||||
@@ -1341,9 +1344,9 @@ a {
|
||||
font-weight: bold;
|
||||
}
|
||||
.ui-priority-secondary {
|
||||
opacity: .7;
|
||||
filter: Alpha(Opacity=70);
|
||||
font-weight: normal;
|
||||
opacity: .7;
|
||||
filter: alpha(Opacity=70);
|
||||
font-weight: normal;
|
||||
}
|
||||
.ui-icon-blank {
|
||||
background-position: 16px 16px;
|
||||
|
||||
@@ -301,9 +301,7 @@ function DisplayLostAttachments(iTopWebPage &$oP, ApplicationContext &$oAppConte
|
||||
$sHistoryEntry = Dict::Format('DBTools:LostAttachments:History', $oOrmDocument->GetFileName());
|
||||
CMDBObject::SetTrackInfo(UserRights::GetUserFriendlyName());
|
||||
$oChangeOp = MetaModel::NewObject('CMDBChangeOpPlugin');
|
||||
/** @var \Change $oChange */
|
||||
$oChange = CMDBObject::GetCurrentChange();
|
||||
$oChangeOp->Set('change', $oChange->GetKey());
|
||||
// CMDBChangeOp.change will be automatically filled
|
||||
$oChangeOp->Set('objclass', $sTargetClass);
|
||||
$oChangeOp->Set('objkey', $sTargetId);
|
||||
$oChangeOp->Set('description', $sHistoryEntry);
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
<module>combodo-db-tools</module>
|
||||
<module>itop-core-update</module>
|
||||
<module>itop-hub-connector</module>
|
||||
<module>itop-oauth-client</module>
|
||||
</modules>
|
||||
<mandatory>true</mandatory>
|
||||
</choice>
|
||||
|
||||
@@ -23,6 +23,7 @@ class ConfigNodesVisitor extends NodeVisitorAbstract
|
||||
Node\Name::class,
|
||||
|
||||
Node\Const_::class,
|
||||
Node\Identifier::class,
|
||||
|
||||
Node\Expr\Array_::class,
|
||||
Node\Expr\ArrayDimFetch::class,
|
||||
@@ -44,6 +45,7 @@ class ConfigNodesVisitor extends NodeVisitorAbstract
|
||||
Node\Expr\PreDec::class,
|
||||
Node\Expr\PreInc::class,
|
||||
Node\Expr\Print_::class,
|
||||
Node\Stmt\Expression::class,
|
||||
Node\Expr\Ternary::class,
|
||||
Node\Expr\UnaryMinus::class,
|
||||
Node\Expr\UnaryPlus::class,
|
||||
|
||||
@@ -76,7 +76,6 @@ Dict::Add('CS CZ', 'Czech', 'Čeština', array(
|
||||
'iTopUpdate:UI:CanCoreUpdate:No' => 'Application cannot be updated: %1$s~~',
|
||||
'iTopUpdate:UI:CanCoreUpdate:Warning' => 'Warning: application update can fail: %1$s~~',
|
||||
'iTopUpdate:UI:CannotUpdateUseSetup' => '<b>Some modified files were detected</b>, a partial update cannot be executed.</br>Follow the <a target="_blank" href="%2$s"> procedure</a> in order to manually upgrade your iTop. You must use the <a href="%1$s">setup</a> to update the application.~~',
|
||||
'iTopUpdate:UI:CannotUpdateNewModules' => '<b>Some new modules were detected</b>, a partial update cannot be executed.</br>Follow the <a target="_blank" href="%2$s"> procedure</a> in order to manually upgrade your iTop. You must use the <a href="%1$s">setup</a> to update the application.~~',
|
||||
'iTopUpdate:UI:CheckInProgress'=>'Please wait during integrity check~~',
|
||||
|
||||
// Setup Messages
|
||||
|
||||
@@ -76,7 +76,6 @@ Dict::Add('DA DA', 'Danish', 'Dansk', array(
|
||||
'iTopUpdate:UI:CanCoreUpdate:No' => 'Application cannot be updated: %1$s~~',
|
||||
'iTopUpdate:UI:CanCoreUpdate:Warning' => 'Warning: application update can fail: %1$s~~',
|
||||
'iTopUpdate:UI:CannotUpdateUseSetup' => '<b>Some modified files were detected</b>, a partial update cannot be executed.</br>Follow the <a target="_blank" href="%2$s"> procedure</a> in order to manually upgrade your iTop. You must use the <a href="%1$s">setup</a> to update the application.~~',
|
||||
'iTopUpdate:UI:CannotUpdateNewModules' => '<b>Some new modules were detected</b>, a partial update cannot be executed.</br>Follow the <a target="_blank" href="%2$s"> procedure</a> in order to manually upgrade your iTop. You must use the <a href="%1$s">setup</a> to update the application.~~',
|
||||
'iTopUpdate:UI:CheckInProgress'=>'Please wait during integrity check~~',
|
||||
|
||||
// Setup Messages
|
||||
|
||||
@@ -76,7 +76,6 @@ Dict::Add('DE DE', 'German', 'Deutsch', array(
|
||||
'iTopUpdate:UI:CanCoreUpdate:No' => 'Anwendungsupgrade nicht möglich: %1$s',
|
||||
'iTopUpdate:UI:CanCoreUpdate:Warning' => 'Warning: application update can fail: %1$s~~',
|
||||
'iTopUpdate:UI:CannotUpdateUseSetup' => '<b>Einige angepasste Dateien wurden erkannt</b>, eine Teil-Update kann nicht ausgeführt werden.<br/>Befolgen Sie das <a target="_blank" href="%2$s">Verfahren</a>, um Ihr iTop manuell zu aktualisieren. Sie müssen das <a href="%1$s">Setup</a> benutzen, um Ihre Applikation zu aktualisieren.<br />',
|
||||
'iTopUpdate:UI:CannotUpdateNewModules' => '<b>Einige neue Module wurden erkannt</b>, eine Teil-Update kann nicht ausgeführt werden.<br/>Befolgen Sie das <a target="_blank" href="%2$s">Verfahren</a>, um Ihr iTop manuell zu aktualisieren. Sie müssen das <a href="%1$s">Setup</a> benutzen, um Ihre Applikation zu aktualisieren.<br />',
|
||||
'iTopUpdate:UI:CheckInProgress'=>'Please wait during integrity check~~',
|
||||
|
||||
// Setup Messages
|
||||
|
||||
@@ -76,7 +76,6 @@ Dict::Add('EN US', 'English', 'English', array(
|
||||
'iTopUpdate:UI:CanCoreUpdate:No' => 'Application cannot be updated: %1$s',
|
||||
'iTopUpdate:UI:CanCoreUpdate:Warning' => 'Warning: application update can fail: %1$s',
|
||||
'iTopUpdate:UI:CannotUpdateUseSetup' => '<b>Some modified files were detected</b>, a partial update cannot be executed.</br>Follow the <a target="_blank" href="%2$s"> procedure</a> in order to manually upgrade your iTop. You must use the <a href="%1$s">setup</a> to update the application.',
|
||||
'iTopUpdate:UI:CannotUpdateNewModules' => '<b>Some new modules were detected</b>, a partial update cannot be executed.</br>Follow the <a target="_blank" href="%2$s"> procedure</a> in order to manually upgrade your iTop. You must use the <a href="%1$s">setup</a> to update the application.',
|
||||
'iTopUpdate:UI:CheckInProgress'=>'Please wait during integrity check',
|
||||
|
||||
// Setup Messages
|
||||
|
||||
@@ -77,7 +77,6 @@ Dict::Add('ES CR', 'Spanish', 'Español, Castellano', array(
|
||||
'iTopUpdate:UI:CanCoreUpdate:No' => 'La aplicación no puede ser actualizada: %1$s',
|
||||
'iTopUpdate:UI:CanCoreUpdate:Warning' => 'Advertencia: la actualización de la aplicación puede fallar: %1$s',
|
||||
'iTopUpdate:UI:CannotUpdateUseSetup' => '<b>Some modified files were detected</b>, a partial update cannot be executed.</br>Follow the <a target="_blank" href="%2$s"> procedure</a> in order to manually upgrade your iTop. You must use the <a href="%1$s">setup</a> to update the application.~~',
|
||||
'iTopUpdate:UI:CannotUpdateNewModules' => '<b>Some new modules were detected</b>, a partial update cannot be executed.</br>Follow the <a target="_blank" href="%2$s"> procedure</a> in order to manually upgrade your iTop. You must use the <a href="%1$s">setup</a> to update the application.~~',
|
||||
'iTopUpdate:UI:CheckInProgress'=>'Please wait during integrity check~~',
|
||||
|
||||
// Setup Messages
|
||||
|
||||
@@ -73,10 +73,9 @@ Dict::Add('FR FR', 'French', 'Français', array(
|
||||
'iTopUpdate:UI:CanCoreUpdate:ErrorFileNotExist' => 'Échec de la vérification des fichiers (Fichier manquant %1$s)',
|
||||
'iTopUpdate:UI:CanCoreUpdate:Failed' => 'Échec de la vérification des fichiers',
|
||||
'iTopUpdate:UI:CanCoreUpdate:Yes' => 'L\'application peut être mise à jour',
|
||||
'iTopUpdate:UI:CanCoreUpdate:No' => 'L\'application ne peut pas être mise à jour : %1$s',
|
||||
'iTopUpdate:UI:CanCoreUpdate:No' => 'L\'application ne peut pas être mise à jour : %1$s',
|
||||
'iTopUpdate:UI:CanCoreUpdate:Warning' => 'Attention : la mise à jour de l\'application peut échouer : %1$s',
|
||||
'iTopUpdate:UI:CannotUpdateUseSetup' => '<b>Des fichiers modifiés ont été détectés</b>, une mise à jour partielle ne peut pas être effectuée.<br />Suivez la <a target="_blank" href="%2$s"> procedure</a> pour mettre à jour manuellement votre iTop. Vous devez utiliser la page <a href="%1$s">d\'installation</a> pour mettre à jour l\'application.',
|
||||
'iTopUpdate:UI:CannotUpdateNewModules' => '<b>De nouveaux modules ont été détectés</b>, une mise à jour partielle ne peut pas être effectuée.<br />Suivez la <a target="_blank" href="%2$s"> procedure</a> pour mettre à jour manuellement votre iTop. Vous devez utiliser la page <a href="%1$s">d\'installation</a> pour mettre à jour l\'application.',
|
||||
'iTopUpdate:UI:CheckInProgress'=>'Veuillez patienter pendant la vérification d\'intégrité',
|
||||
|
||||
// Setup Messages
|
||||
|
||||
@@ -76,7 +76,6 @@ Dict::Add('HU HU', 'Hungarian', 'Magyar', array(
|
||||
'iTopUpdate:UI:CanCoreUpdate:No' => 'Application cannot be updated: %1$s~~',
|
||||
'iTopUpdate:UI:CanCoreUpdate:Warning' => 'Warning: application update can fail: %1$s~~',
|
||||
'iTopUpdate:UI:CannotUpdateUseSetup' => '<b>Some modified files were detected</b>, a partial update cannot be executed.</br>Follow the <a target="_blank" href="%2$s"> procedure</a> in order to manually upgrade your iTop. You must use the <a href="%1$s">setup</a> to update the application.~~',
|
||||
'iTopUpdate:UI:CannotUpdateNewModules' => '<b>Some new modules were detected</b>, a partial update cannot be executed.</br>Follow the <a target="_blank" href="%2$s"> procedure</a> in order to manually upgrade your iTop. You must use the <a href="%1$s">setup</a> to update the application.~~',
|
||||
'iTopUpdate:UI:CheckInProgress'=>'Please wait during integrity check~~',
|
||||
|
||||
// Setup Messages
|
||||
|
||||
@@ -76,7 +76,6 @@ Dict::Add('IT IT', 'Italian', 'Italiano', array(
|
||||
'iTopUpdate:UI:CanCoreUpdate:No' => 'Application cannot be updated: %1$s~~',
|
||||
'iTopUpdate:UI:CanCoreUpdate:Warning' => 'Warning: application update can fail: %1$s~~',
|
||||
'iTopUpdate:UI:CannotUpdateUseSetup' => '<b>Some modified files were detected</b>, a partial update cannot be executed.</br>Follow the <a target="_blank" href="%2$s"> procedure</a> in order to manually upgrade your iTop. You must use the <a href="%1$s">setup</a> to update the application.~~',
|
||||
'iTopUpdate:UI:CannotUpdateNewModules' => '<b>Some new modules were detected</b>, a partial update cannot be executed.</br>Follow the <a target="_blank" href="%2$s"> procedure</a> in order to manually upgrade your iTop. You must use the <a href="%1$s">setup</a> to update the application.~~',
|
||||
'iTopUpdate:UI:CheckInProgress'=>'Please wait during integrity check~~',
|
||||
|
||||
// Setup Messages
|
||||
|
||||
@@ -76,7 +76,6 @@ Dict::Add('JA JP', 'Japanese', '日本語', array(
|
||||
'iTopUpdate:UI:CanCoreUpdate:No' => 'Application cannot be updated: %1$s~~',
|
||||
'iTopUpdate:UI:CanCoreUpdate:Warning' => 'Warning: application update can fail: %1$s~~',
|
||||
'iTopUpdate:UI:CannotUpdateUseSetup' => '<b>Some modified files were detected</b>, a partial update cannot be executed.</br>Follow the <a target="_blank" href="%2$s"> procedure</a> in order to manually upgrade your iTop. You must use the <a href="%1$s">setup</a> to update the application.~~',
|
||||
'iTopUpdate:UI:CannotUpdateNewModules' => '<b>Some new modules were detected</b>, a partial update cannot be executed.</br>Follow the <a target="_blank" href="%2$s"> procedure</a> in order to manually upgrade your iTop. You must use the <a href="%1$s">setup</a> to update the application.~~',
|
||||
'iTopUpdate:UI:CheckInProgress'=>'Please wait during integrity check~~',
|
||||
|
||||
// Setup Messages
|
||||
|
||||
@@ -78,7 +78,6 @@ Dict::Add('NL NL', 'Dutch', 'Nederlands', array(
|
||||
'iTopUpdate:UI:CanCoreUpdate:No' => 'Updaten van de toepassing is niet mogelijk: %1$s',
|
||||
'iTopUpdate:UI:CanCoreUpdate:Warning' => 'Warning: application update can fail: %1$s~~',
|
||||
'iTopUpdate:UI:CannotUpdateUseSetup' => '<b>Some modified files were detected</b>, a partial update cannot be executed.</br>Follow the <a target="_blank" href="%2$s"> procedure</a> in order to manually upgrade your iTop. You must use the <a href="%1$s">setup</a> to update the application.~~',
|
||||
'iTopUpdate:UI:CannotUpdateNewModules' => '<b>Some new modules were detected</b>, a partial update cannot be executed.</br>Follow the <a target="_blank" href="%2$s"> procedure</a> in order to manually upgrade your iTop. You must use the <a href="%1$s">setup</a> to update the application.~~',
|
||||
'iTopUpdate:UI:CheckInProgress'=>'Please wait during integrity check~~',
|
||||
|
||||
// Setup Messages
|
||||
|
||||
@@ -76,7 +76,6 @@ Dict::Add('PT BR', 'Brazilian', 'Brazilian', array(
|
||||
'iTopUpdate:UI:CanCoreUpdate:No' => 'Application cannot be updated: %1$s~~',
|
||||
'iTopUpdate:UI:CanCoreUpdate:Warning' => 'Warning: application update can fail: %1$s~~',
|
||||
'iTopUpdate:UI:CannotUpdateUseSetup' => '<b>Some modified files were detected</b>, a partial update cannot be executed.</br>Follow the <a target="_blank" href="%2$s"> procedure</a> in order to manually upgrade your iTop. You must use the <a href="%1$s">setup</a> to update the application.~~',
|
||||
'iTopUpdate:UI:CannotUpdateNewModules' => '<b>Some new modules were detected</b>, a partial update cannot be executed.</br>Follow the <a target="_blank" href="%2$s"> procedure</a> in order to manually upgrade your iTop. You must use the <a href="%1$s">setup</a> to update the application.~~',
|
||||
'iTopUpdate:UI:CheckInProgress'=>'Please wait during integrity check~~',
|
||||
|
||||
// Setup Messages
|
||||
|
||||
@@ -64,7 +64,6 @@ Dict::Add('RU RU', 'Russian', 'Русский', array(
|
||||
'iTopUpdate:UI:CanCoreUpdate:No' => 'Приложение не может быть обновлено: %1$s',
|
||||
'iTopUpdate:UI:CanCoreUpdate:Warning' => 'Warning: application update can fail: %1$s~~',
|
||||
'iTopUpdate:UI:CannotUpdateUseSetup' => '<b>Some modified files were detected</b>, a partial update cannot be executed.</br>Follow the <a target="_blank" href="%2$s"> procedure</a> in order to manually upgrade your iTop. You must use the <a href="%1$s">setup</a> to update the application.~~',
|
||||
'iTopUpdate:UI:CannotUpdateNewModules' => '<b>Some new modules were detected</b>, a partial update cannot be executed.</br>Follow the <a target="_blank" href="%2$s"> procedure</a> in order to manually upgrade your iTop. You must use the <a href="%1$s">setup</a> to update the application.~~',
|
||||
'iTopUpdate:UI:CheckInProgress'=>'Please wait during integrity check~~',
|
||||
|
||||
// Setup Messages
|
||||
|
||||
@@ -76,7 +76,6 @@ Dict::Add('SK SK', 'Slovak', 'Slovenčina', array(
|
||||
'iTopUpdate:UI:CanCoreUpdate:No' => 'Application cannot be updated: %1$s~~',
|
||||
'iTopUpdate:UI:CanCoreUpdate:Warning' => 'Warning: application update can fail: %1$s~~',
|
||||
'iTopUpdate:UI:CannotUpdateUseSetup' => '<b>Some modified files were detected</b>, a partial update cannot be executed.</br>Follow the <a target="_blank" href="%2$s"> procedure</a> in order to manually upgrade your iTop. You must use the <a href="%1$s">setup</a> to update the application.~~',
|
||||
'iTopUpdate:UI:CannotUpdateNewModules' => '<b>Some new modules were detected</b>, a partial update cannot be executed.</br>Follow the <a target="_blank" href="%2$s"> procedure</a> in order to manually upgrade your iTop. You must use the <a href="%1$s">setup</a> to update the application.~~',
|
||||
'iTopUpdate:UI:CheckInProgress'=>'Please wait during integrity check~~',
|
||||
|
||||
// Setup Messages
|
||||
|
||||
@@ -9,7 +9,6 @@
|
||||
|
||||
namespace Combodo\iTop\CoreUpdate\Service;
|
||||
|
||||
use Combodo\iTop\FilesInformation\Service\FileIntegrityException;
|
||||
use Combodo\iTop\FilesInformation\Service\FilesIntegrity;
|
||||
use DBBackup;
|
||||
use Dict;
|
||||
@@ -539,9 +538,6 @@ final class CoreUpdater
|
||||
$sRootPath = self::UPDATE_DIR.'web/';
|
||||
FilesIntegrity::CheckInstallationIntegrity($sRootPath);
|
||||
|
||||
///Check new modules
|
||||
self::CheckNewModules($sRootPath);
|
||||
|
||||
SetupLog::Info('itop-core-update: Files integrity OK');
|
||||
} catch (Exception $e)
|
||||
{
|
||||
@@ -609,38 +605,4 @@ final class CoreUpdater
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if new modules (not already installed) are present, and throw an exception if that is the case as core update doesn't know how to install them automatically for know
|
||||
*
|
||||
* @param string $sRootPath
|
||||
*
|
||||
* @throws \ApplicationException
|
||||
* @since 2.7.7 3.0.1
|
||||
*/
|
||||
private static function CheckNewModules($sRootPath)
|
||||
{
|
||||
$aFilesInfo = FilesIntegrity::GetInstalledFiles($sRootPath.'manifest.xml');
|
||||
|
||||
if ($aFilesInfo === false) {
|
||||
throw new FileIntegrityException(Dict::Format('FilesInformation:Error:MissingFile', 'manifest.xml'));
|
||||
}
|
||||
|
||||
@clearstatcache();
|
||||
$sSourceDir = MetaModel::GetConfig()->Get('source_dir');
|
||||
foreach ($aFilesInfo as $aFileInfo) {
|
||||
if (strpos($aFileInfo['path'], $sSourceDir) === 0) {
|
||||
$aFilePath = explode('/', $aFileInfo['path']);
|
||||
$sFolderPath = $aFilePath[0].'/'.$aFilePath[1].'/'.$aFilePath[2];
|
||||
//if module don't already exist in itop and if module listed in manifest.xml is included in zip
|
||||
if (!is_dir(APPROOT.'/'.$sFolderPath) && !is_file(APPROOT.'/'.$sFolderPath)
|
||||
&& is_dir($sRootPath.'/'.$sFolderPath)) {
|
||||
$sLink = utils::GetAbsoluteUrlAppRoot().'setup/';
|
||||
$sLinkManualUpdate = 'https://www.itophub.io/wiki/page?id='.utils::GetItopVersionWikiSyntax().'%3Ainstall%3Aupgrading_itop#manually';
|
||||
throw new FileIntegrityException(Dict::Format('iTopUpdate:UI:CannotUpdateNewModules' , $sLink, $sLinkManualUpdate));
|
||||
}
|
||||
}
|
||||
// Packed with missing files...
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,6 +11,7 @@ require_once(APPROOT."setup/runtimeenv.class.inc.php");
|
||||
|
||||
use Config;
|
||||
use Exception;
|
||||
use ModelFactory;
|
||||
use RunTimeEnvironment;
|
||||
use SetupUtils;
|
||||
|
||||
@@ -126,4 +127,38 @@ class RunTimeEnvironmentCoreUpdater extends RunTimeEnvironment
|
||||
}
|
||||
throw new Exception('No configuration file available');
|
||||
}
|
||||
|
||||
protected function GetMFModulesToCompile($sSourceEnv, $sSourceDir)
|
||||
{
|
||||
$aRet = parent::GetMFModulesToCompile($sSourceEnv, $sSourceDir);
|
||||
|
||||
// Add new mandatory modules from datamodel 2.x only
|
||||
$sSourceDirFull = APPROOT.$sSourceDir;
|
||||
if (!is_dir($sSourceDirFull))
|
||||
{
|
||||
throw new Exception("The source directory '$sSourceDirFull' does not exist (or could not be read)");
|
||||
}
|
||||
$aDirsToCompile = [$sSourceDirFull];
|
||||
|
||||
$oFactory = new ModelFactory($aDirsToCompile);
|
||||
$aModules = $oFactory->FindModules();
|
||||
$aAvailableModules = [];
|
||||
/** @var \MFModule $oModule */
|
||||
foreach ($aModules as $oModule) {
|
||||
$aAvailableModules[$oModule->GetName()] = $oModule;
|
||||
}
|
||||
// TODO check the auto-selected modules here
|
||||
foreach($this->oExtensionsMap->GetAllExtensions() as $oExtension) {
|
||||
if ($oExtension->bMarkedAsChosen) {
|
||||
foreach ($oExtension->aModules as $sModuleName) {
|
||||
if (!isset($aRet[$sModuleName]) && isset($aAvailableModules[$sModuleName])) {
|
||||
$aRet[$sModuleName] = $aAvailableModules[$sModuleName];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $aRet;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -76,7 +76,6 @@ Dict::Add('TR TR', 'Turkish', 'Türkçe', array(
|
||||
'iTopUpdate:UI:CanCoreUpdate:No' => 'Application cannot be updated: %1$s~~',
|
||||
'iTopUpdate:UI:CanCoreUpdate:Warning' => 'Warning: application update can fail: %1$s~~',
|
||||
'iTopUpdate:UI:CannotUpdateUseSetup' => '<b>Some modified files were detected</b>, a partial update cannot be executed.</br>Follow the <a target="_blank" href="%2$s"> procedure</a> in order to manually upgrade your iTop. You must use the <a href="%1$s">setup</a> to update the application.~~',
|
||||
'iTopUpdate:UI:CannotUpdateNewModules' => '<b>Some new modules were detected</b>, a partial update cannot be executed.</br>Follow the <a target="_blank" href="%2$s"> procedure</a> in order to manually upgrade your iTop. You must use the <a href="%1$s">setup</a> to update the application.~~',
|
||||
'iTopUpdate:UI:CheckInProgress'=>'Please wait during integrity check~~',
|
||||
|
||||
// Setup Messages
|
||||
|
||||
@@ -64,7 +64,7 @@
|
||||
<fieldset>
|
||||
<div class="message message-error">
|
||||
<div>
|
||||
<span>{{ sError|raw }}</span>
|
||||
<span>{{ sError }}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -76,7 +76,6 @@ Dict::Add('ZH CN', 'Chinese', '简体中文', array(
|
||||
'iTopUpdate:UI:CanCoreUpdate:No' => '应用无法升级: %1$s',
|
||||
'iTopUpdate:UI:CanCoreUpdate:Warning' => '警告: 应用升级可能会失败: %1$s',
|
||||
'iTopUpdate:UI:CannotUpdateUseSetup' => '<b>Some modified files were detected</b>, a partial update cannot be executed.</br>Follow the <a target="_blank" href="%2$s"> procedure</a> in order to manually upgrade your iTop. You must use the <a href="%1$s">setup</a> to update the application.~~',
|
||||
'iTopUpdate:UI:CannotUpdateNewModules' => '<b>Some new modules were detected</b>, a partial update cannot be executed.</br>Follow the <a target="_blank" href="%2$s"> procedure</a> in order to manually upgrade your iTop. You must use the <a href="%1$s">setup</a> to update the application.~~',
|
||||
'iTopUpdate:UI:CheckInProgress'=>'Please wait during integrity check~~',
|
||||
|
||||
// Setup Messages
|
||||
|
||||
@@ -15,12 +15,13 @@
|
||||
<module_parameters>
|
||||
<parameters id="itop-hub-connector" _delta="define">
|
||||
<url>https://www.itophub.io</url>
|
||||
<route_landing>/my-instances/landing-from-remote</route_landing>
|
||||
<route_landing_stateless>/stateless-remote-itop/landing-from-remote-stateless</route_landing_stateless>
|
||||
<route_fetch_unread_messages>/api/messages</route_fetch_unread_messages>
|
||||
<route_mark_all_messages_as_read>/api/messages/mark-all-as-read</route_mark_all_messages_as_read>
|
||||
<route_view_all_messages>/messages</route_view_all_messages>
|
||||
<route_landing>/my-instances/landing-from-remote</route_landing>
|
||||
<route_landing_stateless>/stateless-remote-itop/landing-from-remote-stateless</route_landing_stateless>
|
||||
<route_fetch_unread_messages>/api/messages</route_fetch_unread_messages>
|
||||
<route_mark_all_messages_as_read>/api/messages/mark-all-as-read</route_mark_all_messages_as_read>
|
||||
<route_view_all_messages>/messages</route_view_all_messages>
|
||||
<setup_url>../pages/exec.php?exec_module=itop-hub-connector&exec_page=launch.php&target=inform_after_setup</setup_url>
|
||||
<rgpd_url>https://www.itophub.io/page/data-privacy</rgpd_url>
|
||||
</parameters>
|
||||
</module_parameters>
|
||||
</itop_design>
|
||||
|
||||
5
datamodels/2.x/itop-oauth-client/README.md
Normal file
5
datamodels/2.x/itop-oauth-client/README.md
Normal file
@@ -0,0 +1,5 @@
|
||||
# Extension OAuth 2.0 client
|
||||
|
||||
## GMail
|
||||
|
||||
If the account is in test, after 7 days the tokens are no longer valid, you have to renew the tokens manually.
|
||||
23
datamodels/2.x/itop-oauth-client/ajax.php
Normal file
23
datamodels/2.x/itop-oauth-client/ajax.php
Normal file
@@ -0,0 +1,23 @@
|
||||
<?php
|
||||
/**
|
||||
* @copyright Copyright (C) 2010-2022 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
namespace Combodo\iTop\OAuthClient;
|
||||
|
||||
use Combodo\iTop\OAuthClient\Controller\AjaxOauthClientController;
|
||||
|
||||
require_once(APPROOT.'application/startup.inc.php');
|
||||
|
||||
if (version_compare(ITOP_DESIGN_LATEST_VERSION , '3.0') >= 0) {
|
||||
$sTemplates = MODULESROOT.'itop-oauth-client/templates';
|
||||
} else {
|
||||
$sTemplates = MODULESROOT.'itop-oauth-client/templates/legacy';
|
||||
}
|
||||
|
||||
$oUpdateController = new AjaxOauthClientController($sTemplates, 'itop-oauth-client');
|
||||
$oUpdateController->SetMenuId('OAuthClient');
|
||||
$oUpdateController->HandleOperation();
|
||||
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 48 48" width="48px" height="48px"><linearGradient id="k8yl7~hDat~FaoWq8WjN6a" x1="-1254.397" x2="-1261.911" y1="877.268" y2="899.466" gradientTransform="translate(1981.75 -1362.063) scale(1.5625)" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#114a8b"/><stop offset="1" stop-color="#0669bc"/></linearGradient><path fill="url(#k8yl7~hDat~FaoWq8WjN6a)" d="M17.634,6h11.305L17.203,40.773c-0.247,0.733-0.934,1.226-1.708,1.226H6.697 c-0.994,0-1.8-0.806-1.8-1.8c0-0.196,0.032-0.39,0.094-0.576L15.926,7.227C16.173,6.494,16.86,6,17.634,6L17.634,6z"/><path fill="#0078d4" d="M34.062,29.324H16.135c-0.458-0.001-0.83,0.371-0.831,0.829c0,0.231,0.095,0.451,0.264,0.608 l11.52,10.752C27.423,41.826,27.865,42,28.324,42h10.151L34.062,29.324z"/><linearGradient id="k8yl7~hDat~FaoWq8WjN6b" x1="-1252.05" x2="-1253.788" y1="887.612" y2="888.2" gradientTransform="translate(1981.75 -1362.063) scale(1.5625)" gradientUnits="userSpaceOnUse"><stop offset="0" stop-opacity=".3"/><stop offset=".071" stop-opacity=".2"/><stop offset=".321" stop-opacity=".1"/><stop offset=".623" stop-opacity=".05"/><stop offset="1" stop-opacity="0"/></linearGradient><path fill="url(#k8yl7~hDat~FaoWq8WjN6b)" d="M17.634,6c-0.783-0.003-1.476,0.504-1.712,1.25L5.005,39.595 c-0.335,0.934,0.151,1.964,1.085,2.299C6.286,41.964,6.493,42,6.702,42h9.026c0.684-0.122,1.25-0.603,1.481-1.259l2.177-6.416 l7.776,7.253c0.326,0.27,0.735,0.419,1.158,0.422h10.114l-4.436-12.676l-12.931,0.003L28.98,6H17.634z"/><linearGradient id="k8yl7~hDat~FaoWq8WjN6c" x1="-1252.952" x2="-1244.704" y1="876.6" y2="898.575" gradientTransform="translate(1981.75 -1362.063) scale(1.5625)" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#3ccbf4"/><stop offset="1" stop-color="#2892df"/></linearGradient><path fill="url(#k8yl7~hDat~FaoWq8WjN6c)" d="M32.074,7.225C31.827,6.493,31.141,6,30.368,6h-12.6c0.772,0,1.459,0.493,1.705,1.224 l10.935,32.399c0.318,0.942-0.188,1.963-1.13,2.281C29.093,41.968,28.899,42,28.703,42h12.6c0.994,0,1.8-0.806,1.8-1.801 c0-0.196-0.032-0.39-0.095-0.575L32.074,7.225z"/></svg>
|
||||
|
After Width: | Height: | Size: 2.1 KiB |
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 48 48" width="48px" height="48px"><path fill="#fbc02d" d="M43.611,20.083H42V20H24v8h11.303c-1.649,4.657-6.08,8-11.303,8c-6.627,0-12-5.373-12-12 s5.373-12,12-12c3.059,0,5.842,1.154,7.961,3.039l5.657-5.657C34.046,6.053,29.268,4,24,4C12.955,4,4,12.955,4,24s8.955,20,20,20 s20-8.955,20-20C44,22.659,43.862,21.35,43.611,20.083z"/><path fill="#e53935" d="M6.306,14.691l6.571,4.819C14.655,15.108,18.961,12,24,12c3.059,0,5.842,1.154,7.961,3.039 l5.657-5.657C34.046,6.053,29.268,4,24,4C16.318,4,9.656,8.337,6.306,14.691z"/><path fill="#4caf50" d="M24,44c5.166,0,9.86-1.977,13.409-5.192l-6.19-5.238C29.211,35.091,26.715,36,24,36 c-5.202,0-9.619-3.317-11.283-7.946l-6.522,5.025C9.505,39.556,16.227,44,24,44z"/><path fill="#1565c0" d="M43.611,20.083L43.595,20L42,20H24v8h11.303c-0.792,2.237-2.231,4.166-4.087,5.571 c0.001-0.001,0.002-0.001,0.003-0.002l6.19,5.238C36.971,39.205,44,34,44,24C44,22.659,43.862,21.35,43.611,20.083z"/></svg>
|
||||
|
After Width: | Height: | Size: 977 B |
99
datamodels/2.x/itop-oauth-client/assets/js/oauth_connect.js
Normal file
99
datamodels/2.x/itop-oauth-client/assets/js/oauth_connect.js
Normal file
@@ -0,0 +1,99 @@
|
||||
/**
|
||||
* @copyright Copyright (C) 2010-2022 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
// Function used to open OAuth popup
|
||||
var oWindowObjectReference = null;
|
||||
var sPreviousUrl = null;
|
||||
var oListener = null;
|
||||
var sOAuthAjaxURI = null;
|
||||
var sOAuthObjClass = null;
|
||||
var sOAuthObjKey = null;
|
||||
var sOAuthReturnURI = null;
|
||||
|
||||
|
||||
const oOnOauthSuccess = function (event) {
|
||||
if (oListener !== null) {
|
||||
clearInterval(oListener);
|
||||
}
|
||||
|
||||
$.post(
|
||||
sOAuthAjaxURI,
|
||||
{
|
||||
operation: 'GetDisplayAuthenticationResults',
|
||||
class: sOAuthObjClass,
|
||||
id: sOAuthObjKey,
|
||||
redirect_url: event.data
|
||||
},
|
||||
function (oData) {
|
||||
window.location = oData.data;
|
||||
}
|
||||
);
|
||||
}
|
||||
const oOpenSignInWindow = function (url, name) {
|
||||
// Remove any existing event listener
|
||||
window.removeEventListener('message', oOnOauthSuccess);
|
||||
if (oListener !== null) {
|
||||
clearInterval(oListener);
|
||||
}
|
||||
|
||||
// Window features
|
||||
const sWindowFeatures = 'toolbar=no, menubar=no, width=600, height=700, top=100, left=100';
|
||||
|
||||
if (oWindowObjectReference === null || oWindowObjectReference.closed) {
|
||||
/* If the pointer to the window object in memory does not exist
|
||||
or if such pointer exists but the window was closed */
|
||||
oWindowObjectReference = window.open(url, name, sWindowFeatures);
|
||||
} else if (sPreviousUrl !== url) {
|
||||
/* If the resource to load is different,
|
||||
then we load it in the already opened secondary window, and then
|
||||
we bring such window back on top/in front of its parent window. */
|
||||
oWindowObjectReference = window.open(url, name, sWindowFeatures);
|
||||
oWindowObjectReference.focus();
|
||||
} else {
|
||||
/* Else the window reference must exist and the window
|
||||
is not closed; therefore, we can bring it back on top of any other
|
||||
window with the focus() method. There would be no need to re-create
|
||||
the window or to reload the referenced resource. */
|
||||
oWindowObjectReference.focus();
|
||||
}
|
||||
/* Let know every second our child window that we're waiting for it to complete,
|
||||
once we reach our landing page, it'll send us a reply
|
||||
*/
|
||||
oListener = window.setInterval(function () {
|
||||
if (oWindowObjectReference.closed) {
|
||||
clearInterval(oListener);
|
||||
}
|
||||
oWindowObjectReference.postMessage('anyone', sOAuthReturnURI);
|
||||
}, 1000);
|
||||
|
||||
/* Once we receive a response, transmit it to the server to get authenticate and display
|
||||
results
|
||||
*/
|
||||
window.addEventListener('message', oOnOauthSuccess, false);
|
||||
// Assign the previous URL
|
||||
sPreviousUrl = url;
|
||||
};
|
||||
|
||||
|
||||
const OAuthConnect = function(sClass, sId, sAjaxUri, sReturnUri) {
|
||||
sOAuthAjaxURI = sAjaxUri;
|
||||
sOAuthObjClass = sClass;
|
||||
sOAuthObjKey = sId;
|
||||
sOAuthReturnURI = sReturnUri;
|
||||
|
||||
$.post(
|
||||
sOAuthAjaxURI,
|
||||
{
|
||||
operation: 'GetOAuthAuthorizationUrl',
|
||||
class: sOAuthObjClass,
|
||||
id: sOAuthObjKey
|
||||
},
|
||||
function (oData) {
|
||||
if (oData.status === 'success') {
|
||||
oOpenSignInWindow(oData.data.authorization_url, 'OAuth authorization')
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
16
datamodels/2.x/itop-oauth-client/composer.json
Normal file
16
datamodels/2.x/itop-oauth-client/composer.json
Normal file
@@ -0,0 +1,16 @@
|
||||
{
|
||||
"config": {
|
||||
"classmap-authoritative": true
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Combodo\\iTop\\OAuthClient\\": "src"
|
||||
}
|
||||
},
|
||||
"name": "combodo/itop-oauth-client",
|
||||
"type": "itop-extension",
|
||||
"description": "Remote authentication for OAuth 2.0",
|
||||
"require": {
|
||||
"composer-runtime-api": "^2.0"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
<?php
|
||||
/**
|
||||
* Localized data
|
||||
*
|
||||
* @copyright Copyright (C) 2013 XXXXX
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
Dict::Add('CS CZ', 'Czech', 'Čeština', [
|
||||
'Menu:CreateMailbox' => 'Create a mailbox...~~',
|
||||
'Menu:OAuthClient' => 'OAuth Client~~',
|
||||
'Menu:OAuthClient+' => '~~',
|
||||
'Menu:GenerateTokens' => 'Generate access tokens...~~',
|
||||
'Menu:RegenerateTokens' => 'Regenerate access tokens...~~',
|
||||
|
||||
'itop-oauth-client/Operation:CreateMailBox/Title' => 'Mailbox creation~~',
|
||||
|
||||
'itop-oauth-client:UsedForSMTP' => 'This OAuth client is used for SMTP~~',
|
||||
'itop-oauth-client:TestSMTP' => 'Email send test~~',
|
||||
'itop-oauth-client:MissingOAuthClient' => 'Missing Oauth client for user name %1$s~~',
|
||||
'itop-oauth-client:Message:MissingToken' => 'Generate access token before using this OAuth client~~',
|
||||
'itop-oauth-client:Message:TokenCreated' => 'Access token created~~',
|
||||
'itop-oauth-client:Message:TokenRecreated' => 'Access token regenerated~~',
|
||||
]);
|
||||
|
||||
//
|
||||
// Class: OAuthClient
|
||||
//
|
||||
|
||||
Dict::Add('CS CZ', 'Czech', 'Čeština', [
|
||||
'Class:OAuthClient' => 'Oauth Client~~',
|
||||
'Class:OAuthClient/Attribute:provider' => 'Provider~~',
|
||||
'Class:OAuthClient/Attribute:provider+' => '~~',
|
||||
'Class:OAuthClient/Attribute:name' => 'Login~~',
|
||||
'Class:OAuthClient/Attribute:name+' => '~~',
|
||||
'Class:OAuthClient/Attribute:scope' => 'Scope~~',
|
||||
'Class:OAuthClient/Attribute:scope+' => '~~',
|
||||
'Class:OAuthClient/Attribute:description' => 'Description~~',
|
||||
'Class:OAuthClient/Attribute:description+' => '~~',
|
||||
'Class:OAuthClient/Attribute:client_id' => 'Client id~~',
|
||||
'Class:OAuthClient/Attribute:client_id+' => '~~',
|
||||
'Class:OAuthClient/Attribute:client_secret' => 'Client secret~~',
|
||||
'Class:OAuthClient/Attribute:client_secret+' => '~~',
|
||||
'Class:OAuthClient/Attribute:refresh_token' => 'Refresh token~~',
|
||||
'Class:OAuthClient/Attribute:refresh_token+' => '~~',
|
||||
'Class:OAuthClient/Attribute:refresh_token_expiration' => 'Refresh token expiration~~',
|
||||
'Class:OAuthClient/Attribute:refresh_token_expiration+' => '~~',
|
||||
'Class:OAuthClient/Attribute:token' => 'Access token~~',
|
||||
'Class:OAuthClient/Attribute:token+' => '~~',
|
||||
'Class:OAuthClient/Attribute:token_expiration' => 'Access token expiration~~',
|
||||
'Class:OAuthClient/Attribute:token_expiration+' => '~~',
|
||||
'Class:OAuthClient/Attribute:redirect_url' => 'Redirect url~~',
|
||||
'Class:OAuthClient/Attribute:redirect_url+' => '~~',
|
||||
'Class:OAuthClient/Attribute:mailbox_list' => 'Mailbox list~~',
|
||||
'Class:OAuthClient/Attribute:mailbox_list+' => '~~',
|
||||
]);
|
||||
|
||||
//
|
||||
// Class: OAuthClientAzure
|
||||
//
|
||||
Dict::Add('CS CZ', 'Czech', 'Čeština', [
|
||||
'Class:OAuthClientAzure' => 'OAuth client for Microsoft Azure~~',
|
||||
'Class:OAuthClientAzure/Name' => '%1$s (%2$s)~~',
|
||||
|
||||
]);
|
||||
|
||||
//
|
||||
// Class: OAuthClientGoogle
|
||||
//
|
||||
Dict::Add('CS CZ', 'Czech', 'Čeština', [
|
||||
'Class:OAuthClientGoogle' => 'OAuth client for Google~~',
|
||||
'Class:OAuthClientGoogle/Name' => '%1$s (%2$s)~~',
|
||||
]);
|
||||
|
||||
@@ -0,0 +1,74 @@
|
||||
<?php
|
||||
/**
|
||||
* Localized data
|
||||
*
|
||||
* @copyright Copyright (C) 2013 XXXXX
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
Dict::Add('DA DA', 'Danish', 'Dansk', [
|
||||
'Menu:CreateMailbox' => 'Create a mailbox...~~',
|
||||
'Menu:OAuthClient' => 'OAuth Client~~',
|
||||
'Menu:OAuthClient+' => '~~',
|
||||
'Menu:GenerateTokens' => 'Generate access tokens...~~',
|
||||
'Menu:RegenerateTokens' => 'Regenerate access tokens...~~',
|
||||
|
||||
'itop-oauth-client/Operation:CreateMailBox/Title' => 'Mailbox creation~~',
|
||||
|
||||
'itop-oauth-client:UsedForSMTP' => 'This OAuth client is used for SMTP~~',
|
||||
'itop-oauth-client:TestSMTP' => 'Email send test~~',
|
||||
'itop-oauth-client:MissingOAuthClient' => 'Missing Oauth client for user name %1$s~~',
|
||||
'itop-oauth-client:Message:MissingToken' => 'Generate access token before using this OAuth client~~',
|
||||
'itop-oauth-client:Message:TokenCreated' => 'Access token created~~',
|
||||
'itop-oauth-client:Message:TokenRecreated' => 'Access token regenerated~~',
|
||||
]);
|
||||
|
||||
//
|
||||
// Class: OAuthClient
|
||||
//
|
||||
|
||||
Dict::Add('DA DA', 'Danish', 'Dansk', [
|
||||
'Class:OAuthClient' => 'Oauth Client~~',
|
||||
'Class:OAuthClient/Attribute:provider' => 'Provider~~',
|
||||
'Class:OAuthClient/Attribute:provider+' => '~~',
|
||||
'Class:OAuthClient/Attribute:name' => 'Login~~',
|
||||
'Class:OAuthClient/Attribute:name+' => '~~',
|
||||
'Class:OAuthClient/Attribute:scope' => 'Scope~~',
|
||||
'Class:OAuthClient/Attribute:scope+' => '~~',
|
||||
'Class:OAuthClient/Attribute:description' => 'Description~~',
|
||||
'Class:OAuthClient/Attribute:description+' => '~~',
|
||||
'Class:OAuthClient/Attribute:client_id' => 'Client id~~',
|
||||
'Class:OAuthClient/Attribute:client_id+' => '~~',
|
||||
'Class:OAuthClient/Attribute:client_secret' => 'Client secret~~',
|
||||
'Class:OAuthClient/Attribute:client_secret+' => '~~',
|
||||
'Class:OAuthClient/Attribute:refresh_token' => 'Refresh token~~',
|
||||
'Class:OAuthClient/Attribute:refresh_token+' => '~~',
|
||||
'Class:OAuthClient/Attribute:refresh_token_expiration' => 'Refresh token expiration~~',
|
||||
'Class:OAuthClient/Attribute:refresh_token_expiration+' => '~~',
|
||||
'Class:OAuthClient/Attribute:token' => 'Access token~~',
|
||||
'Class:OAuthClient/Attribute:token+' => '~~',
|
||||
'Class:OAuthClient/Attribute:token_expiration' => 'Access token expiration~~',
|
||||
'Class:OAuthClient/Attribute:token_expiration+' => '~~',
|
||||
'Class:OAuthClient/Attribute:redirect_url' => 'Redirect url~~',
|
||||
'Class:OAuthClient/Attribute:redirect_url+' => '~~',
|
||||
'Class:OAuthClient/Attribute:mailbox_list' => 'Mailbox list~~',
|
||||
'Class:OAuthClient/Attribute:mailbox_list+' => '~~',
|
||||
]);
|
||||
|
||||
//
|
||||
// Class: OAuthClientAzure
|
||||
//
|
||||
Dict::Add('DA DA', 'Danish', 'Dansk', [
|
||||
'Class:OAuthClientAzure' => 'OAuth client for Microsoft Azure~~',
|
||||
'Class:OAuthClientAzure/Name' => '%1$s (%2$s)~~',
|
||||
|
||||
]);
|
||||
|
||||
//
|
||||
// Class: OAuthClientGoogle
|
||||
//
|
||||
Dict::Add('DA DA', 'Danish', 'Dansk', [
|
||||
'Class:OAuthClientGoogle' => 'OAuth client for Google~~',
|
||||
'Class:OAuthClientGoogle/Name' => '%1$s (%2$s)~~',
|
||||
]);
|
||||
|
||||
891
datamodels/2.x/itop-oauth-client/datamodel.itop-oauth-client.xml
Normal file
891
datamodels/2.x/itop-oauth-client/datamodel.itop-oauth-client.xml
Normal file
@@ -0,0 +1,891 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<itop_design xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.7">
|
||||
<constants/>
|
||||
<classes>
|
||||
<class id="OAuthClient" _delta="define">
|
||||
<parent>cmdbAbstractObject</parent>
|
||||
<properties>
|
||||
<category>grant_by_profile,application</category>
|
||||
<abstract>true</abstract>
|
||||
<key_type>autoincrement</key_type>
|
||||
<db_table>priv_oauth_client</db_table>
|
||||
<db_key_field>id</db_key_field>
|
||||
<db_final_class_field/>
|
||||
<naming>
|
||||
<attributes>
|
||||
<attribute id="provider"/>
|
||||
<attribute id="name"/>
|
||||
</attributes>
|
||||
</naming>
|
||||
<display_template/>
|
||||
<icon/>
|
||||
<reconciliation>
|
||||
<attributes>
|
||||
<attribute id="provider"/>
|
||||
<attribute id="name"/>
|
||||
</attributes>
|
||||
</reconciliation>
|
||||
</properties>
|
||||
<fields>
|
||||
<field id="provider" xsi:type="AttributeString">
|
||||
<sql>provider</sql>
|
||||
<default_value/>
|
||||
<is_null_allowed>false</is_null_allowed>
|
||||
</field>
|
||||
<field id="name" xsi:type="AttributeString">
|
||||
<sql>name</sql>
|
||||
<default_value/>
|
||||
<is_null_allowed>false</is_null_allowed>
|
||||
</field>
|
||||
<field id="status" xsi:type="AttributeEnum">
|
||||
<always_load_in_tables>true</always_load_in_tables>
|
||||
<values>
|
||||
<value id="active">active</value>
|
||||
<value id="inactive">inactive</value>
|
||||
</values>
|
||||
<sql>status</sql>
|
||||
<default_value>inactive</default_value>
|
||||
<is_null_allowed>false</is_null_allowed>
|
||||
</field>
|
||||
<field id="description" xsi:type="AttributeText">
|
||||
<sql>description</sql>
|
||||
<default_value/>
|
||||
<is_null_allowed>true</is_null_allowed>
|
||||
</field>
|
||||
<field id="client_id" xsi:type="AttributeText">
|
||||
<sql>client_id</sql>
|
||||
<default_value/>
|
||||
<is_null_allowed>false</is_null_allowed>
|
||||
</field>
|
||||
<field id="client_secret" xsi:type="AttributeText">
|
||||
<sql>client_secret</sql>
|
||||
<default_value/>
|
||||
<is_null_allowed>false</is_null_allowed>
|
||||
</field>
|
||||
<field id="refresh_token" xsi:type="AttributeText">
|
||||
<sql>refresh_token</sql>
|
||||
<default_value/>
|
||||
<is_null_allowed>true</is_null_allowed>
|
||||
<tracking_level>none</tracking_level>
|
||||
</field>
|
||||
<field id="refresh_token_expiration" xsi:type="AttributeDateTime">
|
||||
<sql>refresh_token_expiration</sql>
|
||||
<default_value/>
|
||||
<is_null_allowed>true</is_null_allowed>
|
||||
<tracking_level>none</tracking_level>
|
||||
</field>
|
||||
<field id="token" xsi:type="AttributeText">
|
||||
<sql>token</sql>
|
||||
<default_value/>
|
||||
<is_null_allowed>true</is_null_allowed>
|
||||
<tracking_level>none</tracking_level>
|
||||
</field>
|
||||
<field id="token_expiration" xsi:type="AttributeDateTime">
|
||||
<sql>token_expiration</sql>
|
||||
<default_value/>
|
||||
<is_null_allowed>true</is_null_allowed>
|
||||
<tracking_level>none</tracking_level>
|
||||
</field>
|
||||
<field id="redirect_url" xsi:type="AttributeURL">
|
||||
<sql>redirect_url</sql>
|
||||
<default_value/>
|
||||
<target>_blank</target>
|
||||
<is_null_allowed>true</is_null_allowed>
|
||||
</field>
|
||||
<field id="mailbox_list" xsi:type="AttributeLinkedSet">
|
||||
<linked_class>MailInboxOAuth</linked_class>
|
||||
<ext_key_to_me>oauth_client_id</ext_key_to_me>
|
||||
<count_min>0</count_min>
|
||||
<count_max>0</count_max>
|
||||
</field>
|
||||
</fields>
|
||||
<methods>
|
||||
<method id="DisplayBareHeader">
|
||||
<static>false</static>
|
||||
<access>public</access>
|
||||
<type>Overload-DBObject</type>
|
||||
<code><![CDATA[
|
||||
public function DisplayBareHeader(WebPage $oPage, $bEditMode = false)
|
||||
{
|
||||
parent::DisplayBareHeader($oPage, $bEditMode);
|
||||
if (!$bEditMode) {
|
||||
$oConfig = utils::GetConfig();
|
||||
if ($this->Get('status') == 'inactive') {
|
||||
$oPage->p('<b>'.Dict::S('itop-oauth-client:Message:MissingToken').'</b>');
|
||||
} elseif ($this->Get('used_for_smtp') == 'yes' && $oConfig->Get('email_transport_smtp.username') == $this->Get('name')) {
|
||||
$sLabel = Dict::S('itop-oauth-client:UsedForSMTP');
|
||||
$sTestLabel = Dict::S('itop-oauth-client:TestSMTP');
|
||||
$sTestURL = utils::GetAbsoluteUrlAppRoot().'setup/email.test.php';
|
||||
$oPage->p("<b>$sLabel</b> <a href='$sTestURL' target='_blank'>$sTestLabel</a>");
|
||||
}
|
||||
}
|
||||
}
|
||||
]]></code>
|
||||
</method>
|
||||
<method id="GetAttributeFlags">
|
||||
<static>false</static>
|
||||
<access>public</access>
|
||||
<type>Overload-DBObject</type>
|
||||
<code><![CDATA[
|
||||
public function GetAttributeFlags($sAttCode, &$aReasons = array(), $sTargetState = '')
|
||||
{
|
||||
if ($sAttCode == 'status') {
|
||||
return OPT_ATT_READONLY;
|
||||
}
|
||||
|
||||
return parent::GetAttributeFlags($sAttCode, $aReasons, $sTargetState);
|
||||
}
|
||||
]]></code>
|
||||
</method>
|
||||
<method id="GetInitialStateAttributeFlags">
|
||||
<static>false</static>
|
||||
<access>public</access>
|
||||
<type>Overload-DBObject</type>
|
||||
<code><![CDATA[
|
||||
public function GetInitialStateAttributeFlags($sAttCode, &$aReasons = array())
|
||||
{
|
||||
if ($sAttCode == 'status') {
|
||||
return OPT_ATT_READONLY;
|
||||
}
|
||||
|
||||
return parent::GetInitialStateAttributeFlags($sAttCode, $aReasons);
|
||||
}
|
||||
]]></code>
|
||||
</method>
|
||||
<method id="GetDefaultMailServer">
|
||||
<static>false</static>
|
||||
<access>public</access>
|
||||
<code><![CDATA[
|
||||
public function GetDefaultMailServer()
|
||||
{
|
||||
return 'imap.'.$this->Get('provider').'.com';
|
||||
}
|
||||
]]></code>
|
||||
</method>
|
||||
<method id="GetDefaultMailServerPort">
|
||||
<static>false</static>
|
||||
<access>public</access>
|
||||
<code><![CDATA[
|
||||
public function GetDefaultMailServerPort()
|
||||
{
|
||||
return 993;
|
||||
}
|
||||
]]></code>
|
||||
</method>
|
||||
<method id="GetAccessToken">
|
||||
<static>false</static>
|
||||
<access>public</access>
|
||||
<code><![CDATA[
|
||||
public function GetAccessToken()
|
||||
{
|
||||
if ($this->Get('status') == 'active') {
|
||||
return new \League\OAuth2\Client\Token\AccessToken([
|
||||
'access_token' => $this->Get('token'),
|
||||
'expires_in' => date_format(new DateTime($this->Get('token_expiration')), 'U') - time(),
|
||||
'refresh_token' => $this->Get('refresh_token'),
|
||||
'token_type' => 'Bearer',
|
||||
]);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
]]></code>
|
||||
</method>
|
||||
<method id="SetAccessToken">
|
||||
<static>false</static>
|
||||
<access>public</access>
|
||||
<code><![CDATA[
|
||||
public function SetAccessToken(\League\OAuth2\Client\Token\AccessTokenInterface $oAccessToken)
|
||||
{
|
||||
$this->Set('token', $oAccessToken->getToken());
|
||||
$this->Set('token_expiration', date(AttributeDateTime::GetSQLFormat(), $oAccessToken->getExpires()));
|
||||
if (!empty($oAccessToken->getRefreshToken())) {
|
||||
$this->Set('refresh_token', $oAccessToken->getRefreshToken());
|
||||
}
|
||||
$this->Set('status', 'active');
|
||||
$this->DBUpdate();
|
||||
}
|
||||
]]></code>
|
||||
</method>
|
||||
</methods>
|
||||
<presentation>
|
||||
<details>
|
||||
<items>
|
||||
<item id="name">
|
||||
<rank>1</rank>
|
||||
</item>
|
||||
<item id="description">
|
||||
<rank>2</rank>
|
||||
</item>
|
||||
<item id="provider">
|
||||
<rank>3</rank>
|
||||
</item>
|
||||
<item id="redirect_url">
|
||||
<rank>5</rank>
|
||||
</item>
|
||||
<item id="client_id">
|
||||
<rank>6</rank>
|
||||
</item>
|
||||
<item id="client_secret">
|
||||
<rank>7</rank>
|
||||
</item>
|
||||
<item id="mailbox_list">
|
||||
<rank>8</rank>
|
||||
</item>
|
||||
</items>
|
||||
</details>
|
||||
<list>
|
||||
<items>
|
||||
<item id="status">
|
||||
<rank>1</rank>
|
||||
</item>
|
||||
<item id="provider">
|
||||
<rank>3</rank>
|
||||
</item>
|
||||
</items>
|
||||
</list>
|
||||
<search>
|
||||
<items>
|
||||
<item id="name">
|
||||
<rank>1</rank>
|
||||
</item>
|
||||
<item id="provider">
|
||||
<rank>2</rank>
|
||||
</item>
|
||||
</items>
|
||||
</search>
|
||||
<default_search>
|
||||
<items>
|
||||
<item id="name">
|
||||
<rank>1</rank>
|
||||
</item>
|
||||
<item id="provider">
|
||||
<rank>2</rank>
|
||||
</item>
|
||||
</items>
|
||||
</default_search>
|
||||
</presentation>
|
||||
</class>
|
||||
<class id="OAuthClientAzure" _delta="define">
|
||||
<parent>OAuthClient</parent>
|
||||
<properties>
|
||||
<category>grant_by_profile,application</category>
|
||||
<abstract>false</abstract>
|
||||
<key_type>autoincrement</key_type>
|
||||
<db_table>priv_oauth_client_azure</db_table>
|
||||
<db_key_field>id</db_key_field>
|
||||
<db_final_class_field/>
|
||||
<naming>
|
||||
<attributes>
|
||||
<attribute id="provider"/>
|
||||
<attribute id="name"/>
|
||||
</attributes>
|
||||
</naming>
|
||||
<display_template/>
|
||||
<icon/>
|
||||
<reconciliation>
|
||||
<attributes>
|
||||
<attribute id="provider"/>
|
||||
<attribute id="name"/>
|
||||
</attributes>
|
||||
</reconciliation>
|
||||
<uniqueness_rules>
|
||||
<rule id="server">
|
||||
<attributes>
|
||||
<attribute id="provider"/>
|
||||
<attribute id="client_id"/>
|
||||
<attribute id="client_secret"/>
|
||||
</attributes>
|
||||
<is_blocking>true</is_blocking>
|
||||
</rule>
|
||||
</uniqueness_rules>
|
||||
</properties>
|
||||
<fields>
|
||||
<field id="scope" xsi:type="AttributeEnumSet">
|
||||
<always_load_in_tables>true</always_load_in_tables>
|
||||
<values>
|
||||
<value id="SMTP">SMTP</value>
|
||||
<value id="IMAP">IMAP</value>
|
||||
</values>
|
||||
<sql>scope</sql>
|
||||
<default_value>SMTP,IMAP</default_value>
|
||||
<is_null_allowed>true</is_null_allowed>
|
||||
</field>
|
||||
<field id="advanced_scope" xsi:type="AttributeString">
|
||||
<sql>advanced_scope</sql>
|
||||
<default_value/>
|
||||
<is_null_allowed>true</is_null_allowed>
|
||||
</field>
|
||||
<field id="used_scope" xsi:type="AttributeEnum">
|
||||
<always_load_in_tables>true</always_load_in_tables>
|
||||
<values>
|
||||
<value id="simple">simple</value>
|
||||
<value id="advanced">advanced</value>
|
||||
</values>
|
||||
<sql>used_scope</sql>
|
||||
<default_value>simple</default_value>
|
||||
<is_null_allowed>false</is_null_allowed>
|
||||
<dependencies>
|
||||
<attribute id="scope"/>
|
||||
<attribute id="advanced_scope"/>
|
||||
</dependencies>
|
||||
</field>
|
||||
<field id="used_for_smtp" xsi:type="AttributeEnum">
|
||||
<always_load_in_tables>true</always_load_in_tables>
|
||||
<values>
|
||||
<value id="yes">yes</value>
|
||||
<value id="no">no</value>
|
||||
</values>
|
||||
<sql>used_for_smtp</sql>
|
||||
<default_value>no</default_value>
|
||||
<is_null_allowed>true</is_null_allowed>
|
||||
</field>
|
||||
</fields>
|
||||
<presentation>
|
||||
<details>
|
||||
<items>
|
||||
<item id="col:col1">
|
||||
<rank>10</rank>
|
||||
<items>
|
||||
<item id="fieldset:OAuthClient:baseinfo">
|
||||
<rank>10</rank>
|
||||
<items>
|
||||
<item id="name">
|
||||
<rank>10</rank>
|
||||
</item>
|
||||
<item id="status">
|
||||
<rank>20</rank>
|
||||
</item>
|
||||
<item id="description">
|
||||
<rank>30</rank>
|
||||
</item>
|
||||
<item id="provider">
|
||||
<rank>40</rank>
|
||||
</item>
|
||||
<item id="redirect_url">
|
||||
<rank>50</rank>
|
||||
</item>
|
||||
<item id="client_id">
|
||||
<rank>60</rank>
|
||||
</item>
|
||||
<item id="client_secret">
|
||||
<rank>70</rank>
|
||||
</item>
|
||||
<item id="mailbox_list">
|
||||
<rank>80</rank>
|
||||
</item>
|
||||
</items>
|
||||
</item>
|
||||
</items>
|
||||
</item>
|
||||
<item id="col:col2">
|
||||
<rank>20</rank>
|
||||
<items>
|
||||
<item id="fieldset:OAuthClient:scope">
|
||||
<rank>10</rank>
|
||||
<items>
|
||||
<item id="used_scope">
|
||||
<rank>10</rank>
|
||||
</item>
|
||||
<item id="scope">
|
||||
<rank>20</rank>
|
||||
</item>
|
||||
<item id="advanced_scope">
|
||||
<rank>30</rank>
|
||||
</item>
|
||||
<item id="used_for_smtp">
|
||||
<rank>40</rank>
|
||||
</item>
|
||||
</items>
|
||||
</item>
|
||||
</items>
|
||||
</item>
|
||||
</items>
|
||||
</details>
|
||||
<list>
|
||||
<items>
|
||||
<item id="provider">
|
||||
<rank>10</rank>
|
||||
</item>
|
||||
<item id="status">
|
||||
<rank>10</rank>
|
||||
</item>
|
||||
</items>
|
||||
</list>
|
||||
<standard_search>
|
||||
<items>
|
||||
<item id="name">
|
||||
<rank>10</rank>
|
||||
</item>
|
||||
<item id="provider">
|
||||
<rank>10</rank>
|
||||
</item>
|
||||
<item id="status">
|
||||
<rank>10</rank>
|
||||
</item>
|
||||
</items>
|
||||
</standard_search>
|
||||
</presentation>
|
||||
<methods>
|
||||
<method id="PrefillCreationForm">
|
||||
<static>false</static>
|
||||
<access>public</access>
|
||||
<type>Overload-DBObject</type>
|
||||
<code><![CDATA[
|
||||
public function PrefillCreationForm(&$aContextParam)
|
||||
{
|
||||
$this->Set('provider', 'Azure');
|
||||
$this->Set('redirect_url', Combodo\iTop\Core\Authentication\Client\OAuth\OAuthClientProviderFactory::GetRedirectUri());
|
||||
$this->Set('scope', 'SMTP, IMAP');
|
||||
|
||||
parent::PrefillCreationForm($aContextParam);
|
||||
}
|
||||
]]></code>
|
||||
</method>
|
||||
<method id="DoCheckToWrite">
|
||||
<static>false</static>
|
||||
<access>public</access>
|
||||
<type>Overload-DBObject</type>
|
||||
<code><![CDATA[ public function DoCheckToWrite()
|
||||
{
|
||||
parent::DoCheckToWrite();
|
||||
|
||||
$aChanges = $this->ListChanges();
|
||||
if (array_key_exists('name', $aChanges) || array_key_exists('used_for_smtp', $aChanges))
|
||||
{
|
||||
$sNewName = $this->Get('name');
|
||||
$sNewUseForSMTP = $this->Get('used_for_smtp');
|
||||
if ($sNewUseForSMTP == 'yes') {
|
||||
$oSearch = DBObjectSearch::FromOQL_AllData("SELECT OAuthClientGoogle WHERE name = :newname AND used_for_smtp = :newuseforsmtp AND id != :id UNION SELECT OAuthClientAzure WHERE name = :newname AND used_for_smtp = :newuseforsmtp AND id != :id");
|
||||
$oSet = new DBObjectSet($oSearch, array(), ['id' => $this->GetKey(), 'newname' => $sNewName, 'newuseforsmtp' => $sNewUseForSMTP]);
|
||||
if ($oSet->Count() > 0)
|
||||
{
|
||||
$this->m_aCheckIssues[] = Dict::Format('OAuthClient:Name/UseForSMTPMustBeUnique', $sNewName, $sNewUseForSMTP);
|
||||
}
|
||||
}
|
||||
}
|
||||
} ]]></code>
|
||||
</method>
|
||||
<method id="ComputeValues">
|
||||
<static>false</static>
|
||||
<access>public</access>
|
||||
<type>Overload-DBObject</type>
|
||||
<code><![CDATA[
|
||||
public function ComputeValues()
|
||||
{
|
||||
parent::ComputeValues();
|
||||
if (empty($this->Get('provider'))) {
|
||||
$this->Set('provider', 'Azure');
|
||||
}
|
||||
if (empty($this->Get('redirect_url'))) {
|
||||
$this->Set('redirect_url', Combodo\iTop\Core\Authentication\Client\OAuth\OAuthClientProviderFactory::GetRedirectUri());
|
||||
}
|
||||
if (empty($this->Get('advanced_scope'))) {
|
||||
$this->Set('used_scope', 'simple');
|
||||
if (count($this->Get('scope')->GetValues()) == 0) {
|
||||
$this->Set('scope', 'SMTP, IMAP');
|
||||
}
|
||||
} else {
|
||||
$this->Set('used_scope', 'advanced');
|
||||
$this->Set('scope', '');
|
||||
}
|
||||
}
|
||||
]]></code>
|
||||
</method>
|
||||
<method id="GetAttributeFlags">
|
||||
<static>false</static>
|
||||
<access>public</access>
|
||||
<type>Overload-DBObject</type>
|
||||
<code><![CDATA[
|
||||
public function GetAttributeFlags($sAttCode, &$aReasons = array(), $sTargetState = '')
|
||||
{
|
||||
switch ($sAttCode) {
|
||||
case 'provider':
|
||||
case 'redirect_url':
|
||||
case 'used_scope':
|
||||
return OPT_ATT_READONLY;
|
||||
}
|
||||
|
||||
return parent::GetAttributeFlags($sAttCode, $aReasons, $sTargetState);
|
||||
}
|
||||
]]></code>
|
||||
</method>
|
||||
<method id="GetInitialStateAttributeFlags">
|
||||
<static>false</static>
|
||||
<access>public</access>
|
||||
<type>Overload-DBObject</type>
|
||||
<code><![CDATA[
|
||||
public function GetInitialStateAttributeFlags($sAttCode, &$aReasons = array())
|
||||
{
|
||||
switch ($sAttCode) {
|
||||
case 'provider':
|
||||
case 'redirect_url':
|
||||
case 'used_scope':
|
||||
return OPT_ATT_READONLY;
|
||||
}
|
||||
|
||||
return parent::GetInitialStateAttributeFlags($sAttCode, $aReasons);
|
||||
}
|
||||
]]></code>
|
||||
</method>
|
||||
<method id="GetDefaultMailServer">
|
||||
<static>false</static>
|
||||
<access>public</access>
|
||||
<code><![CDATA[
|
||||
public function GetDefaultMailServer()
|
||||
{
|
||||
return 'outlook.office365.com';
|
||||
}
|
||||
]]></code>
|
||||
</method>
|
||||
<method id="GetScope">
|
||||
<static>false</static>
|
||||
<access>public</access>
|
||||
<code><![CDATA[
|
||||
public function GetScope()
|
||||
{
|
||||
if (!empty($this->Get('advanced_scope'))) {
|
||||
return $this->Get('advanced_scope');
|
||||
}
|
||||
$aScopes = $this->Get('scope')->GetValues();
|
||||
$aRawScopes = ['offline_access'];
|
||||
foreach ($aScopes as $sScope) {
|
||||
switch ($sScope) {
|
||||
case 'SMTP':
|
||||
$aRawScopes[] = 'https://outlook.office.com/SMTP.Send';
|
||||
break;
|
||||
|
||||
case 'IMAP':
|
||||
$aRawScopes[] = 'https://outlook.office.com/IMAP.AccessAsUser.All';
|
||||
break;
|
||||
}
|
||||
}
|
||||
return implode(' ', $aRawScopes);
|
||||
}
|
||||
]]></code>
|
||||
</method>
|
||||
</methods>
|
||||
</class>
|
||||
<class id="OAuthClientGoogle" _delta="define">
|
||||
<parent>OAuthClient</parent>
|
||||
<properties>
|
||||
<category>grant_by_profile,application</category>
|
||||
<abstract>false</abstract>
|
||||
<key_type>autoincrement</key_type>
|
||||
<db_table>priv_oauth_client_google</db_table>
|
||||
<db_key_field>id</db_key_field>
|
||||
<db_final_class_field/>
|
||||
<naming>
|
||||
<attributes>
|
||||
<attribute id="provider"/>
|
||||
<attribute id="name"/>
|
||||
</attributes>
|
||||
</naming>
|
||||
<display_template/>
|
||||
<icon/>
|
||||
<reconciliation>
|
||||
<attributes>
|
||||
<attribute id="provider"/>
|
||||
<attribute id="name"/>
|
||||
</attributes>
|
||||
</reconciliation>
|
||||
<uniqueness_rules>
|
||||
<rule id="server">
|
||||
<attributes>
|
||||
<attribute id="provider"/>
|
||||
<attribute id="client_id"/>
|
||||
<attribute id="client_secret"/>
|
||||
</attributes>
|
||||
<is_blocking>true</is_blocking>
|
||||
</rule>
|
||||
</uniqueness_rules>
|
||||
</properties>
|
||||
<fields>
|
||||
<field id="scope" xsi:type="AttributeEnumSet">
|
||||
<always_load_in_tables>true</always_load_in_tables>
|
||||
<values>
|
||||
<value id="SMTP">SMTP</value>
|
||||
<value id="IMAP">IMAP</value>
|
||||
</values>
|
||||
<sql>scope</sql>
|
||||
<default_value>SMTP,IMAP</default_value>
|
||||
<is_null_allowed>true</is_null_allowed>
|
||||
</field>
|
||||
<field id="advanced_scope" xsi:type="AttributeString">
|
||||
<sql>advanced_scope</sql>
|
||||
<default_value/>
|
||||
<is_null_allowed>true</is_null_allowed>
|
||||
</field>
|
||||
<field id="used_scope" xsi:type="AttributeEnum">
|
||||
<always_load_in_tables>true</always_load_in_tables>
|
||||
<values>
|
||||
<value id="simple">simple</value>
|
||||
<value id="advanced">advanced</value>
|
||||
</values>
|
||||
<sql>used_scope</sql>
|
||||
<default_value>simple</default_value>
|
||||
<is_null_allowed>false</is_null_allowed>
|
||||
<dependencies>
|
||||
<attribute id="scope"/>
|
||||
<attribute id="advanced_scope"/>
|
||||
</dependencies>
|
||||
</field>
|
||||
<field id="used_for_smtp" xsi:type="AttributeEnum">
|
||||
<always_load_in_tables>true</always_load_in_tables>
|
||||
<values>
|
||||
<value id="yes">yes</value>
|
||||
<value id="no">no</value>
|
||||
</values>
|
||||
<sql>used_for_smtp</sql>
|
||||
<default_value>no</default_value>
|
||||
<is_null_allowed>true</is_null_allowed>
|
||||
</field>
|
||||
</fields>
|
||||
<presentation>
|
||||
<details>
|
||||
<items>
|
||||
<item id="col:col1">
|
||||
<rank>10</rank>
|
||||
<items>
|
||||
<item id="fieldset:OAuthClient:baseinfo">
|
||||
<rank>10</rank>
|
||||
<items>
|
||||
<item id="name">
|
||||
<rank>10</rank>
|
||||
</item>
|
||||
<item id="status">
|
||||
<rank>20</rank>
|
||||
</item>
|
||||
<item id="description">
|
||||
<rank>30</rank>
|
||||
</item>
|
||||
<item id="provider">
|
||||
<rank>40</rank>
|
||||
</item>
|
||||
<item id="redirect_url">
|
||||
<rank>50</rank>
|
||||
</item>
|
||||
<item id="client_id">
|
||||
<rank>60</rank>
|
||||
</item>
|
||||
<item id="client_secret">
|
||||
<rank>70</rank>
|
||||
</item>
|
||||
<item id="mailbox_list">
|
||||
<rank>80</rank>
|
||||
</item>
|
||||
</items>
|
||||
</item>
|
||||
</items>
|
||||
</item>
|
||||
<item id="col:col2">
|
||||
<rank>20</rank>
|
||||
<items>
|
||||
<item id="fieldset:OAuthClient:scope">
|
||||
<rank>10</rank>
|
||||
<items>
|
||||
<item id="used_scope">
|
||||
<rank>10</rank>
|
||||
</item>
|
||||
<item id="scope">
|
||||
<rank>20</rank>
|
||||
</item>
|
||||
<item id="advanced_scope">
|
||||
<rank>30</rank>
|
||||
</item>
|
||||
<item id="used_for_smtp">
|
||||
<rank>40</rank>
|
||||
</item>
|
||||
</items>
|
||||
</item>
|
||||
</items>
|
||||
</item>
|
||||
</items>
|
||||
</details>
|
||||
<list>
|
||||
<items>
|
||||
<item id="provider">
|
||||
<rank>10</rank>
|
||||
</item>
|
||||
<item id="status">
|
||||
<rank>10</rank>
|
||||
</item>
|
||||
</items>
|
||||
</list>
|
||||
<standard_search>
|
||||
<items>
|
||||
<item id="name">
|
||||
<rank>10</rank>
|
||||
</item>
|
||||
<item id="provider">
|
||||
<rank>10</rank>
|
||||
</item>
|
||||
<item id="status">
|
||||
<rank>10</rank>
|
||||
</item>
|
||||
</items>
|
||||
</standard_search>
|
||||
</presentation>
|
||||
<methods>
|
||||
<method id="PrefillCreationForm">
|
||||
<static>false</static>
|
||||
<access>public</access>
|
||||
<type>Overload-DBObject</type>
|
||||
<code><![CDATA[
|
||||
public function PrefillCreationForm(&$aContextParam)
|
||||
{
|
||||
$this->Set('provider', 'Google');
|
||||
$this->Set('redirect_url', Combodo\iTop\Core\Authentication\Client\OAuth\OAuthClientProviderFactory::GetRedirectUri());
|
||||
$this->Set('scope', 'SMTP, IMAP');
|
||||
|
||||
parent::PrefillCreationForm($aContextParam);
|
||||
}
|
||||
]]></code>
|
||||
</method>
|
||||
<method id="DoCheckToWrite">
|
||||
<static>false</static>
|
||||
<access>public</access>
|
||||
<type>Overload-DBObject</type>
|
||||
<code><![CDATA[ public function DoCheckToWrite()
|
||||
{
|
||||
parent::DoCheckToWrite();
|
||||
|
||||
$aChanges = $this->ListChanges();
|
||||
if (array_key_exists('name', $aChanges) || array_key_exists('used_for_smtp', $aChanges))
|
||||
{
|
||||
$sNewName = $this->Get('name');
|
||||
$sNewUseForSMTP = $this->Get('used_for_smtp');
|
||||
if ($sNewUseForSMTP == 'yes') {
|
||||
$oSearch = DBObjectSearch::FromOQL_AllData("SELECT OAuthClientGoogle WHERE name = :newname AND used_for_smtp = :newuseforsmtp AND id != :id UNION SELECT OAuthClientAzure WHERE name = :newname AND used_for_smtp = :newuseforsmtp AND id != :id");
|
||||
$oSet = new DBObjectSet($oSearch, array(), ['id' => $this->GetKey(), 'newname' => $sNewName, 'newuseforsmtp' => $sNewUseForSMTP]);
|
||||
if ($oSet->Count() > 0)
|
||||
{
|
||||
$this->m_aCheckIssues[] = Dict::Format('OAuthClient:Name/UseForSMTPMustBeUnique', $sNewName, $sNewUseForSMTP);
|
||||
}
|
||||
}
|
||||
}
|
||||
} ]]></code>
|
||||
</method>
|
||||
<method id="ComputeValues">
|
||||
<static>false</static>
|
||||
<access>public</access>
|
||||
<type>Overload-DBObject</type>
|
||||
<code><![CDATA[
|
||||
public function ComputeValues()
|
||||
{
|
||||
parent::ComputeValues();
|
||||
if (empty($this->Get('provider'))) {
|
||||
$this->Set('provider', 'Google');
|
||||
}
|
||||
if (empty($this->Get('redirect_url'))) {
|
||||
$this->Set('redirect_url', Combodo\iTop\Core\Authentication\Client\OAuth\OAuthClientProviderFactory::GetRedirectUri());
|
||||
}
|
||||
if (empty($this->Get('advanced_scope'))) {
|
||||
$this->Set('used_scope', 'simple');
|
||||
if (count($this->Get('scope')->GetValues()) == 0) {
|
||||
$this->Set('scope', 'SMTP, IMAP');
|
||||
}
|
||||
} else {
|
||||
$this->Set('used_scope', 'advanced');
|
||||
$this->Set('scope', '');
|
||||
}
|
||||
}
|
||||
]]></code>
|
||||
</method>
|
||||
<method id="GetAttributeFlags">
|
||||
<static>false</static>
|
||||
<access>public</access>
|
||||
<type>Overload-DBObject</type>
|
||||
<code><![CDATA[
|
||||
public function GetAttributeFlags($sAttCode, &$aReasons = array(), $sTargetState = '')
|
||||
{
|
||||
switch ($sAttCode) {
|
||||
case 'provider':
|
||||
case 'redirect_url':
|
||||
case 'used_scope':
|
||||
return OPT_ATT_READONLY;
|
||||
}
|
||||
|
||||
return parent::GetAttributeFlags($sAttCode, $aReasons, $sTargetState);
|
||||
}
|
||||
]]></code>
|
||||
</method>
|
||||
<method id="GetInitialStateAttributeFlags">
|
||||
<static>false</static>
|
||||
<access>public</access>
|
||||
<type>Overload-DBObject</type>
|
||||
<code><![CDATA[
|
||||
public function GetInitialStateAttributeFlags($sAttCode, &$aReasons = array())
|
||||
{
|
||||
switch ($sAttCode) {
|
||||
case 'provider':
|
||||
case 'redirect_url':
|
||||
case 'used_scope':
|
||||
return OPT_ATT_READONLY;
|
||||
}
|
||||
|
||||
return parent::GetInitialStateAttributeFlags($sAttCode, $aReasons);
|
||||
}
|
||||
]]></code>
|
||||
</method>
|
||||
<method id="GetDefaultMailServer">
|
||||
<static>false</static>
|
||||
<access>public</access>
|
||||
<code><![CDATA[
|
||||
public function GetDefaultMailServer()
|
||||
{
|
||||
return 'imap.gmail.com';
|
||||
}
|
||||
]]></code>
|
||||
</method>
|
||||
<method id="GetScope">
|
||||
<static>false</static>
|
||||
<access>public</access>
|
||||
<code><![CDATA[
|
||||
public function GetScope()
|
||||
{
|
||||
if (!empty($this->Get('advanced_scope'))) {
|
||||
return $this->Get('advanced_scope');
|
||||
}
|
||||
$aScopes = $this->Get('scope')->GetValues();
|
||||
$aRawScopes = [];
|
||||
foreach ($aScopes as $sScope) {
|
||||
switch ($sScope) {
|
||||
case 'SMTP':
|
||||
$aRawScopes['https://mail.google.com/'] = 'https://mail.google.com/';
|
||||
break;
|
||||
|
||||
case 'IMAP':
|
||||
$aRawScopes['https://mail.google.com/'] = 'https://mail.google.com/';
|
||||
break;
|
||||
}
|
||||
}
|
||||
return implode(' ', $aRawScopes);
|
||||
}
|
||||
]]></code>
|
||||
</method>
|
||||
</methods>
|
||||
</class>
|
||||
</classes>
|
||||
<menus>
|
||||
<menu id="OAuthClient" xsi:type="OQLMenuNode" _delta="define">
|
||||
<rank>100</rank>
|
||||
<parent>ConfigurationTools</parent>
|
||||
<oql><![CDATA[SELECT OAuthClient]]></oql>
|
||||
<do_search>1</do_search>
|
||||
<enable_admin_only>0</enable_admin_only>
|
||||
<enable_class>OAuthClient</enable_class>
|
||||
<enable_action>UR_ACTION_MODIFY</enable_action>
|
||||
</menu>
|
||||
</menus>
|
||||
<user_rights>
|
||||
<groups>
|
||||
<group id="OauthConnection" _delta="define">
|
||||
<classes>
|
||||
<class id="OAuthClient"/>
|
||||
</classes>
|
||||
</group>
|
||||
</groups>
|
||||
<profiles>
|
||||
</profiles>
|
||||
</user_rights>
|
||||
</itop_design>
|
||||
@@ -0,0 +1,74 @@
|
||||
<?php
|
||||
/**
|
||||
* Localized data
|
||||
*
|
||||
* @copyright Copyright (C) 2013 XXXXX
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
Dict::Add('DE DE', 'German', 'Deutsch', [
|
||||
'Menu:CreateMailbox' => 'Create a mailbox...~~',
|
||||
'Menu:OAuthClient' => 'OAuth Client~~',
|
||||
'Menu:OAuthClient+' => '~~',
|
||||
'Menu:GenerateTokens' => 'Generate access token...~~',
|
||||
'Menu:RegenerateTokens' => 'Regenerate access token...~~',
|
||||
|
||||
'itop-oauth-client/Operation:CreateMailBox/Title' => 'Mailbox creation~~',
|
||||
|
||||
'itop-oauth-client:UsedForSMTP' => 'This OAuth client is used for SMTP~~',
|
||||
'itop-oauth-client:TestSMTP' => 'Email send test~~',
|
||||
'itop-oauth-client:MissingOAuthClient' => 'Missing Oauth client for user name %1$s~~',
|
||||
'itop-oauth-client:Message:MissingToken' => 'Generate access token before using this OAuth client~~',
|
||||
'itop-oauth-client:Message:TokenCreated' => 'Access token created~~',
|
||||
'itop-oauth-client:Message:TokenRecreated' => 'Access token regenerated~~',
|
||||
]);
|
||||
|
||||
//
|
||||
// Class: OAuthClient
|
||||
//
|
||||
|
||||
Dict::Add('DE DE', 'German', 'Deutsch', [
|
||||
'Class:OAuthClient' => 'Oauth Client~~',
|
||||
'Class:OAuthClient/Attribute:provider' => 'Provider~~',
|
||||
'Class:OAuthClient/Attribute:provider+' => '~~',
|
||||
'Class:OAuthClient/Attribute:name' => 'Login~~',
|
||||
'Class:OAuthClient/Attribute:name+' => '~~',
|
||||
'Class:OAuthClient/Attribute:scope' => 'Scope~~',
|
||||
'Class:OAuthClient/Attribute:scope+' => '~~',
|
||||
'Class:OAuthClient/Attribute:description' => 'Description~~',
|
||||
'Class:OAuthClient/Attribute:description+' => '~~',
|
||||
'Class:OAuthClient/Attribute:client_id' => 'Client id~~',
|
||||
'Class:OAuthClient/Attribute:client_id+' => '~~',
|
||||
'Class:OAuthClient/Attribute:client_secret' => 'Client secret~~',
|
||||
'Class:OAuthClient/Attribute:client_secret+' => '~~',
|
||||
'Class:OAuthClient/Attribute:refresh_token' => 'Refresh token~~',
|
||||
'Class:OAuthClient/Attribute:refresh_token+' => '~~',
|
||||
'Class:OAuthClient/Attribute:refresh_token_expiration' => 'Refresh token expiration~~',
|
||||
'Class:OAuthClient/Attribute:refresh_token_expiration+' => '~~',
|
||||
'Class:OAuthClient/Attribute:token' => 'Access token~~',
|
||||
'Class:OAuthClient/Attribute:token+' => '~~',
|
||||
'Class:OAuthClient/Attribute:token_expiration' => 'Access token expiration~~',
|
||||
'Class:OAuthClient/Attribute:token_expiration+' => '~~',
|
||||
'Class:OAuthClient/Attribute:redirect_url' => 'Redirect url~~',
|
||||
'Class:OAuthClient/Attribute:redirect_url+' => '~~',
|
||||
'Class:OAuthClient/Attribute:mailbox_list' => 'Mailbox list~~',
|
||||
'Class:OAuthClient/Attribute:mailbox_list+' => '~~',
|
||||
]);
|
||||
|
||||
//
|
||||
// Class: OAuthClientAzure
|
||||
//
|
||||
Dict::Add('DE DE', 'German', 'Deutsch', [
|
||||
'Class:OAuthClientAzure' => 'OAuth client for Microsoft Azure~~',
|
||||
'Class:OAuthClientAzure/Name' => '%1$s (%2$s)~~',
|
||||
|
||||
]);
|
||||
|
||||
//
|
||||
// Class: OAuthClientGoogle
|
||||
//
|
||||
Dict::Add('DE DE', 'German', 'Deutsch', [
|
||||
'Class:OAuthClientGoogle' => 'OAuth client for Google~~',
|
||||
'Class:OAuthClientGoogle/Name' => '%1$s (%2$s)~~',
|
||||
]);
|
||||
|
||||
117
datamodels/2.x/itop-oauth-client/en.dict.itop-oauth-client.php
Normal file
117
datamodels/2.x/itop-oauth-client/en.dict.itop-oauth-client.php
Normal file
@@ -0,0 +1,117 @@
|
||||
<?php
|
||||
/**
|
||||
* Localized data
|
||||
*
|
||||
* @copyright Copyright (C) 2013 XXXXX
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
Dict::Add('EN US', 'English', 'English', [
|
||||
'Menu:CreateMailbox' => 'Create a mailbox...',
|
||||
'Menu:OAuthClient' => 'OAuth Client',
|
||||
'Menu:OAuthClient+' => '',
|
||||
'Menu:GenerateTokens' => 'Generate access token...',
|
||||
'Menu:RegenerateTokens' => 'Regenerate access token...',
|
||||
|
||||
'itop-oauth-client/Operation:CreateMailBox/Title' => 'Mailbox creation',
|
||||
|
||||
'itop-oauth-client:UsedForSMTP' => 'This OAuth client is used for SMTP',
|
||||
'itop-oauth-client:TestSMTP' => 'Email send test',
|
||||
'itop-oauth-client:MissingOAuthClient' => 'Missing Oauth client for user name %1$s',
|
||||
'itop-oauth-client:Message:MissingToken' => 'Generate access token before using this OAuth client',
|
||||
'itop-oauth-client:Message:TokenCreated' => 'Access token created',
|
||||
'itop-oauth-client:Message:TokenRecreated' => 'Access token regenerated',
|
||||
|
||||
'OAuthClient:Name/UseForSMTPMustBeUnique' => 'The combination Login (%1$s) and Use for SMTP (%2$s) has already be used for OAuth Client',
|
||||
|
||||
'OAuthClient:baseinfo' => 'Base Information',
|
||||
'OAuthClient:scope' => 'Scope',
|
||||
]);
|
||||
|
||||
//
|
||||
// Class: OAuthClient
|
||||
//
|
||||
|
||||
Dict::Add('EN US', 'English', 'English', [
|
||||
'Class:OAuthClient' => 'Oauth Client',
|
||||
'Class:OAuthClient/Attribute:provider' => 'Provider',
|
||||
'Class:OAuthClient/Attribute:provider+' => '',
|
||||
'Class:OAuthClient/Attribute:name' => 'Login',
|
||||
'Class:OAuthClient/Attribute:name+' => 'In general, this is your email address',
|
||||
'Class:OAuthClient/Attribute:status' => 'Status',
|
||||
'Class:OAuthClient/Attribute:status+' => 'After creation, use the action “Generate access token” to be able to use this OAuth client',
|
||||
'Class:OAuthClient/Attribute:status/Value:active' => 'Access token generated',
|
||||
'Class:OAuthClient/Attribute:status/Value:inactive' => 'No Access token',
|
||||
'Class:OAuthClient/Attribute:description' => 'Description',
|
||||
'Class:OAuthClient/Attribute:description+' => '',
|
||||
'Class:OAuthClient/Attribute:client_id' => 'Client id',
|
||||
'Class:OAuthClient/Attribute:client_id+' => 'A long string of characters provided by your OAuth2 provider',
|
||||
'Class:OAuthClient/Attribute:client_secret' => 'Client secret',
|
||||
'Class:OAuthClient/Attribute:client_secret+' => 'Another long string of characters provided by your OAuth2 provider',
|
||||
'Class:OAuthClient/Attribute:refresh_token' => 'Refresh token',
|
||||
'Class:OAuthClient/Attribute:refresh_token+' => '',
|
||||
'Class:OAuthClient/Attribute:refresh_token_expiration' => 'Refresh token expiration',
|
||||
'Class:OAuthClient/Attribute:refresh_token_expiration+' => '',
|
||||
'Class:OAuthClient/Attribute:token' => 'Access token',
|
||||
'Class:OAuthClient/Attribute:token+' => '',
|
||||
'Class:OAuthClient/Attribute:token_expiration' => 'Access token expiration',
|
||||
'Class:OAuthClient/Attribute:token_expiration+' => '',
|
||||
'Class:OAuthClient/Attribute:redirect_url' => 'Redirect url',
|
||||
'Class:OAuthClient/Attribute:redirect_url+' => 'This url must be copied in the OAuth2 configuration of the provider',
|
||||
'Class:OAuthClient/Attribute:mailbox_list' => 'Mailbox list',
|
||||
'Class:OAuthClient/Attribute:mailbox_list+' => '',
|
||||
]);
|
||||
|
||||
//
|
||||
// Class: OAuthClientAzure
|
||||
//
|
||||
|
||||
Dict::Add('EN US', 'English', 'English', array(
|
||||
'Class:OAuthClientAzure' => 'OAuth client for Microsoft Azure',
|
||||
'Class:OAuthClientAzure/Name' => '%1$s (%2$s)',
|
||||
'Class:OAuthClientAzure/Attribute:scope' => 'Scope',
|
||||
'Class:OAuthClientAzure/Attribute:scope+' => 'Usually default selection is appropriate',
|
||||
'Class:OAuthClientAzure/Attribute:scope/Value:SMTP' => 'SMTP',
|
||||
'Class:OAuthClientAzure/Attribute:scope/Value:SMTP+' => '',
|
||||
'Class:OAuthClientAzure/Attribute:scope/Value:IMAP' => 'IMAP',
|
||||
'Class:OAuthClientAzure/Attribute:scope/Value:IMAP+' => '',
|
||||
'Class:OAuthClientAzure/Attribute:advanced_scope' => 'Advanced scope',
|
||||
'Class:OAuthClientAzure/Attribute:advanced_scope+' => 'As soon as you enter something here it takes precedence on the “Scope” selection which is then ignored',
|
||||
'Class:OAuthClientAzure/Attribute:used_scope' => 'Used scope',
|
||||
'Class:OAuthClientAzure/Attribute:used_scope+' => '',
|
||||
'Class:OAuthClientAzure/Attribute:used_scope/Value:simple' => 'Simple',
|
||||
'Class:OAuthClientAzure/Attribute:used_scope/Value:simple+' => '',
|
||||
'Class:OAuthClientAzure/Attribute:used_scope/Value:advanced' => 'Advanced',
|
||||
'Class:OAuthClientAzure/Attribute:used_scope/Value:advanced+' => '',
|
||||
'Class:OAuthClientAzure/Attribute:used_for_smtp' => 'Used for SMTP',
|
||||
'Class:OAuthClientAzure/Attribute:used_for_smtp+' => 'At least one OAuth client must have this flag to “Yes”, if you want iTop to use it for sending mails',
|
||||
'Class:OAuthClientAzure/Attribute:used_for_smtp/Value:yes' => 'Yes',
|
||||
'Class:OAuthClientAzure/Attribute:used_for_smtp/Value:no' => 'No',
|
||||
));
|
||||
|
||||
//
|
||||
// Class: OAuthClientGoogle
|
||||
//
|
||||
|
||||
Dict::Add('EN US', 'English', 'English', array(
|
||||
'Class:OAuthClientGoogle' => 'OAuth client for Google',
|
||||
'Class:OAuthClientGoogle/Name' => '%1$s (%2$s)',
|
||||
'Class:OAuthClientGoogle/Attribute:scope' => 'Scope',
|
||||
'Class:OAuthClientGoogle/Attribute:scope+' => 'Usually default selection is appropriate',
|
||||
'Class:OAuthClientGoogle/Attribute:scope/Value:SMTP' => 'SMTP',
|
||||
'Class:OAuthClientGoogle/Attribute:scope/Value:SMTP+' => '',
|
||||
'Class:OAuthClientGoogle/Attribute:scope/Value:IMAP' => 'IMAP',
|
||||
'Class:OAuthClientGoogle/Attribute:scope/Value:IMAP+' => '',
|
||||
'Class:OAuthClientGoogle/Attribute:advanced_scope' => 'Advanced scope',
|
||||
'Class:OAuthClientGoogle/Attribute:advanced_scope+' => 'As soon as you enter something here it takes precedence on the “Scope” selection which is then ignored',
|
||||
'Class:OAuthClientGoogle/Attribute:used_scope' => 'Used scope',
|
||||
'Class:OAuthClientGoogle/Attribute:used_scope+' => '',
|
||||
'Class:OAuthClientGoogle/Attribute:used_scope/Value:simple' => 'Simple',
|
||||
'Class:OAuthClientGoogle/Attribute:used_scope/Value:simple+' => '',
|
||||
'Class:OAuthClientGoogle/Attribute:used_scope/Value:advanced' => 'Advanced',
|
||||
'Class:OAuthClientGoogle/Attribute:used_scope/Value:advanced+' => '',
|
||||
'Class:OAuthClientGoogle/Attribute:used_for_smtp' => 'Used for SMTP',
|
||||
'Class:OAuthClientGoogle/Attribute:used_for_smtp+' => 'At least one OAuth client must have this flag to “Yes”, if you want iTop to use it for sending mails',
|
||||
'Class:OAuthClientGoogle/Attribute:used_for_smtp/Value:yes' => 'Yes',
|
||||
'Class:OAuthClientGoogle/Attribute:used_for_smtp/Value:no' => 'No',
|
||||
));
|
||||
@@ -0,0 +1,74 @@
|
||||
<?php
|
||||
/**
|
||||
* Localized data
|
||||
*
|
||||
* @copyright Copyright (C) 2013 XXXXX
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
Dict::Add('ES CR', 'Spanish', 'Español, Castellaño', [
|
||||
'Menu:CreateMailbox' => 'Create a mailbox...~~',
|
||||
'Menu:OAuthClient' => 'OAuth Client~~',
|
||||
'Menu:OAuthClient+' => '~~',
|
||||
'Menu:GenerateTokens' => 'Generate access tokens...~~',
|
||||
'Menu:RegenerateTokens' => 'Regenerate access tokens...~~',
|
||||
|
||||
'itop-oauth-client/Operation:CreateMailBox/Title' => 'Mailbox creation~~',
|
||||
|
||||
'itop-oauth-client:UsedForSMTP' => 'This OAuth client is used for SMTP~~',
|
||||
'itop-oauth-client:TestSMTP' => 'Email send test~~',
|
||||
'itop-oauth-client:MissingOAuthClient' => 'Missing Oauth client for user name %1$s~~',
|
||||
'itop-oauth-client:Message:MissingToken' => 'Generate access token before using this OAuth client~~',
|
||||
'itop-oauth-client:Message:TokenCreated' => 'Access token created~~',
|
||||
'itop-oauth-client:Message:TokenRecreated' => 'Access token regenerated~~',
|
||||
]);
|
||||
|
||||
//
|
||||
// Class: OAuthClient
|
||||
//
|
||||
|
||||
Dict::Add('ES CR', 'Spanish', 'Español, Castellaño', [
|
||||
'Class:OAuthClient' => 'Oauth Client~~',
|
||||
'Class:OAuthClient/Attribute:provider' => 'Provider~~',
|
||||
'Class:OAuthClient/Attribute:provider+' => '~~',
|
||||
'Class:OAuthClient/Attribute:name' => 'Login~~',
|
||||
'Class:OAuthClient/Attribute:name+' => '~~',
|
||||
'Class:OAuthClient/Attribute:scope' => 'Scope~~',
|
||||
'Class:OAuthClient/Attribute:scope+' => '~~',
|
||||
'Class:OAuthClient/Attribute:description' => 'Description~~',
|
||||
'Class:OAuthClient/Attribute:description+' => '~~',
|
||||
'Class:OAuthClient/Attribute:client_id' => 'Client id~~',
|
||||
'Class:OAuthClient/Attribute:client_id+' => '~~',
|
||||
'Class:OAuthClient/Attribute:client_secret' => 'Client secret~~',
|
||||
'Class:OAuthClient/Attribute:client_secret+' => '~~',
|
||||
'Class:OAuthClient/Attribute:refresh_token' => 'Refresh token~~',
|
||||
'Class:OAuthClient/Attribute:refresh_token+' => '~~',
|
||||
'Class:OAuthClient/Attribute:refresh_token_expiration' => 'Refresh token expiration~~',
|
||||
'Class:OAuthClient/Attribute:refresh_token_expiration+' => '~~',
|
||||
'Class:OAuthClient/Attribute:token' => 'Access token~~',
|
||||
'Class:OAuthClient/Attribute:token+' => '~~',
|
||||
'Class:OAuthClient/Attribute:token_expiration' => 'Access token expiration~~',
|
||||
'Class:OAuthClient/Attribute:token_expiration+' => '~~',
|
||||
'Class:OAuthClient/Attribute:redirect_url' => 'Redirect url~~',
|
||||
'Class:OAuthClient/Attribute:redirect_url+' => '~~',
|
||||
'Class:OAuthClient/Attribute:mailbox_list' => 'Mailbox list~~',
|
||||
'Class:OAuthClient/Attribute:mailbox_list+' => '~~',
|
||||
]);
|
||||
|
||||
//
|
||||
// Class: OAuthClientAzure
|
||||
//
|
||||
Dict::Add('ES CR', 'Spanish', 'Español, Castellaño', [
|
||||
'Class:OAuthClientAzure' => 'OAuth client for Microsoft Azure~~',
|
||||
'Class:OAuthClientAzure/Name' => '%1$s (%2$s)~~',
|
||||
|
||||
]);
|
||||
|
||||
//
|
||||
// Class: OAuthClientGoogle
|
||||
//
|
||||
Dict::Add('ES CR', 'Spanish', 'Español, Castellaño', [
|
||||
'Class:OAuthClientGoogle' => 'OAuth client for Google~~',
|
||||
'Class:OAuthClientGoogle/Name' => '%1$s (%2$s)~~',
|
||||
]);
|
||||
|
||||
116
datamodels/2.x/itop-oauth-client/fr.dict.itop-oauth-client.php
Normal file
116
datamodels/2.x/itop-oauth-client/fr.dict.itop-oauth-client.php
Normal file
@@ -0,0 +1,116 @@
|
||||
<?php
|
||||
/**
|
||||
* Localized data
|
||||
*
|
||||
* @copyright Copyright (C) 2013 XXXXX
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
Dict::Add('FR FR', 'French', 'Français', [
|
||||
'Menu:CreateMailbox' => 'Créer une boite mail...',
|
||||
'Menu:OAuthClient' => 'Client OAuth',
|
||||
'Menu:OAuthClient+' => '',
|
||||
'Menu:GenerateTokens' => 'Créer un jeton d\'accès...',
|
||||
'Menu:RegenerateTokens' => 'Recréer un jeton d\'accès..',
|
||||
|
||||
'itop-oauth-client/Operation:CreateMailBox/Title' => 'Création de boite mail',
|
||||
|
||||
'itop-oauth-client:UsedForSMTP' => 'Ce client Oauth est utilisé pour SMTP',
|
||||
'itop-oauth-client:TestSMTP' => 'Tester l\'envoi de mail',
|
||||
'itop-oauth-client:MissingOAuthClient' => 'Il n\'y a pas de client OAuth pour l\'utilisateur %1$s',
|
||||
'itop-oauth-client:Message:MissingToken' => 'Générez le jeton d\'accès avant d\'utiliser ce client OAuth',
|
||||
'itop-oauth-client:Message:TokenCreated' => 'Le jeton d\'accès à été créé',
|
||||
'itop-oauth-client:Message:TokenRecreated' => 'Le jeton d\'accès à été renouvelé',
|
||||
|
||||
'OAuthClient:Name/UseForSMTPMustBeUnique' => 'La combinaison Login (%1$s) and Utilisé pour SMTP (%2$s) a déjà été utilisée pour OAuth Client',
|
||||
|
||||
'OAuthClient:baseinfo' => 'Information',
|
||||
'OAuthClient:scope' => 'Scope',
|
||||
]);
|
||||
|
||||
//
|
||||
// Class: OAuthClient
|
||||
//
|
||||
|
||||
Dict::Add('FR FR', 'French', 'Français', [
|
||||
'Class:OAuthClient' => 'Client OAuth',
|
||||
'Class:OAuthClient/Attribute:provider' => 'Fournisseur',
|
||||
'Class:OAuthClient/Attribute:provider+' => '',
|
||||
'Class:OAuthClient/Attribute:name' => 'Login',
|
||||
'Class:OAuthClient/Attribute:name+' => 'L\'adresse email à utiliser chez ce fournisseur',
|
||||
'Class:OAuthClient/Attribute:status' => 'Statut',
|
||||
'Class:OAuthClient/Attribute:status+' => 'Après la création, effectuer l\'action \'Créer un jeton d\'accès...\' pour activer ce client OAuth',
|
||||
'Class:OAuthClient/Attribute:status/Value:active' => 'Jeton d\'accès créé',
|
||||
'Class:OAuthClient/Attribute:status/Value:inactive' => 'Pas de jeton d\'accès',
|
||||
'Class:OAuthClient/Attribute:description' => 'Description',
|
||||
'Class:OAuthClient/Attribute:description+' => '',
|
||||
'Class:OAuthClient/Attribute:client_id' => 'ID Client',
|
||||
'Class:OAuthClient/Attribute:client_id+' => 'Recopier la chaine fournie par votre fournisseur OAuth2',
|
||||
'Class:OAuthClient/Attribute:client_secret' => 'Code secret du client',
|
||||
'Class:OAuthClient/Attribute:client_secret+' => 'Recopier l\'information fournie par votre fournisseur OAuth2',
|
||||
'Class:OAuthClient/Attribute:refresh_token' => 'Jeton de renouvellement',
|
||||
'Class:OAuthClient/Attribute:refresh_token+' => '',
|
||||
'Class:OAuthClient/Attribute:refresh_token_expiration' => 'Date d\'expiration du jeton de renouvellement',
|
||||
'Class:OAuthClient/Attribute:refresh_token_expiration+' => '',
|
||||
'Class:OAuthClient/Attribute:token' => 'Jeton d\'accès',
|
||||
'Class:OAuthClient/Attribute:token+' => '',
|
||||
'Class:OAuthClient/Attribute:token_expiration' => 'Date d\'expiration du jeton d\'accès',
|
||||
'Class:OAuthClient/Attribute:token_expiration+' => '',
|
||||
'Class:OAuthClient/Attribute:redirect_url' => 'URL de redirection',
|
||||
'Class:OAuthClient/Attribute:redirect_url+' => 'Cet URL doit être recopié dans la configuration OAuth2 de votre fournisseur',
|
||||
'Class:OAuthClient/Attribute:mailbox_list' => 'Mailbox list',
|
||||
'Class:OAuthClient/Attribute:mailbox_list+' => '',
|
||||
]);
|
||||
|
||||
//
|
||||
// Class: OAuthClientAzure
|
||||
//
|
||||
|
||||
Dict::Add('FR FR', 'French', 'Français', array(
|
||||
'Class:OAuthClientAzure' => 'Client OAuth pour Microsoft Azure',
|
||||
'Class:OAuthClientAzure/Name' => '%1$s (%2$s)',
|
||||
'Class:OAuthClientAzure/Attribute:scope' => 'Niveaux d\'accès',
|
||||
'Class:OAuthClientAzure/Attribute:scope+' => 'Les niveaux par défaut sont les plus souvent suffisants',
|
||||
'Class:OAuthClientAzure/Attribute:scope/Value:SMTP' => 'SMTP',
|
||||
'Class:OAuthClientAzure/Attribute:scope/Value:SMTP+' => '',
|
||||
'Class:OAuthClientAzure/Attribute:scope/Value:IMAP' => 'IMAP',
|
||||
'Class:OAuthClientAzure/Attribute:scope/Value:IMAP+' => '',
|
||||
'Class:OAuthClientAzure/Attribute:advanced_scope' => 'Niveaux d\'accès avancé',
|
||||
'Class:OAuthClientAzure/Attribute:advanced_scope+' => 'A saisir, lorsque les niveaux prédéfinis ne suffisent pas',
|
||||
'Class:OAuthClientAzure/Attribute:used_scope' => 'Niveaux d\'accès utilisés',
|
||||
'Class:OAuthClientAzure/Attribute:used_scope+' => '',
|
||||
'Class:OAuthClientAzure/Attribute:used_scope/Value:simple' => 'Simple',
|
||||
'Class:OAuthClientAzure/Attribute:used_scope/Value:simple+' => '',
|
||||
'Class:OAuthClientAzure/Attribute:used_scope/Value:advanced' => 'Avancé',
|
||||
'Class:OAuthClientAzure/Attribute:used_scope/Value:advanced+' => '',
|
||||
'Class:OAuthClientAzure/Attribute:used_for_smtp' => 'Utilisé pour SMTP',
|
||||
'Class:OAuthClientAzure/Attribute:used_for_smtp+' => 'Le Client OAuth utilisé pour l\'envoi d\'emails doit être à \'Oui\'',
|
||||
'Class:OAuthClientAzure/Attribute:used_for_smtp/Value:yes' => 'Oui',
|
||||
'Class:OAuthClientAzure/Attribute:used_for_smtp/Value:no' => 'Non',
|
||||
));
|
||||
|
||||
//
|
||||
// Class: OAuthClientGoogle
|
||||
//
|
||||
|
||||
Dict::Add('FR FR', 'French', 'Français', array(
|
||||
'Class:OAuthClientGoogle' => 'Client OAuth pour Google',
|
||||
'Class:OAuthClientGoogle/Name' => '%1$s (%2$s)',
|
||||
'Class:OAuthClientGoogle/Attribute:scope' => 'Niveaux d\'accès',
|
||||
'Class:OAuthClientGoogle/Attribute:scope+' => 'Les niveaux par défaut sont les plus souvent suffisants',
|
||||
'Class:OAuthClientGoogle/Attribute:scope/Value:SMTP' => 'SMTP',
|
||||
'Class:OAuthClientGoogle/Attribute:scope/Value:SMTP+' => '',
|
||||
'Class:OAuthClientGoogle/Attribute:scope/Value:IMAP' => 'IMAP',
|
||||
'Class:OAuthClientGoogle/Attribute:scope/Value:IMAP+' => '',
|
||||
'Class:OAuthClientGoogle/Attribute:advanced_scope' => 'Niveaux d\'accès avancé',
|
||||
'Class:OAuthClientGoogle/Attribute:advanced_scope+' => 'A saisir, lorsque les niveaux prédéfinis ne suffisent pas',
|
||||
'Class:OAuthClientGoogle/Attribute:used_scope' => 'Niveaux d\'accès utilisés',
|
||||
'Class:OAuthClientGoogle/Attribute:used_scope+' => '',
|
||||
'Class:OAuthClientGoogle/Attribute:used_scope/Value:simple' => 'Simple',
|
||||
'Class:OAuthClientGoogle/Attribute:used_scope/Value:advanced' => 'Avancé',
|
||||
'Class:OAuthClientGoogle/Attribute:used_scope/Value:advanced+' => '',
|
||||
'Class:OAuthClientGoogle/Attribute:used_for_smtp' => 'Utilisé pour SMTP',
|
||||
'Class:OAuthClientGoogle/Attribute:used_for_smtp+' => 'Le Client OAuth utilisé pour l\'envoi d\'emails doit être à \'Oui\'',
|
||||
'Class:OAuthClientGoogle/Attribute:used_for_smtp/Value:yes' => 'Oui',
|
||||
'Class:OAuthClientGoogle/Attribute:used_for_smtp/Value:no' => 'Non',
|
||||
));
|
||||
@@ -0,0 +1,74 @@
|
||||
<?php
|
||||
/**
|
||||
* Localized data
|
||||
*
|
||||
* @copyright Copyright (C) 2013 XXXXX
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
Dict::Add('HU HU', 'Hungarian', 'Magyar', [
|
||||
'Menu:CreateMailbox' => 'Create a mailbox...~~',
|
||||
'Menu:OAuthClient' => 'OAuth Client~~',
|
||||
'Menu:OAuthClient+' => '~~',
|
||||
'Menu:GenerateTokens' => 'Generate access tokens...~~',
|
||||
'Menu:RegenerateTokens' => 'Regenerate access tokens...~~',
|
||||
|
||||
'itop-oauth-client/Operation:CreateMailBox/Title' => 'Mailbox creation~~',
|
||||
|
||||
'itop-oauth-client:UsedForSMTP' => 'This OAuth client is used for SMTP~~',
|
||||
'itop-oauth-client:TestSMTP' => 'Email send test~~',
|
||||
'itop-oauth-client:MissingOAuthClient' => 'Missing Oauth client for user name %1$s~~',
|
||||
'itop-oauth-client:Message:MissingToken' => 'Generate access token before using this OAuth client~~',
|
||||
'itop-oauth-client:Message:TokenCreated' => 'Access token created~~',
|
||||
'itop-oauth-client:Message:TokenRecreated' => 'Access token regenerated~~',
|
||||
]);
|
||||
|
||||
//
|
||||
// Class: OAuthClient
|
||||
//
|
||||
|
||||
Dict::Add('HU HU', 'Hungarian', 'Magyar', [
|
||||
'Class:OAuthClient' => 'Oauth Client~~',
|
||||
'Class:OAuthClient/Attribute:provider' => 'Provider~~',
|
||||
'Class:OAuthClient/Attribute:provider+' => '~~',
|
||||
'Class:OAuthClient/Attribute:name' => 'Login~~',
|
||||
'Class:OAuthClient/Attribute:name+' => '~~',
|
||||
'Class:OAuthClient/Attribute:scope' => 'Scope~~',
|
||||
'Class:OAuthClient/Attribute:scope+' => '~~',
|
||||
'Class:OAuthClient/Attribute:description' => 'Description~~',
|
||||
'Class:OAuthClient/Attribute:description+' => '~~',
|
||||
'Class:OAuthClient/Attribute:client_id' => 'Client id~~',
|
||||
'Class:OAuthClient/Attribute:client_id+' => '~~',
|
||||
'Class:OAuthClient/Attribute:client_secret' => 'Client secret~~',
|
||||
'Class:OAuthClient/Attribute:client_secret+' => '~~',
|
||||
'Class:OAuthClient/Attribute:refresh_token' => 'Refresh token~~',
|
||||
'Class:OAuthClient/Attribute:refresh_token+' => '~~',
|
||||
'Class:OAuthClient/Attribute:refresh_token_expiration' => 'Refresh token expiration~~',
|
||||
'Class:OAuthClient/Attribute:refresh_token_expiration+' => '~~',
|
||||
'Class:OAuthClient/Attribute:token' => 'Access token~~',
|
||||
'Class:OAuthClient/Attribute:token+' => '~~',
|
||||
'Class:OAuthClient/Attribute:token_expiration' => 'Access token expiration~~',
|
||||
'Class:OAuthClient/Attribute:token_expiration+' => '~~',
|
||||
'Class:OAuthClient/Attribute:redirect_url' => 'Redirect url~~',
|
||||
'Class:OAuthClient/Attribute:redirect_url+' => '~~',
|
||||
'Class:OAuthClient/Attribute:mailbox_list' => 'Mailbox list~~',
|
||||
'Class:OAuthClient/Attribute:mailbox_list+' => '~~',
|
||||
]);
|
||||
|
||||
//
|
||||
// Class: OAuthClientAzure
|
||||
//
|
||||
Dict::Add('HU HU', 'Hungarian', 'Magyar', [
|
||||
'Class:OAuthClientAzure' => 'OAuth client for Microsoft Azure~~',
|
||||
'Class:OAuthClientAzure/Name' => '%1$s (%2$s)~~',
|
||||
|
||||
]);
|
||||
|
||||
//
|
||||
// Class: OAuthClientGoogle
|
||||
//
|
||||
Dict::Add('HU HU', 'Hungarian', 'Magyar', [
|
||||
'Class:OAuthClientGoogle' => 'OAuth client for Google~~',
|
||||
'Class:OAuthClientGoogle/Name' => '%1$s (%2$s)~~',
|
||||
]);
|
||||
|
||||
24
datamodels/2.x/itop-oauth-client/index.php
Normal file
24
datamodels/2.x/itop-oauth-client/index.php
Normal file
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
/**
|
||||
* @copyright Copyright (C) 2010-2022 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
namespace Combodo\iTop\OAuthClient;
|
||||
|
||||
use Combodo\iTop\OAuthClient\Controller\OAuthClientController;
|
||||
|
||||
require_once(APPROOT.'application/startup.inc.php');
|
||||
|
||||
if (version_compare(ITOP_DESIGN_LATEST_VERSION , '3.0') >= 0) {
|
||||
$sTemplates = MODULESROOT.'itop-oauth-client/templates';
|
||||
} else {
|
||||
$sTemplates = MODULESROOT.'itop-oauth-client/templates/legacy';
|
||||
}
|
||||
|
||||
$oUpdateController = new OAuthClientController($sTemplates, 'itop-oauth-client');
|
||||
$oUpdateController->AllowOnlyAdmin();
|
||||
$oUpdateController->SetDefaultOperation('CreateMailbox');
|
||||
$oUpdateController->HandleOperation();
|
||||
|
||||
|
||||
@@ -0,0 +1,74 @@
|
||||
<?php
|
||||
/**
|
||||
* Localized data
|
||||
*
|
||||
* @copyright Copyright (C) 2013 XXXXX
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
Dict::Add('IT IT', 'Italian', 'Italiano', [
|
||||
'Menu:CreateMailbox' => 'Create a mailbox...~~',
|
||||
'Menu:OAuthClient' => 'OAuth Client~~',
|
||||
'Menu:OAuthClient+' => '~~',
|
||||
'Menu:GenerateTokens' => 'Generate access tokens...~~',
|
||||
'Menu:RegenerateTokens' => 'Regenerate access tokens...~~',
|
||||
|
||||
'itop-oauth-client/Operation:CreateMailBox/Title' => 'Mailbox creation~~',
|
||||
|
||||
'itop-oauth-client:UsedForSMTP' => 'This OAuth client is used for SMTP~~',
|
||||
'itop-oauth-client:TestSMTP' => 'Email send test~~',
|
||||
'itop-oauth-client:MissingOAuthClient' => 'Missing Oauth client for user name %1$s~~',
|
||||
'itop-oauth-client:Message:MissingToken' => 'Generate access token before using this OAuth client~~',
|
||||
'itop-oauth-client:Message:TokenCreated' => 'Access token created~~',
|
||||
'itop-oauth-client:Message:TokenRecreated' => 'Access token regenerated~~',
|
||||
]);
|
||||
|
||||
//
|
||||
// Class: OAuthClient
|
||||
//
|
||||
|
||||
Dict::Add('IT IT', 'Italian', 'Italiano', [
|
||||
'Class:OAuthClient' => 'Oauth Client~~',
|
||||
'Class:OAuthClient/Attribute:provider' => 'Provider~~',
|
||||
'Class:OAuthClient/Attribute:provider+' => '~~',
|
||||
'Class:OAuthClient/Attribute:name' => 'Login~~',
|
||||
'Class:OAuthClient/Attribute:name+' => '~~',
|
||||
'Class:OAuthClient/Attribute:scope' => 'Scope~~',
|
||||
'Class:OAuthClient/Attribute:scope+' => '~~',
|
||||
'Class:OAuthClient/Attribute:description' => 'Description~~',
|
||||
'Class:OAuthClient/Attribute:description+' => '~~',
|
||||
'Class:OAuthClient/Attribute:client_id' => 'Client id~~',
|
||||
'Class:OAuthClient/Attribute:client_id+' => '~~',
|
||||
'Class:OAuthClient/Attribute:client_secret' => 'Client secret~~',
|
||||
'Class:OAuthClient/Attribute:client_secret+' => '~~',
|
||||
'Class:OAuthClient/Attribute:refresh_token' => 'Refresh token~~',
|
||||
'Class:OAuthClient/Attribute:refresh_token+' => '~~',
|
||||
'Class:OAuthClient/Attribute:refresh_token_expiration' => 'Refresh token expiration~~',
|
||||
'Class:OAuthClient/Attribute:refresh_token_expiration+' => '~~',
|
||||
'Class:OAuthClient/Attribute:token' => 'Access token~~',
|
||||
'Class:OAuthClient/Attribute:token+' => '~~',
|
||||
'Class:OAuthClient/Attribute:token_expiration' => 'Access token expiration~~',
|
||||
'Class:OAuthClient/Attribute:token_expiration+' => '~~',
|
||||
'Class:OAuthClient/Attribute:redirect_url' => 'Redirect url~~',
|
||||
'Class:OAuthClient/Attribute:redirect_url+' => '~~',
|
||||
'Class:OAuthClient/Attribute:mailbox_list' => 'Mailbox list~~',
|
||||
'Class:OAuthClient/Attribute:mailbox_list+' => '~~',
|
||||
]);
|
||||
|
||||
//
|
||||
// Class: OAuthClientAzure
|
||||
//
|
||||
Dict::Add('IT IT', 'Italian', 'Italiano', [
|
||||
'Class:OAuthClientAzure' => 'OAuth client for Microsoft Azure~~',
|
||||
'Class:OAuthClientAzure/Name' => '%1$s (%2$s)~~',
|
||||
|
||||
]);
|
||||
|
||||
//
|
||||
// Class: OAuthClientGoogle
|
||||
//
|
||||
Dict::Add('IT IT', 'Italian', 'Italiano', [
|
||||
'Class:OAuthClientGoogle' => 'OAuth client for Google~~',
|
||||
'Class:OAuthClientGoogle/Name' => '%1$s (%2$s)~~',
|
||||
]);
|
||||
|
||||
@@ -0,0 +1,74 @@
|
||||
<?php
|
||||
/**
|
||||
* Localized data
|
||||
*
|
||||
* @copyright Copyright (C) 2013 XXXXX
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
Dict::Add('JA JP', 'Japanese', '日本語', [
|
||||
'Menu:CreateMailbox' => 'Create a mailbox...~~',
|
||||
'Menu:OAuthClient' => 'OAuth Client~~',
|
||||
'Menu:OAuthClient+' => '~~',
|
||||
'Menu:GenerateTokens' => 'Generate access tokens...~~',
|
||||
'Menu:RegenerateTokens' => 'Regenerate access tokens...~~',
|
||||
|
||||
'itop-oauth-client/Operation:CreateMailBox/Title' => 'Mailbox creation~~',
|
||||
|
||||
'itop-oauth-client:UsedForSMTP' => 'This OAuth client is used for SMTP~~',
|
||||
'itop-oauth-client:TestSMTP' => 'Email send test~~',
|
||||
'itop-oauth-client:MissingOAuthClient' => 'Missing Oauth client for user name %1$s~~',
|
||||
'itop-oauth-client:Message:MissingToken' => 'Generate access token before using this OAuth client~~',
|
||||
'itop-oauth-client:Message:TokenCreated' => 'Access token created~~',
|
||||
'itop-oauth-client:Message:TokenRecreated' => 'Access token regenerated~~',
|
||||
]);
|
||||
|
||||
//
|
||||
// Class: OAuthClient
|
||||
//
|
||||
|
||||
Dict::Add('JA JP', 'Japanese', '日本語', [
|
||||
'Class:OAuthClient' => 'Oauth Client~~',
|
||||
'Class:OAuthClient/Attribute:provider' => 'Provider~~',
|
||||
'Class:OAuthClient/Attribute:provider+' => '~~',
|
||||
'Class:OAuthClient/Attribute:name' => 'Login~~',
|
||||
'Class:OAuthClient/Attribute:name+' => '~~',
|
||||
'Class:OAuthClient/Attribute:scope' => 'Scope~~',
|
||||
'Class:OAuthClient/Attribute:scope+' => '~~',
|
||||
'Class:OAuthClient/Attribute:description' => 'Description~~',
|
||||
'Class:OAuthClient/Attribute:description+' => '~~',
|
||||
'Class:OAuthClient/Attribute:client_id' => 'Client id~~',
|
||||
'Class:OAuthClient/Attribute:client_id+' => '~~',
|
||||
'Class:OAuthClient/Attribute:client_secret' => 'Client secret~~',
|
||||
'Class:OAuthClient/Attribute:client_secret+' => '~~',
|
||||
'Class:OAuthClient/Attribute:refresh_token' => 'Refresh token~~',
|
||||
'Class:OAuthClient/Attribute:refresh_token+' => '~~',
|
||||
'Class:OAuthClient/Attribute:refresh_token_expiration' => 'Refresh token expiration~~',
|
||||
'Class:OAuthClient/Attribute:refresh_token_expiration+' => '~~',
|
||||
'Class:OAuthClient/Attribute:token' => 'Access token~~',
|
||||
'Class:OAuthClient/Attribute:token+' => '~~',
|
||||
'Class:OAuthClient/Attribute:token_expiration' => 'Access token expiration~~',
|
||||
'Class:OAuthClient/Attribute:token_expiration+' => '~~',
|
||||
'Class:OAuthClient/Attribute:redirect_url' => 'Redirect url~~',
|
||||
'Class:OAuthClient/Attribute:redirect_url+' => '~~',
|
||||
'Class:OAuthClient/Attribute:mailbox_list' => 'Mailbox list~~',
|
||||
'Class:OAuthClient/Attribute:mailbox_list+' => '~~',
|
||||
]);
|
||||
|
||||
//
|
||||
// Class: OAuthClientAzure
|
||||
//
|
||||
Dict::Add('JA JP', 'Japanese', '日本語', [
|
||||
'Class:OAuthClientAzure' => 'OAuth client for Microsoft Azure~~',
|
||||
'Class:OAuthClientAzure/Name' => '%1$s (%2$s)~~',
|
||||
|
||||
]);
|
||||
|
||||
//
|
||||
// Class: OAuthClientGoogle
|
||||
//
|
||||
Dict::Add('JA JP', 'Japanese', '日本語', [
|
||||
'Class:OAuthClientGoogle' => 'OAuth client for Google~~',
|
||||
'Class:OAuthClientGoogle/Name' => '%1$s (%2$s)~~',
|
||||
]);
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
<?php
|
||||
//
|
||||
// iTop module definition file
|
||||
//
|
||||
|
||||
SetupWebPage::AddModule(
|
||||
__FILE__, // Path to the current file, all other file names are relative to the directory containing this file
|
||||
'itop-oauth-client/2.7.7',
|
||||
array(
|
||||
// Identification
|
||||
//
|
||||
'label' => 'OAuth 2.0 client',
|
||||
'category' => 'business',
|
||||
|
||||
// Setup
|
||||
//
|
||||
'dependencies' => array(
|
||||
'itop-welcome-itil/2.7.7,'
|
||||
),
|
||||
'mandatory' => false,
|
||||
'visible' => true,
|
||||
|
||||
// Components
|
||||
//
|
||||
'datamodel' => array(
|
||||
'vendor/autoload.php',
|
||||
'model.itop-oauth-client.php', // Contains the PHP code generated by the "compilation" of datamodel.remote-authent-oauth.xml
|
||||
'src/Service/PopupMenuExtension.php',
|
||||
'src/Service/ApplicationUIExtension.php',
|
||||
),
|
||||
'webservice' => array(
|
||||
|
||||
),
|
||||
'data.struct' => array(
|
||||
// add your 'structure' definition XML files here,
|
||||
),
|
||||
'data.sample' => array(
|
||||
// add your sample data XML files here,
|
||||
),
|
||||
|
||||
// Documentation
|
||||
//
|
||||
'doc.manual_setup' => '', // hyperlink to manual setup documentation, if any
|
||||
'doc.more_information' => '', // hyperlink to more information, if any
|
||||
|
||||
// Default settings
|
||||
//
|
||||
'settings' => array(
|
||||
// Module specific settings go here, if any
|
||||
),
|
||||
)
|
||||
);
|
||||
|
||||
@@ -0,0 +1,74 @@
|
||||
<?php
|
||||
/**
|
||||
* Localized data
|
||||
*
|
||||
* @copyright Copyright (C) 2013 XXXXX
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
Dict::Add('NL NL', 'Dutch', 'Nederlands', [
|
||||
'Menu:CreateMailbox' => 'Create a mailbox...~~',
|
||||
'Menu:OAuthClient' => 'OAuth Client~~',
|
||||
'Menu:OAuthClient+' => '~~',
|
||||
'Menu:GenerateTokens' => 'Generate access tokens...~~',
|
||||
'Menu:RegenerateTokens' => 'Regenerate access tokens...~~',
|
||||
|
||||
'itop-oauth-client/Operation:CreateMailBox/Title' => 'Mailbox creation~~',
|
||||
|
||||
'itop-oauth-client:UsedForSMTP' => 'This OAuth client is used for SMTP~~',
|
||||
'itop-oauth-client:TestSMTP' => 'Email send test~~',
|
||||
'itop-oauth-client:MissingOAuthClient' => 'Missing Oauth client for user name %1$s~~',
|
||||
'itop-oauth-client:Message:MissingToken' => 'Generate access token before using this OAuth client~~',
|
||||
'itop-oauth-client:Message:TokenCreated' => 'Access token created~~',
|
||||
'itop-oauth-client:Message:TokenRecreated' => 'Access token regenerated~~',
|
||||
]);
|
||||
|
||||
//
|
||||
// Class: OAuthClient
|
||||
//
|
||||
|
||||
Dict::Add('NL NL', 'Dutch', 'Nederlands', [
|
||||
'Class:OAuthClient' => 'Oauth Client~~',
|
||||
'Class:OAuthClient/Attribute:provider' => 'Provider~~',
|
||||
'Class:OAuthClient/Attribute:provider+' => '~~',
|
||||
'Class:OAuthClient/Attribute:name' => 'Login~~',
|
||||
'Class:OAuthClient/Attribute:name+' => '~~',
|
||||
'Class:OAuthClient/Attribute:scope' => 'Scope~~',
|
||||
'Class:OAuthClient/Attribute:scope+' => '~~',
|
||||
'Class:OAuthClient/Attribute:description' => 'Description~~',
|
||||
'Class:OAuthClient/Attribute:description+' => '~~',
|
||||
'Class:OAuthClient/Attribute:client_id' => 'Client id~~',
|
||||
'Class:OAuthClient/Attribute:client_id+' => '~~',
|
||||
'Class:OAuthClient/Attribute:client_secret' => 'Client secret~~',
|
||||
'Class:OAuthClient/Attribute:client_secret+' => '~~',
|
||||
'Class:OAuthClient/Attribute:refresh_token' => 'Refresh token~~',
|
||||
'Class:OAuthClient/Attribute:refresh_token+' => '~~',
|
||||
'Class:OAuthClient/Attribute:refresh_token_expiration' => 'Refresh token expiration~~',
|
||||
'Class:OAuthClient/Attribute:refresh_token_expiration+' => '~~',
|
||||
'Class:OAuthClient/Attribute:token' => 'Access token~~',
|
||||
'Class:OAuthClient/Attribute:token+' => '~~',
|
||||
'Class:OAuthClient/Attribute:token_expiration' => 'Access token expiration~~',
|
||||
'Class:OAuthClient/Attribute:token_expiration+' => '~~',
|
||||
'Class:OAuthClient/Attribute:redirect_url' => 'Redirect url~~',
|
||||
'Class:OAuthClient/Attribute:redirect_url+' => '~~',
|
||||
'Class:OAuthClient/Attribute:mailbox_list' => 'Mailbox list~~',
|
||||
'Class:OAuthClient/Attribute:mailbox_list+' => '~~',
|
||||
]);
|
||||
|
||||
//
|
||||
// Class: OAuthClientAzure
|
||||
//
|
||||
Dict::Add('NL NL', 'Dutch', 'Nederlands', [
|
||||
'Class:OAuthClientAzure' => 'OAuth client for Microsoft Azure~~',
|
||||
'Class:OAuthClientAzure/Name' => '%1$s (%2$s)~~',
|
||||
|
||||
]);
|
||||
|
||||
//
|
||||
// Class: OAuthClientGoogle
|
||||
//
|
||||
Dict::Add('NL NL', 'Dutch', 'Nederlands', [
|
||||
'Class:OAuthClientGoogle' => 'OAuth client for Google~~',
|
||||
'Class:OAuthClientGoogle/Name' => '%1$s (%2$s)~~',
|
||||
]);
|
||||
|
||||
@@ -0,0 +1,74 @@
|
||||
<?php
|
||||
/**
|
||||
* Localized data
|
||||
*
|
||||
* @copyright Copyright (C) 2013 XXXXX
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
Dict::Add('PT BR', 'Brazilian', 'Brazilian', [
|
||||
'Menu:CreateMailbox' => 'Create a mailbox...~~',
|
||||
'Menu:OAuthClient' => 'OAuth Client~~',
|
||||
'Menu:OAuthClient+' => '~~',
|
||||
'Menu:GenerateTokens' => 'Generate access tokens...~~',
|
||||
'Menu:RegenerateTokens' => 'Regenerate access tokens...~~',
|
||||
|
||||
'itop-oauth-client/Operation:CreateMailBox/Title' => 'Mailbox creation~~',
|
||||
|
||||
'itop-oauth-client:UsedForSMTP' => 'This OAuth client is used for SMTP~~',
|
||||
'itop-oauth-client:TestSMTP' => 'Email send test~~',
|
||||
'itop-oauth-client:MissingOAuthClient' => 'Missing Oauth client for user name %1$s~~',
|
||||
'itop-oauth-client:Message:MissingToken' => 'Generate access token before using this OAuth client~~',
|
||||
'itop-oauth-client:Message:TokenCreated' => 'Access token created~~',
|
||||
'itop-oauth-client:Message:TokenRecreated' => 'Access token regenerated~~',
|
||||
]);
|
||||
|
||||
//
|
||||
// Class: OAuthClient
|
||||
//
|
||||
|
||||
Dict::Add('PT BR', 'Brazilian', 'Brazilian', [
|
||||
'Class:OAuthClient' => 'Oauth Client~~',
|
||||
'Class:OAuthClient/Attribute:provider' => 'Provider~~',
|
||||
'Class:OAuthClient/Attribute:provider+' => '~~',
|
||||
'Class:OAuthClient/Attribute:name' => 'Login~~',
|
||||
'Class:OAuthClient/Attribute:name+' => '~~',
|
||||
'Class:OAuthClient/Attribute:scope' => 'Scope~~',
|
||||
'Class:OAuthClient/Attribute:scope+' => '~~',
|
||||
'Class:OAuthClient/Attribute:description' => 'Description~~',
|
||||
'Class:OAuthClient/Attribute:description+' => '~~',
|
||||
'Class:OAuthClient/Attribute:client_id' => 'Client id~~',
|
||||
'Class:OAuthClient/Attribute:client_id+' => '~~',
|
||||
'Class:OAuthClient/Attribute:client_secret' => 'Client secret~~',
|
||||
'Class:OAuthClient/Attribute:client_secret+' => '~~',
|
||||
'Class:OAuthClient/Attribute:refresh_token' => 'Refresh token~~',
|
||||
'Class:OAuthClient/Attribute:refresh_token+' => '~~',
|
||||
'Class:OAuthClient/Attribute:refresh_token_expiration' => 'Refresh token expiration~~',
|
||||
'Class:OAuthClient/Attribute:refresh_token_expiration+' => '~~',
|
||||
'Class:OAuthClient/Attribute:token' => 'Access token~~',
|
||||
'Class:OAuthClient/Attribute:token+' => '~~',
|
||||
'Class:OAuthClient/Attribute:token_expiration' => 'Access token expiration~~',
|
||||
'Class:OAuthClient/Attribute:token_expiration+' => '~~',
|
||||
'Class:OAuthClient/Attribute:redirect_url' => 'Redirect url~~',
|
||||
'Class:OAuthClient/Attribute:redirect_url+' => '~~',
|
||||
'Class:OAuthClient/Attribute:mailbox_list' => 'Mailbox list~~',
|
||||
'Class:OAuthClient/Attribute:mailbox_list+' => '~~',
|
||||
]);
|
||||
|
||||
//
|
||||
// Class: OAuthClientAzure
|
||||
//
|
||||
Dict::Add('PT BR', 'Brazilian', 'Brazilian', [
|
||||
'Class:OAuthClientAzure' => 'OAuth client for Microsoft Azure~~',
|
||||
'Class:OAuthClientAzure/Name' => '%1$s (%2$s)~~',
|
||||
|
||||
]);
|
||||
|
||||
//
|
||||
// Class: OAuthClientGoogle
|
||||
//
|
||||
Dict::Add('PT BR', 'Brazilian', 'Brazilian', [
|
||||
'Class:OAuthClientGoogle' => 'OAuth client for Google~~',
|
||||
'Class:OAuthClientGoogle/Name' => '%1$s (%2$s)~~',
|
||||
]);
|
||||
|
||||
@@ -0,0 +1,74 @@
|
||||
<?php
|
||||
/**
|
||||
* Localized data
|
||||
*
|
||||
* @copyright Copyright (C) 2013 XXXXX
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
Dict::Add('RU RU', 'Russian', 'Русский', [
|
||||
'Menu:CreateMailbox' => 'Create a mailbox...~~',
|
||||
'Menu:OAuthClient' => 'OAuth Client~~',
|
||||
'Menu:OAuthClient+' => '~~',
|
||||
'Menu:GenerateTokens' => 'Generate access tokens...~~',
|
||||
'Menu:RegenerateTokens' => 'Regenerate access tokens...~~',
|
||||
|
||||
'itop-oauth-client/Operation:CreateMailBox/Title' => 'Mailbox creation~~',
|
||||
|
||||
'itop-oauth-client:UsedForSMTP' => 'This OAuth client is used for SMTP~~',
|
||||
'itop-oauth-client:TestSMTP' => 'Email send test~~',
|
||||
'itop-oauth-client:MissingOAuthClient' => 'Missing Oauth client for user name %1$s~~',
|
||||
'itop-oauth-client:Message:MissingToken' => 'Generate access token before using this OAuth client~~',
|
||||
'itop-oauth-client:Message:TokenCreated' => 'Access token created~~',
|
||||
'itop-oauth-client:Message:TokenRecreated' => 'Access token regenerated~~',
|
||||
]);
|
||||
|
||||
//
|
||||
// Class: OAuthClient
|
||||
//
|
||||
|
||||
Dict::Add('RU RU', 'Russian', 'Русский', [
|
||||
'Class:OAuthClient' => 'Oauth Client~~',
|
||||
'Class:OAuthClient/Attribute:provider' => 'Provider~~',
|
||||
'Class:OAuthClient/Attribute:provider+' => '~~',
|
||||
'Class:OAuthClient/Attribute:name' => 'Login~~',
|
||||
'Class:OAuthClient/Attribute:name+' => '~~',
|
||||
'Class:OAuthClient/Attribute:scope' => 'Scope~~',
|
||||
'Class:OAuthClient/Attribute:scope+' => '~~',
|
||||
'Class:OAuthClient/Attribute:description' => 'Description~~',
|
||||
'Class:OAuthClient/Attribute:description+' => '~~',
|
||||
'Class:OAuthClient/Attribute:client_id' => 'Client id~~',
|
||||
'Class:OAuthClient/Attribute:client_id+' => '~~',
|
||||
'Class:OAuthClient/Attribute:client_secret' => 'Client secret~~',
|
||||
'Class:OAuthClient/Attribute:client_secret+' => '~~',
|
||||
'Class:OAuthClient/Attribute:refresh_token' => 'Refresh token~~',
|
||||
'Class:OAuthClient/Attribute:refresh_token+' => '~~',
|
||||
'Class:OAuthClient/Attribute:refresh_token_expiration' => 'Refresh token expiration~~',
|
||||
'Class:OAuthClient/Attribute:refresh_token_expiration+' => '~~',
|
||||
'Class:OAuthClient/Attribute:token' => 'Access token~~',
|
||||
'Class:OAuthClient/Attribute:token+' => '~~',
|
||||
'Class:OAuthClient/Attribute:token_expiration' => 'Access token expiration~~',
|
||||
'Class:OAuthClient/Attribute:token_expiration+' => '~~',
|
||||
'Class:OAuthClient/Attribute:redirect_url' => 'Redirect url~~',
|
||||
'Class:OAuthClient/Attribute:redirect_url+' => '~~',
|
||||
'Class:OAuthClient/Attribute:mailbox_list' => 'Mailbox list~~',
|
||||
'Class:OAuthClient/Attribute:mailbox_list+' => '~~',
|
||||
]);
|
||||
|
||||
//
|
||||
// Class: OAuthClientAzure
|
||||
//
|
||||
Dict::Add('RU RU', 'Russian', 'Русский', [
|
||||
'Class:OAuthClientAzure' => 'OAuth client for Microsoft Azure~~',
|
||||
'Class:OAuthClientAzure/Name' => '%1$s (%2$s)~~',
|
||||
|
||||
]);
|
||||
|
||||
//
|
||||
// Class: OAuthClientGoogle
|
||||
//
|
||||
Dict::Add('RU RU', 'Russian', 'Русский', [
|
||||
'Class:OAuthClientGoogle' => 'OAuth client for Google~~',
|
||||
'Class:OAuthClientGoogle/Name' => '%1$s (%2$s)~~',
|
||||
]);
|
||||
|
||||
@@ -0,0 +1,74 @@
|
||||
<?php
|
||||
/**
|
||||
* Localized data
|
||||
*
|
||||
* @copyright Copyright (C) 2013 XXXXX
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
Dict::Add('SK SK', 'Slovak', 'Slovenčina', [
|
||||
'Menu:CreateMailbox' => 'Create a mailbox...~~',
|
||||
'Menu:OAuthClient' => 'OAuth Client~~',
|
||||
'Menu:OAuthClient+' => '~~',
|
||||
'Menu:GenerateTokens' => 'Generate access tokens...~~',
|
||||
'Menu:RegenerateTokens' => 'Regenerate access tokens...~~',
|
||||
|
||||
'itop-oauth-client/Operation:CreateMailBox/Title' => 'Mailbox creation~~',
|
||||
|
||||
'itop-oauth-client:UsedForSMTP' => 'This OAuth client is used for SMTP~~',
|
||||
'itop-oauth-client:TestSMTP' => 'Email send test~~',
|
||||
'itop-oauth-client:MissingOAuthClient' => 'Missing Oauth client for user name %1$s~~',
|
||||
'itop-oauth-client:Message:MissingToken' => 'Generate access token before using this OAuth client~~',
|
||||
'itop-oauth-client:Message:TokenCreated' => 'Access token created~~',
|
||||
'itop-oauth-client:Message:TokenRecreated' => 'Access token regenerated~~',
|
||||
]);
|
||||
|
||||
//
|
||||
// Class: OAuthClient
|
||||
//
|
||||
|
||||
Dict::Add('SK SK', 'Slovak', 'Slovenčina', [
|
||||
'Class:OAuthClient' => 'Oauth Client~~',
|
||||
'Class:OAuthClient/Attribute:provider' => 'Provider~~',
|
||||
'Class:OAuthClient/Attribute:provider+' => '~~',
|
||||
'Class:OAuthClient/Attribute:name' => 'Login~~',
|
||||
'Class:OAuthClient/Attribute:name+' => '~~',
|
||||
'Class:OAuthClient/Attribute:scope' => 'Scope~~',
|
||||
'Class:OAuthClient/Attribute:scope+' => '~~',
|
||||
'Class:OAuthClient/Attribute:description' => 'Description~~',
|
||||
'Class:OAuthClient/Attribute:description+' => '~~',
|
||||
'Class:OAuthClient/Attribute:client_id' => 'Client id~~',
|
||||
'Class:OAuthClient/Attribute:client_id+' => '~~',
|
||||
'Class:OAuthClient/Attribute:client_secret' => 'Client secret~~',
|
||||
'Class:OAuthClient/Attribute:client_secret+' => '~~',
|
||||
'Class:OAuthClient/Attribute:refresh_token' => 'Refresh token~~',
|
||||
'Class:OAuthClient/Attribute:refresh_token+' => '~~',
|
||||
'Class:OAuthClient/Attribute:refresh_token_expiration' => 'Refresh token expiration~~',
|
||||
'Class:OAuthClient/Attribute:refresh_token_expiration+' => '~~',
|
||||
'Class:OAuthClient/Attribute:token' => 'Access token~~',
|
||||
'Class:OAuthClient/Attribute:token+' => '~~',
|
||||
'Class:OAuthClient/Attribute:token_expiration' => 'Access token expiration~~',
|
||||
'Class:OAuthClient/Attribute:token_expiration+' => '~~',
|
||||
'Class:OAuthClient/Attribute:redirect_url' => 'Redirect url~~',
|
||||
'Class:OAuthClient/Attribute:redirect_url+' => '~~',
|
||||
'Class:OAuthClient/Attribute:mailbox_list' => 'Mailbox list~~',
|
||||
'Class:OAuthClient/Attribute:mailbox_list+' => '~~',
|
||||
]);
|
||||
|
||||
//
|
||||
// Class: OAuthClientAzure
|
||||
//
|
||||
Dict::Add('SK SK', 'Slovak', 'Slovenčina', [
|
||||
'Class:OAuthClientAzure' => 'OAuth client for Microsoft Azure~~',
|
||||
'Class:OAuthClientAzure/Name' => '%1$s (%2$s)~~',
|
||||
|
||||
]);
|
||||
|
||||
//
|
||||
// Class: OAuthClientGoogle
|
||||
//
|
||||
Dict::Add('SK SK', 'Slovak', 'Slovenčina', [
|
||||
'Class:OAuthClientGoogle' => 'OAuth client for Google~~',
|
||||
'Class:OAuthClientGoogle/Name' => '%1$s (%2$s)~~',
|
||||
]);
|
||||
|
||||
@@ -0,0 +1,77 @@
|
||||
<?php
|
||||
/**
|
||||
* @copyright Copyright (C) 2010-2022 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
namespace Combodo\iTop\OAuthClient\Controller;
|
||||
|
||||
use cmdbAbstractObject;
|
||||
use Combodo\iTop\Application\TwigBase\Controller\Controller;
|
||||
use Combodo\iTop\Core\Authentication\Client\OAuth\OAuthClientProviderFactory;
|
||||
use Dict;
|
||||
use IssueLog;
|
||||
use MetaModel;
|
||||
use utils;
|
||||
|
||||
class AjaxOauthClientController extends Controller
|
||||
{
|
||||
const LOG_CHANNEL = 'OAuth';
|
||||
|
||||
public function OperationGetOAuthAuthorizationUrl()
|
||||
{
|
||||
$sClass = utils::ReadParam('class');
|
||||
$sId = utils::ReadParam('id');
|
||||
|
||||
IssueLog::Debug("GetAuthorizationUrl for $sClass::$sId", self::LOG_CHANNEL);
|
||||
|
||||
/** @var \OAuthClient $oOAuthClient */
|
||||
$oOAuthClient = MetaModel::GetObject($sClass, $sId);
|
||||
|
||||
$aResult = ['status' => 'success', 'data' => []];
|
||||
|
||||
$sAuthorizationUrl = OAuthClientProviderFactory::GetAuthorizationUrl($oOAuthClient);
|
||||
$aResult['data']['authorization_url'] = $sAuthorizationUrl;
|
||||
|
||||
$this->DisplayJSONPage($aResult);
|
||||
}
|
||||
|
||||
public function OperationGetDisplayAuthenticationResults()
|
||||
{
|
||||
$sClass = utils::ReadParam('class');
|
||||
$sId = utils::ReadParam('id');
|
||||
|
||||
IssueLog::Debug("GetDisplayAuthenticationResults for $sClass::$sId", self::LOG_CHANNEL);
|
||||
|
||||
/** @var \OAuthClient $oOAuthClient */
|
||||
$oOAuthClient = MetaModel::GetObject($sClass, $sId);
|
||||
$bIsCreation = empty($oOAuthClient->Get('token'));
|
||||
|
||||
$sRedirectUrl = utils::ReadParam('redirect_url', '', false, 'raw');
|
||||
|
||||
$sRedirectUrlQuery = parse_url($sRedirectUrl)['query'];
|
||||
|
||||
$aQuery = [];
|
||||
parse_str($sRedirectUrlQuery, $aQuery);
|
||||
$sCode = $aQuery['code'];
|
||||
$oAccessToken = OAuthClientProviderFactory::GetAccessTokenFromCode($oOAuthClient, $sCode);
|
||||
|
||||
$oOAuthClient->SetAccessToken($oAccessToken);
|
||||
|
||||
cmdbAbstractObject::SetSessionMessage(
|
||||
$sClass,
|
||||
$sId,
|
||||
"$sClass:$sId:TokenCreated",
|
||||
$bIsCreation ? Dict::S('itop-oauth-client:Message:TokenCreated') : Dict::S('itop-oauth-client:Message:TokenRecreated'),
|
||||
'ok',
|
||||
1,
|
||||
true
|
||||
);
|
||||
|
||||
$aResult = ['status' => 'success'];
|
||||
$aResult['data'] = utils::GetAbsoluteUrlAppRoot()."pages/UI.php?operation=details&class=$sClass&id=$sId";
|
||||
|
||||
$this->DisplayJSONPage($aResult);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
<?php
|
||||
/**
|
||||
* @copyright Copyright (C) 2010-2022 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
namespace Combodo\iTop\OAuthClient\Controller;
|
||||
|
||||
use Combodo\iTop\Application\TwigBase\Controller\Controller;
|
||||
use IssueLog;
|
||||
use MetaModel;
|
||||
use utils;
|
||||
|
||||
class OAuthClientController extends Controller
|
||||
{
|
||||
const LOG_CHANNEL = 'OAuth';
|
||||
|
||||
public function OperationCreateMailbox()
|
||||
{
|
||||
$aParams = [];
|
||||
|
||||
$sClass = utils::ReadParam('class');
|
||||
$sId = utils::ReadParam('id');
|
||||
|
||||
IssueLog::Debug("CreateMailbox for $sClass::$sId", self::LOG_CHANNEL);
|
||||
|
||||
$oOAuthClient = MetaModel::GetObject($sClass, $sId);
|
||||
$sLogin = $oOAuthClient->Get('name');
|
||||
$sDefaultServer = $oOAuthClient->GetDefaultMailServer();
|
||||
$sDefaultPort = $oOAuthClient->GetDefaultMailServerPort();
|
||||
|
||||
$aParams['sURL'] = utils::GetAbsoluteUrlAppRoot().'pages/UI.php?operation=new&class=MailInboxOAuth'.
|
||||
'&default[mailbox]=INBOX'.
|
||||
'&default[server]='.$sDefaultServer.
|
||||
'&default[port]='.$sDefaultPort.
|
||||
'&default[oauth_client_id]='.$sId.
|
||||
'&default[login]='.$sLogin;
|
||||
|
||||
$this->DisplayPage($aParams);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
<?php
|
||||
/**
|
||||
* @copyright Copyright (C) 2010-2022 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
namespace Combodo\iTop\OAuthClient\Service;
|
||||
|
||||
use AbstractApplicationUIExtension;
|
||||
use OAuthClient;
|
||||
use utils;
|
||||
|
||||
class ApplicationUIExtension extends AbstractApplicationUIExtension
|
||||
{
|
||||
|
||||
public function GetHilightClass($oObject)
|
||||
{
|
||||
if ($oObject instanceof OAuthClient) {
|
||||
// Possible return values are:
|
||||
// HILIGHT_CLASS_CRITICAL, HILIGHT_CLASS_WARNING, HILIGHT_CLASS_OK, HILIGHT_CLASS_NONE
|
||||
$oConfig = utils::GetConfig();
|
||||
if ($oObject->Get('status') == 'inactive') {
|
||||
return HILIGHT_CLASS_WARNING;
|
||||
} elseif ($oObject->Get('used_for_smtp') == 'yes' && $oConfig->Get('email_transport_smtp.username') == $oObject->Get('name')) {
|
||||
return HILIGHT_CLASS_OK;
|
||||
}
|
||||
}
|
||||
|
||||
return HILIGHT_CLASS_NONE;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
<?php
|
||||
/**
|
||||
* @copyright Copyright (C) 2010-2022 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
namespace Combodo\iTop\OAuthClient\Service;
|
||||
|
||||
use ApplicationContext;
|
||||
use Combodo\iTop\Core\Authentication\Client\OAuth\OAuthClientProviderFactory;
|
||||
use Dict;
|
||||
use iPopupMenuExtension;
|
||||
use JSPopupMenuItem;
|
||||
use OAuthClient;
|
||||
use SeparatorPopupMenuItem;
|
||||
use URLPopupMenuItem;
|
||||
use utils;
|
||||
|
||||
class PopupMenuExtension implements \iPopupMenuExtension
|
||||
{
|
||||
const MODULE_CODE = 'itop-oauth-client';
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public static function EnumItems($iMenuId, $param)
|
||||
{
|
||||
$aResult = [];
|
||||
|
||||
switch ($iMenuId) {
|
||||
case iPopupMenuExtension::MENU_OBJDETAILS_ACTIONS:
|
||||
$oObj = $param;
|
||||
if ($oObj instanceof OAuthClient) {
|
||||
$bHasToken = !empty($oObj->Get('token'));
|
||||
$aResult[] = new SeparatorPopupMenuItem();
|
||||
|
||||
$oAppContext = new ApplicationContext();
|
||||
$sMenu = $bHasToken ? 'Menu:RegenerateTokens' : 'Menu:GenerateTokens';
|
||||
$sObjClass = get_class($oObj);
|
||||
$sClass = $sObjClass;
|
||||
$sId = $oObj->GetKey();
|
||||
$sAjaxUri = utils::GetAbsoluteUrlModulePage(static::MODULE_CODE, 'ajax.php');
|
||||
// Add a new menu item that triggers a custom JS function defined in our own javascript file: js/sample.js
|
||||
$sJSFileUrl = utils::GetAbsoluteUrlModulesRoot().static::MODULE_CODE.'/assets/js/oauth_connect.js';
|
||||
$sRedirectUri = OAuthClientProviderFactory::GetRedirectUri();
|
||||
$aResult[] = new JSPopupMenuItem(
|
||||
$sMenu.' from '.$sObjClass,
|
||||
Dict::S($sMenu),
|
||||
"OAuthConnect('$sClass', $sId, '$sAjaxUri', '$sRedirectUri')",
|
||||
[$sJSFileUrl]
|
||||
);
|
||||
|
||||
if ($bHasToken) {
|
||||
$aScopes = $oObj->Get('scope')->GetValues();
|
||||
if (in_array('IMAP', $aScopes)) {
|
||||
$aParams = $oAppContext->GetAsHash();
|
||||
$sMenu = 'Menu:CreateMailbox';
|
||||
$sObjClass = get_class($oObj);
|
||||
$aParams['class'] = $sObjClass;
|
||||
$aParams['id'] = $oObj->GetKey();
|
||||
$aParams['operation'] = 'CreateMailbox';
|
||||
$aResult[] = new URLPopupMenuItem(
|
||||
$sMenu.' from '.$sObjClass,
|
||||
Dict::S($sMenu),
|
||||
utils::GetAbsoluteUrlModulePage(static::MODULE_CODE, 'index.php', $aParams)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
// Unknown type of menu, do nothing
|
||||
break;
|
||||
}
|
||||
|
||||
return $aResult;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
{# @copyright Copyright (C) 2010-2022 Combodo SARL #}
|
||||
{# @license http://opensource.org/licenses/AGPL-3.0 #}
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
{# @copyright Copyright (C) 2010-2022 Combodo SARL #}
|
||||
{# @license http://opensource.org/licenses/AGPL-3.0 #}
|
||||
|
||||
window.location.href = '{{ sURL|raw }}'
|
||||
@@ -0,0 +1,74 @@
|
||||
<?php
|
||||
/**
|
||||
* Localized data
|
||||
*
|
||||
* @copyright Copyright (C) 2013 XXXXX
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
Dict::Add('TR TR', 'Turkish', 'Türkçe', [
|
||||
'Menu:CreateMailbox' => 'Create a mailbox...~~',
|
||||
'Menu:OAuthClient' => 'OAuth Client~~',
|
||||
'Menu:OAuthClient+' => '~~',
|
||||
'Menu:GenerateTokens' => 'Generate access tokens...~~',
|
||||
'Menu:RegenerateTokens' => 'Regenerate access tokens...~~',
|
||||
|
||||
'itop-oauth-client/Operation:CreateMailBox/Title' => 'Mailbox creation~~',
|
||||
|
||||
'itop-oauth-client:UsedForSMTP' => 'This OAuth client is used for SMTP~~',
|
||||
'itop-oauth-client:TestSMTP' => 'Email send test~~',
|
||||
'itop-oauth-client:MissingOAuthClient' => 'Missing Oauth client for user name %1$s~~',
|
||||
'itop-oauth-client:Message:MissingToken' => 'Generate access token before using this OAuth client~~',
|
||||
'itop-oauth-client:Message:TokenCreated' => 'Access token created~~',
|
||||
'itop-oauth-client:Message:TokenRecreated' => 'Access token regenerated~~',
|
||||
]);
|
||||
|
||||
//
|
||||
// Class: OAuthClient
|
||||
//
|
||||
|
||||
Dict::Add('TR TR', 'Turkish', 'Türkçe', [
|
||||
'Class:OAuthClient' => 'Oauth Client~~',
|
||||
'Class:OAuthClient/Attribute:provider' => 'Provider~~',
|
||||
'Class:OAuthClient/Attribute:provider+' => '~~',
|
||||
'Class:OAuthClient/Attribute:name' => 'Login~~',
|
||||
'Class:OAuthClient/Attribute:name+' => '~~',
|
||||
'Class:OAuthClient/Attribute:scope' => 'Scope~~',
|
||||
'Class:OAuthClient/Attribute:scope+' => '~~',
|
||||
'Class:OAuthClient/Attribute:description' => 'Description~~',
|
||||
'Class:OAuthClient/Attribute:description+' => '~~',
|
||||
'Class:OAuthClient/Attribute:client_id' => 'Client id~~',
|
||||
'Class:OAuthClient/Attribute:client_id+' => '~~',
|
||||
'Class:OAuthClient/Attribute:client_secret' => 'Client secret~~',
|
||||
'Class:OAuthClient/Attribute:client_secret+' => '~~',
|
||||
'Class:OAuthClient/Attribute:refresh_token' => 'Refresh token~~',
|
||||
'Class:OAuthClient/Attribute:refresh_token+' => '~~',
|
||||
'Class:OAuthClient/Attribute:refresh_token_expiration' => 'Refresh token expiration~~',
|
||||
'Class:OAuthClient/Attribute:refresh_token_expiration+' => '~~',
|
||||
'Class:OAuthClient/Attribute:token' => 'Access token~~',
|
||||
'Class:OAuthClient/Attribute:token+' => '~~',
|
||||
'Class:OAuthClient/Attribute:token_expiration' => 'Access token expiration~~',
|
||||
'Class:OAuthClient/Attribute:token_expiration+' => '~~',
|
||||
'Class:OAuthClient/Attribute:redirect_url' => 'Redirect url~~',
|
||||
'Class:OAuthClient/Attribute:redirect_url+' => '~~',
|
||||
'Class:OAuthClient/Attribute:mailbox_list' => 'Mailbox list~~',
|
||||
'Class:OAuthClient/Attribute:mailbox_list+' => '~~',
|
||||
]);
|
||||
|
||||
//
|
||||
// Class: OAuthClientAzure
|
||||
//
|
||||
Dict::Add('TR TR', 'Turkish', 'Türkçe', [
|
||||
'Class:OAuthClientAzure' => 'OAuth client for Microsoft Azure~~',
|
||||
'Class:OAuthClientAzure/Name' => '%1$s (%2$s)~~',
|
||||
|
||||
]);
|
||||
|
||||
//
|
||||
// Class: OAuthClientGoogle
|
||||
//
|
||||
Dict::Add('TR TR', 'Turkish', 'Türkçe', [
|
||||
'Class:OAuthClientGoogle' => 'OAuth client for Google~~',
|
||||
'Class:OAuthClientGoogle/Name' => '%1$s (%2$s)~~',
|
||||
]);
|
||||
|
||||
7
datamodels/2.x/itop-oauth-client/vendor/autoload.php
vendored
Normal file
7
datamodels/2.x/itop-oauth-client/vendor/autoload.php
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
<?php
|
||||
|
||||
// autoload.php @generated by Composer
|
||||
|
||||
require_once __DIR__ . '/composer/autoload_real.php';
|
||||
|
||||
return ComposerAutoloaderInitd52424b43ff18219f2ec935428aff074::getLoader();
|
||||
572
datamodels/2.x/itop-oauth-client/vendor/composer/ClassLoader.php
vendored
Normal file
572
datamodels/2.x/itop-oauth-client/vendor/composer/ClassLoader.php
vendored
Normal file
@@ -0,0 +1,572 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Composer.
|
||||
*
|
||||
* (c) Nils Adermann <naderman@naderman.de>
|
||||
* Jordi Boggiano <j.boggiano@seld.be>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Composer\Autoload;
|
||||
|
||||
/**
|
||||
* ClassLoader implements a PSR-0, PSR-4 and classmap class loader.
|
||||
*
|
||||
* $loader = new \Composer\Autoload\ClassLoader();
|
||||
*
|
||||
* // register classes with namespaces
|
||||
* $loader->add('Symfony\Component', __DIR__.'/component');
|
||||
* $loader->add('Symfony', __DIR__.'/framework');
|
||||
*
|
||||
* // activate the autoloader
|
||||
* $loader->register();
|
||||
*
|
||||
* // to enable searching the include path (eg. for PEAR packages)
|
||||
* $loader->setUseIncludePath(true);
|
||||
*
|
||||
* In this example, if you try to use a class in the Symfony\Component
|
||||
* namespace or one of its children (Symfony\Component\Console for instance),
|
||||
* the autoloader will first look for the class under the component/
|
||||
* directory, and it will then fallback to the framework/ directory if not
|
||||
* found before giving up.
|
||||
*
|
||||
* This class is loosely based on the Symfony UniversalClassLoader.
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
* @author Jordi Boggiano <j.boggiano@seld.be>
|
||||
* @see https://www.php-fig.org/psr/psr-0/
|
||||
* @see https://www.php-fig.org/psr/psr-4/
|
||||
*/
|
||||
class ClassLoader
|
||||
{
|
||||
/** @var ?string */
|
||||
private $vendorDir;
|
||||
|
||||
// PSR-4
|
||||
/**
|
||||
* @var array[]
|
||||
* @psalm-var array<string, array<string, int>>
|
||||
*/
|
||||
private $prefixLengthsPsr4 = array();
|
||||
/**
|
||||
* @var array[]
|
||||
* @psalm-var array<string, array<int, string>>
|
||||
*/
|
||||
private $prefixDirsPsr4 = array();
|
||||
/**
|
||||
* @var array[]
|
||||
* @psalm-var array<string, string>
|
||||
*/
|
||||
private $fallbackDirsPsr4 = array();
|
||||
|
||||
// PSR-0
|
||||
/**
|
||||
* @var array[]
|
||||
* @psalm-var array<string, array<string, string[]>>
|
||||
*/
|
||||
private $prefixesPsr0 = array();
|
||||
/**
|
||||
* @var array[]
|
||||
* @psalm-var array<string, string>
|
||||
*/
|
||||
private $fallbackDirsPsr0 = array();
|
||||
|
||||
/** @var bool */
|
||||
private $useIncludePath = false;
|
||||
|
||||
/**
|
||||
* @var string[]
|
||||
* @psalm-var array<string, string>
|
||||
*/
|
||||
private $classMap = array();
|
||||
|
||||
/** @var bool */
|
||||
private $classMapAuthoritative = false;
|
||||
|
||||
/**
|
||||
* @var bool[]
|
||||
* @psalm-var array<string, bool>
|
||||
*/
|
||||
private $missingClasses = array();
|
||||
|
||||
/** @var ?string */
|
||||
private $apcuPrefix;
|
||||
|
||||
/**
|
||||
* @var self[]
|
||||
*/
|
||||
private static $registeredLoaders = array();
|
||||
|
||||
/**
|
||||
* @param ?string $vendorDir
|
||||
*/
|
||||
public function __construct($vendorDir = null)
|
||||
{
|
||||
$this->vendorDir = $vendorDir;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string[]
|
||||
*/
|
||||
public function getPrefixes()
|
||||
{
|
||||
if (!empty($this->prefixesPsr0)) {
|
||||
return call_user_func_array('array_merge', array_values($this->prefixesPsr0));
|
||||
}
|
||||
|
||||
return array();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array[]
|
||||
* @psalm-return array<string, array<int, string>>
|
||||
*/
|
||||
public function getPrefixesPsr4()
|
||||
{
|
||||
return $this->prefixDirsPsr4;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array[]
|
||||
* @psalm-return array<string, string>
|
||||
*/
|
||||
public function getFallbackDirs()
|
||||
{
|
||||
return $this->fallbackDirsPsr0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array[]
|
||||
* @psalm-return array<string, string>
|
||||
*/
|
||||
public function getFallbackDirsPsr4()
|
||||
{
|
||||
return $this->fallbackDirsPsr4;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string[] Array of classname => path
|
||||
* @psalm-var array<string, string>
|
||||
*/
|
||||
public function getClassMap()
|
||||
{
|
||||
return $this->classMap;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string[] $classMap Class to filename map
|
||||
* @psalm-param array<string, string> $classMap
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function addClassMap(array $classMap)
|
||||
{
|
||||
if ($this->classMap) {
|
||||
$this->classMap = array_merge($this->classMap, $classMap);
|
||||
} else {
|
||||
$this->classMap = $classMap;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a set of PSR-0 directories for a given prefix, either
|
||||
* appending or prepending to the ones previously set for this prefix.
|
||||
*
|
||||
* @param string $prefix The prefix
|
||||
* @param string[]|string $paths The PSR-0 root directories
|
||||
* @param bool $prepend Whether to prepend the directories
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function add($prefix, $paths, $prepend = false)
|
||||
{
|
||||
if (!$prefix) {
|
||||
if ($prepend) {
|
||||
$this->fallbackDirsPsr0 = array_merge(
|
||||
(array) $paths,
|
||||
$this->fallbackDirsPsr0
|
||||
);
|
||||
} else {
|
||||
$this->fallbackDirsPsr0 = array_merge(
|
||||
$this->fallbackDirsPsr0,
|
||||
(array) $paths
|
||||
);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$first = $prefix[0];
|
||||
if (!isset($this->prefixesPsr0[$first][$prefix])) {
|
||||
$this->prefixesPsr0[$first][$prefix] = (array) $paths;
|
||||
|
||||
return;
|
||||
}
|
||||
if ($prepend) {
|
||||
$this->prefixesPsr0[$first][$prefix] = array_merge(
|
||||
(array) $paths,
|
||||
$this->prefixesPsr0[$first][$prefix]
|
||||
);
|
||||
} else {
|
||||
$this->prefixesPsr0[$first][$prefix] = array_merge(
|
||||
$this->prefixesPsr0[$first][$prefix],
|
||||
(array) $paths
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a set of PSR-4 directories for a given namespace, either
|
||||
* appending or prepending to the ones previously set for this namespace.
|
||||
*
|
||||
* @param string $prefix The prefix/namespace, with trailing '\\'
|
||||
* @param string[]|string $paths The PSR-4 base directories
|
||||
* @param bool $prepend Whether to prepend the directories
|
||||
*
|
||||
* @throws \InvalidArgumentException
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function addPsr4($prefix, $paths, $prepend = false)
|
||||
{
|
||||
if (!$prefix) {
|
||||
// Register directories for the root namespace.
|
||||
if ($prepend) {
|
||||
$this->fallbackDirsPsr4 = array_merge(
|
||||
(array) $paths,
|
||||
$this->fallbackDirsPsr4
|
||||
);
|
||||
} else {
|
||||
$this->fallbackDirsPsr4 = array_merge(
|
||||
$this->fallbackDirsPsr4,
|
||||
(array) $paths
|
||||
);
|
||||
}
|
||||
} elseif (!isset($this->prefixDirsPsr4[$prefix])) {
|
||||
// Register directories for a new namespace.
|
||||
$length = strlen($prefix);
|
||||
if ('\\' !== $prefix[$length - 1]) {
|
||||
throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator.");
|
||||
}
|
||||
$this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length;
|
||||
$this->prefixDirsPsr4[$prefix] = (array) $paths;
|
||||
} elseif ($prepend) {
|
||||
// Prepend directories for an already registered namespace.
|
||||
$this->prefixDirsPsr4[$prefix] = array_merge(
|
||||
(array) $paths,
|
||||
$this->prefixDirsPsr4[$prefix]
|
||||
);
|
||||
} else {
|
||||
// Append directories for an already registered namespace.
|
||||
$this->prefixDirsPsr4[$prefix] = array_merge(
|
||||
$this->prefixDirsPsr4[$prefix],
|
||||
(array) $paths
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a set of PSR-0 directories for a given prefix,
|
||||
* replacing any others previously set for this prefix.
|
||||
*
|
||||
* @param string $prefix The prefix
|
||||
* @param string[]|string $paths The PSR-0 base directories
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function set($prefix, $paths)
|
||||
{
|
||||
if (!$prefix) {
|
||||
$this->fallbackDirsPsr0 = (array) $paths;
|
||||
} else {
|
||||
$this->prefixesPsr0[$prefix[0]][$prefix] = (array) $paths;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a set of PSR-4 directories for a given namespace,
|
||||
* replacing any others previously set for this namespace.
|
||||
*
|
||||
* @param string $prefix The prefix/namespace, with trailing '\\'
|
||||
* @param string[]|string $paths The PSR-4 base directories
|
||||
*
|
||||
* @throws \InvalidArgumentException
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setPsr4($prefix, $paths)
|
||||
{
|
||||
if (!$prefix) {
|
||||
$this->fallbackDirsPsr4 = (array) $paths;
|
||||
} else {
|
||||
$length = strlen($prefix);
|
||||
if ('\\' !== $prefix[$length - 1]) {
|
||||
throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator.");
|
||||
}
|
||||
$this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length;
|
||||
$this->prefixDirsPsr4[$prefix] = (array) $paths;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Turns on searching the include path for class files.
|
||||
*
|
||||
* @param bool $useIncludePath
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setUseIncludePath($useIncludePath)
|
||||
{
|
||||
$this->useIncludePath = $useIncludePath;
|
||||
}
|
||||
|
||||
/**
|
||||
* Can be used to check if the autoloader uses the include path to check
|
||||
* for classes.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function getUseIncludePath()
|
||||
{
|
||||
return $this->useIncludePath;
|
||||
}
|
||||
|
||||
/**
|
||||
* Turns off searching the prefix and fallback directories for classes
|
||||
* that have not been registered with the class map.
|
||||
*
|
||||
* @param bool $classMapAuthoritative
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setClassMapAuthoritative($classMapAuthoritative)
|
||||
{
|
||||
$this->classMapAuthoritative = $classMapAuthoritative;
|
||||
}
|
||||
|
||||
/**
|
||||
* Should class lookup fail if not found in the current class map?
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isClassMapAuthoritative()
|
||||
{
|
||||
return $this->classMapAuthoritative;
|
||||
}
|
||||
|
||||
/**
|
||||
* APCu prefix to use to cache found/not-found classes, if the extension is enabled.
|
||||
*
|
||||
* @param string|null $apcuPrefix
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setApcuPrefix($apcuPrefix)
|
||||
{
|
||||
$this->apcuPrefix = function_exists('apcu_fetch') && filter_var(ini_get('apc.enabled'), FILTER_VALIDATE_BOOLEAN) ? $apcuPrefix : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* The APCu prefix in use, or null if APCu caching is not enabled.
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function getApcuPrefix()
|
||||
{
|
||||
return $this->apcuPrefix;
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers this instance as an autoloader.
|
||||
*
|
||||
* @param bool $prepend Whether to prepend the autoloader or not
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function register($prepend = false)
|
||||
{
|
||||
spl_autoload_register(array($this, 'loadClass'), true, $prepend);
|
||||
|
||||
if (null === $this->vendorDir) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ($prepend) {
|
||||
self::$registeredLoaders = array($this->vendorDir => $this) + self::$registeredLoaders;
|
||||
} else {
|
||||
unset(self::$registeredLoaders[$this->vendorDir]);
|
||||
self::$registeredLoaders[$this->vendorDir] = $this;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Unregisters this instance as an autoloader.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function unregister()
|
||||
{
|
||||
spl_autoload_unregister(array($this, 'loadClass'));
|
||||
|
||||
if (null !== $this->vendorDir) {
|
||||
unset(self::$registeredLoaders[$this->vendorDir]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads the given class or interface.
|
||||
*
|
||||
* @param string $class The name of the class
|
||||
* @return true|null True if loaded, null otherwise
|
||||
*/
|
||||
public function loadClass($class)
|
||||
{
|
||||
if ($file = $this->findFile($class)) {
|
||||
includeFile($file);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds the path to the file where the class is defined.
|
||||
*
|
||||
* @param string $class The name of the class
|
||||
*
|
||||
* @return string|false The path if found, false otherwise
|
||||
*/
|
||||
public function findFile($class)
|
||||
{
|
||||
// class map lookup
|
||||
if (isset($this->classMap[$class])) {
|
||||
return $this->classMap[$class];
|
||||
}
|
||||
if ($this->classMapAuthoritative || isset($this->missingClasses[$class])) {
|
||||
return false;
|
||||
}
|
||||
if (null !== $this->apcuPrefix) {
|
||||
$file = apcu_fetch($this->apcuPrefix.$class, $hit);
|
||||
if ($hit) {
|
||||
return $file;
|
||||
}
|
||||
}
|
||||
|
||||
$file = $this->findFileWithExtension($class, '.php');
|
||||
|
||||
// Search for Hack files if we are running on HHVM
|
||||
if (false === $file && defined('HHVM_VERSION')) {
|
||||
$file = $this->findFileWithExtension($class, '.hh');
|
||||
}
|
||||
|
||||
if (null !== $this->apcuPrefix) {
|
||||
apcu_add($this->apcuPrefix.$class, $file);
|
||||
}
|
||||
|
||||
if (false === $file) {
|
||||
// Remember that this class does not exist.
|
||||
$this->missingClasses[$class] = true;
|
||||
}
|
||||
|
||||
return $file;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the currently registered loaders indexed by their corresponding vendor directories.
|
||||
*
|
||||
* @return self[]
|
||||
*/
|
||||
public static function getRegisteredLoaders()
|
||||
{
|
||||
return self::$registeredLoaders;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $class
|
||||
* @param string $ext
|
||||
* @return string|false
|
||||
*/
|
||||
private function findFileWithExtension($class, $ext)
|
||||
{
|
||||
// PSR-4 lookup
|
||||
$logicalPathPsr4 = strtr($class, '\\', DIRECTORY_SEPARATOR) . $ext;
|
||||
|
||||
$first = $class[0];
|
||||
if (isset($this->prefixLengthsPsr4[$first])) {
|
||||
$subPath = $class;
|
||||
while (false !== $lastPos = strrpos($subPath, '\\')) {
|
||||
$subPath = substr($subPath, 0, $lastPos);
|
||||
$search = $subPath . '\\';
|
||||
if (isset($this->prefixDirsPsr4[$search])) {
|
||||
$pathEnd = DIRECTORY_SEPARATOR . substr($logicalPathPsr4, $lastPos + 1);
|
||||
foreach ($this->prefixDirsPsr4[$search] as $dir) {
|
||||
if (file_exists($file = $dir . $pathEnd)) {
|
||||
return $file;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// PSR-4 fallback dirs
|
||||
foreach ($this->fallbackDirsPsr4 as $dir) {
|
||||
if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr4)) {
|
||||
return $file;
|
||||
}
|
||||
}
|
||||
|
||||
// PSR-0 lookup
|
||||
if (false !== $pos = strrpos($class, '\\')) {
|
||||
// namespaced class name
|
||||
$logicalPathPsr0 = substr($logicalPathPsr4, 0, $pos + 1)
|
||||
. strtr(substr($logicalPathPsr4, $pos + 1), '_', DIRECTORY_SEPARATOR);
|
||||
} else {
|
||||
// PEAR-like class name
|
||||
$logicalPathPsr0 = strtr($class, '_', DIRECTORY_SEPARATOR) . $ext;
|
||||
}
|
||||
|
||||
if (isset($this->prefixesPsr0[$first])) {
|
||||
foreach ($this->prefixesPsr0[$first] as $prefix => $dirs) {
|
||||
if (0 === strpos($class, $prefix)) {
|
||||
foreach ($dirs as $dir) {
|
||||
if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) {
|
||||
return $file;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// PSR-0 fallback dirs
|
||||
foreach ($this->fallbackDirsPsr0 as $dir) {
|
||||
if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) {
|
||||
return $file;
|
||||
}
|
||||
}
|
||||
|
||||
// PSR-0 include paths.
|
||||
if ($this->useIncludePath && $file = stream_resolve_include_path($logicalPathPsr0)) {
|
||||
return $file;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Scope isolated include.
|
||||
*
|
||||
* Prevents access to $this/self from included files.
|
||||
*
|
||||
* @param string $file
|
||||
* @return void
|
||||
* @private
|
||||
*/
|
||||
function includeFile($file)
|
||||
{
|
||||
include $file;
|
||||
}
|
||||
21
datamodels/2.x/itop-oauth-client/vendor/composer/LICENSE
vendored
Normal file
21
datamodels/2.x/itop-oauth-client/vendor/composer/LICENSE
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
|
||||
Copyright (c) Nils Adermann, Jordi Boggiano
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is furnished
|
||||
to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
|
||||
13
datamodels/2.x/itop-oauth-client/vendor/composer/autoload_classmap.php
vendored
Normal file
13
datamodels/2.x/itop-oauth-client/vendor/composer/autoload_classmap.php
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
<?php
|
||||
|
||||
// autoload_classmap.php @generated by Composer
|
||||
|
||||
$vendorDir = dirname(dirname(__FILE__));
|
||||
$baseDir = dirname($vendorDir);
|
||||
|
||||
return array(
|
||||
'Combodo\\iTop\\OAuthClient\\Controller\\AjaxOauthClientController' => $baseDir . '/src/Controller/AjaxOauthClientController.php',
|
||||
'Combodo\\iTop\\OAuthClient\\Controller\\OAuthClientController' => $baseDir . '/src/Controller/OAuthClientController.php',
|
||||
'Combodo\\iTop\\OAuthClient\\Service\\PopupMenuExtension' => $baseDir . '/src/Service/PopupMenuExtension.php',
|
||||
'Composer\\InstalledVersions' => $vendorDir . '/composer/InstalledVersions.php',
|
||||
);
|
||||
9
datamodels/2.x/itop-oauth-client/vendor/composer/autoload_namespaces.php
vendored
Normal file
9
datamodels/2.x/itop-oauth-client/vendor/composer/autoload_namespaces.php
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
<?php
|
||||
|
||||
// autoload_namespaces.php @generated by Composer
|
||||
|
||||
$vendorDir = dirname(dirname(__FILE__));
|
||||
$baseDir = dirname($vendorDir);
|
||||
|
||||
return array(
|
||||
);
|
||||
10
datamodels/2.x/itop-oauth-client/vendor/composer/autoload_psr4.php
vendored
Normal file
10
datamodels/2.x/itop-oauth-client/vendor/composer/autoload_psr4.php
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
<?php
|
||||
|
||||
// autoload_psr4.php @generated by Composer
|
||||
|
||||
$vendorDir = dirname(dirname(__FILE__));
|
||||
$baseDir = dirname($vendorDir);
|
||||
|
||||
return array(
|
||||
'Combodo\\iTop\\OAuthClient\\' => array($baseDir . '/src'),
|
||||
);
|
||||
46
datamodels/2.x/itop-oauth-client/vendor/composer/autoload_real.php
vendored
Normal file
46
datamodels/2.x/itop-oauth-client/vendor/composer/autoload_real.php
vendored
Normal file
@@ -0,0 +1,46 @@
|
||||
<?php
|
||||
|
||||
// autoload_real.php @generated by Composer
|
||||
|
||||
class ComposerAutoloaderInitd52424b43ff18219f2ec935428aff074
|
||||
{
|
||||
private static $loader;
|
||||
|
||||
public static function loadClassLoader($class)
|
||||
{
|
||||
if ('Composer\Autoload\ClassLoader' === $class) {
|
||||
require __DIR__ . '/ClassLoader.php';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \Composer\Autoload\ClassLoader
|
||||
*/
|
||||
public static function getLoader()
|
||||
{
|
||||
if (null !== self::$loader) {
|
||||
return self::$loader;
|
||||
}
|
||||
|
||||
spl_autoload_register(array('ComposerAutoloaderInitd52424b43ff18219f2ec935428aff074', 'loadClassLoader'), true, true);
|
||||
self::$loader = $loader = new \Composer\Autoload\ClassLoader(\dirname(\dirname(__FILE__)));
|
||||
spl_autoload_unregister(array('ComposerAutoloaderInitd52424b43ff18219f2ec935428aff074', 'loadClassLoader'));
|
||||
|
||||
$useStaticLoader = PHP_VERSION_ID >= 50600 && !defined('HHVM_VERSION') && (!function_exists('zend_loader_file_encoded') || !zend_loader_file_encoded());
|
||||
if ($useStaticLoader) {
|
||||
require __DIR__ . '/autoload_static.php';
|
||||
|
||||
call_user_func(\Composer\Autoload\ComposerStaticInitd52424b43ff18219f2ec935428aff074::getInitializer($loader));
|
||||
} else {
|
||||
$classMap = require __DIR__ . '/autoload_classmap.php';
|
||||
if ($classMap) {
|
||||
$loader->addClassMap($classMap);
|
||||
}
|
||||
}
|
||||
|
||||
$loader->setClassMapAuthoritative(true);
|
||||
$loader->register(true);
|
||||
|
||||
return $loader;
|
||||
}
|
||||
}
|
||||
39
datamodels/2.x/itop-oauth-client/vendor/composer/autoload_static.php
vendored
Normal file
39
datamodels/2.x/itop-oauth-client/vendor/composer/autoload_static.php
vendored
Normal file
@@ -0,0 +1,39 @@
|
||||
<?php
|
||||
|
||||
// autoload_static.php @generated by Composer
|
||||
|
||||
namespace Composer\Autoload;
|
||||
|
||||
class ComposerStaticInitd52424b43ff18219f2ec935428aff074
|
||||
{
|
||||
public static $prefixLengthsPsr4 = array (
|
||||
'C' =>
|
||||
array (
|
||||
'Combodo\\iTop\\OAuthClient\\' => 25,
|
||||
),
|
||||
);
|
||||
|
||||
public static $prefixDirsPsr4 = array (
|
||||
'Combodo\\iTop\\OAuthClient\\' =>
|
||||
array (
|
||||
0 => __DIR__ . '/../..' . '/src',
|
||||
),
|
||||
);
|
||||
|
||||
public static $classMap = array (
|
||||
'Combodo\\iTop\\OAuthClient\\Controller\\AjaxOauthClientController' => __DIR__ . '/../..' . '/src/Controller/AjaxOauthClientController.php',
|
||||
'Combodo\\iTop\\OAuthClient\\Controller\\OAuthClientController' => __DIR__ . '/../..' . '/src/Controller/OAuthClientController.php',
|
||||
'Combodo\\iTop\\OAuthClient\\Service\\PopupMenuExtension' => __DIR__ . '/../..' . '/src/Service/PopupMenuExtension.php',
|
||||
'Composer\\InstalledVersions' => __DIR__ . '/..' . '/composer/InstalledVersions.php',
|
||||
);
|
||||
|
||||
public static function getInitializer(ClassLoader $loader)
|
||||
{
|
||||
return \Closure::bind(function () use ($loader) {
|
||||
$loader->prefixLengthsPsr4 = ComposerStaticInitd52424b43ff18219f2ec935428aff074::$prefixLengthsPsr4;
|
||||
$loader->prefixDirsPsr4 = ComposerStaticInitd52424b43ff18219f2ec935428aff074::$prefixDirsPsr4;
|
||||
$loader->classMap = ComposerStaticInitd52424b43ff18219f2ec935428aff074::$classMap;
|
||||
|
||||
}, null, ClassLoader::class);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
<?php
|
||||
/**
|
||||
* Localized data
|
||||
*
|
||||
* @copyright Copyright (C) 2013 XXXXX
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
Dict::Add('ZH CN', 'Chinese', '简体中文', [
|
||||
'Menu:CreateMailbox' => 'Create a mailbox...~~',
|
||||
'Menu:OAuthClient' => 'OAuth Client~~',
|
||||
'Menu:OAuthClient+' => '~~',
|
||||
'Menu:GenerateTokens' => 'Generate access tokens...~~',
|
||||
'Menu:RegenerateTokens' => 'Regenerate access tokens...~~',
|
||||
|
||||
'itop-oauth-client/Operation:CreateMailBox/Title' => 'Mailbox creation~~',
|
||||
|
||||
'itop-oauth-client:UsedForSMTP' => 'This OAuth client is used for SMTP~~',
|
||||
'itop-oauth-client:TestSMTP' => 'Email send test~~',
|
||||
'itop-oauth-client:MissingOAuthClient' => 'Missing Oauth client for user name %1$s~~',
|
||||
'itop-oauth-client:Message:MissingToken' => 'Generate access token before using this OAuth client~~',
|
||||
'itop-oauth-client:Message:TokenCreated' => 'Access token created~~',
|
||||
'itop-oauth-client:Message:TokenRecreated' => 'Access token regenerated~~',
|
||||
]);
|
||||
|
||||
//
|
||||
// Class: OAuthClient
|
||||
//
|
||||
|
||||
Dict::Add('ZH CN', 'Chinese', '简体中文', [
|
||||
'Class:OAuthClient' => 'Oauth Client~~',
|
||||
'Class:OAuthClient/Attribute:provider' => 'Provider~~',
|
||||
'Class:OAuthClient/Attribute:provider+' => '~~',
|
||||
'Class:OAuthClient/Attribute:name' => 'Login~~',
|
||||
'Class:OAuthClient/Attribute:name+' => '~~',
|
||||
'Class:OAuthClient/Attribute:scope' => 'Scope~~',
|
||||
'Class:OAuthClient/Attribute:scope+' => '~~',
|
||||
'Class:OAuthClient/Attribute:description' => 'Description~~',
|
||||
'Class:OAuthClient/Attribute:description+' => '~~',
|
||||
'Class:OAuthClient/Attribute:client_id' => 'Client id~~',
|
||||
'Class:OAuthClient/Attribute:client_id+' => '~~',
|
||||
'Class:OAuthClient/Attribute:client_secret' => 'Client secret~~',
|
||||
'Class:OAuthClient/Attribute:client_secret+' => '~~',
|
||||
'Class:OAuthClient/Attribute:refresh_token' => 'Refresh token~~',
|
||||
'Class:OAuthClient/Attribute:refresh_token+' => '~~',
|
||||
'Class:OAuthClient/Attribute:refresh_token_expiration' => 'Refresh token expiration~~',
|
||||
'Class:OAuthClient/Attribute:refresh_token_expiration+' => '~~',
|
||||
'Class:OAuthClient/Attribute:token' => 'Access token~~',
|
||||
'Class:OAuthClient/Attribute:token+' => '~~',
|
||||
'Class:OAuthClient/Attribute:token_expiration' => 'Access token expiration~~',
|
||||
'Class:OAuthClient/Attribute:token_expiration+' => '~~',
|
||||
'Class:OAuthClient/Attribute:redirect_url' => 'Redirect url~~',
|
||||
'Class:OAuthClient/Attribute:redirect_url+' => '~~',
|
||||
'Class:OAuthClient/Attribute:mailbox_list' => 'Mailbox list~~',
|
||||
'Class:OAuthClient/Attribute:mailbox_list+' => '~~',
|
||||
]);
|
||||
|
||||
//
|
||||
// Class: OAuthClientAzure
|
||||
//
|
||||
Dict::Add('ZH CN', 'Chinese', '简体中文', [
|
||||
'Class:OAuthClientAzure' => 'OAuth client for Microsoft Azure~~',
|
||||
'Class:OAuthClientAzure/Name' => '%1$s (%2$s)~~',
|
||||
|
||||
]);
|
||||
|
||||
//
|
||||
// Class: OAuthClientGoogle
|
||||
//
|
||||
Dict::Add('ZH CN', 'Chinese', '简体中文', [
|
||||
'Class:OAuthClientGoogle' => 'OAuth client for Google~~',
|
||||
'Class:OAuthClientGoogle/Name' => '%1$s (%2$s)~~',
|
||||
]);
|
||||
|
||||
@@ -162,12 +162,20 @@ class BrickCollection
|
||||
// - Home
|
||||
$this->aHomeOrdering = $this->aAllowedBricks;
|
||||
usort($this->aHomeOrdering, function (PortalBrick $a, PortalBrick $b) {
|
||||
return $a->GetRankHome() > $b->GetRankHome();
|
||||
if ($a->GetRankHome() === $b->GetRankHome()) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return $a->GetRankHome() > $b->GetRankHome() ? 1 : -1;
|
||||
});
|
||||
// - Navigation menu
|
||||
$this->aNavigationMenuOrdering = $this->aAllowedBricks;
|
||||
usort($this->aNavigationMenuOrdering, function (PortalBrick $a, PortalBrick $b) {
|
||||
return $a->GetRankNavigationMenu() > $b->GetRankNavigationMenu();
|
||||
if ($a->GetRankNavigationMenu() === $b->GetRankNavigationMenu()) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return $a->GetRankNavigationMenu() > $b->GetRankNavigationMenu() ? 1 : -1;
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -481,7 +481,11 @@ class ManageBrick extends PortalBrick
|
||||
if (!$this->IsGroupingByDistinctValues($sName))
|
||||
{
|
||||
usort($this->aGrouping[$sName]['groups'], function ($a, $b) {
|
||||
return $a['rank'] > $b['rank'];
|
||||
if ($a['rank'] === $b['rank']) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return $a['rank'] > $b['rank'] ? 1 : -1;
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -91,7 +91,10 @@ class Lists extends AbstractConfiguration
|
||||
}
|
||||
// - Sorting list items by rank
|
||||
usort($aListItems, function ($a, $b) {
|
||||
return $a['rank'] > $b['rank'];
|
||||
if ($a['rank'] == $b['rank']) {
|
||||
return 0;
|
||||
}
|
||||
return $a['rank'] > $b['rank'] ? 1 : -1;
|
||||
});
|
||||
$aClassLists[$sListId] = $aListItems;
|
||||
}
|
||||
|
||||
@@ -91,8 +91,9 @@ class ObjectFormManager extends FormManager
|
||||
* @return array formmanager_data as a PHP array
|
||||
*
|
||||
* @since 2.7.6 3.0.0 N°4384 method creation : factorize as this is used twice now
|
||||
* @since 2.7.7 3.0.1 N°4867 now only used once, but we decided to keep this method anyway
|
||||
*/
|
||||
protected static function DecodeFormManagerData($formManagerData)
|
||||
public static function DecodeFormManagerData($formManagerData)
|
||||
{
|
||||
if (is_array($formManagerData)) {
|
||||
return $formManagerData;
|
||||
@@ -106,31 +107,18 @@ class ObjectFormManager extends FormManager
|
||||
* - formobject_class : The class of the object that is being edited/viewed
|
||||
* - formmode : view|edit|create
|
||||
* - values for parent
|
||||
* @param bool $bTrustContent if false then won't allow modified TWIG content
|
||||
*
|
||||
* @return \Combodo\iTop\Portal\Form\ObjectFormManager new instance init from JSON data
|
||||
*
|
||||
* @inheritDoc
|
||||
* @throws \Exception
|
||||
* @throws \SecurityException if twig content is present and $bTrustContent is false
|
||||
*
|
||||
* @since 2.7.6 3.0.0 N°4384 new $bTrustContent parameter
|
||||
* @since 2.7.7 3.0.1 N°4867 remove param $bTrustContent
|
||||
*/
|
||||
public static function FromJSON($sJson, $bTrustContent = false)
|
||||
public static function FromJSON($sJson)
|
||||
{
|
||||
$aJson = static::DecodeFormManagerData($sJson);
|
||||
|
||||
$oConfig = utils::GetConfig();
|
||||
$bIsContentCheckEnabled = $oConfig->GetModuleSetting(PORTAL_ID, 'enable_formmanager_content_check', true);
|
||||
if ($bIsContentCheckEnabled && (false === $bTrustContent)) {
|
||||
/** @noinspection NestedPositiveIfStatementsInspection */
|
||||
if (isset($aJson['formproperties']['layout']['type']) && ($aJson['formproperties']['layout']['type'] === 'twig')) {
|
||||
// There will be an IssueLog above in the hierarchy due to the exception, but we are logging here so that we can output the JSON data !
|
||||
IssueLog::Error('Portal received a query with forbidden twig content!', \LogChannels::PORTAL, ['formmanager_data' => $aJson]);
|
||||
throw new \SecurityException('Twig content not allowed in this context!');
|
||||
}
|
||||
}
|
||||
|
||||
/** @var \Combodo\iTop\Portal\Form\ObjectFormManager $oFormManager */
|
||||
$oFormManager = parent::FromJSON($sJson);
|
||||
|
||||
@@ -183,37 +171,6 @@ class ObjectFormManager extends FormManager
|
||||
return $oFormManager;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sPostedFormManagerData received data from the browser
|
||||
* @param array $aOriginalFormProperties data generated server side
|
||||
*
|
||||
* @return bool true if the data are identical
|
||||
*
|
||||
* @since 2.7.6 3.0.0 N°4384 Check formmanager_data
|
||||
*/
|
||||
public static function CanTrustFormLayoutContent($sPostedFormManagerData, $aOriginalFormProperties)
|
||||
{
|
||||
$aPostedFormManagerData = static::DecodeFormManagerData($sPostedFormManagerData);
|
||||
$sPostedFormLayoutType = (isset($aPostedFormManagerData['formproperties']['layout']['type'])) ? $aPostedFormManagerData['formproperties']['layout']['type'] : '';
|
||||
|
||||
if ($sPostedFormLayoutType === 'xhtml') {
|
||||
return true;
|
||||
}
|
||||
|
||||
// We need to parse the content so that autoclose tags are returned correctly (`<div />` => `<div></div>`)
|
||||
$oHtmlDocument = new \DOMDocument();
|
||||
|
||||
$sPostedFormLayoutContent = (isset($aPostedFormManagerData['formproperties']['layout']['content'])) ? $aPostedFormManagerData['formproperties']['layout']['content'] : '';
|
||||
$oHtmlDocument->loadXML('<root>'.$sPostedFormLayoutContent.'</root>');
|
||||
$sPostedFormLayoutRendered = $oHtmlDocument->saveHTML();
|
||||
|
||||
$sOriginalFormLayoutContent = (isset($aOriginalFormProperties['layout']['content'])) ? $aOriginalFormProperties['layout']['content'] : '';
|
||||
$oHtmlDocument->loadXML('<root>'.$sOriginalFormLayoutContent.'</root>');
|
||||
$sOriginalFormLayoutContentRendered = $oHtmlDocument->saveHTML();
|
||||
|
||||
return ($sPostedFormLayoutRendered === $sOriginalFormLayoutContentRendered);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return \Symfony\Component\DependencyInjection\ContainerInterface
|
||||
@@ -703,7 +660,7 @@ class ObjectFormManager extends FormManager
|
||||
|
||||
/** @var Field $oField */
|
||||
$oField = null;
|
||||
if (is_callable(get_class($oAttDef).'::MakeFormField'))
|
||||
if (is_callable([$oAttDef, 'MakeFormField']))
|
||||
{
|
||||
$oField = $oAttDef->MakeFormField($this->oObject);
|
||||
}
|
||||
@@ -1172,16 +1129,18 @@ class ObjectFormManager extends FormManager
|
||||
$sObjectClass = get_class($this->oObject);
|
||||
|
||||
try {
|
||||
// modification flags
|
||||
$bIsNew = $this->oObject->IsNew();
|
||||
$bWasModified = $this->oObject->IsModified();
|
||||
$bActivateTriggers = (!$bIsNew && $bWasModified);
|
||||
|
||||
// Forcing allowed writing on the object if necessary. This is used in some particular cases.
|
||||
$bAllowWrite = ($sObjectClass === 'Person' && $this->oObject->GetKey() == UserRights::GetContactId());
|
||||
$bAllowWrite = $this->oContainer->get('security_helper')->IsActionAllowed($bIsNew ? UR_ACTION_CREATE : UR_ACTION_MODIFY, $sObjectClass, $this->oObject->GetKey());
|
||||
if ($bAllowWrite) {
|
||||
$this->oObject->AllowWrite(true);
|
||||
}
|
||||
|
||||
// Writing object to DB
|
||||
$bIsNew = $this->oObject->IsNew();
|
||||
$bWasModified = $this->oObject->IsModified();
|
||||
$bActivateTriggers = (!$bIsNew && $bWasModified);
|
||||
try
|
||||
{
|
||||
$this->oObject->DBWrite();
|
||||
|
||||
@@ -132,12 +132,10 @@ class ObjectFormHandlerHelper
|
||||
$bModal = ($oRequest->isXmlHttpRequest() && empty($sOperation));
|
||||
|
||||
// - Retrieve form properties
|
||||
$aOriginalFormProperties = ApplicationHelper::GetLoadedFormFromClass($this->aCombodoPortalInstanceConf['forms'], $sObjectClass, $sMode);
|
||||
if ($aFormProperties === null)
|
||||
{
|
||||
$aFormProperties = $aOriginalFormProperties;
|
||||
$aFormProperties = ApplicationHelper::GetLoadedFormFromClass($this->aCombodoPortalInstanceConf['forms'], $sObjectClass, $sMode);
|
||||
}
|
||||
|
||||
// - Create and
|
||||
if (empty($sOperation))
|
||||
{
|
||||
@@ -299,8 +297,8 @@ class ObjectFormHandlerHelper
|
||||
throw new HttpException(Response::HTTP_INTERNAL_SERVER_ERROR, 'Parameters formmanager_class and formmanager_data must be defined.');
|
||||
}
|
||||
|
||||
$bTrustContent = $sFormManagerClass::CanTrustFormLayoutContent($sFormManagerData, $aOriginalFormProperties);
|
||||
$oFormManager = $sFormManagerClass::FromJSON($sFormManagerData, $bTrustContent);
|
||||
$this->CheckReadFormDataAllowed($sFormManagerData);
|
||||
$oFormManager = $sFormManagerClass::FromJSON($sFormManagerData);
|
||||
$oFormManager->SetContainer($this->oContainer);
|
||||
|
||||
// Applying action rules if present
|
||||
@@ -438,6 +436,29 @@ class ObjectFormHandlerHelper
|
||||
return $oTwig->render($sId, $aData);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if read object include in form data is allowed, throw an exception otherwise.
|
||||
*
|
||||
* @since 2.7.7
|
||||
*
|
||||
* @param $sFormManagerData form data to check
|
||||
*
|
||||
* @return void
|
||||
* @throws \CoreException
|
||||
* @throws \MissingQueryArgument
|
||||
* @throws \MySQLException
|
||||
* @throws \MySQLHasGoneAwayException
|
||||
* @throws \OQLException
|
||||
*/
|
||||
public function CheckReadFormDataAllowed($sFormManagerData){
|
||||
$aJsonFromData = ObjectFormManager::DecodeFormManagerData($sFormManagerData);
|
||||
if(isset($aJsonFromData['formobject_class'])
|
||||
&& isset($aJsonFromData['formobject_id'])
|
||||
&& !$this->oSecurityHelper->IsActionAllowed(UR_ACTION_READ, $aJsonFromData['formobject_class'], $aJsonFromData['formobject_id'])){
|
||||
throw new HttpException(Response::HTTP_INTERNAL_SERVER_ERROR, 'Form data access denied.');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return an array of the available modes for a form.
|
||||
*
|
||||
|
||||
@@ -103,6 +103,12 @@ class SecurityHelper
|
||||
return false;
|
||||
}
|
||||
|
||||
// Forcing allowed writing on the object if necessary. This is used in some particular cases.
|
||||
$bObjectIsCurrentUser = ($sObjectClass === 'Person' && $sObjectId == UserRights::GetContactId());
|
||||
if(in_array($sAction , array(UR_ACTION_MODIFY, UR_ACTION_READ)) && $bObjectIsCurrentUser){
|
||||
return true;
|
||||
}
|
||||
|
||||
// Checking the scopes layer
|
||||
// - Transforming scope action as there is only 2 values
|
||||
$sScopeAction = ($sAction === UR_ACTION_READ) ? UR_ACTION_READ : UR_ACTION_MODIFY;
|
||||
|
||||
@@ -99,7 +99,14 @@ class AppExtension extends AbstractExtension
|
||||
|
||||
return $sUrl;
|
||||
});
|
||||
|
||||
//since 2.7.7 3.0.2 3.1.0 N°4867 "Twig content not allowed" error when use the extkey widget search icon in the user portal
|
||||
//overwrite native twig filter : disable use of 'system' filter
|
||||
$filters[] = new Twig_SimpleFilter('filter', function ($array, $arrow) {
|
||||
if ($arrow == 'system'){
|
||||
return json_encode($array);
|
||||
}
|
||||
return twig_array_filter($array, $arrow);
|
||||
});
|
||||
|
||||
return $filters;
|
||||
}
|
||||
|
||||
@@ -1047,4 +1047,14 @@ Dict::Add('CS CZ', 'Czech', 'Čeština', array(
|
||||
'Class:AsyncTask/Attribute:event_id+' => '~~',
|
||||
'Class:AsyncTask/Attribute:finalclass' => 'Final class~~',
|
||||
'Class:AsyncTask/Attribute:finalclass+' => '~~',
|
||||
'Class:AsyncTask/Attribute:status' => 'Status~~',
|
||||
'Class:AsyncTask/Attribute:status+' => '~~',
|
||||
'Class:AsyncTask/Attribute:remaining_retries' => 'Remaining retries~~',
|
||||
'Class:AsyncTask/Attribute:remaining_retries+' => '~~',
|
||||
'Class:AsyncTask/Attribute:last_error_code' => 'Last error code~~',
|
||||
'Class:AsyncTask/Attribute:last_error_code+' => '~~',
|
||||
'Class:AsyncTask/Attribute:last_error' => 'Last error~~',
|
||||
'Class:AsyncTask/Attribute:last_error+' => '~~',
|
||||
'Class:AsyncTask/Attribute:last_attempt' => 'Last attempt~~',
|
||||
'Class:AsyncTask/Attribute:last_attempt+' => '~~',
|
||||
));
|
||||
|
||||
@@ -455,6 +455,7 @@ Dict::Add('CS CZ', 'Czech', 'Čeština', array(
|
||||
'UI:Error:ObjectsAlreadyDeleted' => 'Chyba: objekt byl již odstraněn!',
|
||||
'UI:Error:BulkDeleteNotAllowedOn_Class' => 'Nemáte oprávnění k hromadnému odstranění objektů třídy %1$s',
|
||||
'UI:Error:DeleteNotAllowedOn_Class' => 'Nemáte oprávnění k odstranění objektů třídy %1$s',
|
||||
'UI:Error:ReadNotAllowedOn_Class' => 'You are not allowed to view objects of class %1$s~~',
|
||||
'UI:Error:BulkModifyNotAllowedOn_Class' => 'Nemáte oprávnění k hromadné aktualizaci objektů třídy %1$s',
|
||||
'UI:Error:ObjectAlreadyCloned' => 'Chyba: objekt byl již naklonován!',
|
||||
'UI:Error:ObjectAlreadyCreated' => 'Chyba: objekt byl již vytvořen!',
|
||||
@@ -463,6 +464,9 @@ Dict::Add('CS CZ', 'Czech', 'Čeština', array(
|
||||
'UI:Error:InvalidDashboard' => 'Error: invalid dashboard~~',
|
||||
'UI:Error:MaintenanceMode' => 'Application is currently in maintenance~~',
|
||||
'UI:Error:MaintenanceTitle' => 'Maintenance~~',
|
||||
'UI:Error:InvalidToken' => 'Error: the requested operation has already been performed (CSRF token not found)~~',
|
||||
|
||||
'UI:Error:SMTP:UnknownVendor' => 'OAuth SMTP provider %1$s does not exist (email_transport_smtp.oauth.provider)~~',
|
||||
|
||||
'UI:GroupBy:Count' => 'Množství',
|
||||
'UI:GroupBy:Count+' => 'Množství prvků',
|
||||
@@ -1553,6 +1557,8 @@ Dict::Add('CS CZ', 'Czech', 'Čeština', array(
|
||||
|
||||
'UI:Search:Criteria:Raw:Filtered' => 'Filtered~~',
|
||||
'UI:Search:Criteria:Raw:FilteredOn' => 'Filtered on %1$s~~',
|
||||
|
||||
'UI:StateChanged' => 'State changed~~',
|
||||
));
|
||||
|
||||
//
|
||||
|
||||
@@ -1045,4 +1045,14 @@ Dict::Add('DA DA', 'Danish', 'Dansk', array(
|
||||
'Class:AsyncTask/Attribute:event_id+' => '~~',
|
||||
'Class:AsyncTask/Attribute:finalclass' => 'Final class~~',
|
||||
'Class:AsyncTask/Attribute:finalclass+' => '~~',
|
||||
'Class:AsyncTask/Attribute:status' => 'Status~~',
|
||||
'Class:AsyncTask/Attribute:status+' => '~~',
|
||||
'Class:AsyncTask/Attribute:remaining_retries' => 'Remaining retries~~',
|
||||
'Class:AsyncTask/Attribute:remaining_retries+' => '~~',
|
||||
'Class:AsyncTask/Attribute:last_error_code' => 'Last error code~~',
|
||||
'Class:AsyncTask/Attribute:last_error_code+' => '~~',
|
||||
'Class:AsyncTask/Attribute:last_error' => 'Last error~~',
|
||||
'Class:AsyncTask/Attribute:last_error+' => '~~',
|
||||
'Class:AsyncTask/Attribute:last_attempt' => 'Last attempt~~',
|
||||
'Class:AsyncTask/Attribute:last_attempt+' => '~~',
|
||||
));
|
||||
|
||||
@@ -442,6 +442,7 @@ Dict::Add('DA DA', 'Danish', 'Dansk', array(
|
||||
'UI:Error:ObjectsAlreadyDeleted' => 'Fejl: objekterne er allerede slettet!',
|
||||
'UI:Error:BulkDeleteNotAllowedOn_Class' => 'Du har ikke tilladelse til at foretage en masse sletning af objekter i klassen %1$s',
|
||||
'UI:Error:DeleteNotAllowedOn_Class' => 'Du har ikke tilladelse til at slette objekter af klassen %1$s',
|
||||
'UI:Error:ReadNotAllowedOn_Class' => 'You are not allowed to view objects of class %1$s~~',
|
||||
'UI:Error:BulkModifyNotAllowedOn_Class' => 'Du har ikke tilladelse til at foretage en masse opdatering af objekter i klassen %1$s',
|
||||
'UI:Error:ObjectAlreadyCloned' => 'Fejl: objektet er allerede klonet!',
|
||||
'UI:Error:ObjectAlreadyCreated' => 'Fejl: objektet er allerede oprettet!',
|
||||
@@ -450,6 +451,9 @@ Dict::Add('DA DA', 'Danish', 'Dansk', array(
|
||||
'UI:Error:InvalidDashboard' => 'Error: invalid dashboard~~',
|
||||
'UI:Error:MaintenanceMode' => 'Application is currently in maintenance~~',
|
||||
'UI:Error:MaintenanceTitle' => 'Maintenance~~',
|
||||
'UI:Error:InvalidToken' => 'Error: the requested operation has already been performed (CSRF token not found)~~',
|
||||
|
||||
'UI:Error:SMTP:UnknownVendor' => 'OAuth SMTP provider %1$s does not exist (email_transport_smtp.oauth.provider)~~',
|
||||
|
||||
'UI:GroupBy:Count' => 'Antal',
|
||||
'UI:GroupBy:Count+' => 'Antal af elementer',
|
||||
@@ -1542,6 +1546,8 @@ Ved tilknytningen til en trigger, bliver hver handling tildelt et "rækkefølge"
|
||||
|
||||
'UI:Search:Criteria:Raw:Filtered' => 'Filtered~~',
|
||||
'UI:Search:Criteria:Raw:FilteredOn' => 'Filtered on %1$s~~',
|
||||
|
||||
'UI:StateChanged' => 'State changed~~',
|
||||
));
|
||||
|
||||
//
|
||||
|
||||
@@ -1044,4 +1044,14 @@ Dict::Add('DE DE', 'German', 'Deutsch', array(
|
||||
'Class:AsyncTask/Attribute:event_id+' => '',
|
||||
'Class:AsyncTask/Attribute:finalclass' => 'Final Class',
|
||||
'Class:AsyncTask/Attribute:finalclass+' => '',
|
||||
'Class:AsyncTask/Attribute:status' => 'Status~~',
|
||||
'Class:AsyncTask/Attribute:status+' => '~~',
|
||||
'Class:AsyncTask/Attribute:remaining_retries' => 'Remaining retries~~',
|
||||
'Class:AsyncTask/Attribute:remaining_retries+' => '~~',
|
||||
'Class:AsyncTask/Attribute:last_error_code' => 'Last error code~~',
|
||||
'Class:AsyncTask/Attribute:last_error_code+' => '~~',
|
||||
'Class:AsyncTask/Attribute:last_error' => 'Last error~~',
|
||||
'Class:AsyncTask/Attribute:last_error+' => '~~',
|
||||
'Class:AsyncTask/Attribute:last_attempt' => 'Last attempt~~',
|
||||
'Class:AsyncTask/Attribute:last_attempt+' => '~~',
|
||||
));
|
||||
|
||||
@@ -441,6 +441,7 @@ Dict::Add('DE DE', 'German', 'Deutsch', array(
|
||||
'UI:Error:ObjectsAlreadyDeleted' => 'Fehler: die Objekte wurden bereits gelöscht!',
|
||||
'UI:Error:BulkDeleteNotAllowedOn_Class' => 'Sie sind nicht berechtigt, mehrere Objekte der Klasse %1$s zu löschen',
|
||||
'UI:Error:DeleteNotAllowedOn_Class' => 'Sie sind nicht berechtigt, Objekte der Klasse zu löschen %1$s',
|
||||
'UI:Error:ReadNotAllowedOn_Class' => 'You are not allowed to view objects of class %1$s~~',
|
||||
'UI:Error:BulkModifyNotAllowedOn_Class' => 'Sie sind nicht berechtigt, diese Massenaktualisierung der Objekte der Klasse "%1$s" durchzuführen.',
|
||||
'UI:Error:ObjectAlreadyCloned' => 'Fehler: das Objekt wurde bereits dupliziert!',
|
||||
'UI:Error:ObjectAlreadyCreated' => 'Fehler: das Objekt wurde bereits erstellt!',
|
||||
@@ -449,6 +450,9 @@ Dict::Add('DE DE', 'German', 'Deutsch', array(
|
||||
'UI:Error:InvalidDashboard' => 'Fehler: Ungültiges Dashboard',
|
||||
'UI:Error:MaintenanceMode' => 'Die Anwendung befindet sich derzeit im Wartungsmodus.',
|
||||
'UI:Error:MaintenanceTitle' => 'Wartung',
|
||||
'UI:Error:InvalidToken' => 'Error: the requested operation has already been performed (CSRF token not found)~~',
|
||||
|
||||
'UI:Error:SMTP:UnknownVendor' => 'OAuth SMTP provider %1$s does not exist (email_transport_smtp.oauth.provider)~~',
|
||||
|
||||
'UI:GroupBy:Count' => 'Anzahl',
|
||||
'UI:GroupBy:Count+' => 'Anzahl der Elemente',
|
||||
@@ -1540,6 +1544,8 @@ Wenn Aktionen mit Trigger verknüpft sind, bekommt jede Aktion eine Auftragsnumm
|
||||
|
||||
'UI:Search:Criteria:Raw:Filtered' => 'Gefiltert',
|
||||
'UI:Search:Criteria:Raw:FilteredOn' => 'Gefiltert über %1$s',
|
||||
|
||||
'UI:StateChanged' => 'State changed~~',
|
||||
));
|
||||
|
||||
//
|
||||
|
||||
@@ -468,6 +468,8 @@ Dict::Add('EN US', 'English', 'English', array(
|
||||
'UI:Error:MaintenanceTitle' => 'Maintenance',
|
||||
'UI:Error:InvalidToken' => 'Error: the requested operation has already been performed (CSRF token not found)',
|
||||
|
||||
'UI:Error:SMTP:UnknownVendor' => 'OAuth SMTP provider %1$s does not exist (email_transport_smtp.oauth.provider)',
|
||||
|
||||
'UI:GroupBy:Count' => 'Count',
|
||||
'UI:GroupBy:Count+' => 'Number of elements',
|
||||
'UI:CountOfObjects' => '%1$d objects matching the criteria.',
|
||||
|
||||
@@ -22,62 +22,62 @@
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
* @traductor Miguel Turrubiates <miguel_tf@yahoo.com>
|
||||
*/
|
||||
Dict::Add('ES CR', 'Spanish', 'Español, Castellano', array(
|
||||
Dict::Add('ES CR', 'Spanish', 'Español, Castellaño', array(
|
||||
'Core:DeletedObjectLabel' => '%1s (eliminado)',
|
||||
'Core:DeletedObjectTip' => 'Elemento ha sido Eliminado en %1$s (%2$s)',
|
||||
'Core:DeletedObjectTip' => 'Elemento ha sido Eliminado en %1$s (%2$s)',
|
||||
|
||||
'Core:UnknownObjectLabel' => 'Elemento No Encontrado (Clase: %1$s, Identificador: %2$d)',
|
||||
'Core:UnknownObjectTip' => 'El Elemento no pudo ser encontrado. Pudo haber sido eliminado hace tiempo y purgado de la Bitácora.',
|
||||
|
||||
'Core:UniquenessDefaultError' => 'Regla de unicidad \'%1$s\' en error',
|
||||
|
||||
'Core:AttributeLinkedSet' => 'Arreglo de objetos',
|
||||
'Core:AttributeLinkedSet' => 'Arreglo de objetos',
|
||||
'Core:AttributeLinkedSet+' => 'Cualquier tipo de objetos [subclass] de la misma clase',
|
||||
|
||||
'Core:AttributeDashboard' => 'Panel de Control',
|
||||
'Core:AttributeDashboard' => 'Panel de Control',
|
||||
'Core:AttributeDashboard+' => 'Panel de control y supervisión',
|
||||
|
||||
'Core:AttributePhoneNumber' => 'Número telefónico',
|
||||
'Core:AttributePhoneNumber' => 'Número telefónico',
|
||||
'Core:AttributePhoneNumber+' => '',
|
||||
|
||||
'Core:AttributeObsolescenceDate' => 'Fecha de Obsolescencia',
|
||||
'Core:AttributeObsolescenceDate' => 'Fecha de Obsolescencia',
|
||||
'Core:AttributeObsolescenceDate+' => '',
|
||||
|
||||
'Core:AttributeTagSet' => 'Lista de etiquetas',
|
||||
'Core:AttributeTagSet+' => '',
|
||||
'Core:AttributeSet:placeholder' => 'Click to agregar',
|
||||
'Core:AttributeClassAttCodeSet:ItemLabel:AttributeFromClass' => '%1$s (%2$s)',
|
||||
'Core:AttributeClassAttCodeSet:ItemLabel:AttributeFromOneChildClass' => '%1$s (%2$s de %3$s)',
|
||||
'Core:AttributeTagSet' => 'Lista de etiquetas',
|
||||
'Core:AttributeTagSet+' => '',
|
||||
'Core:AttributeSet:placeholder' => 'Click to agregar',
|
||||
'Core:AttributeClassAttCodeSet:ItemLabel:AttributeFromClass' => '%1$s (%2$s)',
|
||||
'Core:AttributeClassAttCodeSet:ItemLabel:AttributeFromOneChildClass' => '%1$s (%2$s de %3$s)',
|
||||
'Core:AttributeClassAttCodeSet:ItemLabel:AttributeFromSeveralChildClasses' => '%1$s (%2$s de clases hijas)',
|
||||
|
||||
'Core:AttributeCaseLog' => 'Bitácora',
|
||||
'Core:AttributeCaseLog' => 'Bitácora',
|
||||
'Core:AttributeCaseLog+' => '',
|
||||
|
||||
'Core:AttributeMetaEnum' => 'Enumeración Calculada',
|
||||
'Core:AttributeMetaEnum' => 'Enumeración Calculada',
|
||||
'Core:AttributeMetaEnum+' => '',
|
||||
|
||||
'Core:AttributeLinkedSetIndirect' => 'Arreglo de objetos (N-N)',
|
||||
'Core:AttributeLinkedSetIndirect' => 'Arreglo de objetos (N-N)',
|
||||
'Core:AttributeLinkedSetIndirect+' => 'Cualquier tipo de objetos [subclass] de la misma clase',
|
||||
|
||||
'Core:AttributeInteger' => 'Entero',
|
||||
'Core:AttributeInteger' => 'Entero',
|
||||
'Core:AttributeInteger+' => 'Valor numérico (puede ser negativo)',
|
||||
|
||||
'Core:AttributeDecimal' => 'Decimal',
|
||||
'Core:AttributeDecimal' => 'Decimal',
|
||||
'Core:AttributeDecimal+' => 'Valor decimal (puede ser negativo)',
|
||||
|
||||
'Core:AttributeBoolean' => 'Booleano',
|
||||
'Core:AttributeBoolean+' => 'Booleano',
|
||||
'Core:AttributeBoolean' => 'Booleano',
|
||||
'Core:AttributeBoolean+' => 'Booleano',
|
||||
'Core:AttributeBoolean/Value:null' => 'Nulo',
|
||||
'Core:AttributeBoolean/Value:yes' => 'Si',
|
||||
'Core:AttributeBoolean/Value:no' => 'No',
|
||||
'Core:AttributeBoolean/Value:yes' => 'Si',
|
||||
'Core:AttributeBoolean/Value:no' => 'No',
|
||||
|
||||
'Core:AttributeArchiveFlag' => 'Bandera de Archivado',
|
||||
'Core:AttributeArchiveFlag/Value:yes' => 'Si',
|
||||
'Core:AttributeArchiveFlag' => 'Bandera de Archivado',
|
||||
'Core:AttributeArchiveFlag/Value:yes' => 'Si',
|
||||
'Core:AttributeArchiveFlag/Value:yes+' => 'Este objeto es solo visible en modo Archivado',
|
||||
'Core:AttributeArchiveFlag/Value:no' => 'No',
|
||||
'Core:AttributeArchiveFlag/Label' => 'Archivado',
|
||||
'Core:AttributeArchiveFlag/Label+' => '',
|
||||
'Core:AttributeArchiveDate/Label' => 'Fecha de Archivado',
|
||||
'Core:AttributeArchiveFlag/Value:no' => 'No',
|
||||
'Core:AttributeArchiveFlag/Label' => 'Archivado',
|
||||
'Core:AttributeArchiveFlag/Label+' => '',
|
||||
'Core:AttributeArchiveDate/Label' => 'Fecha de Archivado',
|
||||
'Core:AttributeArchiveDate/Label+' => '',
|
||||
|
||||
'Core:AttributeObsolescenceFlag' => 'Bandera de Obsolescencia',
|
||||
@@ -193,24 +193,24 @@ Operadores:<br/>
|
||||
'Core:AttributeTable' => 'Tabla',
|
||||
'Core:AttributeTable+' => 'Arreglo indexado con dos dimensiones',
|
||||
|
||||
'Core:AttributePropertySet' => 'Propiedades',
|
||||
'Core:AttributePropertySet' => 'Propiedades',
|
||||
'Core:AttributePropertySet+' => 'Lista de propiedades sin tipo (nombre y valor)',
|
||||
|
||||
'Core:AttributeFriendlyName' => 'Nombre común',
|
||||
'Core:AttributeFriendlyName' => 'Nombre común',
|
||||
'Core:AttributeFriendlyName+' => 'Atributo creado automáticamente; el nombre común es obtenido de varios atributos',
|
||||
|
||||
'Core:FriendlyName-Label' => 'Nombre común',
|
||||
'Core:FriendlyName-Label' => 'Nombre común',
|
||||
'Core:FriendlyName-Description' => 'Nombre común',
|
||||
|
||||
'Core:AttributeTag' => 'Etiquetas',
|
||||
'Core:AttributeTag' => 'Etiquetas',
|
||||
'Core:AttributeTag+' => '',
|
||||
|
||||
'Core:Context=REST/JSON' => 'REST',
|
||||
'Core:Context=Synchro' => 'Synchro',
|
||||
'Core:Context=Setup' => 'Configuración',
|
||||
|
||||
'Core:Context=REST/JSON' => 'REST',
|
||||
'Core:Context=Synchro' => 'Synchro',
|
||||
'Core:Context=Setup' => 'Configuración',
|
||||
'Core:Context=GUI:Console' => 'Consola',
|
||||
'Core:Context=CRON' => 'cron',
|
||||
'Core:Context=GUI:Portal' => 'Portal',
|
||||
'Core:Context=CRON' => 'cron',
|
||||
'Core:Context=GUI:Portal' => 'Portal',
|
||||
));
|
||||
|
||||
|
||||
@@ -223,7 +223,7 @@ Operadores:<br/>
|
||||
// Class: CMDBChange
|
||||
//
|
||||
|
||||
Dict::Add('ES CR', 'Spanish', 'Español, Castellano', array(
|
||||
Dict::Add('ES CR', 'Spanish', 'Español, Castellaño', array(
|
||||
'Class:CMDBChange' => 'Cambio',
|
||||
'Class:CMDBChange+' => 'Cambios',
|
||||
'Class:CMDBChange/Attribute:date' => 'Fecha',
|
||||
@@ -236,7 +236,7 @@ Dict::Add('ES CR', 'Spanish', 'Español, Castellano', array(
|
||||
// Class: CMDBChangeOp
|
||||
//
|
||||
|
||||
Dict::Add('ES CR', 'Spanish', 'Español, Castellano', array(
|
||||
Dict::Add('ES CR', 'Spanish', 'Español, Castellaño', array(
|
||||
'Class:CMDBChangeOp' => 'Operación de Cambios',
|
||||
'Class:CMDBChangeOp+' => 'Operación de Cambios',
|
||||
'Class:CMDBChangeOp/Attribute:change' => 'Cambio',
|
||||
@@ -257,7 +257,7 @@ Dict::Add('ES CR', 'Spanish', 'Español, Castellano', array(
|
||||
// Class: CMDBChangeOpCreate
|
||||
//
|
||||
|
||||
Dict::Add('ES CR', 'Spanish', 'Español, Castellano', array(
|
||||
Dict::Add('ES CR', 'Spanish', 'Español, Castellaño', array(
|
||||
'Class:CMDBChangeOpCreate' => 'Creación de Objeto',
|
||||
'Class:CMDBChangeOpCreate+' => 'Creación de Objeto',
|
||||
));
|
||||
@@ -266,7 +266,7 @@ Dict::Add('ES CR', 'Spanish', 'Español, Castellano', array(
|
||||
// Class: CMDBChangeOpDelete
|
||||
//
|
||||
|
||||
Dict::Add('ES CR', 'Spanish', 'Español, Castellano', array(
|
||||
Dict::Add('ES CR', 'Spanish', 'Español, Castellaño', array(
|
||||
'Class:CMDBChangeOpDelete' => 'Borrado de Objeto',
|
||||
'Class:CMDBChangeOpDelete+' => 'Borrado de Objeto',
|
||||
));
|
||||
@@ -275,7 +275,7 @@ Dict::Add('ES CR', 'Spanish', 'Español, Castellano', array(
|
||||
// Class: CMDBChangeOpSetAttribute
|
||||
//
|
||||
|
||||
Dict::Add('ES CR', 'Spanish', 'Español, Castellano', array(
|
||||
Dict::Add('ES CR', 'Spanish', 'Español, Castellaño', array(
|
||||
'Class:CMDBChangeOpSetAttribute' => 'Cambio en Objeto',
|
||||
'Class:CMDBChangeOpSetAttribute+' => 'Cambio en Objeto',
|
||||
'Class:CMDBChangeOpSetAttribute/Attribute:attcode' => 'Atributo',
|
||||
@@ -286,7 +286,7 @@ Dict::Add('ES CR', 'Spanish', 'Español, Castellano', array(
|
||||
// Class: CMDBChangeOpSetAttributeScalar
|
||||
//
|
||||
|
||||
Dict::Add('ES CR', 'Spanish', 'Español, Castellano', array(
|
||||
Dict::Add('ES CR', 'Spanish', 'Español, Castellaño', array(
|
||||
'Class:CMDBChangeOpSetAttributeScalar' => 'Cambio de Propiedad',
|
||||
'Class:CMDBChangeOpSetAttributeScalar+' => 'Cambio de Propiedades escalares del Objeto',
|
||||
'Class:CMDBChangeOpSetAttributeScalar/Attribute:oldvalue' => 'Valor Anterior',
|
||||
@@ -295,7 +295,7 @@ Dict::Add('ES CR', 'Spanish', 'Español, Castellano', array(
|
||||
'Class:CMDBChangeOpSetAttributeScalar/Attribute:newvalue+' => 'Nuevo Valor del Atributo',
|
||||
));
|
||||
// Used by CMDBChangeOp... & derived classes
|
||||
Dict::Add('ES CR', 'Spanish', 'Español, Castellano', array(
|
||||
Dict::Add('ES CR', 'Spanish', 'Español, Castellaño', array(
|
||||
'Change:ObjectCreated' => 'Objeto Creado',
|
||||
'Change:ObjectDeleted' => 'Objeto Eliminado',
|
||||
'Change:ObjectModified' => 'Objeto Modificado',
|
||||
@@ -314,7 +314,7 @@ Dict::Add('ES CR', 'Spanish', 'Español, Castellano', array(
|
||||
// Class: CMDBChangeOpSetAttributeBlob
|
||||
//
|
||||
|
||||
Dict::Add('ES CR', 'Spanish', 'Español, Castellano', array(
|
||||
Dict::Add('ES CR', 'Spanish', 'Español, Castellaño', array(
|
||||
'Class:CMDBChangeOpSetAttributeBlob' => 'Cambio de Datos',
|
||||
'Class:CMDBChangeOpSetAttributeBlob+' => 'Cambio de Datos',
|
||||
'Class:CMDBChangeOpSetAttributeBlob/Attribute:prevdata' => 'Valor Anterior',
|
||||
@@ -325,7 +325,7 @@ Dict::Add('ES CR', 'Spanish', 'Español, Castellano', array(
|
||||
// Class: CMDBChangeOpSetAttributeText
|
||||
//
|
||||
|
||||
Dict::Add('ES CR', 'Spanish', 'Español, Castellano', array(
|
||||
Dict::Add('ES CR', 'Spanish', 'Español, Castellaño', array(
|
||||
'Class:CMDBChangeOpSetAttributeText' => 'Cambio de Texto',
|
||||
'Class:CMDBChangeOpSetAttributeText+' => 'Cambio de Texto',
|
||||
'Class:CMDBChangeOpSetAttributeText/Attribute:prevdata' => 'Valor Anterior',
|
||||
@@ -336,7 +336,7 @@ Dict::Add('ES CR', 'Spanish', 'Español, Castellano', array(
|
||||
// Class: Event
|
||||
//
|
||||
|
||||
Dict::Add('ES CR', 'Spanish', 'Español, Castellano', array(
|
||||
Dict::Add('ES CR', 'Spanish', 'Español, Castellaño', array(
|
||||
'Class:Event' => 'Bitácora de Eventos',
|
||||
'Class:Event+' => 'Evento interno de aplicación',
|
||||
'Class:Event/Attribute:message' => 'Mensaje',
|
||||
@@ -353,7 +353,7 @@ Dict::Add('ES CR', 'Spanish', 'Español, Castellano', array(
|
||||
// Class: EventNotification
|
||||
//
|
||||
|
||||
Dict::Add('ES CR', 'Spanish', 'Español, Castellano', array(
|
||||
Dict::Add('ES CR', 'Spanish', 'Español, Castellaño', array(
|
||||
'Class:EventNotification' => 'Notificación de Evento',
|
||||
'Class:EventNotification+' => 'Notificación de Evento',
|
||||
'Class:EventNotification/Attribute:trigger_id' => 'Disparador',
|
||||
@@ -368,7 +368,7 @@ Dict::Add('ES CR', 'Spanish', 'Español, Castellano', array(
|
||||
// Class: EventNotificationEmail
|
||||
//
|
||||
|
||||
Dict::Add('ES CR', 'Spanish', 'Español, Castellano', array(
|
||||
Dict::Add('ES CR', 'Spanish', 'Español, Castellaño', array(
|
||||
'Class:EventNotificationEmail' => 'Correo Electrónico de Notificación de Evento',
|
||||
'Class:EventNotificationEmail+' => 'Correo Electrónico de Notificación de Evento',
|
||||
'Class:EventNotificationEmail/Attribute:to' => 'Para',
|
||||
@@ -391,7 +391,7 @@ Dict::Add('ES CR', 'Spanish', 'Español, Castellano', array(
|
||||
// Class: EventIssue
|
||||
//
|
||||
|
||||
Dict::Add('ES CR', 'Spanish', 'Español, Castellano', array(
|
||||
Dict::Add('ES CR', 'Spanish', 'Español, Castellaño', array(
|
||||
'Class:EventIssue' => 'Registro de Evento',
|
||||
'Class:EventIssue+' => 'Evidencia de un evento (warning, error, etc.)',
|
||||
'Class:EventIssue/Attribute:issue' => 'Evento',
|
||||
@@ -414,7 +414,7 @@ Dict::Add('ES CR', 'Spanish', 'Español, Castellano', array(
|
||||
// Class: EventWebService
|
||||
//
|
||||
|
||||
Dict::Add('ES CR', 'Spanish', 'Español, Castellano', array(
|
||||
Dict::Add('ES CR', 'Spanish', 'Español, Castellaño', array(
|
||||
'Class:EventWebService' => 'Evento de WebService',
|
||||
'Class:EventWebService+' => 'Evidencia de una llamada de servicio Web',
|
||||
'Class:EventWebService/Attribute:verb' => 'Verbo',
|
||||
@@ -431,7 +431,7 @@ Dict::Add('ES CR', 'Spanish', 'Español, Castellano', array(
|
||||
'Class:EventWebService/Attribute:data+' => 'Datos de Resultado',
|
||||
));
|
||||
|
||||
Dict::Add('ES CR', 'Spanish', 'Español, Castellano', array(
|
||||
Dict::Add('ES CR', 'Spanish', 'Español, Castellaño', array(
|
||||
'Class:EventRestService' => 'Llamada REST/JSON',
|
||||
'Class:EventRestService+' => 'Traza de llamada a servicio REST/JSON',
|
||||
'Class:EventRestService/Attribute:operation' => 'Operación',
|
||||
@@ -452,7 +452,7 @@ Dict::Add('ES CR', 'Spanish', 'Español, Castellano', array(
|
||||
// Class: EventLoginUsage
|
||||
//
|
||||
|
||||
Dict::Add('ES CR', 'Spanish', 'Español, Castellano', array(
|
||||
Dict::Add('ES CR', 'Spanish', 'Español, Castellaño', array(
|
||||
'Class:EventLoginUsage' => 'Uso de la Cuenta',
|
||||
'Class:EventLoginUsage+' => 'Uso de la Cuenta',
|
||||
'Class:EventLoginUsage/Attribute:user_id' => 'Usuario',
|
||||
@@ -467,7 +467,7 @@ Dict::Add('ES CR', 'Spanish', 'Español, Castellano', array(
|
||||
// Class: Action
|
||||
//
|
||||
|
||||
Dict::Add('ES CR', 'Spanish', 'Español, Castellano', array(
|
||||
Dict::Add('ES CR', 'Spanish', 'Español, Castellaño', array(
|
||||
'Class:Action' => 'Acción Personalizada',
|
||||
'Class:Action+' => 'Acción definida por el usuario',
|
||||
'Class:Action/Attribute:name' => 'Nombre',
|
||||
@@ -492,7 +492,7 @@ Dict::Add('ES CR', 'Spanish', 'Español, Castellano', array(
|
||||
// Class: ActionNotification
|
||||
//
|
||||
|
||||
Dict::Add('ES CR', 'Spanish', 'Español, Castellano', array(
|
||||
Dict::Add('ES CR', 'Spanish', 'Español, Castellaño', array(
|
||||
'Class:ActionNotification' => 'Notificación',
|
||||
'Class:ActionNotification+' => 'Notificación (resúmen)',
|
||||
));
|
||||
@@ -501,7 +501,7 @@ Dict::Add('ES CR', 'Spanish', 'Español, Castellano', array(
|
||||
// Class: ActionEmail
|
||||
//
|
||||
|
||||
Dict::Add('ES CR', 'Spanish', 'Español, Castellano', array(
|
||||
Dict::Add('ES CR', 'Spanish', 'Español, Castellaño', array(
|
||||
'Class:ActionEmail' => 'Notificación por Correo Electrónico',
|
||||
'Class:ActionEmail+' => 'Notificación por Correo Electrónico',
|
||||
'Class:ActionEmail/Attribute:test_recipient' => 'Destinatario de Prueba',
|
||||
@@ -534,24 +534,24 @@ Dict::Add('ES CR', 'Spanish', 'Español, Castellano', array(
|
||||
// Class: Trigger
|
||||
//
|
||||
|
||||
Dict::Add('ES CR', 'Spanish', 'Español, Castellano', array(
|
||||
'Class:Trigger' => 'Disparador',
|
||||
'Class:Trigger+' => 'Disparador',
|
||||
'Class:Trigger/Attribute:description' => 'Descripción',
|
||||
Dict::Add('ES CR', 'Spanish', 'Español, Castellaño', array(
|
||||
'Class:Trigger' => 'Disparador',
|
||||
'Class:Trigger+' => 'Disparador',
|
||||
'Class:Trigger/Attribute:description' => 'Descripción',
|
||||
'Class:Trigger/Attribute:description+' => 'Descripción',
|
||||
'Class:Trigger/Attribute:action_list' => 'Acciones',
|
||||
'Class:Trigger/Attribute:action_list' => 'Acciones',
|
||||
'Class:Trigger/Attribute:action_list+' => 'Acciones realizadas cuando se activó el disparador',
|
||||
'Class:Trigger/Attribute:finalclass' => 'Clase',
|
||||
'Class:Trigger/Attribute:finalclass+' => 'Clase',
|
||||
'Class:Trigger/Attribute:context' => 'Contexto',
|
||||
'Class:Trigger/Attribute:context+' => 'Contexto para permitir el inicio del disparador',
|
||||
'Class:Trigger/Attribute:finalclass' => 'Clase',
|
||||
'Class:Trigger/Attribute:finalclass+' => 'Clase',
|
||||
'Class:Trigger/Attribute:context' => 'Contexto',
|
||||
'Class:Trigger/Attribute:context+' => 'Contexto para permitir el inicio del disparador',
|
||||
));
|
||||
|
||||
//
|
||||
// Class: TriggerOnObject
|
||||
//
|
||||
|
||||
Dict::Add('ES CR', 'Spanish', 'Español, Castellano', array(
|
||||
Dict::Add('ES CR', 'Spanish', 'Español, Castellaño', array(
|
||||
'Class:TriggerOnObject' => 'Disparador (Depende de la clase)',
|
||||
'Class:TriggerOnObject+' => 'Disparador en una clase de objeto dada',
|
||||
'Class:TriggerOnObject/Attribute:target_class' => 'Clase destino',
|
||||
@@ -566,7 +566,7 @@ Dict::Add('ES CR', 'Spanish', 'Español, Castellano', array(
|
||||
// Class: TriggerOnPortalUpdate
|
||||
//
|
||||
|
||||
Dict::Add('ES CR', 'Spanish', 'Español, Castellano', array(
|
||||
Dict::Add('ES CR', 'Spanish', 'Español, Castellaño', array(
|
||||
'Class:TriggerOnPortalUpdate' => 'Disparador (cuando se actualiza desde el portal)',
|
||||
'Class:TriggerOnPortalUpdate+' => 'Disparador cuando un usuario actualiza desde el portal',
|
||||
));
|
||||
@@ -575,7 +575,7 @@ Dict::Add('ES CR', 'Spanish', 'Español, Castellano', array(
|
||||
// Class: TriggerOnStateChange
|
||||
//
|
||||
|
||||
Dict::Add('ES CR', 'Spanish', 'Español, Castellano', array(
|
||||
Dict::Add('ES CR', 'Spanish', 'Español, Castellaño', array(
|
||||
'Class:TriggerOnStateChange' => 'Disparador (en cambio de estado)',
|
||||
'Class:TriggerOnStateChange+' => 'Disparador en cambio de estado de objeto',
|
||||
'Class:TriggerOnStateChange/Attribute:state' => 'Estado',
|
||||
@@ -586,7 +586,7 @@ Dict::Add('ES CR', 'Spanish', 'Español, Castellano', array(
|
||||
// Class: TriggerOnStateEnter
|
||||
//
|
||||
|
||||
Dict::Add('ES CR', 'Spanish', 'Español, Castellano', array(
|
||||
Dict::Add('ES CR', 'Spanish', 'Español, Castellaño', array(
|
||||
'Class:TriggerOnStateEnter' => 'Disparador (entrando a un estado)',
|
||||
'Class:TriggerOnStateEnter+' => 'Disparador en cambio de estado de objeto - entrando',
|
||||
));
|
||||
@@ -595,7 +595,7 @@ Dict::Add('ES CR', 'Spanish', 'Español, Castellano', array(
|
||||
// Class: TriggerOnStateLeave
|
||||
//
|
||||
|
||||
Dict::Add('ES CR', 'Spanish', 'Español, Castellano', array(
|
||||
Dict::Add('ES CR', 'Spanish', 'Español, Castellaño', array(
|
||||
'Class:TriggerOnStateLeave' => 'Disparador (saliendo de un estado)',
|
||||
'Class:TriggerOnStateLeave+' => 'Disparador en cambio de estado de objeto - saliendo',
|
||||
));
|
||||
@@ -604,7 +604,7 @@ Dict::Add('ES CR', 'Spanish', 'Español, Castellano', array(
|
||||
// Class: TriggerOnObjectCreate
|
||||
//
|
||||
|
||||
Dict::Add('ES CR', 'Spanish', 'Español, Castellano', array(
|
||||
Dict::Add('ES CR', 'Spanish', 'Español, Castellaño', array(
|
||||
'Class:TriggerOnObjectCreate' => 'Disparador (creación de objeto)',
|
||||
'Class:TriggerOnObjectCreate+' => 'Disparador en la creación de objeto (hija de clase) de una clase dada',
|
||||
));
|
||||
@@ -613,7 +613,7 @@ Dict::Add('ES CR', 'Spanish', 'Español, Castellano', array(
|
||||
// Class: TriggerOnObjectDelete
|
||||
//
|
||||
|
||||
Dict::Add('ES CR', 'Spanish', 'Español, Castellano', array(
|
||||
Dict::Add('ES CR', 'Spanish', 'Español, Castellaño', array(
|
||||
'Class:TriggerOnObjectDelete' => 'Disparador (eliminando un objecto)',
|
||||
'Class:TriggerOnObjectDelete+' => 'Disparador al eliminar un objecto de la clase dada [o una clase hija] ',
|
||||
));
|
||||
@@ -622,7 +622,7 @@ Dict::Add('ES CR', 'Spanish', 'Español, Castellano', array(
|
||||
// Class: TriggerOnObjectUpdate
|
||||
//
|
||||
|
||||
Dict::Add('ES CR', 'Spanish', 'Español, Castellano', array(
|
||||
Dict::Add('ES CR', 'Spanish', 'Español, Castellaño', array(
|
||||
'Class:TriggerOnObjectUpdate' => 'Disparador (actualizando un objecto)',
|
||||
'Class:TriggerOnObjectUpdate+' => 'Disparador al actualizar un objeto de la clase dada [o una clase hija]',
|
||||
'Class:TriggerOnObjectUpdate/Attribute:target_attcodes' => 'Campos objetivo',
|
||||
@@ -633,7 +633,7 @@ Dict::Add('ES CR', 'Spanish', 'Español, Castellano', array(
|
||||
// Class: TriggerOnThresholdReached
|
||||
//
|
||||
|
||||
Dict::Add('ES CR', 'Spanish', 'Español, Castellano', array(
|
||||
Dict::Add('ES CR', 'Spanish', 'Español, Castellaño', array(
|
||||
'Class:TriggerOnThresholdReached' => 'Disparador (en umbral)',
|
||||
'Class:TriggerOnThresholdReached+' => 'Disparador en umbral Stop-Watch alcanzado',
|
||||
'Class:TriggerOnThresholdReached/Attribute:stop_watch_code' => 'Detener watch',
|
||||
@@ -646,7 +646,7 @@ Dict::Add('ES CR', 'Spanish', 'Español, Castellano', array(
|
||||
// Class: lnkTriggerAction
|
||||
//
|
||||
|
||||
Dict::Add('ES CR', 'Spanish', 'Español, Castellano', array(
|
||||
Dict::Add('ES CR', 'Spanish', 'Español, Castellaño', array(
|
||||
'Class:lnkTriggerAction' => 'Relación Acción y Disparador',
|
||||
'Class:lnkTriggerAction+' => 'Relación Acción y Disparador',
|
||||
'Class:lnkTriggerAction/Attribute:action_id' => 'Acción',
|
||||
@@ -664,7 +664,7 @@ Dict::Add('ES CR', 'Spanish', 'Español, Castellano', array(
|
||||
//
|
||||
// Synchro Data Source
|
||||
//
|
||||
Dict::Add('ES CR', 'Spanish', 'Español, Castellano', array(
|
||||
Dict::Add('ES CR', 'Spanish', 'Español, Castellaño', array(
|
||||
'Class:SynchroDataSource/Attribute:name' => 'Nombre',
|
||||
'Class:SynchroDataSource/Attribute:name+' => 'Nombre de la Fuente de Datos',
|
||||
'Class:SynchroDataSource/Attribute:description' => 'Descripción',
|
||||
@@ -912,80 +912,80 @@ Dict::Add('ES CR', 'Spanish', 'Español, Castellano', array(
|
||||
'Core:BulkExport:PDFPageOrientation' => 'Orientación de la Página:',
|
||||
'Core:BulkExport:PageOrientation-L' => 'Horizontal',
|
||||
'Core:BulkExport:PageOrientation-P' => 'Vertical',
|
||||
'Core:BulkExport:XMLFormat' => 'Archivo XML (*.xml)',
|
||||
'Core:BulkExport:XMLOptions' => 'Opciones XML',
|
||||
'Core:BulkExport:SpreadsheetFormat' => 'Formato Tabla HTML (*.html)',
|
||||
'Core:BulkExport:SpreadsheetOptions' => 'Opciones de Tabla',
|
||||
'Core:BulkExport:OptionNoLocalize' => 'Código de exportación en lugar de etiqueta',
|
||||
'Core:BulkExport:OptionLinkSets' => 'Incluir objetos ligados',
|
||||
'Core:BulkExport:OptionFormattedText' => 'Conservar formato de texto',
|
||||
'Core:BulkExport:ScopeDefinition' => 'Definición de los objetos a exportar',
|
||||
'Core:BulkExportLabelOQLExpression' => 'Consulta OQL:',
|
||||
'Core:BulkExportLabelPhrasebookEntry' => 'Entrada Consulta de Libreta de Consultas:',
|
||||
'Core:BulkExportMessageEmptyOQL' => 'Por favor ingrese una consulta OQL válida.',
|
||||
'Core:BulkExportMessageEmptyPhrasebookEntry' => 'Por favor seleccione un entrada válida de la libreta de consultas.',
|
||||
'Core:BulkExportQueryPlaceholder' => 'Escriba una consulta OQL aquí...',
|
||||
'Core:BulkExportCanRunNonInteractive' => 'Click aquí para ejecutar la exportación en modo no interactivo.',
|
||||
'Core:BulkExportLegacyExport' => 'Click aquí para acceder a la exportación tradicional.',
|
||||
'Core:BulkExport:XLSXOptions' => 'Opciones Excel',
|
||||
'Core:BulkExport:TextFormat' => 'Compos texto conteniendo algunas marcas HTML',
|
||||
'Core:BulkExport:DateTimeFormat' => 'Formato de fecha y hora',
|
||||
'Core:BulkExport:XMLFormat' => 'Archivo XML (*.xml)',
|
||||
'Core:BulkExport:XMLOptions' => 'Opciones XML',
|
||||
'Core:BulkExport:SpreadsheetFormat' => 'Formato Tabla HTML (*.html)',
|
||||
'Core:BulkExport:SpreadsheetOptions' => 'Opciones de Tabla',
|
||||
'Core:BulkExport:OptionNoLocalize' => 'Código de exportación en lugar de etiqueta',
|
||||
'Core:BulkExport:OptionLinkSets' => 'Incluir objetos ligados',
|
||||
'Core:BulkExport:OptionFormattedText' => 'Conservar formato de texto',
|
||||
'Core:BulkExport:ScopeDefinition' => 'Definición de los objetos a exportar',
|
||||
'Core:BulkExportLabelOQLExpression' => 'Consulta OQL:',
|
||||
'Core:BulkExportLabelPhrasebookEntry' => 'Entrada Consulta de Libreta de Consultas:',
|
||||
'Core:BulkExportMessageEmptyOQL' => 'Por favor ingrese una consulta OQL válida.',
|
||||
'Core:BulkExportMessageEmptyPhrasebookEntry' => 'Por favor seleccione un entrada válida de la libreta de consultas.',
|
||||
'Core:BulkExportQueryPlaceholder' => 'Escriba una consulta OQL aquí...',
|
||||
'Core:BulkExportCanRunNonInteractive' => 'Click aquí para ejecutar la exportación en modo no interactivo.',
|
||||
'Core:BulkExportLegacyExport' => 'Click aquí para acceder a la exportación tradicional.',
|
||||
'Core:BulkExport:XLSXOptions' => 'Opciones Excel',
|
||||
'Core:BulkExport:TextFormat' => 'Compos texto conteniendo algunas marcas HTML',
|
||||
'Core:BulkExport:DateTimeFormat' => 'Formato de fecha y hora',
|
||||
'Core:BulkExport:DateTimeFormatDefault_Example' => 'Formato por omisión (%1$s), ej. %2$s',
|
||||
'Core:BulkExport:DateTimeFormatCustom_Format' => 'Formato personalizado: %1$s',
|
||||
'Core:BulkExport:PDF:PageNumber' => 'Página %1$s',
|
||||
'Core:DateTime:Placeholder_d' => 'DD', // Day of the month: 2 digits (with leading zero)
|
||||
'Core:DateTime:Placeholder_j' => 'D', // Day of the month: 1 or 2 digits (without leading zero)
|
||||
'Core:DateTime:Placeholder_m' => 'MM', // Month on 2 digits i.e. 01-12
|
||||
'Core:DateTime:Placeholder_n' => 'M', // Month on 1 or 2 digits 1-12
|
||||
'Core:DateTime:Placeholder_Y' => 'AAAA', // Year on 4 digits
|
||||
'Core:DateTime:Placeholder_y' => 'AA', // Year on 2 digits
|
||||
'Core:DateTime:Placeholder_H' => 'hh', // Hour 00..23
|
||||
'Core:DateTime:Placeholder_h' => 'h', // Hour 01..12
|
||||
'Core:DateTime:Placeholder_G' => 'hh', // Hour 0..23
|
||||
'Core:DateTime:Placeholder_g' => 'h', // Hour 1..12
|
||||
'Core:DateTime:Placeholder_a' => 'am/pm', // am/pm (lowercase)
|
||||
'Core:DateTime:Placeholder_A' => 'AM/PM', // AM/PM (uppercase)
|
||||
'Core:DateTime:Placeholder_i' => 'mm', // minutes, 2 digits: 00..59
|
||||
'Core:DateTime:Placeholder_s' => 'ss', // seconds, 2 digits 00..59
|
||||
'Core:Validator:Default' => 'Formato incorrecto',
|
||||
'Core:Validator:Mandatory' => 'Por favor, ingrese este campo',
|
||||
'Core:Validator:MustBeInteger' => 'Debe ser un entero',
|
||||
'Core:Validator:MustSelectOne' => 'Por favor, seleccione uno',
|
||||
'Core:BulkExport:DateTimeFormatCustom_Format' => 'Formato personalizado: %1$s',
|
||||
'Core:BulkExport:PDF:PageNumber' => 'Página %1$s',
|
||||
'Core:DateTime:Placeholder_d' => 'DD', // Day of the month: 2 digits (with leading zero)
|
||||
'Core:DateTime:Placeholder_j' => 'D', // Day of the month: 1 or 2 digits (without leading zero)
|
||||
'Core:DateTime:Placeholder_m' => 'MM', // Month on 2 digits i.e. 01-12
|
||||
'Core:DateTime:Placeholder_n' => 'M', // Month on 1 or 2 digits 1-12
|
||||
'Core:DateTime:Placeholder_Y' => 'AAAA', // Year on 4 digits
|
||||
'Core:DateTime:Placeholder_y' => 'AA', // Year on 2 digits
|
||||
'Core:DateTime:Placeholder_H' => 'hh', // Hour 00..23
|
||||
'Core:DateTime:Placeholder_h' => 'h', // Hour 01..12
|
||||
'Core:DateTime:Placeholder_G' => 'hh', // Hour 0..23
|
||||
'Core:DateTime:Placeholder_g' => 'h', // Hour 1..12
|
||||
'Core:DateTime:Placeholder_a' => 'am/pm', // am/pm (lowercase)
|
||||
'Core:DateTime:Placeholder_A' => 'AM/PM', // AM/PM (uppercase)
|
||||
'Core:DateTime:Placeholder_i' => 'mm', // minutes, 2 digits: 00..59
|
||||
'Core:DateTime:Placeholder_s' => 'ss', // seconds, 2 digits 00..59
|
||||
'Core:Validator:Default' => 'Formato incorrecto',
|
||||
'Core:Validator:Mandatory' => 'Por favor, ingrese este campo',
|
||||
'Core:Validator:MustBeInteger' => 'Debe ser un entero',
|
||||
'Core:Validator:MustSelectOne' => 'Por favor, seleccione uno',
|
||||
));
|
||||
|
||||
//
|
||||
// Class: TagSetFieldData
|
||||
//
|
||||
Dict::Add('ES CR', 'Spanish', 'Español, Castellano', array(
|
||||
'Class:TagSetFieldData' => '%2$s para la clase %1$s',
|
||||
Dict::Add('ES CR', 'Spanish', 'Español, Castellaño', array(
|
||||
'Class:TagSetFieldData' => '%2$s para la clase %1$s',
|
||||
'Class:TagSetFieldData+' => 'Datos de campo',
|
||||
|
||||
'Class:TagSetFieldData/Attribute:code' => 'Código',
|
||||
'Class:TagSetFieldData/Attribute:code+' => 'Código interno. Debe contener al menos tres caracteres alfanuméricos',
|
||||
'Class:TagSetFieldData/Attribute:label' => 'Etiqueta',
|
||||
'Class:TagSetFieldData/Attribute:label+' => 'Etiqueta mostrada',
|
||||
'Class:TagSetFieldData/Attribute:description' => 'Descripción',
|
||||
'Class:TagSetFieldData/Attribute:code' => 'Código',
|
||||
'Class:TagSetFieldData/Attribute:code+' => 'Código interno. Debe contener al menos tres caracteres alfanuméricos',
|
||||
'Class:TagSetFieldData/Attribute:label' => 'Etiqueta',
|
||||
'Class:TagSetFieldData/Attribute:label+' => 'Etiqueta mostrada',
|
||||
'Class:TagSetFieldData/Attribute:description' => 'Descripción',
|
||||
'Class:TagSetFieldData/Attribute:description+' => 'Descripción de la etiqueta',
|
||||
'Class:TagSetFieldData/Attribute:finalclass' => 'Clase',
|
||||
'Class:TagSetFieldData/Attribute:obj_class' => 'Clase de objeto',
|
||||
'Class:TagSetFieldData/Attribute:obj_attcode' => 'Código de campo',
|
||||
'Class:TagSetFieldData/Attribute:finalclass' => 'Clase',
|
||||
'Class:TagSetFieldData/Attribute:obj_class' => 'Clase de objeto',
|
||||
'Class:TagSetFieldData/Attribute:obj_attcode' => 'Código de campo',
|
||||
|
||||
'Core:TagSetFieldData:ErrorDeleteUsedTag' => 'Etiquetas es uso no pueden ser borradas',
|
||||
'Core:TagSetFieldData:ErrorDeleteUsedTag' => 'Etiquetas es uso no pueden ser borradas',
|
||||
'Core:TagSetFieldData:ErrorDuplicateTagCodeOrLabel' => 'Los códigos o las etiquetas deben ser únicos',
|
||||
'Core:TagSetFieldData:ErrorTagCodeSyntax' => 'El código de la etiqueta debe contener entre 3 y %1$d caracteres alfanuméricos',
|
||||
'Core:TagSetFieldData:ErrorTagCodeReservedWord' => 'El código elegido es una palabra reservada',
|
||||
'Core:TagSetFieldData:ErrorTagLabelSyntax' => 'La etiqueta no odebe contener \'%1$s\' y no puede estar vacía',
|
||||
'Core:TagSetFieldData:ErrorCodeUpdateNotAllowed' => 'Códigos de etiqueta en uso no pueden ser borrados',
|
||||
'Core:TagSetFieldData:ErrorClassUpdateNotAllowed' => 'Etiquetas "Object Class" no pueden ser cambiadas',
|
||||
'Core:TagSetFieldData:ErrorTagCodeSyntax' => 'El código de la etiqueta debe contener entre 3 y %1$d caracteres alfanuméricos',
|
||||
'Core:TagSetFieldData:ErrorTagCodeReservedWord' => 'El código elegido es una palabra reservada',
|
||||
'Core:TagSetFieldData:ErrorTagLabelSyntax' => 'La etiqueta no odebe contener \'%1$s\' y no puede estar vacía',
|
||||
'Core:TagSetFieldData:ErrorCodeUpdateNotAllowed' => 'Códigos de etiqueta en uso no pueden ser borrados',
|
||||
'Core:TagSetFieldData:ErrorClassUpdateNotAllowed' => 'Etiquetas "Object Class" no pueden ser cambiadas',
|
||||
'Core:TagSetFieldData:ErrorAttCodeUpdateNotAllowed' => 'Etiquetas "Attribute Code" no pueden ser cambiadas',
|
||||
'Core:TagSetFieldData:WhereIsThisTagTab' => 'Uso de la etiqueta (%1$d)',
|
||||
'Core:TagSetFieldData:NoEntryFound' => 'No hay entradas para esta etiqueta',
|
||||
'Core:TagSetFieldData:WhereIsThisTagTab' => 'Uso de la etiqueta (%1$d)',
|
||||
'Core:TagSetFieldData:NoEntryFound' => 'No hay entradas para esta etiqueta',
|
||||
));
|
||||
|
||||
//
|
||||
// Class: DBProperty
|
||||
//
|
||||
Dict::Add('ES CR', 'Spanish', 'Español, Castellano', array(
|
||||
Dict::Add('ES CR', 'Spanish', 'Español, Castellaño', array(
|
||||
'Class:DBProperty' => 'Propiedad BD',
|
||||
'Class:DBProperty+' => 'Propiedad de Base de Datos',
|
||||
'Class:DBProperty/Attribute:name' => 'Nombre',
|
||||
@@ -1003,7 +1003,7 @@ Dict::Add('ES CR', 'Spanish', 'Español, Castellano', array(
|
||||
//
|
||||
// Class: BackgroundTask
|
||||
//
|
||||
Dict::Add('ES CR', 'Spanish', 'Español, Castellano', array(
|
||||
Dict::Add('ES CR', 'Spanish', 'Español, Castellaño', array(
|
||||
'Class:BackgroundTask' => 'Tarea en Segundo Plano',
|
||||
'Class:BackgroundTask+' => 'Tarea en Segundo Plano',
|
||||
'Class:BackgroundTask/Attribute:class_name' => 'Nombre de Clase',
|
||||
@@ -1033,7 +1033,7 @@ Dict::Add('ES CR', 'Spanish', 'Español, Castellano', array(
|
||||
//
|
||||
// Class: AsyncTask
|
||||
//
|
||||
Dict::Add('ES CR', 'Spanish', 'Español, Castellano', array(
|
||||
Dict::Add('ES CR', 'Spanish', 'Español, Castellaño', array(
|
||||
'Class:AsyncTask' => 'Tarea Asíncrona',
|
||||
'Class:AsyncTask+' => 'Tarea Asíncrona',
|
||||
'Class:AsyncTask/Attribute:created' => 'Creado',
|
||||
@@ -1046,4 +1046,14 @@ Dict::Add('ES CR', 'Spanish', 'Español, Castellano', array(
|
||||
'Class:AsyncTask/Attribute:event_id+' => 'Evento',
|
||||
'Class:AsyncTask/Attribute:finalclass' => 'Clase',
|
||||
'Class:AsyncTask/Attribute:finalclass+' => 'Clase',
|
||||
'Class:AsyncTask/Attribute:status' => 'Status~~',
|
||||
'Class:AsyncTask/Attribute:status+' => '~~',
|
||||
'Class:AsyncTask/Attribute:remaining_retries' => 'Remaining retries~~',
|
||||
'Class:AsyncTask/Attribute:remaining_retries+' => '~~',
|
||||
'Class:AsyncTask/Attribute:last_error_code' => 'Last error code~~',
|
||||
'Class:AsyncTask/Attribute:last_error_code+' => '~~',
|
||||
'Class:AsyncTask/Attribute:last_error' => 'Last error~~',
|
||||
'Class:AsyncTask/Attribute:last_error+' => '~~',
|
||||
'Class:AsyncTask/Attribute:last_attempt' => 'Last attempt~~',
|
||||
'Class:AsyncTask/Attribute:last_attempt+' => '~~',
|
||||
));
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1053,8 +1053,6 @@ Dict::Add('FR FR', 'French', 'Français', array(
|
||||
'Class:AsyncTask/Attribute:last_error+' => '',
|
||||
'Class:AsyncTask/Attribute:last_attempt' => 'Dernière tentative',
|
||||
'Class:AsyncTask/Attribute:last_attempt+' => '',
|
||||
|
||||
|
||||
));
|
||||
|
||||
// Additional language entries not present in English dict
|
||||
|
||||
@@ -451,6 +451,8 @@ Dict::Add('FR FR', 'French', 'Français', array(
|
||||
'UI:Error:MaintenanceTitle' => 'Maintenance',
|
||||
'UI:Error:InvalidToken' => 'Erreur: l\'opération a déjà été effectuée (CSRF token not found)',
|
||||
|
||||
'UI:Error:SMTP:UnknownVendor' => 'Le provider SMTP Oauth 2.0 %1$s n\'existe pas',
|
||||
|
||||
'UI:GroupBy:Count' => 'Nombre',
|
||||
'UI:GroupBy:Count+' => 'Nombre d\'éléments',
|
||||
'UI:CountOfObjects' => '%1$d objets correspondants aux critères.',
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user