/***
 * Period tracker Algorithm 
 * Handles - User Period Settings, User Period data and User Period predictions
 * Migration script - fetch data from old table and insert them to the new tracker table
 * Tables : period_settings, user_period_tracker
 */
class PeriodPalAlgo
{
    private $conn;
    private $user_cycle_length;
    private $user_cycle_frequency;
    private $user_last_period_date;
    private $AVG_CYCLE_LENGTH = 5;
    private $CYCLE_FREQUENCY = 21;
    private $AVG_CYCLE_FREQUENCY = 28;
    private $FERTILE_START = 13;
    private $OVULATION_DAY = 6;
    private $curr_cycle = array();

    function __construct()
    {
        define('DB_HOST', 'laiqa-rds.cdrl0pybluwc.ap-south-1.rds.amazonaws.com');
        // define('DB_NAME', 'wordpress_production');
        // define('DB_USERNAME', 'production');
        // define('DB_PASSWORD', 'LaiqaProduction$1234');
        define('DB_NAME', 'periodpal_staging');
        define('DB_USERNAME', 'staging');
        define('DB_PASSWORD', 'LaiqaStaging$1234');
        try {
            $this->conn = new PDO("mysql:host=" . DB_HOST . ";dbname=" . DB_NAME . "", DB_USERNAME, DB_PASSWORD);
            $this->conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
            $this->conn->exec("set names utf8mb4");
        } catch (PDOException $e) {
            // echo "Connection failed: " . $e->getMessage();
            exit;
        }
    }

    function debug_data($variable)
    {
        // echo "
";
        // if (gettype($variable) == "array") {
        //     print_r($variable);
        // } else {
        //     echo $variable;
        // }
        // echo "
"; } # add days to the date provided and return date function get_date($current_date, $days_to_add, $subtract = '') { $generated_date = ''; if ($current_date != '' && $days_to_add != '' && $days_to_add != 0) { $add_days = ($days_to_add > 1) ? ($days_to_add - 1) : $days_to_add; $generated_date = date("Y-m-d 00:00:00", strtotime($current_date . " + " . $add_days . ' days')); } else if ($current_date != '' && $subtract != '' && $subtract != 0) { $generated_date = date("Y-m-d 00:00:00", strtotime($current_date . $subtract . ' days')); } return ($generated_date != "") ? date("Y-m-d", strtotime($generated_date)) : ''; // // $days_to_add = ($days_to_add == 1 && $days_to_add != 0 && $days_to_add != '') ? $days_to_add : ($days_to_add - 1); // if one day don't subtract // $days = ($days_to_add == 0) ? $subtract : "+" . $days_to_add; // $generated_date = ''; // if ($current_date != '' && $days != '' && $days != 0) { // // $add_days = $days_to_add - 1; // $generated_date = date("Y-m-d 00:00:00", strtotime($current_date . $days . ' days')); // return date("Y-m-d", strtotime($generated_date)); // } else { // $generated_date = date("Y-m-d 00:00:00", strtotime($current_date . " + " . $days_to_add . ' days')); // return date("Y-m-d", strtotime($generated_date)); // return ''; // } } #get user period settings function get_period_settings($user_id) { $arr_result = array(); $sql_period = "SELECT id,user_id,cycle_length, cycle_frequency,last_period_date FROM period_settings WHERE user_id = '" . $user_id . "' "; $stmt_period = $this->conn->query($sql_period, PDO::FETCH_ASSOC); // $stmt_period->execute(); $arr_result = $stmt_period->fetch(); if (is_array($arr_result) && count($arr_result) != 0) { $this->user_cycle_frequency = ($arr_result['cycle_frequency'] != '' && $arr_result['cycle_frequency'] != 0) ? $arr_result['cycle_frequency'] : $this->AVG_CYCLE_FREQUENCY; $this->user_cycle_length = ($arr_result['cycle_length'] != '' && $arr_result['cycle_length'] != 0) ? $arr_result['cycle_length'] : $this->AVG_CYCLE_LENGTH; $this->user_last_period_date = $arr_result['last_period_date']; $arr_result['status'] = 1; } else { $this->user_cycle_frequency = $this->AVG_CYCLE_FREQUENCY; $this->user_cycle_length = $this->AVG_CYCLE_LENGTH; $this->user_last_period_date = ''; } return $arr_result; } #function to generate fertile window and ovulation for user function generate_fertile_period($start_period_date) { $arr_period_data = array(); // calculate ovulation interval based on cycle length ( difference between average 28 cycle and user provided cycle) $ovulation_day_interval = abs($this->CYCLE_FREQUENCY - $this->user_cycle_frequency) + $this->OVULATION_DAY; // Ovulation date = Start Date + 14 ( Day 14 for average 28days cycle), $arr_period_data['ovulation_date'] = $this->get_date($start_period_date, $ovulation_day_interval); // Fertile window = 5 before ovulation + ovulation day + one day after ovulation $arr_period_data['fertility_start'] = $this->get_date($arr_period_data['ovulation_date'], 0, -5); $arr_period_data['fertility_end'] = $this->get_date($arr_period_data['ovulation_date'], 1, 0); // $arr_period_data['fertility_start'] = date("Y-m-d 00:00:00", strtotime($arr_period_data['ovulation_date'] . '- 4 days')); // $arr_period_data['fertility_end'] = date("Y-m-d 00:00:00", strtotime($arr_period_data['ovulation_date'] . " + 1 days")); // Fertile period ends on ovulation day return $arr_period_data; } #function to generate predictions function generate_prediction($last_period_date, $prediction_count) { $prediction_start = $last_period_date; $last_data = $this->fetch_period_data($last_period_date, $this->curr_cycle['user_id']); $cycle_number = (is_array($last_data) && count($last_data) != 0) ? $last_data['cycle_number'] : 0; #TODO : Data Analysis to be done to learn pattern and change predictions $arr_prediction_data = array(); for ($i = 0; $i < $prediction_count; $i++) { $fertile_data = array(); $arr_prediction_data[$i]['user_id'] = $this->curr_cycle['user_id']; $arr_prediction_data[$i]['start_date'] = $this->get_date($last_period_date, $this->user_cycle_frequency); // prediction start date $temp_start_date = $arr_prediction_data[$i]['start_date']; $arr_prediction_data[$i]['end_date'] = $this->get_date($temp_start_date, $this->user_cycle_length); // prediction end date $arr_prediction_data[$i]['last_period_date'] = $prediction_start; $arr_prediction_data[$i]['predicted_data'] = 1; $arr_prediction_data[$i]['cycle_number'] = ++$cycle_number; #temporary check for migrating old data $today = date("Y-m-d"); $current_start = (date('Ym') == date('Ym', strtotime($temp_start_date))); $current_end = (date('Ym') == date('Ym', strtotime($arr_prediction_data[$i]['end_date']))); $last_month_start = (date('Ym', strtotime(date('Ym') . " -1 month")) == date('Ym', strtotime($temp_start_date))); $last_month_end = (date('Ym', strtotime(date('Ym') . " -1 months")) == date('Ym', strtotime($arr_prediction_data[$i]['end_date']))); $prev_month_start = (date('Ym', strtotime(date('Ym') . " -2 months")) == date('Ym', strtotime($temp_start_date))); $prev_month_end = (date('Ym', strtotime(date('Ym') . " -2 months")) == date('Ym', strtotime($arr_prediction_data[$i]['end_date']))); $month_diff_start = round(abs(strtotime($temp_start_date) - strtotime('today +2 months')) / (30 * 60 * 60 * 24)); $month_diff_end = round(abs(strtotime($arr_prediction_data[$i]['end_date']) - strtotime('today +2 months')) / (30 * 60 * 60 * 24)); // if ($current_start == TRUE || $current_end == TRUE || $last_month_start == TRUE || $last_month_end == TRUE || $prev_month_start == TRUE || $prev_month_end == TRUE) { #temporary check for migrating old data if ($month_diff_start <= 4 || $month_diff_end <= 4) { #generate fertile window and ovulation $fertile_data = $this->generate_fertile_period($temp_start_date); $arr_prediction_data[$i] = array_merge($arr_prediction_data[$i], $fertile_data); $this->save_data($arr_prediction_data[$i]); // save prediction to database $last_period_date = $arr_prediction_data[$i]['start_date']; // set predicted start date as last period date } else { $last_period_date = $arr_prediction_data[$i]['start_date']; // set predicted start date as last period date unset($arr_prediction_data[$i]); # needn't insert predictions for old months } // $last_period_date = $arr_prediction_data[$i]['start_date']; // set predicted start date as last period date } return $arr_prediction_data; } # check for abnormal data function check_if_abnormal($user_id, $start_date) { $arr_prev_data = $this->get_last_period_data($user_id, $start_date); if ($this->curr_cycle['is_abnormal'] == 0) { //generate fertile window and ovulation for normal data $fertile_data = $this->generate_fertile_period($start_date); $this->curr_cycle = array_merge($this->curr_cycle, $fertile_data); } // increment cycle number only if cycle number is not available $this->curr_cycle['cycle_number'] = ($this->curr_cycle['cycle_number'] == '') ? ($arr_prev_data['cycle_no'] + 1) : $this->curr_cycle['cycle_number']; } # delete predictions after the updated cycle to regenerated them using user provided start date function delete_predictions($user_id, $cycle_number, $start_date) { $sql_period_data = "DELETE FROM user_period_tracker where last_period_date='" . $start_date . "' and predicted_data = 1 "; // echo $sql_period_data; $stmt_period_data = $this->conn->query($sql_period_data, PDO::FETCH_ASSOC); // $stmt_period_data->execute(); // $result = $stmt_period_data->fetchAll(); } # get last user entered data function get_last_period_data($user_id, $current_start_date) { $sql_period_data = "SELECT start_date FROM `user_period_tracker` where user_id = " . $user_id . " AND predicted_data = 0 ORDER BY id desc"; $stmt_period_data = $this->conn->query($sql_period_data, PDO::FETCH_ASSOC); // $stmt_period_data->execute(); $result = $stmt_period_data->fetch(); if (is_array($result) && count($result) != 0) { $this->curr_cycle['last_period_date'] = $prev_data["last_period_date"] = $last_period_date = $result['start_date']; $prev_data['cycle_no'] = $result['user_cycle_nos']; // compare month of last period date and current start date // check difference between the dates in months $date_diff = abs(strtotime($last_period_date) - strtotime($current_start_date)); $month_diff = round($date_diff / 30 / 60 / 60 / 24); if ($month_diff == 1) { // if data is previous month date # period cycle less than 21 and greator than 35 days are marked abnormal and fertile date is not generated $this->curr_cycle['is_abnormal'] = (($date_diff / (60 * 60 * 24) > 35) && ($date_diff / (60 * 60 * 24) > 21)) ? 1 : 0; } } else { // no previous user data available - first time user $prev_data['cycle_no'] = 0; $this->curr_cycle['is_abnormal'] = 0; $this->curr_cycle['last_period_date'] = ''; } } # check if predictions exist till today if not generated function check_predictions($start_date, $end_date, $user_id, $id) { $arr_predictions = array(); $period_counts = $this->fetch_period_data($start_date, $user_id, $id, 'count'); if ($period_counts['predicted_data'] == 0 && $period_counts['user_data'] == 0) { //Scenario #1: First Cycle of the user/new user # difference in months $month_diff = round(abs(strtotime($start_date) - strtotime('today +2 months')) / (30 * 60 * 60 * 24)); $arr_generated_predictions = $this->generate_prediction($start_date, $month_diff); $this->curr_cycle["predictions"] = $arr_generated_predictions; } } # fetch future predictions from the data provided function fetch_period_data($start_date, $user_id, $id = '', $count = '') { $arr_data = array(); if ($user_id != '' && $user_id != 0) { if ($count == 'count' && $id != '') { $sql_period_data = "SELECT predicted_data, count(*) as count FROM `user_period_tracker` where user_id = " . $user_id . " AND id != " . $id . " AND `start_date` >= '" . $start_date . "' GROUP BY predicted_data"; } else if ($start_date != '') { $sql_period_data = "SELECT * FROM `user_period_tracker` where user_id = " . $user_id . " AND `start_date` = '" . $start_date . "'"; } else if ($id != 0) { $sql_period_data = "SELECT * FROM `user_period_tracker` where user_id = " . $user_id . " AND `id` = '" . $id . "'"; } $stmt_period_data = $this->conn->query($sql_period_data, PDO::FETCH_ASSOC); $stmt_period_data->execute(); $result = $stmt_period_data->fetchAll(); if (is_array($result)) { if ($count == 'count') { foreach ($result as $count) { if ($count['predicted_data'] == 1) { $arr_data['predicted_data'] = $count['count']; } else { $arr_data['user_data'] = $count['count']; } } return $arr_data; } else { return $result[0]; } } else { return 0; } } else { return 0; } } #get last period date of user //function generate_period_data($user_id, $start_date, $end_date, $id) function generate_period_data($user_id, $start_date, $end_date, $id) { $this->curr_cycle['user_id'] = $user_id; $this->curr_cycle['start_date'] = $start_period_date = $start_date; $arr_period_settings = $this->get_period_settings($user_id); // get the period length and calculate end date if only start date is available( applicable for first user or when user logs current period data) if ($start_date != '' && $end_date == "") { $this->curr_cycle['end_date'] = $end_date = $this->get_date($start_date, $this->user_cycle_length); } else if ($end_date != '') { $this->curr_cycle['end_date'] = $end_date; } # Current Period length $this->curr_cycle['period_length'] = ($start_date != '' && $end_date != '') ? abs(strtotime($start_date) - strtotime($end_date)) / 60 / 60 / 24 : $this->user_cycle_length; } # update current cycle as 1 and other user records to 0 function set_current_cycle_flag($id) { $update_query = " UPDATE user_period_tracker SET is_current_cycle = 0 WHERE id != " . $id; $stmt_update = $this->conn->prepare($update_query); $stmt_update->execute(); } # save period data to database function save_data($arr_data, $id = 0) { $this->debug_data("Save period data"); $last_data = array(); $arr_fields = array("user_id", "start_date", "end_date", "fertility_start", "fertility_end", "ovulation_date", "is_abnormal", "is_current_cycle", "cycle_number", "predicted_data", "last_period_date"); //"created_date","created_by","updated_date","updated_by" if (is_array($arr_data) && count($arr_data) != 0) { foreach ($arr_fields as $field) { if ($id == 0) { $arr_db_data[$field] = $arr_data[$field]; } else { $arr_db_data[] = $field . " = '" . $arr_data[$field] . "'"; } } $last_data = $this->fetch_period_data($arr_data['start_date'], $arr_data['user_id'], '', 'count'); # check if data exists to avoid duplicate entry $data_exists = (is_array($last_data) && count($last_data) != 0 && ($last_data['predicted_data'] != 0) && $last_data['user_data'] != 0) ? 1 : 0; $this->debug_data($data_exists); $this->debug_data($last_data); if (($id == '' || $id == 0) && $data_exists == 0) { $str_data = implode("','", array_values($arr_db_data)); $str_fields = implode(",", array_keys($arr_db_data)); $insert_query = "INSERT INTO user_period_tracker (" . $str_fields . ") VALUES ('" . $str_data . "')"; $stmt_insert = $this->conn->prepare($insert_query); $this->debug_data($insert_query); $stmt_insert->execute(); return $this->conn->lastInsertId(); } else if ($id != 0) { $str_fields = implode(",", array_values($arr_db_data)); $update_query = "UPDATE user_period_tracker SET " . $str_fields . " WHERE id = " . $id . ""; $stmt_update = $this->conn->prepare($update_query); $stmt_update->execute(); $this->debug_data($update_query); $this->curr_cycle['new_start_date'] = $arr_data['start_date']; return $id; } } } // #save period data to database // function save_period($user_id, $start_date, $end_date, $id = 0) // { // // echo "save period
"; // #start_date, end_date, period_length, is_abnormal, is_current_cycle, cycle_no // // first time entry // $this->generate_period_data($user_id, $start_date, $end_date, $id); // #TODO : save current cycle to database // print_r($this->curr_cycle); // } #get user period settings function save_period_settings($arr_data) { $arr_db_data = array(); $arr_settings = $this->get_period_settings($arr_data['user_id']); # check if record exists to avoid duplicate entry $setting_exists = (is_array($arr_settings) && count($arr_settings) != 0) ? 1 : 0; if ($setting_exists == 1) { $arr_data['id'] = $arr_settings['id']; } $setting_id = (isset($arr_data['id']) && $arr_data['id'] != '') ? $arr_data['id'] : 0; $arr_settings_fields = array("user_id", "cycle_length", "cycle_frequency", "last_period_date"); if (is_array($arr_data) && count($arr_data) != 0 && $setting_id == 0 && $setting_exists == 0) { $arr_db_data['user_id'] = isset($arr_data['user_id']) ? $arr_data['user_id'] : 0; $arr_db_data['last_period_date'] = isset($arr_data['last_period_date']) ? $arr_data['last_period_date'] : 0; $arr_db_data['cycle_length'] = isset($arr_data['cycle_length']) ? $arr_data['cycle_length'] : $this->AVG_CYCLE_LENGTH; $arr_db_data['cycle_frequency'] = isset($arr_data['cycle_frequency']) ? $arr_data['cycle_frequency'] : $this->AVG_CYCLE_FREQUENCY; $arr_db_data['created_date'] = date("Y-m-d H:i:s"); $str_data = implode("','", array_values($arr_db_data)); $str_fields = implode(",", array_keys($arr_db_data)); if ($setting_id == 0 && $setting_id == '') { $insert_query = "INSERT INTO period_settings (" . $str_fields . ") VALUES ('" . $str_data . "')"; $stmt_insert = $this->conn->prepare($insert_query); $stmt_insert->execute(); $this->debug_data($insert_query); } } else { $str_field_data = ''; unset($arr_data['id']); foreach ($arr_settings_fields as $field) { if (isset($arr_data[$field])) { $arr_db_data[] = $field . "='" . $arr_data[$field] . "'"; } } // update period settings $str_field_data = implode(",", $arr_db_data); $update_query = " UPDATE period_settings SET " . $str_field_data . " WHERE id = " . $setting_id; $this->debug_data($update_query); $stmt_update = $this->conn->prepare($update_query); $stmt_update->execute(); return $setting_id; } } function check_current_month() { $today = date("Y-m-d"); // print_r($this->curr_cycle); // start or end date in current month // (date('Ym') == date('Ym', strtotime($arr_request['start_date'])) // fertile start - end date in current month // print_r($this->curr_cycle); } # fetch request and execute the flow function request_controller($arr_request) { $this->curr_cycle['user_id'] = $user_id = $arr_request['user_id']; $arr_period_fields = array("user_i", "start_date", "end_date", "id", "cycle_number"); $arr_new_user_fields = array("last_period_date", "cycle_length", "cycle_frequency"); $flow = $arr_request['flag']; switch ($flow) { case 'new_user': #TODO : Stop multiple entries in user period tracker table. don't insert predictions and user data if already available. $this->curr_cycle["is_current_cycle"] = 1; $this->curr_cycle["cycle_number"] = 1; $this->save_period_settings($arr_request); $start_date = $arr_request['last_period_date']; $id = 0; $end_date = $arr_request['end_date']; $this->generate_period_data($user_id, $start_date, '', ''); $this->check_if_abnormal($user_id, $start_date); # check if abnormal data $id = $this->save_data($this->curr_cycle, $id); # save the period data to database $this->check_predictions($start_date, $end_date, $user_id, $id); # check if prediction exists $arr_response['status'] = 1; $arr_response['message'] = "Data Saved"; break; case 'edit_cycle': $status = 1; $message = ''; $today = date("Y-m-d"); if (isset($arr_request['start_date']) && ($arr_request['start_date'] > $today)) { $status = 0; $message = " Period Start Date cannot be greator than current date"; } else if (isset($arr_request['end_date']) && $arr_request['end_date'] > $today) { $status = 0; $message = " Period End Date cannot be greator than current date"; } else if (isset($arr_request['end_date']) && isset($arr_request['start_date']) && ($arr_request['start_date'] >= $arr_request['end_date'])) { $status = 0; $message = " Period Start Date cannot be greator than period end date"; } if ($status != 0) { $id = $arr_request['id']; $this->curr_cycle = $arr_request; // assign the provided by user $arr_period_settings = $this->get_period_settings($user_id); # if start date or end date in current month - mark it as current cycle $current_start = ((date('Ym') == date('Ym', strtotime($arr_request['start_date']))) || ($arr_request['start_date'] <= $today)) ? 1 : 0; $current_end = ((date('Ym') == date('Ym', strtotime($arr_request['end_date']))) || ($arr_request['end_date'] <= $today)) ? 1 : 0; $old_data = $this->fetch_period_data('', $user_id, $id); if (is_array($old_data) && count($old_data) != 0) { $old_cycle_number = $old_data['cycle_number']; $old_start_date = $old_data['start_date']; if ($old_data['predicted_data'] == 1) { $this->curr_cycle['predicted_data'] = 0; $this->curr_cycle['last_period_date'] = '0000-00-00'; $prediction_start_changed = ($old_data['start_date'] == $arr_request['start_date']) ? 0 : 1; } else { $this->curr_cycle['last_period_date'] = '0000-00-00'; $user_start_changed = ($old_data['start_date'] == $arr_request['start_date']) ? 0 : 1; } // $this->curr_cycle['is_current_cycle'] = (($current_start == TRUE || $current_end == TRUE)) ? 1 : $old_data['is_current_cycle']; // set current cycle if start or end date is within today $this->curr_cycle['is_current_cycle'] = $old_data['is_current_cycle']; $this->curr_cycle['cycle_number'] = $old_data['cycle_number']; } $this->check_if_abnormal($user_id, $arr_request['start_date']); # check if abnormal data $id = $this->save_data($this->curr_cycle, $id); # save the period data to database $this->set_current_cycle_flag($id); # update current cycle for others except current record // existing user data start date changed or prediction data changed to user data && start date is different if ($prediction_start_changed == TRUE || $user_start_changed == TRUE) { if ($old_start_date != "") { # delete predictions of user post the cycle $del_count = $this->delete_predictions($user_id, $old_cycle_number, $old_start_date); } $this->check_predictions($arr_request['start_date'], $arr_request['end_date'], $user_id, $id); # check if prediction exists $arr_period_settings['last_period_date'] = $arr_request['start_date']; $this->save_period_settings($arr_period_settings); // update the last period data } if ($this->curr_cycle["end_date"] == '' || $this->curr_cycle["end_date"] == "0000-00-00") { $this->curr_cycle["end_date"] = $this->get_date($this->curr_cycle["start_date"], $this->user_cycle_length); } $this->check_current_month($this->curr_cycle); $id = $this->save_data($this->curr_cycle, $id); # save the period data to database } $arr_response['status'] = $status; $arr_response['message'] = ($message == '') ? "Data Updated Successfully" : $message; $arr_response['data'] = $this->curr_cycle; break; case 'edit_setting': $this->save_period_settings($arr_request); $arr_period_settings = $this->get_period_settings($user_id); if (is_array($arr_period_settings) && count($arr_period_settings) != 0) { $start_date = $arr_period_settings['last_period_date']; } $this->delete_predictions($user_id, '', $start_date); $this->check_predictions($start_date, 0, $user_id, 0); $arr_response['status'] = 1; $arr_response['message'] = "Data Updated Successfully"; $arr_response['data'] = $this->curr_cycle; break; case "get_cycle_data": $id = isset($arr_request['id']) ? $arr_request['id'] : 0; $limit = isset($arr_request['limit']) ? $arr_request['limit'] : ''; $user_id = isset($arr_request['user_id']) ? $arr_request['user_id'] : 0; $current_cycle = isset($arr_request['current_cycle']) ? $arr_request['current_cycle'] : ""; $this->debug_data("USER ID" . $user_id); if ($user_id != '' && $user_id != 0) { $arr_period_data = $this->get_user_period_cycles($user_id, $id, $limit, $current_cycle); // print_r($arr_period_data); $arr_response['status'] = 1; $arr_response['message'] = "Data Provided"; $arr_response['data'] = (is_array($arr_period_data) && count($arr_period_data) != 0) ? $arr_period_data : "Period Data Not available"; } else { $arr_response['status'] = 0; $arr_response['message'] = "User ID missing"; } break; case "get_period_settings": $arr_settings = $this->get_period_settings($user_id); // $arr_response['status'] = 1; //updated status by vidhya $arr_response['status'] = (is_array($arr_settings)) ? 1 : 0; $arr_response['data'] = $arr_settings; $arr_response['message'] = "User Period Settings"; break; case "get_period_calendar": $id = isset($arr_request['id']) ? $arr_request['id'] : 0; $limit = isset($arr_request['limit']) ? $arr_request['limit'] : ''; $user_id = isset($arr_request['user_id']) ? $arr_request['user_id'] : 0; $this->debug_data("USER ID" . $user_id); if ($user_id != '' && $user_id != 0) { $arr_period_data = $this->get_user_period_calendar($user_id, $id, $limit); $arr_response['status'] = 1; $arr_response['message'] = "Data Provided"; $arr_response['data'] = (is_array($arr_period_data) && count($arr_period_data) != 0) ? $arr_period_data : "Period Data Not available"; } else { $arr_response['status'] = 0; $arr_response['message'] = "User ID missing"; } break; } $arr_response['data'] = isset($arr_response['data']) ? $arr_response['data'] : $this->curr_cycle; $this->debug_data($arr_response); return json_encode($arr_response); } // Function to get all the dates in given range function getDatesFromRange($start, $end, $format = 'Y-m-d') { // Declare an empty array $array = array(); // Variable that store the date interval // of period 1 day $interval = new DateInterval('P1D'); $realEnd = new DateTime($end); $realEnd->add($interval); $period = new DatePeriod(new DateTime($start), $interval, $realEnd); // Use loop to store date into array foreach ($period as $date) { $array[] = $date->format($format); } // Return the array elements return $array; } // formating period data as required for app calendar function generate_period_calendar($arr_period, $flag) { switch ($flag) { case 'period': $arr_date_range = $this->getDatesFromRange($arr_period['start_date'], $arr_period['end_date']); break; case 'fertile': $arr_date_range = $this->getDatesFromRange($arr_period['fertility_start'], $arr_period['fertility_end']); break; } $length = count($arr_date_range); for ($i = 0; $i < $length; $i++) { if ($flag == "period") { $day = ($i + 1); $arr_period_data['id'] = $arr_period['id']; $arr_period_data['day'] = " Period Day " . $day; } else if ($flag == "fertile") { $arr_period_data['ovulation'] = ($arr_period['ovulation'] == $arr_date_range[$i]) ? 1 : 0; $arr_period_data['cur_month'] = $arr_period['is_current_cycle']; } $arr_period_data['date'] = $arr_date_range[$i]; $arr_period_data['prediction_user_data'] = $arr_period['predicted_data']; } // print_r($arr_period_data); return $arr_period_data; } # get cycles of user as per filters provided - single or multiple records function get_user_period_cycles($user_id, $id = 0, $limit = '5', $current_cycle = '') { $arr_data = array(); $str_where = ''; $arr_str_where = array(); if (isset($id) && $id != 0) { $arr_str_where[] = " id = " . $id; } if (isset($user_id) && $user_id != 0) { $arr_str_where[] = " user_id = " . $user_id; } if ($limit == 'all') { $arr_str_where[] = " predicted_data = 0"; } else { $limit = ($limit == '5') ? " LIMIT 5" : ' '; } if ($current_cycle == '1') { $arr_str_where[] = " is_current_cycle = 1"; $limit = ''; } if (is_array($arr_str_where) && count($arr_str_where) != 0) { $str_where = implode(" AND ", $arr_str_where); } $sql_period_data = "SELECT id,start_date, end_date, fertility_start,fertility_end,ovulation_date,predicted_data,cycle_number,is_current_cycle FROM `user_period_tracker` where " . $str_where . " order by start_date desc " . $limit; // echo $sql_period_data; // exit; $stmt_period_data = $this->conn->query($sql_period_data, PDO::FETCH_ASSOC); // $this->debug_data($sql_period_data); $stmt_period_data->execute(); $arr_cycles = $stmt_period_data->fetchAll(); if (is_array($arr_cycles) && count($arr_cycles) != 0) { foreach ($arr_cycles as $key => $cycle) { $arr_data[$key] = $cycle; $current_cycle = (date('Ym') == date('Ym', strtotime($cycle['start_date']))) ? 1 : 0; $cycle_end = date(" F j Y ", strtotime($arr_cycles[$key + 1]['start_date'] . '-1 days')); if ($current_cycle) { $arr_data[$key]['cycle_name'] = " Current Cycle "; } else { $arr_data[$key]['cycle_name'] = date(" F j Y ", strtotime($arr_cycles[$key - 1]['start_date'] . '-1 days')) . " - " . date("F j Y", strtotime($cycle['start_date'])); } } } return $arr_data; } # get cycles of user for calendar display function get_user_period_calendar($user_id, $id = 0, $limit = '5', $flag = '') { // echo "get_user_period_cycles_new"; $arr_data = array(); $str_where = ''; $arr_str_where = array(); if (isset($id) && $id != 0) { $arr_str_where[] = " id = " . $id; } if (isset($user_id) && $user_id != 0) { $arr_str_where[] = " user_id = " . $user_id; } if ($limit == 'all') { $arr_str_where[] = " predicted_data = 0"; } if (is_array($arr_str_where) && count($arr_str_where) != 0) { $str_where = implode(" AND ", $arr_str_where); } $limit = ($limit == '5') ? " LIMIT 5" : ' '; $sql_period_data = "SELECT id,start_date, end_date, fertility_start,fertility_end,ovulation_date,predicted_data,cycle_number,is_current_cycle FROM `user_period_tracker` where " . $str_where . " order by start_date desc " . $limit; echo $sql_period_data; die; $stmt_period_data = $this->conn->query($sql_period_data, PDO::FETCH_ASSOC); // $this->debug_data($sql_period_data); $stmt_period_data->execute(); $arr_cycles = $stmt_period_data->fetchAll(); if (is_array($arr_cycles) && count($arr_cycles) != 0) { foreach ($arr_cycles as $key => $cycle) { // period array $period_data_array[$key] = $this->generate_period_calendar($cycle, 'period'); // fertile start - end $fertile_window_array[$key]['from_date'] = $cycle['fertility_start']; $fertile_window_array[$key]['to_date'] = $cycle['fertility_end']; $fertile_window_array[$key]['prediction_user_data'] = $cycle['predicted_data']; // ovulation dates $ovulation_data_array[$key]['ovu_date'] = $cycle['ovulation_date']; $ovulation_data_array[$key]['prediction_user_data'] = $cycle['predicted_data']; // start and end dates $next_period_array[$key]['date'] = $cycle['start_date']; $next_period_array[$key]['to_date'] = $cycle['end_date']; $next_period_array[$key]['prediction_user_data'] = $cycle['predicted_data']; // fertile start to end dates $fertile_data_array[$key] = $this->generate_period_calendar($cycle, 'fertile'); // $arr_data[$key]['period_date_array'] = $this->generate_period_calendar($cycle); // $arr_data[$key]['fertile_window']['from_date'] = $cycle['fertility_start']; // $arr_data[$key]['fertile_window']['to_date'] = $cycle['fertility_end']; // $arr_data[$key]['fertile_window']['prediction_user_data'] = $cycle['fertility_end']; $current_cycle = (date('Ym') == date('Ym', strtotime($cycle['predicted_data']))) ? 1 : 0; if ($limit > 5 || $limit == 'all') { if ($current_cycle) { $arr_data[$key]['cycle_name'] = " Current Cycle "; } else { $arr_data[$key]['cycle_name'] = date("F j Y", strtotime($cycle['start_date'])) . " - " . date(" F j Y ", strtotime($arr_cycles[$key - 1]['start_date'] . '-1 days')); } } } } $arr_data['period_date_array'] = $period_data_array; $arr_data['fertile_window'] = $fertile_window_array; $arr_data['ovulation'] = $ovulation_data_array; $arr_data['next_period'] = $next_period_array; $arr_data['fertile_data'] = $fertile_data_array; // print_r($arr_data); return $arr_data; } ### Run after removing all the records in user period tracker table -- only for migrating old data to new table ### function import_old_data() { $arr_users = array(); $sql_period = "SELECT DISTINCT(user_id) FROM user_period_tracking"; $stmt_period = $this->conn->query($sql_period, PDO::FETCH_ASSOC); // // $stmt_period->execute(); $arr_users = $stmt_period->fetchAll(); // $this->debug_data($arr_users); // exit; if (is_array($arr_users) && count($arr_users) != 0) { $this->curr_cycle["cycle_number"] = 1; foreach ($arr_users as $user) { $user_id = $user['user_id']; $this->debug_data(" START --- Migrate user period records for ---" . $user_id); //save all user period entries $sql_period = "SELECT * FROM user_period_tracking where user_flag=1 AND user_id=" . $user_id . " order by last_periods asc"; $stmt_period = $this->conn->query($sql_period, PDO::FETCH_ASSOC); // $arr_all_data = $stmt_period->fetchAll(); $row_count = count($arr_all_data); if (is_array($arr_all_data) && count($arr_all_data) != 0) { foreach ($arr_all_data as $key => $user_data) { // $this->period_from_old_data($user_data); $this->curr_cycle['user_id'] = $user_id; $this->curr_cycle['start_date'] = $start_date = $user_data['last_periods']; $this->curr_cycle['end_date'] = $user_data['last_period_to']; $this->user_cycle_frequency = $user_data['how_long_periods']; $this->check_if_abnormal($user_id, $start_date); $id = $this->save_data($this->curr_cycle, $id = 0); } } $this->debug_data(" --- SAVE Period Settings ---" . $user_id); // if last record add it as last period date and settings for the user $arr_last_data = $arr_all_data[$row_count - 1]; if (is_array($arr_last_data) && count($arr_last_data) != 0) { $arr_request['user_id'] = $arr_last_data['user_id']; $arr_request['last_period_date'] = $start_date = $arr_last_data['last_periods']; $arr_request['cycle_length'] = $period_length = $arr_last_data['period_lasts']; $arr_request['cycle_frequency'] = $period_frequency = $arr_last_data['how_long_periods']; // $this->curr_cycle["is_current_cycle"] = 1; // $this->curr_cycle["cycle_number"] = 1; $this->save_period_settings($arr_request); unset($arr_last_data); $this->curr_cycle['user_id'] = $user_id; $month_diff = round(abs(strtotime($start_date) - strtotime('today +2 months')) / (30 * 60 * 60 * 24)); $this->debug_data(" --- SAVE Predictions ---" . $user_id); $arr_generated_predictions = $this->generate_prediction($start_date, $month_diff); $this->curr_cycle["predictions"] = $arr_generated_predictions; } } $this->debug_data(" END --- Migration for ---" . $user_id); } } }
Fatal error: Uncaught Error: Class 'PeriodPalAlgo' not found in /var/www/html/stagingapi.periodpal.in/tracker_algorithm/index.php:65 Stack trace: #0 {main} thrown in /var/www/html/stagingapi.periodpal.in/tracker_algorithm/index.php on line 65