webservices.class.inc.php 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323
  1. <?php
  2. /**
  3. * Create Ticket web service
  4. * Web Service API wrapper
  5. *
  6. * @package iTopORM
  7. * @author Romain Quetiez <romainquetiez@yahoo.fr>
  8. * @author Denis Flaven <denisflave@free.fr>
  9. * @license http://www.opensource.org/licenses/lgpl-license.php LGPL
  10. * @link www.itop.com
  11. * @since 1.0
  12. * @version 1.1.1.1 $
  13. */
  14. class WebServiceResult
  15. {
  16. /**
  17. * Overall status
  18. *
  19. * @var m_bStatus
  20. */
  21. public $m_bStatus;
  22. /**
  23. * Error log
  24. *
  25. * @var m_aErrors
  26. */
  27. public $m_aErrors;
  28. /**
  29. * Warning log
  30. *
  31. * @var m_aWarnings
  32. */
  33. public $m_aWarnings;
  34. /**
  35. * Information log
  36. *
  37. * @var m_aInfos
  38. */
  39. public $m_aInfos;
  40. /**
  41. * Constructor
  42. *
  43. * @param status $bStatus
  44. */
  45. public function __construct()
  46. {
  47. $this->m_bStatus = true;
  48. $this->m_aErrors = array();
  49. $this->m_aWarnings = array();
  50. $this->m_aInfos = array();
  51. }
  52. /**
  53. * Did the current processing encounter a stopper issue ?
  54. *
  55. * @return bool
  56. */
  57. public function IsOk()
  58. {
  59. return $this->m_bStatus;
  60. }
  61. /**
  62. * Log an error
  63. *
  64. * @param description $sDescription
  65. */
  66. public function LogError($sDescription)
  67. {
  68. $this->m_aErrors[] = $sDescription;
  69. $this->m_bStatus = false;
  70. }
  71. /**
  72. * Log a warning
  73. *
  74. * @param description $sDescription
  75. */
  76. public function LogWarning($sDescription)
  77. {
  78. $this->m_aWarnings[] = $sDescription;
  79. }
  80. /**
  81. * Log an error or a warning
  82. *
  83. * @param string $sDescription
  84. * @param boolean $bIsStopper
  85. */
  86. public function LogIssue($sDescription, $bIsStopper = true)
  87. {
  88. if ($bIsStopper) $this->LogError($sDescription);
  89. else $this->LogWarning($sDescription);
  90. }
  91. /**
  92. * Log operation details
  93. *
  94. * @param description $sDescription
  95. */
  96. public function LogInfo($sDescription)
  97. {
  98. $this->m_aInfos[] = $sDescription;
  99. }
  100. }
  101. class WebServices
  102. {
  103. /**
  104. * Helper to set an external key
  105. *
  106. * @param string sAttCode
  107. * @param array aCallerDesc
  108. * @param DBObject oTargetObj
  109. * @param WebServiceResult oRes
  110. *
  111. */
  112. protected function SetExternalKey($sAttCode, $aExtKeyDesc, &$oTargetObj, &$oRes)
  113. {
  114. $oExtKey = MetaModel::GetAttributeDef(get_class($oTargetObj), $sAttCode);
  115. $bIsMandatory = !$oExtKey->IsNullAllowed();
  116. if (count($aExtKeyDesc) == 0)
  117. {
  118. $oRes->LogIssue("Ext key $sAttCode: no data was given to give a value to the key", $bIsMandatory);
  119. return;
  120. }
  121. $sKeyClass = $oExtKey->GetTargetClass();
  122. $oReconFilter = new CMDBSearchFilter($sKeyClass);
  123. foreach ($aExtKeyDesc as $sForeignAttCode => $value)
  124. {
  125. if (!MetaModel::IsValidFilterCode($sKeyClass, $sForeignAttCode))
  126. {
  127. $sMsg = "Ext key $sAttCode: '$sForeignAttCode' is not a valid filter code for class '$sKeyClass'";
  128. $oRes->LogIssue($sMsg, $bIsMandatory);
  129. }
  130. // The foreign attribute is one of our reconciliation key
  131. $oReconFilter->AddCondition($sForeignAttCode, $value, '=');
  132. }
  133. $oExtObjects = new CMDBObjectSet($oReconFilter);
  134. switch($oExtObjects->Count())
  135. {
  136. case 0:
  137. $sMsg = "External key $sAttCode could not be found (searched: '".$oReconFilter->ToOQL()."')";
  138. $oRes->LogIssue($sMsg, $bIsMandatory);
  139. break;
  140. case 1:
  141. // Do change the external key attribute
  142. $oForeignObj = $oExtObjects->Fetch();
  143. $oTargetObj->Set($sAttCode, $oForeignObj->GetKey());
  144. // Report it (no need to report if the object already had this value
  145. if (array_key_exists($sAttCode, $oTargetObj->ListChanges()))
  146. {
  147. $oRes->LogInfo("$sAttCode has been set to ".$oForeignObj->GetKey());
  148. }
  149. break;
  150. default:
  151. $sMsg = "Found ".$oExtObjects->Count()." matches for external key $sAttCode (searched: '".$oReconFilter->ToOQL()."')";
  152. $oRes->LogIssue($sMsg, $bIsMandatory);
  153. }
  154. }
  155. /**
  156. * Helper to link objects
  157. *
  158. * @param string sLinkAttCode
  159. * @param string sLinkedClass
  160. * @param array $aLinkList
  161. * @param DBObject oTargetObj
  162. * @param WebServiceResult oRes
  163. *
  164. * @return array List of objects that could not be found
  165. */
  166. protected function AddLinkedObjects($sLinkAttCode, $sLinkedClass, $aLinkList, &$oTargetObj, &$oRes)
  167. {
  168. $oLinkAtt = MetaModel::GetAttributeDef(get_class($oTargetObj), $sLinkAttCode);
  169. $sLinkClass = $oLinkAtt->GetLinkedClass();
  170. $sExtKeyToItem = $oLinkAtt->GetExtKeyToRemote();
  171. $aItemsFound = array();
  172. $aItemsNotFound = array();
  173. foreach ($aLinkList as $aItemData)
  174. {
  175. $sTargetClass = $aItemData['class'];
  176. if (!MetaModel::IsValidClass($sTargetClass))
  177. {
  178. $oRes->LogError("Invalid class $sTargetClass for impacted item");
  179. continue; // skip
  180. }
  181. if (!MetaModel::IsParentClass($sLinkedClass, $sTargetClass))
  182. {
  183. $oRes->LogError("$sTargetClass is not a child class of $sLinkedClass");
  184. continue; // skip
  185. }
  186. $oReconFilter = new CMDBSearchFilter($sTargetClass);
  187. $aCIStringDesc = array();
  188. foreach ($aItemData['search'] as $sAttCode => $value)
  189. {
  190. if (!MetaModel::IsValidFilterCode($sTargetClass, $sAttCode))
  191. {
  192. $oRes->LogError("Invalid filter code $sAttCode for class $sTargetClass");
  193. continue; // skip
  194. }
  195. $aCIStringDesc[] = "$sAttCode: $value";
  196. // The attribute is one of our reconciliation key
  197. $oReconFilter->AddCondition($sAttCode, $value, '=');
  198. }
  199. if (count($aCIStringDesc) == 1)
  200. {
  201. // take the last and unique value to describe the object
  202. $sItemDesc = $value;
  203. }
  204. else
  205. {
  206. // describe the object by the given keys
  207. $sItemDesc = $sTargetClass.'('.implode('/', $aCIStringDesc).')';
  208. }
  209. $oExtObjects = new CMDBObjectSet($oReconFilter);
  210. switch($oExtObjects->Count())
  211. {
  212. case 0:
  213. $oRes->LogWarning("Object to link $sLinkedClass / $sItemDesc could not be found (searched: '".$oReconFilter->ToOQL()."')");
  214. $aItemsNotFound[] = $sItemDesc;
  215. break;
  216. case 1:
  217. $aItemsFound[] = array (
  218. 'object' => $oExtObjects->Fetch(),
  219. 'link_values' => @$aItemData['link_values'],
  220. 'desc' => $sItemDesc,
  221. );
  222. break;
  223. default:
  224. $oRes->LogWarning("Found ".$oExtObjects->Count()." matches for external key $sAttCode (searched: '".$oReconFilter->ToOQL()."')");
  225. $aItemsNotFound[] = $sItemDesc;
  226. }
  227. }
  228. if (count($aItemsFound) > 0)
  229. {
  230. $aLinks = array();
  231. foreach($aItemsFound as $aItemData)
  232. {
  233. $oLink = MetaModel::NewObject($sLinkClass);
  234. $oLink->Set($sExtKeyToItem, $aItemData['object']->GetKey());
  235. foreach($aItemData['link_values'] as $sKey => $value)
  236. {
  237. if(!MetaModel::IsValidAttCode($sLinkClass, $sKey))
  238. {
  239. $oRes->LogWarning("Attaching item '".$aItemData['desc']."', the attribute code '$sKey' is not valid ; check the class '$sLinkClass'");
  240. }
  241. else
  242. {
  243. $oLink->Set($sKey, $value);
  244. }
  245. }
  246. $aLinks[] = $oLink;
  247. }
  248. $oImpactedInfraSet = DBObjectSet::FromArray($sLinkClass, $aLinks);
  249. $oTargetObj->Set($sLinkAttCode, $oImpactedInfraSet);
  250. }
  251. return $aItemsNotFound;
  252. }
  253. /**
  254. * Create an incident ticket from a monitoring system
  255. * Some CIs might be specified (by their name/IP)
  256. *
  257. * @param string sDecription
  258. * @param string sInitialSituation
  259. * @param array aCallerDesc
  260. * @param array aCustomerDesc
  261. * @param array aWorkgroupDesc
  262. * @param array aImpactedCIs
  263. * @param string sSeverity
  264. *
  265. * @return WebServiceResult
  266. */
  267. function CreateIncidentTicket($sDescription, $sInitialSituation, $aCallerDesc, $aCustomerDesc, $aWorkgroupDesc, $aImpactedCIs, $sSeverity)
  268. {
  269. $oRes = new WebServiceResult();
  270. new CMDBChange();
  271. $oMyChange = MetaModel::NewObject("CMDBChange");
  272. $oMyChange->Set("date", time());
  273. $oMyChange->Set("userinfo", "Administrator");
  274. $iChangeId = $oMyChange->DBInsertNoReload();
  275. $oNewTicket = MetaModel::NewObject('bizIncidentTicket');
  276. $oNewTicket->Set('title', $sDescription);
  277. $oNewTicket->Set('initial_situation', $sInitialSituation);
  278. $oNewTicket->Set('severity', $sSeverity);
  279. $this->SetExternalKey('org_id', $aCustomerDesc, $oNewTicket, $oRes);
  280. $this->SetExternalKey('caller_id', $aCallerDesc, $oNewTicket, $oRes);
  281. $this->SetExternalKey('workgroup_id', $aWorkgroupDesc, $oNewTicket, $oRes);
  282. $aDevicesNotFound = $this->AddLinkedObjects('impacted_infra_manual', 'logInfra', $aImpactedCIs, $oNewTicket, $oRes);
  283. if (count($aDevicesNotFound) > 0)
  284. {
  285. $oTargetObj->Set('impact', implode(', ', $aDevicesNotFound));
  286. }
  287. if ($oRes->IsOk())
  288. {
  289. $iId = $oNewTicket->DBInsertTrackedNoReload($oMyChange);
  290. $oRes->LogInfo("Created ticket #$iId");
  291. }
  292. return $oRes;
  293. }
  294. }
  295. ?>