/** * Creates a receipt without receipt-items using the generic tokens * @param $tokens tokens coming from SnapshotReceipt->getAllTokens * @return Receipt object if successfull, FALSE otherwise. */ public static function _createReceiptFromTokens($tokens) { // initialize custom field map self::getCustomFields(); $fields = self::$_custom_fields; $custom_group_id = self::$_custom_group_id; $table = "civicrm_value_donation_receipt_{$custom_group_id}"; // build SET-SQL $sql_set = "`entity_id`={$tokens['contact_id']}"; foreach ($fields as $key => $field) { $value = null; if (0 === strpos($key, 'shipping')) { $token_key = substr($key, strlen('shipping_')); $value = $tokens['addressee'][$token_key]; } elseif ($tokens[$key]) { $value = $tokens[$key]; } elseif ($tokens['contributor'][$key]) { $value = $tokens['contributor'][$key]; } if (!is_null($value)) { $value = CRM_Utils_DonrecHelper::escapeString($value); $sql_set .= ", `{$field}`='{$value}'"; } } // build query $query = "INSERT INTO `{$table}` SET {$sql_set}"; // run the query return CRM_Core_DAO::executeQuery($query); }
/** * Build and run the query to select all contributions * matching the criteria, and try to create a snapshot * * @return snapshot creation result/error */ public static function createSnapshot($values) { // prepare timestamps $raw_from_ts = $values['donrec_contribution_horizon_from']; $raw_to_ts = $values['donrec_contribution_horizon_to']; $date_from = CRM_Utils_DonrecHelper::convertDate($raw_from_ts, -1); $date_to = CRM_Utils_DonrecHelper::convertDate($raw_to_ts, 1); $formatted_date_from = date('Y-m-d H:i:s', $date_from); $formatted_date_to = date('Y-m-d H:i:s', $date_to); $query_date_limit = ""; if ($date_from) { $query_date_limit .= "AND `receive_date` >= '{$formatted_date_from}'"; } if ($date_to) { $query_date_limit .= " AND `receive_date` <= '{$formatted_date_to}'"; } // get table- and column name $table_query = "SELECT `cg`.`table_name`,\n `cf`.`column_name`\n FROM `civicrm_custom_group` AS cg,\n `civicrm_custom_field` AS cf\n WHERE `cg`.`name` = 'zwb_donation_receipt_item'\n AND `cf`.`custom_group_id` = `cg`.`id`\n AND `cf`.`name` = 'status'"; $results = CRM_Core_DAO::executeQuery($table_query); $custom_group_table = NULL; $status_column = NULL; while ($results->fetch()) { $custom_group_table = $results->table_name; $status_column = $results->column_name; } if ($custom_group_table == NULL || $status_column == NULL) { // something went wrong here CRM_Core_Error::debug_log_message("de.systopia.donrec: error: custom_group_table or status_column is empty!"); return array(); } // calculate main selector clause if (!empty($values['contact_id'])) { $contact_id = (int) $values['contact_id']; $main_selector = "`contact_id` = {$contact_id}"; } elseif (!empty($values['contact_ids'])) { $contact_ids = implode(',', $values['contact_ids']); $main_selector = "`contact_id` IN ({$contact_ids})"; } elseif (!empty($values['contribution_ids'])) { $contribution_ids = implode(',', $values['contribution_ids']); $main_selector = "`civicrm_contribution`.`id` IN ({$contribution_ids})"; } else { CRM_Core_Error::debug_log_message("de.systopia.donrec: error: no selector data found in params!"); $main_selector = "FALSE"; } // get financial type selector clause $profile = new CRM_Donrec_Logic_Profile($values['profile']); $financialTypeClause = $profile->getContributionTypesClause(); // run the main query $query = "SELECT `civicrm_contribution`.`id`\n FROM (`civicrm_contribution`)\n LEFT JOIN `{$custom_group_table}` AS existing_receipt\n ON `civicrm_contribution`.`id` = existing_receipt.`entity_id`\n AND existing_receipt.`{$status_column}` = 'ORIGINAL'\n WHERE\n ({$main_selector})\n {$query_date_limit}\n AND {$financialTypeClause}\n AND (`non_deductible_amount` = 0 OR `non_deductible_amount` IS NULL)\n AND `contribution_status_id` = 1\n AND `is_test` = 0\n AND `currency` = 'EUR'\n AND existing_receipt.`entity_id` IS NULL;"; // execute the query $result = CRM_Core_DAO::executeQuery($query); // build array $contributionIds = array(); while ($result->fetch()) { $contributionIds[] = $result->id; } // finally, build the snapshot with it return CRM_Donrec_Logic_Snapshot::create($contributionIds, CRM_Donrec_Logic_Settings::getLoggedInContactID(), $formatted_date_from, $formatted_date_to, $values['profile']); }
/** * Creates a new receipt item * @param array of parameters * @return TRUE or FALSE if there was an error //TODO */ public static function create($params) { self::getCustomFields(); $fields = self::$_custom_fields; $group_id = self::$_custom_group_id; $table = "civicrm_value_donation_receipt_item_{$group_id}"; $params['contribution_hash'] = self::calculateChecksum($params); // build set-string $set_str = "`entity_id`={$params['contribution_id']}"; foreach ($fields as $key => $field) { if (!is_null($params[$key])) { $value = CRM_Utils_DonrecHelper::escapeString($params[$key]); $set_str .= ", `{$field}`='{$value}'"; } } // build query $query = "INSERT INTO `{$table}` SET {$set_str}"; // run query $result = CRM_Core_DAO::executeQuery($query); return $result; }
/** * This is a workaround for the problem that using the translated title right away makes the * table names change. * * FIXME: we should not be working with static table names */ public static function translateCustomGroups() { try { // TRANSLATE zwb_donation_receipt title $custom_group_receipt = civicrm_api3('CustomGroup', 'getsingle', array('name' => 'zwb_donation_receipt')); // since the API is not reliable here, we do this via SQL $new_title = CRM_Utils_DonrecHelper::escapeString(ts('Donation Receipt', array('domain' => 'de.systopia.donrec'))); $custom_group_receipt_id = (int) $custom_group_receipt['id']; CRM_Core_DAO::executeQuery("UPDATE `civicrm_custom_group` SET title='{$new_title}' WHERE id={$custom_group_receipt_id};"); // TRANSLATE zwb_donation_receipt_item title $custom_group_receipt_item = civicrm_api3('CustomGroup', 'getsingle', array('name' => 'zwb_donation_receipt_item')); // since the API is not reliable here, we do this via SQL $new_title = CRM_Utils_DonrecHelper::escapeString(ts('Donation Receipt Item', array('domain' => 'de.systopia.donrec'))); $custom_group_receipt_item_id = (int) $custom_group_receipt_item['id']; CRM_Core_DAO::executeQuery("UPDATE `civicrm_custom_group` SET title='{$new_title}' WHERE id={$custom_group_receipt_item_id};"); } catch (Exception $e) { CRM_Core_Error::debug_log_message('de.systopia.donrec - Error translating custom groups: ' . $e->getMessage()); } }
/** * Prune the "find contributions" and "advanced contact search" forms * by removing the fields that don't make sense or don't work */ function donrec_civicrm_buildForm($formName, &$form) { if ($formName == 'CRM_Contribute_Form_Search') { $item_fields = CRM_Donrec_Logic_ReceiptItem::getCustomFields(); // remove unwanted fields $field_ids_to_remove[] = CRM_Utils_DonrecHelper::getFieldID($item_fields, 'financial_type_id'); $field_ids_to_remove[] = CRM_Utils_DonrecHelper::getFieldID($item_fields, 'total_amount'); $field_ids_to_remove[] = CRM_Utils_DonrecHelper::getFieldID($item_fields, 'non_deductible_amount'); $field_ids_to_remove[] = CRM_Utils_DonrecHelper::getFieldID($item_fields, 'currency'); $field_ids_to_remove[] = CRM_Utils_DonrecHelper::getFieldID($item_fields, 'contribution_hash'); $field_ids_to_remove[] = CRM_Utils_DonrecHelper::getFieldID($item_fields, 'issued_on'); $field_ids_to_remove[] = CRM_Utils_DonrecHelper::getFieldID($item_fields, 'receive_date'); $field_ids_to_remove[] = CRM_Utils_DonrecHelper::getFieldID($item_fields, 'issued_in'); $form->assign('field_ids_to_remove', implode(',', $field_ids_to_remove)); CRM_Core_Region::instance('page-body')->add(array('template' => 'CRM/Donrec/Form/Search/RemoveFields.snippet.tpl')); // DISABLED: date field search doesn't work // CRM_Utils_DonrecHelper::relabelDateField($form, $item_fields, 'issued_on', ts("Issed On - From", array('domain' => 'de.systopia.donrec')), ts("Issed On - To", array('domain' => 'de.systopia.donrec'))); // CRM_Utils_DonrecHelper::relabelDateField($form, $item_fields, 'receive_date', ts("Received - From", array('domain' => 'de.systopia.donrec')), ts("Received - To", array('domain' => 'de.systopia.donrec'))); // override the standard fields $status_id = CRM_Utils_DonrecHelper::getFieldID($item_fields, 'status'); if ($status_id) { $form->add('select', "custom_{$status_id}", ts('Status', array('domain' => 'de.systopia.donrec')), array('' => ts('- any -', array('domain' => 'de.systopia.donrec')), 'original' => ts('original', array('domain' => 'de.systopia.donrec')), 'copy' => ts('copy', array('domain' => 'de.systopia.donrec')), 'withdrawn' => ts('withdrawn', array('domain' => 'de.systopia.donrec')), 'withdrawn_copy' => ts('withdrawn_copy', array('domain' => 'de.systopia.donrec')))); } $status_id = CRM_Utils_DonrecHelper::getFieldID($item_fields, 'type'); if ($status_id) { $form->add('select', "custom_{$status_id}", ts('Type', array('domain' => 'de.systopia.donrec')), array('' => ts('- any -', array('domain' => 'de.systopia.donrec')), 'single' => ts('single receipt', array('domain' => 'de.systopia.donrec')), 'bulk' => ts('bulk receipt', array('domain' => 'de.systopia.donrec')))); } $status_id = CRM_Utils_DonrecHelper::getFieldID($item_fields, 'issued_in'); if ($status_id) { $form->add('text', "custom_{$status_id}", ts('Receipt ID', array('domain' => 'de.systopia.donrec'))); } $status_id = CRM_Utils_DonrecHelper::getFieldID($item_fields, 'issued_by'); if ($status_id) { $form->add('text', "custom_{$status_id}", ts('Issued by contact', array('domain' => 'de.systopia.donrec'))); } } elseif ($formName == 'CRM_Contact_Form_Search_Advanced') { // remove unwanted fields $item_fields = CRM_Donrec_Logic_Receipt::getCustomFields(); $field_ids_to_remove[] = CRM_Utils_DonrecHelper::getFieldID($item_fields, 'issued_on'); $field_ids_to_remove[] = CRM_Utils_DonrecHelper::getFieldID($item_fields, 'original_file'); $field_ids_to_remove[] = CRM_Utils_DonrecHelper::getFieldID($item_fields, 'contact_type'); $field_ids_to_remove[] = CRM_Utils_DonrecHelper::getFieldID($item_fields, 'gender'); $field_ids_to_remove[] = CRM_Utils_DonrecHelper::getFieldID($item_fields, 'prefix'); $field_ids_to_remove[] = CRM_Utils_DonrecHelper::getFieldID($item_fields, 'display_name'); $field_ids_to_remove[] = CRM_Utils_DonrecHelper::getFieldID($item_fields, 'postal_greeting_display'); $field_ids_to_remove[] = CRM_Utils_DonrecHelper::getFieldID($item_fields, 'email_greeting_display'); $field_ids_to_remove[] = CRM_Utils_DonrecHelper::getFieldID($item_fields, 'addressee_display'); $field_ids_to_remove[] = CRM_Utils_DonrecHelper::getFieldID($item_fields, 'street_address'); $field_ids_to_remove[] = CRM_Utils_DonrecHelper::getFieldID($item_fields, 'supplemental_address_1'); $field_ids_to_remove[] = CRM_Utils_DonrecHelper::getFieldID($item_fields, 'supplemental_address_2'); $field_ids_to_remove[] = CRM_Utils_DonrecHelper::getFieldID($item_fields, 'supplemental_address_3'); $field_ids_to_remove[] = CRM_Utils_DonrecHelper::getFieldID($item_fields, 'postal_code'); $field_ids_to_remove[] = CRM_Utils_DonrecHelper::getFieldID($item_fields, 'city'); $field_ids_to_remove[] = CRM_Utils_DonrecHelper::getFieldID($item_fields, 'country'); $field_ids_to_remove[] = CRM_Utils_DonrecHelper::getFieldID($item_fields, 'shipping_addressee_display'); $field_ids_to_remove[] = CRM_Utils_DonrecHelper::getFieldID($item_fields, 'shipping_street_address'); $field_ids_to_remove[] = CRM_Utils_DonrecHelper::getFieldID($item_fields, 'shipping_supplemental_address_1'); $field_ids_to_remove[] = CRM_Utils_DonrecHelper::getFieldID($item_fields, 'shipping_supplemental_address_2'); $field_ids_to_remove[] = CRM_Utils_DonrecHelper::getFieldID($item_fields, 'shipping_supplemental_address_3'); $field_ids_to_remove[] = CRM_Utils_DonrecHelper::getFieldID($item_fields, 'shipping_postal_code'); $field_ids_to_remove[] = CRM_Utils_DonrecHelper::getFieldID($item_fields, 'shipping_city'); $field_ids_to_remove[] = CRM_Utils_DonrecHelper::getFieldID($item_fields, 'shipping_country'); $field_ids_to_remove[] = CRM_Utils_DonrecHelper::getFieldID($item_fields, 'date_from'); $field_ids_to_remove[] = CRM_Utils_DonrecHelper::getFieldID($item_fields, 'date_to'); // remove unwanted fields from receipt items (in contribution tab) $item_fields_receipt = CRM_Donrec_Logic_ReceiptItem::getCustomFields(); $field_ids_to_remove[] = CRM_Utils_DonrecHelper::getFieldID($item_fields_receipt, 'financial_type_id'); $field_ids_to_remove[] = CRM_Utils_DonrecHelper::getFieldID($item_fields_receipt, 'total_amount'); $field_ids_to_remove[] = CRM_Utils_DonrecHelper::getFieldID($item_fields_receipt, 'non_deductible_amount'); $field_ids_to_remove[] = CRM_Utils_DonrecHelper::getFieldID($item_fields_receipt, 'currency'); $field_ids_to_remove[] = CRM_Utils_DonrecHelper::getFieldID($item_fields_receipt, 'contribution_hash'); $field_ids_to_remove[] = CRM_Utils_DonrecHelper::getFieldID($item_fields_receipt, 'issued_on'); $field_ids_to_remove[] = CRM_Utils_DonrecHelper::getFieldID($item_fields_receipt, 'receive_date'); $form->assign('field_ids_to_remove', implode(',', $field_ids_to_remove)); CRM_Core_Region::instance('page-body')->add(array('template' => 'CRM/Donrec/Form/Search/RemoveFields.snippet.tpl')); // DISABLED: date field search doesn't work //CRM_Utils_DonrecHelper::relabelDateField($form, $item_fields, 'issued_on', ts("Issed On - From", array('domain' => 'de.systopia.donrec')), ts("Issed On - To", array('domain' => 'de.systopia.donrec'))); // override the standard fields $status_id = CRM_Utils_DonrecHelper::getFieldID($item_fields, 'status'); if ($status_id) { $form->add('select', "custom_{$status_id}", ts('Status', array('domain' => 'de.systopia.donrec')), array('' => ts('- any -', array('domain' => 'de.systopia.donrec')), 'original' => ts('original', array('domain' => 'de.systopia.donrec')), 'copy' => ts('copy', array('domain' => 'de.systopia.donrec')), 'withdrawn' => ts('withdrawn', array('domain' => 'de.systopia.donrec')), 'withdrawn_copy' => ts('withdrawn_copy', array('domain' => 'de.systopia.donrec')))); } $status_id = CRM_Utils_DonrecHelper::getFieldID($item_fields, 'type'); if ($status_id) { $form->add('select', "custom_{$status_id}", ts('Type', array('domain' => 'de.systopia.donrec')), array('' => ts('- any -', array('domain' => 'de.systopia.donrec')), 'single' => ts('single receipt', array('domain' => 'de.systopia.donrec')), 'bulk' => ts('bulk receipt', array('domain' => 'de.systopia.donrec')))); } $status_id = CRM_Utils_DonrecHelper::getFieldID($item_fields, 'issued_by'); if ($status_id) { $form->add('text', "custom_{$status_id}", ts('Issued by contact', array('domain' => 'de.systopia.donrec'))); } // override the receipt_item standard fields $status_id = CRM_Utils_DonrecHelper::getFieldID($item_fields_receipt, 'status'); if ($status_id) { $form->add('select', "custom_{$status_id}", ts('Status', array('domain' => 'de.systopia.donrec')), array('' => ts('- any -', array('domain' => 'de.systopia.donrec')), 'original' => ts('original', array('domain' => 'de.systopia.donrec')), 'copy' => ts('copy', array('domain' => 'de.systopia.donrec')), 'withdrawn' => ts('withdrawn', array('domain' => 'de.systopia.donrec')), 'withdrawn_copy' => ts('withdrawn_copy', array('domain' => 'de.systopia.donrec')))); } $status_id = CRM_Utils_DonrecHelper::getFieldID($item_fields_receipt, 'type'); if ($status_id) { $form->add('select', "custom_{$status_id}", ts('Type', array('domain' => 'de.systopia.donrec')), array('' => ts('- any -', array('domain' => 'de.systopia.donrec')), 'single' => ts('single receipt', array('domain' => 'de.systopia.donrec')), 'bulk' => ts('bulk receipt', array('domain' => 'de.systopia.donrec')))); } $status_id = CRM_Utils_DonrecHelper::getFieldID($item_fields_receipt, 'issued_in'); if ($status_id) { $form->add('text', "custom_{$status_id}", ts('Receipt ID', array('domain' => 'de.systopia.donrec'))); } $status_id = CRM_Utils_DonrecHelper::getFieldID($item_fields_receipt, 'issued_by'); if ($status_id) { $form->add('text', "custom_{$status_id}", ts('Issued by contact', array('domain' => 'de.systopia.donrec'))); } } }
public static function addDynamicTokens(&$values) { if (!empty($values['issued_by'])) { // add created_by_display_name try { $creator = civicrm_api3('Contact', 'getsingle', array('id' => $values['issued_by'])); $values['issued_by_display_name'] = $creator['display_name']; } catch (Exception $e) { CRM_Core_Error::debug_log_message('de.systopia.donrec - ' . print_r($e, 1)); } } // add the legacy 'today' token if (!empty($values['issued_on'])) { $values['today'] = $values['issued_on']; } // add the monetary tokens: 'total', 'totaltext', 'totalmoney' if (isset($values['total_amount'])) { // format total_amount $values['total_amount'] = number_format((double) $values['total_amount'], 2, '.', ''); $values['total'] = $values['total_amount']; $values['totaltext'] = CRM_Utils_DonrecHelper::convert_number_to_words($values['total_amount']); $values['totalmoney'] = CRM_Utils_Money::format($values['total_amount'], ''); } // add financial type name $financialTypes = CRM_Contribute_PseudoConstant::financialType(); if (is_array($values['lines'])) { foreach ($values['lines'] as $key => $line) { if (!empty($line['financial_type_id'])) { $values['lines'][$key]['financial_type'] = $financialTypes[$line['financial_type_id']]; } } } // sort contribution lines by receive date (#1497) $receive_dates = array(); $sorted_lines = $values['lines']; foreach ($sorted_lines as $key => $line) { $sorted_lines[$key]['id'] = $key; $receive_dates[$key] = $line['receive_date']; } array_multisort($receive_dates, SORT_ASC, $sorted_lines); $values['lines'] = array(); foreach ($sorted_lines as $key => $line) { $values['lines'][$line['id']] = $line; } // add legacy 'items' if (count($values['lines']) > 1) { $values['items'] = $values['lines']; } // add organisation address if (empty($values['organisation'])) { $domain = CRM_Core_BAO_Domain::getDomain(); $values['organisation'] = self::lookupAddressTokens($domain->contact_id, 0, 0); } // ADD watermarks $profile = CRM_Donrec_Logic_Profile::getProfile($values['profile']); if ($values['status'] == 'ORIGINAL') { // nothing to to in this case.. } elseif ($values['status'] == 'COPY') { $values['watermark'] = $profile->get('copy_text'); } else { // in all other cases, it's INVALID/DRAFT: $values['watermark'] = $profile->get('draft_text'); } // copy contributor values to addressee, if not set separately if (!isset($values['addressee']['display_name'])) { $values['addressee']['display_name'] = $values['contributor']['display_name']; } if (!isset($values['addressee']['addressee_display'])) { $values['addressee']['addressee_display'] = $values['contributor']['addressee_display']; } // add URL to view original file, if it exists if (!empty($values['original_file'])) { $values['view_url'] = CRM_Donrec_Logic_File::getPermanentURL($values['original_file'], $values['contributor']['id']); } // TODO: call Token hooks? Currently done by PDF generator }
/** * execute the next step of a donation receipt run * * @return array of stats: */ public function nextStep() { // some containers $exporter_results = array(); $files = array(); $profile = $this->snapshot->getProfile(); // Synchronize this step $lock = CRM_Utils_DonrecHelper::getLock('CRM_Donrec_Logic_Engine', 'nextStep'); if (!$lock->isAcquired()) { // lock timed out CRM_Core_Error::debug_log_message("de.systopia.donrec - couldn't acquire lock. Timeout is " . $lock->_timeout); // compile and return "state of affairs" report $stats = $this->createStats(); $stats['log'] = array(); $stats['files'] = $files; $stats['chunk_size'] = 0; CRM_Donrec_Logic_Exporter::addLogEntry($stats, "Couldn't acquire lock. Parallel processing denied. Lock timeout is {$lock->_timeout}s."); return $stats; } // check status $is_bulk = !empty($this->parameters['bulk']); $is_test = !empty($this->parameters['test']); // initialize stuff $chunk = $this->snapshot->getNextChunk($is_bulk, $is_test); $exporters = $this->getExporters(); // loop over receipts foreach ($chunk as $chunk_id => $chunk_items) { // Setup some parameters //********************************** // Prepare chunk_items: // #FIXME: It is more convenient to have a simalar array-structure for bulk- // and single-processing. In future the getNextChunk-method might be // refactored and build up the arrays correspondingly. $chunk_items = $is_bulk ? $chunk_items : array($chunk_items); $contact_id = $chunk_items[0]['contact_id']; $line_ids = array(); foreach ($chunk_items as $chunk_item) { $line_ids[] = $chunk_item['id']; } // create a SnapshotReceipt $snapshot_receipt = $this->snapshot->getSnapshotReceipt($line_ids, $is_test); // call exporters //********************************** foreach ($exporters as $exporter) { $exporter_id = $exporter->getID(); if ($is_bulk) { $result = $exporter->exportBulk($snapshot_receipt, $is_test); } else { $result = $exporter->exportSingle($snapshot_receipt, $is_test); } if (!isset($exporter_results[$exporter_id])) { $exporter_results[$exporter_id] = array(); $exporter_results[$exporter_id]['success'] = 0; $exporter_results[$exporter_id]['failure'] = 0; } if ($result) { $exporter_results[$exporter_id]['success']++; } else { $exporter_results[$exporter_id]['failure']++; } } // save original pdfs and create receipt for non-test-runs //********************************** if (!$is_test) { $receipt_params = array(); $receipt_params['type'] = $is_bulk ? 'BULK' : 'SINGLE'; if ($profile->saveOriginalPDF()) { $pdf_file = $this->getPDF($line_ids); $file = CRM_Donrec_Logic_File::createPermanentFile($pdf_file, basename($pdf_file), $contact_id); if (!empty($file)) { $receipt_params['original_file'] = $file['id']; } } CRM_Donrec_Logic_Receipt::createFromSnapshotReceipt($snapshot_receipt, $receipt_params); } } // The last chunk is empty. // If it is the last do some wrap-up. // Otherwise mark the chunk as processed. //********************************** if (!$chunk) { foreach ($exporters as $exporter) { $result = $exporter->wrapUp($this->snapshot->getId(), $is_test, $is_bulk); if (!empty($result['download_name']) && !empty($result['download_url'])) { $files[$exporter->getID()] = array($result['download_name'], $result['download_url']); } } } else { $this->snapshot->markChunkProcessed($chunk, $is_test, $is_bulk); } // compile stats //********************************** $stats = $this->createStats(); // create log-messages foreach ($exporter_results as $exporter_id => $result) { $msg = sprintf('%s processed %d items - %d succeeded, %d failed', $exporter_id, count($chunk), $result['success'], $result['failure']); $type = $result['failure'] ? 'ERROR' : 'INFO'; CRM_Donrec_Logic_Exporter::addLogEntry($stats, $msg, $type); } $stats['files'] = $files; if ($chunk == NULL) { $stats['progress'] = 100.0; } else { $stats['chunk_size'] = count($chunk); } // release our lock $lock->release(); return $stats; }