Exemple #1
0
 public static function ResetCache($sEnvironmentId = null)
 {
     if (!function_exists('apc_delete')) {
         return;
     }
     if (is_null($sEnvironmentId)) {
         $sEnvironmentId = MetaModel::GetEnvironmentId();
     }
     $sAppIdentity = 'itop-' . $sEnvironmentId;
     Dict::ResetCache($sAppIdentity);
     foreach (self::GetCacheEntries($sEnvironmentId) as $sKey => $aAPCInfo) {
         $sAPCKey = $aAPCInfo['info'];
         apc_delete($sAPCKey);
     }
 }
 protected function GetSQLQuery($aOrderBy, $aArgs, $aAttToLoad, $aExtendedDataSpec, $iLimitCount, $iLimitStart, $bGetCount, $aGroupByExpr = null)
 {
     // Hide objects that are not visible to the current user
     //
     $oSearch = $this;
     if (!$this->IsAllDataAllowed() && !$this->IsDataFiltered()) {
         $oVisibleObjects = UserRights::GetSelectFilter($this->GetClass(), $this->GetModifierProperties('UserRightsGetSelectFilter'));
         if ($oVisibleObjects === false) {
             // Make sure this is a valid search object, saying NO for all
             $oVisibleObjects = DBObjectSearch::FromEmptySet($this->GetClass());
         }
         if (is_object($oVisibleObjects)) {
             $oSearch = $this->Intersect($oVisibleObjects);
             $oSearch->SetDataFiltered();
         } else {
             // should be true at this point, meaning that no additional filtering
             // is required
         }
     }
     // Compute query modifiers properties (can be set in the search itself, by the context, etc.)
     //
     $aModifierProperties = MetaModel::MakeModifierProperties($oSearch);
     // Create a unique cache id
     //
     if (self::$m_bQueryCacheEnabled || self::$m_bTraceQueries) {
         // Need to identify the query
         $sOqlQuery = $oSearch->ToOql();
         if (count($aModifierProperties)) {
             array_multisort($aModifierProperties);
             $sModifierProperties = json_encode($aModifierProperties);
         } else {
             $sModifierProperties = '';
         }
         $sRawId = $sOqlQuery . $sModifierProperties;
         if (!is_null($aAttToLoad)) {
             $sRawId .= json_encode($aAttToLoad);
         }
         if (!is_null($aGroupByExpr)) {
             foreach ($aGroupByExpr as $sAlias => $oExpr) {
                 $sRawId .= 'g:' . $sAlias . '!' . $oExpr->Render();
             }
         }
         $sRawId .= $bGetCount;
         $sOqlId = md5($sRawId);
     } else {
         $sOqlQuery = "SELECTING... " . $oSearch->GetClass();
         $sOqlId = "query id ? n/a";
     }
     // Query caching
     //
     if (self::$m_bQueryCacheEnabled) {
         // Warning: using directly the query string as the key to the hash array can FAIL if the string
         // is long and the differences are only near the end... so it's safer (but not bullet proof?)
         // to use a hash (like md5) of the string as the key !
         //
         // Example of two queries that were found as similar by the hash array:
         // SELECT SLT JOIN lnkSLTToSLA AS L1 ON L1.slt_id=SLT.id JOIN SLA ON L1.sla_id = SLA.id JOIN lnkContractToSLA AS L2 ON L2.sla_id = SLA.id JOIN CustomerContract ON L2.contract_id = CustomerContract.id WHERE SLT.ticket_priority = 1 AND SLA.service_id = 3 AND SLT.metric = 'TTO' AND CustomerContract.customer_id = 2
         // and
         // SELECT SLT JOIN lnkSLTToSLA AS L1 ON L1.slt_id=SLT.id JOIN SLA ON L1.sla_id = SLA.id JOIN lnkContractToSLA AS L2 ON L2.sla_id = SLA.id JOIN CustomerContract ON L2.contract_id = CustomerContract.id WHERE SLT.ticket_priority = 1 AND SLA.service_id = 3 AND SLT.metric = 'TTR' AND CustomerContract.customer_id = 2
         // the only difference is R instead or O at position 285 (TTR instead of TTO)...
         //
         if (array_key_exists($sOqlId, self::$m_aQueryStructCache)) {
             // hit!
             $oSQLQuery = unserialize(serialize(self::$m_aQueryStructCache[$sOqlId]));
             // Note: cloning is not enough because the subtree is made of objects
         } elseif (self::$m_bUseAPCCache) {
             // Note: For versions of APC older than 3.0.17, fetch() accepts only one parameter
             //
             $sOqlAPCCacheId = 'itop-' . MetaModel::GetEnvironmentId() . '-query-cache-' . $sOqlId;
             $oKPI = new ExecutionKPI();
             $result = apc_fetch($sOqlAPCCacheId);
             $oKPI->ComputeStats('Query APC (fetch)', $sOqlQuery);
             if (is_object($result)) {
                 $oSQLQuery = $result;
                 self::$m_aQueryStructCache[$sOqlId] = $oSQLQuery;
             }
         }
     }
     if (!isset($oSQLQuery)) {
         $oKPI = new ExecutionKPI();
         $oSQLQuery = $oSearch->MakeSQLQuery($aAttToLoad, $bGetCount, $aModifierProperties, $aGroupByExpr);
         $oSQLQuery->SetSourceOQL($sOqlQuery);
         $oKPI->ComputeStats('MakeSQLQuery', $sOqlQuery);
         if (self::$m_bQueryCacheEnabled) {
             if (self::$m_bUseAPCCache) {
                 $oKPI = new ExecutionKPI();
                 apc_store($sOqlAPCCacheId, $oSQLQuery, self::$m_iQueryCacheTTL);
                 $oKPI->ComputeStats('Query APC (store)', $sOqlQuery);
             }
             self::$m_aQueryStructCache[$sOqlId] = $oSQLQuery->DeepClone();
         }
     }
     // Join to an additional table, if required...
     //
     if ($aExtendedDataSpec != null) {
         $sTableAlias = '_extended_data_';
         $aExtendedFields = array();
         foreach ($aExtendedDataSpec['fields'] as $sColumn) {
             $sColRef = $oSearch->GetClassAlias() . '_extdata_' . $sColumn;
             $aExtendedFields[$sColRef] = new FieldExpressionResolved($sColumn, $sTableAlias);
         }
         $oSQLQueryExt = new SQLObjectQuery($aExtendedDataSpec['table'], $sTableAlias, $aExtendedFields);
         $oSQLQuery->AddInnerJoin($oSQLQueryExt, 'id', $aExtendedDataSpec['join_key']);
     }
     return $oSQLQuery;
 }
 protected function _DoExecute($oTrigger, $aContextArgs, &$oLog)
 {
     $sPreviousUrlMaker = ApplicationContext::SetUrlMakerClass();
     try {
         $this->m_iRecipients = 0;
         $this->m_aMailErrors = array();
         $bRes = false;
         // until we do succeed in sending the email
         // Determine recicipients
         //
         $sTo = $this->FindRecipients('to', $aContextArgs);
         $sCC = $this->FindRecipients('cc', $aContextArgs);
         $sBCC = $this->FindRecipients('bcc', $aContextArgs);
         $sFrom = MetaModel::ApplyParams($this->Get('from'), $aContextArgs);
         $sReplyTo = MetaModel::ApplyParams($this->Get('reply_to'), $aContextArgs);
         $sSubject = MetaModel::ApplyParams($this->Get('subject'), $aContextArgs);
         $sBody = MetaModel::ApplyParams($this->Get('body'), $aContextArgs);
         $oObj = $aContextArgs['this->object()'];
         $sMessageId = sprintf('iTop_%s_%d_%f@%s.openitop.org', get_class($oObj), $oObj->GetKey(), microtime(true), MetaModel::GetEnvironmentId());
         $sReference = '<' . $sMessageId . '>';
     } catch (Exception $e) {
         ApplicationContext::SetUrlMakerClass($sPreviousUrlMaker);
         throw $e;
     }
     ApplicationContext::SetUrlMakerClass($sPreviousUrlMaker);
     if (!is_null($oLog)) {
         // 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);
         }
     }
     $oEmail = new EMail();
     if ($this->IsBeingTested()) {
         $oEmail->SetSubject('TEST[' . $sSubject . ']');
         $sTestBody = $sBody;
         $sTestBody .= "<div style=\"border: dashed;\">\n";
         $sTestBody .= "<h1>Testing email notification " . $this->GetHyperlink() . "</h1>\n";
         $sTestBody .= "<p>The email should be sent with the following properties\n";
         $sTestBody .= "<ul>\n";
         $sTestBody .= "<li>TO: {$sTo}</li>\n";
         $sTestBody .= "<li>CC: {$sCC}</li>\n";
         $sTestBody .= "<li>BCC: {$sBCC}</li>\n";
         $sTestBody .= "<li>From: {$sFrom}</li>\n";
         $sTestBody .= "<li>Reply-To: {$sReplyTo}</li>\n";
         $sTestBody .= "<li>References: {$sReference}</li>\n";
         $sTestBody .= "</ul>\n";
         $sTestBody .= "</p>\n";
         $sTestBody .= "</div>\n";
         $oEmail->SetBody($sTestBody);
         $oEmail->SetRecipientTO($this->Get('test_recipient'));
         $oEmail->SetRecipientFrom($this->Get('test_recipient'));
         $oEmail->SetReferences($sReference);
         $oEmail->SetMessageId($sMessageId);
     } else {
         $oEmail->SetSubject($sSubject);
         $oEmail->SetBody($sBody);
         $oEmail->SetRecipientTO($sTo);
         $oEmail->SetRecipientCC($sCC);
         $oEmail->SetRecipientBCC($sBCC);
         $oEmail->SetRecipientFrom($sFrom);
         $oEmail->SetRecipientReplyTo($sReplyTo);
         $oEmail->SetReferences($sReference);
         $oEmail->SetMessageId($sMessageId);
     }
     if (isset($aContextArgs['attachments'])) {
         $aAttachmentReport = array();
         foreach ($aContextArgs['attachments'] as $oDocument) {
             $oEmail->AddAttachment($oDocument->GetData(), $oDocument->GetFileName(), $oDocument->GetMimeType());
             $aAttachmentReport[] = array($oDocument->GetFileName(), $oDocument->GetMimeType(), strlen($oDocument->GetData()));
         }
         $oLog->Set('attachments', $aAttachmentReport);
     }
     if (empty($this->m_aMailErrors)) {
         if ($this->m_iRecipients == 0) {
             return 'No recipient';
         } else {
             $iRes = $oEmail->Send($aErrors, false, $oLog);
             // allow asynchronous mode
             switch ($iRes) {
                 case EMAIL_SEND_OK:
                     return "Sent";
                 case EMAIL_SEND_PENDING:
                     return "Pending";
                 case EMAIL_SEND_ERROR:
                     return "Errors: " . implode(', ', $aErrors);
             }
         }
     } else {
         if (is_array($this->m_aMailErrors) && count($this->m_aMailErrors) > 0) {
             $sError = implode(', ', $this->m_aMailErrors);
         } else {
             $sError = 'Unknown reason';
         }
         return 'Notification was not sent: ' . $sError;
     }
 }