Solved

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

Posted on 2014-11-28
7
188 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 9

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 33

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
Maximize Your Threat Intelligence Reporting

Reporting is one of the most important and least talked about aspects of a world-class threat intelligence program. Here’s how to do it right.

 
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 33

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 33

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 run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

Join & Write a Comment

Developers of all skill levels should learn to use current best practices when developing websites. However many developers, new and old, fall into the trap of using deprecated features because this is what so many tutorials and books tell them to u…
Creating and Managing Databases with phpMyAdmin in cPanel.
Learn how to match and substitute tagged data using PHP regular expressions. Demonstrated on Windows 7, but also applies to other operating systems. Demonstrated technique applies to PHP (all versions) and Firefox, but very similar techniques will w…
The viewer will learn how to count occurrences of each item in an array.

705 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

Need Help in Real-Time?

Connect with top rated Experts

19 Experts available now in Live!

Get 1:1 Help Now