diff --git a/core/MyHelpers.class.inc.php b/core/MyHelpers.class.inc.php index 16e149cd9..fded6913a 100644 --- a/core/MyHelpers.class.inc.php +++ b/core/MyHelpers.class.inc.php @@ -331,15 +331,6 @@ class MyHelpers exit; } - /** - * utf8... converts non ASCII chars into '?' - * Decided after some complex investigations, to have the tools work fine (Oracle+Perl vs mySQL+PHP...) - */ - public static function utf8($strText) - { - return iconv("WINDOWS-1252", "ASCII//TRANSLIT", $strText); - } - /** * xmlentities() * ... same as htmlentities, but designed for xml ! diff --git a/core/action.class.inc.php b/core/action.class.inc.php index dbeaeeea8..6f8dfcb0f 100644 --- a/core/action.class.inc.php +++ b/core/action.class.inc.php @@ -1,5 +1,7 @@ "Name", "description"=>"label", "allowed_values"=>null, "sql"=>"name", "default_value"=>null, "is_null_allowed"=>false, "depends_on"=>array()))); MetaModel::Init_AddAttribute(new AttributeString("description", array("label"=>"Description", "description"=>"one line description", "allowed_values"=>null, "sql"=>"description", "default_value"=>null, "is_null_allowed"=>true, "depends_on"=>array()))); + MetaModel::Init_AddAttribute(new AttributeEnum("status", array("label"=>"Status", "description"=>"In production or ?", "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()))); MetaModel::Init_AddAttribute(new AttributeLinkedSetIndirect("related_triggers", array("label"=>"Related Triggers", "description"=>"Triggers linked to this action", "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()))); //MetaModel::Init_InheritFilters(); @@ -41,14 +44,39 @@ abstract class Action extends cmdbAbstractObject MetaModel::Init_AddFilterFromAttribute("description"); // Display lists - MetaModel::Init_SetZListItems('details', array('name', 'description')); // Attributes to be displayed for the complete details - MetaModel::Init_SetZListItems('list', array('name', 'description')); // Attributes to be displayed for a list + MetaModel::Init_SetZListItems('details', array('name', 'description', 'status')); // Attributes to be displayed for the complete details + MetaModel::Init_SetZListItems('list', array('finalclass', 'name', 'description', 'status')); // Attributes to be displayed for a list // 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 } abstract public function DoExecute($oTrigger, $aContextArgs); + + public function IsActive() + { + switch($this->Get('status')) + { + case 'enabled': + case 'test': + return true; + + default: + return false; + } + } + + public function IsBeingTested() + { + switch($this->Get('status')) + { + case 'test': + return true; + + default: + return false; + } + } } /** @@ -87,8 +115,8 @@ abstract class ActionNotification extends Action MetaModel::Init_InheritFilters(); // Display lists - MetaModel::Init_SetZListItems('details', array('name', 'description')); // Attributes to be displayed for the complete details - MetaModel::Init_SetZListItems('list', array('finalclass', 'name', 'description')); // Attributes to be displayed for a list + MetaModel::Init_SetZListItems('details', array('name', 'description', 'status')); // Attributes to be displayed for the complete details + MetaModel::Init_SetZListItems('list', array('finalclass', 'name', 'description', 'status')); // Attributes to be displayed for a list // 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 @@ -128,6 +156,8 @@ class ActionEmail extends ActionNotification MetaModel::Init_Params($aParams); MetaModel::Init_InheritAttributes(); + MetaModel::Init_AddAttribute(new AttributeEmailAddress("test_recipient", array("label"=>"Test recipient", "description"=>"Detination in case status is set to \"Test\"", "allowed_values"=>null, "sql"=>"test_recipient", "default_value"=>"", "is_null_allowed"=>true, "depends_on"=>array()))); + MetaModel::Init_AddAttribute(new AttributeString("from", array("label"=>"From", "description"=>"Will be sent into the email header", "allowed_values"=>null, "sql"=>"from", "default_value"=>null, "is_null_allowed"=>true, "depends_on"=>array()))); MetaModel::Init_AddAttribute(new AttributeString("reply_to", array("label"=>"Reply to", "description"=>"Will be sent into the email header", "allowed_values"=>null, "sql"=>"reply_to", "default_value"=>null, "is_null_allowed"=>true, "depends_on"=>array()))); MetaModel::Init_AddAttribute(new AttributeOQL("to", array("label"=>"To", "description"=>"Destination of the email", "allowed_values"=>null, "sql"=>"to", "default_value"=>null, "is_null_allowed"=>true, "depends_on"=>array()))); @@ -140,21 +170,36 @@ class ActionEmail extends ActionNotification MetaModel::Init_InheritFilters(); // Display lists - MetaModel::Init_SetZListItems('details', array('name', 'description', 'from', 'reply_to', 'to', 'cc', 'bcc', 'subject', 'body', 'importance')); // Attributes to be displayed for the complete details - MetaModel::Init_SetZListItems('list', array('name', 'to', 'subject')); // Attributes to be displayed for a list + 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 + MetaModel::Init_SetZListItems('list', array('name', 'status', 'to', 'subject')); // Attributes to be displayed for a list // 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 } - // args: a search object - // returns an array of emails - protected function FindRecipients($sAttCode, $aArgs) + // count the recipients found + protected $m_iRecipients; + + // Errors management : not that simple because we need that function to be + // 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 + protected function FindRecipients($sRecipAttCode, $aArgs) { - $sOQL = $this->Get($sAttCode); + $sOQL = $this->Get($sRecipAttCode); if (strlen($sOQL) == '') return ''; - $oSearch = DBObjectSearch::FromOQL($sOQL); + try + { + $oSearch = DBObjectSearch::FromOQL($sOQL); + } + catch (OqlException $e) + { + $this->m_aMailErrors[] = "query syntax error for recipient '$sRecipAttCode'"; + return $e->getMessage(); + } + $sClass = $oSearch->GetClass(); // Determine the email attribute (the first one will be our choice) foreach (MetaModel::ListAttributeDefs($sClass) as $sAttCode => $oAttDef) @@ -166,78 +211,138 @@ class ActionEmail extends ActionNotification break; } } + if (!isset($sEmailAttCode)) + { + $this->m_aMailErrors[] = "wrong target for recipient '$sRecipAttCode'"; + return "The objects of the class '$sClass' do not have any email attribute"; + } $oSet = new DBObjectSet($oSearch, array() /* order */, $aArgs); $aRecipients = array(); while ($oObj = $oSet->Fetch()) { $aRecipients[] = $oObj->Get($sEmailAttCode); + $this->m_iRecipients++; } return implode(', ', $aRecipients); } + public function DoExecute($oTrigger, $aContextArgs) { - // Determine recicipients - // - $sTo = $this->FindRecipients('to', $aContextArgs); - $sCC = $this->FindRecipients('cc', $aContextArgs); - $sBCC = $this->FindRecipients('bcc', $aContextArgs); - - $sFrom = $this->Get('from'); - $sReplyTo = $this->Get('reply_to'); - - $sSubject = MetaModel::ApplyParams($this->Get('subject'), $aContextArgs); - $sBody = MetaModel::ApplyParams($this->Get('body'), $aContextArgs); - - // To send HTML mail, the Content-type header must be set - $sHeaders = 'MIME-Version: 1.0' . "\r\n"; - $sHeaders .= 'Content-type: text/html; charset=iso-8859-1' . "\r\n"; - - // Additional headers - if (strlen($sFrom) > 0) + $this->m_iRecipients = 0; + $this->m_aMailErrors = array(); + $bRes = false; // until we do succeed in sending the email + try { - $sHeaders .= "From: $sFrom\r\n"; - // This is required on Windows because otherwise I would get the error - // "sendmail_from" not set in php.ini" even if it is correctly working - // (apparently, once it worked the SMTP server won't claim anymore for it) - ini_set("sendmail_from", $sFrom); + // Determine recicipients + // + $sTo = $this->FindRecipients('to', $aContextArgs); + $sCC = $this->FindRecipients('cc', $aContextArgs); + $sBCC = $this->FindRecipients('bcc', $aContextArgs); + + $sFrom = $this->Get('from'); + $sReplyTo = $this->Get('reply_to'); + + $sSubject = MetaModel::ApplyParams($this->Get('subject'), $aContextArgs); + $sBody = MetaModel::ApplyParams($this->Get('body'), $aContextArgs); + + $oEmail = new Email(); + + if ($this->IsBeingTested()) + { + $oEmail->SetSubject('TEST['.$sSubject.']'); + $sTestBody = $sBody; + $sTestBody .= "
\n"; + $sTestBody .= "

Testing email notification ".$this->GetHyperlink()."

\n"; + $sTestBody .= "

The email should be sent with the following properties\n"; + $sTestBody .= "

\n"; + $sTestBody .= "

\n"; + $sTestBody .= "
\n"; + $oEmail->SetBody($sTestBody); + $oEmail->SetRecipientTO($this->Get('test_recipient')); + $oEmail->SetRecipientFrom($this->Get('test_recipient')); + } + else + { + $oEmail->SetSubject($sSubject); + $oEmail->SetBody($sBody); + $oEmail->SetRecipientTO($sTo); + $oEmail->SetRecipientCC($sCC); + $oEmail->SetRecipientBCC($sBCC); + $oEmail->SetRecipientFrom($sFrom); + $oEmail->SetRecipientReplyTo($sReplyTo); + } + + if (empty($this->m_aMailErrors)) + { + if ($this->m_iRecipients == 0) + { + $this->m_aMailErrors[] = 'No recipient'; + } + else + { + $this->m_aMailErrors = array_merge($this->m_aMailErrors, $oEmail->Send()); + } + } } - if (strlen($sReplyTo) > 0) + catch (Exception $e) { - $sHeaders .= "Reply-To: $sReplyTo\r\n"; - } - if (strlen($sCC) > 0) - { - $sHeaders .= "Cc: $sCC\r\n"; - } - if (strlen($sBCC) > 0) - { - $sHeaders .= "Bcc: $sBCC\r\n"; + $this->m_aMailErrors[] = $e->getMessage(); } $oLog = new EventNotificationEmail(); - if (mail($sTo, $sSubject, $sBody, $sHeaders)) + if (empty($this->m_aMailErrors)) { - $oLog->Set('message', 'Notification sent'); + if ($this->IsBeingTested()) + { + $oLog->Set('message', 'TEST - Notification sent ('.$this->Get('test_recipient').')'); + } + else + { + $oLog->Set('message', 'Notification sent'); + } } else { - $aLastError = error_get_last(); - $oLog->Set('message', 'Mail could not be sent: '.$aLastError['message']); - //throw new CoreException('mail not sent', array('action'=>$this->GetKey(), 'to'=>$sTo, 'subject'=>$sSubject, 'headers'=>$sHeaders)); + if (is_array($this->m_aMailErrors) && count($this->m_aMailErrors) > 0) + { + $sError = implode(', ', $this->m_aMailErrors); + } + else + { + $sError = 'Unknown reason'; + } + if ($this->IsBeingTested()) + { + $oLog->Set('message', 'TEST - Notification was not sent: '.$sError); + } + else + { + $oLog->Set('message', 'Notification was not sent: '.$sError); + } } $oLog->Set('userinfo', UserRights::GetUser()); $oLog->Set('trigger_id', $oTrigger->GetKey()); $oLog->Set('action_id', $this->GetKey()); $oLog->Set('object_id', $aContextArgs['this->id']); - $oLog->Set('from', $sFrom); - $oLog->Set('to', $sTo); - $oLog->Set('cc', $sCC); - $oLog->Set('bcc', $sBCC); - $oLog->Set('subject', $sSubject); - $oLog->Set('body', $sBody); + + // Note: we have to secure this because those values are calculated + // inside the try statement, and we would like to keep track of as + // many data as we could while some variables may still be undefined + if (isset($sTo)) $oLog->Set('to', $sTo); + if (isset($sCC)) $oLog->Set('cc', $sCC); + if (isset($sBCC)) $oLog->Set('bcc', $sBCC); + if (isset($sFrom)) $oLog->Set('from', $sFrom); + if (isset($sSubject)) $oLog->Set('subject', $sSubject); + if (isset($sBody)) $oLog->Set('body', $sBody); $oLog->DBInsertNoReload(); } } diff --git a/core/dbobject.class.php b/core/dbobject.class.php index e20943a7a..68479ca11 100644 --- a/core/dbobject.class.php +++ b/core/dbobject.class.php @@ -522,14 +522,27 @@ abstract class DBObject // Note: checks the values and consistency public function CheckToInsert() { + $aIssues = array(); foreach(MetaModel::ListAttributeDefs(get_class($this)) as $sAttCode=>$oAttDef) { - if (!$this->CheckValue($sAttCode)) return false; + if (!$this->CheckValue($sAttCode)) + { + $aIssues[$sAttCode] = array( + 'issue' => 'unexpected value' + ); + } } - if (!$this->CheckConsistency()) return false; - return true; + if (count($aIssues) > 0) + { + return array(false, $aIssues); + } + if (!$this->CheckConsistency()) + { + return array(false, $aIssues); + } + return array(true, $aIssues); } - + // check if it is allowed to update the existing object into the database // a displayable error is returned // Note: checks the values and consistency diff --git a/core/event.class.inc.php b/core/event.class.inc.php index 9955dddbd..cbac9e792 100644 --- a/core/event.class.inc.php +++ b/core/event.class.inc.php @@ -32,7 +32,7 @@ class Event extends cmdbAbstractObject ); MetaModel::Init_Params($aParams); //MetaModel::Init_InheritAttributes(); - MetaModel::Init_AddAttribute(new AttributeString("message", array("label"=>"message", "description"=>"short description of the event", "allowed_values"=>null, "sql"=>"message", "default_value"=>null, "is_null_allowed"=>false, "depends_on"=>array()))); + MetaModel::Init_AddAttribute(new AttributeText("message", array("label"=>"message", "description"=>"short description of the event", "allowed_values"=>null, "sql"=>"message", "default_value"=>null, "is_null_allowed"=>false, "depends_on"=>array()))); MetaModel::Init_AddAttribute(new AttributeDate("date", array("label"=>"date", "description"=>"date and time at which the changes have been recorded", "allowed_values"=>null, "sql"=>"date", "default_value"=>"", "is_null_allowed"=>false, "depends_on"=>array()))); MetaModel::Init_AddAttribute(new AttributeString("userinfo", array("label"=>"user info", "description"=>"identification of the user that was doing the action that triggered this event", "allowed_values"=>null, "sql"=>"userinfo", "default_value"=>null, "is_null_allowed"=>true, "depends_on"=>array()))); @@ -110,18 +110,18 @@ class EventNotificationEmail extends EventNotification ); MetaModel::Init_Params($aParams); MetaModel::Init_InheritAttributes(); - MetaModel::Init_AddAttribute(new AttributeText("to", array("label"=>"TO", "description"=>"TO", "allowed_values"=>null, "sql"=>"to", "default_value"=>null, "is_null_allowed"=>false, "depends_on"=>array()))); - MetaModel::Init_AddAttribute(new AttributeText("cc", array("label"=>"CC", "description"=>"CC", "allowed_values"=>null, "sql"=>"cc", "default_value"=>null, "is_null_allowed"=>false, "depends_on"=>array()))); - MetaModel::Init_AddAttribute(new AttributeText("bcc", array("label"=>"BCC", "description"=>"BCC", "allowed_values"=>null, "sql"=>"bcc", "default_value"=>null, "is_null_allowed"=>false, "depends_on"=>array()))); - MetaModel::Init_AddAttribute(new AttributeText("from", array("label"=>"From", "description"=>"Sender of the message", "allowed_values"=>null, "sql"=>"from", "default_value"=>null, "is_null_allowed"=>false, "depends_on"=>array()))); - MetaModel::Init_AddAttribute(new AttributeText("subject", array("label"=>"Subject", "description"=>"Subject", "allowed_values"=>null, "sql"=>"subject", "default_value"=>null, "is_null_allowed"=>false, "depends_on"=>array()))); - MetaModel::Init_AddAttribute(new AttributeText("body", array("label"=>"Body", "description"=>"Body", "allowed_values"=>null, "sql"=>"body", "default_value"=>null, "is_null_allowed"=>false, "depends_on"=>array()))); - + MetaModel::Init_AddAttribute(new AttributeText("to", array("label"=>"TO", "description"=>"TO", "allowed_values"=>null, "sql"=>"to", "default_value"=>null, "is_null_allowed"=>true, "depends_on"=>array()))); + MetaModel::Init_AddAttribute(new AttributeText("cc", array("label"=>"CC", "description"=>"CC", "allowed_values"=>null, "sql"=>"cc", "default_value"=>null, "is_null_allowed"=>true, "depends_on"=>array()))); + MetaModel::Init_AddAttribute(new AttributeText("bcc", array("label"=>"BCC", "description"=>"BCC", "allowed_values"=>null, "sql"=>"bcc", "default_value"=>null, "is_null_allowed"=>true, "depends_on"=>array()))); + MetaModel::Init_AddAttribute(new AttributeText("from", array("label"=>"From", "description"=>"Sender of the message", "allowed_values"=>null, "sql"=>"from", "default_value"=>null, "is_null_allowed"=>true, "depends_on"=>array()))); + MetaModel::Init_AddAttribute(new AttributeText("subject", array("label"=>"Subject", "description"=>"Subject", "allowed_values"=>null, "sql"=>"subject", "default_value"=>null, "is_null_allowed"=>true, "depends_on"=>array()))); + MetaModel::Init_AddAttribute(new AttributeText("body", array("label"=>"Body", "description"=>"Body", "allowed_values"=>null, "sql"=>"body", "default_value"=>null, "is_null_allowed"=>true, "depends_on"=>array()))); MetaModel::Init_InheritFilters(); // Display lists - MetaModel::Init_SetZListItems('details', array('date', 'userinfo', 'trigger_id', 'action_id', 'object_id', 'from', 'to', 'cc', 'bcc', 'subject', 'body')); // Attributes to be displayed for the complete details - MetaModel::Init_SetZListItems('list', array('date', 'userinfo', 'subject')); // Attributes to be displayed for a list + MetaModel::Init_SetZListItems('details', array('date', 'userinfo', 'message', 'trigger_id', 'action_id', 'object_id', 'to', 'cc', 'bcc', 'from', 'subject', 'body')); // Attributes to be displayed for the complete details + MetaModel::Init_SetZListItems('list', array('date', 'userinfo', 'message', 'subject')); // Attributes to be displayed for a list + // 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 diff --git a/core/test.class.inc.php b/core/test.class.inc.php index 905e7ad06..87af7e165 100644 --- a/core/test.class.inc.php +++ b/core/test.class.inc.php @@ -130,9 +130,8 @@ abstract class TestHandler $this->ReportWarning($errstr); break; default: - throw new ExceptionFromError("Fatal warning in line $errline of file $errfile: $errstr"); - $this->ReportWarning("Unknown error type: [$errno] $errstr"); - echo "Unknown error type: [$errno] $errstr
\n"; + $this->ReportWarning("Unknown error type: [$errno] $errstr in $errfile at $errline"); + echo "Unknown error type: [$errno] $errstr in $errfile at $errline
\n"; break; } return true; // do not call the default handler @@ -418,6 +417,48 @@ abstract class TestBizModel extends TestHandler // something here to create records... but that's another story } + protected $m_oChange; + protected function ObjectToDB($oNew, $bReload = false) + { + list($bRes, $aIssues) = $oNew->CheckToInsert(); + if (!$bRes) + { + throw new CoreException('Could not create object, unexpected values', array('attributes' => $aIssues)); + } + if ($oNew instanceof CMDBObject) + { + if (!isset($this->m_oChange)) + { + new CMDBChange(); + $oMyChange = MetaModel::NewObject("CMDBChange"); + $oMyChange->Set("date", time()); + $oMyChange->Set("userinfo", "Someone doing some tests"); + $iChangeId = $oMyChange->DBInsertNoReload(); + $this->m_oChange = $oMyChange; + } + if ($bReload) + { + $iId = $oNew->DBInsertTracked($this->m_oChange); + } + else + { + $iId = $oNew->DBInsertTrackedNoReload($this->m_oChange); + } + } + else + { + if ($bReload) + { + $iId = $oNew->DBInsert(); + } + else + { + $iId = $oNew->DBInsertNoReload(); + } + } + return $iId; + } + protected function ResetDB() { if (MetaModel::DBExists()) diff --git a/core/trigger.class.inc.php b/core/trigger.class.inc.php index e9de6eaa3..511bb42a3 100644 --- a/core/trigger.class.inc.php +++ b/core/trigger.class.inc.php @@ -56,7 +56,10 @@ class Trigger extends cmdbAbstractObject { $iActionId = $oLink->Get('action_id'); $oAction = MetaModel::GetObject('Action', $iActionId); - $oAction->DoExecute($this, $aContextArgs); + if ($oAction->IsActive()) + { + $oAction->DoExecute($this, $aContextArgs); + } } } } diff --git a/pages/UniversalSearch.php b/pages/UniversalSearch.php index b8b300ce6..4a9c9b077 100644 --- a/pages/UniversalSearch.php +++ b/pages/UniversalSearch.php @@ -145,7 +145,8 @@ EOF; } } - if ($oMenuNode->CheckToInsert()) + list($bRes, $aIssues) = $oMenuNode->CheckToInsert(); + if ($bRes) { $oMenuNode->DBInsert(); $oP->add("
"); diff --git a/pages/index.php b/pages/index.php index 5d5b81581..4cbac19c2 100644 --- a/pages/index.php +++ b/pages/index.php @@ -393,7 +393,8 @@ function CreateObject(WebPage $oPage, $sClassName, $aAttributes) $oObj->Set($sAttCode, $aAttributes[$sAttCode]); } } - if ($oObj->CheckToInsert()) + list($bRes, $aIssues) = $oObj->CheckToInsert(); + if ($bRes) { // By rom // $oObj->DBInsert(); @@ -413,6 +414,12 @@ function CreateObject(WebPage $oPage, $sClassName, $aAttributes) else { $oPage->p("Error: object can not be created!\n"); + $oPage->add(""); } $oPage->p("Return to main page"); } @@ -442,7 +449,8 @@ function AddLinks($oPage, $sClassName, $sKey, $sLinkClass, $sExtKeyToMe, $sExtKe $oNewLink = MetaModel::NewObject($sLinkClass); $oNewLink->Set($sExtKeyToMe, $sKey); $oNewLink->Set($sExtKeyToPartner, $oPartnerObj->GetKey()); - if ($oNewLink->CheckToInsert()) + list($bRes, $aIssues) = $oNewLink->CheckToInsert(); + if ($bRes) { $oMyChange = MetaModel::NewObject("CMDBChange"); $oMyChange->Set("date", time()); @@ -455,6 +463,12 @@ function AddLinks($oPage, $sClassName, $sKey, $sLinkClass, $sExtKeyToMe, $sExtKe else { $oPage->p("Error: link can not be created!\n"); + $oPage->add(""); } } } diff --git a/pages/testlist.inc.php b/pages/testlist.inc.php index 42d137528..800ac969f 100644 --- a/pages/testlist.inc.php +++ b/pages/testlist.inc.php @@ -601,22 +601,6 @@ abstract class MyFarm extends TestBizModel MetaModel::DBCheckIntegrity(); } - protected $m_oChange; - protected function ObjectToDB(CMDBObject $oNew) - { - if (!isset($this->m_oChange)) - { - new CMDBChange(); - $oMyChange = MetaModel::NewObject("CMDBChange"); - $oMyChange->Set("date", time()); - $oMyChange->Set("userinfo", "Administrator"); - $iChangeId = $oMyChange->DBInsertNoReload(); - $this->m_oChange = $oMyChange; - } - $iId = $oNew->DBInsertTrackedNoReload($this->m_oChange); - return $iId; -} - protected function InsertMammal($sSpecies, $sSex, $iSpeed, $iMotherid, $iFatherId, $sName, $iHeight, $sBirth) { $oNew = MetaModel::NewObject('Mammal'); @@ -1467,4 +1451,140 @@ class TestWebServicesDirect extends TestBizModel return true; } } + +class TestTriggerAndEmail extends TestBizModel +{ + static public function GetName() {return 'Test trigger and email';} + static public function GetDescription() {return 'Create a trigger and an email, then activates the trigger';} + + static public function GetConfigFile() {return '../config-itop.php';} + + protected function CreateEmailSpec($oTrigger, $sStatus, $sTo, $sCC, $sTesterEmail) + { + $oAction = MetaModel::NewObject("ActionEmail"); + $oAction->Set("status", $sStatus); + $oAction->Set("name", "New server"); + $oAction->Set("test_recipient", $sTesterEmail); + $oAction->Set("from", $sTesterEmail); + $oAction->Set("reply_to", $sTesterEmail); + $oAction->Set("to", $sTo); + $oAction->Set("cc", $sCC); + $oAction->Set("bcc", ""); + $oAction->Set("subject", "New server: '\$this->name()$'"); + $oAction->Set("body", "

Dear customer,

We have created the server \$this->hyperlink()$ in the IT infrastructure database.

You will be further notified when it is in Production.

The IT infrastructure management team.

Here are some accentuated characters for french people: 'ייא'

"); + $oAction->Set("importance", "low"); + $iActionId = $this->ObjectToDB($oAction, true); + + $oLink = MetaModel::NewObject("lnkTriggerAction"); + $oLink->Set("trigger_id", $oTrigger->GetKey()); + $oLink->Set("action_id", $iActionId); + $oLink->Set("order", "1"); + $iLink = $this->ObjectToDB($oLink, true); + } + + protected function DoExecute() + { + $oMyPerson = MetaModel::NewObject("bizPerson"); + $oMyPerson->Set("name", "testemail1"); + $oMyPerson->Set("org_id", "1"); + $oMyPerson->Set("email", "romain.quetiez@hp.com"); + $iPersonId = $this->ObjectToDB($oMyPerson, true); + + $oMyPerson = MetaModel::NewObject("bizPerson"); + $oMyPerson->Set("name", "testemail2"); + $oMyPerson->Set("org_id", "1"); + $oMyPerson->Set("email", "denis.flaven@hp.com"); + $iPersonId = $this->ObjectToDB($oMyPerson, true); + + $oMyPerson = MetaModel::NewObject("bizPerson"); + $oMyPerson->Set("name", "testemail3"); + $oMyPerson->Set("org_id", "1"); + $oMyPerson->Set("email", "erwan.taloc@hp.com"); + $iPersonId = $this->ObjectToDB($oMyPerson, true); + + $oMyServer = MetaModel::NewObject("bizServer"); + $oMyServer->Set("name", "wfr.terminator.com"); + $oMyServer->Set("severity", "low"); + $oMyServer->Set("status", "InStore"); + $oMyServer->Set("org_id", 2); + $oMyServer->Set("location_id", 2); + $iServerId = $this->ObjectToDB($oMyServer, true); + + $oMyTrigger = MetaModel::NewObject("TriggerOnStateEnter"); + $oMyTrigger->Set("description", "Testor"); + $oMyTrigger->Set("target_class", "bizServer"); + $oMyTrigger->Set("state", "Shipped"); + $iTriggerId = $this->ObjectToDB($oMyTrigger, true); + + // Error in OQL field(s) + // + $this->CreateEmailSpec + ( + $oMyTrigger, + 'test', + "SELECT bizPerson WHERE naime = 'Dali'", + "SELECT bizServer", + 'romain.quetiez@hp.com' + ); + + // Error: no recipient + // + $this->CreateEmailSpec + ( + $oMyTrigger, + 'test', + "", + "", + 'romain.quetiez@hp.com' + ); + + // Test + // + $this->CreateEmailSpec + ( + $oMyTrigger, + 'test', + "SELECT bizPerson WHERE name LIKE 'testemail%'", + "SELECT bizPerson", + 'romain.quetiez@hp.com' + ); + + // Test failing because of a wrong test recipient address + // + $this->CreateEmailSpec + ( + $oMyTrigger, + 'test', + "SELECT bizPerson WHERE name LIKE 'testemail%'", + "", + 'toto@walibi.bg' + ); + + // Normal behavior + // + $this->CreateEmailSpec + ( + $oMyTrigger, + 'enabled', + "SELECT bizPerson WHERE name LIKE 'testemail%'", + "", + 'romain.quetiez@hp.com' + ); + + // Does nothing, because it is disabled + // + $this->CreateEmailSpec + ( + $oMyTrigger, + 'disabled', + "SELECT bizPerson WHERE name = 'testemail%'", + "", + 'romain.quetiez@hp.com' + ); + + $oMyTrigger->DoActivate($oMyServer->ToArgs('this')); + + return true; + } +} ?> diff --git a/setup/email.test.php b/setup/email.test.php new file mode 100644 index 000000000..76df1e542 --- /dev/null +++ b/setup/email.test.php @@ -0,0 +1,184 @@ += 5.2.4 + { + $sPhpIniFile = php_ini_loaded_file(); + } + else + { + $sPhpIniFile = 'php.ini'; + } + + $bIsWindows = (array_key_exists('WINDIR', $_SERVER)); + if ($bIsWindows) + { + $sSmtpServer = ini_get('SMTP'); + if (empty($sSmtpServer)) + { + $oP->error("The SMTP server is not defined. Please add the 'SMTP' directive into $sPhpIniFile"); + $bRet = false; + } + else if (strcasecmp($sSmtpServer, 'localhost') == 0) + { + $oP->warning("Your SMTP server is configured to 'localhost'. You might want to set or change the 'SMTP' directive into $sPhpIniFile"); + } + else + { + $oP->info("Your SMTP server: $sSmtpServer. To change this value, modify the 'SMTP' directive into $sPhpIniFile"); + } + + $iSmtpPort = (int) ini_get('smtp_port'); + if (empty($iSmtpPort)) + { + $oP->info("The SMTP port is not defined. Please add the 'smtp_port' directive into $sPhpIniFile"); + $bRet = false; + } + else if ($iSmtpPort = 25) + { + $oP->info("Your SMTP port is configured to the default value: 25. You might want to set or change the 'smtp_port' directive into $sPhpIniFile"); + } + else + { + $oP->info("Your SMTP port is configured to $iSmtpPort. You might want to set or change the 'smtp_port' directive into $sPhpIniFile"); + } + } + else + { + // Not a windows system + } + if ($bRet) + { + $oP->ok("PHP settings are ok to proceed with a test of the email"); + } + return $bRet; +} + + +/** + * Display the form for the first step of the test wizard + * which consists in a basic check of the configuration and display of a form for testing + */ +function DisplayStep1(SetupWebPage $oP) +{ + $sNextOperation = 'step2'; + $oP->add("

iTop email test

\n"); + $oP->add("

Checking prerequisites

\n"); + if (CheckEmailSetting($oP)) + { + $sRedStar = '*'; + $oP->add("

Try to send an email

\n"); + $oP->add("\n"); + // Form goes here + $oP->add("
Test configuration\n"); + $aForm = array(); + $aForm[] = array( + 'label' => "To$sRedStar:", + 'input' => "", + 'help' => ' pure email address (john.foo@worldcompany.com)', + ); + $aForm[] = array( + 'label' => "From:", + 'input' => "", + 'help' => ' defaults to \'To\'', + ); + $oP->form($aForm); + $oP->add("
\n"); + $oP->add("\n"); + $oP->add("\n"); + $oP->add("
\n"); + } +} + +/** + * Display the form for the second step of the configuration wizard + * which consists in sending an email, which maybe a problem under Windows + */ +function DisplayStep2(SetupWebPage $oP, $sFrom, $sTo) +{ + //$sNextOperation = 'step3'; + $oP->add("

iTop configuration wizard

\n"); + $oP->add("

Step 2: send an email

\n"); + $oP->add("

Sending an email to '$sTo'... (From: '$sFrom')

\n"); + $oP->add("
\n"); + + $oEmail = new Email(); + $oEmail->SetRecipientTO($sTo); + $oEmail->SetRecipientFrom($sFrom); + $oEmail->SetSubject("Test iTop"); + $oEmail->SetBody("

Hello,

The email function is now working fine.

You may now be able to use the notification function.

iTop

"); + $aIssues = $oEmail->send(); + if (count($aIssues) > 0) + { + foreach ($aIssues as $sError) + { + $oP->error($sError); + } + $oP->add("\n"); + } + else + { + $oP->ok("The email has been sent, you may now check that the email will arrive..."); + } +} + +/** + * Main program + */ + +// #@# Init default timezone -> do not get a notice... to be improved !!! +// duplicated from 'attributedef.class.inc.php', needed here because mail() does +// generate a notice +date_default_timezone_set('Europe/Paris'); + + +try +{ + switch($sOperation) + { + case 'step1': + DisplayStep1($oP); + break; + + case 'step2': + $oP->no_cache(); + $sTo = Utils::ReadParam('to'); + $sFrom = Utils::ReadParam('from'); + if (strlen($sFrom) == 0) + { + $sFrom = $sTo; + } + DisplayStep2($oP, $sFrom, $sTo); + break; + + default: + $oP->error("Error: unsupported operation '$sOperation'"); + + } +} +catch(Exception $e) +{ + $oP->error("Error: '".$e->getMessage()."'"); +} +catch(CoreException $e) +{ + $oP->error("Error: '".$e->getHtmlDesc()."'"); +} +$oP->output(); +?> diff --git a/setup/setup.js b/setup/setup.js index 8c9e46008..de99764ed 100644 --- a/setup/setup.js +++ b/setup/setup.js @@ -77,6 +77,15 @@ function DoSubmit(sMsg, iStep) case 4: bResult = DoLoadDataAsynchronous(); + break; + + // Email test page + case 10: + if ($('#to').val() == '') + { + alert('Please specify a destination address'); + bResult = false; + } } if (bResult) { diff --git a/toolkit.php b/toolkit.php index 707bdb520..d816778e3 100644 --- a/toolkit.php +++ b/toolkit.php @@ -15,6 +15,7 @@ echo "

Itop consultant

\n"; echo "Check model, Create DB, Update DB (new class, new attribute)
\n"; echo "Backup and restore (shortcut)
\n"; echo "Objects schema (shortcut)
\n"; +echo "Setup the email
\n"; echo "

Web services

\n"; echo "Available functions
\n"; echo "WSDL (dynamically generated)
\n"; diff --git a/webservices/webservices.class.inc.php b/webservices/webservices.class.inc.php index 5595f7113..b525a6948 100644 --- a/webservices/webservices.class.inc.php +++ b/webservices/webservices.class.inc.php @@ -455,7 +455,8 @@ class WebServices { if ($oRes->IsOk()) { - if ($oTargetObj->CheckToInsert()) + list($bRes, $aIssues) = $oTargetObj->CheckToInsert(); + if ($bRes) { $iId = $oTargetObj->DBInsertTrackedNoReload($oChange); $oRes->LogInfo("Created object ".get_class($$oTargetObj)."::$iId");