Merge pull request #4962 from totten/master-angular-ts
[civicrm-core.git] / CRM / Core / Payment.php
index 70c025d946fc31e8982aaa635fec07b858d261cc..187f1c67eaf28d8d026647935b93c35f77f16a3d 100644 (file)
@@ -23,7 +23,9 @@
  | GNU Affero General Public License or the licensing of CiviCRM,     |
  | see the CiviCRM license FAQ at http://civicrm.org/licensing        |
  +--------------------------------------------------------------------+
-*/
+ */
+
+use Civi\Payment\System;
 
 /**
  *
@@ -32,7 +34,6 @@
  * $Id$
  *
  */
-
 abstract class CRM_Core_Payment {
 
   /**
@@ -52,7 +53,7 @@ abstract class CRM_Core_Payment {
    * credit card
    * direct debit
    * or both
-   *
+   * @todo create option group - nb omnipay uses a 3rd type - transparent redirect cc
    */
   const
     PAYMENT_TYPE_CREDIT_CARD = 1,
@@ -61,30 +62,18 @@ abstract class CRM_Core_Payment {
   /**
    * Subscription / Recurring payment Status
    * START, END
-   *
    */
   const
     RECURRING_PAYMENT_START = 'START',
     RECURRING_PAYMENT_END = 'END';
 
-  /**
-   * We only need one instance of this object. So we use the singleton
-   * pattern and cache the instance in this variable
-   *
-   * @var object
-   * @static
-   */
-  static private $_singleton = NULL;
-
   protected $_paymentProcessor;
 
-  /**
-   * @var CRM_Core_Form
-   */
-  protected $_paymentForm = NULL;
-
   /**
    * Singleton function used to manage this object
+   * We will migrate to calling Civi\Payment\System::singleton()->getByProcessor($paymentProcessor)
+   * & Civi\Payment\System::singleton()->getById($paymentProcessor) directly as the main access methods & work
+   * to remove this function all together
    *
    * @param string $mode
    *   The mode of operation: live or test.
@@ -96,9 +85,7 @@ abstract class CRM_Core_Payment {
    *   Should we force a reload of this payment object.
    *
    * @return CRM_Core_Payment
-   * @return \CRM_Core_Payment
    * @throws \CRM_Core_Exception
-   * @static
    */
   public static function &singleton($mode = 'test', &$paymentProcessor, &$paymentForm = NULL, $force = FALSE) {
     // make sure paymentProcessor is not empty
@@ -106,39 +93,15 @@ abstract class CRM_Core_Payment {
     if (empty($paymentProcessor)) {
       return CRM_Core_DAO::$_nullObject;
     }
-
-    $cacheKey = "{$mode}_{$paymentProcessor['id']}_" . (int) isset($paymentForm);
-
-    if (!isset(self::$_singleton[$cacheKey]) || $force) {
-      $config = CRM_Core_Config::singleton();
-      $ext = CRM_Extension_System::singleton()->getMapper();
-      if ($ext->isExtensionKey($paymentProcessor['class_name'])) {
-        $paymentClass = $ext->keyToClass($paymentProcessor['class_name'], 'payment');
-        require_once $ext->classToPath($paymentClass);
-      }
-      else {
-        $paymentClass = 'CRM_Core_' . $paymentProcessor['class_name'];
-        if (empty($paymentClass)) {
-          throw new CRM_Core_Exception('no class provided');
-        }
-        require_once str_replace('_', DIRECTORY_SEPARATOR, $paymentClass) . '.php';
-      }
-
-      //load the object.
-      self::$_singleton[$cacheKey] = $paymentClass::singleton($mode, $paymentProcessor);
-    }
-
-    //load the payment form for required processor.
-    //if ($paymentForm !== NULL) {
-    //self::$_singleton[$cacheKey]->setForm($paymentForm);
-    //}
-
-    return self::$_singleton[$cacheKey];
+    //we use two lines because we can't remove the '&singleton' without risking breakage
+    //of extension classes that extend this one
+    $object = Civi\Payment\System::singleton()->getByProcessor($paymentProcessor);
+    return $object;
   }
 
   /**
    * @param array $params
-   *
+   * @todo move to factory class \Civi\Payment\System (or similar)
    * @return mixed
    */
   public static function logPaymentNotification($params) {
@@ -210,9 +173,8 @@ abstract class CRM_Core_Payment {
 
   /**
    * Setter for the payment form that wants to use the processor
-   *
+   * @deprecated
    * @param CRM_Core_Form $paymentForm
-   *
    */
   public function setForm(&$paymentForm) {
     $this->_paymentForm = $paymentForm;
@@ -220,8 +182,9 @@ abstract class CRM_Core_Payment {
 
   /**
    * Getter for payment form that is using the processor
-   *
-   * @return CRM_Core_Form  A form object
+   * @deprecated
+   * @return CRM_Core_Form
+   *   A form object
    */
   public function getForm() {
     return $this->_paymentForm;
@@ -229,7 +192,7 @@ abstract class CRM_Core_Payment {
 
   /**
    * Getter for accessing member vars
-   *
+   * @todo believe this is unused
    * @param string $name
    *
    * @return null
@@ -240,7 +203,7 @@ abstract class CRM_Core_Payment {
 
   /**
    * Get name for the payment information type
-   *
+   * @todo - use option group + name field (like Omnipay does)
    * @return string
    */
   public function getPaymentTypeName() {
@@ -249,7 +212,7 @@ abstract class CRM_Core_Payment {
 
   /**
    * Get label for the payment information type
-   *
+   * @todo - use option group + labels (like Omnipay does)
    * @return string
    */
   public function getPaymentTypeLabel() {
@@ -301,7 +264,8 @@ abstract class CRM_Core_Payment {
    * Return an array of all the details about the fields potentially required for payment fields
    * Only those determined by getPaymentFormFields will actually be assigned to the form
    *
-   * @return array field metadata
+   * @return array
+   *   field metadata
    */
   public function getPaymentFormFieldsMetadata() {
     //@todo convert credit card type into an option value
@@ -315,7 +279,7 @@ abstract class CRM_Core_Payment {
         'attributes' => array(
           'size' => 20,
           'maxlength' => 20,
-          'autocomplete' => 'off'
+          'autocomplete' => 'off',
         ),
         'is_required' => TRUE,
       ),
@@ -327,7 +291,7 @@ abstract class CRM_Core_Payment {
         'attributes' => array(
           'size' => 5,
           'maxlength' => 10,
-          'autocomplete' => 'off'
+          'autocomplete' => 'off',
         ),
         'is_required' => CRM_Core_BAO_Setting::getItem(CRM_Core_BAO_Setting::CONTRIBUTE_PREFERENCES_NAME,
           'cvv_backoffice_required',
@@ -339,7 +303,8 @@ abstract class CRM_Core_Payment {
             'rule_message' => ts('Please enter a valid value for your card security code. This is usually the last 3-4 digits on the card\'s signature panel.'),
             'rule_name' => 'integer',
             'rule_parameters' => NULL,
-        )),
+          ),
+        ),
       ),
       'credit_card_exp_date' => array(
         'htmlType' => 'date',
@@ -353,7 +318,8 @@ abstract class CRM_Core_Payment {
             'rule_message' => ts('Card expiration date cannot be a past date.'),
             'rule_name' => 'currentDate',
             'rule_parameters' => TRUE,
-          )),
+          ),
+        ),
       ),
       'credit_card_type' => array(
         'htmlType' => 'select',
@@ -371,7 +337,7 @@ abstract class CRM_Core_Payment {
         'attributes' => array(
           'size' => 20,
           'maxlength' => 34,
-          'autocomplete' => 'on'
+          'autocomplete' => 'on',
         ),
         'is_required' => TRUE,
       ),
@@ -384,14 +350,15 @@ abstract class CRM_Core_Payment {
         'attributes' => array(
           'size' => 20,
           'maxlength' => 34,
-          'autocomplete' => 'off'
+          'autocomplete' => 'off',
         ),
         'rules' => array(
           array(
             'rule_message' => ts('Please enter a valid Bank Identification Number (value must not contain punctuation characters).'),
             'rule_name' => 'nopunctuation',
             'rule_parameters' => NULL,
-        )),
+          ),
+        ),
         'is_required' => TRUE,
       ),
       //e.g. SWIFT-BIC can have maxlength of 11 digits
@@ -403,7 +370,7 @@ abstract class CRM_Core_Payment {
         'attributes' => array(
           'size' => 20,
           'maxlength' => 11,
-          'autocomplete' => 'off'
+          'autocomplete' => 'off',
         ),
         'is_required' => TRUE,
         'rules' => array(
@@ -411,7 +378,8 @@ abstract class CRM_Core_Payment {
             'rule_message' => ts('Please enter a valid Bank Identification Number (value must not contain punctuation characters).'),
             'rule_name' => 'nopunctuation',
             'rule_parameters' => NULL,
-        )),
+          ),
+        ),
       ),
       'bank_name' => array(
         'htmlType' => 'text',
@@ -421,11 +389,11 @@ abstract class CRM_Core_Payment {
         'attributes' => array(
           'size' => 20,
           'maxlength' => 64,
-          'autocomplete' => 'off'
+          'autocomplete' => 'off',
         ),
         'is_required' => TRUE,
 
-      )
+      ),
     );
   }
 
@@ -436,10 +404,11 @@ abstract class CRM_Core_Payment {
    * @param array $params
    *   Assoc array of input parameters for this transaction.
    *
-   * @return array the result in an nice formatted array (or an error object)
+   * @return array
+   *   the result in an nice formatted array (or an error object)
    * @abstract
    */
-  abstract function doDirectPayment(&$params);
+  abstract protected function doDirectPayment(&$params);
 
   /**
    * Process payment - this function wraps around both doTransferPayment and doDirectPayment
@@ -449,6 +418,8 @@ abstract class CRM_Core_Payment {
    *
    * @param $component
    *
+   * @return array
+   *   (modified)
    * @throws CRM_Core_Exception
    */
   public function doPayment(&$params, $component) {
@@ -468,13 +439,14 @@ abstract class CRM_Core_Payment {
   /**
    * This function checks to see if we have the right config values
    *
-   * @return string the error message if any
+   * @return string
+   *   the error message if any
    */
-  abstract function checkConfig();
+  abstract protected function checkConfig();
 
   /**
    * @param $paymentProcessor
-   *
+   * @todo move to paypal class or remover
    * @return bool
    */
   public static function paypalRedirect(&$paymentProcessor) {
@@ -494,6 +466,7 @@ abstract class CRM_Core_Payment {
   }
 
   /**
+   * @todo move to0 \Civi\Payment\System factory method
    * Page callback for civicrm/payment/ipn
    */
   public static function handleIPN() {
@@ -512,6 +485,7 @@ abstract class CRM_Core_Payment {
    * 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 to0 \Civi\Payment\System factory method
    *
    * @param $method
    * @param array $params
@@ -580,7 +554,7 @@ abstract class CRM_Core_Payment {
       }
 
       // Instantiate PP
-      $processorInstance = $paymentClass::singleton($mode, $paymentProcessor);
+      $processorInstance = new $paymentClass($mode, $paymentProcessor);
 
       // Does PP implement this method, and can we call it?
       if (!method_exists($processorInstance, $method) ||
@@ -615,7 +589,7 @@ abstract class CRM_Core_Payment {
    * @param string $method
    *   Method to check for.
    *
-   * @return boolean
+   * @return bool
    */
   public function isSupported($method = 'cancelSubscription') {
     return method_exists(CRM_Utils_System::getClassName($this), $method);
@@ -648,11 +622,11 @@ abstract class CRM_Core_Payment {
         break;
     }
 
-    $session       = CRM_Core_Session::singleton();
-    $userId        = $session->get('userID');
-    $contactID     = 0;
+    $session = CRM_Core_Session::singleton();
+    $userId = $session->get('userID');
+    $contactID = 0;
     $checksumValue = '';
-    $entityArg     = '';
+    $entityArg = '';
 
     // Find related Contact
     if ($entityID) {
@@ -697,4 +671,5 @@ INNER JOIN civicrm_contribution con ON ( con.contribution_recur_id = rec.id )
     // Else default
     return $this->_paymentProcessor['url_recur'];
   }
+
 }