fixes for barcode display CRM-13327
[civicrm-core.git] / CRM / Badge / BAO / Badge.php
index fa22b24ccd2e2dc5e8e54f3105e470f53fa79ffe..6dbcf61ea7aa76fa2a1fe81da59c1108069a0913 100644 (file)
@@ -45,8 +45,8 @@ class CRM_Badge_BAO_Badge {
   /**
    *  This function is called to create name label pdf
    *
-   * @param   array    $participants associated array with participant info
-   * @param   array    $layoutInfo   associated array which contains meta data about format/layout
+   * @param   array $participants associated array with participant info
+   * @param   array $layoutInfo   associated array which contains meta data about format/layout
    *
    * @return  void
    * @access  public
@@ -85,13 +85,13 @@ class CRM_Badge_BAO_Badge {
     $formattedRow = array('labelFormat' => $layout['label_format_name']);
 
     if (CRM_Utils_Array::value('rowElements', $layout['data'])) {
-      foreach($layout['data']['rowElements'] as $key => $element) {
+      foreach ($layout['data']['rowElements'] as $key => $element) {
         $value = '';
         if ($element) {
           $value = $row[$element];
           // hack to fix date field display format
           if (strpos($element, '_date')) {
-            $value = CRM_Utils_Date::customFormat($value, "%e %b");
+            $value = CRM_Utils_Date::customFormat($value, "%B %E%f");
           }
         }
 
@@ -99,7 +99,9 @@ class CRM_Badge_BAO_Badge {
           'value' => $value,
           'font_name' => $layout['data']['font_name'][$key],
           'font_size' => $layout['data']['font_size'][$key],
+          'font_style' => $layout['data']['font_style'][$key],
           'text_alignment' => $layout['data']['text_alignment'][$key],
+          'token' => $layout['data']['token'][$key],
         );
       }
     }
@@ -107,13 +109,28 @@ class CRM_Badge_BAO_Badge {
     if (CRM_Utils_Array::value('image_1', $layout['data'])) {
       $formattedRow['image_1'] = $layout['data']['image_1'];
     }
+    if (CRM_Utils_Array::value('width_image_1', $layout['data'])) {
+      $formattedRow['width_image_1'] = $layout['data']['width_image_1'];
+    }
+    if (CRM_Utils_Array::value('height_image_1', $layout['data'])) {
+      $formattedRow['height_image_1'] = $layout['data']['height_image_1'];
+    }
 
     if (CRM_Utils_Array::value('image_2', $layout['data'])) {
       $formattedRow['image_2'] = $layout['data']['image_2'];
     }
+    if (CRM_Utils_Array::value('width_image_2', $layout['data'])) {
+      $formattedRow['width_image_2'] = $layout['data']['width_image_2'];
+    }
+    if (CRM_Utils_Array::value('height_image_2', $layout['data'])) {
+      $formattedRow['height_image_2'] = $layout['data']['height_image_2'];
+    }
 
     if (CRM_Utils_Array::value('add_barcode', $layout['data'])) {
-      $formattedRow['barcode'] = $layout['data']['barcode_alignment'];
+      $formattedRow['barcode'] = array(
+        'alignment' => $layout['data']['barcode_alignment'],
+        'type' => $layout['data']['barcode_type'],
+      );
     }
 
     // finally assign all the row values, so that we can use it for barcode etc
@@ -124,68 +141,157 @@ class CRM_Badge_BAO_Badge {
 
   public function generateLabel($formattedRow) {
     switch ($formattedRow['labelFormat']) {
+      case 'A6 Badge Portrait 150x106':
+      case 'Hanging Badge 3-3/4" x 4-3"/4':
+        self::labelCreator($formattedRow, 5);
+        break;
       case 'Avery 5395':
-        self::labelAvery5395($formattedRow);
+      default:
+        self::labelCreator($formattedRow);
         break;
     }
   }
 
-  public function labelAvery5395(&$formattedRow) {
-    $this->lMarginLogo = 20;
+  public function labelCreator(&$formattedRow, $cellspacing = 0) {
+    $this->lMarginLogo = 18;
     $this->tMarginName = 20;
 
     $x = $this->pdf->GetAbsX();
-    $y = $this->pdf->GetY();
+    $y = $this->pdf->getY();
 
+    $startOffset = 0;
     if (CRM_Utils_Array::value('image_1', $formattedRow)) {
-      $this->printImage($formattedRow['image_1']);
+      $this->printImage($formattedRow['image_1'], NULL, NULL, CRM_Utils_Array::value('width_image_1', $formattedRow),
+        CRM_Utils_Array::value('height_image_1', $formattedRow));
     }
 
     if (CRM_Utils_Array::value('image_2', $formattedRow)) {
-     $this->printImage($formattedRow['image_2'], $x + 68);
+      $this->printImage($formattedRow['image_2'], $x + 68, NULL, CRM_Utils_Array::value('width_image_2', $formattedRow),
+        CRM_Utils_Array::value('height_image_2', $formattedRow));
     }
 
-    $this->pdf->SetLineStyle(array('width' => 0.1, 'cap' => 'round', 'join' => 'round',
-      'dash' => '2,2', 'color' => array(0, 0, 200)));
+    if ((CRM_Utils_Array::value('height_image_1', $formattedRow) >
+      CRM_Utils_Array::value('height_image_2', $formattedRow)) &&
+      CRM_Utils_Array::value('height_image_1', $formattedRow)) {
+      $startOffset = CRM_Utils_Array::value('height_image_1', $formattedRow);
+    }
+    elseif (CRM_Utils_Array::value('height_image_2', $formattedRow)) {
+      $startOffset = CRM_Utils_Array::value('height_image_2', $formattedRow);
+    }
 
-    $this->pdf->SetFont($formattedRow['token'][1]['font_name'], '', $formattedRow['token'][1]['font_size']);
-    $this->pdf->MultiCell($this->pdf->width - $this->lMarginLogo, 0, $formattedRow['token'][1]['value'],
-      $this->border, $formattedRow['token'][1]['text_alignment'], 0, 1, $x + $this->lMarginLogo, $y);
+    $this->pdf->SetLineStyle(array(
+      'width' => 0.1,
+      'cap' => 'round',
+      'join' => 'round',
+      'dash' => '2,2',
+      'color' => array(0, 0, 200)
+    ));
+
+    $rowCount = CRM_Badge_Form_Layout::FIELD_ROWCOUNT;
+    for ($i = 1; $i <= $rowCount; $i++) {
+      if (!empty($formattedRow['token'][$i]['token'])) {
+        $value = '';
+        if ($formattedRow['token'][$i]['token'] != 'spacer') {
+          $value = $formattedRow['token'][$i]['value'];
+        }
 
-    $this->pdf->SetFont($formattedRow['token'][2]['font_name'], '', $formattedRow['token'][2]['font_size']);
-    $this->pdf->MultiCell($this->pdf->width, 10, $formattedRow['token'][2]['value'],
-      $this->border, $formattedRow['token'][2]['text_alignment'], 0, 1, $x, $y + $this->tMarginName);
+        $offset = $this->pdf->getY() + $startOffset + $cellspacing;
 
-    $this->pdf->SetFont($formattedRow['token'][3]['font_name'], '', $formattedRow['token'][3]['font_size']);
-    $this->pdf->MultiCell($this->pdf->width, 0, $formattedRow['token'][3]['value'],
-      $this->border, $formattedRow['token'][3]['text_alignment'], 0, 1, $x, $this->pdf->getY());
+        $this->pdf->SetFont($formattedRow['token'][$i]['font_name'], $formattedRow['token'][$i]['font_style'],
+          $formattedRow['token'][$i]['font_size']);
+        $this->pdf->MultiCell($this->pdf->width, 0, $value,
+          $this->border, $formattedRow['token'][$i]['text_alignment'], 0, 1, $x, $offset);
 
-    $this->pdf->SetFont($formattedRow['token'][4]['font_name'], '', $formattedRow['token'][4]['font_size']);
-    $this->pdf->SetXY($x, $y + $this->pdf->height - 5);
-    $this->pdf->Cell($this->pdf->width, 0, $formattedRow['token'][4]['value'], $this->border, 2,
-      $formattedRow['token'][4]['text_alignment']);
+        // set this to zero so that it is added only for first element
+        $startOffset = 0;
+      }
+    }
 
     if (CRM_Utils_Array::value('barcode', $formattedRow)) {
-      $style = array(
-        'position' => $formattedRow['barcode'],
-        'align' => $formattedRow['barcode'],
-        'stretch' => FALSE,
-        'fitwidth' => TRUE,
-        'cellfitalign' => '',
-        'border' => FALSE,
-        'hpadding' => 'auto',
-        'vpadding' => 'auto',
-        'fgcolor' => array(0, 0, 0),
-        'bgcolor' => FALSE,
-        'text' => FALSE,
-        'font' => 'helvetica',
-        'fontsize' => 8,
-        'stretchtext' => 0,
-      );
+      $data = $formattedRow['values'];
+
+      if ($formattedRow['barcode']['type'] == 'barcode') {
+        $data['current_value'] =
+          $formattedRow['values']['contact_id'] . '-' . $formattedRow['values']['participant_id'];
+      }
+      else {
+        // view participant url
+        $data['current_value'] = CRM_Utils_System::url('civicrm/contact/view/participant',
+          'action=view&reset=1&cid=' . $formattedRow['values']['contact_id'] . '&id='
+          . $formattedRow['values']['participant_id'],
+          TRUE,
+          NULL,
+          FALSE
+        );
+      }
+
+      // call hook alterBarcode
+      CRM_Utils_Hook::alterBarcode($data, $formattedRow['barcode']['type']);
+
+      if ($formattedRow['barcode']['type'] == 'barcode') {
+        // barcode position
+        $xAlign = $x;
+
+        switch ($formattedRow['barcode']['alignment']) {
+          case 'L':
+            $xAlign += -14;
+            break;
+          case 'R':
+            $xAlign += 27;
+            break;
+          case 'C':
+            $xAlign += 9;
+            break;
+        }
 
-      $payload = $formattedRow['values']['contact_id'] . '-' . $formattedRow['values']['participant_id'];
-      $this->pdf->SetXY($x, $y + $this->pdf->height - 5);
-      $this->pdf->write1DBarcode($payload, "C128A", $x, $this->pdf->getY() - 6, 50, 10, 0.4, $style, 'B');
+        $style = array(
+          'position' => '',
+          'align' => '',
+          'stretch' => FALSE,
+          'fitwidth' => TRUE,
+          'cellfitalign' => '',
+          'border' => FALSE,
+          'hpadding' => 13.5,
+          'vpadding' => 'auto',
+          'fgcolor' => array(0, 0, 0),
+          'bgcolor' => FALSE,
+          'text' => FALSE,
+          'font' => 'helvetica',
+          'fontsize' => 8,
+          'stretchtext' => 0,
+        );
+
+        $this->pdf->write1DBarcode($data['current_value'], 'C128', $xAlign, $y + $this->pdf->height - 10, '70',
+          12, 0.4, $style, 'B');
+      }
+      else {
+        // qr code position
+        $xAlign = $x;
+
+        switch ($formattedRow['barcode']['alignment']) {
+          case 'L':
+            $xAlign += -5;
+            break;
+          case 'R':
+            $xAlign += 56;
+            break;
+          case 'C':
+            $xAlign += 29;
+            break;
+        }
+
+        $style = array(
+          'border' => false,
+          'hpadding' => 13.5,
+          'vpadding' => 'auto',
+          'fgcolor' => array(0,0,0),
+          'bgcolor' => false,
+          'position' => '',
+        );
+
+        $this->pdf->write2DBarcode($data['current_value'], 'QRCODE,H', $xAlign, $y  + $this->pdf->height - 26, 30,
+          30, $style, 'B');
+      }
     }
   }
 
@@ -196,7 +302,7 @@ class CRM_Badge_BAO_Badge {
    * @return void
    * @access public
    */
-  function printImage($img, $x='', $y='') {
+  function printImage($img, $x = '', $y = '', $w = NULL, $h = NULL) {
     if (!$x) {
       $x = $this->pdf->GetAbsX();
     }
@@ -208,15 +314,110 @@ class CRM_Badge_BAO_Badge {
     $this->imgRes = 300;
 
     if ($img) {
-      $imgsize = getimagesize($img);
-      // mm
-      $f = $this->imgRes / 25.4;
-      $w = $imgsize[0] / $f;
-      $h = $imgsize[1] / $f;
+      list($w, $h) = self::getImageProperties($img, $this->imgRes, $w, $h);
       $this->pdf->Image($img, $x, $y, $w, $h, '', '', '', FALSE, 72, '', FALSE,
         FALSE, $this->debug, FALSE, FALSE, FALSE);
     }
     $this->pdf->SetXY($x, $y);
   }
+
+  static function getImageProperties($img, $imgRes = 300, $w = NULL, $h = NULL) {
+    $imgsize = getimagesize($img);
+    $f = $imgRes / 25.4;
+    $w = !empty($w) ? $w : $imgsize[0] / $f;
+    $h = !empty($h) ? $h : $imgsize[1] / $f;
+    return array($w, $h);
+  }
+
+  /**
+   * function to build badges parameters before actually creating badges.
+   *
+   * @param  array  $params associated array of submitted values
+   * @params object $form form/controller object
+   *
+   * @return void
+   * @access public
+   * @static
+   */
+  public static function buildBadges(&$params, &$form) {
+    // get name badge layout info
+    $layoutInfo = CRM_Badge_BAO_Layout::buildLayout($params);
+
+    // spit / get actual field names from token
+    $returnProperties = array();
+    if (!empty($layoutInfo['data']['token'])) {
+      foreach ($layoutInfo['data']['token'] as $index => $value) {
+        $element = '';
+        if ($value) {
+          $token = CRM_Utils_Token::getTokens($value);
+          if (key($token) == 'contact') {
+            $element = $token['contact'][0];
+          }
+          elseif (key($token) == 'event') {
+            $element = $token['event'][0];
+            //FIX ME - we need to standardize event token names
+            if (substr($element, 0, 6) != 'event_') {
+              $element = 'event_' . $element;
+            }
+          }
+          elseif (key($token) == 'participant') {
+            $element = $token['participant'][0];
+          }
+
+          // build returnproperties for query
+          $returnProperties[$element] = 1;
+        }
+
+        // add actual field name to row element
+        $layoutInfo['data']['rowElements'][$index] = $element;
+      }
+    }
+
+    // add additional required fields for query execution
+    $additionalFields = array('participant_register_date', 'participant_id', 'event_id', 'contact_id');
+    foreach ($additionalFields as $field) {
+      $returnProperties[$field] = 1;
+    }
+
+    if ($form->_single) {
+      $queryParams = NULL;
+    }
+    else {
+      $queryParams = $form->get('queryParams');
+    }
+
+    $query = new CRM_Contact_BAO_Query($queryParams, $returnProperties, NULL, FALSE, FALSE,
+      CRM_Contact_BAO_Query::MODE_EVENT
+    );
+
+    list($select, $from, $where, $having) = $query->query();
+    if (empty($where)) {
+      $where = "WHERE {$form->_componentClause}";
+    }
+    else {
+      $where .= " AND {$form->_componentClause}";
+    }
+
+    $sortOrder = NULL;
+    if ($form->get(CRM_Utils_Sort::SORT_ORDER)) {
+      $sortOrder = $form->get(CRM_Utils_Sort::SORT_ORDER);
+      if (!empty($sortOrder)) {
+        $sortOrder = " ORDER BY $sortOrder";
+      }
+    }
+    $queryString = "$select $from $where $having $sortOrder";
+
+    $dao = CRM_Core_DAO::executeQuery($queryString);
+    $rows = array();
+    while ($dao->fetch()) {
+      $rows[$dao->participant_id] = array();
+      foreach ($returnProperties as $key => $dontCare) {
+        $rows[$dao->participant_id][$key] = isset($dao->$key) ? $dao->$key : NULL;
+      }
+    }
+
+    $eventBadgeClass = new CRM_Badge_BAO_Badge();
+    $eventBadgeClass->createLabels($rows, $layoutInfo);
+  }
 }