/** * @param array $cxn * @param string $entity * @param string $action * @param array $params * @return mixed */ public static function route($cxn, $entity, $action, $params) { $SUPER_PERM = array('administer CiviCRM'); require_once 'api/v3/utils.php'; // FIXME: Shouldn't the X-Forwarded-Proto check be part of CRM_Utils_System::isSSL()? if (CRM_Core_BAO_Setting::getItem(CRM_Core_BAO_Setting::SYSTEM_PREFERENCES_NAME, 'enableSSL') && !CRM_Utils_System::isSSL() && strtolower(CRM_Utils_Array::value('X_FORWARDED_PROTO', CRM_Utils_System::getRequestHeaders())) != 'https') { return civicrm_api3_create_error('System policy requires HTTPS.'); } // Note: $cxn and cxnId are authenticated before router is called. $dao = new CRM_Cxn_DAO_Cxn(); $dao->cxn_id = $cxn['cxnId']; if (empty($cxn['cxnId']) || !$dao->find(TRUE) || !$dao->cxn_id) { return civicrm_api3_create_error('Failed to lookup connection authorizations.'); } if (!$dao->is_active) { return civicrm_api3_create_error('Connection is inactive.'); } if (!is_string($entity) || !is_string($action) || !is_array($params)) { return civicrm_api3_create_error('API parameters are malformed.'); } if (empty($cxn['perm']['api']) || !is_array($cxn['perm']['api']) || empty($cxn['perm']['grant']) || !(is_array($cxn['perm']['grant']) || is_string($cxn['perm']['grant']))) { return civicrm_api3_create_error('Connection has no permissions.'); } $whitelist = \Civi\API\WhitelistRule::createAll($cxn['perm']['api']); \Civi::service('dispatcher')->addSubscriber(new \Civi\API\Subscriber\WhitelistSubscriber($whitelist)); CRM_Core_Config::singleton()->userPermissionTemp = new CRM_Core_Permission_Temp(); if ($cxn['perm']['grant'] === '*') { CRM_Core_Config::singleton()->userPermissionTemp->grant($SUPER_PERM); } else { CRM_Core_Config::singleton()->userPermissionTemp->grant($cxn['perm']['grant']); } $params['check_permissions'] = 'whitelist'; return civicrm_api($entity, $action, $params); }
/** * @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::service('angular'); $this->region = \CRM_Utils_Request::retrieve('snippet', 'String') ? 'ajax-snippet' : 'html-header'; }
/** * Get available api actions. * * @param array $apiRequest * * @return array * @throws API_Exception */ function civicrm_api3_generic_getActions($apiRequest) { civicrm_api3_verify_mandatory($apiRequest, NULL, array('entity')); $mfp = \Civi::service('magic_function_provider'); $actions = $mfp->getActionNames($apiRequest['version'], $apiRequest['entity']); return civicrm_api3_create_success($actions, $apiRequest['params'], $apiRequest['entity'], 'getactions'); }
/** * Version 3 wrapper for civicrm_api. * * Throws exception. * * @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. * * @throws CiviCRM_API3_Exception * @return array */ function civicrm_api3($entity, $action, $params = array()) { $params['version'] = 3; $result = \Civi::service('civi_api_kernel')->runSafe($entity, $action, $params); if (is_array($result) && !empty($result['is_error'])) { throw new CiviCRM_API3_Exception($result['error_message'], CRM_Utils_Array::value('error_code', $result, 'undefined'), $result); } return $result; }
/** * This virtual function is used to set the default values of * various form elements * * access public * * @return array * reference to the array of default values */ public function setDefaultValues() { // CRM-11761 retrieve user's activity filter preferences $defaults = array(); $userID = CRM_Core_Session::getLoggedInContactID(); if ($userID) { $defaults = Civi::service('settings_manager')->getBagByContact(NULL, $userID)->get('activity_tab_filter'); } return $defaults; }
public function setUp() { $this->useTransaction(TRUE); parent::setUp(); $this->modules = array('one' => new CRM_Core_Module('com.example.one', TRUE), 'two' => new CRM_Core_Module('com.example.two', TRUE)); // Testing on drupal-demo fails because some extensions have mgd ents. CRM_Core_DAO::singleValueQuery('DELETE FROM civicrm_managed'); $this->fixtures['com.example.one-foo'] = array('module' => 'com.example.one', 'name' => 'foo', 'entity' => 'CustomSearch', 'params' => array('version' => 3, 'class_name' => 'CRM_Example_One_Foo', 'is_reserved' => 1)); $this->fixtures['com.example.one-bar'] = array('module' => 'com.example.one', 'name' => 'bar', 'entity' => 'CustomSearch', 'params' => array('version' => 3, 'class_name' => 'CRM_Example_One_Bar', 'is_reserved' => 1)); $this->apiKernel = \Civi::service('civi_api_kernel'); $this->adhocProvider = new \Civi\API\Provider\AdhocProvider(3, 'CustomSearch'); $this->apiKernel->registerApiProvider($this->adhocProvider); }
/** * @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::service('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; }
/** * Convert a callback expression to a valid PHP callback. * * @param string|array $id * A callback expression; any of the following. * * @return array * A PHP callback. Do not serialize (b/c it may include an object). * @throws \RuntimeException */ public function get($id) { if (!is_string($id)) { // An array or object does not need to be further resolved. return $id; } if (strpos($id, '::') !== FALSE) { // Callback: Static method. return explode('::', $id); } elseif (strpos($id, '://') !== FALSE) { $url = parse_url($id); switch ($url['scheme']) { case 'obj': // Object: Lookup in container. return \Civi::service($url['host']); case 'call': // Callback: Object/method in container. $obj = \Civi::service($url['host']); return array($obj, ltrim($url['path'], '/')); case 'api3': // Callback: API. return new ResolverApi($url); case 'global': // Lookup in a global variable. return new ResolverGlobalCallback($url['query'], $url['host'] . (isset($url['path']) ? rtrim($url['path'], '/') : '')); default: throw new \RuntimeException("Unsupported callback scheme: " . $url['scheme']); } } elseif (in_array($id, array('0', '1'))) { // Callback: Constant value. return new ResolverConstantCallback((int) $id); } elseif ($id[0] >= 'A' && $id[0] <= 'Z') { // Object: New/default instance. return new $id(); } else { // Callback: Function. return $id; } }
/** * See class description. */ public function run() { /** * @var \Civi\Angular\Manager $angular */ $angular = \Civi::service('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(); }
/** * @param bool $triggerRebuild * @param bool $sessionReset * * @throws Exception */ public static function rebuildMenuAndCaches($triggerRebuild = FALSE, $sessionReset = FALSE) { $config = CRM_Core_Config::singleton(); $config->clearModuleList(); // also cleanup all caches $config->cleanupCaches($sessionReset || CRM_Utils_Request::retrieve('sessionReset', 'Boolean', CRM_Core_DAO::$_nullObject, FALSE, 0, 'GET')); CRM_Core_Menu::store(); // also reset navigation CRM_Core_BAO_Navigation::resetNavigation(); // also cleanup module permissions $config->cleanupPermissions(); // rebuild word replacement cache - pass false to prevent operations redundant with this fn CRM_Core_BAO_WordReplacement::rebuild(FALSE); Civi::service('settings_manager')->flush(); // Clear js caches CRM_Core_Resources::singleton()->flushStrings()->resetCacheCode(); CRM_Case_XMLRepository::singleton(TRUE); // also rebuild triggers if requested explicitly if ($triggerRebuild || CRM_Utils_Request::retrieve('triggerRebuild', 'Boolean', CRM_Core_DAO::$_nullObject, FALSE, 0, 'GET')) { CRM_Core_DAO::triggerRebuild(); } CRM_Core_DAO_AllCoreTables::reinitializeCache(TRUE); CRM_Core_ManagedEntities::singleton(TRUE)->reconcile(); //CRM-16257 update Config.IDS.ini might be an old copy CRM_Core_IDS::createConfigFile(TRUE); }
/** * 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::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::service('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; } } }
/** * 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::service('dispatcher')->dispatch("hook_civicrm_caseChange", $event); return self::singleton()->invoke(1, $angularModules, self::$_nullObject, self::$_nullObject, self::$_nullObject, self::$_nullObject, self::$_nullObject, 'civicrm_caseChange'); }
public static function getContactActivity() { $contactID = CRM_Utils_Type::escape($_GET['cid'], 'Integer'); $context = CRM_Utils_Type::escape(CRM_Utils_Array::value('context', $_GET), 'String'); $sortMapper = array(); foreach ($_GET['columns'] as $key => $value) { $sortMapper[$key] = $value['data']; } $offset = isset($_GET['start']) ? CRM_Utils_Type::escape($_GET['start'], 'Integer') : 0; $rowCount = isset($_GET['length']) ? CRM_Utils_Type::escape($_GET['length'], 'Integer') : 25; $sort = isset($_GET['order'][0]['column']) ? CRM_Utils_Array::value(CRM_Utils_Type::escape($_GET['order'][0]['column'], 'Integer'), $sortMapper) : NULL; $sortOrder = isset($_GET['order'][0]['dir']) ? CRM_Utils_Type::escape($_GET['order'][0]['dir'], 'String') : 'asc'; $params = $_GET; if ($sort && $sortOrder) { $params['sortBy'] = $sort . ' ' . $sortOrder; } $params['page'] = $offset / $rowCount + 1; $params['rp'] = $rowCount; $params['contact_id'] = $contactID; $params['context'] = $context; // get the contact activities $activities = CRM_Activity_BAO_Activity::getContactActivitySelector($params); foreach ($activities as $key => $value) { //Check if recurring activity if (!empty($value['is_recurring_activity'])) { $repeat = $value['is_recurring_activity']; $activities[$key]['activity_type'] .= '<br/><span class="bold">' . ts('Repeating (%1 of %2)', array(1 => $repeat[0], 2 => $repeat[1])) . '</span>'; } } // store the activity filter preference CRM-11761 $session = CRM_Core_Session::singleton(); $userID = $session->get('userID'); if ($userID) { $activityFilter = array('activity_type_filter_id' => empty($params['activity_type_id']) ? '' : CRM_Utils_Type::escape($params['activity_type_id'], 'Integer'), 'activity_type_exclude_filter_id' => empty($params['activity_type_exclude_id']) ? '' : CRM_Utils_Type::escape($params['activity_type_exclude_id'], 'Integer')); /** @var \Civi\Core\SettingsBag $cSettings */ $cSettings = Civi::service('settings_manager')->getBagByContact(CRM_Core_Config::domainID(), $userID); $cSettings->set('activity_tab_filter', $activityFilter); } CRM_Utils_JSON::output($activities); }
/** * Retrieve a mailer to send any mail from the application. * * @return Mail * @deprecated * @see Civi::service() */ public static function getMailer() { return Civi::service('pear_mail'); }
/** * Get a list of triggers for the contact table. * * @see hook_civicrm_triggerInfo * @see CRM_Core_DAO::triggerRebuild * @see http://issues.civicrm.org/jira/browse/CRM-10554 * * @param $info * @param null $tableName */ public static function triggerInfo(&$info, $tableName = NULL) { //during upgrade, first check for valid version and then create triggers //i.e the columns created_date and modified_date are introduced in 4.3.alpha1 so dont create triggers for older version if (CRM_Core_Config::isUpgradeMode()) { $currentVer = CRM_Core_BAO_Domain::version(TRUE); //if current version is less than 4.3.alpha1 dont create below triggers if (version_compare($currentVer, '4.3.alpha1') < 0) { return; } } // Update timestamp for civicrm_contact itself if ($tableName == NULL || $tableName == self::getTableName()) { $info[] = array('table' => array(self::getTableName()), 'when' => 'BEFORE', 'event' => array('INSERT'), 'sql' => "\nSET NEW.created_date = CURRENT_TIMESTAMP;\n"); } // Update timestamp when modifying closely related core tables $relatedTables = array('civicrm_address', 'civicrm_email', 'civicrm_im', 'civicrm_phone', 'civicrm_website'); self::generateTimestampTriggers($info, $tableName, $relatedTables, 'contact_id'); // Update timestamp when modifying related custom-data tables $customGroupTables = array(); $customGroupDAO = CRM_Core_BAO_CustomGroup::getAllCustomGroupsByBaseEntity('Contact'); $customGroupDAO->is_multiple = 0; $customGroupDAO->find(); while ($customGroupDAO->fetch()) { $customGroupTables[] = $customGroupDAO->table_name; } if (!empty($customGroupTables)) { self::generateTimestampTriggers($info, $tableName, $customGroupTables, 'entity_id'); } // Update phone table to populate phone_numeric field if (!$tableName || $tableName == 'civicrm_phone') { // Define stored sql function needed for phones $sqlTriggers = Civi::service('sql_triggers'); $sqlTriggers->enqueueQuery(self::DROP_STRIP_FUNCTION_43); $sqlTriggers->enqueueQuery(self::CREATE_STRIP_FUNCTION_43); $info[] = array('table' => array('civicrm_phone'), 'when' => 'BEFORE', 'event' => array('INSERT', 'UPDATE'), 'sql' => "\nSET NEW.phone_numeric = civicrm_strip_non_numeric(NEW.phone);\n"); } }
/** * 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. */ 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::service('pear_mail'); if (is_object($mailer)) { $errorScope = CRM_Core_TemporaryErrorScope::ignoreException(); $mailer->send($eq->email, $h, $b); unset($errorScope); } }
/** * 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::service('pear_mail'); if (is_object($mailer)) { $errorScope = CRM_Core_TemporaryErrorScope::ignoreException(); $mailer->send($email, $h, $b); unset($errorScope); } }
/** * Conditionally fire an event during the first page run. * * The install system is currently implemented several times, so it's hard to add * new installation logic. We use a poor-man's method to detect the first run. * * Situations to test: * - New installation * - Upgrade from an old version (predating first-run tracker) * - Upgrade from an old version (with first-run tracking) */ public function handleFirstRun() { // Ordinarily, we prefetch settings en masse and find that the system is already installed. // No extra SQL queries required. if (Civi::settings()->get('installed')) { return; } // Q: How should this behave during testing? if (defined('CIVICRM_TEST')) { return; } // If schema hasn't been loaded yet, then do nothing. Don't want to interfere // with the existing installers. NOTE: If we change the installer pageflow, // then we may want to modify this behavior. if (!CRM_Core_DAO::checkTableExists('civicrm_domain')) { return; } // If we're handling an upgrade, then the system has already been used, so this // is not the first run. if (CRM_Core_Config::isUpgradeMode()) { return; } $dao = CRM_Core_DAO::executeQuery('SELECT version FROM civicrm_domain'); while ($dao->fetch()) { if ($dao->version && version_compare($dao->version, CRM_Utils_System::version(), '<')) { return; } } // The installation flag is stored in civicrm_setting, which is domain-aware. The // flag could have been stored under a different domain. $dao = CRM_Core_DAO::executeQuery(' SELECT domain_id, value FROM civicrm_setting WHERE is_domain = 1 AND name = "installed" '); while ($dao->fetch()) { $value = unserialize($dao->value); if (!empty($value)) { Civi::settings()->set('installed', 1); return; } } // OK, this looks new. Civi::service('dispatcher')->dispatch(\Civi\Core\Event\SystemInstallEvent::EVENT_NAME, new \Civi\Core\Event\SystemInstallEvent()); Civi::settings()->set('installed', 1); }
/** * 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, CRM_Utils_Array::value('from', $params)); 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::service('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 testDefaults() { CRM_Core_DAO::executeQuery('DELETE FROM civicrm_setting WHERE name = "max_attachments"'); Civi::service('settings_manager')->flush(); $this->assertEquals(3, Civi::settings()->get('max_attachments')); $this->assertEquals(3, CRM_Core_Config::singleton()->maxAttachments); }
/** * Temporarily alter the settings-metadata to add a mock setting. * * WARNING: The setting metadata will disappear on the next cache-clear. * * @param $extras * @return void */ public function setMockSettingsMetaData($extras) { Civi::service('settings_manager')->flush(); CRM_Utils_Hook::singleton()->setHook('civicrm_alterSettingsMetaData', function (&$metadata, $domainId, $profile) use($extras) { $metadata = array_merge($metadata, $extras); }); $fields = $this->callAPISuccess('setting', 'getfields', array()); foreach ($extras as $key => $spec) { $this->assertNotEmpty($spec['title']); $this->assertEquals($spec['title'], $fields['values'][$key]['title']); } }
/** * @param $rev */ public function upgrade_4_4_1($rev) { $config = CRM_Core_Config::singleton(); // CRM-13327 upgrade handling for the newly added name badges $ogID = CRM_Core_DAO::getFieldValue('CRM_Core_DAO_OptionGroup', 'name_badge', 'id', 'name'); $nameBadges = array_flip(array_values(CRM_Core_BAO_OptionValue::getOptionValuesAssocArrayFromName('name_badge'))); unset($nameBadges['Avery 5395']); if (!empty($nameBadges)) { $dimension = '{"paper-size":"a4","orientation":"portrait","font-name":"times","font-size":6,"font-style":"","NX":2,"NY":4,"metric":"mm","lMargin":6,"tMargin":19,"SpaceX":0,"SpaceY":0,"width":100,"height":65,"lPadding":0,"tPadding":0}'; $query = "UPDATE civicrm_option_value\n SET value = '{$dimension}'\n WHERE option_group_id = %1 AND name = 'Fattorini Name Badge 100x65'"; CRM_Core_DAO::executeQuery($query, array(1 => array($ogID, 'Integer'))); } else { $dimensions = array(1 => '{"paper-size":"a4","orientation":"landscape","font-name":"times","font-size":6,"font-style":"","NX":2,"NY":1,"metric":"mm","lMargin":25,"tMargin":27,"SpaceX":0,"SpaceY":35,"width":106,"height":150,"lPadding":5,"tPadding":5}', 2 => '{"paper-size":"a4","orientation":"portrait","font-name":"times","font-size":6,"font-style":"","NX":2,"NY":4,"metric":"mm","lMargin":6,"tMargin":19,"SpaceX":0,"SpaceY":0,"width":100,"height":65,"lPadding":0,"tPadding":0}', 3 => '{"paper-size":"a4","orientation":"portrait","font-name":"times","font-size":6,"font-style":"","NX":2,"NY":2,"metric":"mm","lMargin":10,"tMargin":28,"SpaceX":0,"SpaceY":0,"width":96,"height":121,"lPadding":5,"tPadding":5}'); $insertStatements = array(1 => "({$ogID}, %1, '{$dimensions[1]}', %1, NULL, 0, NULL, 2, NULL, 0, 0, 1, NULL, NULL)", 2 => "({$ogID}, %2, '{$dimensions[2]}', %2, NULL, 0, NULL, 3, NULL, 0, 0, 1, NULL, NULL)", 3 => "({$ogID}, %3, '{$dimensions[3]}', %3, NULL, 0, NULL, 4, NULL, 0, 0, 1, NULL, NULL)"); $queryParams = array(1 => array('A6 Badge Portrait 150x106', 'String'), 2 => array('Fattorini Name Badge 100x65', 'String'), 3 => array('Hanging Badge 3-3/4" x 4-3"/4', 'String')); foreach ($insertStatements as $values) { $query = 'INSERT INTO civicrm_option_value (`option_group_id`, `label`, `value`, `name`, `grouping`, `filter`, `is_default`, `weight`, `description`, `is_optgroup`, `is_reserved`, `is_active`, `component_id`, `visibility_id`) VALUES' . $values; CRM_Core_DAO::executeQuery($query, $queryParams); } } // CRM-12578 - Prior to this version a CSS file under drupal would disable core css if (!empty($config->customCSSURL) && strpos($config->userFramework, 'Drupal') === 0) { // The new setting doesn't exist yet - need to create it first $sql = ' INSERT INTO civicrm_setting (group_name, name , value , domain_id , is_domain , created_date) VALUES (%1, %2, %3, %4, %5, now())'; CRM_Core_DAO::executeQuery($sql, array(1 => array(CRM_Core_BAO_Setting::SYSTEM_PREFERENCES_NAME, 'String'), 2 => array('disable_core_css', 'String'), 3 => array(serialize(1), 'String'), 4 => array(CRM_Core_Config::domainID(), 'Positive'), 5 => array(1, 'Int'))); Civi::service('settings_manager')->flush(); } // CRM-13701 - Fix $config->timeInputFormat $sql = "\n SELECT time_format\n FROM civicrm_preferences_date\n WHERE time_format IS NOT NULL\n AND time_format <> ''\n LIMIT 1\n "; $timeInputFormat = CRM_Core_DAO::singleValueQuery($sql); if ($timeInputFormat && $timeInputFormat != $config->timeInputFormat) { $params = array('timeInputFormat' => $timeInputFormat); CRM_Core_BAO_ConfigSetting::add($params); } // CRM-13698 - add 'Available' and 'No-show' activity statuses $insertStatus = array(); $nsinc = $avinc = $inc = 0; if (!CRM_Core_OptionGroup::getValue('activity_status', 'Available', 'name')) { $insertStatus[] = "(%1, 'Available', %2, 'Available', NULL, 0, NULL, %3, 0, 0, 1, NULL, NULL)"; $avinc = $inc = 1; } if (!CRM_Core_OptionGroup::getValue('activity_status', 'No_show', 'name')) { $insertStatus[] = "(%1, 'No-show', %4, 'No_show', NULL, 0, NULL, %5, 0, 0, 1, NULL, NULL)"; $nsinc = $inc + 1; } if (!empty($insertStatus)) { $acOptionGroupID = CRM_Core_DAO::getFieldValue('CRM_Core_DAO_OptionGroup', 'activity_status', 'id', 'name'); $maxVal = CRM_Core_DAO::singleValueQuery("SELECT MAX(ROUND(op.value)) FROM civicrm_option_value op WHERE op.option_group_id = {$acOptionGroupID}"); $maxWeight = CRM_Core_DAO::singleValueQuery("SELECT MAX(weight) FROM civicrm_option_value WHERE option_group_id = {$acOptionGroupID}"); $p[1] = array($acOptionGroupID, 'Integer'); if ($avinc) { $p[2] = array($avinc + $maxVal, 'Integer'); $p[3] = array($avinc + $maxWeight, 'Integer'); } if ($nsinc) { $p[4] = array($nsinc + $maxVal, 'Integer'); $p[5] = array($nsinc + $maxWeight, 'Integer'); } $insertStatus = implode(',', $insertStatus); $sql = "\nINSERT INTO\n civicrm_option_value (`option_group_id`, label, `value`, `name`, `grouping`, `filter`, `is_default`, `weight`, `is_optgroup`, `is_reserved`, `is_active`, `component_id`, `visibility_id`)\nVALUES {$insertStatus}"; CRM_Core_DAO::executeQuery($sql, $p); } $this->addTask(ts('Upgrade DB to %1: SQL', array(1 => '4.4.1')), 'runSql', $rev); $this->addTask('Patch word-replacement schema', 'wordReplacements_patch', $rev); }
public static function getContactActivity() { $requiredParameters = array('cid' => 'Integer'); $optionalParameters = array('context' => 'String', 'activity_type_id' => 'Integer', 'activity_type_exclude_id' => 'Integer'); $params = CRM_Core_Page_AJAX::defaultSortAndPagerParams(); $params += CRM_Core_Page_AJAX::validateParams($requiredParameters, $optionalParameters); // To be consistent, the cid parameter should be renamed to contact_id in // the template file, see templates/CRM/Activity/Selector/Selector.tpl $params['contact_id'] = $params['cid']; unset($params['cid']); // get the contact activities $activities = CRM_Activity_BAO_Activity::getContactActivitySelector($params); if (!empty($_GET['is_unit_test'])) { return $activities; } foreach ($activities['data'] as $key => $value) { // Check if recurring activity. if (!empty($value['is_recurring_activity'])) { $repeat = $value['is_recurring_activity']; $activities['data'][$key]['activity_type'] .= '<br/><span class="bold">' . ts('Repeating (%1 of %2)', array(1 => $repeat[0], 2 => $repeat[1])) . '</span>'; } } // store the activity filter preference CRM-11761 $session = CRM_Core_Session::singleton(); $userID = $session->get('userID'); if ($userID) { $activityFilter = array('activity_type_filter_id' => empty($params['activity_type_id']) ? '' : CRM_Utils_Type::escape($params['activity_type_id'], 'Integer'), 'activity_type_exclude_filter_id' => empty($params['activity_type_exclude_id']) ? '' : CRM_Utils_Type::escape($params['activity_type_exclude_id'], 'Integer')); /** * @var \Civi\Core\SettingsBag $cSettings */ $cSettings = Civi::service('settings_manager')->getBagByContact(CRM_Core_Config::domainID(), $userID); $cSettings->set('activity_tab_filter', $activityFilter); } CRM_Utils_JSON::output($activities); }
/** * Check permission to join onto another api entity * * @param string $entity * @param array $fieldStack * The stack of fields leading up to this join * @return bool */ private function checkPermissionToJoin($entity, $fieldStack) { if (!$this->checkPermissions) { return TRUE; } // Build an array of params that relate to the joined entity $params = array('version' => 3, 'return' => array(), 'check_permissions' => $this->checkPermissions); $prefix = implode('.', $fieldStack) . '.'; $len = strlen($prefix); foreach ($this->options['return'] as $key => $ret) { if (strpos($key, $prefix) === 0) { $params['return'][substr($key, $len)] = $ret; } } foreach ($this->params as $key => $param) { if (strpos($key, $prefix) === 0) { $params[substr($key, $len)] = $param; } } return \Civi::service('civi_api_kernel')->runAuthorize($entity, 'get', $params); }
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})"); } }
/** * 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::service('dispatcher')->dispatch("DAO::post-delete", $event); return $result; }
/** * Store an item in the setting table. * * _setItem() is the common logic shared by setItem() and setItems(). * * @param object $value * (required) The value that will be serialized and stored. * @param string $group * (required) The group name of the item. * @param string $name * (required) The name of the setting. * @param int $componentID * The optional component ID (so componenets can share the same name space). * @param int $contactID * @param int $createdID * An optional ID to assign the creator to. If not set, retrieved from session. * * @param int $domainID */ public static function setItem($value, $group, $name, $componentID = NULL, $contactID = NULL, $createdID = NULL, $domainID = NULL) { /** @var \Civi\Core\SettingsManager $manager */ $manager = \Civi::service('settings_manager'); $settings = $contactID === NULL ? $manager->getBagByDomain($domainID) : $manager->getBagByContact($domainID, $contactID); $settings->set($name, $value); }
/** * Drop triggers for all logged tables. * * @param string $tableName */ public function dropTriggers($tableName = NULL) { /** @var \Civi\Core\SqlTriggers $sqlTriggers */ $sqlTriggers = Civi::service('sql_triggers'); $dao = new CRM_Core_DAO(); if ($tableName) { $tableNames = array($tableName); } else { $tableNames = $this->tables; } foreach ($tableNames as $table) { $validName = CRM_Core_DAO::shortenSQLName($table, 48, TRUE); // before triggers $sqlTriggers->enqueueQuery("DROP TRIGGER IF EXISTS {$validName}_before_insert"); $sqlTriggers->enqueueQuery("DROP TRIGGER IF EXISTS {$validName}_before_update"); $sqlTriggers->enqueueQuery("DROP TRIGGER IF EXISTS {$validName}_before_delete"); // after triggers $sqlTriggers->enqueueQuery("DROP TRIGGER IF EXISTS {$validName}_after_insert"); $sqlTriggers->enqueueQuery("DROP TRIGGER IF EXISTS {$validName}_after_update"); $sqlTriggers->enqueueQuery("DROP TRIGGER IF EXISTS {$validName}_after_delete"); } // now lets also be safe and drop all triggers that start with // civicrm_ if we are dropping all triggers // we need to do this to capture all the leftover triggers since // we did the shortening trigger name for CRM-11794 if ($tableName === NULL) { $triggers = $dao->executeQuery("SHOW TRIGGERS LIKE 'civicrm_%'"); while ($triggers->fetch()) { $sqlTriggers->enqueueQuery("DROP TRIGGER IF EXISTS {$triggers->Trigger}"); } } }
/** * 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::service('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 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']) || !is_string($params['page'])) { throw new API_Exception("Invalid page"); } /** @var \Civi\Cxn\Rpc\RegistrationClient $client */ $client = \Civi::service('cxn_reg_client'); return $client->call($appMeta, 'Cxn', 'getlink', array('page' => $params['page'])); }