From 2045389ad70161f3473737e88a713d1fd9b7f0cf Mon Sep 17 00:00:00 2001 From: Tim Otten Date: Tue, 4 Aug 2015 21:59:06 -0700 Subject: [PATCH] CRM-13422 - CRM_Contribute_ActionMapping_ByPage --- CRM/Contribute/ActionMapping/ByPage.php | 206 ++++++++++++++++++++++++ CRM/Contribute/Tokens.php | 131 +++++++++++++++ Civi/Core/Container.php | 3 +- Civi/Token/TokenRow.php | 40 +++++ 4 files changed, 379 insertions(+), 1 deletion(-) create mode 100644 CRM/Contribute/ActionMapping/ByPage.php create mode 100644 CRM/Contribute/Tokens.php diff --git a/CRM/Contribute/ActionMapping/ByPage.php b/CRM/Contribute/ActionMapping/ByPage.php new file mode 100644 index 0000000000..5d13360b35 --- /dev/null +++ b/CRM/Contribute/ActionMapping/ByPage.php @@ -0,0 +1,206 @@ +register(new static()); + } + + /** + * @return mixed + */ + public function getId() { + return self::MAPPING_ID; + } + + /** + * @return string + */ + public function getEntity() { + return 'civicrm_contribution'; + } + + /** + * Get a printable label for this mapping type. + * + * @return string + */ + public function getLabel() { + return ts('Contribution Page'); + } + + /** + * Get a printable label to use as the header on the 'value' filter. + * + * @return string + */ + public function getValueHeader() { + return ts('Contribution Page'); + } + + /** + * Get a printable label to use as the header on the 'status' filter. + * + * @return string + */ + public function getStatusHeader() { + return ts('Contribution Status'); + } + + /** + * Get a list of value options. + * + * @return array + * Array(string $value => string $label). + * Ex: array(123 => 'Phone Call', 456 => 'Meeting'). + * @throws CRM_Core_Exception + */ + public function getValueLabels() { + return CRM_Contribute_BAO_Contribution::buildOptions('contribution_page_id', 'get', array()); + } + + /** + * Get a list of status options. + * + * @param string|int $value + * The list of status options may be contingent upon the selected filter value. + * This is the selected filter value. + * @return array + * Array(string $value => string $label). + * Ex: Array(123 => 'Completed', 456 => 'Scheduled'). + * @throws CRM_Core_Exception + */ + public function getStatusLabels($value) { + return CRM_Contribute_BAO_Contribution::buildOptions('contribution_status_id', 'get', array()); + } + + /** + * Get a list of available date fields. + * + * @return array + * Array(string $fieldName => string $fieldLabel). + */ + public function getDateFields() { + return array( + 'receive_date' => ts('Receive Date'), + 'cancel_date' => ts('Cancel Date'), + 'receipt_date' => ts('Receipt Date'), + 'thankyou_date' => ts('Thank You Date'), + ); + } + + /** + * FIXME: Unsure. Not sure how it differs from getRecipientTypes... but it does... + * + * @param string $recipientType + * @return array + * Array(mixed $name => string $label). + * Ex: array(1 => 'Attendee', 2 => 'Volunteer'). + */ + public function getRecipientListing($recipientType) { + return array(); + } + + /** + * FIXME: Unsure. Not sure how it differs from getRecipientListing... but it does... + * + * @param bool|NULL $noThanksJustKidding + * This is ridiculous and should not exist. + * If true, don't do our main job. + * @return array + * array(mixed $value => string $label). + * Ex: array('assignee' => 'Activity Assignee'). + */ + public function getRecipientTypes($noThanksJustKidding = FALSE) { + return array(); + } + + /** + * 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; + } + +} diff --git a/CRM/Contribute/Tokens.php b/CRM/Contribute/Tokens.php new file mode 100644 index 0000000000..2c32fee77f --- /dev/null +++ b/CRM/Contribute/Tokens.php @@ -0,0 +1,131 @@ + 'contribution_id', + 'payment_instrument' => 'payment_instrument_id', + 'source' => 'contribution_source', + 'status' => 'contribution_status_id', + 'type' => 'financial_type_id', + ); + } + + public function __construct() { + $tokens = CRM_Utils_Array::subset( + CRM_Utils_Array::collect('title', CRM_Contribute_DAO_Contribution::fields()), + $this->getPassthruTokens() + ); + $tokens['id'] = ts('Contribution ID'); + $tokens['payment_instrument'] = ts('Payment Instrument'); + $tokens['source'] = ts('Contribution Source'); + $tokens['status'] = ts('Contribution Status'); + $tokens['type'] = ts('Financial Type'); + parent::__construct('contribution', $tokens); + } + + public function checkActive(\Civi\Token\TokenProcessor $processor) { + return + !empty($processor->context['actionMapping']) + && $processor->context['actionMapping']->getEntity() === 'civicrm_contribution'; + } + + public function alterActionScheduleQuery(\Civi\ActionSchedule\Event\MailingQueryEvent $e) { + if ($e->mapping->getEntity() !== 'civicrm_contribution') { + return; + } + + $fields = CRM_Contribute_DAO_Contribution::fields(); + foreach ($this->getPassthruTokens() as $token) { + $e->query->select("e." . $fields[$token]['name'] . " AS contrib_{$token}"); + } + foreach ($this->getAliasTokens() as $alias => $orig) { + $e->query->select("e." . $fields[$orig]['name'] . " AS contrib_{$alias}"); + } + } + + /** + * Evaluate the content of a single token. + * + * @param \Civi\Token\TokenRow $row + * The record for which we want token values. + * @param string $field + * The name of the token field. + * @param mixed $prefetch + * Any data that was returned by the prefetch(). + * @return mixed + */ + public function evaluateToken(\Civi\Token\TokenRow $row, $entity, $field, $prefetch = NULL) { + $actionSearchResult = $row->context['actionSearchResult']; + $fieldValue = isset($actionSearchResult->{"contrib_$field"}) ? $actionSearchResult->{"contrib_$field"} : NULL; + + $aliasTokens = $this->getAliasTokens(); + if (in_array($field, array('total_amount', 'fee_amount', 'net_amount'))) { + return $row->format('text/plain')->tokens($entity, $field, + \CRM_Utils_Money::format($fieldValue, $actionSearchResult->contrib_currency)); + } + elseif (isset($aliasTokens[$field])) { + $row->dbToken($entity, $field, 'CRM_Contribute_BAO_Contribution', $aliasTokens[$field], $fieldValue); + } + else { + $row->dbToken($entity, $field, 'CRM_Contribute_BAO_Contribution', $field, $fieldValue); + } + } + +} diff --git a/Civi/Core/Container.php b/Civi/Core/Container.php index fc6a477c5a..ea18bd198a 100644 --- a/Civi/Core/Container.php +++ b/Civi/Core/Container.php @@ -199,7 +199,7 @@ class Container { array() ))->addTag('kernel.event_subscriber'); - foreach (array('Activity', 'Event', 'Member') as $comp) { + foreach (array('Activity', 'Contribute', 'Event', 'Member') as $comp) { $container->setDefinition("crm_" . strtolower($comp) . "_tokens", new Definition( "CRM_{$comp}_Tokens", array() @@ -237,6 +237,7 @@ class Container { )); $dispatcher->addListener(\Civi\ActionSchedule\Events::MAPPINGS, array('CRM_Activity_ActionMapping', 'onRegisterActionMappings')); $dispatcher->addListener(\Civi\ActionSchedule\Events::MAPPINGS, array('CRM_Contact_ActionMapping', 'onRegisterActionMappings')); + $dispatcher->addListener(\Civi\ActionSchedule\Events::MAPPINGS, array('CRM_Contribute_ActionMapping_ByPage', 'onRegisterActionMappings')); $dispatcher->addListener(\Civi\ActionSchedule\Events::MAPPINGS, array('CRM_Event_ActionMapping', 'onRegisterActionMappings')); $dispatcher->addListener(\Civi\ActionSchedule\Events::MAPPINGS, array('CRM_Member_ActionMapping', 'onRegisterActionMappings')); diff --git a/Civi/Token/TokenRow.php b/Civi/Token/TokenRow.php index f05c2f7909..175c954e72 100644 --- a/Civi/Token/TokenRow.php +++ b/Civi/Token/TokenRow.php @@ -127,6 +127,46 @@ class TokenRow { return $this; } + /** + * Update the value of a token. Apply formatting based on DB schema. + * + * @param string $tokenEntity + * @param string $tokenField + * @param string $baoName + * @param array $baoField + * @param mixed $fieldValue + */ + public function dbToken($tokenEntity, $tokenField, $baoName, $baoField, $fieldValue) { + if ($fieldValue === NULL || $fieldValue === '') { + return $this->tokens($tokenEntity, $tokenField, ''); + } + + $fields = $baoName::fields(); + if (!empty($fields[$baoField]['pseudoconstant'])) { + $options = $baoName::buildOptions($baoField, 'get'); + return $this->format('text/plain')->tokens($tokenEntity, $tokenField, $options[$fieldValue]); + } + + switch ($fields[$baoField]['type']) { + case \CRM_Utils_Type::T_DATE + \CRM_Utils_Type::T_TIME: + return $this->format('text/plain')->tokens($tokenEntity, $tokenField, \CRM_Utils_Date::customFormat($fieldValue)); + + case \CRM_Utils_Type::T_MONEY: + // Is this something you should ever use? Seems like you need more context + // to know which currency to use. + return $this->format('text/plain')->tokens($tokenEntity, $tokenField, \CRM_Utils_Money::format($fieldValue)); + + case \CRM_Utils_Type::T_STRING: + case \CRM_Utils_Type::T_BOOLEAN: + case \CRM_Utils_Type::T_INT: + case \CRM_Utils_Type::T_TEXT: + return $this->format('text/plain')->tokens($tokenEntity, $tokenField, $fieldValue); + + } + + throw new \CRM_Core_Exception("Cannot format token for field '$baoField' in '$baoName'"); + } + /** * Auto-convert between different formats */ -- 2.25.1