Skip to content
Snippets Groups Projects
MailingArchiveStat.php 3.02 KiB
Newer Older
<?php
use CRM_Archivemailing_ExtensionUtil as E;

class CRM_Archivemailing_BAO_MailingArchiveStat extends CRM_Archivemailing_DAO_MailingArchiveStat {

  /**
   * Create a new MailingArchiveStat based on array-data
   *
   * @param array $params key-value pairs
   * @return CRM_Archivemailing_DAO_MailingArchiveStat|NULL
  public static function create($params) {
    $className = 'CRM_Archivemailing_DAO_MailingArchiveStat';
    $entityName = 'MailingArchiveStat';
    $hook = empty($params['id']) ? 'create' : 'edit';

    if (empty($params['mailing_id'])) {
      throw new Exception('Missing required param: mailing_id');
    }

    $mailing_id = $params['mailing_id'];

    // I guess we could feed create() with the stats, but otherwise we will fetch them
    if (count($params) == 1) {
      $is_archived = CRM_Core_DAO::executeQuery('SELECT is_archived FROM civicrm_mailing WHERE id = %1', [
        1 => [$mailing_id, 'Positive'],
      ]);

      if ($is_archived && empty($report['event_totals']['delivered'])) {
        Civi::log()->info("archivemailing: mailing $mailing_id is already archived and stats seem empty, skipping stats archival");
      }
      else {
        $report = CRM_Mailing_BAO_Mailing::report($mailing_id);
        $params['recipients'] = $report['event_totals']['queue'];
        $params['deliveries'] = $report['event_totals']['delivered'];
        $params['forwards'] = $report['event_totals']['forward'];
        $params['replies'] = $report['event_totals']['reply'];
        $params['unsubscribes'] = $report['event_totals']['unsubscribe'];
        $params['optouts'] = $report['event_totals']['optout'];
        $params['bounces'] = $report['event_totals']['bounce'];
      }
    }

    // Check if a stats entry already exists
    $stat_id = CRM_Core_DAO::singleValueQuery('SELECT id FROM civicrm_mailing_archive_stat WHERE mailing_id = %1', [
      1 => [$mailing_id, 'Positive'],
    ]);

    if ($stat_id) {
      $params['id'] = $stat_id;
    CRM_Utils_Hook::pre($hook, $entityName, CRM_Utils_Array::value('id', $params), $params);
    $instance = new $className();
    $instance->copyValues($params);
    $instance->save();
    CRM_Utils_Hook::post($hook, $entityName, $instance->id, $instance);

    // Delete the stats from CiviMail queue tables, assuming the FKs cascade deletion
    $result = civicrm_api3('MailingJob', 'get', [
      'mailing_id' => $mailing_id,
    ]);

    if (!empty($result['values'])) {
      $job_ids = array_keys($result['values']);

      CRM_Core_DAO::executeQuery('DELETE FROM civicrm_mailing_event_queue where job_id IN (%1)', [
        1 => [implode(',', $job_ids), 'CommaSeparatedIntegers'],
      ]);
    }

    // Update the mailing as being archived
    // Somewhat using the DAO on purpose, in case eventually we add a hook to detect mailing archival
    // from the UI, and want to automatically trigger the archival of stats.
    CRM_Core_DAO::executeQuery('UPDATE civicrm_mailing SET is_archived = 1 WHERE id = %1', [
      1 => [$mailing_id, 'Positive'],
    ]);

    return $instance;