Still celebrating National IT Professionals Day with 3 months of free Premium Membership. Use Code ITDAY17

x
?
Solved

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

Posted on 2014-11-28
7
Medium Priority
?
214 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 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
Learn how to optimize MySQL for your business need

With the increasing importance of apps & networks in both business & personal interconnections, perfor. has become one of the key metrics of successful communication. This ebook is a hands-on business-case-driven guide to understanding MySQL query parameter tuning & database perf

 
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

Free Tool: Port Scanner

Check which ports are open to the outside world. Helps make sure that your firewall rules are working as intended.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

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

Build an array called $myWeek which will hold the array elements Today, Yesterday and then builds up the rest of the week by the name of the day going back 1 week.   (CODE) (CODE) Then you just need to pass your date to the function. If i…
When table data gets too large to manage or queries take too long to execute the solution is often to buy bigger hardware or assign more CPUs and memory resources to the machine to solve the problem. However, the best, cheapest and most effective so…
The viewer will learn how to look for a specific file type in a local or remote server directory using PHP.
The viewer will learn how to create and use a small PHP class to apply a watermark to an image. This video shows the viewer the setup for the PHP watermark as well as important coding language. Continue to Part 2 to learn the core code used in creat…

718 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