Merge remote-tracking branch 'upstream/4.6' into 4.6-master-2015-08-24-22-26-45
authorKurund Jalmi <kurund@yahoo.com>
Mon, 24 Aug 2015 18:37:52 +0000 (00:07 +0530)
committerKurund Jalmi <kurund@yahoo.com>
Mon, 24 Aug 2015 18:37:52 +0000 (00:07 +0530)
Conflicts:
CRM/Contact/BAO/Relationship.php
CRM/Member/Form/Membership.php
sql/civicrm_generated.mysql
tests/phpunit/api/v3/CustomValueTest.php
xml/version.xml

19 files changed:
1  2 
CRM/Admin/Page/AJAX.php
CRM/Case/BAO/Query.php
CRM/Contact/BAO/Query.php
CRM/Contact/BAO/Relationship.php
CRM/Contribute/Form/Contribution.php
CRM/Contribute/Form/Task/Invoice.php
CRM/Core/BAO/CustomField.php
CRM/Core/BAO/CustomQuery.php
CRM/Core/BAO/CustomValueTable.php
CRM/Core/DAO/permissions.php
CRM/Core/Payment/Form.php
CRM/Core/Payment/ProcessorForm.php
CRM/Mailing/Info.php
CRM/Report/Form/Activity.php
api/v3/utils.php
templates/CRM/Case/Form/Search/Common.tpl
templates/CRM/Core/BillingBlock.tpl
templates/CRM/common/SocialNetwork.tpl
tests/phpunit/api/v3/CustomValueTest.php

Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
index 92c64f9e6b2210131dd81ab596ba622da4822414,98ce9640cac3042a4cbddff5625d9110275263b3..b65daaab49c7f538b65c3c88dfc7a8cdf57ec78c
@@@ -560,17 -463,9 +507,15 @@@ class CRM_Report_Form_Activity extends 
                     ON {$this->_aliases['civicrm_activity_contact']}.contact_id = civicrm_email_source.contact_id AND
                        civicrm_email_source.is_primary = 1";
        }
 +      if ($this->isTableSelected('civicrm_phone')) {
 +        $this->_from .= "
 +            LEFT JOIN civicrm_phone civicrm_phone_source
 +                   ON {$this->_aliases['civicrm_activity_contact']}.contact_id = civicrm_phone_source.contact_id AND
 +                      civicrm_phone_source.is_primary = 1 ";
 +      }
        $this->_aliases['civicrm_contact'] = 'civicrm_contact_source';
      }
-     $this->_from .= " INNER JOIN civicrm_option_value {$this->_aliases['civicrm_option_value']}
-             ON {$this->_aliases['civicrm_option_value']}.option_group_id = {$activityTypeId}
-             AND {$this->_aliases['civicrm_option_value']}.value = {$this->_aliases['civicrm_activity']}.activity_type_id";
      $this->addAddressFromClause();
    }
  
Simple merge
index 24a1d4649338b390480a784366ebf592a988cd60,68765b49866cda994895c4adde1f8cd94e63b30f..8685ae8b2934fbe7d8d32b8d9698912728085686
        <legend>
          {$paymentTypeLabel}
        </legend>
 -      {if $form.$expressButtonName}
 -        {include file= "CRM/Core/paypalexpress.tpl"}
 -      {/if}
 +      {crmRegion name="billing-block-pre"}
 +      {/crmRegion}
        <div class="crm-section billing_mode-section {$paymentTypeName}_info-section">
          {foreach from=$paymentFields item=paymentField}
+           {assign var='name' value=$form.$paymentField.name}
            <div class="crm-section {$form.$paymentField.name}-section">
-             <div class="label">{$form.$paymentField.label}</div>
+             <div class="label">{$form.$paymentField.label}
+               {if $requiredPaymentFields.$name}<span class="crm-marker" title="{ts}This field is required.{/ts}">*</span>{/if}
+             </div>
              <div class="content">{$form.$paymentField.html}
                {if $paymentField == 'cvv2'}{* @todo move to form assignment*}
                  <span class="cvv2-icon" title="{ts}Usually the last 3-4 digits in the signature area on the back of the card.{/ts}"> </span>
index a5c1acacb94cc9e809cc991c828533521e7d0f6d,4920da8abe300571a08df667b423eae104738e6d..be4e17b2710603c4e8b437c4508b392735f1851b
@@@ -62,195 -91,210 +91,288 @@@ class api_v3_CustomValueTest extends Ci
    }
  
    public function testCreateCustomValue() {
-     $params = array(
-       'custom_' . $this->ids['single']['custom_field_id'] => 'customString',
-     ) + $this->params;
+     $customFieldDataType = CRM_Core_BAO_CustomField::dataType();
+     $dataToHtmlTypes = CRM_Core_BAO_CustomField::dataToHtml();
+     $count = 0;
  
-     $result = $this->callAPIAndDocument('custom_value', 'create', $params, __FUNCTION__, __FILE__);
-     $this->assertEquals(1, $result['count']);
-     $result = $this->callAPISuccess('custom_value', 'get', $params);
-   }
+     foreach ($customFieldDataType as $dataType => $label) {
+       switch ($dataType) {
+         case 'Date':
+         case 'StateProvince';
+         case 'String':
+         case 'Link':
+         case 'Int':
+         case 'Float':
+         case 'Money':
 -
+           if (in_array($dataType, array('String', 'Link'))) {
+             $validSQLOperator = array('=', '!=', 'IN', 'NOT IN', 'LIKE', 'NOT LIKE', 'IS NOT NULL', 'IS NULL');
+             $type = 'string';
+           }
+           else {
+             if ($dataType == 'Country') {
+               $type == 'country';
+             }
+             elseif ($dataType == 'StateProvince') {
+               $type = 'state_province';
+             }
+             elseif ($dataType == 'ContactReference') {
+               $type = 'contact';
+             }
+             elseif ($dataType == 'Date') {
+               $type = 'date';
+             }
+             else {
+               $type = $dataType == 'Int' ? 'integer' : 'number';
+             }
+             $validSQLOperator = array('=', '!=', 'IN', 'NOT IN', '<=', '>=', '>', '<', 'IS NOT NULL', 'IS NULL');
+           }
  
-   public function testGetMultipleCustomValues() {
+           foreach ($dataToHtmlTypes[$count] as $html) {
+             $params = array(
+               'custom_group_id' => $this->ids[$type]['custom_group_id'],
+               'label' => "$dataType - $html",
+               'data_type' => $dataType,
+               'html_type' => $html,
+               'default_value' => NULL,
+             );
+             if (!in_array($html, array('Text', 'TextArea')) && !in_array($dataType, array('Link', 'Date', 'ContactReference'))) {
+               $params += array('option_group_id' => $this->optionGroup[$type]['id']);
+             }
+             $customField = $this->customFieldCreate($params);
+             $this->_testCustomValue($customField['values'][$customField['id']], $validSQLOperator, $type);
+           }
+           $count++;
+           break;
  
-     $description = "This demonstrates the use of CustomValue get to fetch single and multi-valued custom data.";
+         default:
+           //TODO: Test case of Country fields remain as it throws foreign key contraint ONLY in test environment
+           $count++;
+           break;
+       }
+     }
+   }
  
+   public function _testCustomValue($customField, $sqlOps, $type) {
+     $isSerialized = CRM_Core_BAO_CustomField::isSerialized($customField);
+     $customId = $customField['id'];
      $params = array(
-       'first_name' => 'abc3',
-       'last_name' => 'xyz3',
        'contact_type' => 'Individual',
-       'email' => 'man3@yahoo.com',
-       'custom_' . $this->ids['single']['custom_field_id'] => "value 1",
-       'custom_' . $this->ids['multi']['custom_field_id'][0] => "value 2",
-       'custom_' . $this->ids['multi']['custom_field_id'][1] => "warm beer",
-       'custom_' . $this->ids['multi']['custom_field_id'][2] => "fl* w*",
-       'custom_' . $this->ids['multi2']['custom_field_id'][2] => "vegemite",
+       'email' => substr(sha1(rand()), 0, 7) . 'man1@yahoo.com',
      );
      $result = $this->callAPISuccess('Contact', 'create', $params);
-     $contact_id = $result['id'];
-     $firstCustomField = $this->ids['multi']['custom_field_id'][0];
-     $secondCustomField = $this->ids['multi2']['custom_field_id'][0];
-     $thirdCustomField = $this->ids['multi2']['custom_field_id'][1];
-     $createParams = array(
-       'contact_type' => 'Individual',
-       'id' => $contact_id,
-       'custom_' . $firstCustomField => "value 3",
-       'custom_' . $secondCustomField => "coffee",
-       'custom_' . $thirdCustomField => "value 4",
-     );
-     $result = $this->callAPISuccess('Contact', 'create', $createParams);
+     $contactId = $result['id'];
  
-     $params = array(
-       'id' => $result['id'],
-       'entity_id' => $result['id'],
-     );
+     $count = rand(1, 2);
+     $seperator = CRM_Core_DAO::VALUE_SEPARATOR;
+     if ($isSerialized) {
+       $selectedValue = $this->optionGroup[$type]['values'];
+       $notselectedValue = $selectedValue[$count];
+       unset($selectedValue[$count]);
+     }
+     elseif ($customField['html_type'] == 'Link') {
+       $selectedValue = "http://" . substr(sha1(rand()), 0, 7) . ".com";
+       $notselectedValue = "http://" . substr(sha1(rand()), 0, 7) . ".com";
+     }
+     elseif ($type == 'date') {
+       $selectedValue = date('Ymd');
+       $notselectedValue = $lesserSelectedValue = date('Ymd', strtotime('yesterday'));
+       $greaterSelectedValue = date('Ymd', strtotime('+ 1 day'));
+     }
+     elseif ($type == 'contact') {
+       $selectedValue = $this->optionGroup[$type]['values'][1];
+       $notselectedValue = $this->optionGroup[$type]['values'][0];
+     }
+     else {
+       $selectedValue = $this->optionGroup[$type]['values'][0];
+       $notselectedValue = $this->optionGroup[$type]['values'][$count];
+       if (in_array(">", $sqlOps)) {
+         $greaterSelectedValue = $selectedValue + 1;
+         $lesserSelectedValue = $selectedValue - 1;
+       }
+     }
  
-     $result = $this->callAPIAndDocument('CustomValue', 'Get', $params, __FUNCTION__, __FILE__, $description);
-     $params['format.field_names'] = 1;
-     $resultformatted = $this->callAPIAndDocument('CustomValue', 'Get', $params, __FUNCTION__, __FILE__, "utilises field names", 'FormatFieldName');
-     // delete the contact
-     $this->callAPISuccess('contact', 'delete', array('id' => $contact_id));
-     $this->assertEquals('coffee', $result['values'][$secondCustomField]['2']);
-     $this->assertEquals('coffee', $result['values'][$secondCustomField]['latest']);
-     $this->assertEquals($secondCustomField, $result['values'][$secondCustomField]['id']);
-     $this->assertEquals('defaultValue', $result['values'][$secondCustomField]['1']);
-     $this->assertEquals($contact_id, $result['values'][$secondCustomField]['entity_id']);
-     $this->assertEquals('value 1', $result['values'][$this->ids['single']['custom_field_id']]['0']);
-     $this->assertEquals('value 1', $result['values'][$this->ids['single']['custom_field_id']]['latest']);
-     $this->assertEquals('value 1', $resultformatted['values']['mySingleField']['latest']);
-     $this->assertEquals('', $result['values'][$thirdCustomField]['1']);
-     $this->assertEquals('value 4', $result['values'][$thirdCustomField]['2']);
-   }
+     $params = array('entity_id' => $contactId, 'custom_' . $customId => $selectedValue);
+     $this->callAPISuccess('CustomValue', 'create', $params);
  
-   public function testMultipleCustomValues() {
-     $params = array(
-       'first_name' => 'abc3',
-       'last_name' => 'xyz3',
-       'contact_type' => 'Individual',
-       'email' => 'man3@yahoo.com',
-       'custom_' . $this->ids['single']['custom_field_id'] => "value 1",
-       'custom_' . $this->ids['multi']['custom_field_id'][0] . '-1' => "multi value 1",
-       'custom_' . $this->ids['multi']['custom_field_id'][0] . '-2' => "multi value 2",
-       'custom_' . $this->ids['multi']['custom_field_id'][1] => "second multi value 1",
-     );
+     foreach ($sqlOps as $op) {
+       $qillOp = CRM_Utils_Array::value($op, CRM_Core_SelectValues::getSearchBuilderOperators(), $op);
+       $description = "\nFind Contact where '$customField[label]' $qillOp ";
+       switch ($op) {
+         case '=':
+           $result = $this->callAPISuccess('Contact', 'Get', array('custom_' . $customId => (is_array($selectedValue) ? implode(CRM_Core_DAO::VALUE_SEPARATOR, $selectedValue) : $selectedValue)));
+           $this->assertEquals($contactId, $result['id']);
+           echo $description . implode("[separator]", (array) $selectedValue);
+           break;
  
-     $result = $this->callAPISuccess('Contact', 'create', $params);
-     $contact_id = $result['id'];
-     $firstCustomField = $this->ids['multi']['custom_field_id'][1];
-     $secondCustomField = $this->ids['single']['custom_field_id'];
-     $thirdCustomField = $this->ids['multi']['custom_field_id'][0];
+         case '!=':
+           $result = $this->callAPISuccess('Contact', 'Get', array('custom_' . $customId => array($op => $notselectedValue)));
+           $this->assertEquals(TRUE, array_key_exists($contactId, $result['values']));
+           echo $description . $notselectedValue;
+           break;
  
-     $createParams = array(
-       'contact_type' => 'Individual',
-       'id' => $contact_id,
-       'custom_' . $firstCustomField . '-1' => "second multi value 2",
-       'custom_' . $firstCustomField . '-2' => "second multi value 3",
-     );
-     $result = $this->callAPISuccess('Contact', 'create', $createParams);
+         case '>':
+         case '<':
+         case '>=':
+         case '<=':
+           if ($isSerialized) {
+             continue;
+           }
+           // To be precise in for these operator we can't just rely on one contact,
+           // hence creating multiple contact with custom value less/more then $selectedValue respectively
+           $result = $this->callAPISuccess('Contact', 'create', array('contact_type' => 'Individual', 'email' => substr(sha1(rand()), 0, 7) . 'man2@yahoo.com'));
+           $contactId2 = $result['id'];
+           $this->callAPISuccess('CustomValue', 'create', array('entity_id' => $contactId2, 'custom_' . $customId => $lesserSelectedValue));
  
-     $params = array(
-       'id' => $result['id'],
-       'entity_id' => $result['id'],
-     );
+           if ($op == '>') {
+             $result = $this->callAPISuccess('Contact', 'Get', array('custom_' . $customId => array($op => $lesserSelectedValue)));
+             $this->assertEquals($contactId, $result['id']);
+             echo $description . $lesserSelectedValue;
+           }
+           elseif ($op == '<') {
+             $result = $this->callAPISuccess('Contact', 'Get', array('custom_' . $customId => array($op => $selectedValue)));
+             $this->assertEquals($contactId2, $result['id']);
+             echo $description . $selectedValue;
+           }
+           else {
+             $result = $this->callAPISuccess('Contact', 'create', array('contact_type' => 'Individual', 'email' => substr(sha1(rand()), 0, 7) . 'man3@yahoo.com'));
+             $contactId3 = $result['id'];
+             $this->callAPISuccess('CustomValue', 'create', array('entity_id' => $contactId3, 'custom_' . $customId => $greaterSelectedValue));
+             $result = $this->callAPISuccess('Contact', 'Get', array('custom_' . $customId => array($op => $selectedValue)));
+             echo $description . $selectedValue;
+             $this->assertEquals($contactId, $result['values'][$contactId]['id']);
+             if ($op == '>=') {
+               $this->assertEquals($contactId3, $result['values'][$contactId3]['id']);
+             }
+             else {
+               $this->assertEquals($contactId2, $result['values'][$contactId2]['id']);
+             }
+             $this->callAPISuccess('contact', 'delete', array('id' => $contactId3));
+           }
+           $this->callAPISuccess('contact', 'delete', array('id' => $contactId2));
+           break;
+         case 'IN':
+           $result = $this->callAPISuccess('Contact', 'Get', array('custom_' . $customId => array($op => (array) $selectedValue)));
+           $this->assertEquals($contactId, $result['id']);
+           echo $description . implode(",", (array) $selectedValue);
+           break;
+         case 'NOT IN':
+           $result = $this->callAPISuccess('Contact', 'Get', array('custom_' . $customId => array($op => (array) $notselectedValue)));
+           $this->assertEquals($contactId, $result['id']);
+           echo $description . implode(",", (array) $notselectedValue);
+           break;
+         case 'LIKE':
+           $selectedValue = is_array($selectedValue) ? $selectedValue[0] : $selectedValue;
+           $result = $this->callAPISuccess('Contact', 'Get', array('custom_' . $customId => array($op => "%$selectedValue%")));
+           $this->assertEquals($contactId, $result['id']);
+           echo $description . "%$selectedValue%";
+           break;
  
-     $result = $this->callAPISuccess('CustomValue', 'Get', $params);
-     // delete the contact
-     $this->callAPISuccess('contact', 'delete', array('id' => $contact_id));
+         case 'NOT LIKE':
+           $result = $this->callAPISuccess('Contact', 'Get', array('custom_' . $customId => array($op => $notselectedValue)));
+           $this->assertEquals($contactId, $result['id']);
+           echo $description . "'$notselectedValue'";
+           break;
  
-     $this->assertEquals($contact_id, $result['values'][$secondCustomField]['entity_id']);
-     $this->assertEquals('value 1', $result['values'][$secondCustomField]['latest']);
-     $this->assertEquals('value 1', $result['values'][$secondCustomField][0]);
+         case 'IS NULL':
+           $result = $this->callAPISuccess('Contact', 'Get', array('custom_' . $customId => array($op => 1)));
+           $this->assertEquals(FALSE, array_key_exists($contactId, $result['values']));
+           echo $description;
+           break;
  
-     $this->assertEquals($contact_id, $result['values'][$thirdCustomField]['entity_id']);
-     $this->assertEquals('multi value 1', $result['values'][$thirdCustomField][1]);
-     $this->assertEquals('multi value 2', $result['values'][$thirdCustomField][2]);
+         case 'IS NOT NULL':
+           $result = $this->callAPISuccess('Contact', 'Get', array('custom_' . $customId => array($op => 1)));
+           $this->assertEquals($contactId, $result['id']);
+           echo $description;
+           break;
+       }
+     }
  
-     $this->assertEquals($contact_id, $result['values'][$firstCustomField]['entity_id']);
-     $this->assertEquals('second multi value 1', $result['values'][$firstCustomField][1]);
-     $this->assertEquals('', $result['values'][$firstCustomField][2]);
-     $this->assertEquals('second multi value 2', $result['values'][$firstCustomField][3]);
-     $this->assertEquals('second multi value 3', $result['values'][$firstCustomField][4]);
-     $this->assertEquals('second multi value 3', $result['values'][$firstCustomField]['latest']);
+     $this->callAPISuccess('Contact', 'delete', array('id' => $contactId));
    }
  
 +  /**
 +   * Ensure custom data is updated when option values are modified
 +   *
 +   * @link https://issues.civicrm.org/jira/browse/CRM-11856
 +   *
 +   * @throws \CiviCRM_API3_Exception
 +   */
 +  public function testAlterOptionValue() {
 +    $selectField = $this->customFieldCreate(array(
 +      'custom_group_id' => $this->ids['single']['custom_group_id'],
 +      'label' => 'Custom Select',
 +      'html_type' => 'Select',
 +      'option_values' => array(
 +        'one' => 'Option1',
 +        'two' => 'Option2',
 +        'notone' => 'OptionNotOne',
 +      ),
 +    ));
 +    $selectField = civicrm_api3('customField', 'getsingle', array('id' => $selectField['id']));
 +    $radioField = $this->customFieldCreate(array(
 +      'custom_group_id' => $this->ids['single']['custom_group_id'],
 +      'label' => 'Custom Radio',
 +      'html_type' => 'Radio',
 +      'option_group_id' => $selectField['option_group_id'],
 +    ));
 +    $multiSelectField = $this->customFieldCreate(array(
 +      'custom_group_id' => $this->ids['single']['custom_group_id'],
 +      'label' => 'Custom Multi-Select',
 +      'html_type' => 'Multi-Select',
 +      'option_group_id' => $selectField['option_group_id'],
 +    ));
 +    $selectName = 'custom_' . $selectField['id'];
 +    $radioName = 'custom_' . $radioField['id'];
 +    $multiSelectName = 'custom_' . $multiSelectField['id'];
 +    $controlFieldName = 'custom_' . $this->ids['single']['custom_field_id'];
 +
 +    $params = array(
 +      'first_name' => 'abc4',
 +      'last_name' => 'xyz4',
 +      'contact_type' => 'Individual',
 +      'email' => 'man4@yahoo.com',
 +      $selectName => 'one',
 +      $multiSelectName => array('one', 'two', 'notone'),
 +      $radioName => 'notone',
 +      // The control group in a science experiment should be unaffected
 +      $controlFieldName => 'one',
 +    );
 +
 +    $contact = $this->callAPISuccess('Contact', 'create', $params);
 +
 +    $result = $this->callAPISuccess('Contact', 'getsingle', array(
 +      'id' => $contact['id'],
 +      'return' => array($selectName, $multiSelectName),
 +    ));
 +    $this->assertEquals('one', $result[$selectName]);
 +    $this->assertEquals(array('one', 'two', 'notone'), $result[$multiSelectName]);
 +
 +    $this->callAPISuccess('OptionValue', 'create', array(
 +      'value' => 'one-modified',
 +      'option_group_id' => $selectField['option_group_id'],
 +      'name' => 'Option1',
 +      'options' => array(
 +        'match-mandatory' => array('option_group_id', 'name'),
 +      ),
 +    ));
 +
 +    $result = $this->callAPISuccess('Contact', 'getsingle', array(
 +      'id' => $contact['id'],
 +      'return' => array($selectName, $multiSelectName, $controlFieldName, $radioName),
 +    ));
 +    // Ensure the relevant fields have been updated
 +    $this->assertEquals('one-modified', $result[$selectName]);
 +    $this->assertEquals(array('one-modified', 'two', 'notone'), $result[$multiSelectName]);
 +    // This field should not have changed because we didn't alter this option
 +    $this->assertEquals('notone', $result[$radioName]);
 +    // This should not have changed because this field doesn't use the affected option group
 +    $this->assertEquals('one', $result[$controlFieldName]);
 +  }
 +
  }