Merge remote-tracking branch 'upstream/4.4' into 4.4-master-2014-06-23-14-48-29
authorTim Otten <totten@civicrm.org>
Mon, 23 Jun 2014 22:12:52 +0000 (15:12 -0700)
committerTim Otten <totten@civicrm.org>
Mon, 23 Jun 2014 22:12:52 +0000 (15:12 -0700)
Conflicts:
CRM/Core/Invoke.php
CRM/Profile/Form.php
CRM/Profile/Form/Edit.php
api/v3/utils.php

16 files changed:
1  2 
CRM/Activity/Form/Task/Delete.php
CRM/Contact/Form/Task/Batch.php
CRM/Core/I18n.php
CRM/Core/Lock.php
CRM/Core/Payment/AuthorizeNetIPN.php
CRM/Core/Payment/PayPalProIPN.php
CRM/Mailing/BAO/MailingJob.php
CRM/Profile/Form.php
CRM/Profile/Form/Edit.php
CRM/Profile/Page/Router.php
CRM/Utils/Address.php
CRM/Utils/Check/Env.php
CRM/Utils/Time.php
api/v3/utils.php
tests/phpunit/api/v3/DomainTest.php
tests/phpunit/api/v3/GrantTest.php

Simple merge
Simple merge
Simple merge
index e1482c444031afba78a929bacfc76d9c5a498e9c,c3e306055b031baa6b3f49e95c0e88496a4f40a9..862d2da5d46d395ee7634734f9022fad1bd0ac8e
@@@ -52,10 -52,11 +52,10 @@@ class CRM_Core_Lock 
     *                                mysql server and you want to limit the number of parallel cron
     *                                jobs - CRM-91XX
     *
 -   * @return object the lock object
 -   *
 +   * @return \CRM_Core_Lock the lock object
     */
-  function __construct($name, $timeout = NULL, $serverWideLock = FALSE) {
-     $config   = CRM_Core_Config::singleton();
+   function __construct($name, $timeout = NULL, $serverWideLock = FALSE) {
+     $config = CRM_Core_Config::singleton();
      $dsnArray = DB::parseDSN($config->dsn);
      $database = $dsnArray['database'];
      $domainID = CRM_Core_Config::domainID();
      $this->release();
    }
  
 +  /**
 +   * @return bool
 +   */
    function acquire() {
+     if (defined('CIVICRM_LOCK_DEBUG')) {
+       CRM_Core_Error::debug_log_message('acquire lock for ' . $this->_name);
+     }
      if (!$this->_hasLock) {
        $query = "SELECT GET_LOCK( %1, %2 )";
-       $params = array(1 => array($this->_name, 'String'),
+       $params = array(
+         1 => array($this->_name, 'String'),
          2 => array($this->_timeout, 'Integer'),
        );
        $res = CRM_Core_DAO::singleValueQuery($query, $params);
index c1c2d741c0008847bdbc9f38368c0bfd52eea56d,fbcf06929da0cf6d62f172ca88c78d21d1519cdd..73926d1fa071c2aed64a50f86c7066d5fcaf3d0d
@@@ -256,12 -238,8 +256,12 @@@ class CRM_Core_Payment_AuthorizeNetIPN 
      }
    }
  
 +  /**
 +   * @param $ids
 +   * @param $input
 +   */
    function getIDs(&$ids, &$input) {
-     $ids['contact'] = self::retrieve('x_cust_id', 'Integer');
+     $ids['contact'] = self::retrieve('x_cust_id', 'Integer', FALSE, 0);
      $ids['contribution'] = self::retrieve('x_invoice_num', 'Integer');
  
      // joining with contribution table for extra checks
Simple merge
Simple merge
index 1b8abfd80d71265ddf1a472c7e25c982afcd9e96,f223130a948473a434cad6a702b4f23774749fdc..0cd7a679d99ad9617430d25c48a1ad7412c257fe
@@@ -1118,8 -1081,8 +1108,8 @@@ class CRM_Profile_Form extends CRM_Core
          return;
        }
      }
-     CRM_Utils_Hook::processProfile($this->_ufGroupName);
+     CRM_Utils_Hook::processProfile($this->_ufGroup['name']);
 -    if (CRM_Utils_Array::value('image_URL', $params)) {
 +    if (!empty($params['image_URL'])) {
        CRM_Contact_BAO_Contact::processImageParams($params);
      }
  
        }
      }
  
-     $addToGroupId = NULL;
-     if (!empty($params['add_to_group'])) {
-       $addToGroupId = $params['add_to_group'];
+     $addToGroupId = CRM_Utils_Array::value('add_to_group_id', $this->_ufGroup);
 -    if ($addToGroupId) {
++    if (!empty($addToGroupId)) {
        //run same check whether group is a mailing list
        $groupTypes = CRM_Core_DAO::getFieldValue('CRM_Contact_DAO_Group',
          $addToGroupId, 'group_type', 'id'
index ce65944bcedb68179ba0da3df6e2c5c9bfa7a8aa,da71bedbc5bd64be233ae02f412591953113c948..4d1e1d7571900792721a47ef1b7e56c5875dce47
@@@ -113,35 -113,16 +113,28 @@@ class CRM_Profile_Form_Edit extends CRM
  
      parent::preProcess();
  
-     // make sure the gid is set and valid
-     if (!$this->_gid) {
-       CRM_Core_Error::fatal(ts('The requested Profile (gid=%1) is disabled, OR there is no Profile with that ID, OR a valid \'gid=\' integer value is missing from the URL. Contact the site administrator if you need assistance.',
-           array(1 => $this->_gid)
-         ));
-     }
 -    // and also the profile is of type 'Profile'
 -    $query = "
 -SELECT module
 -  FROM civicrm_uf_join
 - WHERE module = 'Profile'
 -   AND uf_group_id = %1
 +      // and also the profile is of type 'Profile'
 +      $query = "
 +SELECT module,is_reserved
 +  FROM civicrm_uf_group
 +  LEFT JOIN civicrm_uf_join ON uf_group_id = civicrm_uf_group.id
 +  WHERE civicrm_uf_group.id = %1
  ";
 -    $params = array(1 => array($this->_gid, 'Integer'));
 -    $dao = CRM_Core_DAO::executeQuery($query, $params);
 -    if (!$dao->fetch()) {
 +
 +      $params = array(1 => array($this->_gid, 'Integer'));
 +      $dao = CRM_Core_DAO::executeQuery($query, $params);
 +
 +      $isProfile = false;
 +      while ($dao->fetch()) {
 +          $isProfile = ($isProfile || ($dao->module == "Profile"));
 +      }
 +
 +
 +      //Check that the user has the "add contacts" Permission
 +      $canAdd = CRM_Core_Permission::check("add contacts");
 +
 +      //Remove need for Profile module type when using reserved profiles [CRM-14488]
 +      if( !$dao->N || (!$isProfile && !($dao->is_reserved && $canAdd))) {
        CRM_Core_Error::fatal(ts('The requested Profile (gid=%1) is not configured to be used for \'Profile\' edit and view forms in its Settings. Contact the site administrator if you need assistance.',
            array(1 => $this->_gid)
          ));
        }
  
        if (!$this->_cancelURL) {
-         if ($ufGroup->cancel_URL) {
-           $this->_cancelURL = $ufGroup->cancel_URL;
-         }
-         else {
-           $this->_cancelURL = CRM_Utils_System::url('civicrm/profile',
-             "reset=1&gid={$gidString}"
-           );
-         }
+         $this->_cancelURL = CRM_Utils_System::url('civicrm/profile',
+           "reset=1&gid={$gidString}"
+         );
        }
  
 -      if ($this->_multiRecordProfile) {
 -        $urlParams = "reset=1&id={$this->_id}&gid={$gidString}";
 -
 -        // get checksum if present
 -        if ($this->get('cs')) {
 -          $urlParams .= "&cs=" . $this->get('cs');
 -        }
 -        $this->_postURL = CRM_Utils_System::url('civicrm/profile/edit', $urlParams);
 -        $this->_cancelURL = CRM_Utils_System::url('civicrm/profile/edit', $urlParams);
 -
 -        //passing the post url to template so the popup form does
 -        //proper redirection and proccess form errors if any
 -        if (!isset($this->_onPopupClose) || $this->_onPopupClose == 'redirectToProfile') {
 -          $popupRedirect = CRM_Utils_System::url('civicrm/profile/edit', $urlParams, FALSE, NULL, FALSE);
 -        }
 -        elseif ($this->_onPopupClose == 'redirectToTab') {
 -          $popupRedirect = CRM_Utils_System::url('civicrm/contact/view',
 -            "reset=1&cid={$this->_id}&selectedChild=custom_{$this->_customGroupId}", FALSE, NULL, FALSE);
 -        }
 -
 -        $this->assign('urlParams', $urlParams);
 -        $this->assign('postUrl', $popupRedirect);
 -      }
 -
        // we do this gross hack since qf also does entity replacement
        $this->_postURL = str_replace('&amp;', '&', $this->_postURL);
        $this->_cancelURL = str_replace('&amp;', '&', $this->_cancelURL);
        'isDefault' => TRUE,
      );
  
 -    if ($this->_context != 'dialog') {
 -      $buttons[] = array(
 -        'type' => 'cancel',
 -        'name' => ts('Cancel'),
 -        'isDefault' => TRUE,
 -        'js' => array('onclick' => "location.href='{$this->_cancelURL}'; return false;"),
 -      );
 -    }
 +    $buttons[] = array(
 +      'type' => 'cancel',
 +      'name' => ts('Cancel'),
 +      'isDefault' => TRUE,
++      'js' => array('onclick' => "location.href='{$this->_cancelURL}'; return false;"),
 +    );
  
      $this->addButtons($buttons);
  
index 54da11af2f3584a046a3a431e2858a373d022ee1,0000000000000000000000000000000000000000..181d217db1ef3d886a94d6ac67521ac2bb3a8621
mode 100644,000000..100644
--- /dev/null
@@@ -1,150 -1,0 +1,134 @@@
-       $buttonType = CRM_Utils_Array::value('_qf_Edit_cancel', $_POST);
-       // CRM-5849: we should actually check the button *type*, but we get the *value*, potentially translated;
-       // we should keep both English and translated checks just to make sure we also handle untranslated Cancels
-       if ($buttonType == 'Cancel' or $buttonType == ts('Cancel')) {
-         $cancelURL = CRM_Utils_Request::retrieve('cancelURL',
-           'String',
-           CRM_Core_DAO::$_nullObject,
-           FALSE,
-           NULL,
-           $_POST
-         );
-         if ($cancelURL) {
-           CRM_Utils_System::redirect($cancelURL);
-         }
-       }
 +<?php
 +/*
 + +--------------------------------------------------------------------+
 + | CiviCRM version 4.5                                                |
 + +--------------------------------------------------------------------+
 + | Copyright CiviCRM LLC (c) 2004-2014                                |
 + +--------------------------------------------------------------------+
 + | This file is a part of CiviCRM.                                    |
 + |                                                                    |
 + | CiviCRM is free software; you can copy, modify, and distribute it  |
 + | under the terms of the GNU Affero General Public License           |
 + | Version 3, 19 November 2007 and the CiviCRM Licensing Exception.   |
 + |                                                                    |
 + | CiviCRM is distributed in the hope that it will be useful, but     |
 + | WITHOUT ANY WARRANTY; without even the implied warranty of         |
 + | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.               |
 + | See the GNU Affero General Public License for more details.        |
 + |                                                                    |
 + | You should have received a copy of the GNU Affero General Public   |
 + | License and the CiviCRM Licensing Exception along                  |
 + | with this program; if not, contact CiviCRM LLC                     |
 + | at info[AT]civicrm[DOT]org. If you have questions about the        |
 + | GNU Affero General Public License or the licensing of CiviCRM,     |
 + | see the CiviCRM license FAQ at http://civicrm.org/licensing        |
 + +--------------------------------------------------------------------+
 +*/
 +
 +/**
 + *
 + * @package CRM
 + * @copyright CiviCRM LLC (c) 2004-2014
 + * $Id$
 + *
 + */
 +
 +/**
 + * This is some kind of special-purpose router/front-controller for the various profile URLs.
 + */
 +class CRM_Profile_Page_Router extends CRM_Core_Page {
 +
 +  /**
 +   * This is some kind of special-purpose router/front-controller for the various profile URLs.
 +   *
 +   * @param $args array this array contains the arguments of the url
 +   *
 +   * @return string|void
 +   * @static
 +   * @access public
 +   */
 +  function run($args = NULL) {
 +    if ($args[1] !== 'profile') {
 +      return;
 +    }
 +
 +    $secondArg = CRM_Utils_Array::value(2, $args, '');
 +
 +    if ($secondArg == 'map') {
 +      $controller = new CRM_Core_Controller_Simple(
 +        'CRM_Contact_Form_Task_Map',
 +        ts('Map Contact'),
 +        NULL, FALSE, FALSE, TRUE
 +      );
 +
 +      $gids = explode(',', CRM_Utils_Request::retrieve('gid', 'String', CRM_Core_DAO::$_nullObject, FALSE, 0, 'GET'));
 +
 +      if (count($gids) > 1) {
 +        foreach ($gids as $pfId) {
 +          $profileIds[] = CRM_Utils_Type::escape($pfId, 'Positive');
 +        }
 +        $controller->set('gid', $profileIds[0]);
 +        $profileGID = $profileIds[0];
 +      }
 +      else {
 +        $profileGID = CRM_Utils_Request::retrieve('gid', 'Integer', $controller, TRUE);
 +      }
 +
 +
 +      // make sure that this profile enables mapping
 +      // CRM-8609
 +      $isMap =
 +        CRM_Core_DAO::getFieldValue('CRM_Core_DAO_UFGroup', $profileGID, 'is_map');
 +      if (!$isMap) {
 +        CRM_Core_Error::statusBounce(ts('This profile does not have the map feature turned on.'));
 +      }
 +
 +      $profileView = CRM_Utils_Request::retrieve('pv', 'Integer', $controller, FALSE);
 +
 +      // set the userContext stack
 +      $session = CRM_Core_Session::singleton();
 +      if ($profileView) {
 +        $session->pushUserContext(CRM_Utils_System::url('civicrm/profile/view'));
 +      }
 +      else {
 +        $session->pushUserContext(CRM_Utils_System::url('civicrm/profile', 'force=1'));
 +      }
 +
 +      $controller->set('profileGID', $profileGID);
 +      $controller->process();
 +      return $controller->run();
 +    }
 +
 +    if ($secondArg == 'edit' || $secondArg == 'create') {
 +      if ($secondArg == 'edit') {
 +        $controller = new CRM_Core_Controller_Simple('CRM_Profile_Form_Edit',
 +          ts('Create Profile'),
 +          CRM_Core_Action::UPDATE,
 +          FALSE, FALSE, TRUE
 +        );
 +        $controller->set('edit', 1);
 +        $controller->process();
 +        return $controller->run();
 +      }
 +      else {
 +        $wrapper = new CRM_Utils_Wrapper();
 +        return $wrapper->run('CRM_Profile_Form_Edit',
 +          ts('Create Profile'),
 +          array(
 +            'mode' => CRM_Core_Action::ADD,
 +            'ignoreKey' => TRUE,
 +          )
 +        );
 +      }
 +    }
 +
 +    if ($secondArg == 'view' || empty($secondArg)) {
 +      $page = new CRM_Profile_Page_Listings();
 +      return $page->run();
 +    }
 +
 +    CRM_Utils_System::permissionDenied();
 +    return;
 +  }
 +
 +}
Simple merge
Simple merge
Simple merge
index 1ee834087b9e59ff4d970db954dedc249fb7d344,252f44947935a8ea18a06354922ccc7f5e88cfdd..3fb9699444568f795502c324bd11f4cb4696ecae
@@@ -308,6 -313,6 +307,7 @@@ function _civicrm_api3_get_DAO($name) 
    if(file_exists("api/v3/$name.php")) {
      include_once "api/v3/$name.php";
    }
++
    $daoFn = "_civicrm_api3_" . _civicrm_api_get_entity_name_from_camel($name) . "_DAO";
    if (function_exists($daoFn)) {
      return $daoFn();
@@@ -936,22 -927,101 +951,117 @@@ function _civicrm_api3_custom_format_pa
    }
  }
  
 +/**
 + * @param $params
 + * @param $entity
 + */
 +function _civicrm_api3_format_params_for_create(&$params, $entity) {
 +  $nonGenericEntities = array('Contact', 'Individual', 'Household', 'Organization');
 +
 +  $customFieldEntities = array_diff_key(CRM_Core_BAO_CustomQuery::$extendsMap, array_fill_keys($nonGenericEntities, 1));
 +  if(!array_key_exists($entity, $customFieldEntities)) {
 +    return;
 +  }
 +  $values = array();
 +  _civicrm_api3_custom_format_params($params, $values, $entity);
 +  $params = array_merge($params, $values);
 +}
 +
+ /**
+  * we can't rely on downstream to add separators to checkboxes so we'll check here. We should look at pushing to BAO function
+  * and / or validate function but this is a safe place for now as it has massive test coverage & we can keep the change very specific
+  * note that this is specifically tested in the GRANT api test case so later refactoring should use that as a checking point
+  *
+  * We will only alter the value if we are sure that changing it will make it correct - if it appears wrong but does not appear to have a clear fix we
+  * don't touch - lots of very cautious code in here
+  *
+  * The resulting array should look like
+  * array(
+  *  'key' => 1,
+  *  'key1' => 1,
+  * );
+  *
+  * OR one or more keys wrapped in a CRM_Core_DAO::VALUE_SEPARATOR - either it accepted by the receiving function
+  *
+  * @todo - we are probably skipping handling disabled options as presumably getoptions is not giving us them. This should be non-regressive but might
+  * be fixed in future
+  *
+  * @param $checkboxFieldValue
+  * @param $customFieldLabel
+  * @param $entity
+  *
+  */
+ function formatCheckBoxField(&$checkboxFieldValue, $customFieldLabel, $entity) {
+   if (is_string($checkboxFieldValue) && stristr($checkboxFieldValue, CRM_Core_DAO::VALUE_SEPARATOR)) {
+     // we can assume it's pre-formatted
+     return;
+   }
+   $options = civicrm_api($entity, 'getoptions', array('field' => $customFieldLabel, 'version' => 3));
+   if (!empty($options['is_error'])) {
+     //the check is precautionary - can probably be removed later
+     return;
+   }
+   $options = $options['values'];
+   $validValue = TRUE;
+   if (is_array($checkboxFieldValue)) {
+     foreach ($checkboxFieldValue as $key => $value) {
+       if (!array_key_exists($key, $options)) {
+         $validValue = FALSE;
+       }
+     }
+     if ($validValue) {
+       // we have been passed an array that is already in the 'odd' custom field format
+       return;
+     }
+   }
+   // so we either have an array that is not keyed by the value or we have a string that doesn't hold separators
+   // if the array only has one item we'll treat it like any other string
+   if (is_array($checkboxFieldValue) && count($checkboxFieldValue) == 1) {
+     $possibleValue = reset($checkboxFieldValue);
+   }
+   if (is_string($checkboxFieldValue)) {
+     $possibleValue = $checkboxFieldValue;
+   }
+   if (isset($possibleValue) && array_key_exists($possibleValue, $options)) {
+     $checkboxFieldValue = CRM_Core_DAO::VALUE_SEPARATOR . $possibleValue . CRM_Core_DAO::VALUE_SEPARATOR;
+     return;
+   }
+   elseif (is_array($checkboxFieldValue)) {
+     // so this time around we are considering the values in the array
+     $possibleValues = $checkboxFieldValue;
+     $formatValue = TRUE;
+   }
+   elseif (stristr($checkboxFieldValue, ',')) {
+     $formatValue = TRUE;
+     //lets see if we should separate it - we do this near the end so we
+     // ensure we have already checked that the comma is not part of a legitimate match
+     // and of course, we don't make any changes if we don't now have matches
+     $possibleValues = explode(',', $checkboxFieldValue);
+   }
+   else {
+     // run out of ideas as to what the format might be - if it's a string it doesn't match with or without the ','
+     return;
+   }
+   foreach ($possibleValues as $index => $possibleValue) {
+     if (array_key_exists($possibleValue, $options)) {
+       // do nothing - we will leave formatValue set to true unless another value is not found (which would cause us to ignore the whole value set)
+     }
+     elseif (array_key_exists(trim($possibleValue), $options)) {
+       $possibleValues[$index] = trim($possibleValue);
+     }
+     else {
+       $formatValue = FALSE;
+     }
+   }
+   if ($formatValue) {
+     $checkboxFieldValue = CRM_Core_DAO::VALUE_SEPARATOR . implode(CRM_Core_DAO::VALUE_SEPARATOR, $possibleValues) . CRM_Core_DAO::VALUE_SEPARATOR;
+   }
+ }
  /**
   * @deprecated
   * This function ensures that we have the right input parameters
@@@ -1601,13 -1709,13 +1709,12 @@@ function _civicrm_api3_swap_out_aliases
   *
   * @param array $params params from civicrm_api
   * @param string $fieldName uniquename of field being checked
-  * @param $fieldInfo
-  * @param $entity
+  * @param array $fieldInfo array of fields from getfields function
+  * @param string $entity
   * @throws API_Exception
-  * @internal param array $fieldinfo array of fields from getfields function
   */
  function _civicrm_api3_validate_integer(&$params, &$fieldName, &$fieldInfo, $entity) {
 -  //if fieldname exists in params
 -  if (CRM_Utils_Array::value($fieldName, $params)) {
 +  if (!empty($params[$fieldName])) {
      // if value = 'user_contact_id' (or similar), replace value with contact id
      if (!is_numeric($params[$fieldName]) && is_scalar($params[$fieldName])) {
        $realContactId = _civicrm_api3_resolve_contactID($params[$fieldName]);
Simple merge
Simple merge