diff --git a/includes/redhen_donation.forms.inc b/includes/redhen_donation.forms.inc index b691a43..cb1a23b 100644 --- a/includes/redhen_donation.forms.inc +++ b/includes/redhen_donation.forms.inc @@ -268,6 +268,54 @@ function redhen_donation_entity_settings_form($form, &$form_state, $settings, $e ), ); + $form['settings']['suggestion'] = array( + '#type' => 'fieldset', + '#title' => t('Personalize Donation Suggestions'), + '#description' => t('Suggest a donation amount based on prior donations.'), + '#collapsible' => FALSE, + '#tree' => TRUE, + '#states' => array( + 'invisible' => array( + ':input[name="settings[donation_entry]"]' => array('value' => 'custom'), + ), + ), + ); + $form['settings']['suggestion']['donation_suggestion'] = array( + '#type' => 'select', + '#title' => t('Donation suggestion basis'), + '#default_value' => isset($settings['settings']['suggestion']['donation_suggestion']) ? $settings['settings']['suggestion']['donation_suggestion'] : '', + '#options' => array( + '' => t('-- Disabled --'), + 'largest' => "Largest Donation Amount", + ), + ); + $form['settings']['suggestion']['suggestion_minimum'] = array( + '#type' => 'textfield', + '#title' => t('Suggestion Minimum'), + '#default_value' => isset($settings['settings']['suggestion']['suggestion_minimum']) ? $settings['settings']['suggestion']['suggestion_minimum'] : 0, + '#description' => t('The smallest prior donation amount on which to base donations (useful to avoid extremely small donation suggestions if you have very small-value donors.)'), + '#size' => 10, + '#element_validate' => array('element_validate_number'), + '#states' => array( + 'invisible' => array( + ':input[name="settings[donation_suggestion]"]' => array('value' => ''), + ), + ), + ); + $form['settings']['suggestion']['suggestion_increment'] = array( + '#type' => 'textfield', + '#title' => t('Suggestion multiplier'), + '#default_value' => isset($settings['settings']['suggestion']['suggestion_increment']) ? $settings['settings']['suggestion']['suggestion_increment'] : '1.3', + '#element_validate' => array('element_validate_number'), + '#description' => t('When suggesting donation amounts, what should each amount be generated by to generate the next suggestion?'), + '#size' => 10, + '#states' => array( + 'invisible' => array( + ':input[name="settings[donation_suggestion]"]' => array('value' => ''), + ), + ), + ); + $form['settings']['submit_label'] = array( '#type' => 'textfield', '#title' => t('Submit button'), @@ -611,7 +659,8 @@ function redhen_donation_form($form, &$form_state, RedhenDonation $donation, $us else { $default_product = reset($products); } - if (commerce_recurring_product_is_recurring($default_product) && !empty($settings['settings']['recurring_donation_amounts'])) { + $recurring_default = commerce_recurring_product_is_recurring($default_product); + if ($recurring_default && !empty($settings['settings']['recurring_donation_amounts'])) { $amount_options = $settings['settings']['recurring_donation_amounts']; } else { @@ -626,6 +675,17 @@ function redhen_donation_form($form, &$form_state, RedhenDonation $donation, $us $donation_amounts_default = isset($settings['settings']['donation_amounts_default']) ? $settings['settings']['donation_amounts_default'] : ''; $amount_label = isset($settings['settings']['donation_amounts_label']) ? $settings['settings']['donation_amounts_label'] : 'Donation Amount (@cur)'; $amount_title = format_string($amount_label, array('@cur' => $cur)); + if (!empty($settings['settings']['suggestion']['donation_suggestion']) && $contact_wrapper->getIdentifier()) { + $suggestion_config = array( + 'style' => $settings['settings']['suggestion']['donation_suggestion'], + 'recurring' => $recurring_default, + 'currency' => $cur, + 'minimum' => $settings['settings']['suggestion']['suggestion_minimum'], + 'increment' => $settings['settings']['suggestion']['suggestion_increment'], + 'max' => NULL, + ); + _redhen_donation_suggest_donation($donation_amounts_default, $donation_amounts, $contact_wrapper, $suggestion_config); + } switch ($settings['settings']['donation_entry']) { case 'select': case 'radios': @@ -648,9 +708,12 @@ function redhen_donation_form($form, &$form_state, RedhenDonation $donation, $us '#default_value' => $donation_amounts_default, '#other' => isset($settings['settings']['other_label']) ? $settings['settings']['other_label'] : t('Other'), '#other_description' => t('Please enter an amount.'), + '#other_size' => 5, '#other_unknown_defaults' => 'other', '#other_delimiter' => ', ', '#select_type' => $settings['settings']['donation_entry'] == 'select_other' ? 'select' : 'radios', + '#field_widget' => 'select_or_other_buttons', + '#maxlength' => 30, ); break; @@ -754,6 +817,49 @@ function redhen_donation_amount_options_callback($form, $form_state) { } /** + * Helper function to generate custom donation amount options for a Contact. + * + * @int $donation_amounts_default + * Reference to the default donation amount so it can be altered. + * @array $donation_amounts + * Reference to the Options array for use in a select or radio field. + * @entityMetadataWrapper $contact_wrapper + * Redhen Contact Wrapper: the Contact to suggest amounts for. + * @array $config + * Relevant configuration information. + */ +function _redhen_donation_suggest_donation(&$donation_amounts_default, &$donation_amounts, $contact_wrapper, $config) { + switch ($config['style']) { + case "largest": + $transaction_type = $config['recurring'] ? 'commerce_order_recurring' : 'commerce_order'; + $lower_bound = !empty($config['minimum']) ? $config['minimum'] : min(array_keys($donation_amounts)); + // Find largest historical donation of this type: + $query = new EntityFieldQuery(); + $query->entityCondition('entity_type', 'redhen_donation') + ->propertyCondition('contact_id', $contact_wrapper->getIdentifier(), '=') + ->propertyCondition('transaction_entity_type', $transaction_type, '=') + ->propertyCondition('received', 100 * $lower_bound, '>=') + ->propertyOrderBy('received', 'DESC'); + $result = $query->execute(); + if (!empty($result['redhen_donation'])) { + // Found a donation, build new amounts array: + $first = reset($result['redhen_donation']); + $largest_donation = redhen_donation_load($first->donation_id); + // Round past maximum to nearest $5 for new suggestion. + $amount = 5 * round($largest_donation->received / 500); + $new_amounts = array(); + while (count($donation_amounts) > count($new_amounts)) { + $new_amounts[$amount] = $config['currency'] . $amount; + // Increase amount for next loop, round to nearest $10: + $amount = 10 * round($amount * $config['increment'] / 10); + } + $donation_amounts = $new_amounts; + } + break; + } +} + +/** * Set defaults based on URL query parameters. * * Takes an element array, and recursively sets form default_values on children