/** * Return the next X messages from the mail store * FIXME: in CiviCRM 2.2 this always returns all the emails * * @param int $count number of messages to fetch FIXME: ignored in CiviCRM 2.2 (assumed to be 0, i.e., fetch all) * @return array array of ezcMail objects */ function fetchNext($count = 0) { $mails = array(); $path = rtrim($this->_dir, DIRECTORY_SEPARATOR); if ($this->_debug) { print "fetching {$count} messages\n"; } $directory = new DirectoryIterator($path); foreach ($directory as $entry) { if ($entry->isDot()) { continue; } if (count($mails) >= $count) { break; } $file = $path . DIRECTORY_SEPARATOR . $entry->getFilename(); if ($this->_debug) { print "retrieving message {$file}\n"; } $set = new ezcMailFileSet(array($file)); $parser = new ezcMailParser(); $mail = $parser->parseMail($set); if (!$mail) { return CRM_Core_Error::createAPIError(ts('%1 could not be parsed', array(1 => $file))); } $mails[$file] = $mail[0]; } if ($this->_debug && count($mails) <= 0) { print "No messages found\n"; } return $mails; }
/** * Return the next X messages from the mail store * * @param int $count number of messages to fetch FIXME: ignored in CiviCRM 2.2 (assumed to be 0, i.e., fetch all) * * @return array array of ezcMail objects */ function fetchNext($count = 0) { $mails = array(); if ($this->_debug) { print "fetching {$count} messages\n"; } $query = "SELECT * FROM mailgun_events WHERE processed = 0 AND ignored = 0"; $query_params = array(); if ($count > 0) { $query .= " LIMIT %1"; $query_params[1] = array($count, 'Int'); } $dao = CRM_Core_DAO::executeQuery($query, $query_params); while ($dao->fetch()) { $set = new ezcMailVariableSet($dao->email); $parser = new ezcMailParser(); //set property text attachment as file CRM-5408 $parser->options->parseTextAttachmentsAsFiles = TRUE; $mail = $parser->parseMail($set); if (!$mail) { return CRM_Core_Error::createAPIError(ts('Email ID %1 could not be parsed', array(1 => $dao->id))); } $mails[$dao->id] = $mail[0]; } if ($this->_debug && count($mails) <= 0) { print "No messages found\n"; } return $mails; }
/** * Create an activity for a case via email * * @param int $file email sent * * @return array|void $activity object of newly creted activity via email@access public */ static function recordActivityViaEmail($file) { if (!file_exists($file) || !is_readable($file)) { return CRM_Core_Error::fatal(ts('File %1 does not exist or is not readable', array(1 => $file))); } $result = CRM_Utils_Mail_Incoming::parse($file); if ($result['is_error']) { return $result; } foreach ($result['to'] as $to) { $caseId = NULL; $emailPattern = '/^([A-Z0-9._%+-]+)\\+([\\d]+)@[A-Z0-9.-]+\\.[A-Z]{2,4}$/i'; $replacement = preg_replace($emailPattern, '$2', $to['email']); if ($replacement !== $to['email']) { $caseId = $replacement; //if caseId is invalid, return as error file if (!CRM_Core_DAO::getFieldValue('CRM_Case_DAO_Case', $caseId, 'id')) { return CRM_Core_Error::createAPIError(ts('Invalid case ID ( %1 ) in TO: field.', array(1 => $caseId))); } } else { continue; } // TODO: May want to replace this with a call to getRelatedAndGlobalContacts() when this feature is revisited. // (Or for efficiency call the global one outside the loop and then union with this each time.) $contactDetails = self::getRelatedContacts($caseId, TRUE); if (!empty($contactDetails[$result['from']['id']])) { $params = array(); $params['subject'] = $result['subject']; $params['activity_date_time'] = $result['date']; $params['details'] = $result['body']; $params['source_contact_id'] = $result['from']['id']; $params['status_id'] = CRM_Core_OptionGroup::getValue('activity_status', 'Completed', 'name'); $details = CRM_Case_PseudoConstant::caseActivityType(); $matches = array(); preg_match('/^\\W+([a-zA-Z0-9_ ]+)(\\W+)?\\n/i', $result['body'], $matches); if (!empty($matches) && isset($matches[1])) { $activityType = trim($matches[1]); if (isset($details[$activityType])) { $params['activity_type_id'] = $details[$activityType]['id']; } } if (!isset($params['activity_type_id'])) { $params['activity_type_id'] = CRM_Core_OptionGroup::getValue('activity_type', 'Inbound Email', 'name'); } // create activity $activity = CRM_Activity_BAO_Activity::create($params); $caseParams = array('activity_id' => $activity->id, 'case_id' => $caseId); self::processCaseActivity($caseParams); } else { return CRM_Core_Error::createAPIError(ts('FROM email contact %1 doesn\'t have a relationship to the referenced case.', array(1 => $result['from']['email']))); } } }
/** * @param $file * * @return array * @throws Exception */ public function &parse(&$file) { // check that the file exists and has some content if (!file_exists($file) || !trim(file_get_contents($file))) { return CRM_Core_Error::createAPIError(ts('%1 does not exists or is empty', array(1 => $file))); } require_once 'ezc/Base/src/ezc_bootstrap.php'; require_once 'ezc/autoload/mail_autoload.php'; // explode email to digestable format $set = new ezcMailFileSet(array($file)); $parser = new ezcMailParser(); $mail = $parser->parseMail($set); if (!$mail) { return CRM_Core_Error::createAPIError(ts('%1 could not be parsed', array(1 => $file))); } // since we only have one fileset $mail = $mail[0]; $mailParams = self::parseMailingObject($mail); return $mailParams; }
/** * Take in an array of entityID, custom_ID * and gets the value from the appropriate table. * * To get the values of custom fields with IDs 13 and 43 for contact ID 1327, use: * $params = array( 'entityID' => 1327, 'custom_13' => 1, 'custom_43' => 1 ); * * Entity Type will be inferred by the custom fields you request * Specify $params['entityType'] if you do not supply any custom fields to return * and entity type is other than Contact * * @array $params * * @param array $params * * @throws Exception * @return array */ public static function &getValues(&$params) { if (empty($params)) { return NULL; } if (!isset($params['entityID']) || CRM_Utils_Type::escape($params['entityID'], 'Integer', FALSE) === NULL) { return CRM_Core_Error::createAPIError(ts('entityID needs to be set and of type Integer')); } // first collect all the ids. The format is: // custom_ID $fieldIDs = array(); foreach ($params as $n => $v) { $key = $idx = NULL; if (substr($n, 0, 7) == 'custom_') { $idx = substr($n, 7); if (CRM_Utils_Type::escape($idx, 'Integer', FALSE) === NULL) { return CRM_Core_Error::createAPIError(ts('field ID needs to be of type Integer for index %1', array(1 => $idx))); } $fieldIDs[] = (int) $idx; } } $default = array('Contact', 'Individual', 'Household', 'Organization'); if (!($type = CRM_Utils_Array::value('entityType', $params)) || in_array($params['entityType'], $default)) { $type = NULL; } else { $entities = CRM_Core_SelectValues::customGroupExtends(); if (!array_key_exists($type, $entities)) { if (in_array($type, $entities)) { $type = $entities[$type]; if (in_array($type, $default)) { $type = NULL; } } else { return CRM_Core_Error::createAPIError(ts('Invalid entity type') . ': "' . $type . '"'); } } } $values = self::getEntityValues($params['entityID'], $type, $fieldIDs); if (empty($values)) { // note that this behaviour is undesirable from an API point of view - it should return an empty array // since this is also called by the merger code & not sure the consequences of changing // are just handling undoing this in the api layer. ie. converting the error back into a success $result = array('is_error' => 1, 'error_message' => 'No values found for the specified entity ID and custom field(s).'); return $result; } else { $result = array('is_error' => 0, 'entityID' => $params['entityID']); foreach ($values as $id => $value) { $result["custom_{$id}"] = $value; } return $result; } }
/** * Function to take in an array of entityID, custom_ID * and gets the value from the appropriate table. * * To get the values of custom fields with IDs 13 and 43 for contact ID 1327, use: * $params = array( 'entityID' => 1327, 'custom_13' => 1, 'custom_43' => 1 ); * * @array $params * * @return array * @static */ static function &getValues(&$params) { if (!isset($params['entityID']) || CRM_Utils_Type::escape($params['entityID'], 'Integer', false) === null) { return CRM_Core_Error::createAPIError(ts('entityID needs to be set and of type Integer')); } // first collect all the ids. The format is: // custom_ID $fieldsIDs = array(); foreach ($params as $n => $v) { $key = $idx = null; if (substr($n, 0, 7) == 'custom_') { $idx = substr($n, 7); if (CRM_Utils_Type::escape($idx, 'Integer', false) === null) { return CRM_Core_Error::createAPIError(ts('field ID needs to be of type Integer for index %1', array(1 => $idx))); } $fieldIDs[] = (int) $idx; } } $values = self::getEntityValues($params['entityID'], null, $fieldIDs); if (empty($values)) { return CRM_Core_Error::createAPIError(ts('No values found for the specified entity ID and custom field(s).')); } else { $result = array('is_error' => 0, 'entityID' => $params['entityID']); foreach ($values as $id => $value) { $result["custom_{$id}"] = $value; } return $result; } }
/** * Convert an email file to an activity */ function civicrm_activity_processemail($file, $activityTypeID, $result = array()) { // do not parse if result array already passed (towards EmailProcessor..) if (empty($result)) { // might want to check that email is ok here if (!file_exists($file) || !is_readable($file)) { return CRM_Core_Error::createAPIError(ts('File %1 does not exist or is not readable', array(1 => $file))); } } require_once 'CRM/Utils/Mail/Incoming.php'; $result = CRM_Utils_Mail_Incoming::parse($file); if ($result['is_error']) { return $result; } $params = _civicrm_activity_buildmailparams($result, $activityTypeID); return civicrm_activity_create($params); }
/** * * @param <type> $msg * @param <type> $data * @return <type> */ function &civicrm_create_error($msg, $data = null) { return CRM_Core_Error::createAPIError($msg, $data); }