Getting endless loop in PHP - php

Whenever i try to run this code, it seems like it gets into an endless loop. But, i cant figure out whats causing this problem. Maybe an extra eye on the thing would be able do point out the problem?
The problem only accours when there is a different year zone, example 2012-2018
Example: $this->budget_model->set_monthly_budget('1','2012', '8','2014','1');
function set_monthly_budget($start_month, $start_year, $end_month, $end_year, $budget_group_id)
{
$user_id = 2;
// Current date
$current_month = $start_month;
$current_year = $start_year;
$days_in_current_month = cal_days_in_month(CAL_GREGORIAN, $current_month, $current_year);
$company_id = 1;
$month_goal = 100;
// Check if it is the current month
if($start_year == $end_year)
{
for($x=$current_month;$x<=$end_month;$x++)
{
$data = array(
'user_id' => $user_id,
'budget_group_id' => $budget_group_id,
'month' => $x,
'year' => $start_year,
'company_id' => $company_id,
'month_goal' => $month_goal
);
// Inserting information into the database
$this->db->insert('budget_month',$data);
}
return true; // Return true if the task was completed
}
if($start_year !== $end_year)
{
$temp_start_year = $start_year;
while($temp_start_year !== $end_year)
{
// Check if we are in the same year as we started
if($temp_start_year == $current_year)
{
// Insert remaining months for this year
for($x=$current_month;$x<=12;$x++)
{
$data = array(
'user_id' => $user_id,
'budget_group_id' => $budget_group_id,
'month' => $x,
'year' => $temp_start_year,
'company_id' => $company_id,
'month_goal' => $month_goal
);
// Inserting information into the database
$this->db->insert('budget_month',$data);
}
}
// Check if the temp and end year is the same
if($temp_start_year < $end_year)
{
// Insert remaining months for this year
for($x=1;$x<=12;$x++)
{
$data = array(
'user_id' => $user_id,
'budget_group_id' => $budget_group_id,
'month' => $x,
'year' => $temp_start_year,
'company_id' => $company_id,
'month_goal' => $month_goal
);
// Inserting information into the database
$this->db->insert('budget_month',$data);
}
}
// Check if we are in the same year as we started
if($temp_start_year == $end_year)
{
// Insert remaining months for this year
for($x=1;$x<=$end_month;$x++)
{
$data = array(
'user_id' => $user_id,
'budget_group_id' => $budget_group_id,
'month' => $x,
'year' => $temp_start_year,
'company_id' => $company_id,
'month_goal' => $month_goal
);
// Inserting information into the database
$this->db->insert('budget_month',$data);
}
}
$temp_start_year++;
}
}
}

in your code
while($temp_start_year !== $end_year)
you used !== which also check if the type of the 2 variables are the same.
but this line
$temp_start_year++;
will implicitly cast the variable to integer.
Therefore the !== will be comparing integer to string, which will always evaluate to true.
The solution is as simple as using != instead of !==, or feed an integer instead of string when you call your function (remove the single quotes).

Related

How can i check all selected value quantity?

Can anyone help me? how can i check all the product selected on the select or in the option? i'm using codeigniter 3 and i want to check if there was an available stock or none but i'm new and don't know how to do it i wish someone can help me. first it was working if i select a product with 0 quantity it will not process but if i select a first product with a quantity on hand greater than 0 and selected the second one with empty qty it will still process because it only check the stocks of the first product. how can i check all the qty selected in my select option?
my model:
public function create()
{
$user_id = $this->session->userdata('id');
// get store id from user id
$user_data = $this->model_users->getUserData($user_id);
$bill_no = 'BUBBLE-'.strtoupper(substr(md5(uniqid(mt_rand(), true)), 0, 4));
$data = array(
'bill_no' => $bill_no,
'date_time' => strtotime(date('Y-m-d h:i:s a')),
'gross_amount' => $this->input->post('gross_amount_value'),
'service_charge_rate' => $this->input->post('service_charge_rate'),
'service_charge_amount' => ($this->input->post('service_charge_value') > 0) ?$this->input->post('service_charge_value'):0,
'vat_charge_rate' => $this->input->post('vat_charge_rate'),
'vat_charge_amount' => ($this->input->post('vat_charge_value') > 0) ? $this->input->post('vat_charge_value') : 0,
'net_amount' => $this->input->post('net_amount_value'),
'discount' => $this->input->post('discount_amount_value'),
'paid_status' => 3,
'user_id' => $user_id,
'table_id' => $this->input->post('table_name'),
'discount_id' => json_encode($this->input->post('discount')),
'discount_percent' => $this->input->post('discount_perct_value'),
'datetoday' => date('Y-m-d h:i:s a'),
'payment_id' => json_encode($this->input->post('payment')),
);
$count_product = count($this->input->post('product'));
for($x = 0; $x < $count_product; $x++) {
$prodid = $this->input->post('product')[$x];
$prod_quan = $this->model_products->getProductData($prodid);
$inputQuantity = (int)$this->input->post('qty')[$x];
$check = $this->model_orders->check_stock($prodid, $inputQuantity);
if($check == TRUE)
{
$insert = $this->db->insert('orders', $data);
$order_id = $this->db->insert_id();
$count_product = count($this->input->post('product'));
for($x = 0; $x < $count_product; $x++) {
$items = array(
'order_id' => $order_id,
'product_id' => $this->input->post('product')[$x],
'qty' => $this->input->post('qty')[$x],
'rate' => $this->input->post('rate_value')[$x],
'amount' => $this->input->post('amount_value')[$x],
);
$this->db->insert('order_items', $items);
}
$this->load->model('model_tables');
$this->model_tables->update($this->input->post('table_name'), array('available' => 2));
return ($order_id) ? $order_id : false;
}
else
{
return false;
}
}
}
public function check_stock($productId, $inputQuantity)
{
$product = $this->db->get_where('products', ['id' => $productId])->row();
if(isset($product))
{
if($product->qty < $inputQuantity)
{
$this->session->set_flashdata('error','No more stock on some selected items');
return false;
}
else
{
return true;
}
}
}
and my select in view is something like this:
<select class="form-control select_group update-select" data-row-id="row_1" id="product_1" name="product[]" style="width:100%;" onchange="getProductData(1)" required>
<option disabled selected hidden value=''>--Select Products--</option>
<?php foreach ($products as $k => $v): ?>
<option value="<?php echo $v['id'] ?>"><?php echo $v['name'] ?></option>
<?php endforeach ?>
</select>
Easiest solution is to return false as soon as you find a product that is out of stock, something like the following:
Loop through the selected products and for each one check the stock. If you encounter a product that is out of stock, return false.
If all products are in stock, create the order, then loop through the selected products again and add those to the order in the database.
I haven't tested the code below, so there may be errors. I only changed the if($check == TRUE) part and some curly braces.
public function create()
{
$user_id = $this->session->userdata('id');
// get store id from user id
$user_data = $this->model_users->getUserData($user_id);
$bill_no = 'BUBBLE-'.strtoupper(substr(md5(uniqid(mt_rand(), true)), 0, 4));
$data = array(
'bill_no' => $bill_no,
'date_time' => strtotime(date('Y-m-d h:i:s a')),
'gross_amount' => $this->input->post('gross_amount_value'),
'service_charge_rate' => $this->input->post('service_charge_rate'),
'service_charge_amount' => ($this->input->post('service_charge_value') > 0) ?$this->input->post('service_charge_value'):0,
'vat_charge_rate' => $this->input->post('vat_charge_rate'),
'vat_charge_amount' => ($this->input->post('vat_charge_value') > 0) ? $this->input->post('vat_charge_value') : 0,
'net_amount' => $this->input->post('net_amount_value'),
'discount' => $this->input->post('discount_amount_value'),
'paid_status' => 3,
'user_id' => $user_id,
'table_id' => $this->input->post('table_name'),
'discount_id' => json_encode($this->input->post('discount')),
'discount_percent' => $this->input->post('discount_perct_value'),
'datetoday' => date('Y-m-d h:i:s a'),
'payment_id' => json_encode($this->input->post('payment')),
);
$count_product = count($this->input->post('product'));
for($x = 0; $x < $count_product; $x++) {
$prodid = $this->input->post('product')[$x];
$prod_quan = $this->model_products->getProductData($prodid);
$inputQuantity = (int)$this->input->post('qty')[$x];
$check = $this->model_orders->check_stock($prodid, $inputQuantity);
if($check != TRUE)
{
return false;
}
}
$insert = $this->db->insert('orders', $data);
$order_id = $this->db->insert_id();
$count_product = count($this->input->post('product'));
for($x = 0; $x < $count_product; $x++) {
$items = array(
'order_id' => $order_id,
'product_id' => $this->input->post('product')[$x],
'qty' => $this->input->post('qty')[$x],
'rate' => $this->input->post('rate_value')[$x],
'amount' => $this->input->post('amount_value')[$x],
);
$this->db->insert('order_items', $items);
}
$this->load->model('model_tables');
$this->model_tables->update($this->input->post('table_name'), array('available' => 2));
return ($order_id) ? $order_id : false;
}

Laravel-Visitors Counter

this code repeats one IP hits every time when I visit this IP...
if I visit repeatedly with one IP hits increment, not IP increment
how can I solve this ?? can anyone guide?
$date = new \DateTime;
$check_if_exists = DB::table('visitors')
->where('ip',$_SERVER['REMOTE_ADDR'])->first();
$get_visit_day = DB::table('visitors')->select('created_at')
->where('ip', $_SERVER['REMOTE_ADDR'])->first();
$value = date_create($get_visit_day->created_at);
if(!$check_if_exists)
{
DB::table('visitors')->insert(array('ip' =>
$_SERVER['REMOTE_ADDR'], 'hits' => '1', 'created_at' => $date));
}else{
DB::table('visitors')->where('ip', $_SERVER['REMOTE_ADDR'])
->increment('hits')->insert('updated_at', $date);
// DB::table('visitors')->insert('updated_at', $date);
}
// $value = date_create($get_visit_day->created_at);
if ($check_if_exists && date_format($value, 'd') != date('d')) {
DB::table('visitors')->insert(array('ip' => $_SERVER['REMOTE_ADDR'], 'hits' => '1', 'created_at' => $date));
}[enter image description here][1]
try this if you want to add new record for each day , and increment view count for every hit for today form unique ip
$date = new \DateTime;
$check_if_exists = DB::table('visitors')
->where('ip',$_SERVER['REMOTE_ADDR'])->first();
$get_visit_day = DB::table('visitors')->select('created_at')
->where('ip', $_SERVER['REMOTE_ADDR'])->first();
$is_today_if_exists = DB::table('visitors')->whereDate('created_at',$date)
->where('ip', $_SERVER['REMOTE_ADDR'])->count();
if(!$check_if_exists)
{
DB::table('visitors')->insert(array('ip' =>
$_SERVER['REMOTE_ADDR'], 'hits' => '1', 'created_at' => $date));
}
elseif ($is_today_if_exists>0)
{
DB::table('visitors')->where('ip', $_SERVER['REMOTE_ADDR'])->whereDate('created_at',$date)
->increment('hits');
}
else
{
DB::table('visitors')->insert(array('ip' => $_SERVER['REMOTE_ADDR'], 'hits' => '1', 'created_at' => $date));
}

A non well formed numeric value encountered when function inside foreach

For some reason I keep getting this notice when I try to loop through an array and change it's values.
For some reason, the array is passing 2 values, the one before and the one after when running the same function that changes the values.
class UnitConverter {
public $vulgar_to_float = array('½' => '1/2');
public function replaceUnicode($amount){
foreach($this->vulgar_to_float as $key => $float){
if(is_numeric($amount)){
return $amount;
} else if($key === $amount){
return $float;
}
}
}
public function convertAmount($amount, $from, $to){
if($from === 'pound' && $to === 'ounce'){
return $amount * 16;
} else if($from === 'cup' && $to === 'tablespoon'){
print_r($amount); // here it's echoing 2 values when it should be 1
return $this->replaceUnicode($amount) * 16;
} else {
throw new \Exception('Unable to convert ' . $from . ' to ' . $to);
}
}
}
function convertIngredients($arr){
foreach($arr as $key => $value){
if($arr[$key]['unit_name'] === 'pound'){
$arr[$key]['amount'] = (new UnitConverter())->convertAmount($arr[$key]['amount'], 'pound', 'ounce');
$arr[$key]['unit_name'] = 'ounce';
} else if($arr[$key]['unit_name'] === 'cup'){
$arr[$key]['amount'] = (new UnitConverter())->convertAmount($arr[$key]['amount'], 'cup', 'tablespoon');
$arr[$key]['unit_name'] = 'tablespoon';
}
}
return $arr;
}
function generateBreakfast(){
$array = $var = array(
0 => array( 'amount' => 1, 'ingredient_name' => 'almond flour', 'unit_name' => 'cup' ),
1 => array( 'amount' => ½, 'ingredient_name' => 'erythritol', 'unit_name' => 'cup' ),
2 => array( 'amount' => 1, 'ingredient_name' => 'egg', 'unit_name' => 'large' )
);
$converted_ingredients = convertIngredients($array);
return $converted_ingredients;
}
echo '<pre>';
print_r(generateBreakfast());
echo '</pre>';
So in the convertIngredients, we're calling the convertAmount method, but for some reason there.. it's passing this '1½' instead of just calling the method individually with each iteration.
If you take a look here: https://eval.in/944452 , the amount in erythritol is showing 16, but it should be 8 because 1/2 of 16 = 8.
Replace vulgar_to_float with...
public $vulgar_to_float = array('½' => 0.5);
... and it should work.
As it stands, 16 * '1/2' expression is evaluated by the code. You probably hope that PHP automatically 'resolves' the second operand to a correct numeric value. But it doesn't, as the parsing rules (applied to a string in attempt to cast it to a number) don't treat '/' character in any special way - hence it's discarded, along with the rest of string.
That means, value of 16 * '1/2' is essentially equal to 16 * 1 - which is, as you clearly noticed, 16.
The change prevents this error - and makes life for PHP a little bit easier: if you're going to get a float as replaceUnicode return value, use floats in your map right from the start so that the engine won't have to spend time on type juggling.
Kudos to #raina77ow for indicating the necessary correction. I went ahead and reviewed the code and altered it as follows:
<?php
class UnitConverter {
public $vulgar_to_float = ['½' => 0.5];
public function replaceUnicode( $amount = 0 ){
$half = $this->vulgar_to_float['½'];
return ( is_numeric( $amount ) )? $amount : $half;
}
public function convertAmount($amount, $from, $to){
if($from === 'pound' && $to === 'ounce'){
return $amount * 16;
} else if($from === 'cup' && $to === 'tablespoon'){
return $this->replaceUnicode( $amount ) * 16;
} else {
throw new Exception('Unable to convert ' . $from . ' to ' . $to);
}
}
}
function convertIngredients( $arr = null){
$unit_names = array_column($arr, 'unit_name');
foreach($unit_names as $key => $unit){
if( $unit === 'pound'){
$arr[$key]['amount'] = (new UnitConverter())->convertAmount($arr[$key]['amount'], $unit, 'ounce');
$arr[$key]['unit_name'] = 'ounce';
} else if($unit === 'cup'){
$arr[$key]['amount'] = (new UnitConverter())->convertAmount($arr[$key]['amount'], $unit, 'tablespoon');
$arr[$key]['unit_name'] = 'tablespoon';
} else {
continue;
}
}
return $arr;
}
function generateBreakfast(){
$array = [
0 => array( 'amount' => 1, 'unit_name' => 'cup', 'ingredient_name' => 'almond flour' ),
1 => array( 'amount' => '½', 'unit_name' => 'cup', 'ingredient_name' => 'erythritol' ),
2 => array( 'amount' => 1, 'unit_name' => 'large', 'ingredient_name' => 'egg' )
];
return convertIngredients($array);
}
echo '<pre>';
print_r(generateBreakfast());
echo '</pre>';
See live code
There was a place in the code that needed quotes around the unicode one-half symbol. Also, I tried to eliminate unnecessary verbosity. One code statement creates a variable and then returns it whereas this code returns the value. I used a ternary statement and I used array_column() to pinpoint the unit names in a more straightforward fashion.
And, for the cooks among us, more straightforward to show the unit name and the amount followed by the ingredient :)

How to increase the performance of this function

How to increase the performance of following function in phalcon framework. There are thousands of records in the table. I tried different ways, but I am stuck the point. How can I increase the efficiency and reduce the execution time. Following are two methods:
public function currentmonthAction()
{
$payload = $this->request->getJsonRawBody();
$this->setDB();
$ticketsmodel = new Tickets();
$fromcitycondition = "";
if( isset($payload->city->id) )
{
$fromcitycondition = "and fromcity='{$payload->city->id}'";
}
try{
$date = new \Datetime($payload->date);
$year = $date->format('Y');
$month = $date->format('m');
$month = '08';
$daysInMonth = cal_days_in_month(CAL_GREGORIAN, $month, $year);
/* result for all cities passenger */
$result = array();
// get all cities permutations
$tmpcitiesdata = array();
$rawresultset = Tickets::find (
array(
'columns' => 'fromcity,tocity',
'conditions' => "departure between '{$year}-{$month}-01' and '{$year}-{$month}-$daysInMonth' and tickettype in (1) ". $fromcitycondition,
'group' => 'fromcity,tocity'
));
foreach ($rawresultset as $rawresult) {
$tmpcitiesdata[$rawresult->fromcity.'-'.$rawresult->tocity]['fromcity'] = $rawresult->fromcity;
$tmpcitiesdata[$rawresult->fromcity.'-'.$rawresult->tocity]['tocity'] = $rawresult->tocity;
}
//var_dump($rawresultset);
// get tickets sold based on cities combinations
$total = 0;
foreach ($tmpcitiesdata as $tmpcities) {
$rawresultset = Tickets::find (
array(
'columns' => 'customer',
'conditions' => "departure between '{$year}-{$month}-01' and '{$year}-{$month}-$daysInMonth' and tickettype in (1) and fromcity=". $tmpcities['fromcity']." and tocity=".$tmpcities['tocity'],
'group' => 'customer'
));
$totalsoldRaw = count($rawresultset);
// get ticket cancellations
$rawresultset = Tickets::find (
array(
'conditions' => "departure between '{$year}-{$month}-01' and '{$year}-{$month}-$daysInMonth' and tickettype in (3) and fromcity=". $tmpcities['fromcity']." and tocity=".$tmpcities['tocity']
));
//make sure cancellations are tickets cancellations not booking cancellations
foreach($rawresultset as $rawresult)
{
$resultNumber = Tickets::find("departure='$rawresult->departure' and seatno={$rawresult->seatno} and id < {$rawresult->id} and tickettype = 1" );
if( count($resultNumber) > 0 ){
$totalsoldRaw = $totalsoldRaw-1;
}
}
$total += $totalsoldRaw;
array_push($result, array('total' => $totalsoldRaw, 'fromcity' => Cities::findFirstById($tmpcities['fromcity'])->name, 'tocity' => Cities::findFirstById($tmpcities['tocity'])->name));
}
//sort result based on counts
arsort($result);
//cut result to max 6 cities
$result = array_slice($result, 0, 6);
$this->response->setContentType('application/json')
->setJsonContent(
array( 'totaltickets' => $total, "allcities" => $result )
);
$this->response->send();
return;
}
catch(\PDOException $e)
{
$this->response->setStatusCode('422','Invalid Payload');
$this->response->setContentType('application/json')
->setJsonContent(array(
'flash' => array(
'class' => 'danger',
'message' => $e->getMessage()
)
));
$this->response->send();
return;
}
}
Use count instead of count(result of find). Also are you sure in // get ticket cancellations you don't need group ? Then you can select all tickets for customers in 1,3 tickettype and then filter resultset.
Also can't your first $rawresulset can't be:
$rawresultset = Tickets::find (
array(
'columns' => 'customer,fromcity,tocity,tickettype ',
'conditions' => "departure between '{$year}-{$month}-01' and '{$year}-{$month}-$daysInMonth' and tickettype in (1,3)".$fromcitycondition
'group' => 'customer,fromcity,tocity'
));
?
$ticketCanccelations = $rawresultset->filter(function($row){
if($row->tickettype == 3) {
return $row;
}
});
$resultNumber = Tickets::count("departure='$rawresult->departure' and seatno={$rawresult->seatno} and id < {$rawresult->id} and tickettype = 1" );

codeigniter mysql stop third consecutive insert

I have this codeigniter mysql code to create an appointment:
if ($this->form_validation->run() == TRUE)
{
$data = array(
'startTime' => $startTime ,
'endTime' => $endTime ,
'day' => $date ,
'contact_id' => $this->input->post('InputPatient')
);
$this->db->insert('rdv', $data);
echo 'Appointment Created Successfully.';
}
What I need is - for a specific time like 8pm, I should not have more than 2 appointment created. On third insert with same start time, I should give an error.
Thanks.
Before you do your insert you could do a select to see how many entries there are with the same start time. If there are less than 2 then you can proceed to do your insert.
$this->db->select('count(*) as count')
->from('rdv')
->where('startTime', $startTime)
->where('day', $date);
$query = $this->db->get();
$aResult = $query->row_array();
if($aResult['count'] < 2)
{
//Do your insert
}
Here you go. Before you insert, check if there are already 2 appointments for a specific time and date.
if ($this->form_validation->run() == TRUE)
{
$data = array(
'startTime' => $startTime ,
'endTime' => $endTime ,
'day' => $date ,
'contact_id' => $this->input->post('InputPatient')
);
$isAlreadyTwo = $this->db->from("rdv")
->where(array("startTime" => $startTime, "day" => $day))
->count_all_results() >= 2;
if($isAlreadyTwo)
{
echo "Error!!";
}
else
{
$this->db->insert('rdv', $data);
echo 'Appointment Created Successfully.';
}
}
Hope this helps :)

Categories