/** * Generate a query to locate recipients who match the given * schedule. * * @param \CRM_Core_DAO_ActionSchedule $schedule * The schedule as configured by the administrator. * @param string $phase * See, e.g., RecipientBuilder::PHASE_RELATION_FIRST. * @return \CRM_Utils_SQL_Select * @see RecipientBuilder * @throws \CRM_Core_Exception */ public function createQuery($schedule, $phase, $defaultParams) { $selectedValues = (array) \CRM_Utils_Array::explodePadded($schedule->entity_value); $selectedStatuses = (array) \CRM_Utils_Array::explodePadded($schedule->entity_status); $query = \CRM_Utils_SQL_Select::from("{$this->entity} e")->param($defaultParams); $query['casAddlCheckFrom'] = 'civicrm_activity e'; $query['casContactIdField'] = 'r.contact_id'; $query['casEntityIdField'] = 'e.id'; $query['casContactTableAlias'] = NULL; $query['casDateField'] = 'e.activity_date_time'; if (!is_null($schedule->limit_to)) { $activityContacts = \CRM_Core_OptionGroup::values('activity_contacts', FALSE, FALSE, FALSE, NULL, 'name'); if ($schedule->limit_to == 0 || !isset($activityContacts[$schedule->recipient])) { $recipientTypeId = \CRM_Utils_Array::key('Activity Targets', $activityContacts); } else { $recipientTypeId = $schedule->recipient; } $query->join('r', "INNER JOIN civicrm_activity_contact r ON r.activity_id = e.id AND record_type_id = {$recipientTypeId}"); } // build where clause if (!empty($selectedValues)) { $query->where("e.activity_type_id IN (#selectedValues)")->param('selectedValues', $selectedValues); } else { $query->where("e.activity_type_id IS NULL"); } if (!empty($selectedStatuses)) { $query->where("e.status_id IN (#selectedStatuss)")->param('selectedStatuss', $selectedStatuses); } $query->where('e.is_current_revision = 1 AND e.is_deleted = 0'); return $query; }
/** * Create a default participant line item. * * @todo this should be done in the BAO not the api * * @param array $params * @param $participant * * @throws \CiviCRM_API3_Exception */ function _civicrm_api3_participant_createlineitem(&$params, $participant) { // it is possible that a fee level contains information about multiple // price field values. $priceFieldValueDetails = CRM_Utils_Array::explodePadded($params["fee_level"]); foreach ($priceFieldValueDetails as $detail) { if (preg_match('/- ([0-9]+)$/', $detail, $matches)) { // it is possible that a price field value is payd for multiple times. // (FIXME: if the price field value ends in minus followed by whitespace // and a number, things will go wrong.) $qty = $matches[1]; preg_match('/^(.*) - [0-9]+$/', $detail, $matches); $label = $matches[1]; } else { $label = $detail; $qty = 1; } $sql = "\n SELECT ps.id AS setID, pf.id AS priceFieldID, pfv.id AS priceFieldValueID, pfv.amount AS amount\n FROM civicrm_price_set_entity cpse\n LEFT JOIN civicrm_price_set ps ON cpse.price_set_id = ps.id AND cpse.entity_id = %1 AND cpse.entity_table = 'civicrm_event'\n LEFT JOIN civicrm_price_field pf ON pf.`price_set_id` = ps.id\n LEFT JOIN civicrm_price_field_value pfv ON pfv.price_field_id = pf.id\n where ps.id is not null and pfv.label = %2\n "; $qParams = array(1 => array($params['event_id'], 'Integer'), 2 => array($label, 'String')); $dao = CRM_Core_DAO::executeQuery($sql, $qParams); if ($dao->fetch()) { $lineItemParams = array('price_field_id' => $dao->priceFieldID, 'price_field_value_id' => $dao->priceFieldValueID, 'entity_table' => 'civicrm_participant', 'entity_id' => $participant->id, 'label' => $label, 'qty' => $qty, 'participant_count' => 0, 'unit_price' => $dao->amount, 'line_total' => $qty * $dao->amount); civicrm_api3('line_item', 'create', $lineItemParams); } } }
/** * Generate a query to locate recipients who match the given * schedule. * * @param \CRM_Core_DAO_ActionSchedule $schedule * The schedule as configured by the administrator. * @param string $phase * See, e.g., RecipientBuilder::PHASE_RELATION_FIRST. * @param array $defaultParams * * @return \CRM_Utils_SQL_Select * @see RecipientBuilder */ public function createQuery($schedule, $phase, $defaultParams) { $selectedValues = (array) \CRM_Utils_Array::explodePadded($schedule->entity_value); $selectedStatuses = (array) \CRM_Utils_Array::explodePadded($schedule->entity_status); $query = \CRM_Utils_SQL_Select::from("{$this->entity} e")->param($defaultParams); $query['casAddlCheckFrom'] = 'civicrm_membership e'; $query['casContactIdField'] = 'e.contact_id'; $query['casEntityIdField'] = 'e.id'; $query['casContactTableAlias'] = NULL; $query['casDateField'] = str_replace('membership_', 'e.', $schedule->start_action_date); // FIXME: Numbers should be constants. if (in_array(2, $selectedStatuses)) { //auto-renew memberships $query->where("e.contribution_recur_id IS NOT NULL"); } elseif (in_array(1, $selectedStatuses)) { $query->where("e.contribution_recur_id IS NULL"); } if (!empty($selectedValues)) { $query->where("e.membership_type_id IN (@memberTypeValues)")->param('memberTypeValues', $selectedValues); } else { $query->where("e.membership_type_id IS NULL"); } $query->where("( e.is_override IS NULL OR e.is_override = 0 )"); $query->merge($this->prepareMembershipPermissionsFilter()); $query->where("e.status_id IN (#memberStatus)")->param('memberStatus', \CRM_Member_PseudoConstant::membershipStatus(NULL, "(is_current_member = 1 OR name = 'Expired')", 'id')); // Why is this only for civicrm_membership? if ($schedule->start_action_date && $schedule->is_repeat == FALSE) { $query['casUseReferenceDate'] = TRUE; } return $query; }
/** * Use this API to create a new group. * * The 'extends' value accepts an array or a comma separated string. * e.g array( * 'Individual','Contact') or 'Individual,Contact' * See the CRM Data Model for custom_group property definitions * $params['class_name'] is a required field, class being extended. * * @param array $params * Array per getfields metadata. * * @return array * @todo $params['extends'] is array format - is that std compatible */ function civicrm_api3_custom_group_create($params) { if (isset($params['extends']) && is_string($params['extends'])) { $extends = explode(",", $params['extends']); unset($params['extends']); $params['extends'] = $extends; } if (!isset($params['extends'][0]) || !trim($params['extends'][0])) { return civicrm_api3_create_error("First item in params['extends'] must be a class name (e.g. 'Contact')."); } if (isset($params['extends_entity_column_value']) && !is_array($params['extends_entity_column_value'])) { // BAO fails if this is a string, but API getFields says this must be a string, so we'll do a double backflip $params['extends_entity_column_value'] = CRM_Utils_Array::explodePadded($params['extends_entity_column_value']); } return _civicrm_api3_basic_create(_civicrm_api3_get_BAO(__FUNCTION__), $params); }
/** * Use this API to create a new group. The 'extends' value accepts an array or a comma separated string. * e.g array( 'Individual','Contact') or 'Individual,Contact' * See the CRM Data Model for custom_group property definitions * $params['class_name'] is a required field, class being extended. * * @param $params array Associative array of property name/value pairs to insert in group. * {@getfields CustomGroup_create} * * @return Newly create custom_group object * @todo $params['extends'] is array format - is that std compatible * @access public */ function civicrm_api3_custom_group_create($params) { if (isset($params['extends']) && is_string($params['extends'])) { $extends = explode(",", $params['extends']); unset($params['extends']); $params['extends'] = $extends; } if (!isset($params['extends'][0]) || !trim($params['extends'][0])) { return civicrm_api3_create_error("First item in params['extends'] must be a class name (e.g. 'Contact')."); } if (isset($params['extends_entity_column_value']) && !is_array($params['extends_entity_column_value'])) { // BAO fails if this is a string, but API getFields says this must be a string, so we'll do a double backflip $params['extends_entity_column_value'] = CRM_Utils_Array::explodePadded($params['extends_entity_column_value']); } $customGroup = CRM_Core_BAO_CustomGroup::create($params); _civicrm_api3_object_to_array($customGroup, $values[$customGroup->id]); return civicrm_api3_create_success($values, $params, 'custom_group', $customGroup); }
/** * Generate a query to locate recipients who match the given * schedule. * * @param \CRM_Core_DAO_ActionSchedule $schedule * The schedule as configured by the administrator. * @param string $phase * See, e.g., RecipientBuilder::PHASE_RELATION_FIRST. * @param array $defaultParams * * @return \CRM_Utils_SQL_Select * @see RecipientBuilder */ public function createQuery($schedule, $phase, $defaultParams) { $selectedValues = (array) \CRM_Utils_Array::explodePadded($schedule->entity_value); $selectedStatuses = (array) \CRM_Utils_Array::explodePadded($schedule->entity_status); $query = \CRM_Utils_SQL_Select::from("{$this->entity} e")->param($defaultParams); $query['casAddlCheckFrom'] = 'civicrm_event r'; $query['casContactIdField'] = 'e.contact_id'; $query['casEntityIdField'] = 'e.id'; $query['casContactTableAlias'] = NULL; $query['casDateField'] = str_replace('event_', 'r.', $schedule->start_action_date); $query->join('r', 'INNER JOIN civicrm_event r ON e.event_id = r.id'); if ($schedule->recipient_listing && $schedule->limit_to) { switch ($schedule->recipient) { case 'participant_role': $query->where("e.role_id IN (#recipList)")->param('recipList', \CRM_Utils_Array::explodePadded($schedule->recipient_listing)); break; default: break; } } // build where clause if (!empty($selectedValues)) { $valueField = $this->id == \CRM_Event_ActionMapping::EVENT_TYPE_MAPPING_ID ? 'event_type_id' : 'id'; $query->where("r.{$valueField} IN (@selectedValues)")->param('selectedValues', $selectedValues); } else { $query->where($this->id == \CRM_Event_ActionMapping::EVENT_TYPE_MAPPING_ID ? "r.event_type_id IS NULL" : "r.id IS NULL"); } $query->where('r.is_active = 1'); $query->where('r.is_template = 0'); // participant status criteria not to be implemented for additional recipients // ... why not? if (!empty($selectedStatuses)) { switch ($phase) { case RecipientBuilder::PHASE_RELATION_FIRST: case RecipientBuilder::PHASE_RELATION_REPEAT: $query->where("e.status_id IN (#selectedStatuses)")->param('selectedStatuses', $selectedStatuses); break; } } return $query; }
/** * Convert IDs to values and format for display. * * @param HTML_QuickForm_element $field */ public static function preProcessEntityRef($field) { $val = $field->getValue(); // Temporarily convert string values to an array if (!is_array($val)) { // Try to auto-detect method of serialization $val = strpos($val, ',') ? explode(',', str_replace(', ', ',', $val)) : (array) CRM_Utils_Array::explodePadded($val); } if ($val) { $entity = $field->getAttribute('data-api-entity'); // Get api params, ensure it is an array $params = $field->getAttribute('data-api-params'); $params = $params ? json_decode($params, TRUE) : array(); $result = civicrm_api3($entity, 'getlist', array('id' => $val) + $params); if ($field->isFrozen()) { // Prevent js from treating frozen entityRef as a "live" field $field->removeAttribute('class'); } if (!empty($result['values'])) { $field->setAttribute('data-entity-value', json_encode($result['values'])); } // CRM-15803 - Remove invalid values $val = array_intersect($val, CRM_Utils_Array::collect('id', $result['values'])); } // Convert array values back to a string $field->setValue(implode(',', $val)); }
/** * Store and return an array of all active custom fields. * * @param string $customDataType * Type of Custom Data; empty is a synonym for "all contact data types". * @param bool $showAll * If true returns all fields (includes disabled fields). * @param bool $inline * If true returns all inline fields (includes disabled fields). * @param int $customDataSubType * Custom Data sub type value. * @param int $customDataSubName * Custom Data sub name value. * @param bool $onlyParent * Return only top level custom data, for eg, only Participant and ignore subname and subtype. * @param bool $onlySubType * Return only custom data for subtype. * @param bool $checkPermission * If false, do not include permissioning clause. * * @return array * an array of active custom fields. * */ public static function &getFields($customDataType = 'Individual', $showAll = FALSE, $inline = FALSE, $customDataSubType = NULL, $customDataSubName = NULL, $onlyParent = FALSE, $onlySubType = FALSE, $checkPermission = TRUE) { if (empty($customDataType)) { $customDataType = array('Contact', 'Individual', 'Organization', 'Household'); } if ($customDataType && !is_array($customDataType)) { if (in_array($customDataType, CRM_Contact_BAO_ContactType::subTypes())) { // This is the case when getFieldsForImport() requires fields // limited strictly to a subtype. $customDataSubType = $customDataType; $customDataType = CRM_Contact_BAO_ContactType::getBasicType($customDataType); $onlySubType = TRUE; } if (in_array($customDataType, array_keys(CRM_Core_SelectValues::customGroupExtends()))) { // this makes the method flexible to support retrieving fields // for multiple extends value. $customDataType = array($customDataType); } } $customDataSubType = CRM_Utils_Array::explodePadded($customDataSubType); if (is_array($customDataType)) { $cacheKey = implode('_', $customDataType); } else { $cacheKey = $customDataType; } $cacheKey .= !empty($customDataSubType) ? '_' . implode('_', $customDataSubType) : '_0'; $cacheKey .= $customDataSubName ? "{$customDataSubName}_" : '_0'; $cacheKey .= $showAll ? '_1' : '_0'; $cacheKey .= $inline ? '_1_' : '_0_'; $cacheKey .= $onlyParent ? '_1_' : '_0_'; $cacheKey .= $onlySubType ? '_1_' : '_0_'; $cacheKey .= $checkPermission ? '_1_' : '_0_'; $cgTable = CRM_Core_DAO_CustomGroup::getTableName(); // also get the permission stuff here if ($checkPermission) { $permissionClause = CRM_Core_Permission::customGroupClause(CRM_Core_Permission::VIEW, "{$cgTable}."); } else { $permissionClause = '(1)'; } // lets md5 permission clause and take first 8 characters $cacheKey .= substr(md5($permissionClause), 0, 8); if (strlen($cacheKey) > 40) { $cacheKey = md5($cacheKey); } if (!self::$_importFields || CRM_Utils_Array::value($cacheKey, self::$_importFields) === NULL) { if (!self::$_importFields) { self::$_importFields = array(); } // check if we can retrieve from database cache $fields = CRM_Core_BAO_Cache::getItem('contact fields', "custom importableFields {$cacheKey}"); if ($fields === NULL) { $cfTable = self::getTableName(); $extends = ''; if (is_array($customDataType)) { $value = NULL; foreach ($customDataType as $dataType) { if (in_array($dataType, array_keys(CRM_Core_SelectValues::customGroupExtends()))) { if (in_array($dataType, array('Individual', 'Household', 'Organization'))) { $val = "'" . CRM_Utils_Type::escape($dataType, 'String') . "', 'Contact' "; } else { $val = "'" . CRM_Utils_Type::escape($dataType, 'String') . "'"; } $value = $value ? $value . ", {$val}" : $val; } } if ($value) { $extends = "AND {$cgTable}.extends IN ( {$value} ) "; } } if (!empty($customDataType) && empty($extends)) { // $customDataType specified a filter, but there is no corresponding SQL ($extends) self::$_importFields[$cacheKey] = array(); return self::$_importFields[$cacheKey]; } if ($onlyParent) { $extends .= " AND {$cgTable}.extends_entity_column_value IS NULL AND {$cgTable}.extends_entity_column_id IS NULL "; } $query = "SELECT {$cfTable}.id, {$cfTable}.label,\n {$cgTable}.title,\n {$cfTable}.data_type,\n {$cfTable}.html_type,\n {$cfTable}.default_value,\n {$cfTable}.options_per_line, {$cfTable}.text_length,\n {$cfTable}.custom_group_id,\n {$cfTable}.is_required,\n {$cgTable}.extends, {$cfTable}.is_search_range,\n {$cgTable}.extends_entity_column_value,\n {$cgTable}.extends_entity_column_id,\n {$cfTable}.is_view,\n {$cfTable}.option_group_id,\n {$cfTable}.date_format,\n {$cfTable}.time_format,\n {$cgTable}.is_multiple,\n og.name as option_group_name\n FROM {$cfTable}\n INNER JOIN {$cgTable}\n ON {$cfTable}.custom_group_id = {$cgTable}.id\n LEFT JOIN civicrm_option_group og\n ON {$cfTable}.option_group_id = og.id\n WHERE ( 1 ) "; if (!$showAll) { $query .= " AND {$cfTable}.is_active = 1 AND {$cgTable}.is_active = 1 "; } if ($inline) { $query .= " AND {$cgTable}.style = 'Inline' "; } //get the custom fields for specific type in //combination with fields those support any type. if (!empty($customDataSubType)) { $subtypeClause = array(); foreach ($customDataSubType as $subtype) { $subtype = CRM_Core_DAO::VALUE_SEPARATOR . $subtype . CRM_Core_DAO::VALUE_SEPARATOR; $subtypeClause[] = "{$cgTable}.extends_entity_column_value LIKE '%{$subtype}%'"; } if (!$onlySubType) { $subtypeClause[] = "{$cgTable}.extends_entity_column_value IS NULL"; } $query .= " AND ( " . implode(' OR ', $subtypeClause) . " )"; } if ($customDataSubName) { $query .= " AND ( {$cgTable}.extends_entity_column_id = {$customDataSubName} ) "; } // also get the permission stuff here if ($checkPermission) { $permissionClause = CRM_Core_Permission::customGroupClause(CRM_Core_Permission::VIEW, "{$cgTable}.", TRUE); } else { $permissionClause = '(1)'; } $query .= " {$extends} AND {$permissionClause}\n ORDER BY {$cgTable}.weight, {$cgTable}.title,\n {$cfTable}.weight, {$cfTable}.label"; $dao = CRM_Core_DAO::executeQuery($query); $fields = array(); while ($dao->fetch() != NULL) { $fields[$dao->id]['label'] = $dao->label; $fields[$dao->id]['groupTitle'] = $dao->title; $fields[$dao->id]['data_type'] = $dao->data_type; $fields[$dao->id]['html_type'] = $dao->html_type; $fields[$dao->id]['default_value'] = $dao->default_value; $fields[$dao->id]['text_length'] = $dao->text_length; $fields[$dao->id]['options_per_line'] = $dao->options_per_line; $fields[$dao->id]['custom_group_id'] = $dao->custom_group_id; $fields[$dao->id]['extends'] = $dao->extends; $fields[$dao->id]['is_search_range'] = $dao->is_search_range; $fields[$dao->id]['extends_entity_column_value'] = $dao->extends_entity_column_value; $fields[$dao->id]['extends_entity_column_id'] = $dao->extends_entity_column_id; $fields[$dao->id]['is_view'] = $dao->is_view; $fields[$dao->id]['is_multiple'] = $dao->is_multiple; $fields[$dao->id]['option_group_id'] = $dao->option_group_id; $fields[$dao->id]['date_format'] = $dao->date_format; $fields[$dao->id]['time_format'] = $dao->time_format; $fields[$dao->id]['is_required'] = $dao->is_required; self::getOptionsForField($fields[$dao->id], $dao->option_group_name); } CRM_Core_BAO_Cache::setItem($fields, 'contact fields', "custom importableFields {$cacheKey}"); } self::$_importFields[$cacheKey] = $fields; } return self::$_importFields[$cacheKey]; }
/** * FIXME: Move to somewhere more useful * FIXME: Do real mapping of "types" * * @param string $extends * Entity type; note: "Individual" means "Individual|Contact"; "Household" means "Household|Contact". * @param string $title * A string to use in section headers. * @param array $availableFields * List of fields that are allowed in profiles, e.g. $availableFields['my_field']['field_type']. * @return array * with keys 'sections' and 'schema' * @see js/model/crm.core.js * @see js/model/crm.mappedcore.js */ public static function convertCiviModelToBackboneModel($extends, $title, $availableFields) { $locationFields = CRM_Core_BAO_UFGroup::getLocationFields(); $result = array('schema' => array(), 'sections' => array()); // build field list foreach ($availableFields as $fieldName => $field) { switch ($extends) { case 'Individual': case 'Organization': case 'Household': if ($field['field_type'] != $extends && $field['field_type'] != 'Contact' && !in_array($field['field_type'], CRM_Contact_BAO_ContactType::subTypes($extends))) { continue 2; } break; default: if ($field['field_type'] != $extends) { continue 2; } } $result['schema'][$fieldName] = array('type' => 'Text', 'title' => $field['title'], 'civiFieldType' => $field['field_type']); if (in_array($fieldName, $locationFields)) { $result['schema'][$fieldName]['civiIsLocation'] = TRUE; } if ($fieldName == 'url') { $result['schema'][$fieldName]['civiIsWebsite'] = TRUE; } if (in_array($fieldName, array('phone', 'phone_and_ext'))) { // FIXME what about phone_ext? $result['schema'][$fieldName]['civiIsPhone'] = TRUE; } } // build section list $result['sections']['default'] = array('title' => $title, 'is_addable' => FALSE); $customGroup = CRM_Core_BAO_CustomGroup::getAllCustomGroupsByBaseEntity($extends); $customGroup->orderBy('weight'); $customGroup->is_active = 1; $customGroup->find(); while ($customGroup->fetch()) { $sectionName = 'cg_' . $customGroup->id; $section = array('title' => ts('%1: %2', array(1 => $title, 2 => $customGroup->title)), 'is_addable' => $customGroup->is_reserved ? FALSE : TRUE, 'custom_group_id' => $customGroup->id, 'extends_entity_column_id' => $customGroup->extends_entity_column_id, 'extends_entity_column_value' => CRM_Utils_Array::explodePadded($customGroup->extends_entity_column_value), 'is_reserved' => $customGroup->is_reserved ? TRUE : FALSE); $result['sections'][$sectionName] = $section; } // put fields in their sections $fields = CRM_Core_BAO_CustomField::getFields($extends); foreach ($fields as $fieldId => $field) { $sectionName = 'cg_' . $field['custom_group_id']; $fieldName = 'custom_' . $fieldId; if (isset($result['schema'][$fieldName])) { $result['schema'][$fieldName]['section'] = $sectionName; $result['schema'][$fieldName]['civiIsMultiple'] = (bool) CRM_Core_BAO_CustomField::isMultiRecordField($fieldId); } } return $result; }
/** * Validate & swap out any pseudoconstants / options. * * @param mixed $fieldValue * @param string $entity : api entity name * @param string $fieldName : field name used in api call (not necessarily the canonical name) * @param array $fieldInfo : getfields meta-data * * @throws \API_Exception */ function _civicrm_api3_api_match_pseudoconstant(&$fieldValue, $entity, $fieldName, $fieldInfo) { $options = CRM_Utils_Array::value('options', $fieldInfo); if (!$options) { if (strtolower($entity) == 'profile' && !empty($fieldInfo['entity'])) { // We need to get the options from the entity the field relates to. $entity = $fieldInfo['entity']; } $options = civicrm_api($entity, 'getoptions', array('version' => 3, 'field' => $fieldInfo['name'], 'context' => 'validate')); $options = CRM_Utils_Array::value('values', $options, array()); } // If passed a value-separated string, explode to an array, then re-implode after matching values. $implode = FALSE; if (is_string($fieldValue) && strpos($fieldValue, CRM_Core_DAO::VALUE_SEPARATOR) !== FALSE) { $fieldValue = CRM_Utils_Array::explodePadded($fieldValue); $implode = TRUE; } // If passed multiple options, validate each. if (is_array($fieldValue)) { foreach ($fieldValue as &$value) { if (!is_array($value)) { _civicrm_api3_api_match_pseudoconstant_value($value, $options, $fieldName); } } // TODO: unwrap the call to implodePadded from the conditional and do it always // need to verify that this is safe and doesn't break anything though. // Better yet would be to leave it as an array and ensure that every dao/bao can handle array input if ($implode) { CRM_Utils_Array::implodePadded($fieldValue); } } else { _civicrm_api3_api_match_pseudoconstant_value($fieldValue, $options, $fieldName); } }
/** * Verify that a variable is of a given type, and apply a bit of processing. * * @param mixed $data * The value to be verified/escaped. * @param string $type * The type to verify against. * @param bool $abort * If TRUE, the operation will CRM_Core_Error::fatal() on invalid data. * * @return mixed * The data, escaped if necessary. */ public static function escape($data, $type, $abort = TRUE) { switch ($type) { case 'Integer': case 'Int': if (CRM_Utils_Rule::integer($data)) { return (int) $data; } break; case 'Positive': if (CRM_Utils_Rule::positiveInteger($data)) { return (int) $data; } break; // CRM-8925 for custom fields of this type // CRM-8925 for custom fields of this type case 'Country': case 'StateProvince': // Handle multivalued data in delimited or array format if (is_array($data) || strpos($data, CRM_Core_DAO::VALUE_SEPARATOR) !== FALSE) { $valid = TRUE; foreach (CRM_Utils_Array::explodePadded($data) as $item) { if (!CRM_Utils_Rule::positiveInteger($item)) { $valid = FALSE; } } if ($valid) { return $data; } } elseif (CRM_Utils_Rule::positiveInteger($data)) { return (int) $data; } break; case 'File': if (CRM_Utils_Rule::positiveInteger($data)) { return (int) $data; } break; case 'Link': if (CRM_Utils_Rule::url($data = trim($data))) { return $data; } break; case 'Boolean': if (CRM_Utils_Rule::boolean($data)) { return $data; } break; case 'Float': case 'Money': if (CRM_Utils_Rule::numeric($data)) { return $data; } break; case 'String': case 'Memo': case 'Text': return CRM_Core_DAO::escapeString($data); case 'Date': case 'Timestamp': // a null date or timestamp is valid if (strlen(trim($data)) == 0) { return trim($data); } if ((preg_match('/^\\d{8}$/', $data) || preg_match('/^\\d{14}$/', $data)) && CRM_Utils_Rule::mysqlDate($data)) { return $data; } break; case 'ContactReference': if (strlen(trim($data)) == 0) { return trim($data); } if (CRM_Utils_Rule::validContact($data)) { return (int) $data; } break; case 'MysqlColumnNameOrAlias': if (CRM_Utils_Rule::mysqlColumnNameOrAlias($data)) { $data = str_replace('`', '', $data); $parts = explode('.', $data); $data = '`' . implode('`.`', $parts) . '`'; return $data; } break; case 'MysqlOrderByDirection': if (CRM_Utils_Rule::mysqlOrderByDirection($data)) { return strtolower($data); } break; case 'MysqlOrderBy': if (CRM_Utils_Rule::mysqlOrderBy($data)) { $parts = explode(',', $data); foreach ($parts as &$part) { $part = preg_replace_callback('/^(?:(?:((?:`[\\w-]{1,64}`|[\\w-]{1,64}))(?:\\.))?(`[\\w-]{1,64}`|[\\w-]{1,64})(?: (asc|desc))?)$/i', array('CRM_Utils_Type', 'mysqlOrderByCallback'), trim($part)); } return implode(', ', $parts); } break; default: CRM_Core_Error::fatal($type . " is not a recognised (camel cased) data type."); break; } // @todo Use exceptions instead of CRM_Core_Error::fatal(). if ($abort) { $data = htmlentities($data); CRM_Core_Error::fatal("{$data} is not of the type {$type}"); } return NULL; }
/** * Generate a query to locate contacts who match the given * schedule. * * @param \CRM_Core_DAO_ActionSchedule $schedule * @param string $phase * See, e.g., RecipientBuilder::PHASE_RELATION_FIRST. * @param array $defaultParams * Default parameters that should be included with query. * @return \CRM_Utils_SQL_Select * @see RecipientBuilder * @throws CRM_Core_Exception */ public function createQuery($schedule, $phase, $defaultParams) { $selectedValues = (array) \CRM_Utils_Array::explodePadded($schedule->entity_value); $selectedStatuses = (array) \CRM_Utils_Array::explodePadded($schedule->entity_status); $query = \CRM_Utils_SQL_Select::from("civicrm_contribution e")->param($defaultParams); $query['casAddlCheckFrom'] = 'civicrm_contribution e'; $query['casContactIdField'] = 'e.contact_id'; $query['casEntityIdField'] = 'e.id'; $query['casContactTableAlias'] = NULL; // $schedule->start_action_date is user-supplied data. validate. if (!array_key_exists($schedule->start_action_date, $this->getDateFields())) { throw new CRM_Core_Exception("Invalid date field"); } $query['casDateField'] = $schedule->start_action_date; // build where clause if (!empty($selectedValues)) { $query->where("e.contribution_page_id IN (@selectedValues)")->param('selectedValues', $selectedValues); } if (!empty($selectedStatuses)) { $query->where("e.contribution_status_id IN (#selectedStatuses)")->param('selectedStatuses', $selectedStatuses); } return $query; }
/** * Lower-level logic for rendering a custom field value * * @param string|array $value * @param array $field * @param int|null $entityId * * @return string */ private static function formatDisplayValue($value, $field, $entityId = NULL) { if (self::isSerialized($field) && !is_array($value)) { $value = CRM_Utils_Array::explodePadded($value); } // CRM-12989 fix if ($field['html_type'] == 'CheckBox') { CRM_Utils_Array::formatArrayKeys($value); } $display = is_array($value) ? implode(', ', $value) : (string) $value; switch ($field['html_type']) { case 'Select': case 'Autocomplete-Select': case 'Radio': case 'Select Country': case 'Select State/Province': case 'CheckBox': case 'AdvMulti-Select': case 'Multi-Select': case 'Multi-Select State/Province': case 'Multi-Select Country': if ($field['data_type'] == 'ContactReference' && $value) { $display = CRM_Core_DAO::getFieldValue('CRM_Contact_DAO_Contact', $value, 'display_name'); } elseif (is_array($value)) { $v = array(); foreach ($value as $key => $val) { $v[] = CRM_Utils_Array::value($val, $field['options']); } $display = implode(', ', $v); } else { $display = CRM_Utils_Array::value($value, $field['options'], ''); } break; case 'Select Date': $customFormat = NULL; // FIXME: Are there any legitimate reasons why $value would be an array? // Or should we throw an exception here if it is? $value = is_array($value) ? CRM_Utils_Array::first($value) : $value; $actualPHPFormats = CRM_Core_SelectValues::datePluginToPHPFormats(); $format = CRM_Utils_Array::value('date_format', $field); if ($format) { if (array_key_exists($format, $actualPHPFormats)) { $customTimeFormat = (array) $actualPHPFormats[$format]; switch (CRM_Utils_Array::value('time_format', $field)) { case 1: $customTimeFormat[] = 'g:iA'; break; case 2: $customTimeFormat[] = 'G:i'; break; default: // if time is not selected remove time from value $value = substr($value, 0, 10); } $customFormat = implode(" ", $customTimeFormat); } } $display = CRM_Utils_Date::processDate($value, NULL, FALSE, $customFormat); break; case 'File': // In the context of displaying a profile, show file/image if ($value) { if ($entityId) { $url = self::getFileURL($entityId, $field['id']); if ($url) { $display = $url['file_url']; } } else { // In other contexts show a paperclip icon if (CRM_Utils_Rule::integer($value)) { $icons = CRM_Core_BAO_File::paperIconAttachment('*', $value); $display = $icons[$value]; } else { //CRM-18396, if filename is passed instead $display = $value; } } } break; case 'TextArea': $display = nl2br($display); break; case 'Text': if ($field['data_type'] == 'Money' && isset($value)) { //$value can also be an array(while using IN operator from search builder or api). foreach ((array) $value as $val) { $disp[] = CRM_Utils_Money::format($val); } $display = implode(', ', $disp); } break; } return $display; }
/** * Generate a query to locate contacts who match the given * schedule. * * @param \CRM_Core_DAO_ActionSchedule $schedule * @param string $phase * See, e.g., RecipientBuilder::PHASE_RELATION_FIRST. * @param array $defaultParams * Default parameters that should be included with query. * @return \CRM_Utils_SQL_Select * @see RecipientBuilder * @throws CRM_Core_Exception */ public function createQuery($schedule, $phase, $defaultParams) { $selectedValues = (array) \CRM_Utils_Array::explodePadded($schedule->entity_value); $selectedStatuses = (array) \CRM_Utils_Array::explodePadded($schedule->entity_status); $query = \CRM_Utils_SQL_Select::from("civicrm_contribution e")->param($defaultParams); $query['casAddlCheckFrom'] = 'civicrm_contribution e'; $query['casContactIdField'] = 'e.contact_id'; $query['casEntityIdField'] = 'e.id'; $query['casContactTableAlias'] = NULL; // $schedule->start_action_date is user-supplied data. validate. if (!array_key_exists($schedule->start_action_date, $this->getDateFields())) { throw new CRM_Core_Exception("Invalid date field"); } $query['casDateField'] = $schedule->start_action_date; // build where clause if (!empty($selectedValues)) { $query->where("e.financial_type_id IN (@selectedValues)")->param('selectedValues', $selectedValues); } if (!empty($selectedStatuses)) { $query->where("e.contribution_status_id IN (#selectedStatuses)")->param('selectedStatuses', $selectedStatuses); } if ($schedule->recipient_listing && $schedule->limit_to) { switch ($schedule->recipient) { case 'soft_credit_type': $query['casContactIdField'] = 'soft.contact_id'; $query->join('soft', 'INNER JOIN civicrm_contribution_soft soft ON soft.contribution_id = e.id')->where("soft.soft_credit_type_id IN (#recipList)")->param('recipList', \CRM_Utils_Array::explodePadded($schedule->recipient_listing)); break; } } return $query; }
/** * Verify that a variable is of a given type, and apply a bit of processing. * * @param mixed $data * The value to be verified/escaped. * @param string $type * The type to verify against. * @param bool $abort * If TRUE, the operation will CRM_Core_Error::fatal() on invalid data. * * @return mixed * The data, escaped if necessary. */ public static function escape($data, $type, $abort = TRUE) { switch ($type) { case 'Integer': case 'Int': if (CRM_Utils_Rule::integer($data)) { return (int) $data; } break; case 'Positive': if (CRM_Utils_Rule::positiveInteger($data)) { return (int) $data; } break; // CRM-8925 for custom fields of this type // CRM-8925 for custom fields of this type case 'Country': case 'StateProvince': // Handle multivalued data in delimited or array format if (is_array($data) || strpos($data, CRM_Core_DAO::VALUE_SEPARATOR) !== FALSE) { $valid = TRUE; foreach (CRM_Utils_Array::explodePadded($data) as $item) { if (!CRM_Utils_Rule::positiveInteger($item)) { $valid = FALSE; } } if ($valid) { return $data; } } elseif (CRM_Utils_Rule::positiveInteger($data)) { return (int) $data; } break; case 'File': if (CRM_Utils_Rule::positiveInteger($data)) { return (int) $data; } break; case 'Link': if (CRM_Utils_Rule::url($data = trim($data))) { return $data; } break; case 'Boolean': if (CRM_Utils_Rule::boolean($data)) { return $data; } break; case 'Float': case 'Money': if (CRM_Utils_Rule::numeric($data)) { return $data; } break; case 'String': case 'Memo': case 'Text': return CRM_Core_DAO::escapeString($data); case 'Date': case 'Timestamp': // a null date or timestamp is valid if (strlen(trim($data)) == 0) { return trim($data); } if ((preg_match('/^\\d{8}$/', $data) || preg_match('/^\\d{14}$/', $data)) && CRM_Utils_Rule::mysqlDate($data)) { return $data; } break; case 'ContactReference': if (strlen(trim($data)) == 0) { return trim($data); } if (CRM_Utils_Rule::validContact($data)) { return (int) $data; } break; default: CRM_Core_Error::fatal($type . " is not a recognised (camel cased) data type."); break; } // @todo Use exceptions instead of CRM_Core_Error::fatal(). if ($abort) { $data = htmlentities($data); CRM_Core_Error::fatal("{$data} is not of the type {$type}"); } return NULL; }
/** * Generate a query to locate recipients who match the given * schedule. * * @param \CRM_Core_DAO_ActionSchedule $schedule * The schedule as configured by the administrator. * @param string $phase * See, e.g., RecipientBuilder::PHASE_RELATION_FIRST. * @param array $defaultParams * * @return \CRM_Utils_SQL_Select * @throws \CRM_Core_Exception * @see RecipientBuilder */ public function createQuery($schedule, $phase, $defaultParams) { $selectedValues = (array) \CRM_Utils_Array::explodePadded($schedule->entity_value); $selectedStatuses = (array) \CRM_Utils_Array::explodePadded($schedule->entity_status); // FIXME: This assumes that $values only has one field, but UI shows multiselect. // Properly supporting multiselect would require total rewrite of this function. if (count($selectedValues) != 1 || !isset($selectedValues[0])) { throw new \CRM_Core_Exception("Error: Scheduled reminders may only have one contact field."); } elseif (in_array($selectedValues[0], $this->contactDateFields)) { $dateDBField = $selectedValues[0]; $query = \CRM_Utils_SQL_Select::from("{$this->entity} e")->param($defaultParams); $query->param(array('casAddlCheckFrom' => 'civicrm_contact e', 'casContactIdField' => 'e.id', 'casEntityIdField' => 'e.id', 'casContactTableAlias' => 'e')); $query->where('e.is_deleted = 0 AND e.is_deceased = 0'); } else { //custom field $customFieldParams = array('id' => substr($selectedValues[0], 7)); $customGroup = $customField = array(); \CRM_Core_BAO_CustomField::retrieve($customFieldParams, $customField); $dateDBField = $customField['column_name']; $customGroupParams = array('id' => $customField['custom_group_id'], $customGroup); \CRM_Core_BAO_CustomGroup::retrieve($customGroupParams, $customGroup); $query = \CRM_Utils_SQL_Select::from("{$customGroup['table_name']} e")->param($defaultParams); $query->param(array('casAddlCheckFrom' => "{$customGroup['table_name']} e", 'casContactIdField' => 'e.entity_id', 'casEntityIdField' => 'e.id', 'casContactTableAlias' => NULL)); $query->where('1'); // possible to have no "where" in this case } $query['casDateField'] = 'e.' . $dateDBField; if (in_array(2, $selectedStatuses)) { $query['casAnniversaryMode'] = 1; $query['casDateField'] = 'DATE_ADD(' . $query['casDateField'] . ', INTERVAL ROUND(DATEDIFF(DATE(' . $query['casNow'] . '), ' . $query['casDateField'] . ') / 365) YEAR)'; } return $query; }
/** * Verify if a given subtype is associated with a given basic contact type. * * @param string $subType * Contact subType. * @param string $contactType * Contact Type. * @param bool $ignoreCache * @param string $columnName * * @return bool * true if contact extends, false otherwise. */ public static function isExtendsContactType($subType, $contactType, $ignoreCache = FALSE, $columnName = 'name') { $subType = (array) CRM_Utils_Array::explodePadded($subType); $subtypeList = self::subTypes($contactType, TRUE, $columnName, $ignoreCache); $intersection = array_intersect($subType, $subtypeList); return $subType == $intersection; }
/** * Wrapper for ajax option selector. * * @param array $params * Associated array for params record id. * * @return array * associated array of option list * -rp = rowcount * -page= offset */ public static function getOptionListSelector(&$params) { $options = array(); $field = CRM_Core_BAO_CustomField::getFieldObject($params['fid']); $defVal = CRM_Utils_Array::explodePadded($field->default_value); // format the params $params['offset'] = ($params['page'] - 1) * $params['rp']; $params['rowCount'] = $params['rp']; if (!$field->option_group_id) { return $options; } $queryParams = array(1 => array($field->option_group_id, 'Integer')); $total = "SELECT COUNT(*) FROM civicrm_option_value WHERE option_group_id = %1"; $params['total'] = CRM_Core_DAO::singleValueQuery($total, $queryParams); $limit = " LIMIT {$params['offset']}, {$params['rowCount']} "; $orderBy = ' ORDER BY options.weight asc'; $query = "SELECT * FROM civicrm_option_value as options WHERE option_group_id = %1 {$orderBy} {$limit}"; $dao = CRM_Core_DAO::executeQuery($query, $queryParams); $links = CRM_Custom_Page_Option::actionLinks(); $fields = array('id', 'label', 'value'); $config = CRM_Core_Config::singleton(); while ($dao->fetch()) { $options[$dao->id] = array(); foreach ($fields as $k) { $options[$dao->id][$k] = $dao->{$k}; } $action = array_sum(array_keys($links)); $class = 'crm-entity'; // update enable/disable links depending on custom_field properties. if ($dao->is_active) { $action -= CRM_Core_Action::ENABLE; } else { $class .= ' disabled'; $action -= CRM_Core_Action::DISABLE; } if (in_array($field->html_type, array('CheckBox', 'AdvMulti-Select', 'Multi-Select'))) { if (isset($defVal) && in_array($dao->value, $defVal)) { $options[$dao->id]['is_default'] = '<img src="' . $config->resourceBase . 'i/check.gif" />'; } else { $options[$dao->id]['is_default'] = ''; } } else { if ($field->default_value == $dao->value) { $options[$dao->id]['is_default'] = '<img src="' . $config->resourceBase . 'i/check.gif" />'; } else { $options[$dao->id]['is_default'] = ''; } } $options[$dao->id]['class'] = $dao->id . ',' . $class; $options[$dao->id]['is_active'] = empty($dao->is_active) ? ts('No') : ts('Yes'); $options[$dao->id]['links'] = CRM_Core_Action::formLink($links, $action, array('id' => $dao->id, 'fid' => $params['fid'], 'gid' => $params['gid']), ts('more'), FALSE, 'customOption.row.actions', 'customOption', $dao->id); } return $options; }
/** * Function to set variables up before form is built * * @return void * @access public */ public function preProcess() { $config = CRM_Core_Config::singleton(); $session = CRM_Core_Session::singleton(); // current contribution page id $this->_id = CRM_Utils_Request::retrieve('id', 'Positive', $this); if (!$this->_id) { // seems like the session is corrupted and/or we lost the id trail // lets just bump this to a regular session error and redirect user to main page $this->controller->invalidKeyRedirect(); } // this was used prior to the cleverer this_>getContactID - unsure now $this->_userID = $session->get('userID'); $this->_contactID = $this->_membershipContactID = $this->getContactID(); $this->_mid = NULL; if ($this->_contactID) { $this->_mid = CRM_Utils_Request::retrieve('mid', 'Positive', $this); if ($this->_mid) { $membership = new CRM_Member_DAO_Membership(); $membership->id = $this->_mid; if ($membership->find(TRUE)) { $this->_defaultMemTypeId = $membership->membership_type_id; if ($membership->contact_id != $this->_contactID) { $validMembership = FALSE; $employers = CRM_Contact_BAO_Relationship::getPermissionedEmployer($this->_userID); if (!empty($employers) && array_key_exists($membership->contact_id, $employers)) { $this->_membershipContactID = $membership->contact_id; $this->assign('membershipContactID', $this->_membershipContactID); $this->assign('membershipContactName', $employers[$this->_membershipContactID]['name']); $validMembership = TRUE; } else { $membershipType = new CRM_Member_BAO_MembershipType(); $membershipType->id = $membership->membership_type_id; if ($membershipType->find(TRUE)) { // CRM-14051 - membership_type.relationship_type_id is a CTRL-A padded string w one or more ID values. // Convert to commma separated list. $inheritedRelTypes = implode(CRM_Utils_Array::explodePadded($membershipType->relationship_type_id), ','); $permContacts = CRM_Contact_BAO_Relationship::getPermissionedContacts($this->_userID, $membershipType->relationship_type_id); if (array_key_exists($membership->contact_id, $permContacts)) { $this->_membershipContactID = $membership->contact_id; $validMembership = TRUE; } } } if (!$validMembership) { CRM_Core_Session::setStatus(ts("Oops. The membership you're trying to renew appears to be invalid. Contact your site administrator if you need assistance. If you continue, you will be issued a new membership."), ts('Membership Invalid'), 'alert'); } } } else { CRM_Core_Session::setStatus(ts("Oops. The membership you're trying to renew appears to be invalid. Contact your site administrator if you need assistance. If you continue, you will be issued a new membership."), ts('Membership Invalid'), 'alert'); } unset($membership); } } // we do not want to display recently viewed items, so turn off $this->assign('displayRecent', FALSE); // Contribution page values are cleared from session, so can't use normal Printer Friendly view. // Use Browser Print instead. $this->assign('browserPrint', TRUE); // action $this->_action = CRM_Utils_Request::retrieve('action', 'String', $this, FALSE, 'add'); $this->assign('action', $this->_action); // current mode $this->_mode = $this->_action == 1024 ? 'test' : 'live'; $this->_values = $this->get('values'); $this->_fields = $this->get('fields'); $this->_bltID = $this->get('bltID'); $this->_paymentProcessor = $this->get('paymentProcessor'); $this->_priceSetId = $this->get('priceSetId'); $this->_priceSet = $this->get('priceSet'); if (!$this->_values) { // get all the values from the dao object $this->_values = array(); $this->_fields = array(); CRM_Contribute_BAO_ContributionPage::setValues($this->_id, $this->_values); // check if form is active if (!CRM_Utils_Array::value('is_active', $this->_values)) { // form is inactive, die a fatal death CRM_Core_Error::fatal(ts('The page you requested is currently unavailable.')); } // also check for billing informatin // get the billing location type $locationTypes = CRM_Core_PseudoConstant::get('CRM_Core_DAO_Address', 'location_type_id', array(), 'validate'); // CRM-8108 remove ts around Billing location type //$this->_bltID = array_search( ts('Billing'), $locationTypes ); $this->_bltID = array_search('Billing', $locationTypes); if (!$this->_bltID) { CRM_Core_Error::fatal(ts('Please set a location type of %1', array(1 => 'Billing'))); } $this->set('bltID', $this->_bltID); // check for is_monetary status $isMonetary = CRM_Utils_Array::value('is_monetary', $this->_values); $isPayLater = CRM_Utils_Array::value('is_pay_later', $this->_values); //FIXME: to support multiple payment processors if ($isMonetary && (!$isPayLater || CRM_Utils_Array::value('payment_processor', $this->_values))) { $ppID = CRM_Utils_Array::value('payment_processor', $this->_values); if (!$ppID) { CRM_Core_Error::fatal(ts('A payment processor must be selected for this contribution page (contact the site administrator for assistance).')); } $ppIds = explode(CRM_Core_DAO::VALUE_SEPARATOR, $ppID); $this->_paymentProcessors = CRM_Financial_BAO_PaymentProcessor::getPayments($ppIds, $this->_mode); $this->set('paymentProcessors', $this->_paymentProcessors); //set default payment processor if (!empty($this->_paymentProcessors) && empty($this->_paymentProcessor)) { foreach ($this->_paymentProcessors as $ppId => $values) { if ($values['is_default'] == 1 || count($this->_paymentProcessors) == 1) { $defaultProcessorId = $ppId; break; } } } if (isset($defaultProcessorId)) { $this->_paymentProcessor = CRM_Financial_BAO_PaymentProcessor::getPayment($defaultProcessorId, $this->_mode); $this->assign_by_ref('paymentProcessor', $this->_paymentProcessor); } if (!CRM_Utils_System::isNull($this->_paymentProcessors)) { foreach ($this->_paymentProcessors as $eachPaymentProcessor) { // check selected payment processor is active if (empty($eachPaymentProcessor)) { CRM_Core_Error::fatal(ts('A payment processor configured for this page might be disabled (contact the site administrator for assistance).')); } // ensure that processor has a valid config $this->_paymentObject =& CRM_Core_Payment::singleton($this->_mode, $eachPaymentProcessor, $this); $error = $this->_paymentObject->checkConfig(); if (!empty($error)) { CRM_Core_Error::fatal($error); } } } } // get price info // CRM-5095 CRM_Price_BAO_PriceSet::initSet($this, $this->_id, 'civicrm_contribution_page'); // this avoids getting E_NOTICE errors in php $setNullFields = array('amount_block_is_active', 'honor_block_is_active', 'is_allow_other_amount', 'footer_text'); foreach ($setNullFields as $f) { if (!isset($this->_values[$f])) { $this->_values[$f] = NULL; } } //check if Membership Block is enabled, if Membership Fields are included in profile //get membership section for this contribution page $this->_membershipBlock = CRM_Member_BAO_Membership::getMembershipBlock($this->_id); $this->set('membershipBlock', $this->_membershipBlock); if ($this->_values['custom_pre_id']) { $preProfileType = CRM_Core_BAO_UFField::getProfileType($this->_values['custom_pre_id']); } if ($this->_values['custom_post_id']) { $postProfileType = CRM_Core_BAO_UFField::getProfileType($this->_values['custom_post_id']); } if ((isset($postProfileType) && $postProfileType == 'Membership' || isset($preProfileType) && $preProfileType == 'Membership') && !$this->_membershipBlock['is_active']) { CRM_Core_Error::fatal(ts('This page includes a Profile with Membership fields - but the Membership Block is NOT enabled. Please notify the site administrator.')); } $pledgeBlock = CRM_Pledge_BAO_PledgeBlock::getPledgeBlock($this->_id); if ($pledgeBlock) { $this->_values['pledge_block_id'] = CRM_Utils_Array::value('id', $pledgeBlock); $this->_values['max_reminders'] = CRM_Utils_Array::value('max_reminders', $pledgeBlock); $this->_values['initial_reminder_day'] = CRM_Utils_Array::value('initial_reminder_day', $pledgeBlock); $this->_values['additional_reminder_day'] = CRM_Utils_Array::value('additional_reminder_day', $pledgeBlock); //set pledge id in values $pledgeId = CRM_Utils_Request::retrieve('pledgeId', 'Positive', $this); //authenticate pledge user for pledge payment. if ($pledgeId) { $this->_values['pledge_id'] = $pledgeId; //lets override w/ pledge campaign. $this->_values['campaign_id'] = CRM_Core_DAO::getFieldValue('CRM_Pledge_DAO_Pledge', $pledgeId, 'campaign_id'); self::authenticatePledgeUser(); } } $this->set('values', $this->_values); $this->set('fields', $this->_fields); } // Handle PCP $pcpId = CRM_Utils_Request::retrieve('pcpId', 'Positive', $this); if ($pcpId) { $pcp = CRM_PCP_BAO_PCP::handlePcp($pcpId, 'contribute', $this->_values); $this->_pcpId = $pcp['pcpId']; $this->_pcpBlock = $pcp['pcpBlock']; $this->_pcpInfo = $pcp['pcpInfo']; } // Link (button) for users to create their own Personal Campaign page if ($linkText = CRM_PCP_BAO_PCP::getPcpBlockStatus($this->_id, 'contribute')) { $linkTextUrl = CRM_Utils_System::url('civicrm/contribute/campaign', "action=add&reset=1&pageId={$this->_id}&component=contribute", FALSE, NULL, TRUE); $this->assign('linkTextUrl', $linkTextUrl); $this->assign('linkText', $linkText); } //set pledge block if block id is set if (CRM_Utils_Array::value('pledge_block_id', $this->_values)) { $this->assign('pledgeBlock', TRUE); } // check if one of the (amount , membership) bloks is active or not $this->_membershipBlock = $this->get('membershipBlock'); if (!$this->_values['amount_block_is_active'] && !$this->_membershipBlock['is_active'] && !$this->_priceSetId) { CRM_Core_Error::fatal(ts('The requested online contribution page is missing a required Contribution Amount section or Membership section or Price Set. Please check with the site administrator for assistance.')); } if ($this->_values['amount_block_is_active']) { $this->set('amount_block_is_active', $this->_values['amount_block_is_active']); } $this->_contributeMode = $this->get('contributeMode'); $this->assign('contributeMode', $this->_contributeMode); //assigning is_monetary and is_email_receipt to template $this->assign('is_monetary', $this->_values['is_monetary']); $this->assign('is_email_receipt', $this->_values['is_email_receipt']); $this->assign('bltID', $this->_bltID); //assign cancelSubscription URL to templates $this->assign('cancelSubscriptionUrl', CRM_Utils_Array::value('cancelSubscriptionUrl', $this->_values)); // assigning title to template in case someone wants to use it, also setting CMS page title if ($this->_pcpId) { $this->assign('title', $this->_pcpInfo['title']); CRM_Utils_System::setTitle($this->_pcpInfo['title']); } else { $this->assign('title', $this->_values['title']); CRM_Utils_System::setTitle($this->_values['title']); } $this->_defaults = array(); $this->_amount = $this->get('amount'); //CRM-6907 $config = CRM_Core_Config::singleton(); $config->defaultCurrency = CRM_Utils_Array::value('currency', $this->_values, $config->defaultCurrency); //lets allow user to override campaign. $campID = CRM_Utils_Request::retrieve('campID', 'Positive', $this); if ($campID && CRM_Core_DAO::getFieldValue('CRM_Campaign_DAO_Campaign', $campID)) { $this->_values['campaign_id'] = $campID; } //do check for cancel recurring and clean db, CRM-7696 if (CRM_Utils_Request::retrieve('cancel', 'Boolean', CRM_Core_DAO::$_nullObject)) { self::cancelRecurring(); } }
/** * Format profile contact parameters. * * @param array $params * @param $fields * @param int $contactID * @param int $ufGroupId * @param null $ctype * @param bool $skipCustom * * @return array */ public static function formatProfileContactParams(&$params, &$fields, $contactID = NULL, $ufGroupId = NULL, $ctype = NULL, $skipCustom = FALSE) { $data = $contactDetails = array(); // get the contact details (hier) if ($contactID) { list($details, $options) = self::getHierContactDetails($contactID, $fields); $contactDetails = $details[$contactID]; $data['contact_type'] = CRM_Utils_Array::value('contact_type', $contactDetails); $data['contact_sub_type'] = CRM_Utils_Array::value('contact_sub_type', $contactDetails); } else { //we should get contact type only if contact if ($ufGroupId) { $data['contact_type'] = CRM_Core_BAO_UFField::getProfileType($ufGroupId); //special case to handle profile with only contact fields if ($data['contact_type'] == 'Contact') { $data['contact_type'] = 'Individual'; } elseif (CRM_Contact_BAO_ContactType::isaSubType($data['contact_type'])) { $data['contact_type'] = CRM_Contact_BAO_ContactType::getBasicType($data['contact_type']); } } elseif ($ctype) { $data['contact_type'] = $ctype; } else { $data['contact_type'] = 'Individual'; } } //fix contact sub type CRM-5125 if (array_key_exists('contact_sub_type', $params) && !empty($params['contact_sub_type'])) { $data['contact_sub_type'] = CRM_Utils_Array::implodePadded($params['contact_sub_type']); } elseif (array_key_exists('contact_sub_type_hidden', $params) && !empty($params['contact_sub_type_hidden'])) { // if profile was used, and had any subtype, we obtain it from there //CRM-13596 - add to existing contact types, rather than overwriting $data_contact_sub_type_arr = CRM_Utils_Array::explodePadded($data['contact_sub_type']); if (!in_array($params['contact_sub_type_hidden'], $data_contact_sub_type_arr)) { $data['contact_sub_type'] .= CRM_Utils_Array::implodePadded($params['contact_sub_type_hidden']); } } if ($ctype == 'Organization') { $data['organization_name'] = CRM_Utils_Array::value('organization_name', $contactDetails); } elseif ($ctype == 'Household') { $data['household_name'] = CRM_Utils_Array::value('household_name', $contactDetails); } $locationType = array(); $count = 1; if ($contactID) { //add contact id $data['contact_id'] = $contactID; $primaryLocationType = self::getPrimaryLocationType($contactID); } else { $defaultLocation = CRM_Core_BAO_LocationType::getDefault(); $defaultLocationId = $defaultLocation->id; } $billingLocationTypeId = CRM_Core_BAO_LocationType::getBilling(); $blocks = array('email', 'phone', 'im', 'openid'); $multiplFields = array('url'); // prevent overwritten of formatted array, reset all block from // params if it is not in valid format (since import pass valid format) foreach ($blocks as $blk) { if (array_key_exists($blk, $params) && !is_array($params[$blk])) { unset($params[$blk]); } } $primaryPhoneLoc = NULL; $session = CRM_Core_Session::singleton(); foreach ($params as $key => $value) { $locTypeId = $typeId = NULL; list($fieldName, $locTypeId, $typeId) = CRM_Utils_System::explode('-', $key, 3); //store original location type id $actualLocTypeId = $locTypeId; if ($locTypeId == 'Primary') { if ($contactID) { if (in_array($fieldName, $blocks)) { $locTypeId = self::getPrimaryLocationType($contactID, FALSE, $fieldName); } else { $locTypeId = self::getPrimaryLocationType($contactID, FALSE, 'address'); } $primaryLocationType = $locTypeId; } else { $locTypeId = $defaultLocationId; } } if (is_numeric($locTypeId) && !in_array($fieldName, $multiplFields) && substr($fieldName, 0, 7) != 'custom_') { $index = $locTypeId; if (is_numeric($typeId)) { $index .= '-' . $typeId; } if (!in_array($index, $locationType)) { $locationType[$count] = $index; $count++; } $loc = CRM_Utils_Array::key($index, $locationType); $blockName = in_array($fieldName, $blocks) ? $fieldName : 'address'; $data[$blockName][$loc]['location_type_id'] = $locTypeId; //set is_billing true, for location type "Billing" if ($locTypeId == $billingLocationTypeId) { $data[$blockName][$loc]['is_billing'] = 1; } if ($contactID) { //get the primary location type if ($locTypeId == $primaryLocationType) { $data[$blockName][$loc]['is_primary'] = 1; } } elseif ($locTypeId == $defaultLocationId) { $data[$blockName][$loc]['is_primary'] = 1; } if (in_array($fieldName, array('phone'))) { if ($typeId) { $data['phone'][$loc]['phone_type_id'] = $typeId; } else { $data['phone'][$loc]['phone_type_id'] = ''; } $data['phone'][$loc]['phone'] = $value; //special case to handle primary phone with different phone types // in this case we make first phone type as primary if (isset($data['phone'][$loc]['is_primary']) && !$primaryPhoneLoc) { $primaryPhoneLoc = $loc; } if ($loc != $primaryPhoneLoc) { unset($data['phone'][$loc]['is_primary']); } } elseif ($fieldName == 'phone_ext') { $data['phone'][$loc]['phone_ext'] = $value; } elseif ($fieldName == 'email') { $data['email'][$loc]['email'] = $value; if (empty($contactID)) { $data['email'][$loc]['is_primary'] = 1; } } elseif ($fieldName == 'im') { if (isset($params[$key . '-provider_id'])) { $data['im'][$loc]['provider_id'] = $params[$key . '-provider_id']; } if (strpos($key, '-provider_id') !== FALSE) { $data['im'][$loc]['provider_id'] = $params[$key]; } else { $data['im'][$loc]['name'] = $value; } } elseif ($fieldName == 'openid') { $data['openid'][$loc]['openid'] = $value; } else { if ($fieldName === 'state_province') { // CRM-3393 if (is_numeric($value) && (int) $value >= 1000) { $data['address'][$loc]['state_province_id'] = $value; } elseif (empty($value)) { $data['address'][$loc]['state_province_id'] = ''; } else { $data['address'][$loc]['state_province'] = $value; } } elseif ($fieldName === 'country') { // CRM-3393 if (is_numeric($value) && (int) $value >= 1000) { $data['address'][$loc]['country_id'] = $value; } elseif (empty($value)) { $data['address'][$loc]['country_id'] = ''; } else { $data['address'][$loc]['country'] = $value; } } elseif ($fieldName === 'county') { $data['address'][$loc]['county_id'] = $value; } elseif ($fieldName == 'address_name') { $data['address'][$loc]['name'] = $value; } elseif (substr($fieldName, 0, 14) === 'address_custom') { $data['address'][$loc][substr($fieldName, 8)] = $value; } else { $data['address'][$loc][$fieldName] = $value; } } } else { if (substr($key, 0, 4) === 'url-') { $websiteField = explode('-', $key); $data['website'][$websiteField[1]]['website_type_id'] = $websiteField[1]; $data['website'][$websiteField[1]]['url'] = $value; } elseif (in_array($key, self::$_greetingTypes, TRUE)) { //save email/postal greeting and addressee values if any, CRM-4575 $data[$key . '_id'] = $value; } elseif (!$skipCustom && ($customFieldId = CRM_Core_BAO_CustomField::getKeyID($key))) { // for autocomplete transfer hidden value instead of label if ($params[$key] && isset($params[$key . '_id'])) { $value = $params[$key . '_id']; } // we need to append time with date if ($params[$key] && isset($params[$key . '_time'])) { $value .= ' ' . $params[$key . '_time']; } // if auth source is not checksum / login && $value is blank, do not proceed - CRM-10128 if (($session->get('authSrc') & CRM_Core_Permission::AUTH_SRC_CHECKSUM + CRM_Core_Permission::AUTH_SRC_LOGIN) == 0 && ($value == '' || !isset($value))) { continue; } $valueId = NULL; if (!empty($params['customRecordValues'])) { if (is_array($params['customRecordValues']) && !empty($params['customRecordValues'])) { foreach ($params['customRecordValues'] as $recId => $customFields) { if (is_array($customFields) && !empty($customFields)) { foreach ($customFields as $customFieldName) { if ($customFieldName == $key) { $valueId = $recId; break; } } } } } } //CRM-13596 - check for contact_sub_type_hidden first if (array_key_exists('contact_sub_type_hidden', $params)) { $type = $params['contact_sub_type_hidden']; } else { $type = $data['contact_type']; if (!empty($data['contact_sub_type'])) { $type = $data['contact_sub_type']; $type = CRM_Utils_Array::explodePadded($type); // generally a contact even if, has multiple subtypes the parent-type is going to be one only // and since formatCustomField() would be interested in parent type, lets consider only one subtype // as the results going to be same. $type = $type[0]; } } CRM_Core_BAO_CustomField::formatCustomField($customFieldId, $data['custom'], $value, $type, $valueId, $contactID); } elseif ($key == 'edit') { continue; } else { if ($key == 'location') { foreach ($value as $locationTypeId => $field) { foreach ($field as $block => $val) { if ($block == 'address' && array_key_exists('address_name', $val)) { $value[$locationTypeId][$block]['name'] = $value[$locationTypeId][$block]['address_name']; } } } } if ($key == 'phone' && isset($params['phone_ext'])) { $data[$key] = $value; foreach ($value as $cnt => $phoneBlock) { if ($params[$key][$cnt]['location_type_id'] == $params['phone_ext'][$cnt]['location_type_id']) { $data[$key][$cnt]['phone_ext'] = CRM_Utils_Array::retrieveValueRecursive($params['phone_ext'][$cnt], 'phone_ext'); } } } elseif (in_array($key, array('nick_name', 'job_title', 'middle_name', 'birth_date', 'gender_id', 'current_employer', 'prefix_id', 'suffix_id')) && ($value == '' || !isset($value)) && ($session->get('authSrc') & CRM_Core_Permission::AUTH_SRC_CHECKSUM + CRM_Core_Permission::AUTH_SRC_LOGIN) == 0 || $key == 'current_employer' && empty($params['current_employer'])) { // CRM-10128: if auth source is not checksum / login && $value is blank, do not fill $data with empty value // to avoid update with empty values continue; } else { $data[$key] = $value; } } } } if (!isset($data['contact_type'])) { $data['contact_type'] = 'Individual'; } //set the values for checkboxes (do_not_email, do_not_mail, do_not_trade, do_not_phone) $privacy = CRM_Core_SelectValues::privacy(); foreach ($privacy as $key => $value) { if (array_key_exists($key, $fields)) { // do not reset values for existing contacts, if fields are added to a profile if (array_key_exists($key, $params)) { $data[$key] = $params[$key]; if (empty($params[$key])) { $data[$key] = 0; } } elseif (!$contactID) { $data[$key] = 0; } } } return array($data, $contactDetails); }