mirror of
https://github.com/Combodo/iTop.git
synced 2026-02-23 20:34:12 +01:00
Compare commits
60 Commits
tag
...
feature/bl
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1004dd9afb | ||
|
|
9628a1d028 | ||
|
|
5585385d08 | ||
|
|
98870b06e3 | ||
|
|
46d91322c1 | ||
|
|
ca28f8f3c4 | ||
|
|
0aaa55b35b | ||
|
|
e9a1167da6 | ||
|
|
a67fce66fc | ||
|
|
491d1d7d53 | ||
|
|
54b48dc908 | ||
|
|
dadeab58eb | ||
|
|
0ecdc6620b | ||
|
|
80161b909e | ||
|
|
888232e8c3 | ||
|
|
d904883bdd | ||
|
|
35d2c3afac | ||
|
|
7cee8c3cd0 | ||
|
|
27622bbcec | ||
|
|
219270ce81 | ||
|
|
16dd47a3b9 | ||
|
|
70835984de | ||
|
|
d9224f43f2 | ||
|
|
5b9643d6fb | ||
|
|
d3525190d5 | ||
|
|
f20808d929 | ||
|
|
aee80e41ca | ||
|
|
56ea6c8848 | ||
|
|
b7136c0b7a | ||
|
|
ea94986247 | ||
|
|
d8363067e6 | ||
|
|
b302569feb | ||
|
|
44008fc179 | ||
|
|
c2f62a13e6 | ||
|
|
accda04a37 | ||
|
|
f364e7b043 | ||
|
|
42afe033ef | ||
|
|
8de4c0360d | ||
|
|
24130dd94f | ||
|
|
59cc6d3f76 | ||
|
|
ee37373cfa | ||
|
|
56d9653f15 | ||
|
|
d5670abdcc | ||
|
|
0360a3160d | ||
|
|
bcd21aefb4 | ||
|
|
3cbcdd4f13 | ||
|
|
c46d0f5662 | ||
|
|
b2454d44ae | ||
|
|
79cfb95f6e | ||
|
|
ff2e1a3507 | ||
|
|
503afb9831 | ||
|
|
b6772917ae | ||
|
|
00971f9ec7 | ||
|
|
a3a97fa228 | ||
|
|
18c4ca9131 | ||
|
|
466ddf768e | ||
|
|
76d26e8ef9 | ||
|
|
b526d6422b | ||
|
|
63c02ff33d | ||
|
|
4688c92e7c |
@@ -6,6 +6,8 @@ cd test
|
||||
export DEBUG_UNIT_TEST=0
|
||||
RUN_NONREG_TESTS=0
|
||||
|
||||
#USAGE ${debugMode} ${runNonRegOQLTests} "${coverture}" "${testFile}"
|
||||
|
||||
if [ $# -ge 1 -a "x$1" == "xtrue" ]
|
||||
then
|
||||
export DEBUG_UNIT_TEST=1
|
||||
@@ -13,10 +15,27 @@ else
|
||||
export DEBUG_UNIT_TEST=0
|
||||
fi
|
||||
|
||||
set -x
|
||||
OPTION=""
|
||||
if [ $# -ge 3 -a "x$3" == "xtrue" ]
|
||||
then
|
||||
##coverture
|
||||
OPTION="-dxdebug.coverage_enable=1 --coverage-clover ../var/test/coverage.xml"
|
||||
fi
|
||||
|
||||
TESTFILE="$4"
|
||||
if [ "x$TESTFILE" != "x" ]
|
||||
then
|
||||
# shellcheck disable=SC2001
|
||||
TESTFILE=$(echo "$TESTFILE" | sed 's|test/||1')
|
||||
php vendor/bin/phpunit --log-junit ../var/test/phpunit-log.junit.xml $OPTION $TESTFILE --teamcity
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if [ $# -ge 2 -a "x$2" == "xtrue" ]
|
||||
then
|
||||
php vendor/bin/phpunit --log-junit ../var/test/phpunit-log.junit.xml --teamcity
|
||||
php vendor/bin/phpunit --log-junit ../var/test/phpunit-log.junit.xml $OPTION --teamcity
|
||||
else
|
||||
#echo php vendor/bin/phpunit --log-junit ../var/test/phpunit-log.junit.xml --teamcity
|
||||
php vendor/bin/phpunit --log-junit ../var/test/phpunit-log.junit.xml --exclude-group OQL --teamcity
|
||||
php vendor/bin/phpunit --log-junit ../var/test/phpunit-log.junit.xml $OPTION --exclude-group OQL --teamcity
|
||||
fi
|
||||
|
||||
@@ -60,7 +60,7 @@ For example, if no version is currently prepared for shipping we could have:
|
||||
In this example, when 2.8.0-beta is shipped that will become:
|
||||
|
||||
- `develop`: future 2.9.0 version
|
||||
- `release/2.8`: 2.8.0-beta
|
||||
- `release/2.8.0`: 2.8.0-beta
|
||||
- `support/2.7`: 2.7.x maintenance version
|
||||
- `support/2.6`: 2.6.x maintenance version
|
||||
- `support/2.5`: 2.5.x maintenance version
|
||||
|
||||
5
Jenkinsfile
vendored
5
Jenkinsfile
vendored
@@ -2,6 +2,8 @@ pipeline {
|
||||
agent any
|
||||
parameters {
|
||||
booleanParam(name: 'debugMode', defaultValue: 'false', description: 'Debug mode?')
|
||||
string(name: 'testFile', defaultValue: '', description: 'Provide test file to execute. Example: test/core/LogAPITest.php')
|
||||
booleanParam(name: 'coverture', defaultValue: 'false', description: 'Test coverture?')
|
||||
booleanParam(name: 'runNonRegOQLTests', defaultValue: 'false', description: 'Do You want to run legacy OQL regression tests?')
|
||||
}
|
||||
stages {
|
||||
@@ -40,7 +42,7 @@ pipeline {
|
||||
parallel {
|
||||
stage('phpunit') {
|
||||
steps {
|
||||
sh './.jenkins/bin/tests/phpunit.sh ${debugMode} ${runNonRegOQLTests}'
|
||||
sh './.jenkins/bin/tests/phpunit.sh ${debugMode} ${runNonRegOQLTests} "${coverture}" "${testFile}"'
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -50,6 +52,7 @@ pipeline {
|
||||
|
||||
post {
|
||||
always {
|
||||
archiveArtifacts allowEmptyArchive:true, excludes: '.gitkeep', artifacts: 'var/test/*.xml'
|
||||
junit 'var/test/phpunit-log.junit.xml'
|
||||
}
|
||||
failure {
|
||||
|
||||
65
README.md
65
README.md
@@ -21,21 +21,35 @@ iTop also offers mass import tools and web services to integrate with your IT
|
||||
- [Data synchronization][18] (for data federation)
|
||||
|
||||
|
||||
## Latest release
|
||||
|
||||
- [Changes since the previous version][62]
|
||||
- [New features][63]
|
||||
- [Installation notes][64]
|
||||
- [Download][65]
|
||||
|
||||
[62]: https://www.itophub.io/wiki/page?id=latest:release:change_log
|
||||
[63]: https://www.itophub.io/wiki/page?id=latest:release:start
|
||||
[64]: https://www.itophub.io/wiki/page?id=latest:install:start
|
||||
[65]: https://sourceforge.net/projects/itop/files/latest/download
|
||||
|
||||
|
||||
## Resources
|
||||
|
||||
- [iTop Forums][1]: community support
|
||||
- [iTop Tickets][2]: for feature requests and bug reports
|
||||
- [Releases download][3]
|
||||
- [Documentation][4] covering both iTop and its official extensions
|
||||
- [iTop Hub][5] : discover and install extensions !
|
||||
|
||||
- [Software requirements][4]
|
||||
- [Documentation][5] covering both iTop and its official extensions
|
||||
- [iTop Hub][6] : discover and install extensions !
|
||||
|
||||
|
||||
[1]: https://sourceforge.net/p/itop/discussion/
|
||||
[2]: https://sourceforge.net/p/itop/tickets/
|
||||
[3]: https://sourceforge.net/projects/itop/files/itop/
|
||||
[4]: https://www.itophub.io/wiki
|
||||
[5]: https://store.itophub.io/en_US/
|
||||
[4]: https://www.itophub.io/wiki/page?id=latest:install:upgrading_itop
|
||||
[5]: https://www.itophub.io/wiki
|
||||
[6]: https://store.itophub.io/en_US/
|
||||
|
||||
[10]: https://www.itophub.io/wiki/page?id=latest%3Adatamodel%3Astart#configuration_management_cmdb
|
||||
[11]: https://www.itophub.io/wiki/page?id=latest%3Adatamodel%3Astart#ticketing
|
||||
@@ -49,47 +63,6 @@ iTop also offers mass import tools and web services to integrate with your IT
|
||||
|
||||
|
||||
|
||||
## Last releases
|
||||
|
||||
### Versions 2.7.*
|
||||
- 2.7.1 published on April 8, 2020
|
||||
- [Changes since the previous version][62]
|
||||
- [New features][63]
|
||||
- [Migration notes][64]
|
||||
- [Download iTop 2.7.0-2][65]
|
||||
|
||||
[62]: https://www.itophub.io/wiki/page?id=2_7_0:release:change_log
|
||||
[63]: https://www.itophub.io/wiki/page?id=2_7_0:release:2_7_whats_new
|
||||
[64]: https://www.itophub.io/wiki/page?id=2_7_0:install:260_to_270_migration_notes
|
||||
[65]: https://sourceforge.net/projects/itop/files/itop/2.7.0-2
|
||||
|
||||
|
||||
### Versions 2.6.*
|
||||
- 2.6.0 published on January 9, 2019
|
||||
- [Changes since the previous version][58]
|
||||
- [New features][59]
|
||||
- [Migration notes][60]
|
||||
- [Download iTop 2.6.3][61]
|
||||
|
||||
[58]: https://www.itophub.io/wiki/page?id=2_6_0:release:change_log
|
||||
[59]: https://www.itophub.io/wiki/page?id=2_6_0:release:2_6_whats_new
|
||||
[60]: https://www.itophub.io/wiki/page?id=2_6_0:install:250_to_260_migration_notes
|
||||
[61]: https://sourceforge.net/projects/itop/files/itop/2.6.3
|
||||
|
||||
|
||||
### Versions 2.5.*
|
||||
- 2.5.0 published on July 11, 2018
|
||||
- [Changes since the previous version][54]
|
||||
- [New features][55]
|
||||
- [Migration notes][56]
|
||||
- [Download iTop 2.5.1][57]
|
||||
|
||||
[54]: https://www.itophub.io/wiki/page?id=2_5_0:release:change_log
|
||||
[55]: https://www.itophub.io/wiki/page?id=2_5_0:release:2_5_whats_new
|
||||
[56]: https://www.itophub.io/wiki/page?id=2_5_0:install:240_to_250_migration_notes
|
||||
[57]: https://sourceforge.net/projects/itop/files/itop/2.5.1
|
||||
|
||||
|
||||
## About Us
|
||||
|
||||
iTop development is sponsored, led and supported by [Combodo][0].
|
||||
|
||||
@@ -29,9 +29,13 @@ require_once(APPROOT."/application/webpage.class.inc.php");
|
||||
|
||||
class CLIPage implements Page
|
||||
{
|
||||
function __construct($s_title)
|
||||
/** @var string */
|
||||
public $s_title;
|
||||
|
||||
function __construct($s_title)
|
||||
{
|
||||
}
|
||||
$this->s_title = $s_title;
|
||||
}
|
||||
|
||||
public function output()
|
||||
{
|
||||
@@ -48,22 +52,22 @@ class CLIPage implements Page
|
||||
public function add($sText)
|
||||
{
|
||||
echo $sText;
|
||||
}
|
||||
}
|
||||
|
||||
public function p($sText)
|
||||
{
|
||||
echo $sText."\n";
|
||||
}
|
||||
}
|
||||
|
||||
public function pre($sText)
|
||||
{
|
||||
echo $sText."\n";
|
||||
}
|
||||
}
|
||||
|
||||
public function add_comment($sText)
|
||||
{
|
||||
echo "#".$sText."\n";
|
||||
}
|
||||
}
|
||||
|
||||
public function table($aConfig, $aData, $aParams = array())
|
||||
{
|
||||
@@ -93,5 +97,3 @@ class CLIPage implements Page
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
|
||||
@@ -73,19 +73,16 @@ class iTopWebPage extends NiceWebPage implements iTabbedPage
|
||||
$this->add_header("Content-type: text/html; charset=".self::PAGES_CHARSET);
|
||||
$this->add_header("Cache-control: no-cache");
|
||||
$this->add_linked_stylesheet("../css/jquery.treeview.css");
|
||||
$this->add_linked_stylesheet("../css/jquery.autocomplete.css");
|
||||
$this->add_linked_stylesheet("../css/jquery-ui-timepicker-addon.css");
|
||||
$this->add_linked_stylesheet("../css/jquery.multiselect.css");
|
||||
$this->add_linked_stylesheet("../css/magnific-popup.css");
|
||||
$this->add_linked_stylesheet("../css/c3.min.css");
|
||||
$this->add_linked_stylesheet("../css/font-awesome/css/all.min.css");
|
||||
$this->add_linked_stylesheet("../css/font-awesome/css/v4-shims.min.css");
|
||||
$this->add_linked_stylesheet("../js/ckeditor/plugins/codesnippet/lib/highlight/styles/obsidian.css");
|
||||
|
||||
$this->add_linked_script('../js/jquery.layout.min.js');
|
||||
$this->add_linked_script('../js/jquery.ba-bbq.min.js');
|
||||
$this->add_linked_script("../js/jquery.treeview.js");
|
||||
$this->add_linked_script("../js/jquery.autocomplete.js");
|
||||
$this->add_linked_script("../js/date.js");
|
||||
$this->add_linked_script("../js/jquery-ui-timepicker-addon.js");
|
||||
$this->add_linked_script("../js/jquery-ui-timepicker-addon-i18n.min.js");
|
||||
|
||||
@@ -92,7 +92,6 @@ class LoginWebPage extends NiceWebPage
|
||||
{
|
||||
$this->add_linked_stylesheet(utils::GetAbsoluteUrlAppRoot().'css/login.css');
|
||||
$this->add_linked_stylesheet(utils::GetAbsoluteUrlAppRoot().'css/font-awesome/css/all.min.css');
|
||||
$this->add_linked_stylesheet(utils::GetAbsoluteUrlAppRoot().'css/font-awesome/css/v4-shims.min.css');
|
||||
}
|
||||
|
||||
public static function SetLoginFailedMessage($sMessage)
|
||||
@@ -100,6 +99,44 @@ class LoginWebPage extends NiceWebPage
|
||||
self::$m_sLoginFailedMessage = $sMessage;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $oUser
|
||||
* @param array $aProfiles
|
||||
*
|
||||
* @return array
|
||||
* @throws \CoreException
|
||||
* @throws \CoreUnexpectedValue
|
||||
*/
|
||||
public static function SynchroniseProfiles(&$oUser, array $aProfiles, $sOrigin)
|
||||
{
|
||||
$oProfilesSet = $oUser->Get(‘profile_list’);
|
||||
//delete old profiles
|
||||
$aExistingProfiles = [];
|
||||
while ($oProfile = $oProfilesSet->Fetch())
|
||||
{
|
||||
array_push($aExistingProfiles, $oProfile->Get('profileid'));
|
||||
$iArrayKey = array_search($oProfile->Get('profileid'), $aProfiles);
|
||||
if (!$iArrayKey)
|
||||
{
|
||||
$oProfilesSet->RemoveItem($oProfile->Get('profileid'));
|
||||
}
|
||||
else
|
||||
{
|
||||
unset($aProfiles[$iArrayKey]);
|
||||
}
|
||||
}
|
||||
//add profiles not already linked with user
|
||||
foreach ($aProfiles as $iProfileId)
|
||||
{
|
||||
$oLink = new URP_UserProfile();
|
||||
$oLink->Set('profileid', $iProfileId);
|
||||
$oLink->Set('reason', $sOrigin);
|
||||
|
||||
$oProfilesSet->AddItem(MetaModel::NewObject('URP_UserProfile', array('profileid' => $iProfileId, 'reason' => $sOrigin)));
|
||||
}
|
||||
$oUser->Set('profile_list', $oProfilesSet);
|
||||
}
|
||||
|
||||
public function DisplayLoginHeader($bMainAppLogo = false)
|
||||
{
|
||||
$sLogo = 'itop-logo-external.png';
|
||||
@@ -886,20 +923,12 @@ class LoginWebPage extends NiceWebPage
|
||||
}
|
||||
|
||||
// Now synchronize the profiles
|
||||
$oProfilesSet = DBObjectSet::FromScratch('URP_UserProfile');
|
||||
$sOrigin = 'External User provisioning';
|
||||
if (isset($_SESSION['login_mode']))
|
||||
{
|
||||
$sOrigin .= " ({$_SESSION['login_mode']})";
|
||||
}
|
||||
foreach ($aProfiles as $iProfileId)
|
||||
{
|
||||
$oLink = new URP_UserProfile();
|
||||
$oLink->Set('profileid', $iProfileId);
|
||||
$oLink->Set('reason', $sOrigin);
|
||||
$oProfilesSet->AddObject($oLink);
|
||||
}
|
||||
$oUser->Set('profile_list', $oProfilesSet);
|
||||
$aExistingProfiles = self::SynchroniseProfiles($oUser, $aProfiles, $sOrigin);
|
||||
if ($oUser->IsModified())
|
||||
{
|
||||
$oUser->DBWrite();
|
||||
|
||||
@@ -272,7 +272,7 @@ EOF
|
||||
$iMinChars = isset($aArgs['iMinChars']) ? $aArgs['iMinChars'] : 3; //@@@ $this->oAttDef->GetMinAutoCompleteChars();
|
||||
|
||||
// the input for the auto-complete
|
||||
$sHTMLValue .= "<input class=\"field_autocomplete\" type=\"text\" id=\"label_$this->iId\" value=\"$sDisplayValue\"/>";
|
||||
$sHTMLValue .= "<input id=\"label_$this->iId\" value=\"$sDisplayValue\"/>";
|
||||
$sHTMLValue .= "<span class=\"field_input_btn\"><div class=\"mini_button\" id=\"mini_search_{$this->iId}\" onClick=\"oACWidget_{$this->iId}.Search();\"><i class=\"fas fa-search\"></i></div></span>";
|
||||
|
||||
// another hidden input to store & pass the object's Id
|
||||
@@ -281,18 +281,53 @@ EOF
|
||||
$JSSearchMode = $this->bSearchMode ? 'true' : 'false';
|
||||
// Scripts to start the autocomplete and bind some events to it
|
||||
$oPage->add_ready_script(
|
||||
<<<EOF
|
||||
oACWidget_{$this->iId} = new ExtKeyWidget('{$this->iId}', '{$this->sTargetClass}', '$sFilter', '$sTitle', false, $sWizHelper, '{$this->sAttCode}', $sJSSearchMode, $sJSDoSearch);
|
||||
oACWidget_{$this->iId}.emptyHtml = "<div style=\"background: #fff; border:0; text-align:center; vertical-align:middle;\"><p>$sMessage</p></div>";
|
||||
$('#label_$this->iId').autocomplete(GetAbsoluteUrlAppRoot()+'pages/ajax.render.php', { scroll:true, minChars:{$iMinChars}, autoFill:false, matchContains:true, mustMatch: true, keyHolder:'#{$this->iId}', extraParams:{operation:'ac_extkey', sTargetClass:'{$this->sTargetClass}',sFilter:'$sFilter',bSearchMode:$JSSearchMode, json: function() { return $sWizHelperJSON; } }});
|
||||
$('#label_$this->iId').keyup(function() { if ($(this).val() == '') { $('#$this->iId').val(''); } } ); // Useful for search forms: empty value in the "label", means no value, immediatly !
|
||||
$('#label_$this->iId').result( function(event, data, formatted) { OnAutoComplete('{$this->iId}', event, data, formatted); } );
|
||||
$('#$this->iId').bind('update', function() { oACWidget_{$this->iId}.Update(); } );
|
||||
<<<JS
|
||||
$('#label_$this->iId').autocomplete({
|
||||
source: function( request, response ) {
|
||||
$.post( {
|
||||
url: GetAbsoluteUrlAppRoot()+'pages/ajax.render.php',
|
||||
dataType: "json",
|
||||
data: {
|
||||
q:request.term,
|
||||
operation:'ac_extkey',
|
||||
sTargetClass:'{$this->sTargetClass}',
|
||||
sFilter:'$sFilter',
|
||||
bSearchMode:$JSSearchMode,
|
||||
sOutputFormat:'json',
|
||||
json: function() { return $sWizHelperJSON; }
|
||||
},
|
||||
success: function( data ) {
|
||||
response( data );
|
||||
}
|
||||
} );
|
||||
},
|
||||
autoFocus: true,
|
||||
minLength:{$iMinChars},
|
||||
select: function( event, ui ) {
|
||||
$('#$this->iId').val( ui.item.value );
|
||||
$('#label_$this->iId').val( ui.item.label );
|
||||
$('#$this->iId').trigger('validate');
|
||||
$('#$this->iId').trigger('extkeychange');
|
||||
$('#$this->iId').trigger('change');
|
||||
return false;
|
||||
}
|
||||
})
|
||||
.autocomplete( "instance" )._renderItem = function( ul, item ) {
|
||||
var term = this.term.replace("/([\^\$\(\)\[\]\{\}\*\.\+\?\|\\])/gi", "\\$1");
|
||||
var val = item.label.replace(new RegExp("(?![^&;]+;)(?!<[^<>]*)(" + term + ")(?![^<>]*>)(?![^&;]+;)", "gi"), "<strong>$1</strong>");
|
||||
if (item.obsolete == 'yes'){
|
||||
val = val + ' <b>old</b>';
|
||||
}
|
||||
return $( "<li>" )
|
||||
.append( val )
|
||||
.appendTo( ul );
|
||||
};
|
||||
|
||||
if ($('#ac_dlg_{$this->iId}').length == 0)
|
||||
{
|
||||
$('body').append('<div id="ac_dlg_{$this->iId}"></div>');
|
||||
}
|
||||
EOF
|
||||
JS
|
||||
);
|
||||
}
|
||||
if ($bExtensions && MetaModel::IsHierarchicalClass($this->sTargetClass) !== false)
|
||||
@@ -441,10 +476,12 @@ EOF
|
||||
$iMax = 150;
|
||||
$oValuesSet->SetLimit($iMax);
|
||||
$oValuesSet->SetSort(false);
|
||||
$aOrder = array('friendlyname'=>true);
|
||||
$oValuesSet->SetOrderBy($aOrder);
|
||||
$oValuesSet->SetSort(true);
|
||||
$oValuesSet->SetModifierProperty('UserRightsGetSelectFilter', 'bSearchMode', $this->bSearchMode);
|
||||
$oValuesSet->SetLimit($iMax);
|
||||
$aValuesContains = $oValuesSet->GetValues(array('this' => $oObj, 'current_extkey_id' => $iCurrentExtKeyId), $sContains, 'contains');
|
||||
asort($aValuesContains);
|
||||
$aValuesContains = $oValuesSet->GetValues(array('this' => $oObj, 'current_extkey_id' => $iCurrentExtKeyId), $sContains, 'start_with');
|
||||
$aValues = array();
|
||||
foreach($aValuesContains as $sKey => $sFriendlyName)
|
||||
{
|
||||
@@ -453,6 +490,24 @@ EOF
|
||||
$aValues[$sKey] = $sFriendlyName;
|
||||
}
|
||||
}
|
||||
if (sizeof($aValuesContains) < $iMax)
|
||||
{
|
||||
$aValuesContains = $oValuesSet->GetValues(array('this' => $oObj, 'current_extkey_id' => $iCurrentExtKeyId), $sContains,
|
||||
'contains');
|
||||
//asort($aValuesContains);
|
||||
$iSize=sizeof($aValuesContains);
|
||||
foreach($aValuesContains as $sKey => $sFriendlyName)
|
||||
{
|
||||
if (!isset($aValues[$sKey]))
|
||||
{
|
||||
$aValues[$sKey] = $sFriendlyName;
|
||||
if (++$iSize >= $iMax)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
switch($sOutputFormat)
|
||||
{
|
||||
|
||||
@@ -35,6 +35,10 @@ require_once(APPROOT.'/core/email.class.inc.php');
|
||||
*/
|
||||
abstract class Action extends cmdbAbstractObject
|
||||
{
|
||||
/**
|
||||
* @throws \CoreException
|
||||
* @throws \Exception
|
||||
*/
|
||||
public static function Init()
|
||||
{
|
||||
$aParams = array
|
||||
@@ -57,15 +61,32 @@ abstract class Action extends cmdbAbstractObject
|
||||
MetaModel::Init_AddAttribute(new AttributeLinkedSetIndirect("trigger_list", array("linked_class"=>"lnkTriggerAction", "ext_key_to_me"=>"action_id", "ext_key_to_remote"=>"trigger_id", "allowed_values"=>null, "count_min"=>0, "count_max"=>0, "depends_on"=>array())));
|
||||
|
||||
// Display lists
|
||||
MetaModel::Init_SetZListItems('details', array('name', 'description', 'status', 'trigger_list')); // Attributes to be displayed for the complete details
|
||||
MetaModel::Init_SetZListItems('list', array('finalclass', 'name', 'description', 'status')); // Attributes to be displayed for a list
|
||||
// - Attributes to be displayed for the complete details
|
||||
MetaModel::Init_SetZListItems('details', array('name', 'description', 'status', 'trigger_list'));
|
||||
// - Attributes to be displayed for a list
|
||||
MetaModel::Init_SetZListItems('list', array('finalclass', 'name', 'description', 'status'));
|
||||
// Search criteria
|
||||
MetaModel::Init_SetZListItems('default_search', array('name', 'description', 'status')); // Criteria of the std search form
|
||||
// MetaModel::Init_SetZListItems('advanced_search', array('name')); // Criteria of the advanced search form
|
||||
// - Criteria of the std search form
|
||||
MetaModel::Init_SetZListItems('default_search', array('name', 'description', 'status'));
|
||||
// - Criteria of the advanced search form
|
||||
// MetaModel::Init_SetZListItems('advanced_search', array('name'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Encapsulate the execution of the action and handle failure & logging
|
||||
*
|
||||
* @param \Trigger $oTrigger
|
||||
* @param array $aContextArgs
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
abstract public function DoExecute($oTrigger, $aContextArgs);
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
* @throws \ArchivedObjectException
|
||||
* @throws \CoreException
|
||||
*/
|
||||
public function IsActive()
|
||||
{
|
||||
switch($this->Get('status'))
|
||||
@@ -79,6 +100,13 @@ abstract class Action extends cmdbAbstractObject
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if the current action status is set on "test"
|
||||
*
|
||||
* @return bool
|
||||
* @throws \ArchivedObjectException
|
||||
* @throws \CoreException
|
||||
*/
|
||||
public function IsBeingTested()
|
||||
{
|
||||
switch($this->Get('status'))
|
||||
@@ -99,6 +127,10 @@ abstract class Action extends cmdbAbstractObject
|
||||
*/
|
||||
abstract class ActionNotification extends Action
|
||||
{
|
||||
/**
|
||||
* @inheritDoc
|
||||
* @throws \CoreException
|
||||
*/
|
||||
public static function Init()
|
||||
{
|
||||
$aParams = array
|
||||
@@ -117,11 +149,15 @@ abstract class ActionNotification extends Action
|
||||
MetaModel::Init_InheritAttributes();
|
||||
|
||||
// Display lists
|
||||
MetaModel::Init_SetZListItems('details', array('name', 'description', 'status', 'trigger_list')); // Attributes to be displayed for the complete details
|
||||
MetaModel::Init_SetZListItems('list', array('finalclass', 'name', 'description', 'status')); // Attributes to be displayed for a list
|
||||
// - Attributes to be displayed for the complete details
|
||||
MetaModel::Init_SetZListItems('details', array('name', 'description', 'status', 'trigger_list'));
|
||||
// - Attributes to be displayed for a list
|
||||
MetaModel::Init_SetZListItems('list', array('finalclass', 'name', 'description', 'status'));
|
||||
// Search criteria
|
||||
// MetaModel::Init_SetZListItems('standard_search', array('name')); // Criteria of the std search form
|
||||
// MetaModel::Init_SetZListItems('advanced_search', array('name')); // Criteria of the advanced search form
|
||||
// - Criteria of the std search form
|
||||
// MetaModel::Init_SetZListItems('standard_search', array('name'));
|
||||
// - Criteria of the advanced search form
|
||||
// MetaModel::Init_SetZListItems('advanced_search', array('name'));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -132,6 +168,9 @@ abstract class ActionNotification extends Action
|
||||
*/
|
||||
class ActionEmail extends ActionNotification
|
||||
{
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public static function Init()
|
||||
{
|
||||
$aParams = array
|
||||
@@ -161,11 +200,15 @@ class ActionEmail extends ActionNotification
|
||||
MetaModel::Init_AddAttribute(new AttributeEnum("importance", array("allowed_values"=>new ValueSetEnum('low,normal,high'), "sql"=>"importance", "default_value"=>'normal', "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
|
||||
// Display lists
|
||||
MetaModel::Init_SetZListItems('details', array('name', 'description', 'status', 'test_recipient', 'from', 'reply_to', 'to', 'cc', 'bcc', 'subject', 'body', 'importance', 'trigger_list')); // Attributes to be displayed for the complete details
|
||||
MetaModel::Init_SetZListItems('list', array('name', 'status', 'to', 'subject')); // Attributes to be displayed for a list
|
||||
// - Attributes to be displayed for the complete details
|
||||
MetaModel::Init_SetZListItems('details', array('name', 'description', 'status', 'test_recipient', 'from', 'reply_to', 'to', 'cc', 'bcc', 'subject', 'body', 'importance', 'trigger_list'));
|
||||
// - Attributes to be displayed for a list
|
||||
MetaModel::Init_SetZListItems('list', array('name', 'status', 'to', 'subject'));
|
||||
// Search criteria
|
||||
MetaModel::Init_SetZListItems('standard_search', array('name','description', 'status', 'subject')); // Criteria of the std search form
|
||||
// MetaModel::Init_SetZListItems('advanced_search', array('name')); // Criteria of the advanced search form
|
||||
// - Criteria of the std search form
|
||||
MetaModel::Init_SetZListItems('standard_search', array('name','description', 'status', 'subject'));
|
||||
// - Criteria of the advanced search form
|
||||
// MetaModel::Init_SetZListItems('advanced_search', array('name'));
|
||||
}
|
||||
|
||||
// count the recipients found
|
||||
@@ -175,7 +218,18 @@ class ActionEmail extends ActionNotification
|
||||
// executed in the background, while making sure that any issue would be reported clearly
|
||||
protected $m_aMailErrors; //array of strings explaining the issue
|
||||
|
||||
// returns a the list of emails as a string, or a detailed error description
|
||||
/**
|
||||
* Return a the list of emails as a string, or a detailed error description
|
||||
*
|
||||
* @param string $sRecipAttCode
|
||||
* @param array $aArgs
|
||||
*
|
||||
* @return string
|
||||
* @throws \ArchivedObjectException
|
||||
* @throws \CoreException
|
||||
* @throws \CoreUnexpectedValue
|
||||
* @throws \MySQLException
|
||||
*/
|
||||
protected function FindRecipients($sRecipAttCode, $aArgs)
|
||||
{
|
||||
$sOQL = $this->Get($sRecipAttCode);
|
||||
@@ -224,9 +278,7 @@ class ActionEmail extends ActionNotification
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \Trigger $oTrigger
|
||||
* @param array $aContextArgs
|
||||
*
|
||||
* @inheritDoc
|
||||
* @throws \CoreException
|
||||
* @throws \CoreUnexpectedValue
|
||||
* @throws \CoreWarning
|
||||
@@ -306,6 +358,7 @@ class ActionEmail extends ActionNotification
|
||||
*
|
||||
* @return string
|
||||
* @throws \CoreException
|
||||
* @throws \Exception
|
||||
*/
|
||||
protected function _DoExecute($oTrigger, $aContextArgs, &$oLog)
|
||||
{
|
||||
@@ -316,7 +369,7 @@ class ActionEmail extends ActionNotification
|
||||
$this->m_aMailErrors = array();
|
||||
$bRes = false; // until we do succeed in sending the email
|
||||
|
||||
// Determine recicipients
|
||||
// Determine recipients
|
||||
//
|
||||
$sTo = $this->FindRecipients('to', $aContextArgs);
|
||||
$sCC = $this->FindRecipients('cc', $aContextArgs);
|
||||
@@ -439,4 +492,3 @@ class ActionEmail extends ActionNotification
|
||||
}
|
||||
}
|
||||
}
|
||||
?>
|
||||
|
||||
@@ -65,6 +65,10 @@ class ExecAsyncTask implements iBackgroundProcess
|
||||
*/
|
||||
abstract class AsyncTask extends DBObject
|
||||
{
|
||||
/**
|
||||
* @throws \CoreException
|
||||
* @throws \Exception
|
||||
*/
|
||||
public static function Init()
|
||||
{
|
||||
$aParams = array
|
||||
@@ -285,11 +289,13 @@ abstract class AsyncTask extends DBObject
|
||||
|
||||
/**
|
||||
* Throws an exception (message and code)
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
abstract public function DoProcess();
|
||||
|
||||
/**
|
||||
* Describes the error codes that DoProcess can return by the mean of exceptions
|
||||
* Describes the error codes that DoProcess can return by the mean of exceptions
|
||||
*/
|
||||
static public function EnumErrorCodes()
|
||||
{
|
||||
@@ -352,6 +358,11 @@ class AsyncSendEmail extends AsyncTask
|
||||
$oNew->DBInsert();
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
* @throws \ArchivedObjectException
|
||||
* @throws \CoreException
|
||||
*/
|
||||
public function DoProcess()
|
||||
{
|
||||
$sMessage = $this->Get('message');
|
||||
|
||||
@@ -742,7 +742,7 @@ abstract class AttributeDefinition
|
||||
*
|
||||
* @return mixed a value out of suffix/value pairs, for SELECT result interpretation
|
||||
*/
|
||||
public function FromSQLToValue($aCols, $sPrefix = '')
|
||||
public function FromSQLToValue($aCols, $sPrefix = '', $oHostObject = null, $sHostAttCode = null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
@@ -2402,9 +2402,9 @@ class AttributeDBFieldVoid extends AttributeDefinition
|
||||
return $aColumns;
|
||||
}
|
||||
|
||||
public function FromSQLToValue($aCols, $sPrefix = '')
|
||||
public function FromSQLToValue($aCols, $sPrefix = '', $oHostObject = null, $sHostAttCode = null)
|
||||
{
|
||||
$value = $this->MakeRealValue($aCols[$sPrefix.''], null);
|
||||
$value = $this->MakeRealValue($aCols[$sPrefix.''], $oHostObject);
|
||||
|
||||
return $value;
|
||||
}
|
||||
@@ -3913,7 +3913,7 @@ class AttributeEncryptedString extends AttributeString
|
||||
* @return string
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function FromSQLToValue($aCols, $sPrefix = '')
|
||||
public function FromSQLToValue($aCols, $sPrefix = '', $oHostObject = null, $sHostAttCode = null)
|
||||
{
|
||||
$oSimpleCrypt = new SimpleCrypt(self::$sLibrary);
|
||||
$sValue = $oSimpleCrypt->Decrypt(self::$sKey, $aCols[$sPrefix]);
|
||||
@@ -4283,7 +4283,7 @@ class AttributeText extends AttributeString
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function FromSQLToValue($aCols, $sPrefix = '')
|
||||
public function FromSQLToValue($aCols, $sPrefix = '', $oHostObject = null, $sHostAttCode = null)
|
||||
{
|
||||
$value = $aCols[$sPrefix.''];
|
||||
if ($this->GetOptional('format', null) != null)
|
||||
@@ -4577,7 +4577,7 @@ class AttributeCaseLog extends AttributeLongText
|
||||
* @return \ormCaseLog
|
||||
* @throws \MissingColumnException
|
||||
*/
|
||||
public function FromSQLToValue($aCols, $sPrefix = '')
|
||||
public function FromSQLToValue($aCols, $sPrefix = '', $oHostObject = null, $sHostAttCode = null)
|
||||
{
|
||||
if (!array_key_exists($sPrefix, $aCols))
|
||||
{
|
||||
@@ -7378,18 +7378,18 @@ class AttributeExternalField extends AttributeDefinition
|
||||
//public function GetSQLExpressions($sPrefix = '') {return array();}
|
||||
|
||||
// Here, we get the data...
|
||||
public function FromSQLToValue($aCols, $sPrefix = '')
|
||||
public function FromSQLToValue($aCols, $sPrefix = '', $oHostObject = null, $sHostAttCode = null)
|
||||
{
|
||||
$oExtAttDef = $this->GetExtAttDef();
|
||||
|
||||
return $oExtAttDef->FromSQLToValue($aCols, $sPrefix);
|
||||
return $oExtAttDef->FromSQLToValue($aCols, $sPrefix, $oHostObject, $sHostAttCode);
|
||||
}
|
||||
|
||||
public function GetAsHTML($value, $oHostObject = null, $bLocalize = true)
|
||||
{
|
||||
$oExtAttDef = $this->GetExtAttDef();
|
||||
|
||||
return $oExtAttDef->GetAsHTML($value, null, $bLocalize);
|
||||
return $oExtAttDef->GetAsHTML($value, $oHostObject, $bLocalize);
|
||||
}
|
||||
|
||||
public function GetAsXML($value, $oHostObject = null, $bLocalize = true)
|
||||
@@ -7645,6 +7645,10 @@ class AttributeBlob extends AttributeDefinition
|
||||
|
||||
if (is_object($proposedValue))
|
||||
{
|
||||
if (!$proposedValue instanceof ormDocument)
|
||||
{
|
||||
throw new Exception(__METHOD__.": unexpected class ".get_class($proposedValue));
|
||||
}
|
||||
$proposedValue = clone $proposedValue;
|
||||
}
|
||||
else
|
||||
@@ -7661,6 +7665,7 @@ class AttributeBlob extends AttributeDefinition
|
||||
}
|
||||
}
|
||||
|
||||
$proposedValue->SetHostObject($oHostObj, $this->GetCode());
|
||||
return $proposedValue;
|
||||
}
|
||||
|
||||
@@ -7679,7 +7684,7 @@ class AttributeBlob extends AttributeDefinition
|
||||
return $aColumns;
|
||||
}
|
||||
|
||||
public function FromSQLToValue($aCols, $sPrefix = '')
|
||||
public function FromSQLToValue($aCols, $sPrefix = '', $oHostObject = null, $sHostAttCode = null)
|
||||
{
|
||||
if (!array_key_exists($sPrefix, $aCols))
|
||||
{
|
||||
@@ -7703,7 +7708,7 @@ class AttributeBlob extends AttributeDefinition
|
||||
$sFileName = isset($aCols[$sPrefix.'_filename']) ? $aCols[$sPrefix.'_filename'] : '';
|
||||
|
||||
$value = new ormDocument($data, $sMimeType, $sFileName);
|
||||
|
||||
$value->SetHostObject($oHostObject, $sHostAttCode);
|
||||
return $value;
|
||||
}
|
||||
|
||||
@@ -7945,18 +7950,6 @@ class AttributeImage extends AttributeBlob
|
||||
return "Image";
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
* @see AttributeBlob::MakeRealValue()
|
||||
*/
|
||||
public function MakeRealValue($proposedValue, $oHostObj)
|
||||
{
|
||||
$oDoc = parent::MakeRealValue($proposedValue, $oHostObj);
|
||||
|
||||
// The validation of the MIME Type is done by CheckFormat below
|
||||
return $oDoc;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check that the supplied ormDocument actually contains an image
|
||||
* {@inheritDoc}
|
||||
@@ -8231,7 +8224,7 @@ class AttributeStopWatch extends AttributeDefinition
|
||||
return date("Y-m-d H:i:s", $iSeconds);
|
||||
}
|
||||
|
||||
public function FromSQLToValue($aCols, $sPrefix = '')
|
||||
public function FromSQLToValue($aCols, $sPrefix = '', $oHostObject = null, $sHostAttCode = null)
|
||||
{
|
||||
$aExpectedCols = array($sPrefix, $sPrefix.'_started', $sPrefix.'_laststart', $sPrefix.'_stopped');
|
||||
foreach($this->ListThresholds() as $iThreshold => $aFoo)
|
||||
@@ -9068,7 +9061,7 @@ class AttributeSubItem extends AttributeDefinition
|
||||
//
|
||||
// protected function ScalarToSQL($value) {return $value;} // format value as a valuable SQL literal (quoted outside)
|
||||
|
||||
public function FromSQLToValue($aCols, $sPrefix = '')
|
||||
public function FromSQLToValue($aCols, $sPrefix = '', $oHostObject = null, $sHostAttCode = null)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -9286,7 +9279,7 @@ class AttributeOneWayPassword extends AttributeDefinition
|
||||
return $aColumns;
|
||||
}
|
||||
|
||||
public function FromSQLToValue($aCols, $sPrefix = '')
|
||||
public function FromSQLToValue($aCols, $sPrefix = '', $oHostObject = null, $sHostAttCode = null)
|
||||
{
|
||||
if (!array_key_exists($sPrefix, $aCols))
|
||||
{
|
||||
@@ -9483,7 +9476,7 @@ class AttributeTable extends AttributeDBField
|
||||
return $proposedValue;
|
||||
}
|
||||
|
||||
public function FromSQLToValue($aCols, $sPrefix = '')
|
||||
public function FromSQLToValue($aCols, $sPrefix = '', $oHostObject = null, $sHostAttCode = null)
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -9498,11 +9491,11 @@ class AttributeTable extends AttributeDBField
|
||||
}
|
||||
if ($value === false)
|
||||
{
|
||||
$value = $this->MakeRealValue($aCols[$sPrefix.''], null);
|
||||
$value = $this->MakeRealValue($aCols[$sPrefix.''], $oHostObject);
|
||||
}
|
||||
} catch (Exception $e)
|
||||
{
|
||||
$value = $this->MakeRealValue($aCols[$sPrefix.''], null);
|
||||
$value = $this->MakeRealValue($aCols[$sPrefix.''], $oHostObject);
|
||||
}
|
||||
|
||||
return $value;
|
||||
@@ -9897,11 +9890,11 @@ abstract class AttributeSet extends AttributeDBFieldVoid
|
||||
* @return mixed
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function FromSQLToValue($aCols, $sPrefix = '')
|
||||
public function FromSQLToValue($aCols, $sPrefix = '', $oHostObject = null, $sHostAttCode = null)
|
||||
{
|
||||
$sValue = $aCols["$sPrefix"];
|
||||
|
||||
return $this->MakeRealValue($sValue, null, true);
|
||||
return $this->MakeRealValue($sValue, $oHostObject, true);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -11046,7 +11039,7 @@ class AttributeTagSet extends AttributeSet
|
||||
* @throws \CoreException
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function FromSQLToValue($aCols, $sPrefix = '')
|
||||
public function FromSQLToValue($aCols, $sPrefix = '', $oHostObject = null, $sHostAttCode = null)
|
||||
{
|
||||
$sValue = $aCols["$sPrefix"];
|
||||
|
||||
@@ -11628,7 +11621,7 @@ class AttributeFriendlyName extends AttributeDefinition
|
||||
return $sLabel;
|
||||
}
|
||||
|
||||
public function FromSQLToValue($aCols, $sPrefix = '')
|
||||
public function FromSQLToValue($aCols, $sPrefix = '', $oHostObject = null, $sHostAttCode = null)
|
||||
{
|
||||
$sValue = $aCols[$sPrefix];
|
||||
|
||||
|
||||
@@ -513,83 +513,6 @@ abstract class CMDBObject extends DBObject
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated 2.7.0 N°2361 simply use {@link DBInsert} instead, that will automatically create and persist a CMDBChange object.
|
||||
* If you need to persist your own, call {@link CMDBObject::SetCurrentChange} before.
|
||||
*
|
||||
* @param \CMDBChange $oChange
|
||||
* @param null $bSkipStrongSecurity
|
||||
*
|
||||
* @return int|null
|
||||
* @throws \ArchivedObjectException
|
||||
* @throws \CoreCannotSaveObjectException
|
||||
* @throws \CoreException
|
||||
* @throws \CoreUnexpectedValue
|
||||
* @throws \CoreWarning
|
||||
* @throws \MySQLException
|
||||
* @throws \OQLException
|
||||
* @throws \SecurityException
|
||||
*/
|
||||
public function DBInsertTracked(CMDBChange $oChange, $bSkipStrongSecurity = null)
|
||||
{
|
||||
self::SetCurrentChange($oChange);
|
||||
$this->CheckUserRights($bSkipStrongSecurity, UR_ACTION_MODIFY);
|
||||
$ret = $this->DBInsertTracked_Internal();
|
||||
return $ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated 2.7.0 N°2361 simply use {@link DBInsertNoReload} instead, that will automatically create and persist a CMDBChange object.
|
||||
* If you need to persist your own, call {@link CMDBObject::SetCurrentChange} before.
|
||||
*
|
||||
* @param \CMDBChange $oChange
|
||||
* @param null $bSkipStrongSecurity
|
||||
*
|
||||
* @return int
|
||||
* @throws \ArchivedObjectException
|
||||
* @throws \CoreCannotSaveObjectException
|
||||
* @throws \CoreException
|
||||
* @throws \CoreUnexpectedValue
|
||||
* @throws \CoreWarning
|
||||
* @throws \MySQLException
|
||||
* @throws \OQLException
|
||||
* @throws \SecurityException
|
||||
*/
|
||||
public function DBInsertTrackedNoReload(CMDBChange $oChange, $bSkipStrongSecurity = null)
|
||||
{
|
||||
self::SetCurrentChange($oChange);
|
||||
$this->CheckUserRights($bSkipStrongSecurity, UR_ACTION_MODIFY);
|
||||
$ret = $this->DBInsertTracked_Internal(true);
|
||||
return $ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated 2.7.0 N°2361 simply use {@link DBInsert} or {@link DBInsertNoReload} instead
|
||||
*
|
||||
* @param bool $bDoNotReload
|
||||
*
|
||||
* @return integer Identifier of the created object
|
||||
* @throws \ArchivedObjectException
|
||||
* @throws \CoreCannotSaveObjectException
|
||||
* @throws \CoreException
|
||||
* @throws \CoreUnexpectedValue
|
||||
* @throws \CoreWarning
|
||||
* @throws \MySQLException
|
||||
* @throws \OQLException
|
||||
*/
|
||||
protected function DBInsertTracked_Internal($bDoNotReload = false)
|
||||
{
|
||||
if ($bDoNotReload)
|
||||
{
|
||||
$ret = $this->DBInsertNoReload();
|
||||
}
|
||||
else
|
||||
{
|
||||
$ret = $this->DBInsert();
|
||||
}
|
||||
return $ret;
|
||||
}
|
||||
|
||||
public function DBClone($newKey = null)
|
||||
{
|
||||
return $this->DBCloneTracked_Internal();
|
||||
@@ -622,24 +545,6 @@ abstract class CMDBObject extends DBObject
|
||||
return $ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated 2.7.0 N°2361 simply use {@link DBUpdate} instead, that will automatically create and persist a CMDBChange object.
|
||||
* If you need to persist your own, call {@link CMDBObject::SetCurrentChange} before.
|
||||
*
|
||||
* @param \CMDBChange $oChange
|
||||
* @param null $bSkipStrongSecurity
|
||||
*
|
||||
* @return int|void
|
||||
* @throws \CoreCannotSaveObjectException
|
||||
* @throws \CoreException
|
||||
* @throws \SecurityException
|
||||
*/
|
||||
public function DBUpdateTracked(CMDBChange $oChange, $bSkipStrongSecurity = null)
|
||||
{
|
||||
self::SetCurrentChange($oChange);
|
||||
$this->CheckUserRights($bSkipStrongSecurity, UR_ACTION_MODIFY);
|
||||
$this->DBUpdate();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param null $oDeletionPlan
|
||||
@@ -659,31 +564,6 @@ abstract class CMDBObject extends DBObject
|
||||
return $this->DBDeleteTracked_Internal($oDeletionPlan);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated 2.7.0 N°2361 simply use {@link DBDelete} instead, that will automatically create and persist a CMDBChange object.
|
||||
* If you need to persist your own, call {@link CMDBObject::SetCurrentChange} before.
|
||||
*
|
||||
* @param \CMDBChange $oChange
|
||||
* @param null $bSkipStrongSecurity
|
||||
* @param null $oDeletionPlan
|
||||
*
|
||||
* @throws \ArchivedObjectException
|
||||
* @throws \CoreCannotSaveObjectException
|
||||
* @throws \CoreException
|
||||
* @throws \CoreUnexpectedValue
|
||||
* @throws \DeleteException
|
||||
* @throws \MySQLException
|
||||
* @throws \MySQLHasGoneAwayException
|
||||
* @throws \OQLException
|
||||
* @throws \SecurityException
|
||||
*/
|
||||
public function DBDeleteTracked(CMDBChange $oChange, $bSkipStrongSecurity = null, &$oDeletionPlan = null)
|
||||
{
|
||||
self::SetCurrentChange($oChange);
|
||||
$this->CheckUserRights($bSkipStrongSecurity, UR_ACTION_DELETE);
|
||||
$this->DBDeleteTracked_Internal($oDeletionPlan);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param null $oDeletionPlan
|
||||
*
|
||||
|
||||
@@ -859,25 +859,6 @@ class CMDBSource
|
||||
self::$m_iTransactionLevel = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @deprecated 2.7.0 N°1627 use ItopCounter instead
|
||||
*
|
||||
* @param string $sTable
|
||||
*
|
||||
* @return int
|
||||
* @throws \MySQLException
|
||||
* @throws \MySQLHasGoneAwayException
|
||||
*/
|
||||
public static function GetNextInsertId($sTable)
|
||||
{
|
||||
$sSQL = "SHOW TABLE STATUS LIKE '$sTable'";
|
||||
$oResult = self::Query($sSQL);
|
||||
$aRow = $oResult->fetch_assoc();
|
||||
|
||||
return $aRow['Auto_increment'];
|
||||
}
|
||||
|
||||
public static function GetInsertId()
|
||||
{
|
||||
$iRes = self::$m_oMysqli->insert_id;
|
||||
|
||||
@@ -461,7 +461,7 @@ abstract class DBObject implements iDisplay
|
||||
|
||||
if (array_key_exists($sAttRef, $aRow))
|
||||
{
|
||||
$value = $oAttDef->FromSQLToValue($aRow, $sAttRef);
|
||||
$value = $oAttDef->FromSQLToValue($aRow, $sAttRef, $this, $sAttCode);
|
||||
$bIsDefined = true;
|
||||
}
|
||||
}
|
||||
@@ -2947,46 +2947,6 @@ abstract class DBObject implements iDisplay
|
||||
return $this->m_iKey;
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* @deprecated 2.7.0 N°2361 simply use {@see DBObject::DBInsert()} instead, that will automatically create and persist a CMDBChange object.
|
||||
* If you need to persist your own, call {@see CMDBObject::SetCurrentChange()} before.
|
||||
*
|
||||
* @param CMDBChange $oChange
|
||||
*
|
||||
* @return int|null
|
||||
* @throws CoreException
|
||||
*/
|
||||
public function DBInsertTracked(CMDBChange $oChange)
|
||||
{
|
||||
CMDBObject::SetCurrentChange($oChange);
|
||||
return $this->DBInsert();
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* @deprecated 2.7.0 N°2361 simply use {@see DBObject::DBInsertNoReload()} instead, that will automatically create and persist a CMDBChange object.
|
||||
* If you need to persist your own, call {@see CMDBObject::SetCurrentChange()} before.
|
||||
*
|
||||
* @param CMDBChange $oChange
|
||||
*
|
||||
* @return int
|
||||
* @throws ArchivedObjectException
|
||||
* @throws CoreCannotSaveObjectException
|
||||
* @throws CoreException
|
||||
* @throws CoreUnexpectedValue
|
||||
* @throws CoreWarning
|
||||
* @throws MySQLException
|
||||
* @throws OQLException
|
||||
*/
|
||||
public function DBInsertTrackedNoReload(CMDBChange $oChange)
|
||||
{
|
||||
CMDBObject::SetCurrentChange($oChange);
|
||||
return $this->DBInsertNoReload();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a copy of the current object into the database
|
||||
*
|
||||
@@ -3338,25 +3298,6 @@ abstract class DBObject implements iDisplay
|
||||
$this->m_aPreviousValuesForUpdatedAttributes = $aPreviousValuesForUpdatedAttributes;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @internal
|
||||
*
|
||||
* @deprecated 2.7.0 N°2361 simply use {@see DBObject::DBUpdate()} instead, that will automatically create and persist a CMDBChange object.
|
||||
* If you need to persist your own, call {@see CMDBObject::SetCurrentChange()} before.
|
||||
*
|
||||
* @param CMDBChange $oChange
|
||||
*
|
||||
* @return int
|
||||
* @throws CoreCannotSaveObjectException
|
||||
* @throws CoreException
|
||||
*/
|
||||
public function DBUpdateTracked(CMDBChange $oChange)
|
||||
{
|
||||
CMDBObject::SetCurrentChange($oChange);
|
||||
return $this->DBUpdate();
|
||||
}
|
||||
|
||||
/**
|
||||
* Make the current changes persistent - clever wrapper for Insert or Update
|
||||
*
|
||||
@@ -3611,32 +3552,7 @@ abstract class DBObject implements iDisplay
|
||||
return $oDeletionPlan;
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* @deprecated 2.7.0 N°2361 simply use {@see DBObject::DBDelete()} instead.
|
||||
* If you need to persist your own, call {@see CMDBObject::SetCurrentChange()} before.
|
||||
*
|
||||
* @param CMDBChange $oChange
|
||||
* @param boolean $bSkipStrongSecurity
|
||||
* @param \DeletionPlan $oDeletionPlan
|
||||
*
|
||||
* @throws ArchivedObjectException
|
||||
* @throws CoreCannotSaveObjectException
|
||||
* @throws CoreException
|
||||
* @throws CoreUnexpectedValue
|
||||
* @throws DeleteException
|
||||
* @throws MySQLException
|
||||
* @throws MySQLHasGoneAwayException
|
||||
* @throws OQLException
|
||||
*/
|
||||
public function DBDeleteTracked(CMDBChange $oChange, $bSkipStrongSecurity = null, &$oDeletionPlan = null)
|
||||
{
|
||||
CMDBObject::SetCurrentChange($oChange);
|
||||
$this->DBDelete($oDeletionPlan);
|
||||
}
|
||||
|
||||
/**
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* @return array
|
||||
@@ -4420,22 +4336,7 @@ abstract class DBObject implements iDisplay
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* implement relations
|
||||
*
|
||||
* Return an empty set for the parent of all
|
||||
*
|
||||
* this way of implementing the relations suffers limitations (not handling the redundancy)
|
||||
* and you should consider defining those things in XML
|
||||
*
|
||||
* @internal
|
||||
* @deprecated
|
||||
*/
|
||||
public static function GetRelationQueries($sRelCode)
|
||||
{
|
||||
return array();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Reserved: do not overload
|
||||
*
|
||||
@@ -4446,72 +4347,6 @@ abstract class DBObject implements iDisplay
|
||||
return array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Use GetRelatedObjectsDown/Up instead to take redundancy into account
|
||||
*
|
||||
* @internal
|
||||
* @deprecated
|
||||
*/
|
||||
public function GetRelatedObjects($sRelCode, $iMaxDepth = 99, &$aResults = array())
|
||||
{
|
||||
// Temporary patch: until the impact analysis GUI gets rewritten,
|
||||
// let's consider that "depends on" is equivalent to "impacts/up"
|
||||
// The current patch has been implemented in DBObject and MetaModel
|
||||
$sHackedRelCode = $sRelCode;
|
||||
$bDown = true;
|
||||
if ($sRelCode == 'depends on')
|
||||
{
|
||||
$sHackedRelCode = 'impacts';
|
||||
$bDown = false;
|
||||
}
|
||||
foreach (MetaModel::EnumRelationQueries(get_class($this), $sHackedRelCode, $bDown) as $sDummy => $aQueryInfo)
|
||||
{
|
||||
$sQuery = $bDown ? $aQueryInfo['sQueryDown'] : $aQueryInfo['sQueryUp'];
|
||||
//$bPropagate = $aQueryInfo["bPropagate"];
|
||||
//$iDepth = $bPropagate ? $iMaxDepth - 1 : 0;
|
||||
$iDepth = $iMaxDepth - 1;
|
||||
|
||||
// Note: the loop over the result set has been written in an unusual way for error reporting purposes
|
||||
// In the case of a wrong query parameter name, the error occurs on the first call to Fetch,
|
||||
// thus we need to have this first call into the try/catch, but
|
||||
// we do NOT want to nest the try/catch for the error message to be clear
|
||||
try
|
||||
{
|
||||
$oFlt = DBObjectSearch::FromOQL($sQuery);
|
||||
$oObjSet = new DBObjectSet($oFlt, array(), $this->ToArgsForQuery());
|
||||
$oObj = $oObjSet->Fetch();
|
||||
}
|
||||
catch (Exception $e)
|
||||
{
|
||||
$sClassOfDefinition = $aQueryInfo['_legacy_'] ? get_class($this).'(or a parent)::GetRelationQueries()' : $aQueryInfo['sDefinedInClass'];
|
||||
throw new Exception("Wrong query for the relation $sRelCode/$sClassOfDefinition/{$aQueryInfo['sNeighbour']}: ".$e->getMessage());
|
||||
}
|
||||
if ($oObj)
|
||||
{
|
||||
do
|
||||
{
|
||||
$sRootClass = MetaModel::GetRootClass(get_class($oObj));
|
||||
$sObjKey = $oObj->GetKey();
|
||||
if (array_key_exists($sRootClass, $aResults))
|
||||
{
|
||||
if (array_key_exists($sObjKey, $aResults[$sRootClass]))
|
||||
{
|
||||
continue; // already visited, skip
|
||||
}
|
||||
}
|
||||
|
||||
$aResults[$sRootClass][$sObjKey] = $oObj;
|
||||
if ($iDepth > 0)
|
||||
{
|
||||
$oObj->GetRelatedObjects($sRelCode, $iDepth, $aResults);
|
||||
}
|
||||
}
|
||||
while ($oObj = $oObjSet->Fetch());
|
||||
}
|
||||
}
|
||||
return $aResults;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compute the "RelatedObjects" (forward or "down" direction) for the object
|
||||
* for the specified relation
|
||||
|
||||
@@ -1324,7 +1324,7 @@ class DBObjectSearch extends DBSearch
|
||||
|
||||
// Make the list of acceptable arguments... could be factorized with run_query, into oSearch->GetQueryParams($bExclude magic params)
|
||||
$aNakedMagicArguments = array();
|
||||
foreach (MetaModel::PrepareQueryArguments(array()) as $sArgName => $value)
|
||||
foreach (MetaModel::PrepareQueryArguments(array(),array(), $this->GetExpectedArguments()) as $sArgName => $value)
|
||||
{
|
||||
$iPos = strpos($sArgName, '->object()');
|
||||
if ($iPos === false)
|
||||
@@ -1387,7 +1387,7 @@ class DBObjectSearch extends DBSearch
|
||||
{
|
||||
$aParams = array_merge($aContextParams, $this->m_aParams);
|
||||
}
|
||||
$aParams = MetaModel::PrepareQueryArguments($aParams);
|
||||
$aParams = MetaModel::PrepareQueryArguments($aParams,array(), $this->GetExpectedArguments());
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1580,7 +1580,7 @@ class DBObjectSearch extends DBSearch
|
||||
$aRet = array('selects' => array(), 'joins' => array(), 'where' => array());
|
||||
|
||||
$aParams = array_merge($this->m_aParams);
|
||||
$aParams = MetaModel::PrepareQueryArguments($aParams);
|
||||
$aParams = MetaModel::PrepareQueryArguments($aParams, array(), $this->GetExpectedArguments());
|
||||
|
||||
foreach ($this->m_aSelectedClasses as $sAlias => $sClass)
|
||||
{
|
||||
@@ -1787,7 +1787,7 @@ class DBObjectSearch extends DBSearch
|
||||
{
|
||||
$oSQLObjectQueryBuilder = new SQLObjectQueryBuilder($this);
|
||||
$oSQLQuery = $oSQLObjectQueryBuilder->MakeSQLObjectDeleteQuery();
|
||||
$aScalarArgs = MetaModel::PrepareQueryArguments($aArgs, $this->GetInternalParams());
|
||||
$aScalarArgs = MetaModel::PrepareQueryArguments($aArgs, $this->GetInternalParams(), $this->GetExpectedArguments());
|
||||
$sRet = $oSQLQuery->RenderDelete($aScalarArgs);
|
||||
return $sRet;
|
||||
}
|
||||
@@ -1803,7 +1803,7 @@ class DBObjectSearch extends DBSearch
|
||||
{
|
||||
$oSQLObjectQueryBuilder = new SQLObjectQueryBuilder($this);
|
||||
$oSQLQuery = $oSQLObjectQueryBuilder->MakeSQLObjectUpdateQuery($aValues);
|
||||
$aScalarArgs = MetaModel::PrepareQueryArguments($aArgs, $this->GetInternalParams());
|
||||
$aScalarArgs = MetaModel::PrepareQueryArguments($aArgs, $this->GetInternalParams(), $this->GetExpectedArguments());
|
||||
$sRet = $oSQLQuery->RenderUpdate($aScalarArgs);
|
||||
return $sRet;
|
||||
}
|
||||
@@ -1822,7 +1822,7 @@ class DBObjectSearch extends DBSearch
|
||||
{
|
||||
$oSQLObjectQueryBuilder = new SQLObjectQueryBuilder($this);
|
||||
$oSQLQuery = $oSQLObjectQueryBuilder->MakeSQLObjectUpdateQuery($aValues);
|
||||
$aScalarArgs = MetaModel::PrepareQueryArguments($aArgs, $this->GetInternalParams());
|
||||
$aScalarArgs = MetaModel::PrepareQueryArguments($aArgs, $this->GetInternalParams(), $this->GetExpectedArguments());
|
||||
$sRet = $oSQLQuery->RenderInsert($aScalarArgs);
|
||||
return $sRet;
|
||||
}
|
||||
|
||||
@@ -1312,34 +1312,6 @@ class DBObjectSet implements iDBObjectSetIterator
|
||||
return $oNewSet;
|
||||
}
|
||||
|
||||
/**
|
||||
* Will be deprecated soon - use MetaModel::GetRelatedObjectsDown/Up instead to take redundancy into account
|
||||
*
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function GetRelatedObjects($sRelCode, $iMaxDepth = 99)
|
||||
{
|
||||
$aRelatedObjs = array();
|
||||
|
||||
$aVisited = array(); // optimization for consecutive calls of MetaModel::GetRelatedObjects
|
||||
$this->Seek(0);
|
||||
while ($oObject = $this->Fetch())
|
||||
{
|
||||
$aMore = $oObject->GetRelatedObjects($sRelCode, $iMaxDepth, $aVisited);
|
||||
foreach ($aMore as $sClass => $aRelated)
|
||||
{
|
||||
foreach ($aRelated as $iObj => $oObj)
|
||||
{
|
||||
if (!isset($aRelatedObjs[$sClass][$iObj]))
|
||||
{
|
||||
$aRelatedObjs[$sClass][$iObj] = $oObj;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return $aRelatedObjs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compute the "RelatedObjects" (forward or "down" direction) for the set
|
||||
* for the specified relation
|
||||
@@ -1496,7 +1468,7 @@ class DBObjectSet implements iDBObjectSetIterator
|
||||
public function ListConstantFields()
|
||||
{
|
||||
// The complete list of arguments will include magic arguments (e.g. current_user->attcode)
|
||||
$aScalarArgs = MetaModel::PrepareQueryArguments($this->m_oFilter->GetInternalParams(), $this->m_aArgs);
|
||||
$aScalarArgs = MetaModel::PrepareQueryArguments($this->m_oFilter->GetInternalParams(), $this->m_aArgs, $this->m_oFilter->ListParameters());
|
||||
$aConst = $this->m_oFilter->ListConstantFields();
|
||||
|
||||
foreach($aConst as $sClassAlias => $aVals)
|
||||
@@ -1515,7 +1487,7 @@ class DBObjectSet implements iDBObjectSetIterator
|
||||
|
||||
public function ApplyParameters()
|
||||
{
|
||||
$aAllArgs = MetaModel::PrepareQueryArguments($this->m_oFilter->GetInternalParams(), $this->m_aArgs);
|
||||
$aAllArgs = MetaModel::PrepareQueryArguments($this->m_oFilter->GetInternalParams(), $this->m_aArgs, $this->m_oFilter->GetExpectedArguments());
|
||||
$this->m_oFilter->ApplyParameters($aAllArgs);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,14 +24,14 @@ abstract class HTMLSanitizer
|
||||
{
|
||||
// Do nothing..
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sanitizes the given HTML document
|
||||
* @param string $sHTML
|
||||
* @return string
|
||||
*/
|
||||
abstract public function DoSanitize($sHTML);
|
||||
|
||||
|
||||
/**
|
||||
* Sanitize an HTML string with the configured sanitizer, falling back to HTMLDOMSanitizer in case of Exception or invalid configuration
|
||||
* @param string $sHTML
|
||||
@@ -50,7 +50,7 @@ abstract class HTMLSanitizer
|
||||
IssueLog::Warning('The configured "html_sanitizer" class "'.$sSanitizerClass.'" is not a subclass of HTMLSanitizer. Will use HTMLDOMSanitizer as the default sanitizer.');
|
||||
$sSanitizerClass = 'HTMLDOMSanitizer';
|
||||
}
|
||||
|
||||
|
||||
try
|
||||
{
|
||||
$oSanitizer = new $sSanitizerClass();
|
||||
@@ -70,7 +70,7 @@ abstract class HTMLSanitizer
|
||||
{
|
||||
IssueLog::Error('Failed to sanitize an HTML string with "HTMLDOMSanitizer". The following exception occured: '.$e->getMessage());
|
||||
IssueLog::Error('The HTML will NOT be sanitized.');
|
||||
$sCleanHTML = $sHTML;
|
||||
$sCleanHTML = $sHTML;
|
||||
}
|
||||
}
|
||||
return $sCleanHTML;
|
||||
@@ -97,7 +97,7 @@ class HTMLNullSanitizer extends HTMLSanitizer
|
||||
{
|
||||
return $sHTML;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -109,7 +109,7 @@ class HTMLNullSanitizer extends HTMLSanitizer
|
||||
class HTMLPurifierSanitizer extends HTMLSanitizer
|
||||
{
|
||||
protected static $oPurifier = null;
|
||||
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
if (self::$oPurifier == null)
|
||||
@@ -120,7 +120,7 @@ class HTMLPurifierSanitizer extends HTMLSanitizer
|
||||
throw new Exception("Missing library '$sLibPath', cannot use HTMLPurifierSanitizer.");
|
||||
}
|
||||
require_once($sLibPath);
|
||||
|
||||
|
||||
$oPurifierConfig = HTMLPurifier_Config::createDefault();
|
||||
$oPurifierConfig->set('Core.Encoding', 'UTF-8'); // defaults to 'UTF-8'
|
||||
$oPurifierConfig->set('HTML.Doctype', 'XHTML 1.0 Strict'); // defaults to 'XHTML 1.0 Transitional'
|
||||
@@ -142,11 +142,11 @@ class HTMLPurifierSanitizer extends HTMLSanitizer
|
||||
self::$oPurifier = new HTMLPurifier($oPurifierConfig);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public function DoSanitize($sHTML)
|
||||
{
|
||||
$sCleanHtml = self::$oPurifier->purify($sHTML);
|
||||
return $sCleanHtml;
|
||||
return $sCleanHtml;
|
||||
}
|
||||
}
|
||||
*/
|
||||
@@ -278,13 +278,13 @@ class HTMLDOMSanitizer extends HTMLSanitizer
|
||||
$sHTML = preg_replace('~\xc2\xa0~', ' ', $sHTML);
|
||||
|
||||
@$this->oDoc->loadHTML('<?xml encoding="UTF-8"?>'.$sHTML); // For loading HTML chunks where the character set is not specified
|
||||
|
||||
|
||||
$this->CleanNode($this->oDoc);
|
||||
|
||||
|
||||
$oXPath = new DOMXPath($this->oDoc);
|
||||
$sXPath = "//body";
|
||||
$oNodesList = $oXPath->query($sXPath);
|
||||
|
||||
|
||||
if ($oNodesList->length == 0)
|
||||
{
|
||||
// No body, save the whole document
|
||||
@@ -297,10 +297,10 @@ class HTMLDOMSanitizer extends HTMLSanitizer
|
||||
// remove the body tag itself
|
||||
$sCleanHtml = str_replace( array('<body>', '</body>'), '', $sCleanHtml);
|
||||
}
|
||||
|
||||
|
||||
return $sCleanHtml;
|
||||
}
|
||||
|
||||
|
||||
protected function CleanNode(DOMNode $oElement)
|
||||
{
|
||||
$aAttrToRemove = array();
|
||||
@@ -341,7 +341,7 @@ class HTMLDOMSanitizer extends HTMLSanitizer
|
||||
$oElement->removeAttribute($sName);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if ($oElement->hasChildNodes())
|
||||
{
|
||||
$aChildElementsToRemove = array();
|
||||
@@ -390,7 +390,7 @@ class HTMLDOMSanitizer extends HTMLSanitizer
|
||||
}
|
||||
return implode(';', $aAllowedStyles);
|
||||
}
|
||||
|
||||
|
||||
protected function IsValidAttributeContent($sAttributeName, $sValue)
|
||||
{
|
||||
if (array_key_exists($sAttributeName, self::$aAttrsWhiteList))
|
||||
|
||||
@@ -2047,7 +2047,6 @@ abstract class MetaModel
|
||||
*/
|
||||
protected static function ComputeRelationQueries($sRelCode)
|
||||
{
|
||||
$bHasLegacy = false;
|
||||
$aQueries = array();
|
||||
foreach(self::GetClasses() as $sClass)
|
||||
{
|
||||
@@ -2133,158 +2132,8 @@ abstract class MetaModel
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Read legacy definitions
|
||||
// The up/down queries have to be reconcilied, which can only be done later when all the classes have been browsed
|
||||
//
|
||||
// The keys used to store a query (up or down) into the array are built differently between the modern and legacy made data:
|
||||
// Modern way: aQueries[sClass]['up'|'down'][sArrowId], where sArrowId is made of the source class + neighbour id (XML def)
|
||||
// Legacy way: aQueries[sClass]['up'|'down'][sRemoteClass]
|
||||
// The modern way does allow for several arrows between two classes
|
||||
// The legacy way aims at simplifying the transformation (reconciliation between up and down)
|
||||
if ($sRelCode == 'impacts')
|
||||
{
|
||||
$sRevertCode = 'depends on';
|
||||
|
||||
$aLegacy = call_user_func_array(array($sClass, 'GetRelationQueries'), array($sRelCode));
|
||||
foreach($aLegacy as $sId => $aLegacyEntry)
|
||||
{
|
||||
$bHasLegacy = true;
|
||||
|
||||
$oFilter = DBObjectSearch::FromOQL($aLegacyEntry['sQuery']);
|
||||
$sRemoteClass = $oFilter->GetClass();
|
||||
|
||||
// Determine wether the query is inherited from a parent or not
|
||||
$bInherited = false;
|
||||
foreach(self::EnumParentClasses($sClass) as $sParent)
|
||||
{
|
||||
if (!isset($aQueries[$sParent]['down'][$sRemoteClass]))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if ($aLegacyEntry['sQuery'] == $aQueries[$sParent]['down'][$sRemoteClass]['sQueryDown'])
|
||||
{
|
||||
$bInherited = true;
|
||||
$aQueries[$sClass]['down'][$sRemoteClass] = $aQueries[$sParent]['down'][$sRemoteClass];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!$bInherited)
|
||||
{
|
||||
$aQueries[$sClass]['down'][$sRemoteClass] = array(
|
||||
'_legacy_' => true,
|
||||
'sDefinedInClass' => $sClass,
|
||||
'sFromClass' => $sClass,
|
||||
'sToClass' => $sRemoteClass,
|
||||
'sDirection' => 'down',
|
||||
'sQueryDown' => $aLegacyEntry['sQuery'],
|
||||
'sQueryUp' => null,
|
||||
'sNeighbour' => $sRemoteClass // Normalize the neighbour id
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
$aLegacy = call_user_func_array(array($sClass, 'GetRelationQueries'), array($sRevertCode));
|
||||
foreach($aLegacy as $sId => $aLegacyEntry)
|
||||
{
|
||||
$bHasLegacy = true;
|
||||
|
||||
$oFilter = DBObjectSearch::FromOQL($aLegacyEntry['sQuery']);
|
||||
$sRemoteClass = $oFilter->GetClass();
|
||||
|
||||
// Determine wether the query is inherited from a parent or not
|
||||
$bInherited = false;
|
||||
foreach(self::EnumParentClasses($sClass) as $sParent)
|
||||
{
|
||||
if (!isset($aQueries[$sParent]['up'][$sRemoteClass]))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if ($aLegacyEntry['sQuery'] == $aQueries[$sParent]['up'][$sRemoteClass]['sQueryUp'])
|
||||
{
|
||||
$bInherited = true;
|
||||
$aQueries[$sClass]['up'][$sRemoteClass] = $aQueries[$sParent]['up'][$sRemoteClass];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!$bInherited)
|
||||
{
|
||||
$aQueries[$sClass]['up'][$sRemoteClass] = array(
|
||||
'_legacy_' => true,
|
||||
'sDefinedInClass' => $sRemoteClass,
|
||||
'sFromClass' => $sRemoteClass,
|
||||
'sToClass' => $sClass,
|
||||
'sDirection' => 'both',
|
||||
'sQueryDown' => null,
|
||||
'sQueryUp' => $aLegacyEntry['sQuery'],
|
||||
'sNeighbour' => $sClass// Normalize the neighbour id
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
//else
|
||||
//{
|
||||
// Cannot take the legacy system into account... simply ignore it
|
||||
//}
|
||||
} // foreach class
|
||||
|
||||
// Perform the up/down reconciliation for the legacy definitions
|
||||
if ($bHasLegacy)
|
||||
{
|
||||
foreach(self::GetClasses() as $sClass)
|
||||
{
|
||||
// Foreach "up" legacy query, update its "down" counterpart
|
||||
if (isset($aQueries[$sClass]['up']))
|
||||
{
|
||||
foreach($aQueries[$sClass]['up'] as $sNeighbourId => $aNeighbourData)
|
||||
{
|
||||
if (!array_key_exists('_legacy_', $aNeighbourData))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (!$aNeighbourData['_legacy_'])
|
||||
{
|
||||
continue;
|
||||
} // Skip modern definitions
|
||||
|
||||
$sLocalClass = $aNeighbourData['sToClass'];
|
||||
foreach(self::EnumChildClasses($aNeighbourData['sFromClass'], ENUM_CHILD_CLASSES_ALL) as $sRemoteClass)
|
||||
{
|
||||
if (isset($aQueries[$sRemoteClass]['down'][$sLocalClass]))
|
||||
{
|
||||
$aQueries[$sRemoteClass]['down'][$sLocalClass]['sQueryUp'] = $aNeighbourData['sQueryUp'];
|
||||
$aQueries[$sRemoteClass]['down'][$sLocalClass]['sDirection'] = 'both';
|
||||
}
|
||||
// Be silent in order to transparently support legacy data models where the counterpart query does not always exist
|
||||
//else
|
||||
//{
|
||||
// throw new Exception("Legacy definition of the relation '$sRelCode/$sRevertCode', defined on $sLocalClass (relation: $sRevertCode, inherited to $sClass), missing the counterpart query on class $sRemoteClass ($sRelCode)");
|
||||
//}
|
||||
}
|
||||
}
|
||||
}
|
||||
// Foreach "down" legacy query, update its "up" counterpart (if any)
|
||||
foreach($aQueries[$sClass]['down'] as $sNeighbourId => $aNeighbourData)
|
||||
{
|
||||
if (!$aNeighbourData['_legacy_'])
|
||||
{
|
||||
continue;
|
||||
} // Skip modern definitions
|
||||
|
||||
$sLocalClass = $aNeighbourData['sFromClass'];
|
||||
foreach(self::EnumChildClasses($aNeighbourData['sToClass'], ENUM_CHILD_CLASSES_ALL) as $sRemoteClass)
|
||||
{
|
||||
if (isset($aQueries[$sRemoteClass]['up'][$sLocalClass]))
|
||||
{
|
||||
$aQueries[$sRemoteClass]['up'][$sLocalClass]['sQueryDown'] = $aNeighbourData['sQueryDown'];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $aQueries;
|
||||
}
|
||||
|
||||
@@ -3318,18 +3167,6 @@ abstract class MetaModel
|
||||
// In fact it is an ABSTRACT function, but this is not compatible with the fact that it is STATIC (error in E_STRICT interpretation)
|
||||
}
|
||||
|
||||
/**
|
||||
* To be overloaded by biz model declarations
|
||||
*
|
||||
* @param string $sRelCode
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function GetRelationQueries($sRelCode)
|
||||
{
|
||||
// In fact it is an ABSTRACT function, but this is not compatible with the fact that it is STATIC (error in E_STRICT interpretation)
|
||||
return array();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $aParams
|
||||
@@ -7239,99 +7076,11 @@ abstract class MetaModel
|
||||
return $aResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated 2.5.0 It is not recommended to use this function: call {@link MetaModel::GetLinkClasses} instead !
|
||||
* The only difference with EnumLinkingClasses is the output format
|
||||
*
|
||||
* @see MetaModel::GetLinkClasses
|
||||
* @return string[] classes having at least two external keys (thus too many classes as compared to GetLinkClasses)
|
||||
*
|
||||
*/
|
||||
public static function EnumLinksClasses()
|
||||
{
|
||||
// Returns a flat array of classes having at least two external keys
|
||||
$aResult = array();
|
||||
foreach(self::$m_aAttribDefs as $sSomeClass => $aClassAttributes)
|
||||
{
|
||||
$iExtKeyCount = 0;
|
||||
foreach($aClassAttributes as $sAttCode => $oAttDef)
|
||||
{
|
||||
if (self::$m_aAttribOrigins[$sSomeClass][$sAttCode] != $sSomeClass)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if ($oAttDef->IsExternalKey())
|
||||
{
|
||||
$iExtKeyCount++;
|
||||
}
|
||||
}
|
||||
if ($iExtKeyCount >= 2)
|
||||
{
|
||||
$aResult[] = $sSomeClass;
|
||||
}
|
||||
}
|
||||
return $aResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated 2.5.0 It is not recommended to use this function: call {@link MetaModel::GetLinkClasses} instead !
|
||||
* The only difference with EnumLinksClasses is the output format
|
||||
*
|
||||
* @see MetaModel::GetLinkClasses
|
||||
*
|
||||
*@param string $sClass
|
||||
*
|
||||
* @return string[] classes having at least two external keys (thus too many classes as compared to GetLinkClasses)
|
||||
* @throws \CoreException
|
||||
*
|
||||
*/
|
||||
public static function EnumLinkingClasses($sClass = "")
|
||||
{
|
||||
// N-N links, array of sLinkClass => (array of sAttCode=>sClass)
|
||||
$aResult = array();
|
||||
foreach(self::EnumLinksClasses() as $sSomeClass)
|
||||
{
|
||||
$aTargets = array();
|
||||
$bFoundClass = false;
|
||||
foreach(self::ListAttributeDefs($sSomeClass) as $sAttCode => $oAttDef)
|
||||
{
|
||||
if (self::$m_aAttribOrigins[$sSomeClass][$sAttCode] != $sSomeClass)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if ($oAttDef->IsExternalKey())
|
||||
{
|
||||
$sRemoteClass = $oAttDef->GetTargetClass();
|
||||
if (empty($sClass))
|
||||
{
|
||||
$aTargets[$sAttCode] = $sRemoteClass;
|
||||
}
|
||||
elseif ($sClass == $sRemoteClass)
|
||||
{
|
||||
$bFoundClass = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
$aTargets[$sAttCode] = $sRemoteClass;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (empty($sClass) || $bFoundClass)
|
||||
{
|
||||
$aResult[$sSomeClass] = $aTargets;
|
||||
}
|
||||
}
|
||||
return $aResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* Using GetLinkClasses is the recommended way to determine if a class is
|
||||
* actually an N-N relation because it is based on the decision made by the
|
||||
* designer the data model
|
||||
*
|
||||
* This function has two siblings that will be soon deprecated:
|
||||
* {@link MetaModel::EnumLinkingClasses} and {@link MetaModel::EnumLinkClasses}
|
||||
*
|
||||
* @return array (target class => (external key code => target class))
|
||||
* @throws \CoreException
|
||||
*/
|
||||
|
||||
@@ -1643,6 +1643,35 @@ class FieldExpression extends UnaryExpression
|
||||
// Has been resolved into an SQL expression
|
||||
class FieldExpressionResolved extends FieldExpression
|
||||
{
|
||||
protected $m_aAdditionalExpressions;
|
||||
|
||||
public function __construct($mExpression, $sParent = '')
|
||||
{
|
||||
$this->m_aAdditionalExpressions = array();
|
||||
if (is_array($mExpression))
|
||||
{
|
||||
foreach ($mExpression as $sSuffix => $sExpression)
|
||||
{
|
||||
if ($sSuffix == '')
|
||||
{
|
||||
$sName = $sExpression;
|
||||
}
|
||||
$this->m_aAdditionalExpressions[$sSuffix] = new FieldExpressionResolved($sExpression, $sParent);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$sName = $mExpression;
|
||||
}
|
||||
|
||||
parent::__construct($sName, $sParent);
|
||||
}
|
||||
|
||||
public function AdditionalExpressions()
|
||||
{
|
||||
return $this->m_aAdditionalExpressions;
|
||||
}
|
||||
|
||||
public function GetUnresolvedFields($sAlias, &$aUnresolved)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -38,6 +38,8 @@ class ormDocument
|
||||
protected $m_data;
|
||||
protected $m_sMimeType;
|
||||
protected $m_sFileName;
|
||||
protected $m_oHostObject;
|
||||
protected $m_sHostObjectAttcode;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
@@ -47,6 +49,15 @@ class ormDocument
|
||||
$this->m_data = $data;
|
||||
$this->m_sMimeType = $sMimeType;
|
||||
$this->m_sFileName = $sFileName;
|
||||
|
||||
$this->m_oHostObject = null;
|
||||
$this->m_sHostObjectAttcode = null;
|
||||
}
|
||||
|
||||
public function SetHostObject(DBObject $oHostObject, $sAttCode)
|
||||
{
|
||||
$this->m_oHostObject = $oHostObject;
|
||||
$this->m_sHostObjectAttcode = $sAttCode;
|
||||
}
|
||||
|
||||
public function __toString()
|
||||
@@ -138,6 +149,12 @@ class ormDocument
|
||||
*/
|
||||
public function GetDownloadLink($sClass, $Id, $sAttCode)
|
||||
{
|
||||
if ($this->m_oHostObject)
|
||||
{
|
||||
$sClass = get_class($this->m_oHostObject);
|
||||
$Id = $this->m_oHostObject->GetKey();
|
||||
$sAttCode = $this->m_sHostObjectAttcode;
|
||||
}
|
||||
return "<a href=\"".utils::GetAbsoluteUrlAppRoot()."pages/ajax.document.php?operation=download_document&class=$sClass&id=$Id&field=$sAttCode\">".htmlentities($this->GetFileName(), ENT_QUOTES, 'UTF-8')."</a>\n";
|
||||
}
|
||||
|
||||
@@ -147,6 +164,12 @@ class ormDocument
|
||||
*/
|
||||
public function GetDisplayURL($sClass, $Id, $sAttCode)
|
||||
{
|
||||
if ($this->m_oHostObject)
|
||||
{
|
||||
$sClass = get_class($this->m_oHostObject);
|
||||
$Id = $this->m_oHostObject->GetKey();
|
||||
$sAttCode = $this->m_sHostObjectAttcode;
|
||||
}
|
||||
// TODO: When refactoring this with the URLMaker system, mind to also change calls in the portal (look for the "p_object_document_display" route)
|
||||
return utils::GetAbsoluteUrlAppRoot() . "pages/ajax.render.php?operation=display_document&class=$sClass&id=$Id&field=$sAttCode";
|
||||
}
|
||||
@@ -157,6 +180,12 @@ class ormDocument
|
||||
*/
|
||||
public function GetDownloadURL($sClass, $Id, $sAttCode)
|
||||
{
|
||||
if ($this->m_oHostObject)
|
||||
{
|
||||
$sClass = get_class($this->m_oHostObject);
|
||||
$Id = $this->m_oHostObject->GetKey();
|
||||
$sAttCode = $this->m_sHostObjectAttcode;
|
||||
}
|
||||
// Compute a signature to reset the cache anytime the data changes (this is acceptable if used only with icon files)
|
||||
$sSignature = md5($this->GetData());
|
||||
// TODO: When refactoring this with the URLMaker system, mind to also change calls in the portal (look for the "p_object_document_display" route)
|
||||
|
||||
@@ -178,6 +178,14 @@ class QueryBuilderExpressions
|
||||
foreach ($this->m_aSelectExpr as $sColAlias => $oExpr)
|
||||
{
|
||||
$this->m_aSelectExpr[$sColAlias] = $oExpr->Translate($aTranslationData, $bMatchAll, $bMarkFieldsAsResolved);
|
||||
if ($this->m_aSelectExpr[$sColAlias] instanceof FieldExpressionResolved)
|
||||
{
|
||||
// Split the field with the relevant alias
|
||||
foreach ($this->m_aSelectExpr[$sColAlias]->AdditionalExpressions() as $sSuffix => $oAdditionalExpr)
|
||||
{
|
||||
$this->m_aSelectExpr[$sColAlias.$sSuffix] = $oAdditionalExpr->Translate($aTranslationData, $bMatchAll, $bMarkFieldsAsResolved);
|
||||
}
|
||||
}
|
||||
}
|
||||
if ($this->m_aGroupByExpr)
|
||||
{
|
||||
|
||||
@@ -239,24 +239,16 @@ class SQLObjectQueryBuilder
|
||||
continue;
|
||||
}
|
||||
$oAttDef = MetaModel::GetAttributeDef($sClass, $sAttCode);
|
||||
foreach ($oAttDef->GetSQLExpressions() as $sColId => $sSQLExpr)
|
||||
$oFieldSQLExp = new FieldExpressionResolved($oAttDef->GetSQLExpressions(), $sClassAlias);
|
||||
/**
|
||||
* @var string $sPluginClass
|
||||
* @var iQueryModifier $oQueryModifier
|
||||
*/
|
||||
foreach (MetaModel::EnumPlugins('iQueryModifier') as $sPluginClass => $oQueryModifier)
|
||||
{
|
||||
if (!empty($sColId))
|
||||
{
|
||||
// Multi column attributes
|
||||
$oBuild->m_oQBExpressions->AddSelect($sSelectedClassAlias.$sAttCode.$sColId, new FieldExpression($sAttCode.$sColId, $sClassAlias));
|
||||
}
|
||||
$oFieldSQLExp = new FieldExpressionResolved($sSQLExpr, $sClassAlias);
|
||||
/**
|
||||
* @var string $sPluginClass
|
||||
* @var iQueryModifier $oQueryModifier
|
||||
*/
|
||||
foreach (MetaModel::EnumPlugins('iQueryModifier') as $sPluginClass => $oQueryModifier)
|
||||
{
|
||||
$oFieldSQLExp = $oQueryModifier->GetFieldExpression($oBuild, $sClass, $sAttCode, $sColId, $oFieldSQLExp, $oBaseSQLQuery);
|
||||
}
|
||||
$aTranslation[$sClassAlias][$sAttCode.$sColId] = $oFieldSQLExp;
|
||||
$oFieldSQLExp = $oQueryModifier->GetFieldExpression($oBuild, $sClass, $sAttCode, '', $oFieldSQLExp, $oBaseSQLQuery);
|
||||
}
|
||||
$aTranslation[$sClassAlias][$sAttCode] = $oFieldSQLExp;
|
||||
}
|
||||
|
||||
// Translate the selected columns
|
||||
|
||||
@@ -141,7 +141,10 @@ class ValueSetObjects extends ValueSetDefinition
|
||||
$this->m_oExtraCondition = $oFilter;
|
||||
$this->m_bIsLoaded = false;
|
||||
}
|
||||
|
||||
public function SetOrderBy(array $aOrderBy)
|
||||
{
|
||||
$this->m_aOrderBy = $aOrderBy;
|
||||
}
|
||||
public function ToObjectSet($aArgs = array(), $sContains = '', $iAdditionalValue = null)
|
||||
{
|
||||
if ($this->m_bAllowAllData)
|
||||
@@ -243,7 +246,7 @@ class ValueSetObjects extends ValueSetDefinition
|
||||
$oExpression = DBObjectSearch::GetPolymorphicExpression($oFilter->GetClass(), 'friendlyname');
|
||||
$aFields = $oExpression->ListRequiredFields();
|
||||
$sClass = $oFilter->GetClass();
|
||||
foreach($aFields as $sField)
|
||||
/*foreach($aFields as $sField)
|
||||
{
|
||||
$aFieldItems = explode('.', $sField);
|
||||
if ($aFieldItems[0] != $sClass)
|
||||
@@ -251,7 +254,7 @@ class ValueSetObjects extends ValueSetDefinition
|
||||
$sOperation = 'contains';
|
||||
break;
|
||||
}
|
||||
}
|
||||
}*/
|
||||
|
||||
switch ($sOperation)
|
||||
{
|
||||
|
||||
7
css/font-awesome/css/font-awesome.min.css
vendored
7
css/font-awesome/css/font-awesome.min.css
vendored
@@ -1,7 +0,0 @@
|
||||
/**
|
||||
This was the file containing the rules of Font Awesome v4. Kept for scripts that included it directly.
|
||||
@deprecated 2.7.0 N°2269, use /css/font-awesome/css/all.min.css instead (Font Awesome v5)
|
||||
*/
|
||||
|
||||
@import "all.min.css";
|
||||
@import "v4-shims.min.css";
|
||||
5
css/font-awesome/css/v4-shims.min.css
vendored
5
css/font-awesome/css/v4-shims.min.css
vendored
File diff suppressed because one or more lines are too long
@@ -3903,4 +3903,52 @@ input:checked + .slider:before {
|
||||
}
|
||||
.ui-dialog .ui-dialog-content .treecontrol a {
|
||||
font-size: small;
|
||||
}
|
||||
}
|
||||
/*for autocomplete*/
|
||||
.ui-autocomplete {
|
||||
padding: 0px;
|
||||
border: 1px solid black;
|
||||
background-color: white;
|
||||
overflow: hidden;
|
||||
z-index: 99999;
|
||||
|
||||
ul {
|
||||
width: 100%;
|
||||
list-style-position: outside;
|
||||
list-style: none;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
li.ui-menu-item {
|
||||
margin: 0px;
|
||||
padding: 2px 5px;
|
||||
white-space: nowrap;
|
||||
padding-right: 20px; /* Space for the scrollbar */
|
||||
cursor: default;
|
||||
display: block;
|
||||
/*
|
||||
if width will be 100% horizontal scrollbar will apear
|
||||
when scroll mode will be used
|
||||
*/
|
||||
/*width: 100%;*/
|
||||
font: menu;
|
||||
font-size: 12px;
|
||||
/*
|
||||
it is very important, if line-height not setted or setted
|
||||
in relative units scroll will be broken in firefox
|
||||
*/
|
||||
line-height: 16px;
|
||||
overflow: hidden;
|
||||
|
||||
&:nth-child(odd) {
|
||||
background-color: #eee;
|
||||
}
|
||||
|
||||
&.ui-state-focus {
|
||||
background-color: #0A246A;
|
||||
border-color: #0A246A;
|
||||
color: white;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -156,7 +156,7 @@ class CASLoginExtension extends AbstractLoginFSMExtension implements iLogoutExte
|
||||
{
|
||||
phpCAS::setDebug(APPROOT.'log/cas.log');
|
||||
}
|
||||
|
||||
|
||||
// Initialize phpCAS
|
||||
$sCASVersion = Config::Get('cas_version');
|
||||
$sCASHost = Config::Get('cas_host');
|
||||
@@ -500,15 +500,8 @@ class CASUserProvisioning
|
||||
}
|
||||
|
||||
// Now synchronize the profiles
|
||||
$oProfilesSet = DBObjectSet::FromScratch('URP_UserProfile');
|
||||
foreach($aProfiles as $iProfileId)
|
||||
{
|
||||
$oLink = new URP_UserProfile();
|
||||
$oLink->Set('profileid', $iProfileId);
|
||||
$oLink->Set('reason', 'CAS/LDAP Synchro');
|
||||
$oProfilesSet->AddObject($oLink);
|
||||
}
|
||||
$oUser->Set('profile_list', $oProfilesSet);
|
||||
LoginWebPage::SynchroniseProfiles($oUser, $aProfiles, 'CAS/LDAP Synchro');
|
||||
|
||||
phpCAS::log("Info: the user '".$oUser->GetName()."' (id=".$oUser->GetKey().") now has the following profiles: '".implode("', '", $aProfiles)."'.");
|
||||
if ($oUser->IsModified())
|
||||
{
|
||||
|
||||
@@ -134,6 +134,8 @@ set_time_limit(0);
|
||||
if (utils::IsModeCLI())
|
||||
{
|
||||
$oP = new CLIPage("iTop - Database Backup");
|
||||
|
||||
SetupUtils::CheckPhpAndExtensionsForCli($oP);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -250,6 +250,8 @@ catch(Exception $e)
|
||||
|
||||
if (utils::IsModeCLI())
|
||||
{
|
||||
SetupUtils::CheckPhpAndExtensionsForCli(new CLIPage('Check backup utility'));
|
||||
|
||||
echo date('Y-m-d H:i:s')." - running check-backup utility\n";
|
||||
try
|
||||
{
|
||||
|
||||
@@ -1684,16 +1684,6 @@
|
||||
</list>
|
||||
</presentation>
|
||||
<methods>
|
||||
<method id="GetRelationQueries">
|
||||
<comment>/**
|
||||
* Placeholder for backward compatibility (iTop <= 2.1.0)
|
||||
* in case an extension attempts to redefine this function...
|
||||
*/</comment>
|
||||
<static>true</static>
|
||||
<access>public</access>
|
||||
<type>Overload-DBObject</type>
|
||||
<code><![CDATA[ public static function GetRelationQueries($sRelCode){return parent::GetRelationQueries($sRelCode);} ]]></code>
|
||||
</method>
|
||||
<method id="DisplayBareRelations">
|
||||
<static>false</static>
|
||||
<access>public</access>
|
||||
@@ -2170,18 +2160,7 @@
|
||||
</items>
|
||||
</list>
|
||||
</presentation>
|
||||
<methods>
|
||||
<method id="GetRelationQueries">
|
||||
<comment>/**
|
||||
* Placeholder for backward compatibility (iTop <= 2.1.0)
|
||||
* in case an extension attempts to redefine this function...
|
||||
*/</comment>
|
||||
<static>true</static>
|
||||
<access>public</access>
|
||||
<type>Overload-DBObject</type>
|
||||
<code><![CDATA[ public static function GetRelationQueries($sRelCode){return parent::GetRelationQueries($sRelCode);} ]]></code>
|
||||
</method>
|
||||
</methods>
|
||||
<methods/>
|
||||
</class>
|
||||
<class id="DatacenterDevice" _delta="define">
|
||||
<parent>ConnectableCI</parent>
|
||||
@@ -2732,18 +2711,7 @@
|
||||
</items>
|
||||
</list>
|
||||
</presentation>
|
||||
<methods>
|
||||
<method id="GetRelationQueries">
|
||||
<comment>/**
|
||||
* Placeholder for backward compatibility (iTop <= 2.1.0)
|
||||
* in case an extension attempts to redefine this function...
|
||||
*/</comment>
|
||||
<static>true</static>
|
||||
<access>public</access>
|
||||
<type>Overload-DBObject</type>
|
||||
<code><![CDATA[ public static function GetRelationQueries($sRelCode){return parent::GetRelationQueries($sRelCode);} ]]></code>
|
||||
</method>
|
||||
</methods>
|
||||
<methods/>
|
||||
<relations>
|
||||
<relation id="impacts">
|
||||
<neighbours>
|
||||
@@ -3060,18 +3028,7 @@
|
||||
</items>
|
||||
</list>
|
||||
</presentation>
|
||||
<methods>
|
||||
<method id="GetRelationQueries">
|
||||
<comment>/**
|
||||
* Placeholder for backward compatibility (iTop <= 2.1.0)
|
||||
* in case an extension attempts to redefine this function...
|
||||
*/</comment>
|
||||
<static>true</static>
|
||||
<access>public</access>
|
||||
<type>Overload-DBObject</type>
|
||||
<code><![CDATA[ public static function GetRelationQueries($sRelCode){return parent::GetRelationQueries($sRelCode);} ]]></code>
|
||||
</method>
|
||||
</methods>
|
||||
<methods/>
|
||||
</class>
|
||||
<class id="ApplicationSolution" _delta="define">
|
||||
<parent>FunctionalCI</parent>
|
||||
@@ -3210,18 +3167,7 @@
|
||||
</items>
|
||||
</list>
|
||||
</presentation>
|
||||
<methods>
|
||||
<method id="GetRelationQueries">
|
||||
<comment>/**
|
||||
* Placeholder for backward compatibility (iTop <= 2.1.0)
|
||||
* in case an extension attempts to redefine this function...
|
||||
*/</comment>
|
||||
<static>true</static>
|
||||
<access>public</access>
|
||||
<type>Overload-DBObject</type>
|
||||
<code><![CDATA[ public static function GetRelationQueries($sRelCode){return parent::GetRelationQueries($sRelCode);} ]]></code>
|
||||
</method>
|
||||
</methods>
|
||||
<methods/>
|
||||
<relations>
|
||||
<relation id="impacts">
|
||||
<neighbours>
|
||||
@@ -3341,18 +3287,7 @@
|
||||
</items>
|
||||
</list>
|
||||
</presentation>
|
||||
<methods>
|
||||
<method id="GetRelationQueries">
|
||||
<comment>/**
|
||||
* Placeholder for backward compatibility (iTop <= 2.1.0)
|
||||
* in case an extension attempts to redefine this function...
|
||||
*/</comment>
|
||||
<static>true</static>
|
||||
<access>public</access>
|
||||
<type>Overload-DBObject</type>
|
||||
<code><![CDATA[ public static function GetRelationQueries($sRelCode){return parent::GetRelationQueries($sRelCode);} ]]></code>
|
||||
</method>
|
||||
</methods>
|
||||
<methods/>
|
||||
</class>
|
||||
<class id="SoftwareInstance" _delta="define">
|
||||
<parent>FunctionalCI</parent>
|
||||
@@ -3533,18 +3468,7 @@
|
||||
</items>
|
||||
</list>
|
||||
</presentation>
|
||||
<methods>
|
||||
<method id="GetRelationQueries">
|
||||
<comment>/**
|
||||
* Placeholder for backward compatibility (iTop <= 2.1.0)
|
||||
* in case an extension attempts to redefine this function...
|
||||
*/</comment>
|
||||
<static>true</static>
|
||||
<access>public</access>
|
||||
<type>Overload-DBObject</type>
|
||||
<code><![CDATA[ public static function GetRelationQueries($sRelCode){return parent::GetRelationQueries($sRelCode);} ]]></code>
|
||||
</method>
|
||||
</methods>
|
||||
<methods/>
|
||||
</class>
|
||||
<class id="Middleware" _delta="define">
|
||||
<parent>SoftwareInstance</parent>
|
||||
@@ -3669,18 +3593,7 @@
|
||||
</items>
|
||||
</list>
|
||||
</presentation>
|
||||
<methods>
|
||||
<method id="GetRelationQueries">
|
||||
<comment>/**
|
||||
* Placeholder for backward compatibility (iTop <= 2.1.0)
|
||||
* in case an extension attempts to redefine this function...
|
||||
*/</comment>
|
||||
<static>true</static>
|
||||
<access>public</access>
|
||||
<type>Overload-DBObject</type>
|
||||
<code><![CDATA[ public static function GetRelationQueries($sRelCode){return parent::GetRelationQueries($sRelCode);} ]]></code>
|
||||
</method>
|
||||
</methods>
|
||||
<methods/>
|
||||
<relations>
|
||||
<relation id="impacts">
|
||||
<neighbours>
|
||||
@@ -3814,18 +3727,7 @@
|
||||
</items>
|
||||
</list>
|
||||
</presentation>
|
||||
<methods>
|
||||
<method id="GetRelationQueries">
|
||||
<comment>/**
|
||||
* Placeholder for backward compatibility (iTop <= 2.1.0)
|
||||
* in case an extension attempts to redefine this function...
|
||||
*/</comment>
|
||||
<static>true</static>
|
||||
<access>public</access>
|
||||
<type>Overload-DBObject</type>
|
||||
<code><![CDATA[ public static function GetRelationQueries($sRelCode){return parent::GetRelationQueries($sRelCode);} ]]></code>
|
||||
</method>
|
||||
</methods>
|
||||
<methods/>
|
||||
<relations>
|
||||
<relation id="impacts">
|
||||
<neighbours>
|
||||
@@ -3959,18 +3861,7 @@
|
||||
</items>
|
||||
</list>
|
||||
</presentation>
|
||||
<methods>
|
||||
<method id="GetRelationQueries">
|
||||
<comment>/**
|
||||
* Placeholder for backward compatibility (iTop <= 2.1.0)
|
||||
* in case an extension attempts to redefine this function...
|
||||
*/</comment>
|
||||
<static>true</static>
|
||||
<access>public</access>
|
||||
<type>Overload-DBObject</type>
|
||||
<code><![CDATA[ public static function GetRelationQueries($sRelCode){return parent::GetRelationQueries($sRelCode);} ]]></code>
|
||||
</method>
|
||||
</methods>
|
||||
<methods/>
|
||||
<relations>
|
||||
<relation id="impacts">
|
||||
<neighbours>
|
||||
@@ -4329,18 +4220,7 @@
|
||||
</items>
|
||||
</list>
|
||||
</presentation>
|
||||
<methods>
|
||||
<method id="GetRelationQueries">
|
||||
<comment>/**
|
||||
* Placeholder for backward compatibility (iTop <= 2.1.0)
|
||||
* in case an extension attempts to redefine this function...
|
||||
*/</comment>
|
||||
<static>true</static>
|
||||
<access>public</access>
|
||||
<type>Overload-DBObject</type>
|
||||
<code><![CDATA[ public static function GetRelationQueries($sRelCode){return parent::GetRelationQueries($sRelCode);} ]]></code>
|
||||
</method>
|
||||
</methods>
|
||||
<methods/>
|
||||
</class>
|
||||
<class id="DatabaseSchema" _delta="define">
|
||||
<parent>FunctionalCI</parent>
|
||||
@@ -4462,18 +4342,7 @@
|
||||
</items>
|
||||
</list>
|
||||
</presentation>
|
||||
<methods>
|
||||
<method id="GetRelationQueries">
|
||||
<comment>/**
|
||||
* Placeholder for backward compatibility (iTop <= 2.1.0)
|
||||
* in case an extension attempts to redefine this function...
|
||||
*/</comment>
|
||||
<static>true</static>
|
||||
<access>public</access>
|
||||
<type>Overload-DBObject</type>
|
||||
<code><![CDATA[ public static function GetRelationQueries($sRelCode){return parent::GetRelationQueries($sRelCode);} ]]></code>
|
||||
</method>
|
||||
</methods>
|
||||
<methods/>
|
||||
</class>
|
||||
<class id="WebApplication" _delta="define">
|
||||
<parent>FunctionalCI</parent>
|
||||
@@ -4604,18 +4473,7 @@
|
||||
</items>
|
||||
</list>
|
||||
</presentation>
|
||||
<methods>
|
||||
<method id="GetRelationQueries">
|
||||
<comment>/**
|
||||
* Placeholder for backward compatibility (iTop <= 2.1.0)
|
||||
* in case an extension attempts to redefine this function...
|
||||
*/</comment>
|
||||
<static>true</static>
|
||||
<access>public</access>
|
||||
<type>Overload-DBObject</type>
|
||||
<code><![CDATA[ public static function GetRelationQueries($sRelCode){return parent::GetRelationQueries($sRelCode);} ]]></code>
|
||||
</method>
|
||||
</methods>
|
||||
<methods/>
|
||||
</class>
|
||||
<class id="Software" _delta="define">
|
||||
<parent>cmdbAbstractObject</parent>
|
||||
|
||||
@@ -232,18 +232,7 @@
|
||||
<count_max>0</count_max>
|
||||
</field>
|
||||
</fields>
|
||||
<methods>
|
||||
<method id="GetRelationQueries">
|
||||
<comment>/**
|
||||
* Placeholder for backward compatibility (iTop <= 2.1.0)
|
||||
* in case an extension attempts to redefine this function...
|
||||
*/</comment>
|
||||
<static>true</static>
|
||||
<access>public</access>
|
||||
<type>Overload-DBObject</type>
|
||||
<code><![CDATA[ public static function GetRelationQueries($sRelCode){return parent::GetRelationQueries($sRelCode);} ]]></code>
|
||||
</method>
|
||||
</methods>
|
||||
<methods/>
|
||||
<presentation>
|
||||
<details>
|
||||
<items>
|
||||
@@ -411,18 +400,7 @@
|
||||
</reconciliation>
|
||||
</properties>
|
||||
<fields/>
|
||||
<methods>
|
||||
<method id="GetRelationQueries">
|
||||
<comment>/**
|
||||
* Placeholder for backward compatibility (iTop <= 2.1.0)
|
||||
* in case an extension attempts to redefine this function...
|
||||
*/</comment>
|
||||
<static>true</static>
|
||||
<access>public</access>
|
||||
<type>Overload-DBObject</type>
|
||||
<code><![CDATA[ public static function GetRelationQueries($sRelCode){return parent::GetRelationQueries($sRelCode);} ]]></code>
|
||||
</method>
|
||||
</methods>
|
||||
<methods/>
|
||||
<presentation>
|
||||
<details>
|
||||
<items>
|
||||
@@ -911,18 +889,7 @@
|
||||
</items>
|
||||
</list>
|
||||
</presentation>
|
||||
<methods>
|
||||
<method id="GetRelationQueries">
|
||||
<comment>/**
|
||||
* Placeholder for backward compatibility (iTop <= 2.1.0)
|
||||
* in case an extension attempts to redefine this function...
|
||||
*/</comment>
|
||||
<static>true</static>
|
||||
<access>public</access>
|
||||
<type>Overload-DBObject</type>
|
||||
<code><![CDATA[ public static function GetRelationQueries($sRelCode){return parent::GetRelationQueries($sRelCode);} ]]></code>
|
||||
</method>
|
||||
</methods>
|
||||
<methods/>
|
||||
</class>
|
||||
</classes>
|
||||
<menus>
|
||||
|
||||
@@ -241,7 +241,6 @@ function DoInstall(WebPage $oPage)
|
||||
|
||||
|
||||
$oPage->add_linked_stylesheet('../css/font-awesome/css/all.min.css');
|
||||
$oPage->add_linked_stylesheet('../css/font-awesome/css/v4-shims.min.css');
|
||||
|
||||
|
||||
$oPage->add('<div id="hub_installation_widget"></div>');
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
id="brick-{{ oBrick.GetId }}"
|
||||
data-brick-id="{{ oBrick.GetId }}">
|
||||
<div>
|
||||
<div class="tile_title"><span class="icon fa fa-{{ oBrick.GetTileMode }}"></span> {{ oBrick.GetTitle()|dict_s }}
|
||||
<div class="tile_title"><span class="icon fas fa-{{ oBrick.GetTileMode }}"></span> {{ oBrick.GetTitle()|dict_s }}
|
||||
({{ iCount }})</span> </div>
|
||||
{% include 'itop-portal-base/portal/templates/bricks/manage/mode-' ~ oBrick.GetTileMode ~ '.html.twig' with {'oBrick': oBrick, 'aColumns': aColumns, 'aNames': aNames, 'aUrls': aUrls, 'aDisplayValues': aDisplayValues} %}
|
||||
</div>
|
||||
|
||||
@@ -43,7 +43,6 @@
|
||||
<link href="{{ app['combodo.absolute_url'] ~ 'css/font-combodo/font-combodo.css'|add_itop_version }}" rel="stylesheet">
|
||||
{# - Font awesome #}
|
||||
<link href="{{ app['combodo.absolute_url'] ~ 'css/font-awesome/css/all.min.css'|add_itop_version }}" rel="stylesheet">
|
||||
<link href="{{ app['combodo.absolute_url'] ~ 'css/font-awesome/css/v4-shims.min.css'|add_itop_version }}" rel="stylesheet">
|
||||
{# - Misc libs #}
|
||||
<link href="{{ app['combodo.portal.base.absolute_url'] ~ 'lib/typeahead/css/typeaheadjs.bootstrap.css'|add_itop_version }}" rel="stylesheet">
|
||||
<link href="{{ app['combodo.absolute_url'] ~ 'css/selectize.default.css'|add_itop_version }}" rel="stylesheet">
|
||||
|
||||
@@ -240,18 +240,7 @@
|
||||
</items>
|
||||
</list>
|
||||
</presentation>
|
||||
<methods>
|
||||
<method id="GetRelationQueries">
|
||||
<comment>/**
|
||||
* Placeholder for backward compatibility (iTop <= 2.1.0)
|
||||
* in case an extension attempts to redefine this function...
|
||||
*/</comment>
|
||||
<static>true</static>
|
||||
<access>public</access>
|
||||
<type>Overload-DBObject</type>
|
||||
<code><![CDATA[ public static function GetRelationQueries($sRelCode){return parent::GetRelationQueries($sRelCode);} ]]></code>
|
||||
</method>
|
||||
</methods>
|
||||
<methods/>
|
||||
<relations>
|
||||
<relation id="impacts">
|
||||
<neighbours>
|
||||
@@ -498,18 +487,7 @@
|
||||
</items>
|
||||
</list>
|
||||
</presentation>
|
||||
<methods>
|
||||
<method id="GetRelationQueries">
|
||||
<comment>/**
|
||||
* Placeholder for backward compatibility (iTop <= 2.1.0)
|
||||
* in case an extension attempts to redefine this function...
|
||||
*/</comment>
|
||||
<static>true</static>
|
||||
<access>public</access>
|
||||
<type>Overload-DBObject</type>
|
||||
<code><![CDATA[ public static function GetRelationQueries($sRelCode){return parent::GetRelationQueries($sRelCode);} ]]></code>
|
||||
</method>
|
||||
</methods>
|
||||
<methods/>
|
||||
<relations>
|
||||
<relation id="impacts">
|
||||
<neighbours>
|
||||
@@ -756,18 +734,7 @@
|
||||
</items>
|
||||
</list>
|
||||
</presentation>
|
||||
<methods>
|
||||
<method id="GetRelationQueries">
|
||||
<comment>/**
|
||||
* Placeholder for backward compatibility (iTop <= 2.1.0)
|
||||
* in case an extension attempts to redefine this function...
|
||||
*/</comment>
|
||||
<static>true</static>
|
||||
<access>public</access>
|
||||
<type>Overload-DBObject</type>
|
||||
<code><![CDATA[ public static function GetRelationQueries($sRelCode){return parent::GetRelationQueries($sRelCode);} ]]></code>
|
||||
</method>
|
||||
</methods>
|
||||
<methods/>
|
||||
<relations>
|
||||
<relation id="impacts">
|
||||
<neighbours>
|
||||
@@ -1014,18 +981,7 @@
|
||||
</items>
|
||||
</list>
|
||||
</presentation>
|
||||
<methods>
|
||||
<method id="GetRelationQueries">
|
||||
<comment>/**
|
||||
* Placeholder for backward compatibility (iTop <= 2.1.0)
|
||||
* in case an extension attempts to redefine this function...
|
||||
*/</comment>
|
||||
<static>true</static>
|
||||
<access>public</access>
|
||||
<type>Overload-DBObject</type>
|
||||
<code><![CDATA[ public static function GetRelationQueries($sRelCode){return parent::GetRelationQueries($sRelCode);} ]]></code>
|
||||
</method>
|
||||
</methods>
|
||||
<methods/>
|
||||
<relations>
|
||||
<relation id="impacts">
|
||||
<neighbours>
|
||||
@@ -1127,18 +1083,7 @@
|
||||
</items>
|
||||
</list>
|
||||
</presentation>
|
||||
<methods>
|
||||
<method id="GetRelationQueries">
|
||||
<comment>/**
|
||||
* Placeholder for backward compatibility (iTop <= 2.1.0)
|
||||
* in case an extension attempts to redefine this function...
|
||||
*/</comment>
|
||||
<static>true</static>
|
||||
<access>public</access>
|
||||
<type>Overload-DBObject</type>
|
||||
<code><![CDATA[ public static function GetRelationQueries($sRelCode){return parent::GetRelationQueries($sRelCode);} ]]></code>
|
||||
</method>
|
||||
</methods>
|
||||
<methods/>
|
||||
</class>
|
||||
<class id="NASFileSystem" _delta="define">
|
||||
<parent>cmdbAbstractObject</parent>
|
||||
@@ -1245,18 +1190,7 @@
|
||||
</items>
|
||||
</list>
|
||||
</presentation>
|
||||
<methods>
|
||||
<method id="GetRelationQueries">
|
||||
<comment>/**
|
||||
* Placeholder for backward compatibility (iTop <= 2.1.0)
|
||||
* in case an extension attempts to redefine this function...
|
||||
*/</comment>
|
||||
<static>true</static>
|
||||
<access>public</access>
|
||||
<type>Overload-DBObject</type>
|
||||
<code><![CDATA[ public static function GetRelationQueries($sRelCode){return parent::GetRelationQueries($sRelCode);} ]]></code>
|
||||
</method>
|
||||
</methods>
|
||||
<methods/>
|
||||
</class>
|
||||
<class id="FiberChannelInterface" _delta="define">
|
||||
<parent>NetworkInterface</parent>
|
||||
@@ -1511,18 +1445,7 @@
|
||||
</items>
|
||||
</list>
|
||||
</presentation>
|
||||
<methods>
|
||||
<method id="GetRelationQueries">
|
||||
<comment>/**
|
||||
* Placeholder for backward compatibility (iTop <= 2.1.0)
|
||||
* in case an extension attempts to redefine this function...
|
||||
*/</comment>
|
||||
<static>true</static>
|
||||
<access>public</access>
|
||||
<type>Overload-DBObject</type>
|
||||
<code><![CDATA[ public static function GetRelationQueries($sRelCode){return parent::GetRelationQueries($sRelCode);} ]]></code>
|
||||
</method>
|
||||
</methods>
|
||||
<methods/>
|
||||
<relations>
|
||||
<relation id="impacts">
|
||||
<neighbours>
|
||||
|
||||
@@ -235,18 +235,7 @@
|
||||
</items>
|
||||
</list>
|
||||
</presentation>
|
||||
<methods>
|
||||
<method id="GetRelationQueries">
|
||||
<comment>/**
|
||||
* Placeholder for backward compatibility (iTop <= 2.1.0)
|
||||
* in case an extension attempts to redefine this function...
|
||||
*/</comment>
|
||||
<static>true</static>
|
||||
<access>public</access>
|
||||
<type>Overload-DBObject</type>
|
||||
<code><![CDATA[ public static function GetRelationQueries($sRelCode){return parent::GetRelationQueries($sRelCode);} ]]></code>
|
||||
</method>
|
||||
</methods>
|
||||
<methods/>
|
||||
<relations>
|
||||
<relation id="impacts">
|
||||
<neighbours>
|
||||
@@ -394,18 +383,7 @@
|
||||
</items>
|
||||
</list>
|
||||
</presentation>
|
||||
<methods>
|
||||
<method id="GetRelationQueries">
|
||||
<comment>/**
|
||||
* Placeholder for backward compatibility (iTop <= 2.1.0)
|
||||
* in case an extension attempts to redefine this function...
|
||||
*/</comment>
|
||||
<static>true</static>
|
||||
<access>public</access>
|
||||
<type>Overload-DBObject</type>
|
||||
<code><![CDATA[ public static function GetRelationQueries($sRelCode){return parent::GetRelationQueries($sRelCode);} ]]></code>
|
||||
</method>
|
||||
</methods>
|
||||
<methods/>
|
||||
<relations>
|
||||
<relation id="impacts">
|
||||
<neighbours>
|
||||
@@ -540,18 +518,7 @@
|
||||
</items>
|
||||
</list>
|
||||
</presentation>
|
||||
<methods>
|
||||
<method id="GetRelationQueries">
|
||||
<comment>/**
|
||||
* Placeholder for backward compatibility (iTop <= 2.1.0)
|
||||
* in case an extension attempts to redefine this function...
|
||||
*/</comment>
|
||||
<static>true</static>
|
||||
<access>public</access>
|
||||
<type>Overload-DBObject</type>
|
||||
<code><![CDATA[ public static function GetRelationQueries($sRelCode){return parent::GetRelationQueries($sRelCode);} ]]></code>
|
||||
</method>
|
||||
</methods>
|
||||
<methods/>
|
||||
</class>
|
||||
<class id="VirtualMachine" _delta="define">
|
||||
<parent>VirtualDevice</parent>
|
||||
@@ -783,18 +750,7 @@
|
||||
</items>
|
||||
</list>
|
||||
</presentation>
|
||||
<methods>
|
||||
<method id="GetRelationQueries">
|
||||
<comment>/**
|
||||
* Placeholder for backward compatibility (iTop <= 2.1.0)
|
||||
* in case an extension attempts to redefine this function...
|
||||
*/</comment>
|
||||
<static>true</static>
|
||||
<access>public</access>
|
||||
<type>Overload-DBObject</type>
|
||||
<code><![CDATA[ public static function GetRelationQueries($sRelCode){return parent::GetRelationQueries($sRelCode);} ]]></code>
|
||||
</method>
|
||||
</methods>
|
||||
<methods/>
|
||||
</class>
|
||||
<class id="LogicalInterface" _delta="define">
|
||||
<parent>IPInterface</parent>
|
||||
|
||||
@@ -820,9 +820,9 @@ Dict::Add('NL NL', 'Dutch', 'Nederlands', array(
|
||||
'Class:SynchroAttribute/Attribute:update' => 'Update',
|
||||
'Class:SynchroAttribute/Attribute:reconcile' => 'Reconcile',
|
||||
'Class:SynchroAttribute/Attribute:update_policy' => 'Update Policy',
|
||||
'Class:SynchroAttribute/Attribute:update_policy/Value:master_locked' => 'Gesloten',
|
||||
'Class:SynchroAttribute/Attribute:update_policy/Value:master_unlocked' => 'Open',
|
||||
'Class:SynchroAttribute/Attribute:update_policy/Value:write_if_empty' => 'Begin indien leeg',
|
||||
'Class:SynchroAttribute/Attribute:update_policy/Value:master_locked' => 'Geblokkeerd',
|
||||
'Class:SynchroAttribute/Attribute:update_policy/Value:master_unlocked' => 'Vrij',
|
||||
'Class:SynchroAttribute/Attribute:update_policy/Value:write_if_empty' => 'Vul in indien leeg',
|
||||
'Class:SynchroAttribute/Attribute:finalclass' => 'Klasse',
|
||||
'Class:SynchroAttExtKey' => 'Synchro Attribuut (ExtKey)',
|
||||
'Class:SynchroAttExtKey/Attribute:reconciliation_attcode' => 'Reconciliation-attribuut',
|
||||
|
||||
@@ -408,7 +408,7 @@ $(function()
|
||||
var oFilterElem = $('<div></div>')
|
||||
.addClass('sf_filter')
|
||||
.addClass('sfm_filter')
|
||||
.append('<span class="sff_input_wrapper"><input type="text" placeholder="' + Dict.S('UI:Search:Value:Filter:Placeholder') + '" /><span class="sff_picto sff_filter fas fa-filter"></span><span class="sff_picto sff_reset fa fa-times"></span></span>')
|
||||
.append('<span class="sff_input_wrapper"><input type="text" placeholder="' + Dict.S('UI:Search:Value:Filter:Placeholder') + '" /><span class="sff_picto sff_filter fas fa-filter"></span><span class="sff_picto sff_reset fas fa-times"></span></span>')
|
||||
.appendTo(oContentElem);
|
||||
|
||||
// - Lists container
|
||||
|
||||
30
readme.txt
30
readme.txt
@@ -4,6 +4,7 @@ iTop stands for *IT Operations Portal*.
|
||||
It is a complete open source, ITIL, web based service management tool including a fully customizable CMDB, a helpdesk system and a document management tool.
|
||||
iTop also offers mass import tools and web services to integrate with your IT
|
||||
|
||||
|
||||
## Features
|
||||
- Fully configurable **CMDB**
|
||||
- **HelpDesk** and Incident Management
|
||||
@@ -17,34 +18,21 @@ iTop also offers mass import tools and web services to integrate with your IT
|
||||
- **Data synchronization** (for data federation)
|
||||
|
||||
|
||||
## Resources
|
||||
## Latest release
|
||||
- [Changes since the previous version](https://wiki.openitop.org/doku.php?id=latest:release:change_log)
|
||||
- [New features](https://wiki.openitop.org/doku.php?id=latest:release:start)
|
||||
- [Migration notes](https://wiki.openitop.org/doku.php?id=latest:install:start)
|
||||
- [Download](https://sourceforge.net/projects/itop/files/latest/download)
|
||||
|
||||
|
||||
## Resources
|
||||
- [iTop Forums](https://sourceforge.net/p/itop/discussion/): for support request
|
||||
- [iTop Tickets](https://sourceforge.net/p/itop/tickets/): for feature requests and bug reports
|
||||
- [Releases download](https://sourceforge.net/projects/itop/files/itop/)
|
||||
- [Software requirements](https://wiki.openitop.org/doku.php?id=latest:install:upgrading_itop)
|
||||
- [iTop documentation](https://www.itophub.io/wiki/page) for iTop and official extensions
|
||||
- [iTop extensions](https://store.itophub.io/en_US/) for discovering ans installing extensions
|
||||
|
||||
|
||||
## Releases
|
||||
### Version 2.7
|
||||
- [Changes since the previous version](https://wiki.openitop.org/doku.php?id=2_7_0:release:change_log)
|
||||
- [New features](https://wiki.openitop.org/doku.php?id=2_7_0:release:2_7_whats_new)
|
||||
- [Migration notes](https://wiki.openitop.org/doku.php?id=2_7_0:install:260_to_270_migration_notes)
|
||||
|
||||
### Version 2.6
|
||||
- [Changes since the previous version](https://wiki.openitop.org/doku.php?id=2_6_0:release:change_log)
|
||||
- [New features](https://wiki.openitop.org/doku.php?id=2_6_0:release:2_6_whats_new)
|
||||
- [Migration notes](https://wiki.openitop.org/doku.php?id=2_6_0:install:250_to_260_migration_notes)
|
||||
|
||||
|
||||
### Version 2.5
|
||||
- [Changes since the previous version](https://wiki.openitop.org/doku.php?id=2_5_0:release:change_log)
|
||||
- [New features](https://wiki.openitop.org/doku.php?id=2_5_0:release:2_5_whats_new)
|
||||
- [Migration notes](https://wiki.openitop.org/doku.php?id=2_5_0:install:240_to_250_migration_notes)
|
||||
|
||||
|
||||
### Version 2.4
|
||||
- [Changes since the previous version](https://wiki.openitop.org/doku.php?id=2_4_0:release:change_log)
|
||||
- [New features](https://wiki.openitop.org/doku.php?id=2_4_0:release:2_4_whats_new)
|
||||
- [Migration notes](https://wiki.openitop.org/doku.php?id=2_4_0:install:230_to_240_migration_notes)
|
||||
|
||||
@@ -277,7 +277,6 @@ class iTopExtensionsMap
|
||||
$oExtension->sVersion = $oXml->Get('version');
|
||||
$oExtension->bMandatory = ($oXml->Get('mandatory') == 'true');
|
||||
$oExtension->sMoreInfoUrl = $oXml->Get('more_info_url');
|
||||
$oExtension->sVersion = $oXml->Get('version');
|
||||
$oExtension->sSource = $sSource;
|
||||
$oExtension->sSourceDir = $sSearchDir;
|
||||
|
||||
|
||||
@@ -39,6 +39,50 @@ class CheckResult
|
||||
$this->sLabel = $sLabel;
|
||||
$this->sDescription = $sDescription;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
* @since 2.8.0 N°2214
|
||||
*/
|
||||
public function __toString()
|
||||
{
|
||||
$sPrintDesc = (empty($this->sDescription)) ? '' : " ({$this->sDescription})";
|
||||
return "{$this->sLabel}$sPrintDesc";
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \CheckResult[] $aResults
|
||||
*
|
||||
* @return \CheckResult[] only elements that are error (iSeverity===ERROR)
|
||||
*
|
||||
* @since 2.8.0 N°2214
|
||||
*/
|
||||
public static function KeepOnlyErrors($aResults)
|
||||
{
|
||||
return array_filter($aResults,
|
||||
static function ($v)
|
||||
{
|
||||
if ($v->iSeverity === CheckResult::ERROR) {
|
||||
return $v;
|
||||
}
|
||||
},
|
||||
ARRAY_FILTER_USE_BOTH);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \CheckResult[] $aResults
|
||||
*
|
||||
* @return string[]
|
||||
* @uses \CheckResult::__toString
|
||||
*
|
||||
* @since 2.8.0 N°2214
|
||||
*/
|
||||
public static function FromObjectsToStrings($aResults)
|
||||
{
|
||||
return array_map(function ($value) {
|
||||
return $value->__toString();
|
||||
}, $aResults);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -50,15 +94,15 @@ class CheckResult
|
||||
class SetupUtils
|
||||
{
|
||||
// -- Minimum versions (requirements : forbids installation if not met)
|
||||
const PHP_MIN_VERSION = '5.6.0'; // 5.6 will be supported until the end of 2018 (see http://php.net/supported-versions.php)
|
||||
const PHP_MIN_VERSION = '7.1.3'; // 7 will be supported until the end of 2019 (see http://php.net/supported-versions.php)
|
||||
const MYSQL_MIN_VERSION = '5.6.0'; // 5.6 to have fulltext on InnoDB for Tags fields (N°931)
|
||||
const MYSQL_NOT_VALIDATED_VERSION = ''; // MySQL 8 is now OK (N°2010 in 2.7.0) but has no query cache so mind the perf on large volumes !
|
||||
|
||||
// -- versions that will be the minimum in next iTop major release (warning if not met)
|
||||
const PHP_NEXT_MIN_VERSION = '7.1.3'; // we are aiming on switching to Symfony 4 in iTop 2.8
|
||||
const PHP_NEXT_MIN_VERSION = ''; //
|
||||
const MYSQL_NEXT_MIN_VERSION = ''; // no new MySQL requirement for next iTop version
|
||||
// -- First recent version that is not yet validated by Combodo (warning)
|
||||
const PHP_NOT_VALIDATED_VERSION = '7.5.0';
|
||||
const PHP_NOT_VALIDATED_VERSION = '8.0.0';
|
||||
|
||||
const MIN_MEMORY_LIMIT = 33554432; // 32 * 1024 * 1024 - we can use expressions in const since PHP 5.6 but we are in the setup !
|
||||
const SUHOSIN_GET_MAX_VALUE_LENGTH = 2048;
|
||||
@@ -370,6 +414,37 @@ class SetupUtils
|
||||
return $aResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \CLIPage $oCliPage
|
||||
* @param int $iExitCode
|
||||
*
|
||||
* @since 2.8.0 N°2214
|
||||
*/
|
||||
public static function CheckPhpAndExtensionsForCli($oCliPage, $iExitCode = -1)
|
||||
{
|
||||
$aPhpCheckResults = self::CheckPhpAndExtensions();
|
||||
$aPhpCheckErrors = CheckResult::KeepOnlyErrors($aPhpCheckResults);
|
||||
if (empty($aPhpCheckErrors))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
$sMessageTitle = 'Error: PHP minimum requirements are not met !';
|
||||
$oCliPage->p($sMessageTitle);
|
||||
$aPhpCheckErrorsForPrint = CheckResult::FromObjectsToStrings($aPhpCheckErrors);
|
||||
foreach ($aPhpCheckErrorsForPrint as $sError)
|
||||
{
|
||||
$oCliPage->p(' * '.$sError);
|
||||
}
|
||||
$oCliPage->output();
|
||||
|
||||
// some CLI scripts are launched automatically
|
||||
// we need a log so that we don't miss errors after migration !
|
||||
IssueLog::Error($oCliPage->s_title.' '.$sMessageTitle, 'CLI', $aPhpCheckErrorsForPrint);
|
||||
|
||||
exit($iExitCode);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param CheckResult[] $aResult checks log
|
||||
*/
|
||||
|
||||
@@ -411,7 +411,7 @@ class CriterionToOQL extends CriterionConversionAbstract
|
||||
// Use the 'below' operator by default
|
||||
$oSearch->AddCondition_PointingTo($oHKFilter, $sAttCode);
|
||||
$oCriteria = $oSearch->GetCriteria();
|
||||
$aArgs = MetaModel::PrepareQueryArguments(array(), $oSearch->GetInternalParams());
|
||||
$aArgs = MetaModel::PrepareQueryArguments(array(), $oSearch->GetInternalParams(), $oSearch->GetExpectedArguments() );
|
||||
$oSearch->ResetCondition();
|
||||
$sCondition = $oCriteria->Render($aArgs);
|
||||
}
|
||||
|
||||
@@ -530,7 +530,7 @@ class SearchForm
|
||||
{
|
||||
$aOrCriterion = array();
|
||||
$bIsEmptyExpression = true;
|
||||
$aArgs = MetaModel::PrepareQueryArguments($aArgs, $oSearch->GetInternalParams());
|
||||
$aArgs = MetaModel::PrepareQueryArguments($aArgs, $oSearch->GetInternalParams(), $oSearch->GetExpectedArguments());
|
||||
|
||||
if ($oSearch instanceof DBObjectSearch)
|
||||
{
|
||||
|
||||
@@ -72,6 +72,7 @@ function ReadMandatoryParam($oP, $sParam, $sSanitizationFilter = 'parameter')
|
||||
if (utils::IsModeCLI())
|
||||
{
|
||||
$oP = new CLIPage(Dict::S("TitleSynchroExecution"));
|
||||
SetupUtils::CheckPhpAndExtensionsForCli($oP, -2);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -255,6 +255,7 @@ class CLILikeWebPage extends WebPage
|
||||
if (utils::IsModeCLI())
|
||||
{
|
||||
$oP = new CLIPage(Dict::S('TitleSynchroExecution'));
|
||||
SetupUtils::CheckPhpAndExtensionsForCli($oP, -2);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -277,5 +277,42 @@ class HTMLDOMSanitizerTest extends ItopTestCase
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider CallInlineImageProcessImageTagProvider
|
||||
*/
|
||||
public function testDoSanitizeCallInlineImageProcessImageTag($sHtml, $iExpectedCount)
|
||||
{
|
||||
require_once APPROOT.'test/core/sanitizer/InlineImageMock.php';
|
||||
|
||||
$oSanitizer = new HTMLDOMSanitizer();
|
||||
$oSanitizer->DoSanitize($sHtml);
|
||||
|
||||
$iCalledCount = \InlineImage::GetCallCounter();
|
||||
$this->assertEquals($iExpectedCount, $iCalledCount);
|
||||
}
|
||||
|
||||
public function CallInlineImageProcessImageTagProvider()
|
||||
{
|
||||
return array(
|
||||
'no image' => array(
|
||||
'html' => '<p>bar</p>',
|
||||
'expected' => 0,
|
||||
),
|
||||
'basic image' => array(
|
||||
'html' => '<img />',
|
||||
'expected' => 1,
|
||||
),
|
||||
'nested images within forbidden tags' => array(
|
||||
'html' => '<html><body><img /><iframe baz="1"><div baz="baz"><article baz="1" biz="2">baz<img /><img /></article>rab</div> oof<img /></iframe><img /></body></html>',
|
||||
'expected' => 2,
|
||||
),
|
||||
// This test will be restored with the ticket n°2556
|
||||
// 'nested images within forbidden and removed tags' => array(
|
||||
// 'html' => '<html><body><img /><iframe baz="1"><div baz="baz"><object baz="1" biz="2">baz<img /><img /></object>rab</div> oof<img /></iframe><img /></body></html>',
|
||||
// 'expected' => 2,
|
||||
// ),
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
39
test/core/sanitizer/InlineImageMock.php
Normal file
39
test/core/sanitizer/InlineImageMock.php
Normal file
@@ -0,0 +1,39 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright (C) 2010-2020 Combodo SARL
|
||||
*
|
||||
* This file is part of iTop.
|
||||
*
|
||||
* iTop is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* iTop is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with iTop. If not, see <http: *www.gnu.org/licenses/>
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* Mock class used by @see \Combodo\iTop\Test\UnitTest\Core\HTMLDOMSanitizerTest
|
||||
*
|
||||
*/
|
||||
class InlineImage
|
||||
{
|
||||
private static $iCallCounter = 0;
|
||||
|
||||
public static function ProcessImageTag(DOMNode $oNode)
|
||||
{
|
||||
self::$iCallCounter++;
|
||||
}
|
||||
|
||||
public static function GetCallCounter()
|
||||
{
|
||||
return self::$iCallCounter;
|
||||
}
|
||||
}
|
||||
@@ -485,7 +485,7 @@ class TestMyBizModel extends TestBizModel
|
||||
echo "Max depth = $iMaxDepth</br>\n";
|
||||
|
||||
$oObj = MetaModel::GetObject("cmdbContact", 18);
|
||||
$aRels = $oObj->GetRelatedObjects("Potes", $iMaxDepth);
|
||||
$aRels = $oObj->GetRelatedObjectsDown("Potes", $iMaxDepth);
|
||||
echo $oObj->Get('name')." has some 'Potes'...</br>\n";
|
||||
foreach ($aRels as $sClass => $aObjs)
|
||||
{
|
||||
@@ -581,391 +581,6 @@ class TestMyBizModel extends TestBizModel
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Test a complex biz model on the fly
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
abstract class MyFarm extends TestBizModel
|
||||
{
|
||||
static public function GetConfigFile() {return '/config-test-farm.php';}
|
||||
|
||||
protected function DoPrepare()
|
||||
{
|
||||
parent::DoPrepare();
|
||||
$this->ResetDB();
|
||||
MetaModel::DBCheckIntegrity();
|
||||
}
|
||||
|
||||
protected function InsertMammal($sSpecies, $sSex, $iSpeed, $iMotherid, $iFatherId, $sName, $iHeight, $sBirth)
|
||||
{
|
||||
$oNew = MetaModel::NewObject('Mammal');
|
||||
$oNew->Set('species', $sSpecies);
|
||||
$oNew->Set('sex', $sSex);
|
||||
$oNew->Set('speed', $iSpeed);
|
||||
$oNew->Set('mother', $iMotherid);
|
||||
$oNew->Set('father', $iFatherId);
|
||||
$oNew->Set('name', $sName);
|
||||
$oNew->Set('height', $iHeight);
|
||||
$oNew->Set('birth', $sBirth);
|
||||
return $this->ObjectToDB($oNew);
|
||||
}
|
||||
|
||||
protected function InsertBird($sSpecies, $sSex, $iSpeed, $iMotherid, $iFatherId)
|
||||
{
|
||||
$oNew = MetaModel::NewObject('Bird');
|
||||
$oNew->Set('species', $sSpecies);
|
||||
$oNew->Set('sex', $sSex);
|
||||
$oNew->Set('speed', $iSpeed);
|
||||
$oNew->Set('mother', $iMotherid);
|
||||
$oNew->Set('father', $iFatherId);
|
||||
return $this->ObjectToDB($oNew);
|
||||
}
|
||||
|
||||
protected function InsertFlyingBird($sSpecies, $sSex, $iSpeed, $iMotherid, $iFatherId, $iFlyingSpeed)
|
||||
{
|
||||
$oNew = MetaModel::NewObject('FlyingBird');
|
||||
$oNew->Set('species', $sSpecies);
|
||||
$oNew->Set('sex', $sSex);
|
||||
$oNew->Set('speed', $iSpeed);
|
||||
$oNew->Set('mother', $iMotherid);
|
||||
$oNew->Set('father', $iFatherId);
|
||||
$oNew->Set('flyingspeed', $iFlyingSpeed);
|
||||
return $this->ObjectToDB($oNew);
|
||||
}
|
||||
|
||||
private function InsertGroup($sName, $iLeaderId)
|
||||
{
|
||||
$oNew = MetaModel::NewObject('Group');
|
||||
$oNew->Set('name', $sName);
|
||||
$oNew->Set('leader', $iLeaderId);
|
||||
$iId = $oNew->DBInsertNoReload();
|
||||
return $iId;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class TestQueriesOnFarm extends MyFarm
|
||||
{
|
||||
static public function GetName()
|
||||
{
|
||||
return 'Farm test';
|
||||
}
|
||||
|
||||
static public function GetDescription()
|
||||
{
|
||||
return 'A series of tests on the farm business model (SQL generation)';
|
||||
}
|
||||
|
||||
protected function CheckQuery($sQuery, $bIsCorrectQuery)
|
||||
{
|
||||
if ($bIsCorrectQuery)
|
||||
{
|
||||
echo "<h4 style=\"color:green;\">$sQuery</h4>\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
echo "<h4 style=\"color:red;\">$sQuery</h3>\n";
|
||||
}
|
||||
try
|
||||
{
|
||||
//$oOql = new OqlInterpreter($sQuery);
|
||||
//$oTrash = $oOql->ParseQuery();
|
||||
//self::DumpVariable($oTrash, true);
|
||||
$oMyFilter = DBObjectSearch::FromOQL($sQuery);
|
||||
}
|
||||
catch (OQLException $oOqlException)
|
||||
{
|
||||
if ($bIsCorrectQuery)
|
||||
{
|
||||
echo "<p>More info on this unexpected failure:<br/>".$oOqlException->getHtmlDesc()."</p>\n";
|
||||
throw $oOqlException;
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Everything is fine :-)
|
||||
echo "<p>More info on this expected failure:\n";
|
||||
echo "<ul>\n";
|
||||
echo "<li>".get_class($oOqlException)."</li>\n";
|
||||
echo "<li>".$oOqlException->getMessage()."</li>\n";
|
||||
echo "<li>".$oOqlException->getHtmlDesc()."</li>\n";
|
||||
echo "</ul>\n";
|
||||
echo "</p>\n";
|
||||
return true;
|
||||
}
|
||||
}
|
||||
// The query was correctly parsed, was it expected to be correct ?
|
||||
if (!$bIsCorrectQuery)
|
||||
{
|
||||
throw new UnitTestException("The query '$sQuery' was parsed with success, while it shouldn't (?)");
|
||||
return false;
|
||||
}
|
||||
echo "<p>To OQL: ".$oMyFilter->ToOQL()."</p>";
|
||||
|
||||
$this->search_and_show_list($oMyFilter);
|
||||
|
||||
//echo "<p>first pass<p>\n";
|
||||
//self::DumpVariable($oMyFilter, true);
|
||||
$sQuery1 = $oMyFilter->MakeSelectQuery();
|
||||
//echo "<p>second pass<p>\n";
|
||||
//self::DumpVariable($oMyFilter, true);
|
||||
//$sQuery1 = $oMyFilter->MakeSelectQuery();
|
||||
|
||||
$sSerialize = $oMyFilter->serialize();
|
||||
echo "<p>Serialized:$sSerialize</p>\n";
|
||||
$oFilter2 = DBObjectSearch::unserialize($sSerialize);
|
||||
try
|
||||
{
|
||||
$sQuery2 = $oFilter2->MakeSelectQuery();
|
||||
}
|
||||
catch (Exception $e)
|
||||
{
|
||||
echo "<p>Could not compute the query after unserialize</p>\n";
|
||||
echo "<p>Query 1: $sQuery1</p>\n";
|
||||
MyHelpers::var_cmp_html($oMyFilter, $oFilter2);
|
||||
throw $e;
|
||||
}
|
||||
//if ($oFilter2 != $oMyFilter) no, they may differ while the resulting query is the same!
|
||||
if ($sQuery1 != $sQuery2)
|
||||
{
|
||||
echo "<p>serialize/unserialize mismatch :-(</p>\n";
|
||||
MyHelpers::var_cmp_html($sQuery1, $sQuery2);
|
||||
MyHelpers::var_cmp_html($oMyFilter, $oFilter2);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
protected function DoExecute()
|
||||
{
|
||||
// $this->ReportError("Found two different OQL expression out of the (same?) filter: <em>$sExpr1</em> != <em>$sExpr2</em>");
|
||||
// $this->ReportSuccess('Found '.$oSet->Count()." objects of class $sClassName");
|
||||
echo "<h3>Create protagonists...</h3>";
|
||||
|
||||
$iId1 = $this->InsertMammal('human', 'male', 10, 0, 0, 'romanoff', 192, '1971-07-19');
|
||||
$iId2 = $this->InsertMammal('human', 'female', 9, 0, 0, 'rouanita', 165, '1983-01-23');
|
||||
$this->InsertMammal('human', 'female', 3, $iId2, $iId1, 'pomme', 169, '2008-02-23');
|
||||
$this->InsertMammal('pig', 'female', 3, 0, 0, 'grouinkette', 85, '2006-06-01');
|
||||
$this->InsertMammal('donkey', 'female', 3, 0, 0, 'muleta', 124, '2003-11-11');
|
||||
|
||||
$this->InsertBird('rooster', 'male', 12, 0, 0);
|
||||
$this->InsertFlyingBird('pie', 'female', 11, 0, 0, 35);
|
||||
|
||||
// Benchmarking
|
||||
//
|
||||
if (false)
|
||||
{
|
||||
define ('COUNT_BENCHMARK', 10);
|
||||
echo "<h3>Parsing a long query, ".COUNT_BENCHMARK." times</h3>";
|
||||
$sQuery = "SELECT Animal AS Child JOIN Mammal AS Dad ON Child.father = Dad.id JOIN Animal AS Mum ON Child.mother = Mum.id WHERE Dad.birth < DATE_SUB(CURRENT_DATE(), INTERVAL 10 YEAR) AND Dad.height * 2 <= ROUND(TO_DAYS(Dad.birth) / (3 + 1) * 5 - 3)";
|
||||
|
||||
$fStart = MyHelpers::getmicrotime();
|
||||
for($i=0 ; $i < COUNT_BENCHMARK ; $i++)
|
||||
{
|
||||
$oMyFilter = DBObjectSearch::FromOQL($sQuery);
|
||||
}
|
||||
$fDuration = MyHelpers::getmicrotime() - $fStart;
|
||||
$fParsingDuration = $fDuration / COUNT_BENCHMARK;
|
||||
echo "<p>Mean time by op: $fParsingDuration</p>";
|
||||
}
|
||||
|
||||
echo "<h3>Test queries...</h3>";
|
||||
|
||||
$aQueries = array(
|
||||
'SELECT Animal' => true,
|
||||
'SELECT Animal WHERE Animal.pkey = 1' => false,
|
||||
'SELECT Animal WHERE Animal.id = 1' => true,
|
||||
'SELECT Aniiimal' => false,
|
||||
'SELECTe Animal' => false,
|
||||
'SELECT * FROM Animal' => false,
|
||||
'SELECT Animal AS zoo WHERE zoo.species = \'human\'' => true,
|
||||
'SELECT Animal AS zoo WHERE species = \'human\'' => true,
|
||||
'SELECT Animal AS zoo WHERE espece = \'human\'' => false,
|
||||
'SELECT Animal AS zoo WHERE zoo.species IN (\'human\', "pig")' => true,
|
||||
'SELECT Animal AS zoo WHERE CONCATENATION(zoo.species, zoo.sex) LIKE "hum%male"' => false,
|
||||
'SELECT Animal AS zoo WHERE CONCAT(zoo.species, zoo.sex) LIKE "hum%male"' => true,
|
||||
'SELECT Animal AS zoo WHERE zoo.species NOT IN (\'human\', "pig")' => true,
|
||||
'SELECT Animal AS zoo WHERE zoo.kind = \'human\'' => false,
|
||||
'SELECT Animal WHERE Animal.species = \'human\' AND Animal.sex = \'female\'' => true,
|
||||
'SELECT Mammal AS x WHERE (x.species = \'human\' AND x.name LIKE \'ro%\') OR (x.species = \'donkey\' AND x.name LIKE \'po%\')' => true,
|
||||
'SELECT Mammal AS x WHERE x.species = \'human\' AND x.name LIKE \'ro%\' OR x.species = \'donkey\' AND x.name LIKE \'po%\'' => true,
|
||||
'SELECT Mammal AS m WHERE MONTH(m.birth) = 7' => true,
|
||||
'SELECT Mammal AS m WHERE DAY(m.birth) = 19' => true,
|
||||
'SELECT Mammal AS m WHERE YEAR(m.birth) = 1971' => true,
|
||||
'SELECT Mammal AS m WHERE m.birth < DATE_SUB(CURRENT_DATE(), INTERVAL 10 YEAR)' => true,
|
||||
'SELECT Mammal AS m WHERE m.birth > DATE_SUB(NOW(), INTERVAL 2000 DAY)' => true,
|
||||
'SELECT Mammal AS m WHERE (TO_DAYS(NOW()) - TO_DAYS(m.birth)) > 2000' => true,
|
||||
'SELECT Mammal AS m WHERE m.name = IF(FLOOR(ROUND(m.height)) > 2, "pomme", "romain")' => true,
|
||||
'SELECT Mammal AS m WHERE (1 + 2' => false,
|
||||
'SELECT Mammal AS m WHERE (1 + 2 * 4 / 23) > 0' => true,
|
||||
'SELECT Mammal AS m WHERE (4 / 23 * 2 + 1) > 0' => true,
|
||||
'SELECT Mammal AS m WHERE 1/0' => true,
|
||||
'SELECT Mammal AS m WHERE MONTH(m.birth) = 7' => true,
|
||||
'SELECT Animal JOIN Group ON Group.leader = Animal.id' => true,
|
||||
'SELECT Group JOIN Animal ON Group.leader = Animal.id' => true,
|
||||
'SELECT Animal AS A JOIN Group AS G1 ON G1.leader = A.id' => true,
|
||||
'SELECT Animal AS A JOIN Group AS G ON FooClass.leader = A.id' => false,
|
||||
'SELECT Animal AS A JOIN Group AS G ON G.leader = FooClass.id' => false,
|
||||
'SELECT Animal AS A JOIN Group AS G ON G.masterchief = A.id' => false,
|
||||
'SELECT Animal AS A JOIN Group AS G ON A.id = G.leader' => false,
|
||||
'SELECT Animal AS A JOIN Group AS G ON G.leader = A.id WHERE A.sex=\'male\' OR G.qwerty = 123' => false,
|
||||
'SELECT Animal AS A JOIN Group AS G ON G.leader = A.id WHERE A.sex=\'male\' OR G.name LIKE "a%"' => true,
|
||||
'SELECT Animal AS A JOIN Group AS G ON G.leader = A.id WHERE A.id = 1' => true,
|
||||
'SELECT Animal AS A JOIN Group AS G ON G.leader = A.id WHERE id = 1' => false,
|
||||
'SELECT Animal AS A JOIN Group AS G ON A.member = G.id' => false,
|
||||
'SELECT Mammal AS M JOIN Group AS G ON M.member = G.id' => true,
|
||||
'SELECT Mammal AS M JOIN Group AS G ON A.member = G.id' => false,
|
||||
'SELECT Mammal AS myAlias JOIN Group AS myAlias ON myAlias.member = myAlias.id' => false,
|
||||
'SELECT Mammal AS Mammal JOIN Group AS Mammal ON Mammal.member = Mammal.id' => false,
|
||||
'SELECT Group AS G WHERE G.leader_name LIKE "%"' => true,
|
||||
'SELECT Group AS G WHERE G.leader_speed < 100000' => true,
|
||||
'SELECT Mammal AS M JOIN Group AS G ON M.member = G.id WHERE G.leader_name LIKE "%"' => true,
|
||||
'SELECT Mammal AS M JOIN Group AS G ON M.member = G.id WHERE G.leader_speed < 100000' => true,
|
||||
'SELECT Mammal AS Child JOIN Mammal AS Dad ON Child.father = Dad.id' => true,
|
||||
'SELECT Mammal AS Child JOIN Animal AS Dad ON Child.father = Dad.id' => true,
|
||||
'SELECT Animal AS Child JOIN Mammal AS Dad ON Child.father = Dad.id' => true,
|
||||
'SELECT Animal AS Child JOIN Animal AS Dad ON Child.father = Dad.id' => true,
|
||||
'SELECT Animal AS Dad JOIN Animal AS Child ON Child.father = Dad.id' => true,
|
||||
'SELECT Animal AS Child JOIN Animal AS Dad ON Child.father = Dad.id JOIN Animal AS Mum ON Child.mother = Mum.id' => true,
|
||||
'SELECT Animal AS Child JOIN Animal AS Dad ON Child.father = Dad.id JOIN Animal AS Mum ON Child.mother = Mum.id WHERE Dad.id = 1' => true,
|
||||
'SELECT Animal AS Child JOIN Animal AS Dad ON Child.father = Dad.id JOIN Animal AS Mum ON Child.mother = Mum.id WHERE Dad.name = \'romanoff\'' => false,
|
||||
'SELECT Animal AS Child JOIN Mammal AS Dad ON Child.father = Dad.id' => true,
|
||||
'SELECT Animal AS Child JOIN Mammal AS Dad ON Child.father = Dad.id JOIN Animal AS Mum ON Child.mother = Mum.id WHERE Dad.name = \'romanoff\' OR Mum.speed = 0' => true,
|
||||
'SELECT Animal AS Dad JOIN Animal AS Child ON Child.father = Dad.id JOIN Animal AS Mum ON Child.mother = Mum.id' => true,
|
||||
'SELECT Mammal AS Dad JOIN Mammal AS Child ON Child.father = Dad.id' => true,
|
||||
'SELECT Mammal AS Dad JOIN Mammal AS Child ON Child.father = Dad.id JOIN Mammal AS Mum ON Child.mother = Mum.id WHERE Dad.name = \'romanoff\' OR Mum.name=\'chloe\' OR Child.name=\'bizounours\'' => true,
|
||||
// Specifying multiple objects
|
||||
'SELECT Animal FROM Animal' => true,
|
||||
'SELECT yelele FROM Animal' => false,
|
||||
'SELECT Animal FROM Animal AS A' => false,
|
||||
'SELECT A FROM Animal AS A' => true,
|
||||
);
|
||||
//$aQueries = array(
|
||||
// 'SELECT Mammal AS M JOIN Group AS G ON M.member = G.id WHERE G.leader_name LIKE "%"' => true,
|
||||
//);
|
||||
foreach($aQueries as $sQuery => $bIsCorrect)
|
||||
{
|
||||
$this->CheckQuery($sQuery, $bIsCorrect);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Test data load
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class TestBulkChangeOnFarm extends TestBizModel
|
||||
{
|
||||
static public function GetName()
|
||||
{
|
||||
return 'Farm test - data load';
|
||||
}
|
||||
|
||||
static public function GetDescription()
|
||||
{
|
||||
return 'Bulk load';
|
||||
}
|
||||
|
||||
static public function GetConfigFile() {return '/config-test-farm.php';}
|
||||
|
||||
protected function DoPrepare()
|
||||
{
|
||||
parent::DoPrepare();
|
||||
$this->ResetDB();
|
||||
MetaModel::DBCheckIntegrity();
|
||||
}
|
||||
|
||||
protected function DoExecute()
|
||||
{
|
||||
// $this->ReportError("Found two different OQL expression out of the (same?) filter: <em>$sExpr1</em> != <em>$sExpr2</em>");
|
||||
// $this->ReportSuccess('Found '.$oSet->Count()." objects of class $sClassName");
|
||||
|
||||
$oParser = new CSVParser("denomination,hauteur,age
|
||||
suzy,123,2009-01-01
|
||||
chita,456,
|
||||
", ',', '"');
|
||||
$aData = $oParser->ToArray(1, array('_name', '_height', '_birth'));
|
||||
self::DumpVariable($aData);
|
||||
|
||||
$oBulk = new BulkChange(
|
||||
'Mammal',
|
||||
$aData,
|
||||
// attributes
|
||||
array('name' => '_name', 'height' => '_height', 'birth' => '_birth'),
|
||||
// ext keys
|
||||
array(),
|
||||
// reconciliation
|
||||
array('name')
|
||||
);
|
||||
|
||||
$oMyChange = MetaModel::NewObject("CMDBChange");
|
||||
$oMyChange->Set("date", time());
|
||||
$oMyChange->Set("userinfo", "Testor");
|
||||
$iChangeId = $oMyChange->DBInsert();
|
||||
// echo "Created new change: $iChangeId</br>";
|
||||
|
||||
echo "<h3>Planned for loading...</h3>";
|
||||
$aRes = $oBulk->Process();
|
||||
self::DumpVariable($aRes);
|
||||
echo "<h3>Go for loading...</h3>";
|
||||
$aRes = $oBulk->Process($oMyChange);
|
||||
self::DumpVariable($aRes);
|
||||
|
||||
return;
|
||||
|
||||
$oRawData = array(
|
||||
'Mammal',
|
||||
array('species', 'sex', 'speed', 'mother', 'father', 'name', 'height', 'birth'),
|
||||
"human,male,23,0,0,romulus,192,1971
|
||||
human,male,23,0,0,remus,154,-50
|
||||
human,male,23,0,0,julius,160,-49
|
||||
human,female,23,0,0,cleopatra,142,-50
|
||||
pig,female,23,0,0,confucius,50,2003"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Test data load
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class TestFullTextSearchOnFarm extends MyFarm
|
||||
{
|
||||
static public function GetName()
|
||||
{
|
||||
return 'Farm test - full text search';
|
||||
}
|
||||
|
||||
static public function GetDescription()
|
||||
{
|
||||
return 'Focus on the full text search feature';
|
||||
}
|
||||
|
||||
protected function DoExecute()
|
||||
{
|
||||
echo "<h3>Create protagonists...</h3>";
|
||||
|
||||
$iId1 = $this->InsertMammal('human', 'male', 10, 0, 0, 'romanoff', 192, '1971-07-19');
|
||||
$iId2 = $this->InsertMammal('human', 'female', 9, 0, 0, 'rouanita', 165, '1983-01-23');
|
||||
$this->InsertMammal('human', 'female', 3, $iId2, $iId1, 'pomme', 169, '2008-02-23');
|
||||
$this->InsertMammal('pig', 'female', 3, 0, 0, 'grouinkette', 85, '2006-06-01');
|
||||
$this->InsertMammal('donkey', 'female', 3, 0, 0, 'muleta', 124, '2003-11-11');
|
||||
|
||||
$this->InsertBird('rooster', 'male', 12, 0, 0);
|
||||
$this->InsertFlyingBird('pie', 'female', 11, 0, 0, 35);
|
||||
|
||||
echo "<h3>Search...</h3>";
|
||||
$oSearch = new DBObjectSearch('Mammal');
|
||||
$oSearch->AddCondition_FullText('manof');
|
||||
//$oResultSet = new DBObjectSet($oSearch);
|
||||
$this->search_and_show_list($oSearch);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Test queries
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -60,7 +60,7 @@ function ReadMandatoryParam($oP, $sParam, $sSanitizationFilter = 'parameter')
|
||||
|
||||
function UsageAndExit($oP)
|
||||
{
|
||||
$bModeCLI = utils::IsModeCLI();
|
||||
$bModeCLI = ($oP instanceof CLIPage);
|
||||
|
||||
if ($bModeCLI)
|
||||
{
|
||||
@@ -477,9 +477,12 @@ function ReorderProcesses(&$aProcesses, $aTasks, $oNow, $bVerbose, &$oP)
|
||||
|
||||
set_time_limit(0); // Some background actions may really take long to finish (like backup)
|
||||
|
||||
if (utils::IsModeCLI())
|
||||
$bIsModeCLI = utils::IsModeCLI();
|
||||
if ($bIsModeCLI)
|
||||
{
|
||||
$oP = new CLIPage("iTop - cron");
|
||||
|
||||
SetupUtils::CheckPhpAndExtensionsForCli($oP, EXIT_CODE_FATAL);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -497,7 +500,7 @@ catch (Exception $e)
|
||||
exit(EXIT_CODE_FATAL);
|
||||
}
|
||||
|
||||
if (utils::IsModeCLI())
|
||||
if ($bIsModeCLI)
|
||||
{
|
||||
// Next steps:
|
||||
// specific arguments: 'csvfile'
|
||||
|
||||
@@ -32,6 +32,12 @@ require_once(APPROOT.'/core/bulkexport.class.inc.php');
|
||||
require_once(APPROOT.'/application/startup.inc.php');
|
||||
|
||||
|
||||
|
||||
const EXIT_CODE_ERROR = -1;
|
||||
const EXIT_CODE_FATAL = -2;
|
||||
|
||||
|
||||
|
||||
function ReportErrorAndExit($sErrorMessage)
|
||||
{
|
||||
if (utils::IsModeCLI())
|
||||
@@ -39,14 +45,14 @@ function ReportErrorAndExit($sErrorMessage)
|
||||
$oP = new CLIPage("iTop - Export");
|
||||
$oP->p('ERROR: '.$sErrorMessage);
|
||||
$oP->output();
|
||||
exit(-1);
|
||||
exit(EXIT_CODE_ERROR);
|
||||
}
|
||||
else
|
||||
{
|
||||
$oP = new WebPage("iTop - Export");
|
||||
$oP->p('ERROR: '.$sErrorMessage);
|
||||
$oP->output();
|
||||
exit(-1);
|
||||
exit(EXIT_CODE_ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -58,7 +64,7 @@ function ReportErrorAndUsage($sErrorMessage)
|
||||
$oP->p('ERROR: '.$sErrorMessage);
|
||||
Usage($oP);
|
||||
$oP->output();
|
||||
exit(-1);
|
||||
exit(EXIT_CODE_ERROR);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -66,7 +72,7 @@ function ReportErrorAndUsage($sErrorMessage)
|
||||
$oP->p('ERROR: '.$sErrorMessage);
|
||||
Usage($oP);
|
||||
$oP->output();
|
||||
exit(-1);
|
||||
exit(EXIT_CODE_ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -565,6 +571,8 @@ function DoExport(WebPage $oP, BulkExport $oExporter, $bInteractive = false)
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
if (utils::IsModeCLI())
|
||||
{
|
||||
SetupUtils::CheckPhpAndExtensionsForCli(new CLIPage('iTop - Export'));
|
||||
|
||||
try
|
||||
{
|
||||
// Do this before loging, in order to allow setting user credentials from within the file
|
||||
@@ -573,7 +581,7 @@ if (utils::IsModeCLI())
|
||||
catch(Exception $e)
|
||||
{
|
||||
echo "Error: ".$e->GetMessage()."<br/>\n";
|
||||
exit(-2);
|
||||
exit(EXIT_CODE_FATAL);
|
||||
}
|
||||
|
||||
$sAuthUser = utils::ReadParam('auth_user', null, true /* Allow CLI */, 'raw_data');
|
||||
|
||||
@@ -29,6 +29,11 @@ require_once(APPROOT.'/application/excelexporter.class.inc.php');
|
||||
|
||||
require_once(APPROOT.'/application/startup.inc.php');
|
||||
|
||||
|
||||
const EXIT_CODE_ERROR = -1;
|
||||
const EXIT_CODE_FATAL = -2;
|
||||
|
||||
|
||||
try
|
||||
{
|
||||
// Do this before loging, in order to allow setting user credentials from within the file
|
||||
@@ -37,12 +42,15 @@ try
|
||||
catch(Exception $e)
|
||||
{
|
||||
echo "Error: ".$e->GetMessage()."<br/>\n";
|
||||
exit -2;
|
||||
exit(EXIT_CODE_FATAL);
|
||||
}
|
||||
|
||||
if (utils::IsModeCLI())
|
||||
{
|
||||
$sAuthUser = utils::ReadParam('auth_user', null, true /* Allow CLI */, 'raw_data');
|
||||
$oP = new CLIPage("iTop - Export");
|
||||
SetupUtils::CheckPhpAndExtensionsForCli($oP, EXIT_CODE_FATAL);
|
||||
|
||||
$sAuthUser = utils::ReadParam('auth_user', null, true /* Allow CLI */, 'raw_data');
|
||||
$sAuthPwd = utils::ReadParam('auth_pwd', null, true /* Allow CLI */, 'raw_data');
|
||||
|
||||
if (UserRights::CheckCredentials($sAuthUser, $sAuthPwd))
|
||||
@@ -51,10 +59,9 @@ if (utils::IsModeCLI())
|
||||
}
|
||||
else
|
||||
{
|
||||
$oP = new CLIPage("iTop - Export");
|
||||
$oP->p("Access restricted or wrong credentials ('$sAuthUser')");
|
||||
$oP->p("Access restricted or wrong credentials ('$sAuthUser')");
|
||||
$oP->output();
|
||||
exit -1;
|
||||
exit(EXIT_CODE_ERROR);
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -74,7 +81,7 @@ if (utils::IsArchiveMode() && !UserRights::CanBrowseArchive())
|
||||
$oP = new CLIPage("iTop - Export");
|
||||
$oP->p("The user account is not authorized to access the archives");
|
||||
$oP->output();
|
||||
exit -1;
|
||||
exit(EXIT_CODE_ERROR);
|
||||
}
|
||||
|
||||
$bLocalize = (utils::ReadParam('no_localize', 0) != 1);
|
||||
|
||||
@@ -212,6 +212,7 @@ function ReadMandatoryParam($oP, $sParam, $sSanitizationFilter)
|
||||
if (utils::IsModeCLI())
|
||||
{
|
||||
$oP = new CLIPage("iTop - Bulk import");
|
||||
SetupUtils::CheckPhpAndExtensionsForCli($oP, -2);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user