Solved

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

Posted on 2014-11-28
7
194 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
Microsoft Certification Exam 74-409

Veeam® is happy to provide the Microsoft community with a study guide prepared by MVP and MCT, Orin Thomas. This guide will take you through each of the exam objectives, helping you to prepare for and pass the examination.

 
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

Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

Question has a verified solution.

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

Suggested Solutions

Title # Comments Views Activity
Keep getting 503 on Curl request 6 30
join tables 4 50
Is this error or Notice in php error log? 6 32
Facial recognition to look through the whole database for a person 3 39
As a database administrator, you may need to audit your table(s) to determine whether the data types are optimal for your real-world data needs.  This Article is intended to be a resource for such a task. Preface The other day, I was involved …
This article discusses how to create an extensible mechanism for linked drop downs.
The viewer will learn how to dynamically set the form action using jQuery.
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…

930 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

13 Experts available now in Live!

Get 1:1 Help Now