Attempt to fix paging on contact summary
[civicrm-core.git] / CRM / Report / Form.php
index 8ee80e9800c7d961040c90f4e40b6f4525ef9134..783026daa2737ae87d450d72d459a8ab3b56bc53 100644 (file)
@@ -2129,12 +2129,30 @@ class CRM_Report_Form extends CRM_Core_Form {
    * @return string
    */
   public function whereSubtypeClause($field, $value, $op) {
+    // Get the correct SQL operator.
+    switch ($op) {
+      case 'notin':
+        $op = 'nhas';
+        $clauseSeparator = 'AND';
+        break;
+
+      case 'in':
+        $op = 'has';
+        $clauseSeparator = 'OR';
+        break;
+    }
+    $sqlOp = $this->getSQLOperator($op);
     $clause = '( ';
     $subtypeFilters = count($value);
-    for ($i = 0; $i < $subtypeFilters; $i++) {
-      $clause .= "{$field['dbAlias']} LIKE '%$value[$i]%'";
-      if ($i !== ($subtypeFilters - 1)) {
-        $clause .= " OR ";
+    if ($sqlOp == 'IS NULL' || $sqlOp == 'IS NOT NULL') {
+      $clause .= "{$field['dbAlias']} $sqlOp";
+    }
+    else {
+      for ($i = 0; $i < $subtypeFilters; $i++) {
+        $clause .= "{$field['dbAlias']} $sqlOp '%$value[$i]%'";
+        if ($i !== ($subtypeFilters - 1)) {
+          $clause .= " $clauseSeparator ";
+        }
       }
     }
     $clause .= ' )';
@@ -2394,12 +2412,6 @@ WHERE cg.extends IN ('" . implode("','", $this->_customGroupExtends) . "') AND
       }
     }
 
-    // build array of section totals
-    $this->sectionTotals();
-
-    // process grand-total row
-    $this->grandTotal($rows);
-
     // Find alter display functions.
     $firstRow = reset($rows);
     if ($firstRow) {
@@ -2440,6 +2452,12 @@ WHERE cg.extends IN ('" . implode("','", $this->_customGroupExtends) . "') AND
     $this->alterDisplay($rows);
     CRM_Utils_Hook::alterReportVar('rows', $rows, $this);
 
+    // build array of section totals
+    $this->sectionTotals();
+
+    // process grand-total row
+    $this->grandTotal($rows);
+
     // use this method for formatting custom rows for display purpose.
     $this->alterCustomDataDisplay($rows);
   }
@@ -3358,7 +3376,7 @@ WHERE cg.extends IN ('" . implode("','", $this->_customGroupExtends) . "') AND
             if ($value && empty($field['no_display'])) {
               $statistics['filters'][] = [
                 'title' => CRM_Utils_Array::value('title', $field),
-                'value' => $value,
+                'value' => CRM_Utils_String::htmlToText($value),
               ];
             }
           }
@@ -3447,28 +3465,18 @@ WHERE cg.extends IN ('" . implode("','", $this->_customGroupExtends) . "') AND
         echo $content;
       }
       else {
-        if ($chartType = CRM_Utils_Array::value('charts', $this->_params)) {
-          $config = CRM_Core_Config::singleton();
-          //get chart image name
-          $chartImg = $this->_chartId . '.png';
-          //get image url path
-          $uploadUrl
-            = str_replace('/persist/contribute/', '/persist/', $config->imageUploadURL) .
-            'openFlashChart/';
-          $uploadUrl .= $chartImg;
-          //get image doc path to overwrite
-          $uploadImg
-            = str_replace('/persist/contribute/', '/persist/', $config->imageUploadDir) .
-            'openFlashChart/' . $chartImg;
-          //Load the image
-          $chart = imagecreatefrompng($uploadUrl);
-          //convert it into formatted png
-          CRM_Utils_System::setHttpHeader('Content-type', 'image/png');
-          //overwrite with same image
-          imagepng($chart, $uploadImg);
-          //delete the object
-          imagedestroy($chart);
-        }
+        // Nb. Once upon a time we used a package called Open Flash Charts to
+        // draw charts, and we had a feature whereby a browser could send the
+        // server a PNG version of the chart, which could then be included in a
+        // PDF by including <img> tags in the HTML for the conversion below.
+        //
+        // This feature stopped working when browsers stopped supporting Flash,
+        // and although we have a different client-side charting library in
+        // place, we decided not to reimplement the (rather convoluted)
+        // browser-sending-rendered-chart-to-server process.
+        //
+        // If this feature is required in future we should find a better way to
+        // render charts on the server side, e.g. server-created SVG.
         CRM_Utils_PDF_Utils::html2pdf($content, "CiviReport.pdf", FALSE, ['orientation' => 'landscape']);
       }
       CRM_Utils_System::civiExit();
@@ -4693,6 +4701,8 @@ LEFT JOIN civicrm_contact {$field['alias']} ON {$field['alias']}.id = {$this->_a
    *      Not currently used in core but may be used in override extensions.
    */
   protected function joinAddressFromContact($prefix = '', $extra = []) {
+    $defaults = ['primary_only' => TRUE];
+    $params = array_merge($defaults, $extra);
     $addressTables = ['civicrm_address', 'civicrm_country', 'civicrm_worldregion', 'civicrm_state_province'];
     $isJoinRequired = $this->_addressField;
     foreach ($addressTables as $addressTable) {
@@ -4701,11 +4711,15 @@ LEFT JOIN civicrm_contact {$field['alias']} ON {$field['alias']}.id = {$this->_a
       }
     }
     if ($isJoinRequired) {
-      $this->_from .= "
+      $fromJoin = "
                  LEFT JOIN civicrm_address {$this->_aliases[$prefix . 'civicrm_address']}
                            ON ({$this->_aliases[$prefix . 'civicrm_contact']}.id =
-                               {$this->_aliases[$prefix . 'civicrm_address']}.contact_id) AND
+                               {$this->_aliases[$prefix . 'civicrm_address']}.contact_id)";
+      if ($params['primary_only']) {
+        $fromJoin .= "  AND
                                {$this->_aliases[$prefix . 'civicrm_address']}.is_primary = 1\n";
+      }
+      $this->_from .= $fromJoin;
     }
   }
 
@@ -4720,15 +4734,21 @@ LEFT JOIN civicrm_contact {$field['alias']} ON {$field['alias']}.id = {$this->_a
    *      Not currently used in core but may be used in override extensions.
    */
   protected function joinCountryFromAddress($prefix = '', $extra = []) {
+    $defaults = ['primary_only' => TRUE];
+    $params = array_merge($defaults, $extra);
     // include country field if country column is to be included
     if ($this->isTableSelected($prefix . 'civicrm_country') || $this->isTableSelected($prefix . 'civicrm_worldregion')) {
       if (empty($this->_aliases[$prefix . 'civicrm_country'])) {
         $this->_aliases[$prefix . 'civicrm_country'] = $prefix . '_report_country';
       }
-      $this->_from .= "
+      $fromJoin = "
             LEFT JOIN civicrm_country {$this->_aliases[$prefix . 'civicrm_country']}
-                   ON {$this->_aliases[$prefix . 'civicrm_address']}.country_id = {$this->_aliases[$prefix . 'civicrm_country']}.id AND
+                   ON {$this->_aliases[$prefix . 'civicrm_address']}.country_id = {$this->_aliases[$prefix . 'civicrm_country']}.id";
+      if ($params['primary_only']) {
+        $fromJoin .= " AND
                       {$this->_aliases[$prefix . 'civicrm_address']}.is_primary = 1 ";
+      }
+      $this->_from .= $fromJoin;
     }
   }
 
@@ -4743,12 +4763,18 @@ LEFT JOIN civicrm_contact {$field['alias']} ON {$field['alias']}.id = {$this->_a
    *      Not currently used in core but may be used in override extensions.
    */
   protected function joinPhoneFromContact($prefix = '', $extra = []) {
+    $defaults = ['primary_only' => TRUE];
+    $params = array_merge($defaults, $extra);
     // include phone field if phone column is to be included
     if ($this->isTableSelected($prefix . 'civicrm_phone')) {
-      $this->_from .= "
+      $fromJoin = "
       LEFT JOIN civicrm_phone {$this->_aliases[$prefix . 'civicrm_phone']}
-             ON {$this->_aliases[$prefix . 'civicrm_contact']}.id = {$this->_aliases[$prefix . 'civicrm_phone']}.contact_id AND
+             ON {$this->_aliases[$prefix . 'civicrm_contact']}.id = {$this->_aliases[$prefix . 'civicrm_phone']}.contact_id";
+      if ($params['primary_only']) {
+        $fromJoin .= " AND
                 {$this->_aliases[$prefix . 'civicrm_phone']}.is_primary = 1\n";
+      }
+      $this->_from .= $fromJoin;
     }
   }
 
@@ -4763,12 +4789,18 @@ LEFT JOIN civicrm_contact {$field['alias']} ON {$field['alias']}.id = {$this->_a
    *      Not currently used in core but may be used in override extensions.
    */
   protected function joinEmailFromContact($prefix = '', $extra = []) {
+    $defaults = ['primary_only' => TRUE];
+    $params = array_merge($defaults, $extra);
     // include email field if email column is to be included
     if ($this->isTableSelected($prefix . 'civicrm_email')) {
-      $this->_from .= "
+      $fromJoin = "
             LEFT JOIN  civicrm_email {$this->_aliases[$prefix . 'civicrm_email']}
-                   ON ({$this->_aliases[$prefix . 'civicrm_contact']}.id = {$this->_aliases[$prefix . 'civicrm_email']}.contact_id AND
-                       {$this->_aliases[$prefix . 'civicrm_email']}.is_primary = 1) ";
+                   ON {$this->_aliases[$prefix . 'civicrm_contact']}.id = {$this->_aliases[$prefix . 'civicrm_email']}.contact_id";
+      if ($params['primary_only']) {
+        $fromJoin .= " AND
+                       {$this->_aliases[$prefix . 'civicrm_email']}.is_primary = 1 ";
+      }
+      $this->_from .= $fromJoin;
     }
   }
 
@@ -5000,37 +5032,6 @@ LEFT JOIN civicrm_contact {$field['alias']} ON {$field['alias']}.id = {$this->_a
     }
   }
 
-  /**
-   * Show charts on print screen.
-   */
-  public static function uploadChartImage() {
-    // upload strictly for '.png' images
-    $name = trim(basename(CRM_Utils_Request::retrieve('name', 'String', CRM_Core_DAO::$_nullObject, FALSE, NULL, 'GET')));
-    if (preg_match('/\.png$/', $name)) {
-
-      // Get the RAW .png from the input.
-      $httpRawPostData = file_get_contents("php://input");
-
-      // prepare the directory
-      $config = CRM_Core_Config::singleton();
-      $defaultPath
-        = str_replace('/persist/contribute/', '/persist/', $config->imageUploadDir) .
-        '/openFlashChart/';
-      if (!file_exists($defaultPath)) {
-        mkdir($defaultPath, 0777, TRUE);
-      }
-
-      // full path to the saved image including filename
-      $destination = $defaultPath . $name;
-
-      //write and save
-      $jfh = fopen($destination, 'w') or die("can't open file");
-      fwrite($jfh, $httpRawPostData);
-      fclose($jfh);
-      CRM_Utils_System::civiExit();
-    }
-  }
-
   /**
    * Apply common settings to entityRef fields.
    *
@@ -5718,7 +5719,7 @@ LEFT JOIN civicrm_contact {$field['alias']} ON {$field['alias']}.id = {$this->_a
       ],
       $options['prefix'] . 'postal_code_suffix' => [
         'title' => $options['prefix_label'] . ts('Postal Code Suffix'),
-        'name' => 'postal_code',
+        'name' => 'postal_code_suffix',
         'type' => 1,
         'is_fields' => TRUE,
         'is_filters' => TRUE,
@@ -5759,7 +5760,7 @@ LEFT JOIN civicrm_contact {$field['alias']} ON {$field['alias']}.id = {$this->_a
         'options' => CRM_Core_PseudoConstant::country(),
       ],
       $options['prefix'] . 'location_type_id' => [
-        'name' => 'is_primary',
+        'name' => 'location_type_id',
         'title' => $options['prefix_label'] . ts('Location Type'),
         'type' => CRM_Utils_Type::T_INT,
         'is_fields' => TRUE,
@@ -5929,7 +5930,7 @@ LEFT JOIN civicrm_contact {$field['alias']} ON {$field['alias']}.id = {$this->_a
     if ($this->groupConcatTested && (!empty($this->_groupByArray) || $this->isForceGroupBy)) {
       if ((empty($field['statistics']) || in_array('GROUP_CONCAT', $field['statistics']))) {
         $label = CRM_Utils_Array::value('title', $field);
-        $alias = "{$tableName}_{$fieldName}";
+        $alias = $field['tplField'] ?? "{$tableName}_{$fieldName}";
         $this->_columnHeaders["{$tableName}_{$fieldName}"]['title'] = $label;
         $this->_selectAliases[] = $alias;
         if (empty($this->_groupByArray[$tableName . '_' . $fieldName])) {