Merge remote-tracking branch 'upstream/4.3' into 4.3-master-2013-07-14-22-39-05
authorKurund Jalmi <kurund@civicrm.org>
Sun, 14 Jul 2013 17:40:20 +0000 (23:10 +0530)
committerKurund Jalmi <kurund@civicrm.org>
Sun, 14 Jul 2013 17:40:20 +0000 (23:10 +0530)
Conflicts:
CRM/Contact/BAO/Contact.php
CRM/Group/Page/AJAX.php
CRM/Report/Form/Member/Detail.php
CRM/Utils/SoapServer.php
CRM/Utils/System/Base.php
sql/civicrm_generated.mysql
tests/phpunit/CRM/Core/DAOTest.php
tests/phpunit/CiviTest/CiviUnitTestCase.php
tests/phpunit/api/v3/ContributionTest.php
xml/version.xml

62 files changed:
1  2 
CRM/Admin/Form/Setting/Component.php
CRM/Case/XMLProcessor/Process.php
CRM/Contact/BAO/Contact.php
CRM/Contact/BAO/Contact/Utils.php
CRM/Contact/BAO/Query.php
CRM/Contact/Selector.php
CRM/Contribute/BAO/Contribution.php
CRM/Contribute/BAO/Contribution/Utils.php
CRM/Contribute/Form/Contribution.php
CRM/Contribute/Form/Contribution/Confirm.php
CRM/Contribute/Form/ContributionBase.php
CRM/Contribute/Form/ContributionPage/AddProduct.php
CRM/Contribute/Form/ManagePremiums.php
CRM/Core/BAO/CustomField.php
CRM/Core/BAO/CustomGroup.php
CRM/Core/DAO.php
CRM/Core/Payment/PayPalIPN.php
CRM/Core/Payment/PayPalProIPN.php
CRM/Custom/Form/Group.php
CRM/Event/Form/ManageEvent/Fee.php
CRM/Event/Form/Registration/Register.php
CRM/Financial/BAO/FinancialItem.php
CRM/Financial/BAO/FinancialTypeAccount.php
CRM/Group/Page/AJAX.php
CRM/Logging/Differ.php
CRM/Member/Form/MembershipType.php
CRM/Pledge/Form/Search.php
CRM/Report/Form.php
CRM/Report/Form/Member/Detail.php
CRM/Upgrade/Form.php
CRM/Upgrade/Incremental/php/FourThree.php
CRM/Upgrade/Incremental/sql/4.3.alpha1.mysql.tpl
CRM/Utils/Address/BatchUpdate.php
CRM/Utils/String.php
CRM/Utils/System.php
CRM/Utils/System/Base.php
CRM/Utils/System/Drupal.php
CRM/Utils/System/Drupal6.php
CRM/Utils/System/Joomla.php
CRM/Utils/Token.php
api/api.php
api/v3/Contact.php
api/v3/Contribution.php
api/v3/MembershipType.php
install/template.html
settings/Core.setting.php
templates/CRM/Contribute/Form/Contribution/OnBehalfOf.tpl
templates/CRM/Contribute/Form/Contribution/PremiumBlock.tpl
templates/CRM/Contribute/Form/ContributionPage/Settings.tpl
templates/CRM/Event/Page/EventInfo.tpl
tests/phpunit/CRM/Contact/BAO/GroupContactCacheTest.php
tests/phpunit/CRM/Core/DAOTest.php
tests/phpunit/CiviTest/CiviUnitTestCase.php
tests/phpunit/WebTest/Contribute/OfflineContributionTest.php
tests/phpunit/api/v3/APITest.php
tests/phpunit/api/v3/ContributionTest.php
tests/phpunit/api/v3/MembershipTypeTest.php
tests/phpunit/api/v3/ParticipantTest.php
xml/templates/message_templates/event_offline_receipt_html.tpl
xml/templates/message_templates/event_offline_receipt_text.tpl
xml/templates/message_templates/event_online_receipt_html.tpl
xml/templates/message_templates/event_online_receipt_text.tpl

Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
index e96d0e3d927cb2590280f9d03bcfddcf11a11304,2c33cd62be0f216b29236ef7909bb0004e77e156..1bf279f5b47a48079c3badcaa776fc9b68795e9b
@@@ -1046,12 -1068,11 +1049,11 @@@ class CRM_Contribute_Form_Contribution 
        $itemId = key($lineItems);
        $fieldType = NULL;
        if ($itemId && CRM_Utils_Array::value('price_field_id', $lineItems[$itemId])) {
 -        $fieldType = CRM_Core_DAO::getFieldValue('CRM_Price_DAO_Field', $lineItems[$itemId]['price_field_id'], 'html_type');
 +        $fieldType = CRM_Core_DAO::getFieldValue('CRM_Price_DAO_PriceField', $lineItems[$itemId]['price_field_id'], 'html_type');
        }
        $lineItems[$itemId]['unit_price'] = $lineItems[$itemId]['line_total'] = CRM_Utils_Rule::cleanMoney(CRM_Utils_Array::value('total_amount', $submittedValues));
-       $lineItems[$itemId]['id'] = $itemId;
        // 10117 update th line items for participants
 -      $this->_priceSetId = CRM_Core_DAO::getFieldValue('CRM_Price_DAO_Field', $lineItems[$itemId]['price_field_id'], 'price_set_id');
 +      $this->_priceSetId = CRM_Core_DAO::getFieldValue('CRM_Price_DAO_PriceField', $lineItems[$itemId]['price_field_id'], 'price_set_id');
        $lineItem[$this->_priceSetId] = $lineItems;
      }
      $isQuickConfig = 0;
Simple merge
Simple merge
Simple merge
index bff959517fc082d8d9cf1e4a199e9ea82dc072e0,5a468fb1ffa21b2263bfb7e186a04c64b7a099b6..dba831909efd7bda65a5d3cdef930be38d97a910
@@@ -339,4 -349,5 +347,4 @@@ class CRM_Core_Payment_PayPalIPN extend
      $input['net_amount'] = self::retrieve('settle_amount', 'Money', 'POST', FALSE);
      $input['trxn_id']    = self::retrieve('txn_id', 'String', 'POST', FALSE);
    }
- }
+ }
 -
Simple merge
Simple merge
Simple merge
Simple merge
index 938e98cfd07963265567a765a2010d17feeb4c5b,f3b39c9bc9a21dfbc04806cb695a45a18b978368..6ea2d725d930c317cad9d396464552fc893ca66d
@@@ -46,8 -46,9 +46,9 @@@ class CRM_Group_Page_AJAX 
        $groups = CRM_Contact_BAO_Group::getGroupListSelector($params);
  
        echo json_encode($groups);
 -      CRM_Utils_System::civiExit();      
 +      CRM_Utils_System::civiExit();
-     } else {
+     }
+     else {
        $sortMapper = array(
          0 => 'groups.title', 1 => 'groups.id', 2 => 'createdBy.sort_name', 3 => '',
          4 => 'groups.group_type', 5 => 'groups.visibility',
Simple merge
Simple merge
Simple merge
index bfa11a967b9ab19bd8562c5c2808f6ebaef6783d,0b4d0dc1738cb0ce48bf560e9c4d76cb01532d8d..247cd69b14a5af2ed421cca243c82c8657ec08c6
@@@ -196,22 -199,7 +196,21 @@@ class CRM_Report_Form extends CRM_Core_
    protected $_sections = NULL;
    protected $_autoIncludeIndexedFieldsAsOrderBys = 0;
    protected $_absoluteUrl = FALSE;
-   protected $_grandFlag   = FALSE;
  
 +  /**
 +   * Flag to indicate if result-set is to be stored in a class variable which could be retrieved using getResultSet() method.
 +   *
 +   * @var boolean
 +   */
 +  protected $_storeResultSet = FALSE;
 +
 +  /**
 +   * When _storeResultSet Flag is set use this var to store result set in form of array
 +   *
 +   * @var boolean
 +   */
 +  protected $_resultSet = array();
 +
    /**
     * To what frequency group-by a date column
     *
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
index 4d951a12e180464c789978974bdfd105ab7840ce,2fceed28f0b1421f39c3e7720eaf0110eec7b020..c522696281bdd0c26f35e4ba6ac20cbfa9905385
@@@ -127,17 -124,14 +127,27 @@@ abstract class CRM_Utils_System_Base 
    function flush() {
      // nullop by default
    }
-     /**
++  /**
 +   * Return default Site Settings
 +   * @return array array
 +   * - $url, (Joomla - non admin url)
 +   * - $siteName,
 +   * - $siteRoot
 +   */
-   function getDefaultSiteSettings($dir){
++  function getDefaultSiteSettings($dir) {
 +    $config = CRM_Core_Config::singleton();
 +    $url = $config->userFrameworkBaseURL;
 +    return array($url, NULL, NULL);
 +  }
++
+   /**
+    * Perform an post login activities required by the UF -
+    * e.g. for drupal: records a watchdog message about the new session, saves the login timestamp, calls hook_user op 'login' and generates a new session.
+    * @param array $edit: The array of form values submitted by the user.
+    *
+   function userLoginFinalize($edit = array()){
+   }
 -  */
++   */
  }
  
Simple merge
Simple merge
Simple merge
Simple merge
diff --cc api/api.php
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
index 8bad54cf3c6afcf178ec13c4bcb73e965ec97ee0,fe455c6e3bf755af26e781f00e47e299a20be31f..946de3836cf2f2a3f881af3f9a1a130dd9722610
  
  require_once 'CiviTest/CiviUnitTestCase.php';
  class CRM_Core_DAOTest extends CiviUnitTestCase {
 +  function get_info() {
 +    return array(
 +      'name'    => 'DAO',
 +      'description' => 'Test core DAO functions',
 +      'group'     => 'Core',
 +    );
 +  }
 +
 +  function testGetReferenceColumns() {
 +    // choose CRM_Core_DAO_Email as an arbitrary example
 +    $emailRefs = CRM_Core_DAO_Email::getReferenceColumns();
 +    $refsByTarget = array();
 +    foreach ($emailRefs as $refSpec) {
 +      $refsByTarget[$refSpec->getTargetTable()] = $refSpec;
 +    }
 +    $this->assertTrue(array_key_exists('civicrm_contact', $refsByTarget));
 +    $contactRef = $refsByTarget['civicrm_contact'];
 +    $this->assertEquals('contact_id', $contactRef->getReferenceKey());
 +    $this->assertEquals('id', $contactRef->getTargetKey());
 +    $this->assertEquals(FALSE, $contactRef->isGeneric());
 +  }
 +
 +  function testGetReferencesToTable() {
 +    $refs = CRM_Core_DAO::getReferencesToTable(CRM_Financial_DAO_FinancialType::getTableName());
 +    $refsBySource = array();
 +    foreach ($refs as $refSpec) {
 +      $refsBySource[$refSpec->getReferenceTable()] = $refSpec;
 +    }
 +    $this->assertTrue(array_key_exists('civicrm_entity_financial_account', $refsBySource));
 +    $genericRef = $refsBySource['civicrm_entity_financial_account'];
 +    $this->assertEquals('entity_id', $genericRef->getReferenceKey());
 +    $this->assertEquals('entity_table', $genericRef->getTypeColumn());
 +    $this->assertEquals('id', $genericRef->getTargetKey());
 +    $this->assertEquals(TRUE, $genericRef->isGeneric());
 +  }
 +
 +  function testFindReferences() {
 +    $params = array(
 +      'first_name' => 'Testy',
 +      'last_name' => 'McScallion',
 +      'contact_type' => 'Individual',
 +    );
 +
 +    $contact = CRM_Contact_BAO_Contact::add($params);
 +    $this->assertNotNull($contact->id);
 +
 +    $params = array(
 +      'email' => 'spam@dev.null',
 +      'contact_id' => $contact->id,
 +      'is_primary' => 0,
 +      'location_type_id' => 1,
 +    );
 +
 +    $email = CRM_Core_BAO_Email::add($params);
 +
 +    $refs = $contact->findReferences();
 +    $refsByTable = array();
 +    foreach ($refs as $refObj) {
 +      $refsByTable[$refObj->__table] = $refObj;
 +    }
 +
 +    $this->assertTrue(array_key_exists('civicrm_email', $refsByTable));
 +    $refDao = $refsByTable['civicrm_email'];
 +    $refDao->find(TRUE);
 +    $this->assertEquals($contact->id, $refDao->contact_id);
 +  }
++
+   function composeQueryExamples() {
+     $cases = array();
+     // $cases[] = array('Input-SQL', 'Input-Params', 'Expected-SQL');
+     // CASE: No params
+     $cases[] = array(
+       'SELECT * FROM whatever',
+       array(),
+       'SELECT * FROM whatever',
+     );
+     // CASE: Integer param
+     $cases[] = array(
+       'SELECT * FROM whatever WHERE id = %1',
+       array(
+         1 => array(10, 'Integer'),
+       ),
+       'SELECT * FROM whatever WHERE id = 10',
+     );
+     // CASE: String param
+     $cases[] = array(
+       'SELECT * FROM whatever WHERE name = %1',
+       array(
+         1 => array('Alice', 'String'),
+       ),
+       'SELECT * FROM whatever WHERE name = \'Alice\'',
+     );
+     // CASE: Two params
+     $cases[] = array(
+       'SELECT * FROM whatever WHERE name = %1 AND title = %2',
+       array(
+         1 => array('Alice', 'String'),
+         2 => array('Bob', 'String'),
+       ),
+       'SELECT * FROM whatever WHERE name = \'Alice\' AND title = \'Bob\'',
+     );
+     // CASE: Two params with special character (%1)
+     $cases[] = array(
+       'SELECT * FROM whatever WHERE name = %1 AND title = %2',
+       array(
+         1 => array('Alice %2', 'String'),
+         2 => array('Bob', 'String'),
+       ),
+       'SELECT * FROM whatever WHERE name = \'Alice %2\' AND title = \'Bob\'',
+     );
+     // CASE: Two params with special character ($1)
+     $cases[] = array(
+       'SELECT * FROM whatever WHERE name = %1 AND title = %2',
+       array(
+         1 => array('Alice $1', 'String'),
+         2 => array('Bob', 'String'),
+       ),
+       'SELECT * FROM whatever WHERE name = \'Alice $1\' AND title = \'Bob\'',
+     );
+     return $cases;
+   }
+   /**
+    * @dataProvider composeQueryExamples
+    */
+   function testComposeQuery($inputSql, $inputParams, $expectSql) {
+     $actualSql = CRM_Core_DAO::composeQuery($inputSql, $inputParams);
+     $this->assertEquals($expectSql, $actualSql);
+   }
+   // CASE: Two params where the %2 is already present in the query
+   // NOTE: This case should rightly FAIL, as using strstr in the replace mechanism will turn
+   // the query into: SELECT * FROM whatever WHERE name = 'Alice' AND title = 'Bob' AND year LIKE ''Bob'012'
+   // So, to avoid such ERROR, the query should be framed like:
+   // 'SELECT * FROM whatever WHERE name = %1 AND title = %3 AND year LIKE '%2012'
+   // $params[3] = array('Bob', 'String');
+   // i.e. the place holder should be unique and should not contain in any other operational use in query
+   function testComposeQueryFailure() {
+     $cases[] = array(
+       'SELECT * FROM whatever WHERE name = %1 AND title = %2 AND year LIKE \'%2012\' ',
+       array(
+         1 => array('Alice', 'String'),
+         2 => array('Bob', 'String'),
+       ),
+       'SELECT * FROM whatever WHERE name = \'Alice\' AND title = \'Bob\' AND year LIKE \'%2012\' ',
+     );
+     list($inputSql, $inputParams, $expectSql) = $cases[0];
+     $actualSql = CRM_Core_DAO::composeQuery($inputSql, $inputParams);
+     $this->assertFalse(($expectSql == $actualSql));
+   }
  }
index 0a13133f1f30a703d6eeaca446913fa487d94cf8,2769ac61d3c244ba27d5d190c50419c6fa82e839..a88355236bdcf1324aa8f8188707bbcbc24c5f51
@@@ -601,12 -596,12 +601,12 @@@ class CiviUnitTestCase extends PHPUnit_
      );
    }
  
--/**
-  * check that api returned 'is_error' => 0
-  * else provide full message
-  * @param array $apiResult api result
-  * @param string $prefix extra test to add to message
-  */
 -* check that api returned 'is_error' => 0
 -* else provide full message
 -* @param array $apiResult api result
 -* @param string $prefix extra test to add to message
 -*/
++  /**
++   * check that api returned 'is_error' => 0
++   * else provide full message
++   * @param array $apiResult api result
++   * @param string $prefix extra test to add to message
++   */
    function assertAPISuccess($apiResult, $prefix = '') {
      if (!empty($prefix)) {
        $prefix .= ': ';
    function assertType($expected, $actual, $message = '') {
      return $this->assertInternalType($expected, $actual, $message);
    }
--  /**
  
 -/**
 -* This function exists to wrap api functions
 -* so we can ensure they succeed & throw exceptions without litterering the test with checks
 -* @param string $entity
 -* @param string $action
 -* @param array $params
 -* @param string $function - pass this in to create a generated example
 -* @param string $file - pass this in to create a generated example
 -*/
 +  /**
 +   * This function exists to wrap api functions
 +   * so we can ensure they succeed & throw exceptions without litterering the test with checks
 +   * @param string $entity
 +   * @param string $action
 +   * @param array $params
 +   * @param string $function - pass this in to create a generated example
 +   * @param string $file - pass this in to create a generated example
 +   */
    function callAPISuccess($entity, $action, $params) {
      $params = array_merge(array(
          'version' => API_LATEST_VERSION,
    }
  
    /**
 -* This function exists to wrap api getValue function & check the result
 -* so we can ensure they succeed & throw exceptions without litterering the test with checks
 -* There is a type check in this
 -* @param string $entity
 -* @param array $params
 -* @param string $type - per http://php.net/manual/en/function.gettype.php possible types
 -* - boolean
 -* - integer
 -* - double
 -* - string
 -* - array
 -* - object
 -*/
 +   * This function exists to wrap api getValue function & check the result
 +   * so we can ensure they succeed & throw exceptions without litterering the test with checks
 +   * There is a type check in this
 +   * @param string $entity
 +   * @param array $params
 +   * @param string $type - per http://php.net/manual/en/function.gettype.php possible types
-    *  - boolean
-    *  - integer
-    *  - double
-    *  - string
-    *  - array
-    *  - object
++   * - boolean
++   * - integer
++   * - double
++   * - string
++   * - array
++   * - object
 +   */
    function callAPISuccessGetValue($entity, $params, $type = NULL) {
      $params += array(
        'version' => API_LATEST_VERSION,
      }
      return $result;
    }
++
    /**
 -* This function exists to wrap api functions
 -* so we can ensure they succeed, generate and example & throw exceptions without litterering the test with checks
 -*
 -* @param string $entity
 -* @param string $action
 -* @param array $params
 -* @param string $function - pass this in to create a generated example
 -* @param string $file - pass this in to create a generated example
 -*/
 +   * This function exists to wrap api functions
 +   * so we can ensure they succeed, generate and example & throw exceptions without litterering the test with checks
 +   *
 +   * @param string $entity
 +   * @param string $action
 +   * @param array $params
 +   * @param string $function - pass this in to create a generated example
 +   * @param string $file - pass this in to create a generated example
 +   */
    function callAPIAndDocument($entity, $action, $params, $function, $file, $description = "", $subfile = NULL, $actionName = NULL){
      $params['version'] = API_LATEST_VERSION;
      if(!isset($params['debug'])){
  
    /**
     * Function to delete financial Types
--   *      * @param int $contributionTypeId
++   * @param int $contributionTypeId
     */
    function contributionTypeDelete($contributionTypeID = NULL) {
      if ($contributionTypeID === NULL) {
     * Add entity(s) to the tag
     *
     * @param  array  $params
--   *
     */
    function entityTagAdd($params) {
      $params['version'] = API_LATEST_VERSION;
Simple merge
index f29c9e698cc14adf23aac1892a77f4af0e639a14,94a43dff00ed7335f8b0f64b644100f0d8b1d58c..c5f41cdd9541af7fa4ad6e7fd28d4c0ff00141dc
@@@ -1282,7 -1303,56 +1282,57 @@@ class api_v3_ContributionTest extends C
      $this->contributionDelete($contribution1['id']);
      $this->contributionDelete($contribution2['id']);
    }
 +
+   /**
+    * Test completing a transaction via the API
+    *
+    * Note that we are creating a logged in user because email goes out from
+    * that person
+    */
+   function testCompleteTransaction() {
+     $mut = new CiviMailUtils( $this, true );
+     $this->createLoggedInUser();
+     $params = array_merge($this->_params, array('contribution_status_id' => 1,));
+     $contribution = $this->callAPISuccess('contribution','create', $params);
+     $apiResult = $this->callAPISuccess('contribution', 'completetransaction', array(
+       'id' => $contribution['id'],
+     )
+     );
+     $contribution = $this->callAPISuccess('contribution', 'get', array('id' => $contribution['id'], 'sequential' => 1,));
+     $this->assertEquals('Completed', $contribution['values'][0]['contribution_status']);
+     $mut->checkMailLog(array(
+       'Receipt - Contribution',
+       'Please print this confirmation for your records.',
+     ));
+     $mut->stop();
+   }
+   /**
+    * Test completing a transaction with an event via the API
+    *
+    * Note that we are creating a logged in user because email goes out from
+    * that person
+    */
+   function testCompleteTransactionWithParticipantRecord() {
+     $mut = new CiviMailUtils( $this, true );
+     $mut->clearMessages();
+     $this->createLoggedInUser();
+     $contributionID = $this->createPendingParticipantContribution();
+     $apiResult = $this->callAPISuccess('contribution', 'completetransaction', array(
+       'id' => $contributionID,
+     )
+     );
+     $participantStatus = $this->callAPISuccessGetValue('participant', array('id' => $this->ids['participant'], 'return' => 'participant_status_id'));
+     $this->assertEquals(1, $participantStatus);
+     $mut->checkMailLog(array(
+       'Annual CiviCRM meet',
+       'Event',
+       'This letter is a confirmation that your registration has been received and your status has been updated to registered for the following',
+     ));
+   $mut->stop();
+   }
    /**
     * Test sending a mail via the API
     */