0

I'm trying to build a table that is conditionally organized based off user input. I need my WHERE and GROUP BY clauses to change based off user input values (from radio selects sent to php through ajax - these tested successfully), stored in php variables. I tried to run a series of if statements to change the WHERE and GROUP BY clauses based on the values of the ajax data variables and then concat then into my SELECT statement. I try the same method for building the column headers and the table itself. When I test the current code, the table headers display (the first column is empty because of the variable) but the columns aren't built. I don't receive any errors when I inspect the page and my ajax variables display the appropriate values.

The problem is definately with the IF statements but I'm not sure how to fix that.

Note: the SQL statements works perfectly when I manually enter a WHERE or GROUP BY clause using the same values I'm trying to store in variables.

MY CODE:

AJAX Response:

//Get Table Type.
if (isset($_POST['revenueTblType'])) {
  $revenueTblType = $_POST['revenueTblType'];
  print_r($revenueTblType);
};

//Get Report Type
if (isset($_POST['revenueWO'])) {
  $revenueWO = $_POST['revenueWO'];
  print_r($revenueWO);
};

//Get date include value.
if (isset($_POST['revenueWODate'])) {
  $revenueWODate = $_POST['revenueWODate'];
  print_r($revenueWODate);
};

//Get date range.
$revenuefromajax=$_POST['revenuefrom'];
$revenuetoajax=$_POST['revenueto'];

$revenuefromstring = strtotime($revenuefromajax);
$revenuetostring = strtotime($revenuetoajax);

$revenuefrom=date("Y-m-d", $revenuefromstring);
$revenueto=date("Y-m-d", $revenuetostring);

//Get selected Status Values.
if (isset($_POST['revenue_checkboxes'])) {
  $revenue_check = $_POST['revenue_checkboxes'];
};

IF STATEMENTS and TABLE BUILD:

/////////////   Select Data and Display it in a table.   //////////////


//$groupbyclause = "";

    if ($revenueTblType=='Customer') {
        $groupbyclause="x.company ASC";
        $columnheader='Customer';
        $columnname='company';
    }
    else if ($revenueTblType=='Revenue Category') {
        $groupbyclause="x.revenue ASC";
        $columnheader='Revenue Category';
        $columnname='revenue';
    }


//$whereclause = "";

    if (($revenueWO=='Completed Workorders') and ($revenueWODate=='All Workorders')) {
        $whereclause="x.stagestatus = 'Complete'";
    }
    else if (($revenueWO=='Completed Workorders') and ($revenueWODate=='Workorder Date Range')) {
        $whereclause ="x.stagestatus = 'Complete' AND x.shippeddate BETWEEN '".$revenuefrom."' AND '".$revenueto."'"; 
    }
    else if ($revenueWO=='Workorder Status') {
         $whereclause ="x.stagestatus IN (". implode(',', array_map(function($item) {return '"' . $item . '"'; }, $revenue_check)) .")";
    }


    echo "<BR>";
    echo "<BR>";


    //SELECT statement pulls ALL COMPLETED history info by CUSTOMER.
    $sql="SELECT x.company, x.revenue, x.stagestatus, x.shippeddate, FORMAT(SUM(x.totprice), 2) as totalprice, FORMAT(SUM(x.sgtotquantity), 2) as totqty, FORMAT(SUM(x.sgtotalsqft), 2) as sgtotsqft, FORMAT(SUM(x.totprice)/SUM(x.sgtotalsqft), 2) as avgsqftrevenue, FORMAT(SUM(x.totprice)/SUM(x.sgtotquantity), 2) as avgunitrevenue FROM (SELECT t1.company, t1.revenue, t1.stagestatus, t1.shippeddate, t1.id, TRIM(LEADING '$' FROM t1.totalprice) AS totprice, t2.invoiceid, SUM(t2.quantity) AS sgtotquantity, SUM(t2.width * t2.height * t2.quantity ) /144 AS sgtotalsqft, (t1.totalprice/(SUM(t2.width * t2.height * t2.quantity ) /144)) as avgsqftrev, (t1.totalprice) / SUM(t2.quantity)) AS avgunitrev
      FROM invoices AS t1 INNER JOIN lineitems AS t2 ON t1.id = t2.invoiceid
      WHERE (t2.invoiceid = t1.id)
      GROUP BY t1.id) x
      WHERE '".$whereclause."'
      GROUP BY ".$groupbyclause.""; //this line edited per comment suggestions.//



$result = $conn->query($sql);       


    echo "<table id='revenueReportA' align='center' class='report_DT'>
    <thead>
    <tr>


    <th>".$columnheader."</th>
    <th>Total Revenue</th>
    <th>Total SQ FT</th>
    <th>AVG Revenue Per SQ FT</th>
    <th>Total Number of Units</th>
    <th>AVG Revenue Per Unit</th>
    </tr>
    </head>";


        if ($result = $conn->query($sql)) {

            // fetch associative array 
            while ($row = $result->fetch_assoc()) {

              echo "<tbody>";
              echo "<tr>";
              echo "<td>" . $row[$columnname] . "</td>";
              echo "<td>" ."$". $row['totalprice'] . "</td>";
              echo "<td>" . $row['sgtotsqft'] ."&nbsp;&nbsp;". "ft<sup>2</sup>". "</td>";
              echo "<td>" ."$". $row['avgsqftrevenue'] . "</td>";
              echo "<td>" . $row['totqty'] . "</td>";
              echo "<td>" ."$". $row['avgunitrevenue'] . "</td>";
              echo "</tr>";
              echo "</tbody>";
              }//End table while.
              echo "</table>";
              echo "<BR>";

         }//End table if.

///////////////////////////////////////////////////////////////////////////////


//Free the result variable. 
$result->free();



//Close the Database connection.
$conn->close(); 

All suggestions are welcome. Thank you!

rdimouro
  • 225
  • 1
  • 4
  • 17
  • [Little Bobby](http://bobby-tables.com/) says ***[your script is at risk for SQL Injection Attacks.](http://stackoverflow.com/questions/60174/how-can-i-prevent-sql-injection-in-php)***. Even [escaping the string](http://stackoverflow.com/questions/5741187/sql-injection-that-gets-around-mysql-real-escape-string) is not safe! ***SQL Injection*** , it's not just for breakfast any more! – Jay Blanchard Oct 27 '16 at 19:12
  • `$whereclause = "(x.stagestatus = 'Complete') AND (x.shippeddate BETWEEN '".$revenuefrom."' AND '".$revenueto."')";` specify brackets to distinguish between these conditions. – Nana Partykar Oct 27 '16 at 19:18

2 Answers2

0

You have too many ' characters in query. Currently all of your WHERE statement is quoted as well as GROUP BY statement.

Change this:

WHERE '".$whereclause."'
GROUP BY '".$groupbyclause."'"

To this:

WHERE ".$whereclause."
GROUP BY ".$groupbyclause
ElChupacabra
  • 1,045
  • 10
  • 18
0

Be caution with last line:

//SELECT statement pulls ALL COMPLETED history info by CUSTOMER.

$sql="SELECT x.company, x.revenue, x.stagestatus, x.shippeddate, FORMAT(SUM(x.totprice), 2) as totalprice, FORMAT(SUM(x.sgtotquantity), 2) as totqty, FORMAT(SUM(x.sgtotalsqft), 2) as sgtotsqft, FORMAT(SUM(x.totprice)/SUM(x.sgtotalsqft), 2) as avgsqftrevenue, FORMAT(SUM(x.totprice)/SUM(x.sgtotquantity), 2) as avgunitrevenue FROM (SELECT t1.company, t1.revenue, t1.stagestatus, t1.shippeddate, t1.id, TRIM(LEADING '$' FROM t1.totalprice) AS totprice, t2.invoiceid, SUM(t2.quantity) AS sgtotquantity, SUM(t2.width * t2.height * t2.quantity ) /144 AS sgtotalsqft, (t1.totalprice/(SUM(t2.width * t2.height * t2.quantity ) /144)) as avgsqftrev, (t1.totalprice) / SUM(t2.quantity)) AS avgunitrev
  FROM invoices AS t1 INNER JOIN lineitems AS t2 ON t1.id = t2.invoiceid
  WHERE (t2.invoiceid = t1.id)
  GROUP BY t1.id) x
  WHERE ".$whereclause."
  GROUP BY ".$groupbyclause."";
phsaires
  • 2,188
  • 1
  • 14
  • 11
  • Can you explain why? Is the GROUP BY clause at risk of SQL injection? Note: the values I'm pulling over are only from checkbox and radio buttons, not text input fields. Does that fix/reduce the risk of sql injection? – rdimouro Oct 27 '16 at 19:53
  • It´s only a syntax warning. Nothing about sql injection. By the way, you putted an ASC in GROUP BY. Must be in ORDER BY clausule. – phsaires Oct 27 '16 at 19:59
  • What do you think your table with only two echos? I guess better. echo " " . $row[$columnname] . " $". $row['totalprice'] . " " . $row['sgtotsqft'] ."  ". "ft2". " $". $row['avgsqftrevenue'] . " " . $row['totqty'] . " " ."$". $row['avgunitrevenue'] . " "; }//End table while. echo "
    ";
    – phsaires Oct 27 '16 at 20:10
  • I'm sorry... what was the question? If its about the $columnname part, I was trying to echo one column if the user chooses to view the table by revenue category ( column name = 'revenue' ) or by customer (column name = 'company'). idk if that was the correct syntax or not for what I was trying to achieve... – rdimouro Oct 27 '16 at 20:15
  • do you think I would have better luck using a switch statement instead of IF statements? – rdimouro Oct 27 '16 at 20:25
  • If you have just two conditions, IF is ideal. And the syntax, I reported about open and close php clausules in the SQL with double quotes. – phsaires Oct 27 '16 at 20:36