incident.php 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761
  1. <?php
  2. require_once('../application/application.inc.php');
  3. require_once('../application/startup.inc.php');
  4. require_once('../application/itopwizardwebpage.class.inc.php');
  5. abstract class DialogWizard
  6. {
  7. protected $m_sCurrentStep;
  8. protected $m_aSteps;
  9. public function __construct($sStep)
  10. {
  11. $this->m_sCurrentStep = $sStep;
  12. }
  13. protected function GetFields($sStep = '')
  14. {
  15. if ($sStep == '')
  16. {
  17. $sStep = $this->m_sCurrentStep;
  18. }
  19. return $this->m_aSteps[$sStep];
  20. }
  21. protected function AddContextToForm(WebPage $oPage)
  22. {
  23. // Store as hidden fields in the page all the variables from the previous steps
  24. foreach($this->m_aSteps as $sStep => $aFields)
  25. {
  26. if ($sStep == $this->m_sCurrentStep) continue;
  27. foreach($aFields as $sAttName => $sFieldName)
  28. {
  29. $oPage->add("<input type=\"hidden\" name=\"$sFieldName\" value=\"".htmlentities(Utils::ReadParam($sFieldName, ''))."\" />\n");
  30. }
  31. }
  32. }
  33. function GetObjectPicker(WebPage $oPage, $sTitle, $sFieldName, $sClass)
  34. {
  35. $sScript =
  36. <<<EOF
  37. function UpdateObjectList(sClass)
  38. {
  39. var sRelatedObjectIds = new String($('#related_object_ids').val());
  40. if (sRelatedObjectIds.length > 0)
  41. {
  42. aRelatedObjectIds = sRelatedObjectIds.split(' ');
  43. }
  44. else
  45. {
  46. aRelatedObjectIds = new Array();
  47. aRelatedObjectIds[0] = 0;
  48. }
  49. var sibusql = sClass+": pkey IN {" + aRelatedObjectIds.join(", ") + "}";
  50. $.get("ajax.render.php?filter=" + sibusql + "&style=list&encoding=sibusql",
  51. { operation: "ajax" },
  52. function(data){
  53. $("#related_objects").empty();
  54. $("#related_objects").append(data);
  55. $("#related_objects").removeClass("loading");
  56. });
  57. }
  58. function AddObject(sClass)
  59. {
  60. var sRelatedObjectIds = new String($('#related_object_ids').val());
  61. var sCurrentObjectId = new String($('#ac_current_object_id').val());
  62. if (sRelatedObjectIds.length > 0)
  63. {
  64. aRelatedObjectIds = sRelatedObjectIds.split(' ');
  65. }
  66. else
  67. {
  68. aRelatedObjectIds = new Array();
  69. }
  70. // To do: check if the ID is not already in the list...
  71. aRelatedObjectIds[aRelatedObjectIds.length] = sCurrentObjectId;
  72. // Update the form & reload the list
  73. $('#related_object_ids').val(aRelatedObjectIds.join(' '));
  74. UpdateObjectList(sClass);
  75. }
  76. function ManageObjects(sTitle, sClass, sInputId)
  77. {
  78. $('#Manage_DlgTitle').text(sTitle);
  79. sObjList = new String($('#'+sInputId).val());
  80. if (sObjList == '')
  81. {
  82. sObjList = new String('0');
  83. }
  84. var aObjList = sObjList.split(' ');
  85. Manage_LoadSelect('selected_objects', sClass+': pkey IN {' + aObjList.join(', ') + '}');
  86. Manage_LoadSelect('available_objects', sClass);
  87. $('#ManageObjectsDlg').jqmShow();
  88. }
  89. function Manage_LoadSelect(sSelectedId, sFilter)
  90. {
  91. $('#'+sSelectedId).addClass('loading');
  92. $.get('ajax.render.php?filter=' + sFilter,
  93. { operation: 'combo_options' },
  94. function(data){
  95. $('#'+sSelectedId).empty();
  96. $('#'+sSelectedId).append(data);
  97. $('#'+sSelectedId).removeClass('loading');
  98. }
  99. );
  100. }
  101. function Manage_SwapSelectedObjects(oSourceSelect, oDestinationSelect)
  102. {
  103. for (i=oSourceSelect.length-1;i>=0;i--) // Count down because we are removing the indexes from the combo
  104. {
  105. if (oSourceSelect.options[i].selected)
  106. {
  107. var newOption = document.createElement('option');
  108. newOption.text = oSourceSelect.options[i].text;
  109. newOption.value = oSourceSelect.options[i].value;
  110. oDestinationSelect.add(newOption, null);
  111. oSourceSelect.remove(i);
  112. }
  113. }
  114. Manage_UpdateButtons();
  115. }
  116. function Manage_UpdateButtons()
  117. {
  118. var oSrc = document.getElementById('available_objects');
  119. var oAddBtn = document.getElementById('btn_add_objects')
  120. var oDst = document.getElementById('selected_objects');
  121. var oRemoveBtn = document.getElementById('btn_remove_objects')
  122. if (oSrc.selectedIndex == -1)
  123. {
  124. oAddBtn.disabled = true;
  125. }
  126. else
  127. {
  128. oAddBtn.disabled = false;
  129. }
  130. if (oDst.selectedIndex == -1)
  131. {
  132. oRemoveBtn.disabled = true;
  133. }
  134. else
  135. {
  136. oRemoveBtn.disabled = false;
  137. }
  138. }
  139. function Manage_AddObjects()
  140. {
  141. var oSrc = document.getElementById('available_objects');
  142. var oDst = document.getElementById('selected_objects');
  143. Manage_SwapSelectedObjects(oSrc, oDst);
  144. }
  145. function Manage_RemoveObjects()
  146. {
  147. var oSrc = document.getElementById('selected_objects');
  148. var oDst = document.getElementById('available_objects');
  149. Manage_SwapSelectedObjects(oSrc, oDst);
  150. }
  151. function Manage_Ok(sClass)
  152. {
  153. var objectsToAdd = document.getElementById('selected_objects');
  154. var aSelectedObjects = new Array();
  155. for (i=0; i<objectsToAdd.length;i++)
  156. {
  157. aSelectedObjects[aSelectedObjects.length] = objectsToAdd.options[i].value;
  158. }
  159. $('#related_object_ids').val(aSelectedObjects.join(' '));
  160. UpdateObjectList(sClass);
  161. }
  162. function FilterLeft($sClass)
  163. {
  164. alert('Not Yet Implemented');
  165. }
  166. function FilterRight($sClass)
  167. {
  168. alert('Not Yet Implemented');
  169. }
  170. EOF;
  171. $sManageObjectsDlg = <<< EOF
  172. <div class="page_header"><h1 id="Manage_DlgTitle">Selected Objects</h1></div>
  173. <table width="100%">
  174. <tr>
  175. <td>
  176. <p>Selected objects:</p>
  177. <button type="button" class="action" onClick="FilterLeft('$sClass');"><span> Filter... </span></button>
  178. <p><select id="selected_objects" size="10" multiple onChange="Manage_UpdateButtons()" style="width:300px;">
  179. </select></p>
  180. </td>
  181. <td style="text-align:center; valign:middle;">
  182. <p><button type="button" id="btn_add_objects" onClick="Manage_AddObjects();"> &lt;&lt; Add </button></p>
  183. <p><button type="button" id="btn_remove_objects" onClick="Manage_RemoveObjects();"> Remove &gt;&gt; </button></p>
  184. </td>
  185. <td>
  186. <p>Available objects:</p>
  187. <button type="button" class="action" onClick="FilterRight('$sClass');"><span> Filter... </span></button>
  188. <p><select id="available_objects" size="10" multiple onChange="Manage_UpdateButtons()" style="width:300px;">
  189. </select></p>
  190. </td>
  191. </tr>
  192. <tr>
  193. <td colspan="3">
  194. <button type="button" class="jqmClose" onClick="Manage_Ok('$sClass')"> Ok </button>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<button type="button" class="jqmClose"> Cancel</button>
  195. </td>
  196. </tr>
  197. </table>
  198. EOF;
  199. $sHTML = '<input type="text" name="" id="current_object_id" size="30"/>
  200. <input type="hidden" id="related_object_ids" name="'.$sFieldName.'" value="">
  201. &nbsp;<button type="button" class="action" onClick="return AddObject(\''.$sClass.'\');"><span> Add </span></button>
  202. &nbsp;<button type="button" class="action" onClick="return ManageObjects(\''.$sTitle.'\', \''.$sClass.'\', \'related_object_ids\');"><span> ... </span></button>';
  203. $sHTML .= '<input type="hidden" id="ac_current_object_id" name="" value="">';
  204. $sHTML .= '<div class="jqmWindow" id="ManageObjectsDlg">'.$sManageObjectsDlg.'</div>';
  205. $oPage->add_script($sScript);
  206. $oPage->add_ready_script("\$('#current_object_id').autocomplete('./ajax.render.php', { minChars:3, onItemSelect:selectItem, onFindValue:findValue, formatItem:formatItem, autoFill:true, keyHolder:'#ac_current_object_id', extraParams:{operation:'link', sclass:'$sClass', attCode:'name'}});");
  207. $oPage->add_ready_script("$('#ManageObjectsDlg').jqm({overlay:70, modal:true, toTop:true});"); // jqModal Window
  208. $oPage->add_ready_script("UpdateObjectList('$sClass');");
  209. return $sHTML;
  210. }
  211. function DisplayObjectPickerList(WebPage $oPage, $sClass)
  212. {
  213. $oFilter = new CMDBSearchFilter($sClass);
  214. $oFilter->AddCondition('pkey', array(0), 'IN');
  215. //$oPage->p($oFilter->__DescribeHTML());
  216. $oBlock = new DisplayBlock($oFilter, 'list', true /* Asynchronous */);
  217. $oBlock->Display($oPage, 'related_objects');
  218. }
  219. }
  220. class IncidentCreationWizard extends DialogWizard
  221. {
  222. public function __construct($sStep)
  223. {
  224. parent::__construct($sStep);
  225. $this->m_aSteps =
  226. array(
  227. '1' => array('title' => 'attr_title', 'customer_id' => 'attr_customer_id', 'initial_situation' => 'attr_initial_situation', 'severity' => 'attr_severity', 'impact' => 'attr_impact', 'workgroup_id' => 'attr_workgroup_id', 'action_log' => 'attr_action_log'),
  228. '2' => array('impacted_infra_ids' => 'impacted_infra_ids'),
  229. '3' => array('additional_impacted_object_ids' => 'additional_impacted_object_ids'),
  230. '4' => array('related_incident_ids' => 'related_incident_ids'),
  231. '5' => array('contact_ids' => 'contact_ids'),
  232. );
  233. }
  234. protected function AddContextToForm($oPage)
  235. {
  236. parent::AddContextToForm($oPage);
  237. $oPage->add("<input type=\"hidden\" name=\"operation\" value=\"new\" />\n");
  238. $oPage->add("<input type=\"hidden\" name=\"step\" value=\"".$this->m_sNextStep."\" />\n");
  239. }
  240. public function DisplayNewTicketForm(WebPage $oPage)
  241. {
  242. assert($this->m_sCurrentStep == '1');
  243. $this->m_sNextStep = '2';
  244. $aFields = $this->GetFields();
  245. $oPage->add('<form method="get">');
  246. $aDetails = array();
  247. $aAttributesDef = MetaModel::ListAttributeDefs('bizIncidentTicket');
  248. foreach($aFields as $sAttCode => $sFieldName)
  249. {
  250. $oAttDef = $aAttributesDef[$sAttCode];
  251. $sHTMLValue = cmdbAbstractObject::GetFormElementForField($oPage, 'bizIncidentTicket', $sAttCode, $oAttDef);
  252. $aDetails[] = array('label' => $oAttDef->GetLabel().' <span class="hilite">*</span>', 'value' => $sHTMLValue);
  253. }
  254. $oPage->details($aDetails);
  255. $this->AddContextToForm($oPage);
  256. $oPage->add("<button type=\"button\" class=\"action\" onClick=\"goBack()\"><span>Cancel</span></button>&nbsp;&nbsp;&nbsp;&nbsp;\n");
  257. $oPage->add("<button type=\"submit\" class=\"action\"><span>Next >></span></button>\n");
  258. $oPage->add('</form>');
  259. }
  260. public function DisplayImpactedInfraForm(WebPage $oPage)
  261. {
  262. assert($this->m_sCurrentStep == '2');
  263. $this->m_sNextStep = '3';
  264. $oPage->add('<form method="get">');
  265. $aDetails = array();
  266. $sHTML = $this->GetObjectPicker($oPage, 'Impacted Infrastructure', 'impacted_infra_ids', 'logInfra');
  267. $aDetails[] = array('label' => 'Impacted element:', 'value' => $sHTML);
  268. $oPage->details($aDetails);
  269. $this->DisplayObjectPickerList($oPage, 'logInfra');
  270. $this->AddContextToForm($oPage);
  271. $oPage->add("<button type=\"button\" class=\"action\" onClick=\"goBack()\"><span><< Back</span></button>&nbsp;&nbsp;&nbsp;&nbsp;\n");
  272. $oPage->add("<button type=\"submit\" class=\"action\"><span>Next >></span></button>\n");
  273. $oPage->add('</form>');
  274. }
  275. public function DisplayAdditionalImpactedObjectForm(WebPage $oPage)
  276. {
  277. assert($this->m_sCurrentStep == '3');
  278. $this->m_sNextStep = '4';
  279. $sImpactedInfraIds = Utils::ReadParam('impacted_infra_ids');
  280. $sImpactedInfraIds = Utils::ReadParam('impacted_infra_ids', '');
  281. if (!empty($sImpactedInfraIds))
  282. {
  283. $oPage->p('Impacted Infrastructure:');
  284. $oFilter = new CMDBSearchFilter('logRealObject');
  285. $oFilter->AddCondition('pkey', explode(' ', $sImpactedInfraIds), 'IN');
  286. $oBlock = new DisplayBlock($oFilter, 'list', false /* Synchronous */);
  287. $oBlock->Display($oPage, 'impacted_infra');
  288. }
  289. $aImpactedInfraIds = explode(' ', $sImpactedInfraIds);
  290. $oInfraSet = CMDBObjectSet::FromScratch('logRealObject');
  291. foreach($aImpactedInfraIds as $id)
  292. {
  293. $oObj = MetaModel::GetObject('logRealObject', $id);
  294. $oInfraSet->AddObject($oObj);
  295. }
  296. $aImpactedObject = $oInfraSet->GetRelatedObjects('impacts');
  297. $aAdditionalIds = array();
  298. foreach($aImpactedObject as $sRootClass => $aObjects)
  299. {
  300. foreach($aObjects as $oObj)
  301. {
  302. $aAdditionalIds[] = $oObj->GetKey();
  303. }
  304. }
  305. $sAdditionalIds = implode(' ', $aAdditionalIds);
  306. $oPage->add_ready_script('$("#related_object_ids").val("'.$sAdditionalIds.'");');
  307. $oPage->p('Additional Impact Computed:');
  308. $this->DisplayObjectPickerList($oPage, 'logRealObject');
  309. $oPage->add('<form method="get">');
  310. $aDetails = array();
  311. $sHTML = $this->GetObjectPicker($oPage, 'Additional Impacted Infrastructure', 'additional_impacted_object_ids', 'logRealObject');
  312. $aDetails[] = array('label' => 'Impacted element:', 'value' => $sHTML);
  313. $oPage->details($aDetails);
  314. $this->AddContextToForm($oPage);
  315. $oPage->add("<button type=\"button\" class=\"action\" onClick=\"goBack()\"><span><< Back</span></button>&nbsp;&nbsp;&nbsp;&nbsp;\n");
  316. $oPage->add("<button type=\"submit\" class=\"action\"><span>Next >></span></button>\n");
  317. $oPage->add('</form>');
  318. }
  319. public function DisplayRelatedTicketsForm(WebPage $oPage)
  320. {
  321. assert($this->m_sCurrentStep == '4');
  322. $this->m_sNextStep = '5';
  323. $oRelatedTicketsFilter = new DBObjectSearch('bizIncidentTicket');
  324. $sImpactedInfraIds = Utils::ReadParam('impacted_infra_ids', '');
  325. $sAdditionalImpactedObjectIds = Utils::ReadParam('additional_impacted_object_ids', '');
  326. $sIds = trim($sImpactedInfraIds.' '.$sAdditionalImpactedObjectIds);
  327. $aTicketIds = array();
  328. if (!empty($sIds))
  329. {
  330. $aIds = explode(' ', $sIds);
  331. $sSibusQL = "bizIncidentTicket: PKEY IS ticket_id IN (lnkInfraTicket: infra_id IN (logRealObject: pkey IN {".implode(',', $aIds)."}))";
  332. $oTicketSearch = DBObjectSearch::FromSibusQL($sSibusQL);
  333. $oRelatedTicketSet = new DBObjectSet($oTicketSearch);
  334. while ($oTicket = $oRelatedTicketSet->Fetch())
  335. {
  336. $aTicketIds[] = $oTicket->GetKey();
  337. }
  338. }
  339. $sTicketIds = implode(' ', $aTicketIds);
  340. $oPage->add_ready_script('$("#related_object_ids").val("'.$sTicketIds.'");');
  341. $oPage->p('Potentially related incidents:');
  342. $this->DisplayObjectPickerList($oPage, 'bizIncidentTicket');
  343. $oPage->add('<form method="get">');
  344. $sHTML = $this->GetObjectPicker($oPage, 'Related Incidents', 'related_incident_ids', 'bizIncidentTicket');
  345. $aDetails[] = array('label' => 'Related Incident:', 'value' => $sHTML);
  346. $oPage->details($aDetails);
  347. $this->AddContextToForm($oPage);
  348. $oPage->add("<button type=\"button\" class=\"action\" onClick=\"goBack()\"><span><< Back</span></button>&nbsp;&nbsp;&nbsp;&nbsp;\n");
  349. $oPage->add("<button type=\"submit\" class=\"action\"><span>Next >></span></button>\n");
  350. $oPage->add('</form>');
  351. }
  352. public function DisplayContactsToNotifyForm(WebPage $oPage)
  353. {
  354. assert($this->m_sCurrentStep == '5');
  355. $this->m_sNextStep = '6';
  356. $oPage->add('<form method="get">');
  357. $sHTML = $this->GetObjectPicker($oPage, 'Contacts to notify', 'contact_ids', 'bizContact');
  358. $aDetails[] = array('label' => 'Additional contact:', 'value' => $sHTML);
  359. $oPage->details($aDetails);
  360. $this->DisplayObjectPickerList($oPage, 'bizContact');
  361. $this->AddContextToForm($oPage);
  362. $oPage->add("<button type=\"button\" class=\"action\" onClick=\"goBack()\"><span><< Back</span></button>&nbsp;&nbsp;&nbsp;&nbsp;\n");
  363. $oPage->add("<button type=\"submit\" class=\"action\"><span>Next >></span></button>\n");
  364. $oPage->add('</form>');
  365. }
  366. function DisplayFinalForm(WebPage $oPage)
  367. {
  368. $oAppContext = new ApplicationContext();
  369. assert($this->m_sCurrentStep == '6');
  370. $this->m_sNextStep = '7';
  371. $aDetails = array();
  372. $aAttributesDef = MetaModel::ListAttributeDefs('bizIncidentTicket');
  373. $aFields = $this->GetFields('1');
  374. foreach($aFields as $sAttCode => $sFieldName)
  375. {
  376. $oAttDef = $aAttributesDef[$sAttCode];
  377. $sValue = Utils::ReadParam($sFieldName, '');
  378. if ($oAttDef->IsExternalKey() && isset($sValue) && ($sValue != 0))
  379. {
  380. $oTargetObj = MetaModel::GetObject($oAttDef->GetTargetClass(), $sValue);
  381. if (!is_object($oTargetObj))
  382. {
  383. trigger_error("Houston: could not find ".$oAttDef->GetTargetClass()."::$sValue");
  384. }
  385. $sPage = cmdbAbstractObject::ComputeUIPage($oAttDef->GetTargetClass());
  386. $sHint = htmlentities($oAttDef->GetTargetClass()."::".$sValue);
  387. $sHTMLValue = "<a href=\"$sPage?operation=details&class=".$oAttDef->GetTargetClass()."&id=$sValue&".$oAppContext->GetForLink()."\" title=\"$sHint\">".$oTargetObj->GetName()."</a>";
  388. }
  389. else
  390. {
  391. $sHTMLValue = $oAttDef->GetAsHTML($sValue);
  392. }
  393. $aDetails[] = array('label' => $oAttDef->GetLabel(), 'value' => $sHTMLValue);
  394. }
  395. $oPage->details($aDetails);
  396. $oPage->AddTabContainer('LinkedObjects');
  397. $oPage->SetCurrentTabContainer('LinkedObjects');
  398. $sImpactedInfraIds = Utils::ReadParam('impacted_infra_ids', '');
  399. $sImpactedInfraIds .= ' '.Utils::ReadParam('additional_impacted_object_ids', '');
  400. $sImpactedInfraIds = trim($sImpactedInfraIds);
  401. $oPage->SetCurrentTab("Infrastructure impacted");
  402. if (!empty($sImpactedInfraIds))
  403. {
  404. $oFilter = new CMDBSearchFilter('logRealObject');
  405. $oFilter->AddCondition('pkey', explode(' ', $sImpactedInfraIds), 'IN');
  406. $oBlock = new DisplayBlock($oFilter, 'list', false /* Synchronous */);
  407. $oBlock->Display($oPage, 'related_objects');
  408. }
  409. else
  410. {
  411. $oPage->p("There is no infrastructure impacted by this incident");
  412. }
  413. $sRelatedIncidentIds = Utils::ReadParam('related_incident_ids', '');
  414. $oPage->SetCurrentTab("Related tickets");
  415. if (!empty($sRelatedIncidentIds))
  416. {
  417. $oFilter = new CMDBSearchFilter('bizIncidentTicket');
  418. $oFilter->AddCondition('pkey', explode(' ', $sRelatedIncidentIds), 'IN');
  419. $oBlock = new DisplayBlock($oFilter, 'list', false /* Synchronous */);
  420. $oBlock->Display($oPage, 'related_incidents');
  421. }
  422. else
  423. {
  424. $oPage->p("There is no other incident related to this one");
  425. }
  426. $oPage->SetCurrentTab("Contacts to notify");
  427. $sContactIds = Utils::ReadParam('contact_ids', '');
  428. if (!empty($sContactIds))
  429. {
  430. $oFilter = new CMDBSearchFilter('bizContact');
  431. $oFilter->AddCondition('pkey', explode(' ', $sContactIds), 'IN');
  432. $oBlock = new DisplayBlock($oFilter, 'list', false /* Synchronous */);
  433. $oBlock->Display($oPage, 'contacts');
  434. }
  435. else
  436. {
  437. $oPage->p("There is no contact to notify");
  438. }
  439. $oPage->SetCurrentTab();
  440. $oPage->add('<form method="post" action="incident.php">');
  441. $this->AddContextToForm($oPage);
  442. $oPage->add("<button type=\"button\" class=\"action\" onClick=\"goBack()\"><span><< Back</span></button>&nbsp;&nbsp;&nbsp;&nbsp;\n");
  443. $oPage->add("<button type=\"submit\" class=\"action\" value=\"create\"><span> Create Ticket</span></button>&nbsp;&nbsp;&nbsp;&nbsp;\n");
  444. $oPage->add("<button type=\"submit\" class=\"action\" value=\"create_notify\"><span> Create Ticket and Send Notifications</span></button>\n");
  445. $oPage->add('</form>');
  446. }
  447. public function CreateIncident(WebPage $oPage)
  448. {
  449. $oAppContext = new ApplicationContext();
  450. assert($this->m_sCurrentStep == '7');
  451. $this->m_sNextStep = '1';
  452. $oIncident = MetaModel::NewObject('bizIncidentTicket');
  453. $oPage->p("Creation of Incident Ticket.");
  454. $aFields = $this->GetFields('1');
  455. foreach($aFields as $sAttCode => $sFieldName)
  456. {
  457. $sValue = Utils::ReadPostedParam($sFieldName, '');
  458. $oIncident->Set($sAttCode, $sValue);
  459. }
  460. $oIncident->Set('ticket_status', 'New');
  461. $oIncident->Set('start_date', time());
  462. $oIncident->Set('name', 'ID not set');
  463. if ($oIncident->CheckToInsert())
  464. {
  465. // Create the ticket itself
  466. $oMyChange = MetaModel::NewObject("CMDBChange");
  467. $oMyChange->Set("date", time());
  468. $oMyChange->Set("userinfo", "Administrator");
  469. $iChangeId = $oMyChange->DBInsert();
  470. $oIncident->DBInsertTracked($oMyChange);
  471. $sName = sprintf('I-%06d', $oIncident->GetKey());
  472. $oIncident->Set('name', $sName);
  473. $oIncident->DBUpdateTracked($oMyChange);
  474. $oPage->p("Incident $sName created.\n");
  475. // Now link the objects to the Incident:
  476. // 1) the impacted infra
  477. $sImpactedInfraIds = Utils::ReadParam('impacted_infra_ids', '');
  478. $sImpactedInfraIds .= ' '.Utils::ReadParam('additional_impacted_object_ids', '');
  479. $sImpactedInfraIds = trim($sImpactedInfraIds);
  480. if (!empty($sImpactedInfraIds))
  481. {
  482. $aImpactedInfra = explode(' ', $sImpactedInfraIds);
  483. foreach($aImpactedInfra as $iInfraId)
  484. {
  485. $oLink = MetaModel::NewObject('lnkInfraTicket');
  486. $oLink->Set('infra_id', $iInfraId);
  487. $oLink->Set('ticket_id', $oIncident->GetKey());
  488. $oLink->Set('impact', 'automatic');
  489. $oLink->DBInsertTracked($oMyChange);
  490. }
  491. }
  492. // 2) the related incidents
  493. $sRelatedIncidentsIds = Utils::ReadPostedParam('related_incident_ids');
  494. if (!empty($sRelatedIncidentsIds))
  495. {
  496. $aRelatedIncidents = explode(' ', $sRelatedIncidentsIds);
  497. foreach($aRelatedIncidents as $iIncidentId)
  498. {
  499. $oLink = MetaModel::NewObject('lnkRelatedTicket');
  500. $oLink->Set('rel_ticket_id', $iIncidentId);
  501. $oLink->Set('ticket_id', $oIncident->GetKey());
  502. $oLink->Set('impact', 'automatic');
  503. $oLink->DBInsertTracked($oMyChange);
  504. }
  505. }
  506. // 3) the contacts to notify
  507. $sContactsIds = Utils::ReadPostedParam('contact_ids');
  508. if (!empty($sContactsIds))
  509. {
  510. $aContactsToNotify = explode(' ', $sContactsIds);
  511. foreach($aContactsToNotify as $iContactId)
  512. {
  513. $oLink = MetaModel::NewObject('lnkContactRealObject');
  514. $oLink->Set('contact_id', $iContactId);
  515. $oLink->Set('object_id', $oIncident->GetKey());
  516. $oLink->Set('role', 'notification');
  517. $oLink->DBInsertTracked($oMyChange);
  518. }
  519. }
  520. $oIncident->DisplayDetails($oPage, 'bizIncidentTicket', $oIncident->GetKey());
  521. }
  522. else
  523. {
  524. $oPage->p("<strong>Error: object can not be created!</strong>\n");
  525. }
  526. }
  527. }
  528. $oContext = new UserContext();
  529. $oAppContext = new ApplicationContext();
  530. $currentOrganization = utils::ReadParam('org_id', '');
  531. $operation = utils::ReadParam('operation', '');
  532. $oP = new iTopWebPage("ITop - Incident Management", $currentOrganization);
  533. switch($operation)
  534. {
  535. case 'details':
  536. $sClass = utils::ReadParam('class', '');
  537. $id = utils::ReadParam('id', '');
  538. if ( empty($sClass) || empty($id)) // TO DO: check that the class name is valid !
  539. {
  540. $oP->add("<p>'class' and 'id' parameters must be specifed for this operation.</p>\n");
  541. }
  542. else
  543. {
  544. $oObj = $oContext->GetObject($sClass, $id);
  545. if ($oObj != null)
  546. {
  547. $oP->set_title("iTop - ".$oObj->GetName()." - $sClass details");
  548. $oObj->DisplayDetails($oP);
  549. }
  550. else
  551. {
  552. $oP->set_title("iTop - Error");
  553. $oP->add("<p>Sorry this object does not exist (or you are not allowed to view it).</p>\n");
  554. }
  555. }
  556. break;
  557. case 'new':
  558. $step = utils::ReadParam('step', '1');
  559. $aSteps = array(
  560. 'Ticket Information',
  561. 'Impacted Infrastructure',
  562. 'Additional Impact',
  563. 'Related Tickets',
  564. 'Contacts to Notify',
  565. 'Confirmation',
  566. 'Ticket Creation'
  567. );
  568. $oWizard = new IncidentCreationWizard($step);
  569. $oP = new iTopWizardWebPage("ITop - Incident Management", $currentOrganization, $step, $aSteps);
  570. switch($step)
  571. {
  572. case 1:
  573. default:
  574. //$oP->add('<div class="page_header"><h1><span class="hilite">New incident</span></h1></div>');
  575. $oWizard->DisplayNewTicketForm($oP);
  576. break;
  577. case 2:
  578. //$oP->add('<div class="page_header"><h1>New ticket: <span class="hilite">Select the Impacted Infrastructure</span></h1></div>');
  579. $oWizard->DisplayImpactedInfraForm($oP);
  580. break;
  581. case 3:
  582. //$oP->add('<div class="page_header"><h1>New ticket: <span class="hilite">Additional Impacted Objects</span></h1></div>');
  583. $oWizard->DisplayAdditionalImpactedObjectForm($oP);
  584. break;
  585. case 4:
  586. //$oP->add('<div class="page_header"><h1>New ticket: <span class="hilite">Select Related Incidents</span></h1></div>');
  587. $oWizard->DisplayRelatedTicketsForm($oP);
  588. break;
  589. case 5:
  590. //$oP->add('<div class="page_header"><h1>New ticket: <span class="hilite">Select the Contacts to Notify</span></h1></div>');
  591. $oWizard->DisplayContactsToNotifyForm($oP);
  592. break;
  593. case 6:
  594. //$oP->add('<div class="page_header"><h1>New ticket: <span class="hilite">Confirm and Create the Ticket</span></h1></div>');
  595. $oWizard->DisplayFinalForm($oP);
  596. break;
  597. case 7:
  598. $oWizard->CreateIncident($oP);
  599. break;
  600. }
  601. break;
  602. case 'modify':
  603. $oP->add_linked_script("../js/json.js");
  604. $oP->add_linked_script("../js/forms-json-utils.js");
  605. $oP->add_linked_script("../js/wizardhelper.js");
  606. $oP->add_linked_script("../js/wizard.utils.js");
  607. $oP->add_linked_script("../js/linkswidget.js");
  608. $oP->add_linked_script("../js/jquery.blockUI.js");
  609. $sClass = utils::ReadParam('class', '');
  610. $id = utils::ReadParam('id', '');
  611. if ( empty($sClass) || empty($id)) // TO DO: check that the class name is valid !
  612. {
  613. $oP->add("<p>'class' and 'id' parameters must be specifed for this operation.</p>\n");
  614. }
  615. else
  616. {
  617. $oObj = $oContext->GetObject($sClass, $id);
  618. if ($oObj != null)
  619. {
  620. $oP->set_title("iTop - ".$oObj->GetName()." - $sClass modification");
  621. $oP->add("<h1>".$oObj->GetName()." - $sClass modification</h1>\n");
  622. $oObj->DisplayModifyForm($oP);
  623. }
  624. else
  625. {
  626. $oP->set_title("iTop - Error");
  627. $oP->add("<p>Sorry this object does not exist (or you are not allowed to view it).</p>\n");
  628. }
  629. }
  630. break;
  631. case 'apply_modify':
  632. $sClass = utils::ReadPostedParam('class', '');
  633. $id = utils::ReadPostedParam('id', '');
  634. $sTransactionId = utils::ReadPostedParam('transaction_id', '');
  635. if ( empty($sClass) || empty($id)) // TO DO: check that the class name is valid !
  636. {
  637. $oP->add("<p>'class' and 'id' parameters must be specifed for this operation.</p>\n");
  638. }
  639. else if (!utils::IsTransactionValid($sTransactionId))
  640. {
  641. $oP->p("<strong>Error: object has already be updated!</strong>\n");
  642. }
  643. else
  644. {
  645. $oObj = $oContext->GetObject($sClass, $id);
  646. if ($oObj != null)
  647. {
  648. $oP->set_title("iTop - ".$oObj->GetName()." - $sClass modification");
  649. $oP->add("<h1>".$oObj->GetName()." - $sClass modification</h1>\n");
  650. $bObjectModified = false;
  651. foreach(MetaModel::ListAttributeDefs(get_class($oObj)) as $sAttCode=>$oAttDef)
  652. {
  653. $iFlags = $oObj->GetAttributeFlags($sAttCode);
  654. if ($iFlags & (OPT_ATT_HIDDEN | OPT_ATT_READONLY))
  655. {
  656. // Non-visible, or read-only attribute, do nothing
  657. }
  658. else if ($sAttCode == 'finalclass')
  659. {
  660. // This very specific field is read-only
  661. }
  662. else if (!$oAttDef->IsExternalField())
  663. {
  664. $aAttributes[$sAttCode] = trim(utils::ReadPostedParam("attr_$sAttCode", null));
  665. $previousValue = $oObj->Get($sAttCode);
  666. if (!is_null($aAttributes[$sAttCode]) && ($previousValue != $aAttributes[$sAttCode]))
  667. {
  668. $oObj->Set($sAttCode, $aAttributes[$sAttCode]);
  669. $bObjectModified = true;
  670. }
  671. }
  672. }
  673. if (!$bObjectModified)
  674. {
  675. $oP->p("No modification detected. ".get_class($oObj)." has <strong>not</strong> been updated.\n");
  676. }
  677. else if ($oObj->CheckToUpdate())
  678. {
  679. $oMyChange = MetaModel::NewObject("CMDBChange");
  680. $oMyChange->Set("date", time());
  681. $oMyChange->Set("userinfo", "Made by somebody"); // TO DO put the correct user info here
  682. $iChangeId = $oMyChange->DBInsert();
  683. $oObj->DBUpdateTracked($oMyChange);
  684. $oP->p(get_class($oObj)." updated.\n");
  685. }
  686. else
  687. {
  688. $oP->p("<strong>Error: object can not be updated!</strong>\n");
  689. //$oObj->Reload(); // restore default values!
  690. }
  691. }
  692. else
  693. {
  694. $oP->set_title("iTop - Error");
  695. $oP->add("<p>Sorry this object does not exist (or you are not allowed to edit it).</p>\n");
  696. }
  697. }
  698. $oP->add("<p>Alors ça roule ?</p>");
  699. $oObj->DisplayDetails($oP);
  700. break;
  701. }
  702. $oP->output();
  703. ?>