Merge pull request #6429 from mallezie/crm-16976
authorcolemanw <coleman@civicrm.org>
Sat, 8 Aug 2015 14:27:40 +0000 (10:27 -0400)
committercolemanw <coleman@civicrm.org>
Sat, 8 Aug 2015 14:27:40 +0000 (10:27 -0400)
CRM-16976 allow to filter campaigns based on active state

46 files changed:
CRM/Batch/Page/AJAX.php
CRM/Campaign/Page/AJAX.php
CRM/Contact/BAO/GroupContact.php
CRM/Contact/Page/AJAX.php
CRM/Contact/Page/ImageFile.php
CRM/Core/Block.php
CRM/Core/Controller.php
CRM/Core/Form.php
CRM/Core/Page/AJAX.php
CRM/Core/Page/AJAX/Attachment.php
CRM/Custom/Page/AJAX.php
CRM/Dedupe/Merger.php
CRM/Export/BAO/Export.php
CRM/Financial/BAO/ExportFormat.php
CRM/Financial/Page/AJAX.php
CRM/Group/Page/AJAX.php
CRM/Mailing/Info.php
CRM/Mailing/Page/Preview.php
CRM/Member/Form/Membership.php
CRM/Report/Form.php
CRM/Report/Form/Mailing/Summary.php
CRM/Report/Utils/Report.php
CRM/Upgrade/Incremental/php/FourSix.php
CRM/Upgrade/Incremental/sql/4.6.7.mysql.tpl [new file with mode: 0644]
CRM/Utils/API/ReloadOption.php
CRM/Utils/ICalendar.php
CRM/Utils/JSON.php
CRM/Utils/PDF/Utils.php
CRM/Utils/REST.php
CRM/Utils/System.php
CRM/Utils/System/Base.php
CRM/Utils/System/Drupal.php
CRM/Utils/System/Drupal6.php
CRM/Utils/System/Drupal8.php
CRM/Utils/System/Joomla.php
CRM/Utils/System/UnitTests.php
Civi/API/Subscriber/ChainSubscriber.php
api/api.php
api/v3/Event.php
api/v3/Mailing.php
templates/CRM/Admin/Page/APIExplorer.js
templates/CRM/Contact/Page/View/CustomData.tpl
tests/phpunit/CRM/Utils/API/ReloadOptionTest.php
tests/phpunit/WebTest/Utils/RedirectTest.php [new file with mode: 0644]
tests/phpunit/api/v3/ContactTest.php
tests/phpunit/api/v3/EventTest.php

index 434533e67812d94304325e4251d85394d7375dfe..864b38a882d9156c882ebafe09a8a79ab362aeba 100644 (file)
@@ -114,7 +114,7 @@ class CRM_Batch_Page_AJAX {
         'links',
       );
     }
-    header('Content-Type: application/json');
+    CRM_Utils_System::setHttpHeader('Content-Type', 'application/json');
     echo CRM_Utils_JSON::encodeDataTableSelector($batches, $sEcho, $iTotal, $iFilteredTotal, $selectorElements);
     CRM_Utils_System::civiExit();
   }
index dc036e05ce3707869dfeb61cb2bd50766cb6ebfc..07d953b074f8ecacc0ffa651bbbf4311c2961143 100644 (file)
@@ -360,7 +360,7 @@ class CRM_Campaign_Page_AJAX {
 
     $iFilteredTotal = $iTotal;
 
-    header('Content-Type: application/json');
+    CRM_Utils_System::setHttpHeader('Content-Type', 'application/json');
     echo CRM_Utils_JSON::encodeDataTableSelector($searchRows, $sEcho, $iTotal, $iFilteredTotal, $selectorElements);
     CRM_Utils_System::civiExit();
   }
@@ -660,7 +660,7 @@ class CRM_Campaign_Page_AJAX {
 
     $iFilteredTotal = $iTotal;
 
-    header('Content-Type: application/json');
+    CRM_Utils_System::setHttpHeader('Content-Type', 'application/json');
     echo CRM_Utils_JSON::encodeDataTableSelector($searchRows, $sEcho, $iTotal, $iFilteredTotal, $selectorElements);
     CRM_Utils_System::civiExit();
   }
@@ -764,7 +764,7 @@ class CRM_Campaign_Page_AJAX {
 
     $iFilteredTotal = $iTotal;
 
-    header('Content-Type: application/json');
+    CRM_Utils_System::setHttpHeader('Content-Type', 'application/json');
     echo CRM_Utils_JSON::encodeDataTableSelector($searchRows, $sEcho, $iTotal, $iFilteredTotal, $selectorElements);
     CRM_Utils_System::civiExit();
   }
@@ -863,7 +863,7 @@ class CRM_Campaign_Page_AJAX {
 
     $iFilteredTotal = $iTotal;
 
-    header('Content-Type: application/json');
+    CRM_Utils_System::setHttpHeader('Content-Type', 'application/json');
     echo CRM_Utils_JSON::encodeDataTableSelector($searchRows, $sEcho, $iTotal, $iFilteredTotal, $selectorElements);
     CRM_Utils_System::civiExit();
   }
index 2a564f3febed09ababe1531805937839920afe0b..8a4bb40b9e98b669c862d26caa0e2ea13fc9b118 100644 (file)
@@ -351,7 +351,7 @@ class CRM_Contact_BAO_GroupContact extends CRM_Contact_DAO_GroupContact {
                     civicrm_subscription_history.method as method';
     }
 
-    $where = " WHERE contact_a.id = %1 AND civicrm_group.is_active = 1 AND civicrm_group.saved_search_id IS NULL";
+    $where = " WHERE contact_a.id = %1 AND civicrm_group.is_active = 1";
 
     if ($excludeHidden) {
       $where .= " AND civicrm_group.is_hidden = 0 ";
@@ -381,6 +381,10 @@ class CRM_Contact_BAO_GroupContact extends CRM_Contact_DAO_GroupContact {
 
     $from = CRM_Contact_BAO_Query::fromClause($tables);
 
+    //CRM-16945: seems hackish but as per CRM-16483 of using group criteria for Search Builder it is mandatory
+    //to include group_contact_cache clause when group table is present, so following code remove duplicacy
+    $from = str_replace("OR civicrm_group.id = civicrm_group_contact_cache.group_id", 'AND civicrm_group.saved_search_id IS NULL', $from);
+
     $where .= " AND $permission ";
 
     if ($onlyPublicGroups) {
@@ -799,15 +803,10 @@ AND    contact_id IN ( $contactStr )
 
     $options = CRM_Core_PseudoConstant::get(__CLASS__, $fieldName, $params, $context);
 
-    if (($fieldName == 'group' || $fieldName == 'group_id')) {
-      // Enforce group visibility permissions
-      if (!empty($props['check_permissions'])) {
-        $options = CRM_Core_PseudoConstant::group();
-      }
-      if ($context == 'search' || $context == 'create') {
-        // Sort group list by hierarchy
-        $options = CRM_Contact_BAO_Group::getGroupsHierarchy($options, NULL, '- ', TRUE);
-      }
+    // Sort group list by hierarchy
+    // TODO: This will only work when api.entity is "group_contact". What about others?
+    if (($fieldName == 'group' || $fieldName == 'group_id') && ($context == 'search' || $context == 'create')) {
+      $options = CRM_Contact_BAO_Group::getGroupsHierarchy($options, NULL, '- ', TRUE);
     }
 
     return $options;
index feba0661a7ed82fe6684b4e1d4fee05b9b70f646..a2a9b3bd9c54559ebc3f2dce95ba5092186e3795 100644 (file)
@@ -295,7 +295,7 @@ class CRM_Contact_Page_AJAX {
   }
 
   public static function groupTree() {
-    header('Content-Type: application/json');
+    CRM_Utils_System::setHttpHeader('Content-Type', 'application/json');
     $gids = CRM_Utils_Type::escape($_GET['gids'], 'String');
     echo CRM_Contact_BAO_GroupNestingCache::json($gids);
     CRM_Utils_System::civiExit();
@@ -305,7 +305,7 @@ class CRM_Contact_Page_AJAX {
    * Delete custom value.
    */
   public static function deleteCustomValue() {
-    header('Content-Type: text/plain');
+    CRM_Utils_System::setHttpHeader('Content-Type', 'text/plain');
     $customValueID = CRM_Utils_Type::escape($_REQUEST['valueID'], 'Positive');
     $customGroupID = CRM_Utils_Type::escape($_REQUEST['groupID'], 'Positive');
 
@@ -370,7 +370,7 @@ class CRM_Contact_Page_AJAX {
         $userEmail
         ) = CRM_Contact_BAO_Contact_Location::getEmailDetails($contactID);
 
-      header('Content-Type: text/plain');
+      CRM_Utils_System::setHttpHeader('Content-Type', 'text/plain');
       if ($userEmail) {
         echo $userEmail;
       }
@@ -713,7 +713,7 @@ LIMIT {$offset}, {$rowCount}
       }
     }
 
-    header('Content-Type: application/json');
+    CRM_Utils_System::setHttpHeader('Content-Type', 'application/json');
     echo CRM_Utils_JSON::encodeDataTableSelector($searchRows, $sEcho, $iTotal, $iFilteredTotal, $selectorElements);
 
     CRM_Utils_System::civiExit();
index 443b3ca706fa5e93d73b496d239f0942a92df034..13e4af98e889e74bee1ba1be18982e5af83f5077 100644 (file)
@@ -83,11 +83,11 @@ class CRM_Contact_Page_ImageFile extends CRM_Core_Page {
       header('HTTP/1.0 403 Forbidden');
       return;
     }
-    header('Expires: ' . gmdate('D, d M Y H:i:s \G\M\T', CRM_Utils_Time::getTimeRaw() + $ttl));
-    header("Content-Type: $mimeType");
-    header("Content-Disposition: inline; filename=\"" . basename($file) . "\"");
-    header("Cache-Control: max-age=$ttl, public");
-    header('Pragma: public');
+    CRM_Utils_System::setHttpHeader('Expires', gmdate('D, d M Y H:i:s \G\M\T', CRM_Utils_Time::getTimeRaw() + $ttl));
+    CRM_Utils_System::setHttpHeader("Content-Type", $mimeType);
+    CRM_Utils_System::setHttpHeader("Content-Disposition", "inline; filename=\"" . basename($file) . "\"");
+    CRM_Utils_System::setHttpHeader("Cache-Control", "max-age=$ttl, public");
+    CRM_Utils_System::setHttpHeader('Pragma', 'public');
     readfile($file);
   }
 
index 0f42416532ec4f5d41fb95a9a35bfec65078202d..9fe861ccbb1d62f63c3fd44390193a9787f9a042 100644 (file)
@@ -459,7 +459,7 @@ class CRM_Core_Block {
       $value['url'] = CRM_Utils_System::url($short['path'], $short['query'], FALSE);
     }
     $value['title'] = $short['title'];
-    $value['ref'] = $short['ref'];
+    $value['ref'] = isset($short['ref']) ? $short['ref'] : '';
     if (!empty($short['shortCuts'])) {
       foreach ($short['shortCuts'] as $shortCut) {
         $value['shortCuts'][] = self::setShortcutValues($shortCut);
index c085183bdbe92a52304e9e978137f4823d49303a..4b437735718243fd01cc8fc0513bb344046d68b0 100644 (file)
@@ -692,13 +692,13 @@ class CRM_Core_Controller extends HTML_QuickForm_Controller {
    */
   public function setWord($fileName = NULL) {
     //Mark as a CSV file.
-    header('Content-Type: application/vnd.ms-word');
+    CRM_Utils_System::setHttpHeader('Content-Type', 'application/vnd.ms-word');
 
     //Force a download and name the file using the current timestamp.
     if (!$fileName) {
       $fileName = 'Contacts_' . $_SERVER['REQUEST_TIME'] . '.doc';
     }
-    header("Content-Disposition: attachment; filename=Contacts_$fileName");
+    CRM_Utils_System::setHttpHeader("Content-Disposition", "attachment; filename=Contacts_$fileName");
   }
 
   /**
@@ -706,14 +706,14 @@ class CRM_Core_Controller extends HTML_QuickForm_Controller {
    */
   public function setExcel($fileName = NULL) {
     //Mark as an excel file.
-    header('Content-Type: application/vnd.ms-excel');
+    CRM_Utils_System::setHttpHeader('Content-Type', 'application/vnd.ms-excel');
 
     //Force a download and name the file using the current timestamp.
     if (!$fileName) {
       $fileName = 'Contacts_' . $_SERVER['REQUEST_TIME'] . '.xls';
     }
 
-    header("Content-Disposition: attachment; filename=Contacts_$fileName");
+    CRM_Utils_System::setHttpHeader("Content-Disposition", "attachment; filename=Contacts_$fileName");
   }
 
   /**
@@ -858,18 +858,25 @@ class CRM_Core_Controller extends HTML_QuickForm_Controller {
   }
 
   /**
-   * Instead of outputting a fatal error message, we'll just redirect to the entryURL if present
+   * Instead of outputting a fatal error message, we'll just redirect
+   * to the entryURL if present
    *
    * @return void
    */
   public function invalidKeyRedirect() {
-    if ($this->_entryURL) {
-      CRM_Core_Session::setStatus(ts('Your browser session has expired and we are unable to complete your form submission. We have returned you to the initial step so you can complete and resubmit the form. If you experience continued difficulties, please contact us for assistance.'));
-      return CRM_Utils_System::redirect($this->_entryURL);
-    }
-    else {
-      self::invalidKeyCommon();
+    if ($this->_entryURL && $url_parts = parse_url($this->_entryURL)) {
+      // CRM-16832: Ensure local redirects only.
+      if (!empty($url_parts['path'])) {
+        // Prepend a slash, but don't duplicate it.
+        $redirect_url = '/' . ltrim($url_parts['path'], '/');
+        if (!empty($url_parts['query'])) {
+          $redirect_url .= '?' . $url_parts['query'];
+        }
+        CRM_Core_Session::setStatus(ts('Your browser session has expired and we are unable to complete your form submission. We have returned you to the initial step so you can complete and resubmit the form. If you experience continued difficulties, please contact us for assistance.'));
+        return CRM_Utils_System::redirect($redirect_url);
+      }
     }
+    self::invalidKeyCommon();
   }
 
 }
index 75fc295862efabe308f1852783d63b32b3319e42..ea8615f5c36c6a1074131199f2131ce52063ddcd 100644 (file)
@@ -1202,7 +1202,7 @@ class CRM_Core_Form extends HTML_QuickForm_Page {
       $options = $props['options'];
     }
     else {
-      $info = civicrm_api3($props['entity'], 'getoptions', $props + array('check_permissions' => 1));
+      $info = civicrm_api3($props['entity'], 'getoptions', $props);
       $options = $info['values'];
     }
     if (!array_key_exists('placeholder', $props)) {
index 7d6604ea832f44e703bf9c435ca8cc38e5d61874..a510c94a55b627b489a865926d427520bf12fe83 100644 (file)
@@ -189,7 +189,7 @@ class CRM_Core_Page_AJAX {
 
     // CRM-11831 @see http://www.malsup.com/jquery/form/#file-upload
     if (isset($_SERVER['HTTP_X_REQUESTED_WITH']) && $_SERVER['HTTP_X_REQUESTED_WITH'] == 'XMLHttpRequest') {
-      header('Content-Type: application/json');
+      CRM_Utils_System::setHttpHeader('Content-Type', 'application/json');
     }
     else {
       $output = "<textarea>$output</textarea>";
@@ -209,9 +209,9 @@ class CRM_Core_Page_AJAX {
       // Encourage browsers to cache for a long time - 1 year
       $ttl = 60 * 60 * 24 * 364;
     }
-    header('Expires: ' . gmdate('D, d M Y H:i:s \G\M\T', time() + $ttl));
-    header('Content-Type:      application/javascript');
-    header("Cache-Control: max-age=$ttl, public");
+    CRM_Utils_System::setHttpHeader('Expires', gmdate('D, d M Y H:i:s \G\M\T', time() + $ttl));
+    CRM_Utils_System::setHttpHeader('Content-Type', 'application/javascript');
+    CRM_Utils_System::setHttpHeader('Cache-Control', "max-age=$ttl, public");
   }
 
 }
index 7aaf3cd5d899e2dc9909c30f47a9d830805966d9..d043a5f43b3de6947108614a452c94476cc0b806 100644 (file)
@@ -135,7 +135,7 @@ class CRM_Core_Page_AJAX_Attachment {
     if ($isError) {
       $sapi_type = php_sapi_name();
       if (substr($sapi_type, 0, 3) == 'cgi') {
-        header("Status: 500 Internal Server Error");
+        CRM_Utils_System::setHttpHeader("Status", "500 Internal Server Error");
       }
       else {
         header("HTTP/1.1 500 Internal Server Error");
index b4bc680cb04dab4ed46c3ad98a640e70a509c134..eabe16f097f1ec00e46ef4abb7fe1307949e2257 100644 (file)
@@ -62,7 +62,7 @@ class CRM_Custom_Page_AJAX {
       'class',
     );
 
-    header('Content-Type: application/json');
+    CRM_Utils_System::setHttpHeader('Content-Type', 'application/json');
     echo CRM_Utils_JSON::encodeDataTableSelector($options, $sEcho, $iTotal, $iFilteredTotal, $selectorElements);
     CRM_Utils_System::civiExit();
   }
index 8566e7a18344904072fd4fd2c95875ece70b70ad..119164cbbb178b02317546519464ca20059bfadd 100644 (file)
@@ -1315,7 +1315,7 @@ INNER JOIN  civicrm_membership membership2 ON membership1.membership_type_id = m
           }
 
           // overwrite - need to delete block which belongs to main-contact.
-          if ($mainBlockId && ($operation == 2)) {
+          if (isset($mainBlockId) && $mainBlockId && ($operation == 2)) {
             $deleteDAO = new $daoName();
             $deleteDAO->id = $mainBlockId;
             $deleteDAO->find(TRUE);
index ecc9b1849992b05983d2ea5b0aa7757dff8107f3..c560444b4b537e2210255228f713ae48059b0fd3 100644 (file)
@@ -1251,11 +1251,11 @@ INSERT INTO {$componentTable} SELECT distinct gc.contact_id FROM civicrm_group_c
         $errorFileName = $parserName::errorFileName($type);
         $saveFileName = $parserName::saveFileName($type);
         if (!empty($errorFileName) && !empty($saveFileName)) {
-          header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
-          header('Content-Description: File Transfer');
-          header('Content-Type: text/csv');
-          header('Content-Length: ' . filesize($errorFileName));
-          header('Content-Disposition: attachment; filename=' . $saveFileName);
+          CRM_Utils_System::setHttpHeader('Cache-Control', 'must-revalidate, post-check=0, pre-check=0');
+          CRM_Utils_System::setHttpHeader('Content-Description', 'File Transfer');
+          CRM_Utils_System::setHttpHeader('Content-Type', 'text/csv');
+          CRM_Utils_System::setHttpHeader('Content-Length', filesize($errorFileName));
+          CRM_Utils_System::setHttpHeader('Content-Disposition', 'attachment; filename=' . $saveFileName);
 
           readfile($errorFileName);
         }
index ac035fbe004f11749571742cb758806c3ace0530..e0ffac1bbcb2ffdf28c5d6d7165768df898925a9 100644 (file)
@@ -155,9 +155,9 @@ class CRM_Financial_BAO_ExportFormat {
       $zip = $config->customFileUploadDir . 'Financial_Transactions_' . date('YmdHis') . '.zip';
       $result = $this->createZip($this->_downloadFile, $zip, TRUE);
       if ($result) {
-        header('Content-Type: application/zip');
-        header('Content-Disposition: attachment; filename=' . CRM_Utils_File::cleanFileName(basename($zip)));
-        header('Content-Length: ' . filesize($zip));
+        CRM_Utils_System::setHttpHeader('Content-Type', 'application/zip');
+        CRM_Utils_System::setHttpHeader('Content-Disposition', 'attachment; filename=' . CRM_Utils_File::cleanFileName(basename($zip)));
+        CRM_Utils_System::setHttpHeader('Content-Length', '' . filesize($zip));
         ob_clean();
         flush();
         readfile($config->customFileUploadDir . CRM_Utils_File::cleanFileName(basename($zip)));
@@ -166,9 +166,9 @@ class CRM_Financial_BAO_ExportFormat {
       }
     }
     else {
-      header('Content-Type: text/plain');
-      header('Content-Disposition: attachment; filename=' . CRM_Utils_File::cleanFileName(basename($this->_downloadFile[0])));
-      header('Content-Length: ' . filesize($this->_downloadFile[0]));
+      CRM_Utils_System::setHttpHeader('Content-Type', 'text/plain');
+      CRM_Utils_System::setHttpHeader('Content-Disposition', 'attachment; filename=' . CRM_Utils_File::cleanFileName(basename($this->_downloadFile[0])));
+      CRM_Utils_System::setHttpHeader('Content-Length', '' . filesize($this->_downloadFile[0]));
       ob_clean();
       flush();
       readfile($config->customFileUploadDir . CRM_Utils_File::cleanFileName(basename($this->_downloadFile[0])));
index 907a4b20bf7b07eb3d29d4947c705a773dec9e9a..f8cfa05a78a6205f497a8a137baba66de7b44bd7 100644 (file)
@@ -460,7 +460,7 @@ class CRM_Financial_Page_AJAX {
       'action',
     );
 
-    header('Content-Type: application/json');
+    CRM_Utils_System::setHttpHeader('Content-Type', 'application/json');
     echo CRM_Utils_JSON::encodeDataTableSelector($financialitems, $sEcho, $iTotal, $iFilteredTotal, $selectorElements);
     CRM_Utils_System::civiExit();
   }
index 6844ef559ecdd0c83d0dde238e8fe1085eaa8c45..aca4ddc1333b8bd4dddeb1d9bf63e71e448f58d0 100644 (file)
@@ -112,7 +112,7 @@ class CRM_Group_Page_AJAX {
       if (!empty($params['is_unit_test'])) {
         return array($groups, $iFilteredTotal);
       }
-      header('Content-Type: application/json');
+      CRM_Utils_System::setHttpHeader('Content-Type', 'application/json');
       echo CRM_Utils_JSON::encodeDataTableSelector($groups, $sEcho, $iTotal, $iFilteredTotal, $selectorElements);
       CRM_Utils_System::civiExit();
     }
index b38946c9dfe66ae5d9867e1b1c09adafd58eda6a..2bed417cb922f85de163ef06fa749257311f1ec8 100644 (file)
@@ -144,6 +144,7 @@ class CRM_Mailing_Info extends CRM_Core_Component_Info {
     ));
     $fromAddress = civicrm_api3('OptionValue', 'get', $params + array(
       'option_group_id' => "from_email_address",
+      'domain_id' => CRM_Core_Config::domainID(),
     ));
     CRM_Core_Resources::singleton()
       ->addSetting(array(
index cc615381aff5555b552d91bd047233d52b7fc60f..7b96ff1cfd6878c59211b22cef05ccc5d208bf8b 100644 (file)
@@ -92,11 +92,11 @@ class CRM_Mailing_Page_Preview extends CRM_Core_Page {
     );
 
     if ($type == 'html') {
-      header('Content-Type: text/html; charset=utf-8');
+      CRM_Utils_System::setHttpHeader('Content-Type', 'text/html; charset=utf-8');
       print $mime->getHTMLBody();
     }
     else {
-      header('Content-Type: text/plain; charset=utf-8');
+      CRM_Utils_System::setHttpHeader('Content-Type', 'text/plain; charset=utf-8');
       print $mime->getTXTBody();
     }
     CRM_Utils_System::civiExit();
index f58e7dd9dff2348d4e266b069f0dccbb2337cc2b..f9650ed85991b11fd3779989f643091d9182e497 100644 (file)
@@ -1793,7 +1793,7 @@ class CRM_Member_Form_Membership extends CRM_Member_Form {
     CRM_Core_Session::setStatus($statusMsg, ts('Complete'), 'success');
     //CRM-15187
     // dusplay message when membership type is changed
-    if ($this->_id && !in_array($this->_memType, $this->_memTypeSelected)) {
+    if (($this->_action & CRM_Core_Action::UPDATE) && $this->_id && !in_array($this->_memType, $this->_memTypeSelected)) {
       CRM_Core_Session::setStatus(
         ts('The financial types associated with the old and new membership types are different. You may want to edit the contribution associated with this membership to adjust its financial type.'),
         ts('Warning')
index 8c03314d19fd4547b31a94079f3fcb1631d3be06..b4aec7d9345833c7a9df1b896c9f06e97a80c04f 100644 (file)
@@ -3142,7 +3142,7 @@ WHERE cg.extends IN ('" . implode("','", $this->_customGroupExtends) . "') AND
           //Load the image
           $chart = imagecreatefrompng($uploadUrl);
           //convert it into formatted png
-          header('Content-type: image/png');
+          CRM_Utils_System::setHttpHeader('Content-type', 'image/png');
           //overwrite with same image
           imagepng($chart, $uploadImg);
           //delete the object
index d53ba5841d3f1fea058d057156ce18b8b9ce6c35..52e3e3f38ae65fdc32eba65cd72489c0d95fcab3 100644 (file)
@@ -146,7 +146,7 @@ class CRM_Report_Form_Mailing_Summary extends CRM_Report_Form {
       'dao' => 'CRM_Mailing_DAO_Mailing',
       'fields' => array(
         'delivered_count' => array(
-          'name' => 'id',
+          'name' => 'event_queue_id',
           'title' => ts('Delivered'),
         ),
         'accepted_rate' => array(
@@ -164,7 +164,7 @@ class CRM_Report_Form_Mailing_Summary extends CRM_Report_Form {
       'dao' => 'CRM_Mailing_DAO_Mailing',
       'fields' => array(
         'bounce_count' => array(
-          'name' => 'id',
+          'name' => 'event_queue_id',
           'title' => ts('Bounce'),
         ),
         'bounce_rate' => array(
@@ -182,7 +182,7 @@ class CRM_Report_Form_Mailing_Summary extends CRM_Report_Form {
       'dao' => 'CRM_Mailing_DAO_Mailing',
       'fields' => array(
         'open_count' => array(
-          'name' => 'id',
+          'name' => 'event_queue_id',
           'title' => ts('Opened'),
         ),
         'open_rate' => array(
@@ -200,7 +200,7 @@ class CRM_Report_Form_Mailing_Summary extends CRM_Report_Form {
       'dao' => 'CRM_Mailing_DAO_Mailing',
       'fields' => array(
         'click_count' => array(
-          'name' => 'id',
+          'name' => 'event_queue_id',
           'title' => ts('Clicks'),
         ),
         'CTR' => array(
index ca511b13b05cd03a1c96a5715a7755d6f271ab5a..74ce2c21c7ba46b655703fc65f8bfd78a69ed08e 100644 (file)
@@ -223,11 +223,11 @@ WHERE  inst.report_id = %1";
    */
   public static function export2csv(&$form, &$rows) {
     //Mark as a CSV file.
-    header('Content-Type: text/csv');
+    CRM_Utils_System::setHttpHeader('Content-Type', 'text/csv');
 
     //Force a download and name the file using the current timestamp.
     $datetime = date('Ymd-Gi', $_SERVER['REQUEST_TIME']);
-    header('Content-Disposition: attachment; filename=Report_' . $datetime . '.csv');
+    CRM_Utils_System::setHttpHeader('Content-Disposition', 'attachment; filename=Report_' . $datetime . '.csv');
     echo self::makeCsv($form, $rows);
     CRM_Utils_System::civiExit();
   }
index ca7ccf6efc183d0a8b884e8f3d60ce08d38ca1cc..c2ccfde1bd91de58d77cd7f6f4fc337a9a902e4a 100644 (file)
@@ -177,4 +177,21 @@ class CRM_Upgrade_Incremental_php_FourSix extends CRM_Upgrade_Incremental_Base {
     return TRUE;
   }
 
+  /**
+   * Queue Task Callback for CRM-16846
+   *
+   * Run a sql file without resetting locale to that version
+   */
+  public static function task_4_6_x_runOnlySql(CRM_Queue_TaskContext $ctx, $rev) {
+    $upgrade = new CRM_Upgrade_Form();
+    $smarty = CRM_Core_Smarty::singleton();
+    $smarty->assign('domainID', CRM_Core_Config::domainID());
+
+    $fileName = "CRM/Upgrade/Incremental/sql/$rev.mysql.tpl";
+
+    $upgrade->source($smarty->fetch($fileName), TRUE);
+
+    return TRUE;
+  }
+
 }
diff --git a/CRM/Upgrade/Incremental/sql/4.6.7.mysql.tpl b/CRM/Upgrade/Incremental/sql/4.6.7.mysql.tpl
new file mode 100644 (file)
index 0000000..3371bfa
--- /dev/null
@@ -0,0 +1 @@
+{* file to handle db changes in 4.6.7 during upgrade *}
index 162d408516657d435f98fbf54f4f59f1adf900ed..af863ab62f9577dfdc075fc3934ac9f58c2b0c2a 100644 (file)
@@ -80,6 +80,7 @@ class CRM_Utils_API_ReloadOption implements API_Wrapper {
       if (!CRM_Utils_Array::value('is_error', $result, FALSE)) {
         $reloadMode = $apiRequest['params']['options']['reload'];
       }
+      $id = (!empty($apiRequest['params']['sequential'])) ? 0 : $result['id'];
     }
 
     switch ($reloadMode) {
@@ -98,16 +99,16 @@ class CRM_Utils_API_ReloadOption implements API_Wrapper {
         if ($reloadResult['is_error']) {
           throw new API_Exception($reloadResult['error_message']);
         }
-        $result['values'][$result['id']] = array_merge($result['values'][$result['id']], $reloadResult['values'][$result['id']]);
+        $result['values'][$id] = array_merge($result['values'][$id], $reloadResult['values'][$result['id']]);
         return $result;
 
       case 'selected':
         $params = array(
-          'id' => $result['id'],
+          'id' => $id,
           'return' => $this->pickReturnFields($apiRequest),
         );
         $reloadResult = civicrm_api3($apiRequest['entity'], 'get', $params);
-        $result['values'][$result['id']] = array_merge($result['values'][$result['id']], $reloadResult['values'][$result['id']]);
+        $result['values'][$id] = array_merge($result['values'][$id], $reloadResult['values'][$id]);
         return $result;
 
       default:
index 096ce70f7613bd45f648d32909ac526ec68b3af8..0f460658fd498a88c0b032d8e82232941f0f1a7a 100644 (file)
@@ -109,16 +109,15 @@ class CRM_Utils_ICalendar {
   public static function send($calendar, $content_type = 'text/calendar', $charset = 'us-ascii', $fileName = NULL, $disposition = NULL) {
     $config = CRM_Core_Config::singleton();
     $lang = $config->lcMessages;
-    header("Content-Language: $lang");
-    // header( "Content-Type: $content_type; charset=$charset; profile=\"ICalendar\"" );
-    header("Content-Type: $content_type; charset=$charset");
+    CRM_Utils_System::setHttpHeader("Content-Language", $lang);
+    CRM_Utils_System::setHttpHeader("Content-Type", "$content_type; charset=$charset");
 
     if ($content_type == 'text/calendar') {
-      header('Content-Length: ' . strlen($calendar));
-      header("Content-Disposition: $disposition; filename=\"$fileName\"");
-      header("Pragma: no-cache");
-      header("Expires: 0");
-      header("Cache-Control: no-cache, must-revalidate");
+      CRM_Utils_System::setHttpHeader('Content-Length', strlen($calendar));
+      CRM_Utils_System::setHttpHeader("Content-Disposition", "$disposition; filename=\"$fileName\"");
+      CRM_Utils_System::setHttpHeader("Pragma", "no-cache");
+      CRM_Utils_System::setHttpHeader("Expires", "0");
+      CRM_Utils_System::setHttpHeader("Cache-Control", "no-cache, must-revalidate");
     }
 
     echo $calendar;
index f210f1dfa6fcfc68fdd8dd9eed98b0f118f5c0a7..01e0b60bbf32f4fd108d0ad2a2611aad7c50c037 100644 (file)
@@ -43,7 +43,7 @@ class CRM_Utils_JSON {
    * @param mixed $input
    */
   public static function output($input) {
-    header('Content-Type: application/json');
+    CRM_Utils_System::setHttpHeader('Content-Type', 'application/json');
     echo json_encode($input);
     CRM_Utils_System::civiExit();
   }
index f2c9bd85588899f41ae18255cca136052f400bbd..62d592e5c2557b894715439b1aa13479e81d633c 100644 (file)
@@ -233,8 +233,8 @@ class CRM_Utils_PDF_Utils {
       return $pdf;
     }
     else {
-      header('Content-Type: application/pdf');
-      header('Content-Disposition: attachment; filename="' . $fileName . '"');
+      CRM_Utils_System::setHttpHeader('Content-Type', 'application/pdf');
+      CRM_Utils_System::setHttpHeader('Content-Disposition', 'attachment; filename="' . $fileName . '"');
       echo $pdf;
     }
   }
@@ -400,9 +400,9 @@ class CRM_Utils_PDF_Utils {
       $len = strlen($buf);
 
       if ($echo) {
-        header('Content-type: application/pdf');
-        header("Content-Length: $len");
-        header("Content-Disposition: inline; filename={$output}.pdf");
+        CRM_Utils_System::setHttpHeader('Content-type', 'application/pdf');
+        CRM_Utils_System::setHttpHeader("Content-Length", $len);
+        CRM_Utils_System::setHttpHeader("Content-Disposition", "inline; filename={$output}.pdf");
         echo $buf;
         CRM_Utils_System::civiExit();
       }
index 4bac9b7db502bf026e45019df4d33707e34e9bde..f00f96a3afb22869c0b938e54b84cf92f210955a 100644 (file)
@@ -145,11 +145,11 @@ class CRM_Utils_REST {
     }
 
     if (!empty($requestParams['json'])) {
-      header('Content-Type: application/json');
       if (!empty($requestParams['prettyprint'])) {
-        // Used by the api explorer
+        // Don't set content-type header for api explorer output
         return self::jsonFormated(array_merge($result));
       }
+      CRM_Utils_System::setHttpHeader('Content-Type', 'application/json');
       return json_encode(array_merge($result));
     }
 
@@ -451,7 +451,7 @@ class CRM_Utils_REST {
    * @param $pearError
    */
   public static function fatal($pearError) {
-    header('Content-Type: text/xml');
+    CRM_Utils_System::setHttpHeader('Content-Type', 'text/xml');
     $error = array();
     $error['code'] = $pearError->getCode();
     $error['error_message'] = $pearError->getMessage();
@@ -484,7 +484,7 @@ class CRM_Utils_REST {
     $smarty = CRM_Core_Smarty::singleton();
     CRM_Utils_System::setTitle("$entity::$tplfile inline $tpl");
     if (!$smarty->template_exists($tpl)) {
-      header("Status: 404 Not Found");
+      CRM_Utils_System::setHttpHeader("Status", "404 Not Found");
       die ("Can't find the requested template file templates/$tpl");
     }
     if (array_key_exists('id', $_GET)) {// special treatmenent, because it's often used
index a9d1e3a901a7ce5bd1f2c2551b916c4efb3dab6c..3ea64b468137955b270e9b497aad68153f135b4a 100644 (file)
@@ -410,7 +410,7 @@ class CRM_Utils_System {
       ));
     }
 
-    header('Location: ' . $url);
+    self::setHttpHeader('Location', $url);
     self::civiExit();
   }
 
@@ -813,8 +813,8 @@ class CRM_Utils_System {
   ) {
     $now = gmdate('D, d M Y H:i:s') . ' GMT';
 
-    header('Content-Type: ' . $mimeType);
-    header('Expires: ' . $now);
+    self::setHttpHeader('Content-Type', $mimeType);
+    self::setHttpHeader('Expires', $now);
 
     // lem9 & loic1: IE need specific headers
     $isIE = strstr($_SERVER['HTTP_USER_AGENT'], 'MSIE');
@@ -825,13 +825,13 @@ class CRM_Utils_System {
       $fileString = "filename=\"{$name}\"";
     }
     if ($isIE) {
-      header("Content-Disposition: inline; $fileString");
-      header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
-      header('Pragma: public');
+      self::setHttpHeader("Content-Disposition", "inline; $fileString");
+      self::setHttpHeader('Cache-Control', 'must-revalidate, post-check=0, pre-check=0');
+      self::setHttpHeader('Pragma', 'public');
     }
     else {
-      header("Content-Disposition: $disposition; $fileString");
-      header('Pragma: no-cache');
+      self::setHttpHeader("Content-Disposition", "$disposition; $fileString");
+      self::setHttpHeader('Pragma', 'no-cache');
     }
 
     if ($output) {
@@ -1880,4 +1880,12 @@ class CRM_Utils_System {
     return NULL;
   }
 
+  /**
+   * @param string $name
+   * @param string $value
+   */
+  public static function setHttpHeader($name, $value) {
+    CRM_Core_Config::singleton()->userSystem->setHttpHeader($name, $value);
+  }
+
 }
index 866aeeafed11b172cbb36a1179a544dc58fab961..dec96a5dbc370fc491f804b64879a2628fa5aea2 100644 (file)
@@ -740,4 +740,12 @@ abstract class CRM_Utils_System_Base {
   public function appendCoreResources(&$list) {
   }
 
+  /**
+   * @param string $name
+   * @param string $value
+   */
+  public function setHttpHeader($name, $value) {
+    header("$name: $value");
+  }
+
 }
index 105bab57df2488e3d751303d3f51cec22e66e1b4..c3f3921f945bfa6c08dd823b4db6ff9545f172e7 100644 (file)
@@ -773,4 +773,11 @@ AND    u.status = 1
     return $timezone;
   }
 
+  /**
+   * @inheritDoc
+   */
+  public function setHttpHeader($name, $value) {
+    drupal_add_http_header($name, $value);
+  }
+
 }
index 5d52afc3124aaf43432f5843eb2abc54c569c877..cd354b9357a9f85418faf632cd22bdbf8c93cd87 100644 (file)
@@ -741,4 +741,11 @@ class CRM_Utils_System_Drupal6 extends CRM_Utils_System_DrupalBase {
     return $timezone;
   }
 
+  /**
+   * @inheritDoc
+   */
+  public function setHttpHeader($name, $value) {
+    drupal_set_header("$name: $value");
+  }
+
 }
index 7de4b715090be3d1352c345c37cb8eefa1f998e6..e824e5d31e1093a1fe36934ef41a3d5ce6164cd1 100644 (file)
@@ -551,4 +551,11 @@ class CRM_Utils_System_Drupal8 extends CRM_Utils_System_DrupalBase {
       $cache_backend->deleteAll();
     }
   }
+
+  /**
+   * @inheritDoc
+   */
+  public function setHttpHeader($name, $value) {
+    \Symfony\Component\HttpFoundation\Response->headers->set($name, $value);
+  }
 }
index a8431f47b948a38c7b98f5bdc7f19fa27883317b..daa5c84964f5e1845f557d28806f45e8f9d1f14c 100644 (file)
@@ -456,7 +456,7 @@ class CRM_Utils_System_Joomla extends CRM_Utils_System_Base {
    */
   public function logout() {
     session_destroy();
-    header("Location:index.php");
+    CRM_Utils_System::setHttpHeader("Location", "index.php");
   }
 
   /**
index f2014b027f971beb65634ec53efee7ec597a1059..e24468a094396a9ac8c124ff1d453a67dccba9f7 100644 (file)
@@ -162,7 +162,7 @@ class CRM_Utils_System_UnitTests extends CRM_Utils_System_Base {
    */
   public function logout() {
     session_destroy();
-    header("Location:index.php");
+    CRM_Utils_System::setHttpHeader("Location", "index.php");
   }
 
   /**
index 4e66cce043cec6415a2d8e6f57a0bf0a14603de4..074753bd205ab004e0ca562980f8bbba028d14fc 100644 (file)
@@ -183,7 +183,7 @@ class ChainSubscriber implements EventSubscriberInterface {
             foreach ($newparams as $entityparams) {
               $subParams = array_merge($genericParams, $entityparams);
               _civicrm_api_replace_variables($subParams, $result['values'][$idIndex], $separator);
-              $result['values'][$result['id']][$field][] = $apiKernel->run($subEntity, $subaction, $subParams);
+              $result['values'][$idIndex][$field][] = $apiKernel->run($subEntity, $subaction, $subParams);
               if ($result['is_error'] === 1) {
                 throw new \Exception($subEntity . ' ' . $subaction . 'call failed with' . $result['error_message']);
               }
index 4f53c542fc0324b54e6361ee65a70ba28f963cc5..8b55d97347e26335c6a7e5a35d93db3ac4556a8d 100644 (file)
@@ -158,6 +158,10 @@ function _civicrm_api_replace_variables(&$params, &$parentResult, $separator = '
           $count = count($stringParts);
         }
       }
+      // CRM-16168 If we have failed to swap it out we should unset it rather than leave the placeholder.
+      if (substr($params[$field], 0, 6) == '$value') {
+        $params[$field] = NULL;
+      }
     }
   }
 }
index 4728270b45361f3c8dcc16dd2cae943839d67647..b6c24ff5ee156c96a4550261b204f06983c6ab6a 100644 (file)
  *   API result Array.
  */
 function civicrm_api3_event_create($params) {
-  civicrm_api3_verify_one_mandatory($params, NULL, array('event_type_id', 'template_id'));
+  // Required fields for creating an event
+  if (empty($params['id']) && empty($params['is_template'])) {
+    civicrm_api3_verify_mandatory($params, NULL, array(
+      'start_date',
+      'title',
+      array('event_type_id', 'template_id'),
+    ));
+  }
+  // Required fields for creating an event template
+  elseif (empty($params['id']) && !empty($params['is_template'])) {
+    civicrm_api3_verify_mandatory($params, NULL, array(
+      'template_title',
+    ));
+  }
 
   // Clone event from template
   if (!empty($params['template_id']) && empty($params['id'])) {
@@ -64,8 +77,6 @@ function civicrm_api3_event_create($params) {
  *   Array of parameters determined by getfields.
  */
 function _civicrm_api3_event_create_spec(&$params) {
-  $params['start_date']['api.required'] = 1;
-  $params['title']['api.required'] = 1;
   $params['is_active']['api.default'] = 1;
   $params['financial_type_id']['api.aliases'] = array('contribution_type_id');
   $params['is_template']['api.default'] = 0;
index 46c97b86d82c2313b3f8f8dcdf2f86988f5767b4..8250138f87f18c79568e222b1cc9179d21ed80db 100755 (executable)
@@ -591,6 +591,7 @@ function civicrm_api3_mailing_send_test($params) {
         ->where('c.is_opt_out = 0')
         ->where('c.do_not_email = 0')
         ->where('c.is_deceased = 0')
+        ->where('c.is_deleted = 0')
         ->groupBy('e.id')
         ->orderBy(array('e.is_bulkmail DESC', 'e.is_primary DESC'))
         ->toSQL();
index 35a7701c7b1222d1c0c05136503f0c34bb507567..1c8499dc466af7cc38a7bf651254ec3e96256c02 100644 (file)
    * Note: We have to manually execute the ajax in order to add the secret extra "prettyprint" param
    */
   function execute() {
+    var footer;
     $('#api-result').html('<div class="crm-loading-element"></div>');
     $.ajax({
       url: CRM.url('civicrm/ajax/rest'),
       type: _.includes(action, 'get') ? 'GET' : 'POST',
       dataType: 'text'
     }).done(function(text) {
+      // There may be debug information appended to the end of the json string
+      var footerPos = text.indexOf("\n}<");
+      if (footerPos) {
+        footer = text.substr(footerPos + 2);
+        text = text.substr(0, footerPos + 2);
+      }
       $('#api-result').text(text);
       prettyPrint('#api-result');
+      if (footer) {
+        $('#api-result').append(footer);
+      }
     });
   }
 
index 6cd6b78bb5f516742660a2f9e34715ed8d6e3b05..58167d6a07affd38594f94198a968ac180804033 100644 (file)
 *}
 {* template for custom data *}
 {assign var="customDataGroupName" value=$customDataGroup.name}
+{strip}
+  {if $displayStyle neq 'tableOriented' and ($action eq 16 or $action eq 4)} {* Browse or View actions *}
+    <div class="form-item">
+      {include file="CRM/Custom/Page/CustomDataView.tpl"}
+    </div>
+  {/if}
+{/strip}
 {foreach from=$viewCustomData item=customGroupWrapper}
   {foreach from=$customGroupWrapper item=customGroup key=customGroupId}
     {assign var="customRegion" value='contact-custom-data-'|cat:$customGroup.name}
           </script>
         {/literal}
       {else}
-        {strip}
-          {if $action eq 16 or $action eq 4} {* Browse or View actions *}
-            <div class="form-item">
-              {include file="CRM/Custom/Page/CustomDataView.tpl"}
-            </div>
-          {/if}
-        {/strip}
-
         {if $mainEditForm}
           <script type="text/javascript">
             var showBlocks1 = new Array({$showBlocks1});
index e83e4b17164e5d7078072b5a626a04a9cd033a5b..45d0b5ef2f3a0df4dcc512930b3a22470e6f5316 100644 (file)
@@ -87,6 +87,29 @@ class CRM_Utils_API_ReloadOptionTest extends CiviUnitTestCase {
     $this->assertAPISuccess($result['values'][$result['id']]['api.Email.create']);
   }
 
+  /**
+   * When the reload option is combined with chaining, the reload should munge
+   * the chain results, even if sequential=1.
+   */
+  public function testReloadNoChainInterferenceSequential() {
+    $result = $this->callAPISuccess('contact', 'create', array(
+      'sequential' => 1,
+      'contact_type' => 'Individual',
+      'first_name' => 'First',
+      'last_name' => 'Last',
+      'nick_name' => 'Firstie',
+      'api.Email.create' => array(
+        'email' => 'test@example.com',
+      ),
+      'options' => array(
+        'reload' => 1,
+      ),
+    ));
+    $this->assertEquals('First', $result['values'][0]['first_name']);
+    $this->assertEquals('munged', $result['values'][0]['nick_name']);
+    $this->assertAPISuccess($result['values'][0]['api.Email.create']);
+  }
+
   /**
    * An implementation of hook_civicrm_post used with all our test cases.
    *
diff --git a/tests/phpunit/WebTest/Utils/RedirectTest.php b/tests/phpunit/WebTest/Utils/RedirectTest.php
new file mode 100644 (file)
index 0000000..39d3829
--- /dev/null
@@ -0,0 +1,135 @@
+<?php
+/*
+ +--------------------------------------------------------------------+
+ | CiviCRM version 4.6                                                |
+ +--------------------------------------------------------------------+
+ | Copyright CiviCRM LLC (c) 2004-2015                                |
+ +--------------------------------------------------------------------+
+ | 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 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        |
+ +--------------------------------------------------------------------+
+ */
+
+require_once 'CiviTest/CiviUnitTestCase.php';
+require_once 'CiviTest/CiviSeleniumSettings.php';
+
+/**
+ *  Include configuration
+ */
+define('CIVICRM_SETTINGS_PATH', __DIR__ . '/civicrm.settings.dist.php');
+define('CIVICRM_SETTINGS_LOCAL_PATH', __DIR__ . '/civicrm.settings.local.php');
+define('CIVICRM_WEBTEST', 1);
+
+if (file_exists(CIVICRM_SETTINGS_LOCAL_PATH)) {
+  require_once CIVICRM_SETTINGS_LOCAL_PATH;
+}
+require_once CIVICRM_SETTINGS_PATH;
+
+
+/**
+ * Check that we handle redirects appropriately.
+ */
+class WebTest_Utils_RedirectTest extends CiviUnitTestCase {
+  protected $url;
+  protected $ch;
+
+  /**
+   * @param string|null $name
+   */
+  public function __construct($name = NULL) {
+    parent::__construct($name);
+
+    $this->settings = new CiviSeleniumSettings();
+    if (property_exists($this->settings, 'serverStartupTimeOut') && $this->settings->serverStartupTimeOut) {
+      global $CiviSeleniumTestCase_polled;
+      if (!$CiviSeleniumTestCase_polled) {
+        $CiviSeleniumTestCase_polled = TRUE;
+        CRM_Utils_Network::waitForServiceStartup(
+          $this->drivers[0]->getHost(),
+          $this->drivers[0]->getPort(),
+          $this->settings->serverStartupTimeOut
+        );
+      }
+    }
+  }
+
+  protected function setUp() {
+    parent::setUp();
+    //URL should eventually be adapted for multisite
+    $this->url = $this->settings->sandboxURL;
+
+    $this->ch = curl_init();
+    curl_setopt($this->ch, CURLOPT_HEADER, FALSE);
+    curl_setopt($this->ch, CURLOPT_FOLLOWLOCATION, FALSE);
+    // curl_setopt($this->ch, CURLOPT_ENCODING, 'gzip');
+    // curl_setopt($this->ch, CURLOPT_VERBOSE, 0);
+  }
+
+  /**
+   *
+   */
+  private function tryRedirect($input_url, $expected_url) {
+    // file_put_contents('php://stderr', $input_url . "\n", FILE_APPEND);
+    $url = $this->url . '/' . $input_url;
+    $expected_url = $this->url . '/' . $expected_url;
+    curl_setopt($this->ch, CURLOPT_URL, $url);
+    $req = curl_exec($this->ch);
+    $this->assertEquals(0, curl_errno($this->ch), 'cURL error: ' . curl_error($this->ch));
+    if (!curl_errno($this->ch)) {
+      $info = curl_getinfo($this->ch);
+      // file_put_contents('php://stderr', print_r($info,1), FILE_APPEND);
+      $this->assertEquals($expected_url, $info['redirect_url']);
+      $this->assertEquals('302', $info['http_code']);
+    }
+  }
+
+  /**
+   * Handle onsite redirects with absolute URL.
+   */
+  public function testAbsoluteOnsiteRedirect() {
+    $this->tryRedirect("civicrm/contribute/transact?qfKey=xxx&entryURL={$this->url}/civicrm/contribute/transact%3Fid%3D1", 'civicrm/contribute/transact?id=1');
+  }
+
+  /**
+   * Handle onsite redirects with slash prefix and query params.
+   */
+  public function testOnsiteRedirectWithSlashPrefixAndQueryParams() {
+    $this->tryRedirect('civicrm/contribute/transact?qfKey=xxx&entryURL=/civicrm/contribute/transact%3Fid%3D1', 'civicrm/contribute/transact?id=1');
+  }
+
+  /**
+   * Handle onsite redirects with non-CiviCRM paths.
+   */
+  public function testOtherpathRedirect() {
+    $this->tryRedirect('civicrm/contribute/transact?qfKey=xxx&entryURL=asdf', 'asdf');
+  }
+
+  /**
+   * Handle offsite redirects without path as onsite redirects.
+   */
+  public function testOffsiteRedirectNoPath() {
+    $this->tryRedirect('civicrm/contribute/transact?qfKey=xxx&entryURL=http://evil.example.com/', '');
+  }
+
+  /**
+   * Handle offsite redirects with paths as onsite redirects.
+   */
+  public function testOffsiteRedirectWithPath() {
+    $this->tryRedirect('civicrm/contribute/transact?qfKey=xxx&entryURL=http://evil.example.com/civicrm', 'civicrm');
+  }
+
+}
index 209d4ac6315ce1573538fc08c6a276a89bea4101..985c94153b305ef94169673cca7fad0e4fc997da 100644 (file)
@@ -1634,7 +1634,44 @@ class api_v3_ContactTest extends CiviUnitTestCase {
   }
 
   /**
-   * Verify attempt to create individual with chained arrays.
+   *  Verify attempt to create individual with chained arrays and sequential
+   */
+  public function testGetIndividualWithChainedArraysAndSequential() {
+    $ids = $this->entityCustomGroupWithSingleFieldCreate(__FUNCTION__, __FILE__);
+    $params['custom_' . $ids['custom_field_id']] = "custom string";
+
+    $moreids = $this->CustomGroupMultipleCreateWithFields();
+    $description = "/*this demonstrates the usage of chained api functions. In this case no notes or custom fields have been created ";
+    $subfile = "APIChainedArray";
+    $params = array(
+      'sequential' => 1,
+      'first_name' => 'abc3',
+      'last_name' => 'xyz3',
+      'contact_type' => 'Individual',
+      'email' => 'man3@yahoo.com',
+      'api.website.create' => array(
+        array(
+          'url' => "http://civicrm.org",
+        ),
+        array(
+          'url' => "https://civicrm.org",
+        ),
+      ),
+    );
+
+    $result = $this->callAPISuccess('Contact', 'create', $params);
+
+    // delete the contact and custom groups
+    $this->callAPISuccess('contact', 'delete', array('id' => $result['id']));
+    $this->customGroupDelete($ids['custom_group_id']);
+    $this->customGroupDelete($moreids['custom_group_id']);
+
+    $this->assertEquals($result['id'], $result['values'][0]['id']);
+    $this->assertArrayKeyExists('api.website.create', $result['values'][0]);
+  }
+
+  /**
+   *  Verify attempt to create individual with chained arrays
    */
   public function testGetIndividualWithChainedArrays() {
     $ids = $this->entityCustomGroupWithSingleFieldCreate(__FUNCTION__, __FILE__);
@@ -1701,6 +1738,47 @@ class api_v3_ContactTest extends CiviUnitTestCase {
     $this->assertEquals("http://civicrm.org", $result['values'][$result['id']]['api.website.get']['values'][0]['url']);
   }
 
+  /**
+   *  Verify attempt to create individual with chained arrays and sequential.
+   *
+   *  See https://issues.civicrm.org/jira/browse/CRM-15815
+   */
+  public function testCreateIndividualWithChainedArrayAndSequential() {
+    $params = array(
+      'sequential' => 1,
+      'first_name' => 'abc5',
+      'last_name' => 'xyz5',
+      'contact_type' => 'Individual',
+      'email' => 'woman5@yahoo.com',
+      'api.phone.create' => array(
+        array('phone' => '03-231 07 95'),
+        array('phone' => '03-232 51 62'),
+      ),
+      'api.website.create' => array(
+        'url' => 'http://civicrm.org',
+      ),
+    );
+    $result = $this->callAPISuccess('Contact', 'create', $params);
+
+    // I could try to parse the result to see whether the two phone numbers
+    // and the website are there, but I am not sure about the correct format.
+    // So I will just fetch it again before checking.
+    // See also http://forum.civicrm.org/index.php/topic,35393.0.html
+    $params = array(
+      'sequential' => 1,
+      'id' => $result['id'],
+      'api.website.get' => array(),
+      'api.phone.get' => array(),
+    );
+    $result = $this->callAPISuccess('Contact', 'get', $params);
+
+    // delete the contact
+    $this->callAPISuccess('contact', 'delete', $result);
+
+    $this->assertEquals(2, $result['values'][0]['api.phone.get']['count']);
+    $this->assertEquals(1, $result['values'][0]['api.website.get']['count']);
+  }
+
   public function testGetIndividualWithChainedArraysFormats() {
     $description = "This demonstrates the usage of chained api functions.\nIn this case no notes or custom fields have been created.";
     $subfile = "APIChainedArrayFormats";
index b672d56c3479f8eead4568e063402b0e1dc51fc6..2627e9c1bb60775d159f8b80f0fde63ddb2aba5d 100644 (file)
@@ -280,6 +280,65 @@ class api_v3_EventTest extends CiviUnitTestCase {
     $this->callAPISuccess('event', 'delete', array('id' => $result['id']));
   }
 
+  /**
+   * Chaining get event and loc block.
+   */
+  public function testChainingGetLocBlock() {
+    // create a loc block and an event for that loc block.
+    $eventParams = $this->_params[0];
+    $eventParams['loc_bloc_id'] = '$value.id';
+    $locBlockParams = array(
+      'address' => array(
+        'street_address' => 'Kipdorp 24',
+        'postal_code' => '2000',
+        'city' => 'Antwerpen',
+        'country_id' => '1020',
+        'location_type_id' => '1',
+      ),
+      'api.Event.create' => $eventParams,
+      'sequential' => 1,
+    );
+    $createResult = $this->callAPIAndDocument('LocBlock', 'create', $locBlockParams, __FUNCTION__, __FILE__);
+    $locBlockId = $createResult['id'];
+    $addressId = $createResult['values'][0]['address_id'];
+    $eventId = $createResult['values'][0]['api.Event.create']['id'];
+
+    // request the event with its loc block:
+    $check = $this->callAPISuccess($this->_entity, 'getsingle', array(
+      'id' => $eventId,
+      'api.LocBlock.get' => array('id' => '$value.loc_block_id'),
+      'sequential' => 1,
+    ));
+
+    // assert
+    $this->assertEquals($eventId, $check['id'], ' in line ' . __LINE__);
+    $this->assertEquals(1, $check['api.LocBlock.get']['count'], ' in line ' . __LINE__);
+    $this->assertEquals($locBlockId, $check['api.LocBlock.get']['id'], ' in line ' . __LINE__);
+
+    // cleanup
+    $this->callAPISuccess($this->_entity, 'delete', array('id' => $eventId));
+  }
+
+  /**
+   * Chaining get event and non existing loc block.
+   *
+   * Even if there is no loc block, at least the event should be returned.
+   * http://forum.civicrm.org/index.php/topic,36113.0.html
+   */
+  public function testChainingGetNonExistingLocBlock() {
+    $params = $this->_params[0];
+    $result = $this->callAPISuccess($this->_entity, 'create', $params);
+
+    $check = $this->callAPISuccess($this->_entity, 'get', array(
+      'id' => $result['id'],
+      // this chaining request should not break things:
+      'api.LocBlock.get' => array('id' => '$value.loc_block_id'),
+      ));
+    $this->assertEquals($result['id'], $check['id']);
+
+    $this->callAPISuccess($this->_entity, 'Delete', array('id' => $result['id']));
+  }
+
   /**
    * Check with complete array + custom field.
    *
@@ -532,7 +591,7 @@ class api_v3_EventTest extends CiviUnitTestCase {
     $description = "Demonstrate use of getfields to interrogate api.";
     $params = array('action' => 'create');
     $result = $this->callAPISuccess('event', 'getfields', $params);
-    $this->assertEquals(1, $result['values']['title']['api.required']);
+    $this->assertEquals(1, $result['values']['is_active']['api.default']);
   }
 
   /**
@@ -542,7 +601,7 @@ class api_v3_EventTest extends CiviUnitTestCase {
     $description = "Demonstrate use of getfields to interrogate api.";
     $params = array('api_action' => 'create');
     $result = $this->callAPISuccess('event', 'getfields', $params);
-    $this->assertEquals(1, $result['values']['title']['api.required']);
+    $this->assertEquals(1, $result['values']['is_active']['api.default']);
   }
 
   public function testgetfieldsGet() {
@@ -559,4 +618,29 @@ class api_v3_EventTest extends CiviUnitTestCase {
     $this->assertEquals(1, $result['values']['id']['api.required']);
   }
 
+  public function testCreateFromTemplate() {
+    $templateParams = array(
+      'summary' => 'Sign up now to learn the results of this unit test',
+      'description' => 'This event is created from a template, so all the values should be the same as the original ones.',
+      'event_type_id' => 1,
+      'is_public' => 1,
+      'end_date' => '2018-06-25 17:00:00',
+      'is_online_registration' => 1,
+      'registration_start_date' => '2017-06-25 17:00:00',
+      'registration_end_date' => '2018-06-25 17:00:00',
+      'max_participants' => 100,
+      'event_full_text' => 'Sorry! We are already full',
+    );
+    $templateResult = $this->callAPISuccess('Event', 'create', array('is_template' => 1, 'template_title' => 'Test tpl') + $templateParams);
+    $eventResult = $this->callAPISuccess('Event', 'create', array(
+      'template_id' => $templateResult['id'],
+      'title' => 'Clone1',
+      'start_date' => '2018-06-25 16:00:00',
+    ));
+    $eventResult = $this->callAPISuccess('Event', 'getsingle', array('id' => $eventResult['id']));
+    foreach ($templateParams as $param => $value) {
+      $this->assertEquals($value, $eventResult[$param]);
+    }
+  }
+
 }