Go Premium for a chance to win a PS4. Enter to Win

x
?
Solved

Updating a previous variable with the current one within a PHP loop

Posted on 2014-11-28
7
Medium Priority
?
218 Views
Last Modified: 2014-12-10
Hi,
I have "price offer" items under certain processes;

PROCESS 1
index no 0      price offer a   count=1 ($selected_price_offers_cnt)

PROCESS 2
index no 1      price offer b   count=3     (3+1=4)
index no 2      price offer c   count=3     (3+1=4)
index no 3      price offer d   count=3     (3+1=4) 3=selected_price_offers_cnt, 1=$previous, 4=$next 


PROCESS 3
index no 4      price offer e   count=2     (2+4=6)
index no 5      price offer f   count=2     (2+4=6) 2=selected_price_offers_cnt, 4=$previous, 6=$next

Open in new window


What I need to do is to print "scale sub total" only below the LAST price offer item of EACH PROCESSES.
In other words, below a, d and f.

In order to do that I try to compare the latest count of the price offers from the beginning (1, 4 and 6) with the current row index no + 1.
If we arrive at the last price offer of a PROCESS X, its count will be == index no + 1 (like at process offer d count 4 = index no 3 + 1).
So I need to keep $previous variable updated with $next for the following PROCESS Y.  

My code takes unnaturally long time to finish execution and at last it prints only one sale sub total line.
(As this code is used inside Drupal 7 views global php field, SQL queries are arranged to work there and they return correct values, no problem there.)
Any approaches other than while...loop is also welcomed.

<?php 
$process_nid = $row->nid_3;
$current_index_no = $view->row_index; //the number of the row that is being processed

$selected_price_offers = db_query("SELECT entity_id FROM drupal_field_data_field_process WHERE bundle = 'price_offer' AND deleted = '0' AND field_process_nid = {$process_nid} AND entity_id IN (SELECT content_id FROM drupal_flag_counts WHERE fid='18' AND content_type='node' AND COUNT = '1')");
$selected_price_offers_cnt = db_query("SELECT COUNT(entity_id) FROM drupal_field_data_field_process WHERE bundle = 'price_offer' AND deleted = '0' AND field_process_nid = {$process_nid} AND entity_id IN (SELECT content_id FROM drupal_flag_counts WHERE fid='18' AND content_type='node' AND COUNT = '1')")->fetchField();

$previous = 0;

while($current_index_no) { 
  
	$next = $selected_price_offers_cnt + $previous; // add the previous to the current amount

if ($next == ($current_index_no+1)) {

	$previous = $next; // save the new price offer count to the $previous in order to use it at the next row

// this part below works as expected
$sum1 = 0;
foreach($selected_price_offers as $item) {
$po_item= $item->entity_id;
$scale1 = db_query("SELECT field_sub_total_scale_1_value FROM drupal_field_data_field_sub_total_scale_1 WHERE bundle = 'price_offer' AND deleted = '0' AND entity_id = {$po_item}")->fetchField();
  $sum1+= $scale1;
}
  print "scale sub total:&nbsp;".number_format($sum1,2,",","."). " TL";
}
else {
echo "";
}
}
?>

Open in new window

0
Comment
Question by:sbayrak
  • 3
  • 3
7 Comments
 
LVL 10

Expert Comment

by:oliverpolden
ID: 40470721
You have an infinite loop. That's why it's taking so long. Instead of while, why don't you do
if ($current_index_no >= 0) {
  ...
}
0
 
LVL 1

Author Comment

by:sbayrak
ID: 40470769
Well, yes, "if" rescues it from the infinite loop, but as $previous variable outside that if statement isn't updated, $next = $selected_price_offers_cnt + $previous does not also work. It always begins to run with $previous = 0 again.
0
 
LVL 34

Expert Comment

by:Slick812
ID: 40471833
????, , I just do not see the way you have set this up?
You say this - 'Well, yes, "if" rescues it from the infinite loop,'
You will need to place a loop break;  in the
     if ($next == ($current_index_no+1)) {
 to get OUT of the infinite loop

BUT the value of the $current_index_no NEVER changes within the while loop, ,
so to me the loop as -
     while($current_index_no) {

does not need to be there, as in code like -
$process_nid = $row->nid_3;
$current_index_no = $view->row_index; //the number of the row that is being processed

$selected_price_offers = db_query("SELECT entity_id FROM drupal_field_data_field_process WHERE bundle = 'price_offer' AND deleted = '0' AND field_process_nid = {$process_nid} AND entity_id IN (SELECT content_id FROM drupal_flag_counts WHERE fid='18' AND content_type='node' AND COUNT = '1')");
$selected_price_offers_cnt = db_query("SELECT COUNT(entity_id) FROM drupal_field_data_field_process WHERE bundle = 'price_offer' AND deleted = '0' AND field_process_nid = {$process_nid} AND entity_id IN (SELECT content_id FROM drupal_flag_counts WHERE fid='18' AND content_type='node' AND COUNT = '1')")->fetchField();

$previous = 0;

// took out the while loop here
  
	$next = $selected_price_offers_cnt + $previous; // add the previous to the current amount

	$previous = $next; // save the new price offer count to the $previous in order to use it at the next row

// this part below works as expected
$sum1 = 0;
foreach($selected_price_offers as $item) {
$po_item= $item->entity_id;
$scale1 = db_query("SELECT field_sub_total_scale_1_value FROM drupal_field_data_field_sub_total_scale_1 WHERE bundle = 'price_offer' AND deleted = '0' AND entity_id = {$po_item}")->fetchField();
  $sum1+= $scale1;
}
  print "scale sub total:&nbsp;".number_format($sum1,2,",","."). " TL";
}
else {
echo "";
}

Open in new window

I would think NOT using the while loop would give you the output you need?
But That may not be the case? If a while loop is used with the -
    while($current_index_no) {
you are going to Have To change the value of the $current_index_no  inside of the loop.
$process_nid = $row->nid_3;
$current_index_no = $view->row_index; //the number of the row that is being processed

$selected_price_offers = db_query("SELECT entity_id FROM drupal_field_data_field_process WHERE bundle = 'price_offer' AND deleted = '0' AND field_process_nid = {$process_nid} AND entity_id IN (SELECT content_id FROM drupal_flag_counts WHERE fid='18' AND content_type='node' AND COUNT = '1')");
$selected_price_offers_cnt = db_query("SELECT COUNT(entity_id) FROM drupal_field_data_field_process WHERE bundle = 'price_offer' AND deleted = '0' AND field_process_nid = {$process_nid} AND entity_id IN (SELECT content_id FROM drupal_flag_counts WHERE fid='18' AND content_type='node' AND COUNT = '1')")->fetchField();

$previous = 0;

while($current_index_no) { 
  
	$next = $selected_price_offers_cnt + $previous; // add the previous to the current amount

if ($next == ($current_index_no+1)) {

	$previous = $next; // save the new price offer count to the $previous in order to use it at the next row

// this part below works as expected
$sum1 = 0;
foreach($selected_price_offers as $item) {
$po_item= $item->entity_id;
$scale1 = db_query("SELECT field_sub_total_scale_1_value FROM drupal_field_data_field_sub_total_scale_1 WHERE bundle = 'price_offer' AND deleted = '0' AND entity_id = {$po_item}")->fetchField();
  $sum1+= $scale1;
}
  print "scale sub total:&nbsp;".number_format($sum1,2,",","."). " TL";
}
else {
echo "";
}
--$current_index_no; // this will REDUCE the value of $current_index_no by ONE
}

Open in new window

0
Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 1

Accepted Solution

by:
sbayrak earned 0 total points
ID: 40472801
As you said Slick812, I stayed away from "while" and anyhow I found a way to manage it all by using $_session variables and boolean flags at appropriate places. You can't update a previous variable outside the loop with the one inside I think. But session variables work. I share the code below (/w debugging echo(s)). What I couldn't understand is "at (4)" how can it update $_SESSION['index_flag'] as false when arrived at the last price offer, while simultaneously satisfying (2) and make all things work seamlessly?!! It looks like those if and else are workin' together. I really want to know what happens there and how. :) Can someone help me to get it? Thanks you for your comments.

<?php 
$process_nid = $row->nid_3;
$current_index_no = $view->row_index;
$view_index = $current_index_no + 1;
$view = views_get_current_view();
$view->execute();
$view_count = count( $view->result );

// OUR DATABASE QUERIES

$selected_price_offers = db_query("SELECT entity_id FROM drupal_field_data_field_process WHERE bundle = 'price_offer' AND deleted = '0' AND field_process_nid = {$process_nid} AND entity_id IN (SELECT content_id FROM drupal_flag_counts WHERE fid='18' AND content_type='node' AND COUNT = '1')");
$selected_price_offers_cnt = db_query("SELECT COUNT(entity_id) FROM drupal_field_data_field_process WHERE bundle = 'price_offer' AND deleted = '0' AND field_process_nid = {$process_nid} AND entity_id IN (SELECT content_id FROM drupal_flag_counts WHERE fid='18' AND content_type='node' AND COUNT = '1')")->fetchField();

// SESSION START

if($current_index_no == 0)
{
//$_SESSION['view_index_previous'] = 0;
unset($_SESSION['view_index_previous']);
unset($_SESSION['index_flag']);
}

echo "view index no: ".$view_index."<br/>"; // control
echo "price offer count in this process: ".$selected_price_offers_cnt."<br/>"; // control
echo "view index previous: ".$_SESSION['view_index_previous']."<br/>"; // control
echo "index flag state (base): ".$_SESSION['index_flag']."<br/>"; // control

	// (1) CHECK IF THE FIRST PROCESS HAS MORE THAN 1 PRICE OFFER
	// IF YES, IT CANNOT SATISFY "IF (2) > (3)" BECAUSE ITS LAST PRICE OFFER WILL NOT HAVE VIEW INDEX PREVIOUS AND INDEX FLAG VALUE

	if (!isset($_SESSION['view_index_previous']) && $selected_price_offers_cnt > 1) {

		echo "assigning 0 to view index previous...<br/>";
		$_SESSION['view_index_previous'] = 0;
		$_SESSION['index_flag'] = true;
		echo "index flag state (1): ".$_SESSION['index_flag']."<br/>"; // control

	}

	// (2) CHECK IF WE ARRIVED AT THE LAST PRICE OFFER OF THE CURRENT PROCESS

	if ($selected_price_offers_cnt == ($view_index - $_SESSION['view_index_previous'])) {
	
		// (3) UPDATE view_index_previous VARIABLE WITH LAST PRICE OFFER'S INDEX NUMBER IF NOT UPDATED BEFORE
		// FLAG IT AS UPDATED

		if($_SESSION['index_flag'] == false) {

			$_SESSION['view_index_previous'] = $view_index;
			echo "This is the last price offer, here we recorded the last index point as ".$_SESSION['view_index_previous']."<br/>"; // control
			$_SESSION['index_flag'] = true;
			echo "index flag state (2): ".$_SESSION['index_flag']."<br/>"; // control

		} else {

			echo "view index previous is still ".$_SESSION['view_index_previous']."<br/>"; // control

			// (4) SOMEHOW (!???), BELOW FLAGGING SETS index flag state (base): NULL WHEN ARRIVED AT THE LAST PRICE OFFER AND MAKE THINGS WORK!?

			$_SESSION['index_flag'] = false;
			echo "index flag state (4 else): ".$_SESSION['index_flag']."<br/>"; // control

		}

		// SUB TOTALS

		print "______________________________________________________________";
		$sum1 = 0;
		$sum2 = 0;
		$sum3 = 0;
		$sum4 = 0;
		$sum5 = 0;

			foreach($selected_price_offers as $item) {
			$po_item= $item->entity_id;
			$scale1 = db_query("SELECT field_sub_total_scale_1_value FROM drupal_field_data_field_sub_total_scale_1 WHERE bundle = 'price_offer' AND deleted = '0' AND entity_id = {$po_item}")->fetchField();
			$scale2 = db_query("SELECT field_sub_total_scale_2_value FROM drupal_field_data_field_sub_total_scale_2 WHERE bundle = 'price_offer' AND deleted = '0' AND entity_id = {$po_item}")->fetchField();
			$scale3 = db_query("SELECT field_sub_total_scale_3_value FROM drupal_field_data_field_sub_total_scale_3 WHERE bundle = 'price_offer' AND deleted = '0' AND entity_id = {$po_item}")->fetchField();
			$scale4 = db_query("SELECT field_sub_total_scale_4_value FROM drupal_field_data_field_sub_total_scale_4 WHERE bundle = 'price_offer' AND deleted = '0' AND entity_id = {$po_item}")->fetchField();
			$scale5 = db_query("SELECT field_sub_total_scale_5_value FROM drupal_field_data_field_sub_total_scale_5 WHERE bundle = 'price_offer' AND deleted = '0' AND entity_id = {$po_item}")->fetchField();
			$sum1+= $scale1;
			$sum2+= $scale2;
			$sum3+= $scale3;
			$sum4+= $scale4;
			$sum5+= $scale5;
			}
  			echo "<br /><br />";
			print "scale 1 sub total:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;".number_format($sum1,2,",","."). " TL<br />";
			print "scale 2 sub total:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;".number_format($sum2,2,",","."). " TL<br />";
			print "scale 3 sub total:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;".number_format($sum3,2,",","."). " TL<br />";
			print "scale 4 sub total:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;".number_format($sum4,2,",","."). " TL<br />";
			print "scale 5 sub total:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;".number_format($sum5,2,",","."). " TL<br />";
	} else {
		echo "This is not the last price offer of the current process<br/>";
		echo "index flag state (2 else): ".$_SESSION['index_flag']."<br/>"; // control
	}
?>

Open in new window

0
 
LVL 34

Expert Comment

by:Slick812
ID: 40474549
?? ?? ??
I looked at your last code work with the  $_SESSION[ ]  variables, however I just can NOT understand what you are trying to do, especially with this code at -
     if($_SESSION['index_flag'] == false) {

This seems like a "Blind" test, as It only tests the  $_SESSION['index_flag']   variable and then reverses it (false becomes true, true becomes false), no matter what else might be a factor. As far As I can see, this could Only update the -
        $_SESSION['view_index_previous'] = $view_index;
on every Other Process, and NOT on every process, as  the   $_SESSION['view_index_previous']   would be false in one and true in the next. You do have  a single  IF test at -
          if (!isset($_SESSION['view_index_previous']) && $selected_price_offers_cnt > 1) {
for setting the   $_SESSION['index_flag'] , but this only happens if there is NO  $_SESSION['view_index_previous'] set,

I can NOT follow your logic of this, or what you expect as a result from your code.
0
 
LVL 34

Expert Comment

by:Slick812
ID: 40474582
Just to maybe change your view, I originally told you about using a LOOP (while LOOP) and having a
      $previous = 0;
outside of the LOOP. I did not mean you could add an arbitrary useless while loop as you did at first with your -
     while($current_index_no) {
and get any useful results,
Please consider What is the Important Variable that is needed for this to work using some kind of  $previous  to store the value need in the next LOOP pass.
To me the Important variable here is your -
     $current_index_no
so the LOOP you need to work with is the one that changes the value of   $current_index_no   on Every Loop pass through , with this line o code -
      $current_index_no = $view->row_index;
this is NOT a LOOP that you can add to your code, this is One that is already in your code, that I can not see from your work here.
Sorry if I have misunderstood you here, but not sure what I can say or show to help this?
0
 
LVL 1

Author Closing Comment

by:sbayrak
ID: 40490910
There were no other comments providing a solution. Even my solution is not a stylish one, it works.
0

Featured Post

How to Use the Help Bell

Need to boost the visibility of your question for solutions? Use the Experts Exchange Help Bell to confirm priority levels and contact subject-matter experts for question attention.  Check out this how-to article for more information.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Many old projects have bad code, but the budget doesn't exist to rewrite the codebase. You can update this code to be safer by introducing contemporary input validation, sanitation, and safer database queries.
It’s a season to be thankful, and we’re thankful for users like you who engage on site, solve technology problems, and network with others in the industry. What tech are we most thankful for? Keep reading.
Explain concepts important to validation of email addresses with regular expressions. Applies to most languages/tools that uses regular expressions. Consider email address RFCs: Look at HTML5 form input element (with type=email) regex pattern: T…
This tutorial will teach you the core code needed to finalize the addition of a watermark to your image. The viewer will use a small PHP class to learn and create a watermark.
Suggested Courses

877 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question