|
17 | 17 | * You should have received a copy of the GNU Affero General Public License
|
18 | 18 | */
|
19 | 19 |
|
| 20 | +use Combodo\iTop\Core\CMDBChange\CMDBChangeOrigin; |
| 21 | + |
20 | 22 | require_once('../approot.inc.php');
|
21 | 23 | require_once(APPROOT.'/application/application.inc.php');
|
22 | 24 |
|
23 | 25 | require_once(APPROOT.'/application/startup.inc.php');
|
24 | 26 | require_once(APPROOT.'/application/loginwebpage.class.inc.php');
|
25 |
| -LoginWebPage::DoLogin(); |
| 27 | +LoginWebPage::DoLogin(); |
26 | 28 |
|
27 | 29 | $sOperation = utils::ReadParam('operation', 'menu');
|
28 | 30 | $oAppContext = new ApplicationContext();
|
|
31 | 33 |
|
32 | 34 | // Main program
|
33 | 35 | $sOperation = utils::ReadParam('operation', 'details');
|
34 |
| -try |
| 36 | + |
| 37 | +/** |
| 38 | + * @param \DBObject|null $oReplica |
| 39 | + * @param $this |
| 40 | + * |
| 41 | + * @return \SynchroLog |
| 42 | + * @throws \ArchivedObjectException |
| 43 | + * @throws \CoreCannotSaveObjectException |
| 44 | + * @throws \CoreException |
| 45 | + * @throws \CoreUnexpectedValue |
| 46 | + * @throws \CoreWarning |
| 47 | + * @throws \MySQLException |
| 48 | + * @throws \OQLException |
| 49 | + * @throws \SynchroExceptionNotStarted |
| 50 | + */ |
| 51 | +function Synchro($oReplica): SynchroLog |
35 | 52 | {
|
36 |
| - switch($sOperation) |
37 |
| - { |
38 |
| - case 'details': |
39 |
| - $iId = utils::ReadParam('id', null); |
40 |
| - if ($iId == null) |
41 |
| - { |
42 |
| - throw new ApplicationException(Dict::Format('UI:Error:1ParametersMissing', 'id')); |
| 53 | + $oDataSource = MetaModel::GetObject('SynchroDataSource', $oReplica->Get('sync_source_id')); |
| 54 | + |
| 55 | + $oStatLog = new SynchroLog(); |
| 56 | + $oStatLog->Set('sync_source_id', $oDataSource->GetKey()); |
| 57 | + $oStatLog->Set('start_date', time()); |
| 58 | + $oStatLog->Set('status', 'running'); |
| 59 | + $oStatLog->AddTrace('Manual synchro'); |
| 60 | + |
| 61 | + // Get the list of SQL columns |
| 62 | + $aAttCodesExpected = array(); |
| 63 | + $aAttCodesToReconcile = array(); |
| 64 | + $aAttCodesToUpdate = array(); |
| 65 | + $sSelectAtt = 'SELECT SynchroAttribute WHERE sync_source_id = :source_id AND (update = 1 OR reconcile = 1)'; |
| 66 | + $oSetAtt = new DBObjectSet(DBObjectSearch::FromOQL($sSelectAtt), array() /* order by*/, array('source_id' => $oDataSource->GetKey()) /* aArgs */); |
| 67 | + while ($oSyncAtt = $oSetAtt->Fetch()) { |
| 68 | + if ($oSyncAtt->Get('update')) { |
| 69 | + $aAttCodesToUpdate[$oSyncAtt->Get('attcode')] = $oSyncAtt; |
43 | 70 | }
|
44 |
| - $oReplica = MetaModel::GetObject('SynchroReplica', $iId); |
45 |
| - $oReplica->DisplayDetails($oP); |
46 |
| - break; |
47 |
| - |
48 |
| - case 'oql': |
49 |
| - $sOQL = utils::ReadParam('oql', null, false, 'raw_data'); |
50 |
| - if ($sOQL == null) |
51 |
| - { |
52 |
| - throw new ApplicationException(Dict::Format('UI:Error:1ParametersMissing', 'oql')); |
| 71 | + if ($oSyncAtt->Get('reconcile')) { |
| 72 | + $aAttCodesToReconcile[$oSyncAtt->Get('attcode')] = $oSyncAtt; |
53 | 73 | }
|
54 |
| - $oFilter = DBObjectSearch::FromOQL($sOQL); |
55 |
| - $oBlock1 = new DisplayBlock($oFilter, 'search', false, array('menu' => false, 'table_id' => '1')); |
56 |
| - $oBlock1->Display($oP, 0); |
57 |
| - $oP->add('<p class="page-header">'.MetaModel::GetClassIcon('SynchroReplica').Dict::S('Core:SynchroReplica:ListOfReplicas').'</p>'); |
58 |
| - $iSourceId = utils::ReadParam('datasource', null); |
59 |
| - if ($iSourceId != null) |
60 |
| - { |
61 |
| - $oSource = MetaModel::GetObject('SynchroDataSource', $iSourceId); |
62 |
| - $oP->p(Dict::Format('Core:SynchroReplica:BackToDataSource', $oSource->GetHyperlink()).'</a>'); |
| 74 | + $aAttCodesExpected[$oSyncAtt->Get('attcode')] = $oSyncAtt; |
| 75 | + } |
| 76 | + |
| 77 | + // Get the list of attributes, determine reconciliation keys and update targets |
| 78 | + // |
| 79 | + if ($oDataSource->Get('reconciliation_policy') == 'use_attributes') { |
| 80 | + $aReconciliationKeys = $aAttCodesToReconcile; |
| 81 | + } elseif ($oDataSource->Get('reconciliation_policy') == 'use_primary_key') { |
| 82 | + // Override the settings made at the attribute level ! |
| 83 | + $aReconciliationKeys = array('primary_key' => null); |
| 84 | + } |
| 85 | + |
| 86 | + if (count($aAttCodesToUpdate) == 0) { |
| 87 | + $oStatLog->AddTrace('No attribute to update'); |
| 88 | + throw new SynchroExceptionNotStarted('There is no attribute to update'); |
| 89 | + } |
| 90 | + if (count($aReconciliationKeys) == 0) { |
| 91 | + $oStatLog->AddTrace('No attribute for reconciliation'); |
| 92 | + throw new SynchroExceptionNotStarted('No attribute for reconciliation'); |
| 93 | + } |
| 94 | + |
| 95 | + |
| 96 | + $aAttributesToUpdate = array(); |
| 97 | + foreach ($aAttCodesToUpdate as $sAttCode => $oSyncAtt) { |
| 98 | + $oAttDef = MetaModel::GetAttributeDef($oDataSource->GetTargetClass(), $sAttCode); |
| 99 | + if ($oAttDef->IsWritable()) { |
| 100 | + $aAttributesToUpdate[$sAttCode] = $oSyncAtt; |
63 | 101 | }
|
64 |
| - $oBlock = new DisplayBlock($oFilter, 'list', false, array('menu'=>false)); |
65 |
| - $oBlock->Display($oP, 1); |
66 |
| - break; |
| 102 | + } |
| 103 | + // Create a change used for logging all the modifications/creations happening during the synchro |
| 104 | + $oChange = MetaModel::NewObject('CMDBChange'); |
| 105 | + $oChange->Set('date', time()); |
| 106 | + $sUserString = CMDBChange::GetCurrentUserName(); |
| 107 | + $oChange->Set('userinfo', $sUserString.' '.Dict::S('Core:SyncDataExchangeComment')); |
| 108 | + $oChange->Set('origin', CMDBChangeOrigin::SYNCHRO_DATA_SOURCE); |
| 109 | + $oChange->DBInsert(); |
| 110 | + CMDBObject::SetCurrentChange($oChange); |
| 111 | + |
| 112 | + $oReplica->InitExtendedData($oDataSource); |
| 113 | + |
| 114 | + $oReplica->Synchro($oDataSource, $aReconciliationKeys, $aAttributesToUpdate, $oChange, $oStatLog); |
| 115 | + $oReplica->DBUpdate(); |
| 116 | + |
| 117 | + return $oStatLog; |
| 118 | +} |
| 119 | + |
| 120 | +try { |
| 121 | + switch ($sOperation) { |
| 122 | + case 'details': |
| 123 | + $iId = utils::ReadParam('id', null); |
| 124 | + if ($iId == null) { |
| 125 | + throw new ApplicationException(Dict::Format('UI:Error:1ParametersMissing', 'id')); |
| 126 | + } |
| 127 | + $oReplica = MetaModel::GetObject('SynchroReplica', $iId); |
| 128 | + $oReplica->DisplayDetails($oP); |
| 129 | + break; |
| 130 | + |
| 131 | + case 'oql': |
| 132 | + $sOQL = utils::ReadParam('oql', null, false, 'raw_data'); |
| 133 | + if ($sOQL == null) { |
| 134 | + throw new ApplicationException(Dict::Format('UI:Error:1ParametersMissing', 'oql')); |
| 135 | + } |
| 136 | + $oFilter = DBObjectSearch::FromOQL($sOQL); |
| 137 | + $oBlock1 = new DisplayBlock($oFilter, 'search', false, array('menu' => false, 'table_id' => '1')); |
| 138 | + $oBlock1->Display($oP, 0); |
| 139 | + $oP->add('<p class="page-header">'.MetaModel::GetClassIcon('SynchroReplica').Dict::S('Core:SynchroReplica:ListOfReplicas').'</p>'); |
| 140 | + $iSourceId = utils::ReadParam('datasource', null); |
| 141 | + if ($iSourceId != null) { |
| 142 | + $oSource = MetaModel::GetObject('SynchroDataSource', $iSourceId); |
| 143 | + $oP->p(Dict::Format('Core:SynchroReplica:BackToDataSource', $oSource->GetHyperlink()).'</a>'); |
| 144 | + } |
| 145 | + $oBlock = new DisplayBlock($oFilter, 'list', false, array('menu' => false)); |
| 146 | + $oBlock->Display($oP, 1); |
| 147 | + break; |
67 | 148 |
|
68 | 149 | case 'delete':
|
69 | 150 | case 'select_for_deletion':
|
70 |
| - // Redirect to the page that implements bulk delete |
71 |
| - $sDelete = utils::GetAbsoluteUrlAppRoot().'pages/UI.php?'.$_SERVER['QUERY_STRING']; |
72 |
| - header("Location: $sDelete"); |
73 |
| - break; |
| 151 | + // Redirect to the page that implements bulk delete |
| 152 | + $sDelete = utils::GetAbsoluteUrlAppRoot().'pages/UI.php?'.$_SERVER['QUERY_STRING']; |
| 153 | + header("Location: $sDelete"); |
| 154 | + break; |
| 155 | + |
| 156 | + case 'unlinksynchro': |
| 157 | + $iId = utils::ReadParam('id', null); |
| 158 | + if ($iId == null) { |
| 159 | + throw new ApplicationException(Dict::Format('UI:Error:1ParametersMissing', 'id')); |
| 160 | + } |
| 161 | + $oReplica = MetaModel::GetObject('SynchroReplica', $iId); |
| 162 | + $oReplica->Set('dest_id', ''); |
| 163 | + $oReplica->Set('status', 'new'); |
| 164 | + $oReplica->DBWrite(); |
| 165 | + |
| 166 | + $oStatLog = Synchro($oReplica); |
| 167 | + $oP->add(implode('<br>', $oStatLog->GetTraces())); |
| 168 | + |
| 169 | + $oReplica->DisplayDetails($oP); |
| 170 | + break; |
| 171 | + |
| 172 | + case 'unlink': |
| 173 | + $iId = utils::ReadParam('id', null); |
| 174 | + if ($iId == null) { |
| 175 | + throw new ApplicationException(Dict::Format('UI:Error:1ParametersMissing', 'id')); |
| 176 | + } |
| 177 | + $oReplica = MetaModel::GetObject('SynchroReplica', $iId); |
| 178 | + $oReplica->Set('dest_id', ''); |
| 179 | + $oReplica->Set('status', 'new'); |
| 180 | + $oReplica->DBWrite(); |
| 181 | + |
| 182 | + $oReplica->DisplayDetails($oP); |
| 183 | + break; |
| 184 | + |
| 185 | + case 'synchro': |
| 186 | + $iId = utils::ReadParam('id', null); |
| 187 | + if ($iId == null) { |
| 188 | + throw new ApplicationException(Dict::Format('UI:Error:1ParametersMissing', 'id')); |
| 189 | + } |
| 190 | + $oReplica = MetaModel::GetObject('SynchroReplica', $iId); |
| 191 | + $oStatLog = Synchro($oReplica); |
| 192 | + break; |
74 | 193 | }
|
75 | 194 | }
|
76 | 195 | catch(CoreException $e)
|
|
0 commit comments