<commit_before><?php

require_once 'sparkpost.civix.php';

/**
 * Implements hook_civicrm_config().
 *
 * @link http://wiki.civicrm.org/confluence/display/CRMDOC/hook_civicrm_config
 */
function sparkpost_civicrm_config(&$config) {
  _sparkpost_civix_civicrm_config($config);
}

/**
 * Implements hook_civicrm_xmlMenu().
 *
 * @param array $files
 *
 * @link http://wiki.civicrm.org/confluence/display/CRMDOC/hook_civicrm_xmlMenu
 */
function sparkpost_civicrm_xmlMenu(&$files) {
  _sparkpost_civix_civicrm_xmlMenu($files);
}

/**
 * Implements hook_civicrm_install().
 *
 * @link http://wiki.civicrm.org/confluence/display/CRMDOC/hook_civicrm_install
 */
function sparkpost_civicrm_install() {
  _sparkpost_civix_civicrm_install();
}

/**
 * Implements hook_civicrm_uninstall().
 *
 * @link http://wiki.civicrm.org/confluence/display/CRMDOC/hook_civicrm_uninstall
 */
function sparkpost_civicrm_uninstall() {
  _sparkpost_civix_civicrm_uninstall();
}

/**
 * Implements hook_civicrm_enable().
 *
 * @link http://wiki.civicrm.org/confluence/display/CRMDOC/hook_civicrm_enable
 */
function sparkpost_civicrm_enable() {
  _sparkpost_civix_civicrm_enable();
  sparkpost_job_create();

  //Check and fix bad field type on civicrm_mailing_bounce_type.name
  $field_type  = CRM_Core_DAO::singleValueQuery("SELECT DATA_TYPE FROM INFORMATION_SCHEMA.COLUMNS WHERE table_name = 'civicrm_mailing_bounce_type' AND COLUMN_NAME = 'name'");
  $field_length  = CRM_Core_DAO::singleValueQuery("SELECT CHARACTER_MAXIMUM_LENGTH FROM INFORMATION_SCHEMA.COLUMNS WHERE table_name = 'civicrm_mailing_bounce_type' AND COLUMN_NAME = 'name'");

  if($field_type != 'varchar' || $field_length < 24) {
    CRM_Core_DAO::singleValueQuery("ALTER TABLE civicrm_mailing_bounce_type CHANGE name name VARCHAR(24) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL COMMENT 'Type of bounce'");
  }

  //Add bounce type and pattern to database
  if(!CRM_Core_DAO::singleValueQuery("SELECT count(id) as 'COUNT' FROM civicrm_mailing_bounce_type WHERE `name` = 'SparkPost'")) {
    CRM_Core_DAO::singleValueQuery("INSERT INTO `civicrm_mailing_bounce_type` (`name`, `description`, `hold_threshold`) VALUES ('SparkPost', 'SparkPost supression list', 1)");
    $bounce_type_id = CRM_Core_DAO::singleValueQuery("SELECT `id` FROM `civicrm_mailing_bounce_type` WHERE `name` = 'SparkPost' LIMIT 1");
    CRM_Core_DAO::singleValueQuery("INSERT INTO `civicrm_mailing_bounce_pattern` (`bounce_type_id`, `pattern`) VALUES ($bounce_type_id, 'recipient address suppressed due to customer policy')");
  }
  sparkpost_addOptionValues();
  sparkpost_mailingsCheck();

  Civi::settings()->set('com.pesc.sparkpost.debug', FALSE);
}

/**
 * Implements hook_civicrm_disable().
 *
 * @link http://wiki.civicrm.org/confluence/display/CRMDOC/hook_civicrm_disable
 */
function sparkpost_civicrm_disable() {
  _sparkpost_civix_civicrm_disable();
}

/**
 * Implements hook_civicrm_upgrade().
 *
 * @param $op string, the type of operation being performed; 'check' or 'enqueue'
 * @param $queue CRM_Queue_Queue, (for 'enqueue') the modifiable list of pending up upgrade tasks
 *
 * @return mixed
 *   Based on op. for 'check', returns array(boolean) (TRUE if upgrades are pending)
 *                for 'enqueue', returns void
 *
 * @link http://wiki.civicrm.org/confluence/display/CRMDOC/hook_civicrm_upgrade
 */
function sparkpost_civicrm_upgrade($op, CRM_Queue_Queue $queue = NULL) {
  return _sparkpost_civix_civicrm_upgrade($op, $queue);
}

/**
 * Implements hook_civicrm_managed().
 *
 * Generate a list of entities to create/deactivate/delete when this module
 * is installed, disabled, uninstalled.
 *
 * @link http://wiki.civicrm.org/confluence/display/CRMDOC/hook_civicrm_managed
 */
function sparkpost_civicrm_managed(&$entities) {
  _sparkpost_civix_civicrm_managed($entities);
}

/**
 * Implements hook_civicrm_caseTypes().
 *
 * Generate a list of case-types.
 *
 * @param array $caseTypes
 *
 * Note: This hook only runs in CiviCRM 4.4+.
 *
 * @link http://wiki.civicrm.org/confluence/display/CRMDOC/hook_civicrm_caseTypes
 */
function sparkpost_civicrm_caseTypes(&$caseTypes) {
  _sparkpost_civix_civicrm_caseTypes($caseTypes);
}

/**
 * Implements hook_civicrm_angularModules().
 *
 * Generate a list of Angular modules.
 *
 * Note: This hook only runs in CiviCRM 4.5+. It may
 * use features only available in v4.6+.
 *
 * @link http://wiki.civicrm.org/confluence/display/CRMDOC/hook_civicrm_caseTypes
 */
function sparkpost_civicrm_angularModules(&$angularModules) {
_sparkpost_civix_civicrm_angularModules($angularModules);
}

/**
 * Implements hook_civicrm_alterSettingsFolders().
 *
 * @link http://wiki.civicrm.org/confluence/display/CRMDOC/hook_civicrm_alterSettingsFolders
 */
function sparkpost_civicrm_alterSettingsFolders(&$metaDataFolders = NULL) {
  _sparkpost_civix_civicrm_alterSettingsFolders($metaDataFolders);
}

/**
 * Implementation of hook_civicrm_alterMailParams( )
 * Inserts SMTP headers for use in SparkPost API and subsequent bounce processing
 */
function sparkpost_civicrm_alterMailParams(&$params, $context) {
  sparkpost_debug('Hooked civicrm_alterMailParams');
  sparkpost_debug('params', $params);

  sparkpost_addOptionValues();
  sparkpost_mailingsCheck();

  // If this is a bulk email
  if($context == 'civimail') {
    $temphash = explode(CRM_Core_Config::Singleton()->verpSeparator, $params['Return-Path']);
    $hash = substr($temphash[3], 0, strpos($temphash[3], '@'));

    $mailEventQueue = civicrm_api3('MailingEventQueue', 'get', array(
      'sequential' => 1,
      'hash' => $hash
    ));

    // Prepare SparkPost metadata
    $mailing = sparkpost_mailing($hash);
    $campaign = mb_convert_encoding($mailing['name'], 'UTF-8', 'auto');

    if(mb_strlen($campaign, 'UTF-8') > 64) {
      $campaign = substr($campaign, 0, 64);
    }

    $tags = array(
      'campaign_id' => $campaign,
      'metadata' => array(
        'civi_type' => 'bulk',
        'civi_hash' => $hash,
        'civi_jobid' => $mailEventQueue['values'][0]['job_id'],
        'civi_queue' => $mailEventQueue['values'][0]['id']
      )
    );
  }

  // If this is a transactional email
  else {
    /**
     * The if-statement below is a temporary solution, until a bug which causes
     * the civicrm_alterMailParams hook to be ran twice is fixed.

     * The first time the hook runs, $params['subject'], $params['text'], and
     * $params['html'] is not set. We wait until it is set to execute our code.
     */
    if(isset($params['subject'])) {
      // If this is an offline transaction, get initiator's contact ID
      $session = CRM_Core_Session::singleton();
      $sourceContactID = $session->get('userID');
      sparkpost_debug('sourceContactID', $sourceContactID);

      // If this is an online transaction, get domain contact ID
      if (!$sourceContactID)
        $sourceContactID = CRM_Core_DAO::getFieldValue('CRM_Core_DAO_Domain', CRM_Core_Config::domainID(), 'contact_id');

      // Get target contact ID
      $targetContactID = sparkpost_getTargetContactId($params)[0];

      // Get activity type ID "Transactional Email"
      $activityType = civicrm_api3('OptionValue', 'get', array('sequential' => 1,'option_group_id' => 'activity_type','name' => 'Transactional Email'));
      $activityTypeID = $activityType['values'][0]['value'];
      sparkpost_debug('activityType', $activityType);

      // Get activity status ID for "Pending"
      $activityStatus = civicrm_api3('OptionValue', 'get', array('sequential' => 1,'option_group_id' => 'activity_status','name' => 'Pending'));
      $activityStatusID = $activityStatus['values'][0]['value'];<commit_msg>Fixed issue with duplicate activities created<commit_after><?php

require_once 'sparkpost.civix.php';

/**
 * Implements hook_civicrm_config().
 *
 * @link http://wiki.civicrm.org/confluence/display/CRMDOC/hook_civicrm_config
 */
function sparkpost_civicrm_config(&$config) {
  _sparkpost_civix_civicrm_config($config);
}

/**
 * Implements hook_civicrm_xmlMenu().
 *
 * @param array $files
 *
 * @link http://wiki.civicrm.org/confluence/display/CRMDOC/hook_civicrm_xmlMenu
 */
function sparkpost_civicrm_xmlMenu(&$files) {
  _sparkpost_civix_civicrm_xmlMenu($files);
}

/**
 * Implements hook_civicrm_install().
 *
 * @link http://wiki.civicrm.org/confluence/display/CRMDOC/hook_civicrm_install
 */
function sparkpost_civicrm_install() {
  _sparkpost_civix_civicrm_install();
}

/**
 * Implements hook_civicrm_uninstall().
 *
 * @link http://wiki.civicrm.org/confluence/display/CRMDOC/hook_civicrm_uninstall
 */
function sparkpost_civicrm_uninstall() {
  _sparkpost_civix_civicrm_uninstall();
}

/**
 * Implements hook_civicrm_enable().
 *
 * @link http://wiki.civicrm.org/confluence/display/CRMDOC/hook_civicrm_enable
 */
function sparkpost_civicrm_enable() {
  _sparkpost_civix_civicrm_enable();
  sparkpost_job_create();

  //Check and fix bad field type on civicrm_mailing_bounce_type.name
  $field_type  = CRM_Core_DAO::singleValueQuery("SELECT DATA_TYPE FROM INFORMATION_SCHEMA.COLUMNS WHERE table_name = 'civicrm_mailing_bounce_type' AND COLUMN_NAME = 'name'");
  $field_length  = CRM_Core_DAO::singleValueQuery("SELECT CHARACTER_MAXIMUM_LENGTH FROM INFORMATION_SCHEMA.COLUMNS WHERE table_name = 'civicrm_mailing_bounce_type' AND COLUMN_NAME = 'name'");

  if($field_type != 'varchar' || $field_length < 24) {
    CRM_Core_DAO::singleValueQuery("ALTER TABLE civicrm_mailing_bounce_type CHANGE name name VARCHAR(24) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL COMMENT 'Type of bounce'");
  }

  //Add bounce type and pattern to database
  if(!CRM_Core_DAO::singleValueQuery("SELECT count(id) as 'COUNT' FROM civicrm_mailing_bounce_type WHERE `name` = 'SparkPost'")) {
    CRM_Core_DAO::singleValueQuery("INSERT INTO `civicrm_mailing_bounce_type` (`name`, `description`, `hold_threshold`) VALUES ('SparkPost', 'SparkPost supression list', 1)");
    $bounce_type_id = CRM_Core_DAO::singleValueQuery("SELECT `id` FROM `civicrm_mailing_bounce_type` WHERE `name` = 'SparkPost' LIMIT 1");
    CRM_Core_DAO::singleValueQuery("INSERT INTO `civicrm_mailing_bounce_pattern` (`bounce_type_id`, `pattern`) VALUES ($bounce_type_id, 'recipient address suppressed due to customer policy')");
  }
  sparkpost_addOptionValues();
  sparkpost_mailingsCheck();

  Civi::settings()->set('com.pesc.sparkpost.debug', FALSE);
}

/**
 * Implements hook_civicrm_disable().
 *
 * @link http://wiki.civicrm.org/confluence/display/CRMDOC/hook_civicrm_disable
 */
function sparkpost_civicrm_disable() {
  _sparkpost_civix_civicrm_disable();
}

/**
 * Implements hook_civicrm_upgrade().
 *
 * @param $op string, the type of operation being performed; 'check' or 'enqueue'
 * @param $queue CRM_Queue_Queue, (for 'enqueue') the modifiable list of pending up upgrade tasks
 *
 * @return mixed
 *   Based on op. for 'check', returns array(boolean) (TRUE if upgrades are pending)
 *                for 'enqueue', returns void
 *
 * @link http://wiki.civicrm.org/confluence/display/CRMDOC/hook_civicrm_upgrade
 */
function sparkpost_civicrm_upgrade($op, CRM_Queue_Queue $queue = NULL) {
  return _sparkpost_civix_civicrm_upgrade($op, $queue);
}

/**
 * Implements hook_civicrm_managed().
 *
 * Generate a list of entities to create/deactivate/delete when this module
 * is installed, disabled, uninstalled.
 *
 * @link http://wiki.civicrm.org/confluence/display/CRMDOC/hook_civicrm_managed
 */
function sparkpost_civicrm_managed(&$entities) {
  _sparkpost_civix_civicrm_managed($entities);
}

/**
 * Implements hook_civicrm_caseTypes().
 *
 * Generate a list of case-types.
 *
 * @param array $caseTypes
 *
 * Note: This hook only runs in CiviCRM 4.4+.
 *
 * @link http://wiki.civicrm.org/confluence/display/CRMDOC/hook_civicrm_caseTypes
 */
function sparkpost_civicrm_caseTypes(&$caseTypes) {
  _sparkpost_civix_civicrm_caseTypes($caseTypes);
}

/**
 * Implements hook_civicrm_angularModules().
 *
 * Generate a list of Angular modules.
 *
 * Note: This hook only runs in CiviCRM 4.5+. It may
 * use features only available in v4.6+.
 *
 * @link http://wiki.civicrm.org/confluence/display/CRMDOC/hook_civicrm_caseTypes
 */
function sparkpost_civicrm_angularModules(&$angularModules) {
_sparkpost_civix_civicrm_angularModules($angularModules);
}

/**
 * Implements hook_civicrm_alterSettingsFolders().
 *
 * @link http://wiki.civicrm.org/confluence/display/CRMDOC/hook_civicrm_alterSettingsFolders
 */
function sparkpost_civicrm_alterSettingsFolders(&$metaDataFolders = NULL) {
  _sparkpost_civix_civicrm_alterSettingsFolders($metaDataFolders);
}

/**
 * Implementation of hook_civicrm_alterMailParams( )
 * Inserts SMTP headers for use in SparkPost API and subsequent bounce processing
 */
function sparkpost_civicrm_alterMailParams(&$params, $context) {
  sparkpost_debug('Hooked civicrm_alterMailParams');
  sparkpost_debug('params', $params);

  sparkpost_addOptionValues();
  sparkpost_mailingsCheck();

  // If this is a bulk email
  if($context == 'civimail') {
    $temphash = explode(CRM_Core_Config::Singleton()->verpSeparator, $params['Return-Path']);
    $hash = substr($temphash[3], 0, strpos($temphash[3], '@'));

    $mailEventQueue = civicrm_api3('MailingEventQueue', 'get', array(
      'sequential' => 1,
      'hash' => $hash
    ));

    // Prepare SparkPost metadata
    $mailing = sparkpost_mailing($hash);
    $campaign = mb_convert_encoding($mailing['name'], 'UTF-8', 'auto');

    if(mb_strlen($campaign, 'UTF-8') > 64) {
      $campaign = substr($campaign, 0, 64);
    }

    $tags = array(
      'campaign_id' => $campaign,
      'metadata' => array(
        'civi_type' => 'bulk',
        'civi_hash' => $hash,
        'civi_jobid' => $mailEventQueue['values'][0]['job_id'],
        'civi_queue' => $mailEventQueue['values'][0]['id']
      )
    );
  }
  // If this is a transactional email
  elseif($context == 'singleEmail') {
    /**
     * The if-statement below is a temporary solution, until a bug which causes
     * the civicrm_alterMailParams hook to be ran twice is fixed.

     * The first time the hook runs, $params['subject'], $params['text'], and
     * $params['html'] is not set. We wait until it is set to execute our code.
     */
    if(isset($params['subject'])) {
      // If this is an offline transaction, get initiator's contact ID
      $session = CRM_Core_Session::singleton();
      $sourceContactID = $session->get('userID');
      sparkpost_debug('sourceContactID', $sourceContactID);

      // If this is an online transaction, get domain contact ID
      if (!$sourceContactID)
        $sourceContactID = CRM_Core_DAO::getFieldValue('CRM_Core_DAO_Domain', CRM_Core_Config::domainID(), 'contact_id');

      // Get target contact ID
      $targetContactID = sparkpost_getTargetContactId($params)[0];

      // Get activity type ID "Transactional Email"
      $activityType = civicrm_api3('OptionValue', 'get', array('sequential' => 1,'option_group_id' => 'activity_type','name' => 'Transactional Email'));
      $activityTypeID = $activityType['values'][0]['value'];
      sparkpost_debug('activityType', $activityType);

      // Get activity status ID for "Pending"
      $activityStatus = civicrm_api3('OptionValue', 'get', array('sequential' => 1,'option_group_id' => 'activity_status','name' => 'Pending'));
      $activityStatusID = $activityStatus['values'][0]['value'];
{'fraction_non_alphanumeric': 0.13215773034877668, 'fraction_numerical': 0.0045549193128578865, 'mean_word_length': 4.959286545172548, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 39, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 8}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2826813', 'n_tokens_mistral': 5450, 'n_tokens_neox': 5273, 'n_words': 991}