<commit_before><?php
/*-------------------------------------------------------+
| de.systopia.rcont - Analyse Recurring Contributions    |
| Copyright (C) 2016 SYSTOPIA                            |
| Author: <NAME> (<EMAIL>)                 |
| http://www.systopia.de/                                |
+--------------------------------------------------------+
| This program is released as free software under the    |
| Affero GPL license. You can redistribute it and/or     |
| modify it under the terms of this license which you    |
| can read by viewing the included agpl.txt or online    |
| at www.gnu.org/licenses/agpl.html. Removal of this     |
| copyright header is strictly prohibited without        |
| written permission from the original author(s).        |
+--------------------------------------------------------*/
 
/**
 * Configuration page for the Project60 Membership extension
 */
class CRM_Rcont_Sequence {

  protected $cycle;
  protected $most_recent_contribution;
  protected $cycle_day                = NULL;
  protected $minimum_cycle_day_offset = 0;
  protected $maximum_cycle_day_offset = 0;
  protected $cycle_day_offset_list    = array();
  protected $contribution_sequence    = array();
  protected $cycle_tolerance          = NULL;
  protected $max_skips                = 0;       // tolerate missing $max_skips periods
  protected $max_skip_time            = 0;       // tolerate a maximum of $max_skip_time seconds of skipped periods. 
  protected $hash                     = '';

  public static $identical_fields  = array(
    'financial_type_id'     => 'financial_type_id',
    'campaign_id'           => 'campaign_id',
    // 'payment_instrument_id' => 'payment_instrument_id',
    'contact_id'            => 'contact_id',
    'amount'                => 'total_amount',
    'currency'              => 'currency',
    );

  /**
   * create a new series with the most recent contribution
   */
  public function __construct($contribution, $cycle, $tolerance = '7 days', $max_skips = 0, $max_skip_days = NULL) {
    $this->cycle = $cycle;
    $this->cycle_tolerance = strtotime($tolerance, 0);
    $this->most_recent_contribution = $contribution;
    $this->contribution_sequence[] = $contribution;
    $this->cycle_day = date('d', strtotime($contribution['receive_date']));
    $this->cycle_day_offset_list[] = 0;
    $this->max_skips = (int) $max_skips;
    if ($max_skip_days === NULL) {
      // defaults to $cycle x ($max_skips+1) + $tolerance
      $this->max_skip_time = strtotime($cycle, 0) * ($this->max_skips + 1) + $this->cycle_tolerance;
      // error_log("SKIP time: " . $this->max_skip_time / 60 / 60 / 24);
    } else {
      $this->max_skip_time = strtotime("+{$max_skip_days} days", 0);
    }
  }

  /**
   * check if the sequence has enough entries to be considered a real sequence
   */
  public function isSequence($minimum_count = 5) {
    return count($this->contribution_sequence) >= $minimum_count;
  }

  /**
   * check if the given contribution matches the 
   * sequence.
   *
   * @return intervals (usually 1, but more if skip allowed). FALSE if it doesn't match
   */
  public function matches($contribution) {
    // first: without receive date there's nothing we can do
    if (empty($contribution['receive_date'])) {
      return FALSE;
    }

    // now: check if all values are identical
    foreach ($this->identical_fields as $field_name) {
      if ($contribution[$field_name] != $this->most_recent_contribution[$field_name]) {
        // error_log("FIELD MISMATCH");
        return FALSE;
      }
    }
<commit_msg>minor bugfix<commit_after><?php
/*-------------------------------------------------------+
| de.systopia.rcont - Analyse Recurring Contributions    |
| Copyright (C) 2016 SYSTOPIA                            |
| Author: <NAME> (<EMAIL>)                 |
| http://www.systopia.de/                                |
+--------------------------------------------------------+
| This program is released as free software under the    |
| Affero GPL license. You can redistribute it and/or     |
| modify it under the terms of this license which you    |
| can read by viewing the included agpl.txt or online    |
| at www.gnu.org/licenses/agpl.html. Removal of this     |
| copyright header is strictly prohibited without        |
| written permission from the original author(s).        |
+--------------------------------------------------------*/
 
/**
 * Configuration page for the Project60 Membership extension
 */
class CRM_Rcont_Sequence {

  protected $cycle;
  protected $most_recent_contribution;
  protected $cycle_day                = NULL;
  protected $minimum_cycle_day_offset = 0;
  protected $maximum_cycle_day_offset = 0;
  protected $cycle_day_offset_list    = array();
  protected $contribution_sequence    = array();
  protected $cycle_tolerance          = NULL;
  protected $max_skips                = 0;       // tolerate missing $max_skips periods
  protected $max_skip_time            = 0;       // tolerate a maximum of $max_skip_time seconds of skipped periods. 
  protected $hash                     = '';

  public static $identical_fields  = array(
    'financial_type_id'     => 'financial_type_id',
    'campaign_id'           => 'campaign_id',
    // 'payment_instrument_id' => 'payment_instrument_id',
    'contact_id'            => 'contact_id',
    'amount'                => 'total_amount',
    'currency'              => 'currency',
    );

  /**
   * create a new series with the most recent contribution
   */
  public function __construct($contribution, $cycle, $tolerance = '7 days', $max_skips = 0, $max_skip_days = NULL) {
    $this->cycle = $cycle;
    $this->cycle_tolerance = strtotime($tolerance, 0);
    $this->most_recent_contribution = $contribution;
    $this->contribution_sequence[] = $contribution;
    $this->cycle_day = date('d', strtotime($contribution['receive_date']));
    $this->cycle_day_offset_list[] = 0;
    $this->max_skips = (int) $max_skips;
    if ($max_skip_days === NULL) {
      // defaults to $cycle x ($max_skips+1) + $tolerance
      $this->max_skip_time = strtotime($cycle, 0) * ($this->max_skips + 1) + $this->cycle_tolerance;
      // error_log("SKIP time: " . $this->max_skip_time / 60 / 60 / 24);
    } else {
      $this->max_skip_time = strtotime("+{$max_skip_days} days", 0);
    }
  }

  /**
   * check if the sequence has enough entries to be considered a real sequence
   */
  public function isSequence($minimum_count = 5) {
    return count($this->contribution_sequence) >= $minimum_count;
  }

  /**
   * check if the given contribution matches the 
   * sequence.
   *
   * @return intervals (usually 1, but more if skip allowed). FALSE if it doesn't match
   */
  public function matches($contribution) {
    // first: without receive date there's nothing we can do
    if (empty($contribution['receive_date'])) {
      return FALSE;
    }

    // now: check if all values are identical
    foreach (self::$identical_fields as $field_name) {
      if ($contribution[$field_name] != $this->most_recent_contribution[$field_name]) {
        // error_log("FIELD MISMATCH");
        return FALSE;
      }
    }

{'fraction_non_alphanumeric': 0.16056769166550716, 'fraction_numerical': 0.007235285932934465, 'mean_word_length': 2.2747152619589976, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 50, 'https://': 0, 'lorem ipsum': 0, 'www.': 4, 'xml': 0}, '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': '2844301', 'n_tokens_mistral': 2192, 'n_tokens_neox': 2029, 'n_words': 547}