/** * @param string $title * Title of the page. * @param int $mode * Mode of the page. * @param \CRM_Core_Resources|null $res * Resource manager. */ public function __construct($title = NULL, $mode = NULL, $res = NULL) { parent::__construct($title, $mode); $this->res = \CRM_Core_Resources::singleton(); $this->angular = \Civi\Core\Container::singleton()->get('angular'); $this->region = \CRM_Utils_Request::retrieve('snippet', 'String') ? 'ajax-snippet' : 'html-header'; }
function tearDown() { parent::tearDown(); CRM_Core_DAO::singleValueQuery('DELETE FROM civicrm_managed'); CRM_Core_DAO::singleValueQuery('DELETE FROM civicrm_option_value WHERE name like "CRM_Example_%"'); \Civi\Core\Container::singleton(TRUE); }
/** * @param $apiRequest * * @return array * @throws API_Exception */ function civicrm_api3_generic_getActions($apiRequest) { civicrm_api3_verify_mandatory($apiRequest, NULL, array('entity')); $mfp = \Civi\Core\Container::singleton()->get('magic_function_provider'); $actions = $mfp->getActionNames($apiRequest['version'], $apiRequest['entity']); return civicrm_api3_create_success($actions); }
/** * @param $fields * * @return array|bool * @throws API_Exception */ public static function formRule($fields) { $errors = array(); require_once 'api/api.php'; /** @var \Civi\API\Kernel $apiKernel */ $apiKernel = \Civi\Core\Container::singleton()->get('civi_api_kernel'); $apiRequest = \Civi\API\Request::create($fields['api_entity'], $fields['api_action'], array('version' => 3), NULL); try { $apiKernel->resolve($apiRequest); } catch (\Civi\API\Exception\NotImplementedException $e) { $errors['api_action'] = ts('Given API command is not defined.'); } if (!empty($errors)) { return $errors; } return empty($errors) ? TRUE : $errors; }
/** * See class description. */ public function run() { /** * @var \Civi\Angular\Manager $angular */ $angular = \Civi\Core\Container::singleton()->get('angular'); $moduleNames = $this->parseModuleNames(\CRM_Utils_Request::retrieve('modules', 'String'), $angular); switch (\CRM_Utils_Request::retrieve('format', 'String')) { case 'json': case '': $this->send('application/javascript', json_encode($this->getMetadata($moduleNames, $angular))); break; case 'js': $this->send('application/javascript', $this->digestJs($angular->getResources($moduleNames, 'js', 'path'))); break; case 'css': $this->send('text/css', \CRM_Utils_File::concat($angular->getResources($moduleNames, 'css', 'path'), "\n")); break; default: \CRM_Core_Error::fatal("Unrecognized format"); } \CRM_Utils_System::civiExit(); }
/** * Singleton function used to manage this object. * * @param bool $loadFromDB * whether to load from the database. * @param bool $force * whether to force a reconstruction. * * @return CRM_Core_Config */ public static function &singleton($loadFromDB = TRUE, $force = FALSE) { if (self::$_singleton === NULL || $force) { $GLOBALS['civicrm_default_error_scope'] = CRM_Core_TemporaryErrorScope::create(array('CRM_Core_Error', 'handle')); $errorScope = CRM_Core_TemporaryErrorScope::create(array('CRM_Core_Error', 'simpleHandler')); if (defined('E_DEPRECATED')) { error_reporting(error_reporting() & ~E_DEPRECATED); } self::$_singleton = new CRM_Core_Config(); \Civi\Core\Container::boot($loadFromDB); if ($loadFromDB && self::$_singleton->dsn) { $domain = \CRM_Core_BAO_Domain::getDomain(); \CRM_Core_BAO_ConfigSetting::applyLocale(\Civi::settings($domain->id), $domain->locales); unset($errorScope); CRM_Utils_Hook::config(self::$_singleton); self::$_singleton->authenticate(); // Extreme backward compat: $config binds to active domain at moment of setup. self::$_singleton->getSettings(); Civi::service('settings_manager')->useDefaults(); } } return self::$_singleton; }
/** * Get information about fields for a given api request. * * Getfields information is used for documentation, validation, default setting * We first query the scheme using the $dao->fields function & then augment * that information by calling the _spec functions that apply to the relevant function * Note that we use 'unique' field names as described in the xml/schema files * for get requests & just field name for create. This is because some get functions * access multiple objects e.g. contact api accesses is_deleted from the activity * table & from the contact table * * @param array $apiRequest * Api request as an array. Keys are. * - entity: string * - action: string * - version: string * - function: callback (mixed) * - params: array, varies * * @param bool $unique * Determines whether to key by unique field names (only affects get-type) actions * * @return array * API success object */ function civicrm_api3_generic_getfields($apiRequest, $unique = TRUE) { static $results = array(); if (CRM_Utils_Array::value('cache_clear', $apiRequest['params'])) { $results = array(); // we will also clear pseudoconstants here - should potentially be moved to relevant BAO classes CRM_Core_PseudoConstant::flush(); if (!empty($apiRequest['params']['fieldname'])) { CRM_Utils_PseudoConstant::flushConstant($apiRequest['params']['fieldname']); } if (!empty($apiRequest['params']['option_group_id'])) { $optionGroupName = civicrm_api('option_group', 'getvalue', array('version' => 3, 'id' => $apiRequest['params']['option_group_id'], 'return' => 'name')); if (is_string($optionGroupName)) { CRM_Utils_PseudoConstant::flushConstant(_civicrm_api_get_camel_name($optionGroupName)); } } } $entity = $apiRequest['entity']; $lowercase_entity = _civicrm_api_get_entity_name_from_camel($entity); $subentity = CRM_Utils_Array::value('contact_type', $apiRequest['params']); $action = CRM_Utils_Array::value('action', $apiRequest['params']); $sequential = empty($apiRequest['params']['sequential']) ? 0 : 1; $apiRequest['params']['options'] = CRM_Utils_Array::value('options', $apiRequest['params'], array()); $optionsToResolve = (array) CRM_Utils_Array::value('get_options', $apiRequest['params']['options'], array()); if (!$action || $action == 'getvalue' || $action == 'getcount') { $action = 'get'; } // If no options, return results from cache if (!$apiRequest['params']['options'] && isset($results[$entity . $subentity]) && isset($action, $results[$entity . $subentity]) && isset($action, $results[$entity . $subentity][$sequential])) { return $results[$entity . $subentity][$action][$sequential]; } // defaults based on data model and API policy switch ($action) { case 'getfields': $values = _civicrm_api_get_fields($entity, FALSE, $apiRequest['params']); return civicrm_api3_create_success($values, $apiRequest['params'], $entity, 'getfields'); case 'create': case 'update': case 'replace': $unique = FALSE; case 'get': case 'getsingle': case 'getcount': case 'getstat': $metadata = _civicrm_api_get_fields($apiRequest['entity'], $unique, $apiRequest['params']); if (empty($metadata['id'])) { // if id is not set we will set it eg. 'id' from 'case_id', case_id will be an alias if (!empty($metadata[strtolower($apiRequest['entity']) . '_id'])) { $metadata['id'] = $metadata[$lowercase_entity . '_id']; unset($metadata[$lowercase_entity . '_id']); $metadata['id']['api.aliases'] = array($lowercase_entity . '_id'); } } else { // really the preference would be to set the unique name in the xml // question is which is a less risky fix this close to a release - setting in xml for the known failure // (note) or setting for all api where fields is returning 'id' & we want to accept 'note_id' @ the api layer // nb we don't officially accept note_id anyway - rationale here is more about centralising a now-tested // inconsistency $metadata['id']['api.aliases'] = array($lowercase_entity . '_id'); } break; case 'delete': $metadata = array('id' => array('title' => $entity . ' ID', 'api.required' => 1, 'api.aliases' => array($lowercase_entity . '_id'), 'type' => CRM_Utils_Type::T_INT)); break; // Note: adding setvalue case here instead of in a generic spec function because // some APIs override the generic setvalue fn which causes the generic spec to be overlooked. // Note: adding setvalue case here instead of in a generic spec function because // some APIs override the generic setvalue fn which causes the generic spec to be overlooked. case 'setvalue': $metadata = array('field' => array('title' => 'Field name', 'api.required' => 1, 'type' => CRM_Utils_Type::T_STRING), 'id' => array('title' => $entity . ' ID', 'api.required' => 1, 'type' => CRM_Utils_Type::T_INT), 'value' => array('title' => 'Value', 'description' => "Field value to set", 'api.required' => 1)); if (array_intersect(array('all', 'field'), $optionsToResolve)) { $options = civicrm_api3_generic_getfields(array('entity' => $entity, array('params' => array('action' => 'create')))); $metadata['field']['options'] = CRM_Utils_Array::collect('title', $options['values']); } break; default: // oddballs are on their own $metadata = array(); } // Normalize this for the sake of spec funcions $apiRequest['params']['options']['get_options'] = $optionsToResolve; // find any supplemental information $hypApiRequest = array('entity' => $apiRequest['entity'], 'action' => $action, 'version' => $apiRequest['version']); try { list($apiProvider, $hypApiRequest) = \Civi\Core\Container::singleton()->get('civi_api_kernel')->resolve($hypApiRequest); if (isset($hypApiRequest['function'])) { $helper = '_' . $hypApiRequest['function'] . '_spec'; } else { // not implemented MagicFunctionProvider $helper = NULL; } } catch (\Civi\API\Exception\NotImplementedException $e) { $helper = NULL; } if (function_exists($helper)) { // alter $helper($metadata, $apiRequest); } foreach ($metadata as $fieldname => $fieldSpec) { // Ensure 'name' is set if (!isset($fieldSpec['name'])) { $metadata[$fieldname]['name'] = $fieldname; } _civicrm_api3_generic_get_metadata_options($metadata, $apiRequest, $fieldname, $fieldSpec); // Convert options to "sequential" format if ($sequential && !empty($metadata[$fieldname]['options'])) { $metadata[$fieldname]['options'] = CRM_Utils_Array::makeNonAssociative($metadata[$fieldname]['options']); } } $results[$entity][$action][$sequential] = civicrm_api3_create_success($metadata, $apiRequest['params'], $entity, 'getfields'); return $results[$entity][$action][$sequential]; }
/** * @param CRM_Core_DAO_ActionSchedule $schedule * @param \Civi\ActionSchedule\Mapping $mapping * @return \Civi\Token\TokenProcessor */ protected static function createTokenProcessor($schedule, $mapping) { $tp = new \Civi\Token\TokenProcessor(\Civi\Core\Container::singleton()->get('dispatcher'), array('controller' => __CLASS__, 'actionSchedule' => $schedule, 'actionMapping' => $mapping, 'smarty' => TRUE)); $tp->addMessage('body_text', $schedule->body_text, 'text/plain'); $tp->addMessage('body_html', $schedule->body_html, 'text/html'); $tp->addMessage('sms_body_text', $schedule->sms_body_text, 'text/plain'); $tp->addMessage('subject', $schedule->subject, 'text/plain'); return $tp; }
/** * Send a response email informing the contact of the groups from which he. * has been unsubscribed. * * @param string $queue_id * The queue event ID. * @param array $groups * List of group IDs. * @param bool $is_domain * Is this domain-level?. * @param int $job * The job ID. * * @return void */ public static function send_unsub_response($queue_id, $groups, $is_domain = FALSE, $job) { $config = CRM_Core_Config::singleton(); $domain = CRM_Core_BAO_Domain::getDomain(); $jobObject = new CRM_Mailing_BAO_MailingJob(); $jobTable = $jobObject->getTableName(); $mailingObject = new CRM_Mailing_DAO_Mailing(); $mailingTable = $mailingObject->getTableName(); $contactsObject = new CRM_Contact_DAO_Contact(); $contacts = $contactsObject->getTableName(); $emailObject = new CRM_Core_DAO_Email(); $email = $emailObject->getTableName(); $queueObject = new CRM_Mailing_Event_BAO_Queue(); $queue = $queueObject->getTableName(); //get the default domain email address. list($domainEmailName, $domainEmailAddress) = CRM_Core_BAO_Domain::getNameAndEmail(); $dao = new CRM_Mailing_BAO_Mailing(); $dao->query(" SELECT * FROM {$mailingTable}\n INNER JOIN {$jobTable} ON\n {$jobTable}.mailing_id = {$mailingTable}.id\n WHERE {$jobTable}.id = {$job}"); $dao->fetch(); $component = new CRM_Mailing_BAO_Component(); if ($is_domain) { $component->id = $dao->optout_id; } else { $component->id = $dao->unsubscribe_id; } $component->find(TRUE); $html = $component->body_html; if ($component->body_text) { $text = $component->body_text; } else { $text = CRM_Utils_String::htmlToText($component->body_html); } $eq = new CRM_Core_DAO(); $eq->query("SELECT {$contacts}.preferred_mail_format as format,\n {$contacts}.id as contact_id,\n {$email}.email as email,\n {$queue}.hash as hash\n FROM {$contacts}\n INNER JOIN {$queue} ON {$queue}.contact_id = {$contacts}.id\n INNER JOIN {$email} ON {$queue}.email_id = {$email}.id\n WHERE {$queue}.id = " . CRM_Utils_Type::escape($queue_id, 'Integer')); $eq->fetch(); if ($groups) { foreach ($groups as $key => $value) { if (!$value) { unset($groups[$key]); } } } $message = new Mail_mime("\n"); list($addresses, $urls) = CRM_Mailing_BAO_Mailing::getVerpAndUrls($job, $queue_id, $eq->hash, $eq->email); $bao = new CRM_Mailing_BAO_Mailing(); $bao->body_text = $text; $bao->body_html = $html; $tokens = $bao->getTokens(); if ($eq->format == 'HTML' || $eq->format == 'Both') { $html = CRM_Utils_Token::replaceDomainTokens($html, $domain, TRUE, $tokens['html']); $html = CRM_Utils_Token::replaceUnsubscribeTokens($html, $domain, $groups, TRUE, $eq->contact_id, $eq->hash); $html = CRM_Utils_Token::replaceActionTokens($html, $addresses, $urls, TRUE, $tokens['html']); $html = CRM_Utils_Token::replaceMailingTokens($html, $dao, NULL, $tokens['html']); $message->setHTMLBody($html); } if (!$html || $eq->format == 'Text' || $eq->format == 'Both') { $text = CRM_Utils_Token::replaceDomainTokens($text, $domain, FALSE, $tokens['text']); $text = CRM_Utils_Token::replaceUnsubscribeTokens($text, $domain, $groups, FALSE, $eq->contact_id, $eq->hash); $text = CRM_Utils_Token::replaceActionTokens($text, $addresses, $urls, FALSE, $tokens['text']); $text = CRM_Utils_Token::replaceMailingTokens($text, $dao, NULL, $tokens['text']); $message->setTxtBody($text); } $emailDomain = CRM_Core_BAO_MailSettings::defaultDomain(); $headers = array('Subject' => $component->subject, 'From' => "\"{$domainEmailName}\" <do-not-reply@{$emailDomain}>", 'To' => $eq->email, 'Reply-To' => "do-not-reply@{$emailDomain}", 'Return-Path' => "do-not-reply@{$emailDomain}"); CRM_Mailing_BAO_Mailing::addMessageIdHeader($headers, 'u', $job, $queue_id, $eq->hash); $b = CRM_Utils_Mail::setMimeParams($message); $h = $message->headers($headers); $mailer = \Civi\Core\Container::singleton()->get('pear_mail'); if (is_object($mailer)) { $errorScope = CRM_Core_TemporaryErrorScope::ignoreException(); $mailer->send($eq->email, $h, $b); unset($errorScope); } }
/** * Initiate all pending/ready jobs * * @param array $testParams * @param null $mode * * @return void */ public static function runJobs($testParams = NULL, $mode = NULL) { $job = new CRM_Mailing_BAO_MailingJob(); $config = CRM_Core_Config::singleton(); $jobTable = CRM_Mailing_DAO_MailingJob::getTableName(); $mailingTable = CRM_Mailing_DAO_Mailing::getTableName(); if (!empty($testParams)) { $query = "\n SELECT *\n FROM {$jobTable}\n WHERE id = {$testParams['job_id']}"; $job->query($query); } else { $currentTime = date('YmdHis'); $mailingACL = CRM_Mailing_BAO_Mailing::mailingACL('m'); $domainID = CRM_Core_Config::domainID(); $modeClause = 'AND m.sms_provider_id IS NULL'; if ($mode == 'sms') { $modeClause = 'AND m.sms_provider_id IS NOT NULL'; } // Select the first child job that is scheduled // CRM-6835 $query = "\n SELECT j.*\n FROM {$jobTable} j,\n {$mailingTable} m\n WHERE m.id = j.mailing_id AND m.domain_id = {$domainID}\n {$modeClause}\n AND j.is_test = 0\n AND ( ( j.start_date IS null\n AND j.scheduled_date <= {$currentTime}\n AND j.status = 'Scheduled' )\n OR ( j.status = 'Running'\n AND j.end_date IS null ) )\n AND (j.job_type = 'child')\n AND {$mailingACL}\n ORDER BY j.mailing_id,\n j.id\n "; $job->query($query); } while ($job->fetch()) { // still use job level lock for each child job $lock = Civi\Core\Container::singleton()->get('lockManager')->acquire("data.mailing.job.{$job->id}"); if (!$lock->isAcquired()) { continue; } // for test jobs we do not change anything, since its on a short-circuit path if (empty($testParams)) { // we've got the lock, but while we were waiting and processing // other emails, this job might have changed under us // lets get the job status again and check $job->status = CRM_Core_DAO::getFieldValue('CRM_Mailing_DAO_MailingJob', $job->id, 'status', 'id', TRUE); if ($job->status != 'Running' && $job->status != 'Scheduled') { // this includes Cancelled and other statuses, CRM-4246 $lock->release(); continue; } } /* Queue up recipients for the child job being launched */ if ($job->status != 'Running') { $transaction = new CRM_Core_Transaction(); // have to queue it up based on the offset and limits // get the parent ID, and limit and offset $job->queue($testParams); // Mark up the starting time $saveJob = new CRM_Mailing_DAO_MailingJob(); $saveJob->id = $job->id; $saveJob->start_date = date('YmdHis'); $saveJob->status = 'Running'; $saveJob->save(); $transaction->commit(); } // Get the mailer if ($mode === NULL) { $mailer = \Civi\Core\Container::singleton()->get('pear_mail'); } elseif ($mode == 'sms') { $mailer = CRM_SMS_Provider::singleton(array('mailing_id' => $job->mailing_id)); } // Compose and deliver each child job $isComplete = $job->deliver($mailer, $testParams); CRM_Utils_Hook::post('create', 'CRM_Mailing_DAO_Spool', $job->id, $isComplete); // Mark the child complete if ($isComplete) { /* Finish the job */ $transaction = new CRM_Core_Transaction(); $saveJob = new CRM_Mailing_DAO_MailingJob(); $saveJob->id = $job->id; $saveJob->end_date = date('YmdHis'); $saveJob->status = 'Complete'; $saveJob->save(); $transaction->commit(); // don't mark the mailing as complete } // Release the child joblock $lock->release(); if ($testParams) { return $isComplete; } } }
/** * Send an automated response. * * @param object $mailing * The mailing object. * @param int $queue_id * The queue ID. * @param string $replyto * Optional reply-to from the reply. * * @return void */ private static function autoRespond(&$mailing, $queue_id, $replyto) { $config = CRM_Core_Config::singleton(); $contacts = CRM_Contact_DAO_Contact::getTableName(); $email = CRM_Core_DAO_Email::getTableName(); $queue = CRM_Mailing_Event_DAO_Queue::getTableName(); $eq = new CRM_Core_DAO(); $eq->query("SELECT {$contacts}.preferred_mail_format as format,\n {$email}.email as email,\n {$queue}.job_id as job_id,\n {$queue}.hash as hash\n FROM {$contacts}\n INNER JOIN {$queue} ON {$queue}.contact_id = {$contacts}.id\n INNER JOIN {$email} ON {$queue}.email_id = {$email}.id\n WHERE {$queue}.id = " . CRM_Utils_Type::escape($queue_id, 'Integer')); $eq->fetch(); $to = empty($replyto) ? $eq->email : $replyto; $component = new CRM_Mailing_BAO_Component(); $component->id = $mailing->reply_id; $component->find(TRUE); $message = new Mail_Mime("\n"); $domain = CRM_Core_BAO_Domain::getDomain(); list($domainEmailName, $_) = CRM_Core_BAO_Domain::getNameAndEmail(); $emailDomain = CRM_Core_BAO_MailSettings::defaultDomain(); $headers = array('Subject' => $component->subject, 'To' => $to, 'From' => "\"{$domainEmailName}\" <do-not-reply@{$emailDomain}>", 'Reply-To' => "do-not-reply@{$emailDomain}", 'Return-Path' => "do-not-reply@{$emailDomain}"); /* TODO: do we need reply tokens? */ $html = $component->body_html; if ($component->body_text) { $text = $component->body_text; } else { $text = CRM_Utils_String::htmlToText($component->body_html); } $bao = new CRM_Mailing_BAO_Mailing(); $bao->body_text = $text; $bao->body_html = $html; $tokens = $bao->getTokens(); if ($eq->format == 'HTML' || $eq->format == 'Both') { $html = CRM_Utils_Token::replaceDomainTokens($html, $domain, TRUE, $tokens['html']); $html = CRM_Utils_Token::replaceMailingTokens($html, $mailing, NULL, $tokens['html']); $message->setHTMLBody($html); } if (!$html || $eq->format == 'Text' || $eq->format == 'Both') { $text = CRM_Utils_Token::replaceDomainTokens($text, $domain, FALSE, $tokens['text']); $text = CRM_Utils_Token::replaceMailingTokens($text, $mailing, NULL, $tokens['text']); $message->setTxtBody($text); } $b = CRM_Utils_Mail::setMimeParams($message); $h = $message->headers($headers); CRM_Mailing_BAO_Mailing::addMessageIdHeader($h, 'a', $eq->job_id, queue_id, $eq->hash); $mailer = \Civi\Core\Container::singleton()->get('pear_mail'); if (is_object($mailer)) { $errorScope = CRM_Core_TemporaryErrorScope::ignoreException(); $mailer->send($to, $h, $b); unset($errorScope); } }
/** * @param string $entity * type of entities to deal with * @param string $action * create, get, delete or some special action name. * @param array $params * array to be passed to function * @param null $extra * * @return array|int */ function civicrm_api($entity, $action, $params, $extra = NULL) { return \Civi\Core\Container::singleton()->get('civi_api_kernel')->run($entity, $action, $params, $extra); }
/** * This hook fires whenever a record in a case changes. * * @param \Civi\CCase\Analyzer $analyzer */ public static function caseChange(\Civi\CCase\Analyzer $analyzer) { $event = new \Civi\CCase\Event\CaseChangeEvent($analyzer); \Civi\Core\Container::singleton()->get('dispatcher')->dispatch("hook_civicrm_caseChange", $event); return self::singleton()->invoke(1, $angularModules, self::$_nullObject, self::$_nullObject, self::$_nullObject, self::$_nullObject, self::$_nullObject, 'civicrm_caseChange'); }
/** * * @param array $params * @return array * @throws Exception */ function civicrm_api3_cxn_getcfg($params) { $result = array('CIVICRM_CXN_CA' => defined('CIVICRM_CXN_CA') ? CIVICRM_CXN_CA : NULL, 'CIVICRM_CXN_VIA' => defined('CIVICRM_CXN_VIA') ? CIVICRM_CXN_VIA : NULL, 'CIVICRM_CXN_APPS_URL' => defined('CIVICRM_CXN_APPS_URL') ? CIVICRM_CXN_APPS_URL : NULL, 'siteCallbackUrl' => CRM_Cxn_BAO_Cxn::getSiteCallbackUrl()); return civicrm_api3_create_success($result); $cxnId = _civicrm_api3_cxn_parseCxnId($params); $appMeta = CRM_Cxn_BAO_Cxn::getAppMeta($cxnId); if (empty($params['page']) || !is_string($params['page'])) { throw new API_Exception("Invalid page"); } /** @var \Civi\Cxn\Rpc\RegistrationClient $client */ $client = \Civi\Core\Container::singleton()->get('cxn_reg_client'); return $client->call($appMeta, 'Cxn', 'getlink', array('page' => $params['page'])); }
/** * @param string $title * Title of the page. * @param int $mode * Mode of the page. * @param \CRM_Core_Resources|null $res * Resource manager. */ public function __construct($title = NULL, $mode = NULL, $res = NULL) { parent::__construct($title, $mode); $this->res = \CRM_Core_Resources::singleton(); $this->angular = \Civi\Core\Container::singleton()->get('angular'); }
/** * Wrapper function to send mail in CiviCRM. Hooks are called from this function. The input parameter * is an associateive array which holds the values of field needed to send an email. These are: * * from : complete from envelope * toName : name of person to send email * toEmail : email address to send to * cc : email addresses to cc * bcc : email addresses to bcc * subject : subject of the email * text : text of the message * html : html version of the message * replyTo : reply-to header in the email * attachments: an associative array of * fullPath : complete pathname to the file * mime_type: mime type of the attachment * cleanName: the user friendly name of the attachmment * * @param array $params * (by reference). * * @return bool * TRUE if a mail was sent, else FALSE. */ public static function send(&$params) { $returnPath = CRM_Core_BAO_MailSettings::defaultReturnPath(); $includeMessageId = CRM_Core_BAO_MailSettings::includeMessageId(); $emailDomain = CRM_Core_BAO_MailSettings::defaultDomain(); $from = CRM_Utils_Array::value('from', $params); if (!$returnPath) { $returnPath = self::pluckEmailFromHeader($from); } $params['returnPath'] = $returnPath; // first call the mail alter hook CRM_Utils_Hook::alterMailParams($params); // check if any module has aborted mail sending if (!empty($params['abortMailSend']) || empty($params['toEmail'])) { return FALSE; } $textMessage = CRM_Utils_Array::value('text', $params); $htmlMessage = CRM_Utils_Array::value('html', $params); $attachments = CRM_Utils_Array::value('attachments', $params); // CRM-6224 if (trim(CRM_Utils_String::htmlToText($htmlMessage)) == '') { $htmlMessage = FALSE; } $headers = array(); // CRM-10699 support custom email headers if (!empty($params['headers'])) { $headers = array_merge($headers, $params['headers']); } $headers['From'] = $params['from']; $headers['To'] = self::formatRFC822Email(CRM_Utils_Array::value('toName', $params), CRM_Utils_Array::value('toEmail', $params), FALSE); $headers['Cc'] = CRM_Utils_Array::value('cc', $params); $headers['Bcc'] = CRM_Utils_Array::value('bcc', $params); $headers['Subject'] = CRM_Utils_Array::value('subject', $params); $headers['Content-Type'] = $htmlMessage ? 'multipart/mixed; charset=utf-8' : 'text/plain; charset=utf-8'; $headers['Content-Disposition'] = 'inline'; $headers['Content-Transfer-Encoding'] = '8bit'; $headers['Return-Path'] = CRM_Utils_Array::value('returnPath', $params); // CRM-11295: Omit reply-to headers if empty; this avoids issues with overzealous mailservers $replyTo = CRM_Utils_Array::value('replyTo', $params, $from); if (!empty($replyTo)) { $headers['Reply-To'] = $replyTo; } $headers['Date'] = date('r'); if ($includeMessageId) { $headers['Message-ID'] = '<' . uniqid('civicrm_', TRUE) . "@{$emailDomain}>"; } if (!empty($params['autoSubmitted'])) { $headers['Auto-Submitted'] = "Auto-Generated"; } //make sure we has to have space, CRM-6977 foreach (array('From', 'To', 'Cc', 'Bcc', 'Reply-To', 'Return-Path') as $fld) { if (isset($headers[$fld])) { $headers[$fld] = str_replace('"<', '" <', $headers[$fld]); } } // quote FROM, if comma is detected AND is not already quoted. CRM-7053 if (strpos($headers['From'], ',') !== FALSE) { $from = explode(' <', $headers['From']); $headers['From'] = self::formatRFC822Email($from[0], substr(trim($from[1]), 0, -1), TRUE); } require_once 'Mail/mime.php'; $msg = new Mail_mime("\n"); if ($textMessage) { $msg->setTxtBody($textMessage); } if ($htmlMessage) { $msg->setHTMLBody($htmlMessage); } if (!empty($attachments)) { foreach ($attachments as $fileID => $attach) { $msg->addAttachment($attach['fullPath'], $attach['mime_type'], $attach['cleanName']); } } $message = self::setMimeParams($msg); $headers =& $msg->headers($headers); $to = array($params['toEmail']); $result = NULL; $mailer = \Civi\Core\Container::singleton()->get('pear_mail'); // Mail_smtp and Mail_sendmail mailers require Bcc anc Cc emails // be included in both $to and $headers['Cc', 'Bcc'] if (get_class($mailer) != "Mail_mail") { //get emails from headers, since these are //combination of name and email addresses. if (!empty($headers['Cc'])) { $to[] = CRM_Utils_Array::value('Cc', $headers); } if (!empty($headers['Bcc'])) { $to[] = CRM_Utils_Array::value('Bcc', $headers); } } if (is_object($mailer)) { $errorScope = CRM_Core_TemporaryErrorScope::ignoreException(); $result = $mailer->send($to, $headers, $message); if (is_a($result, 'PEAR_Error')) { $message = self::errorMessage($mailer, $result); // append error message in case multiple calls are being made to // this method in the course of sending a batch of messages. CRM_Core_Session::setStatus($message, ts('Mailing Error'), 'error'); return FALSE; } // CRM-10699 CRM_Utils_Hook::postEmailSend($params); return TRUE; } return FALSE; }
public function tearDown() { parent::tearDown(); \Civi\Core\Container::singleton(TRUE); }
/** * Ask a contact for subscription confirmation (opt-in) * * @param string $email * The email address. * * @return void */ public function send_confirm_request($email) { $config = CRM_Core_Config::singleton(); $domain = CRM_Core_BAO_Domain::getDomain(); //get the default domain email address. list($domainEmailName, $domainEmailAddress) = CRM_Core_BAO_Domain::getNameAndEmail(); $localpart = CRM_Core_BAO_MailSettings::defaultLocalpart(); $emailDomain = CRM_Core_BAO_MailSettings::defaultDomain(); $confirm = implode($config->verpSeparator, array($localpart . 'c', $this->contact_id, $this->id, $this->hash)) . "@{$emailDomain}"; $group = new CRM_Contact_BAO_Group(); $group->id = $this->group_id; $group->find(TRUE); $component = new CRM_Mailing_BAO_Component(); $component->is_default = 1; $component->is_active = 1; $component->component_type = 'Subscribe'; $component->find(TRUE); $headers = array('Subject' => $component->subject, 'From' => "\"{$domainEmailName}\" <{$domainEmailAddress}>", 'To' => $email, 'Reply-To' => $confirm, 'Return-Path' => "do-not-reply@{$emailDomain}"); $url = CRM_Utils_System::url('civicrm/mailing/confirm', "reset=1&cid={$this->contact_id}&sid={$this->id}&h={$this->hash}", TRUE); $html = $component->body_html; if ($component->body_text) { $text = $component->body_text; } else { $text = CRM_Utils_String::htmlToText($component->body_html); } $bao = new CRM_Mailing_BAO_Mailing(); $bao->body_text = $text; $bao->body_html = $html; $tokens = $bao->getTokens(); $html = CRM_Utils_Token::replaceDomainTokens($html, $domain, TRUE, $tokens['html']); $html = CRM_Utils_Token::replaceSubscribeTokens($html, $group->title, $url, TRUE); $text = CRM_Utils_Token::replaceDomainTokens($text, $domain, FALSE, $tokens['text']); $text = CRM_Utils_Token::replaceSubscribeTokens($text, $group->title, $url, FALSE); // render the & entities in text mode, so that the links work $text = str_replace('&', '&', $text); $message = new Mail_mime("\n"); $message->setHTMLBody($html); $message->setTxtBody($text); $b = CRM_Utils_Mail::setMimeParams($message); $h = $message->headers($headers); CRM_Mailing_BAO_Mailing::addMessageIdHeader($h, 's', $this->contact_id, $this->id, $this->hash); $mailer = \Civi\Core\Container::singleton()->get('pear_mail'); if (is_object($mailer)) { $errorScope = CRM_Core_TemporaryErrorScope::ignoreException(); $mailer->send($email, $h, $b); unset($errorScope); } }
/** * Deletes items from table which match current objects variables. * * Returns the true on success * * for example * * Designed to be extended * * $object = new mytable(); * $object->ID=123; * echo $object->delete(); // builds a conditon * * $object = new mytable(); * $object->whereAdd('age > 12'); * $object->limit(1); * $object->orderBy('age DESC'); * $object->delete(true); // dont use object vars, use the conditions, limit and order. * * @param bool $useWhere (optional) If DB_DATAOBJECT_WHEREADD_ONLY is passed in then * we will build the condition only using the whereAdd's. Default is to * build the condition only using the object parameters. * * * @return mixed Int (No. of rows affected) on success, false on failure, 0 on no data affected */ public function delete($useWhere = FALSE) { $result = parent::delete($useWhere); $event = new \Civi\Core\DAO\Event\PostDelete($this, $result); \Civi\Core\Container::singleton()->get('dispatcher')->dispatch("DAO::post-delete", $event); return $result; }
/** * * @param array $params * Array with keys: * - cxn_guid OR app_guid: string. * - page: string. * @return array * @throws Exception */ function civicrm_api3_cxn_getlink($params) { $cxnId = _civicrm_api3_cxn_parseCxnId($params); $appMeta = CRM_Cxn_BAO_Cxn::getAppMeta($cxnId); if (empty($params['page_name']) || !is_string($params['page_name'])) { throw new API_Exception("Invalid page"); } /** @var \Civi\Cxn\Rpc\RegistrationClient $client */ $client = \Civi\Core\Container::singleton()->get('cxn_reg_client'); return $client->call($appMeta, 'Cxn', 'getlink', array('page' => $params['page_name'])); }
public function __get($k) { if (!isset($this->map[$k])) { throw new \CRM_Core_Exception("Cannot read unrecognized property CRM_Core_Config::\${$k}."); } if (isset($this->cache[$k])) { return $this->cache[$k]; } $type = $this->map[$k][0]; $name = isset($this->map[$k][1]) ? $this->map[$k][1] : $k; switch ($type) { case 'setting': return $this->getSettings()->get($name); case 'setting-path': // Array(0 => $type, 1 => $setting, 2 => $actions). $value = $this->getSettings()->get($name); $value = Civi::paths()->getPath($value); if ($value) { $value = CRM_Utils_File::addTrailingSlash($value); if (isset($this->map[$k][2]) && in_array('mkdir', $this->map[$k][2])) { CRM_Utils_File::createDir($value); } if (isset($this->map[$k][2]) && in_array('restrict', $this->map[$k][2])) { CRM_Utils_File::restrictAccess($value); } } $this->cache[$k] = $value; return $value; case 'setting-url-abs': $value = $this->getSettings()->get($name); $this->cache[$k] = Civi::paths()->getUrl($value, 'absolute'); return $this->cache[$k]; case 'setting-url-rel': $value = $this->getSettings()->get($name); $this->cache[$k] = Civi::paths()->getUrl($value, 'relative'); return $this->cache[$k]; case 'runtime': return \Civi\Core\Container::getBootService('runtime')->{$name}; case 'boot-svc': $this->cache[$k] = \Civi\Core\Container::getBootService($name); return $this->cache[$k]; case 'local': $this->initLocals(); return $this->locals[$name]; case 'user-system': $userSystem = \Civi\Core\Container::getBootService('userSystem'); $this->cache[$k] = call_user_func(array($userSystem, $name)); return $this->cache[$k]; case 'service': return \Civi::service($name); case 'callback': // Array(0 => $type, 1 => $obj, 2 => $getter, 3 => $setter, 4 => $unsetter). if (!isset($this->map[$k][1], $this->map[$k][2])) { throw new \CRM_Core_Exception("Cannot find getter for property CRM_Core_Config::\${$k}"); } return \Civi\Core\Resolver::singleton()->call(array($this->map[$k][1], $this->map[$k][2]), array($k)); default: throw new \CRM_Core_Exception("Cannot read property CRM_Core_Config::\${$k} ({$type})"); } }
protected function tearDown() { parent::tearDown(); $this->cleanupFiles(); \Civi\Core\Container::singleton(TRUE); }
/** * Fetch a service from the container. * * @param string $id * The service ID. * @return mixed */ public static function service($id) { return \Civi\Core\Container::singleton()->get($id); }
/** * Obtain the domain settings. * * @param int|null $domainID * For the default domain, leave $domainID as NULL. * @return \Civi\Core\SettingsBag */ public static function settings($domainID = NULL) { return \Civi\Core\Container::getBootService('settings_manager')->getBagByDomain($domainID); }