Пример #1
0
 /**
  * @param CRM_Contribute_Form_Contribution_Main|CRM_Event_Form_Registration_Register|CRM_Financial_Form_Payment $form
  * @param null $type
  * @param null $mode
  *
  * @throws Exception
  */
 public static function preProcess(&$form, $type = NULL, $mode = NULL)
 {
     if ($type) {
         $form->_type = $type;
     } else {
         $form->_type = CRM_Utils_Request::retrieve('type', 'String', $form);
     }
     if ($form->_type) {
         $form->_paymentProcessor = CRM_Financial_BAO_PaymentProcessor::getPayment($form->_type, $form->_mode);
     }
     if (empty($form->_paymentProcessor)) {
         // This would happen when hitting the back-button on a multi-page form with a $0 selection in play.
         return;
     }
     $form->set('paymentProcessor', $form->_paymentProcessor);
     $form->_paymentObject = System::singleton()->getByProcessor($form->_paymentProcessor);
     $form->assign('suppressSubmitButton', $form->_paymentObject->isSuppressSubmitButtons());
     $form->assign('currency', CRM_Utils_Array::value('currency', $form->_values));
     // also set cancel subscription url
     if (!empty($form->_paymentProcessor['is_recur']) && !empty($form->_values['is_recur'])) {
         $form->_values['cancelSubscriptionUrl'] = $form->_paymentObject->subscriptionURL(NULL, NULL, 'cancel');
     }
     if (!empty($form->_values['custom_pre_id'])) {
         $profileAddressFields = array();
         $fields = CRM_Core_BAO_UFGroup::getFields($form->_values['custom_pre_id'], FALSE, CRM_Core_Action::ADD, NULL, NULL, FALSE, NULL, FALSE, NULL, CRM_Core_Permission::CREATE, NULL);
         foreach ((array) $fields as $key => $value) {
             CRM_Core_BAO_UFField::assignAddressField($key, $profileAddressFields, array('uf_group_id' => $form->_values['custom_pre_id']));
         }
         if (count($profileAddressFields)) {
             $form->set('profileAddressFields', $profileAddressFields);
         }
     }
     //checks after setting $form->_paymentProcessor
     // we do this outside of the above conditional to avoid
     // saving the country/state list in the session (which could be huge)
     CRM_Core_Payment_Form::setPaymentFieldsByProcessor($form, $form->_paymentProcessor, CRM_Utils_Request::retrieve('billing_profile_id', 'String'));
     $form->assign_by_ref('paymentProcessor', $form->_paymentProcessor);
     // check if this is a paypal auto return and redirect accordingly
     //@todo - determine if this is legacy and remove
     if (CRM_Core_Payment::paypalRedirect($form->_paymentProcessor)) {
         $url = CRM_Utils_System::url('civicrm/contribute/transact', "_qf_ThankYou_display=1&qfKey={$form->controller->_key}");
         CRM_Utils_System::redirect($url);
     }
     // make sure we have a valid payment class, else abort
     if (!empty($form->_values['is_monetary']) && !$form->_paymentProcessor['class_name'] && empty($form->_values['is_pay_later'])) {
         CRM_Core_Error::fatal(ts('Payment processor is not set for this page'));
     }
     if (!empty($form->_membershipBlock) && !empty($form->_membershipBlock['is_separate_payment']) && (!empty($form->_paymentProcessor['class_name']) && !$form->_paymentObject->supports('MultipleConcurrentPayments'))) {
         CRM_Core_Error::fatal(ts('This contribution page is configured to support separate contribution and membership payments. This %1 plugin does not currently support multiple simultaneous payments, or the option to "Execute real-time monetary transactions" is disabled. Please contact the site administrator and notify them of this error', array(1 => $form->_paymentProcessor['payment_processor_type'])));
     }
 }
Пример #2
0
 public function testSettingUrl()
 {
     /** @var CRM_Core_Payment_Dummy $processor */
     $processor = \Civi\Payment\System::singleton()->getById($this->processorCreate());
     $success = 'http://success.com';
     $cancel = 'http://cancel.com';
     $processor->setCancelUrl($cancel);
     $processor->setSuccessUrl($success);
     // Using ReflectionUtils to access protected methods
     $successGetter = new ReflectionMethod($processor, 'getReturnSuccessUrl');
     $successGetter->setAccessible(TRUE);
     $this->assertEquals($success, $successGetter->invoke($processor, NULL));
     $cancelGetter = new ReflectionMethod($processor, 'getReturnFailUrl');
     $cancelGetter->setAccessible(TRUE);
     $this->assertEquals($cancel, $cancelGetter->invoke($processor, NULL));
 }
 /**
  * @param CRM_Contribute_Form_Contribution_Main|CRM_Event_Form_Registration_Register|CRM_Financial_Form_Payment $form
  * @param null $type
  * @param null $mode
  *
  * @throws Exception
  */
 public static function preProcess(&$form, $type = NULL, $mode = NULL)
 {
     if ($type) {
         $form->_type = $type;
     } else {
         $form->_type = CRM_Utils_Request::retrieve('type', 'String', $form);
     }
     if ($form->_type) {
         $form->_paymentProcessor = CRM_Financial_BAO_PaymentProcessor::getPayment($form->_type, $form->_mode);
     }
     $form->set('paymentProcessor', $form->_paymentProcessor);
     $form->_paymentObject = Civi\Payment\System::singleton()->getByProcessor($form->_paymentProcessor);
     $form->assign('suppressSubmitButton', $form->_paymentObject->isSuppressSubmitButtons());
     // also set cancel subscription url
     if (!empty($form->_paymentProcessor['is_recur']) && !empty($form->_values['is_recur'])) {
         $form->_values['cancelSubscriptionUrl'] = $form->_paymentObject->subscriptionURL();
     }
     //checks after setting $form->_paymentProcessor
     // we do this outside of the above conditional to avoid
     // saving the country/state list in the session (which could be huge)
     CRM_Core_Payment_Form::setPaymentFieldsByProcessor($form, $form->_paymentProcessor);
     $form->assign_by_ref('paymentProcessor', $form->_paymentProcessor);
     // check if this is a paypal auto return and redirect accordingly
     //@todo - determine if this is legacy and remove
     if (CRM_Core_Payment::paypalRedirect($form->_paymentProcessor)) {
         $url = CRM_Utils_System::url('civicrm/contribute/transact', "_qf_ThankYou_display=1&qfKey={$form->controller->_key}");
         CRM_Utils_System::redirect($url);
     }
     // make sure we have a valid payment class, else abort
     if (!empty($form->_values['is_monetary']) && !$form->_paymentProcessor['class_name'] && empty($form->_values['is_pay_later'])) {
         CRM_Core_Error::fatal(ts('Payment processor is not set for this page'));
     }
     if (!empty($form->_membershipBlock) && !empty($form->_membershipBlock['is_separate_payment']) && (!empty($form->_paymentProcessor['class_name']) && !$form->_paymentObject->supports('MultipleConcurrentPayments'))) {
         CRM_Core_Error::fatal(ts('This contribution page is configured to support separate contribution and membership payments. This %1 plugin does not currently support multiple simultaneous payments, or the option to "Execute real-time monetary transactions" is disabled. Please contact the site administrator and notify them of this error', array(1 => $form->_paymentProcessor['payment_processor_type'])));
     }
 }
Пример #4
0
 /**
  * Payment callback handler.
  *
  * The processor_name or processor_id is passed in.
  * Note that processor_id is more reliable as one site may have more than one instance of a
  * processor & ideally the processor will be validating the results
  * Load requested payment processor and call that processor's handle<$method> method
  *
  * @todo move to \Civi\Payment\System factory method
  *
  * @param string $method
  *   'PaymentNotification' or 'PaymentCron'
  * @param array $params
  *
  * @throws \CRM_Core_Exception
  * @throws \Exception
  */
 public static function handlePaymentMethod($method, $params = array())
 {
     if (!isset($params['processor_id']) && !isset($params['processor_name'])) {
         $q = explode('/', CRM_Utils_Array::value('q', $params, ''));
         $lastParam = array_pop($q);
         if (is_numeric($lastParam)) {
             $params['processor_id'] = $_GET['processor_id'] = $lastParam;
         } else {
             throw new CRM_Core_Exception("Either 'processor_id' (recommended) or 'processor_name' (deprecated) is required for payment callback.");
         }
     }
     self::logPaymentNotification($params);
     $sql = "SELECT ppt.class_name, ppt.name as processor_name, pp.id AS processor_id\n              FROM civicrm_payment_processor_type ppt\n        INNER JOIN civicrm_payment_processor pp\n                ON pp.payment_processor_type_id = ppt.id\n               AND pp.is_active";
     if (isset($params['processor_id'])) {
         $sql .= " WHERE pp.id = %2";
         $args[2] = array($params['processor_id'], 'Integer');
         $notFound = ts("No active instances of payment processor %1 were found.", array(1 => $params['processor_id']));
     } else {
         // This is called when processor_name is passed - passing processor_id instead is recommended.
         $sql .= " WHERE ppt.name = %2 AND pp.is_test = %1";
         $args[1] = array(CRM_Utils_Array::value('mode', $params) == 'test' ? 1 : 0, 'Integer');
         $args[2] = array($params['processor_name'], 'String');
         $notFound = ts("No active instances of payment processor '%1' were found.", array(1 => $params['processor_name']));
     }
     $dao = CRM_Core_DAO::executeQuery($sql, $args);
     // Check whether we found anything at all.
     if (!$dao->N) {
         CRM_Core_Error::fatal($notFound);
     }
     $method = 'handle' . $method;
     $extension_instance_found = FALSE;
     // In all likelihood, we'll just end up with the one instance returned here. But it's
     // possible we may get more. Hence, iterate through all instances ..
     while ($dao->fetch()) {
         // Check pp is extension - is this still required - surely the singleton below handles it.
         $ext = CRM_Extension_System::singleton()->getMapper();
         if ($ext->isExtensionKey($dao->class_name)) {
             $paymentClass = $ext->keyToClass($dao->class_name, 'payment');
             require_once $ext->classToPath($paymentClass);
         }
         $processorInstance = Civi\Payment\System::singleton()->getById($dao->processor_id);
         // Should never be empty - we already established this processor_id exists and is active.
         if (empty($processorInstance)) {
             continue;
         }
         // Does PP implement this method, and can we call it?
         if (!method_exists($processorInstance, $method) || !is_callable(array($processorInstance, $method))) {
             // on the off chance there is a double implementation of this processor we should keep looking for another
             // note that passing processor_id is more reliable & we should work to deprecate processor_name
             continue;
         }
         // Everything, it seems, is ok - execute pp callback handler
         $processorInstance->{$method}();
         $extension_instance_found = TRUE;
     }
     if (!$extension_instance_found) {
         $message = "No extension instances of the '%1' payment processor were found.<br />" . "%2 method is unsupported in legacy payment processors.";
         CRM_Core_Error::fatal(ts($message, array(1 => $params['processor_name'], 2 => $method)));
     }
 }
Пример #5
0
 /**
  * Clean up financial entities after financial tests (so we remember to get all the tables :-))
  */
 public function quickCleanUpFinancialEntities()
 {
     $tablesToTruncate = array('civicrm_activity', 'civicrm_activity_contact', 'civicrm_contribution', 'civicrm_contribution_soft', 'civicrm_contribution_product', 'civicrm_financial_trxn', 'civicrm_financial_item', 'civicrm_contribution_recur', 'civicrm_line_item', 'civicrm_contribution_page', 'civicrm_payment_processor', 'civicrm_entity_financial_trxn', 'civicrm_membership', 'civicrm_membership_type', 'civicrm_membership_payment', 'civicrm_membership_log', 'civicrm_membership_block', 'civicrm_event', 'civicrm_participant', 'civicrm_participant_payment', 'civicrm_pledge', 'civicrm_pledge_payment', 'civicrm_price_set_entity', 'civicrm_price_field_value', 'civicrm_price_field');
     $this->quickCleanup($tablesToTruncate);
     CRM_Core_DAO::executeQuery("DELETE FROM civicrm_membership_status WHERE name NOT IN('New', 'Current', 'Grace', 'Expired', 'Pending', 'Cancelled', 'Deceased')");
     $this->restoreDefaultPriceSetConfig();
     $var = TRUE;
     CRM_Member_BAO_Membership::createRelatedMemberships($var, $var, TRUE);
     System::singleton()->flushProcessors();
 }
Пример #6
0
 /**
  * Set variables up before form is built.
  *
  * @throws \CRM_Contribute_Exception_InactiveContributionPageException
  * @throws \Exception
  */
 public function preProcess()
 {
     $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');
     //Check if honor block is enabled for current contribution
     $ufJoinParams = array('module' => 'soft_credit', 'entity_table' => 'civicrm_contribution_page', 'entity_id' => $this->_id);
     $ufJoin = new CRM_Core_DAO_UFJoin();
     $ufJoin->copyValues($ufJoinParams);
     $ufJoin->find(TRUE);
     $this->_honor_block_is_active = $ufJoin->is_active;
     $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 comma 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);
         if (empty($this->_values['is_active'])) {
             throw new CRM_Contribute_Exception_InactiveContributionPageException(ts('The page you requested is currently unavailable.'), $this->_id);
         }
         $this->assignBillingType();
         // 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 || !empty($this->_values['payment_processor']))) {
             $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).'));
             }
             $paymentProcessorIDs = explode(CRM_Core_DAO::VALUE_SEPARATOR, $ppID);
             $this->_paymentProcessors = CRM_Financial_BAO_PaymentProcessor::getPayments($paymentProcessorIDs, $this->_mode);
             $this->set('paymentProcessors', $this->_paymentProcessors);
             if (!empty($this->_paymentProcessors)) {
                 foreach ($this->_paymentProcessors as $paymentProcessorID => $paymentProcessorDetail) {
                     if (($processor = Civi\Payment\System::singleton()->getByProcessor($paymentProcessorDetail)) != FALSE) {
                         // We don't really know why we do this.
                         $this->_paymentObject = $processor;
                     }
                     if (empty($this->_paymentProcessor) && $paymentProcessorDetail['is_default'] == 1 || count($this->_paymentProcessors) == 1) {
                         $this->_paymentProcessor = $paymentProcessorDetail;
                         $this->assign('paymentProcessor', $this->_paymentProcessor);
                     }
                 }
                 if (empty($this->_paymentObject)) {
                     throw new CRM_Core_Exception(ts('No valid payment processor'));
                 }
             } else {
                 throw new CRM_Core_Exception(ts('A payment processor configured for this page might be disabled (contact the site administrator for assistance).'));
             }
         }
         // 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', '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 (!empty($this->_values['pledge_block_id'])) {
         $this->assign('pledgeBlock', TRUE);
     }
     // check if one of the (amount , membership)  blocks 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();
     }
     // check if billing block is required for pay later
     if (CRM_Utils_Array::value('is_pay_later', $this->_values)) {
         $this->_isBillingAddressRequiredForPayLater = CRM_Utils_Array::value('is_billing_required', $this->_values);
         $this->assign('isBillingAddressRequiredForPayLater', $this->_isBillingAddressRequiredForPayLater);
     }
 }