action.class.inc.php 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349
  1. <?php
  2. require_once('../core/email.class.inc.php');
  3. /**
  4. * A user defined action, to customize the application
  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. abstract class Action extends cmdbAbstractObject
  15. {
  16. public static function Init()
  17. {
  18. $aParams = array
  19. (
  20. "category" => "core/cmdb",
  21. "name" => "action",
  22. "description" => "Custom action",
  23. "key_type" => "autoincrement",
  24. "key_label" => "",
  25. "name_attcode" => "name",
  26. "state_attcode" => "",
  27. "reconc_keys" => array(),
  28. "db_table" => "priv_action",
  29. "db_key_field" => "id",
  30. "db_finalclass_field" => "realclass",
  31. "display_template" => "",
  32. );
  33. MetaModel::Init_Params($aParams);
  34. //MetaModel::Init_InheritAttributes();
  35. MetaModel::Init_AddAttribute(new AttributeString("name", array("allowed_values"=>null, "sql"=>"name", "default_value"=>null, "is_null_allowed"=>false, "depends_on"=>array())));
  36. MetaModel::Init_AddAttribute(new AttributeString("description", array("allowed_values"=>null, "sql"=>"description", "default_value"=>null, "is_null_allowed"=>true, "depends_on"=>array())));
  37. MetaModel::Init_AddAttribute(new AttributeEnum("status", array("allowed_values"=>new ValueSetEnum(array('test'=>'Being tested' ,'enabled'=>'In production', 'disabled'=>'Inactive')), "sql"=>"status", "default_value"=>"test", "is_null_allowed"=>false, "depends_on"=>array())));
  38. MetaModel::Init_AddAttribute(new AttributeLinkedSetIndirect("related_triggers", 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())));
  39. //MetaModel::Init_InheritFilters();
  40. MetaModel::Init_AddFilterFromAttribute("name");
  41. MetaModel::Init_AddFilterFromAttribute("description");
  42. // Display lists
  43. MetaModel::Init_SetZListItems('details', array('name', 'description', 'status')); // Attributes to be displayed for the complete details
  44. MetaModel::Init_SetZListItems('list', array('finalclass', 'name', 'description', 'status')); // Attributes to be displayed for a list
  45. // Search criteria
  46. // MetaModel::Init_SetZListItems('standard_search', array('name')); // Criteria of the std search form
  47. // MetaModel::Init_SetZListItems('advanced_search', array('name')); // Criteria of the advanced search form
  48. }
  49. abstract public function DoExecute($oTrigger, $aContextArgs);
  50. public function IsActive()
  51. {
  52. switch($this->Get('status'))
  53. {
  54. case 'enabled':
  55. case 'test':
  56. return true;
  57. default:
  58. return false;
  59. }
  60. }
  61. public function IsBeingTested()
  62. {
  63. switch($this->Get('status'))
  64. {
  65. case 'test':
  66. return true;
  67. default:
  68. return false;
  69. }
  70. }
  71. }
  72. /**
  73. * A notification
  74. *
  75. * @package iTopORM
  76. * @author Romain Quetiez <romainquetiez@yahoo.fr>
  77. * @author Denis Flaven <denisflave@free.fr>
  78. * @license http://www.opensource.org/licenses/lgpl-license.php LGPL
  79. * @link www.itop.com
  80. * @since 1.0
  81. * @version 1.1.1.1 $
  82. */
  83. abstract class ActionNotification extends Action
  84. {
  85. public static function Init()
  86. {
  87. $aParams = array
  88. (
  89. "category" => "core/cmdb",
  90. "name" => "notification",
  91. "description" => "Notification (abstract)",
  92. "key_type" => "autoincrement",
  93. "key_label" => "",
  94. "name_attcode" => "name",
  95. "state_attcode" => "",
  96. "reconc_keys" => array(),
  97. "db_table" => "priv_action_notification",
  98. "db_key_field" => "id",
  99. "db_finalclass_field" => "",
  100. "display_template" => "",
  101. );
  102. MetaModel::Init_Params($aParams);
  103. MetaModel::Init_InheritAttributes();
  104. MetaModel::Init_InheritFilters();
  105. // Display lists
  106. MetaModel::Init_SetZListItems('details', array('name', 'description', 'status')); // Attributes to be displayed for the complete details
  107. MetaModel::Init_SetZListItems('list', array('finalclass', 'name', 'description', 'status')); // Attributes to be displayed for a list
  108. // Search criteria
  109. // MetaModel::Init_SetZListItems('standard_search', array('name')); // Criteria of the std search form
  110. // MetaModel::Init_SetZListItems('advanced_search', array('name')); // Criteria of the advanced search form
  111. }
  112. }
  113. /**
  114. * An email notification
  115. *
  116. * @package iTopORM
  117. * @author Romain Quetiez <romainquetiez@yahoo.fr>
  118. * @author Denis Flaven <denisflave@free.fr>
  119. * @license http://www.opensource.org/licenses/lgpl-license.php LGPL
  120. * @link www.itop.com
  121. * @since 1.0
  122. * @version 1.1.1.1 $
  123. */
  124. class ActionEmail extends ActionNotification
  125. {
  126. public static function Init()
  127. {
  128. $aParams = array
  129. (
  130. "category" => "core/cmdb",
  131. "name" => "email notification",
  132. "description" => "Action: Email notification",
  133. "key_type" => "autoincrement",
  134. "key_label" => "",
  135. "name_attcode" => "name",
  136. "state_attcode" => "",
  137. "reconc_keys" => array(),
  138. "db_table" => "priv_action_email",
  139. "db_key_field" => "id",
  140. "db_finalclass_field" => "",
  141. "display_template" => "",
  142. );
  143. MetaModel::Init_Params($aParams);
  144. MetaModel::Init_InheritAttributes();
  145. MetaModel::Init_AddAttribute(new AttributeEmailAddress("test_recipient", array("allowed_values"=>null, "sql"=>"test_recipient", "default_value"=>"", "is_null_allowed"=>true, "depends_on"=>array())));
  146. MetaModel::Init_AddAttribute(new AttributeString("from", array("allowed_values"=>null, "sql"=>"from", "default_value"=>null, "is_null_allowed"=>true, "depends_on"=>array())));
  147. MetaModel::Init_AddAttribute(new AttributeString("reply_to", array("allowed_values"=>null, "sql"=>"reply_to", "default_value"=>null, "is_null_allowed"=>true, "depends_on"=>array())));
  148. MetaModel::Init_AddAttribute(new AttributeOQL("to", array("allowed_values"=>null, "sql"=>"to", "default_value"=>null, "is_null_allowed"=>true, "depends_on"=>array())));
  149. MetaModel::Init_AddAttribute(new AttributeOQL("cc", array("allowed_values"=>null, "sql"=>"cc", "default_value"=>null, "is_null_allowed"=>true, "depends_on"=>array())));
  150. MetaModel::Init_AddAttribute(new AttributeOQL("bcc", array("allowed_values"=>null, "sql"=>"bcc", "default_value"=>null, "is_null_allowed"=>true, "depends_on"=>array())));
  151. MetaModel::Init_AddAttribute(new AttributeTemplateString("subject", array("allowed_values"=>null, "sql"=>"subject", "default_value"=>null, "is_null_allowed"=>false, "depends_on"=>array())));
  152. MetaModel::Init_AddAttribute(new AttributeTemplateText("body", array("allowed_values"=>null, "sql"=>"body", "default_value"=>null, "is_null_allowed"=>false, "depends_on"=>array())));
  153. 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())));
  154. MetaModel::Init_InheritFilters();
  155. // Display lists
  156. MetaModel::Init_SetZListItems('details', array('name', 'description', 'status', 'test_recipient', 'from', 'reply_to', 'to', 'cc', 'bcc', 'subject', 'body', 'importance')); // Attributes to be displayed for the complete details
  157. MetaModel::Init_SetZListItems('list', array('name', 'status', 'to', 'subject')); // Attributes to be displayed for a list
  158. // Search criteria
  159. // MetaModel::Init_SetZListItems('standard_search', array('name')); // Criteria of the std search form
  160. // MetaModel::Init_SetZListItems('advanced_search', array('name')); // Criteria of the advanced search form
  161. }
  162. // count the recipients found
  163. protected $m_iRecipients;
  164. // Errors management : not that simple because we need that function to be
  165. // executed in the background, while making sure that any issue would be reported clearly
  166. protected $m_aMailErrors; //array of strings explaining the issue
  167. // returns a the list of emails as a string, or a detailed error description
  168. protected function FindRecipients($sRecipAttCode, $aArgs)
  169. {
  170. $sOQL = $this->Get($sRecipAttCode);
  171. if (strlen($sOQL) == '') return '';
  172. try
  173. {
  174. $oSearch = DBObjectSearch::FromOQL($sOQL);
  175. }
  176. catch (OqlException $e)
  177. {
  178. $this->m_aMailErrors[] = "query syntax error for recipient '$sRecipAttCode'";
  179. return $e->getMessage();
  180. }
  181. $sClass = $oSearch->GetClass();
  182. // Determine the email attribute (the first one will be our choice)
  183. foreach (MetaModel::ListAttributeDefs($sClass) as $sAttCode => $oAttDef)
  184. {
  185. if ($oAttDef instanceof AttributeEmailAddress)
  186. {
  187. $sEmailAttCode = $sAttCode;
  188. // we've got one, exit the loop
  189. break;
  190. }
  191. }
  192. if (!isset($sEmailAttCode))
  193. {
  194. $this->m_aMailErrors[] = "wrong target for recipient '$sRecipAttCode'";
  195. return "The objects of the class '$sClass' do not have any email attribute";
  196. }
  197. $oSet = new DBObjectSet($oSearch, array() /* order */, $aArgs);
  198. $aRecipients = array();
  199. while ($oObj = $oSet->Fetch())
  200. {
  201. $aRecipients[] = $oObj->Get($sEmailAttCode);
  202. $this->m_iRecipients++;
  203. }
  204. return implode(', ', $aRecipients);
  205. }
  206. public function DoExecute($oTrigger, $aContextArgs)
  207. {
  208. $this->m_iRecipients = 0;
  209. $this->m_aMailErrors = array();
  210. $bRes = false; // until we do succeed in sending the email
  211. try
  212. {
  213. // Determine recicipients
  214. //
  215. $sTo = $this->FindRecipients('to', $aContextArgs);
  216. $sCC = $this->FindRecipients('cc', $aContextArgs);
  217. $sBCC = $this->FindRecipients('bcc', $aContextArgs);
  218. $sFrom = $this->Get('from');
  219. $sReplyTo = $this->Get('reply_to');
  220. $sSubject = MetaModel::ApplyParams($this->Get('subject'), $aContextArgs);
  221. $sBody = MetaModel::ApplyParams($this->Get('body'), $aContextArgs);
  222. $oEmail = new Email();
  223. if ($this->IsBeingTested())
  224. {
  225. $oEmail->SetSubject('TEST['.$sSubject.']');
  226. $sTestBody = $sBody;
  227. $sTestBody .= "<div style=\"border: dashed;\">\n";
  228. $sTestBody .= "<h1>Testing email notification ".$this->GetHyperlink()."</h1>\n";
  229. $sTestBody .= "<p>The email should be sent with the following properties\n";
  230. $sTestBody .= "<ul>\n";
  231. $sTestBody .= "<li>TO: $sTo</li>\n";
  232. $sTestBody .= "<li>CC: $sCC</li>\n";
  233. $sTestBody .= "<li>BCC: $sBCC</li>\n";
  234. $sTestBody .= "<li>From: $sFrom</li>\n";
  235. $sTestBody .= "<li>Reply-To: $sReplyTo</li>\n";
  236. $sTestBody .= "</ul>\n";
  237. $sTestBody .= "</p>\n";
  238. $sTestBody .= "</div>\n";
  239. $oEmail->SetBody($sTestBody);
  240. $oEmail->SetRecipientTO($this->Get('test_recipient'));
  241. $oEmail->SetRecipientFrom($this->Get('test_recipient'));
  242. }
  243. else
  244. {
  245. $oEmail->SetSubject($sSubject);
  246. $oEmail->SetBody($sBody);
  247. $oEmail->SetRecipientTO($sTo);
  248. $oEmail->SetRecipientCC($sCC);
  249. $oEmail->SetRecipientBCC($sBCC);
  250. $oEmail->SetRecipientFrom($sFrom);
  251. $oEmail->SetRecipientReplyTo($sReplyTo);
  252. }
  253. if (empty($this->m_aMailErrors))
  254. {
  255. if ($this->m_iRecipients == 0)
  256. {
  257. $this->m_aMailErrors[] = 'No recipient';
  258. }
  259. else
  260. {
  261. $this->m_aMailErrors = array_merge($this->m_aMailErrors, $oEmail->Send());
  262. }
  263. }
  264. }
  265. catch (Exception $e)
  266. {
  267. $this->m_aMailErrors[] = $e->getMessage();
  268. }
  269. $oLog = new EventNotificationEmail();
  270. if (empty($this->m_aMailErrors))
  271. {
  272. if ($this->IsBeingTested())
  273. {
  274. $oLog->Set('message', 'TEST - Notification sent ('.$this->Get('test_recipient').')');
  275. }
  276. else
  277. {
  278. $oLog->Set('message', 'Notification sent');
  279. }
  280. }
  281. else
  282. {
  283. if (is_array($this->m_aMailErrors) && count($this->m_aMailErrors) > 0)
  284. {
  285. $sError = implode(', ', $this->m_aMailErrors);
  286. }
  287. else
  288. {
  289. $sError = 'Unknown reason';
  290. }
  291. if ($this->IsBeingTested())
  292. {
  293. $oLog->Set('message', 'TEST - Notification was not sent: '.$sError);
  294. }
  295. else
  296. {
  297. $oLog->Set('message', 'Notification was not sent: '.$sError);
  298. }
  299. }
  300. $oLog->Set('userinfo', UserRights::GetUser());
  301. $oLog->Set('trigger_id', $oTrigger->GetKey());
  302. $oLog->Set('action_id', $this->GetKey());
  303. $oLog->Set('object_id', $aContextArgs['this->id']);
  304. // Note: we have to secure this because those values are calculated
  305. // inside the try statement, and we would like to keep track of as
  306. // many data as we could while some variables may still be undefined
  307. if (isset($sTo)) $oLog->Set('to', $sTo);
  308. if (isset($sCC)) $oLog->Set('cc', $sCC);
  309. if (isset($sBCC)) $oLog->Set('bcc', $sBCC);
  310. if (isset($sFrom)) $oLog->Set('from', $sFrom);
  311. if (isset($sSubject)) $oLog->Set('subject', $sSubject);
  312. if (isset($sBody)) $oLog->Set('body', $sBody);
  313. $oLog->DBInsertNoReload();
  314. }
  315. }
  316. ?>