/***
* 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