eBay Platform Notifications recommends periodic polling of the GetOrders API to ensure each and every order is received.
In my case, I have Platform Notifications set-up to parse the XML file received and insert it into a MySQL database using PHP.
Now I am looking to, as recommended, "double pass" using GetOrders, which should essentially give me duplicates for each and every single row (or order).
My structure is rather straightforward. But I have a UNIQUE INDEX for OrderLineItemID which, to my understanding, is the unique identifier for each eBay Order.
Is there a better way to do this than I am currently doing?
//retrieve and escape variables for insertion//
$sql = "INSERT INTO eBayOrders (OrderLineItemID, SalesRecordNumber, BuyerUserID, BuyerEmail, Title, SKU, Quantity, TransactionPrice)
VALUES ('".$orderlineitemid."', '".$recordnumber."', '".$buyeruserid."', '".$buyeremail."', '".$title."', '".$sku."', '".$qty."', '".$transactionprice."')";
}
if ($connect->query($sql) === TRUE) {
echo "New Record Created Successfully";
} else {
echo "Error: " . $sql . "<br />" . $connect->error;
$connect->close();
die();
}
Because of my UNIQUE ON OrderLineItemID, when a duplicate order comes in, the query will result in an error, close the connection, and then exit the script.
I've thought about first checking to see (maybe using a SELECT statement) if the row exists, and then trying an insert, but I'm doing a foreach loop of up to 100 orders using the GetOrders API to run my SQL queries, and it seems like just allowing it to fall to error might be a quicker option, but I'm weary on if this can cause issues down the line.
In all, I'm not familiar with best practices for MySQL "double passes". Anyone have any insight on the best way to conduct this?
edit: here is my entire foreach loop:
foreach ($orders as $order) {
$i++;
$buyeruserid2 = $order->BuyerUserID;
$buyeruserid = mysqli_real_escape_string($connect, $buyeruserid2);
// $extendedorderid = $order->TransactionArray->Transaction->ExtendedOrderID;
$buyeremail2 = $order->TransactionArray->Transaction->Buyer->Email;
$buyeremail = mysqli_real_escape_string($connect, $buyeremail2);
$salesrecordnumber2 = $order->TransactionArray->Transaction->ShippingDetails->SellingManagerSalesRecordNumber;
$salesrecordnumber = mysqli_real_escape_string($connect, $salesrecordnumber2);
$orderlineitemid2 = $order->TransactionArray->Transaction->OrderLineItemID;
$orderlineitemid = mysqli_real_escape_string($connect, $orderlineitemid2);
$title2 = $order->TransactionArray->Transaction->Item->Title;
$title = mysqli_real_escape_string($connect, $title2);
$sku2 = $order->TransactionArray->Transaction->Item->SKU;
$sku = mysqli_real_escape_string($connect, $sku2);
$quantitypurchased2 = $order->TransactionArray->Transaction->QuantityPurchased;
$quantitypurchased = mysqli_real_escape_string($connect, $quantitypurchased2);
$transactionprice2 = $order->TransactionArray->Transaction->TransactionPrice;
$transactionprice = mysqli_real_escape_string($connect, $transactionprice2);
echo $i;
echo "\n";
echo "BuyerUserID: " . $buyeruserid . "\n";
echo "extendedorderid: " . $quantitypurchased . "\n";
echo "BuyerEmail: " . $buyeremail . "\n";
echo "SellingManagerSalesRecordNumber: " . $salesrecordnumber . "\n";
echo "OrderLineItemID: " . $orderlineitemid . "\n";
// echo "ExtendedOrderID: " . $transaction->ExtendedOrderID . "\n";
echo "Title: " . $title . "\n";
echo "SKU: " . $sku . "\n";
echo "QuantityPurchased: " . $quantitypurchased . "\n";
echo "TransactionPrice: " . $transactionprice . "\n";
echo "\n";
$sql = "INSERT INTO eBayOrders (OrderLineItemID, SalesRecordNumber, BuyerUserID, BuyerEmail, Title, SKU, Quantity, TransactionPrice)
VALUES ('".$orderlineitemid."', '".$recordnumber."', '".$buyeruserid."', '".$buyeremail."', '".$title."', '".$sku."', '".$qty."', '".$transactionprice."')";
if ($connect->query($sql) === TRUE) {
echo "New Record Created Successfully";
} else {
echo "Error: " . $sql . "<br />" . $connect->error;
$connect->close();
die();
}
}
To avoid an error when an INSERT fails due to a unique key constraint, we can use the IGNORE option on the INSERT statement.
INSERT IGNORE INTO eBayOrders ...
If you use the IGNORE modifier, errors that occur while executing the INSERT statement are ignored. For example, without IGNORE, a row that duplicates an existing UNIQUE index or PRIMARY KEY value in the table causes a duplicate-key error and the statement is aborted. With IGNORE, the row is discarded and no error occurs. Ignored errors generate warnings instead.
But this also affects error conditions other than duplicate key exceptions.
As another option, we can use INSERT ... ON DUPLICATE KEY ...
Documentation available here:
Reference: https://dev.mysql.com/doc/refman/5.7/en/insert.html
Related
So hey guys!
I currently have a code that gets data from a custom table called wp_refundrequests, and prints them as a table to the page. On the page the admin can either Accept, or Deny the request by pressing a button on the side of each order. Denying the request just deletes the request from the table, but accepting should delete it from the current table and insert the information to the next table called "accepted requests".
The wp_refundrequests table contains customer's order that they want to refund.
The code that gets the info and prints it:
global $wpdb;
$requests = $wpdb->get_results("SELECT * FROM wp_refundrequests", ARRAY_A);
foreach ($requests as $row) {
echo "<div class='requests'>" . "<li class='refunds'>" . "Palauttajan nimi: ".
$row['customer_name'] . "</br>" ."Palautettavat tuotteet: ".$row['product_name']."<br> "."Määrä: ".
$row['product_qty'] . " "
. "<br>Kommentti: " . $row['comment'] . "<br> " . "Hinta: " . $row['refund_total'] . "€ " .
"<br>" . "Päivämäärä: " . $row['request_date'] . " " .
"<a class='right' href='admin-page?deleteid=" . $row['request_id'] . "'>Deny</a></li>" .
"<li class='refundaccepts'><a href='admin-page?acceptid=" . $row['request_id']
. "'>Accept</a></li>" . "</div>";
$_SESSION['custname'] = $row['customer_name'];
$_SESSION['prodname'] = $row['product_name'];
}
With my current code, the "Accept" button deletes it, and inserts information in to the new table, BUT the information that is inserted is wrong. It seems like it wants to either insert the latest data that had been inserted in to the wp_refundrequests table to the wp_acceptedrequests, or it keeps the data from the latest refund request and tries to insert that instead because for example as seen here(Sorry for the bits of Finnish as well):
If I were to click the "Accept" button on the above, older one, the query would still insert it like this:
So it basically inserts the info from the latest refund_request insert and inserts that instead of the one selected. However the one that had been selected still gets deleted from the table.
Here's the code that is triggered when the user clicks on "Accept"
$custname = $_SESSION['custname'];
$prodname = $_SESSION['prodname'];
if(isset($_GET['acceptid'])) {
$accept = $_GET['acceptid'];
/* Query to do whatever here */
$wpdb->print_error();
$wpdb->insert("wp_acceptedrequests", [
"customer_name" => "$custname",
"name_product" => "$prodname",
"date" => date("Y/m/d/G:i:sa") ,
]);
$wpdb->print_error();
$wpdb->query("DELETE FROM wp_refundrequests WHERE request_id = $accept");
}
I have to say I have no idea why it doesn't want to insert the selected request, please comment if there's something confusing, I'll try to clear it up then.
Thanks in advance!
You redefine $_SESSION with in foreach loop so at the end of foreach it will equal to the last one, pass each row parameter to it is accept link like this
"<li class='refundaccepts'><a href='admin-page?acceptid=" . $row['request_id']."&custname=".$row['customer_name']."&prodname=".$row['product_name']."'>Accept</a></li></div>";
Then call it the same way you get $accept-ID
if(isset($_GET['acceptid'])) {
$accept = $_GET['acceptid'];
$custname = $_GET['custname'];
$prodname = $_GET['prodname'];
Note:Iuse my phone so make sure if it was a syntax error in the href part of the code
Please try like this and comment out the session variable.
if(isset($_GET['acceptid'])) {
$accept = $_GET['acceptid'];
$accepted_requests = $wpdb->get_results("SELECT * FROM wp_refundrequests WHERE id = $accept", ARRAY_A);
if( !empty($accepted_requests) ) {
$insert = $wpdb->insert("wp_acceptedrequests", $accepted_requests);
if($insert) {
$wpdb->query("DELETE FROM wp_refundrequests WHERE request_id = $accept");
}
}
}
So, I'm using a database to store ship data.
As I load data into the database, I am checking whether the ship already exists. Sometimes, more than one ship has the same name. This code tries to go through the array, pull out all the ships with the same name, and then ask, in turn if that is the right one- if not, then it's yet another with the same name.
$sql = "SELECT Ship_Primary_Key, ship_original_rate, Ship_Launch_Year from Ships WHERE Ship_Name = '" . $shipname . "'";
$result = $conn->query ($sql);
if ($result-> num_rows > 0) //Does the ship name already exist in the DB? {
$ships_in_db = mysqli_fetch_all ($result,MYSQLI_ASSOC);
foreach ($ships_in_db as $row) {
echo "new record is " . $shipname . " as a " . $shiprate . ". Records already include " . $shipname . ", launched " . $row["Ship_Launch_Year"] . " as a " . $row ['ship_original_ra
$yesno = trim(fread(STDIN,5));
if ($yesno == "y" || $yesno == "yes") {
//ship already exists in the DB. Get the Key
echo $shipname . " is not new to the database and the key is " . $row["Ship_Primary_Key"] . "\n";
$shipkey = $row["Ship_Primary_Key"];
break 1;
}
}
//if you get through the loop of ships without assigning a primary key, ship is new
if (empty($shipkey)) {
$shipkey = write_ship_to_DB($shipname,$shiprate,$launchyear,$launchname,$conn);
}
}
So the problem is, I know that I have at least three ships with the same name in the first set of data (that are different). The problem is, it only ever asks about the first one. When I put 'n', it just goes on, and never asks about the second ship with the same name that already exists.
I think it's a problem with the Foreach loop and the break statement.
I'd appreciate any help with this
I've figured out the problem.
Because of the loop- I wasn't resetting the "Ship_Id" variable, which meant that the second or nth time a ship with the same name came around, a new ship wasn't created.
Now I've solved that. So the problem isn't this code at all- it's other code.
This is the part of the PHP code I am having the issue:
$query = "SELECT * FROM clients where idcard = '$idcard'";
$result = mysqli_query($dbc, $query)
or die("Error quering database.");
if(mysqli_fetch_array($result) == False) echo "Sorry, no clients found";
while($row = mysqli_fetch_array($result)) {
$list = $row['first_name'] . " " . $row['last_name'] . " " . $row['address'] . " " . $row['town'] . " " . $row['telephone'] . " " . $row['mobile'];
echo "<br />";
echo $list;
}
Even if I insert an existing idcard value I get no output when there is the if statement, an incorrect idcard displays "Sorry, no clients found" fine. However if I remove the if statement if I enter an existing idcard the data displays ok.
Can you let me know what is wrong with the code please ?
Thanks
Use mysqli_num_rows to count the results:
if(mysqli_num_rows($result) == 0) echo "Sorry, no clients found";
mysqli_fetch_array() fetches an item from the database.
This means your if() code fetches a first item from the database.
Then, when you call mysqli_fetch_array() again from the while() condition, the first item has already been fetched, and you are trying to fetch the second one ; which does not exist.
You must ensure that you use the result from mysqli_fetch_array() and not call it one time just for nothing ; or, as an alternative, you could use the mysqli_num_rows() function (quoting) :
Returns the number of rows in the result set.
$query = "SELECT * FROM clients where idcard = '$idcard'";
$result = mysqli_query($dbc, $query)
or die("Error quering database.");
if(mysqli_num_rows($result) == 0) {
echo "Sorry, no clients found";
}else{
while($row = mysqli_fetch_array($result)) {
$list = $row['first_name'] . " " . $row['last_name'] . " " . $row['address'] . " " . $row['town'] . " " . $row['telephone'] . " " . $row['mobile'];
echo $list . "<br />";
}
}
Try this.
EDITED: Added closing bracket.
Use mysqli_num_rows() to test if there is anything returned.
Imagine you put some money in your pocket.
Eventually an idea came to your mind to see if you are still have the money.
You are taking it out and count them. All right.
Still holding them in hand you decided to take them from pocket. Oops! The pocket is empty!
That's your problem.
To see if you got any rows from the database you can use mysqli_num_rows(). It will return the number of bills, without fetching them from the pocket.
The problem is, that you try to use mysqli_fetch_array to queck for the number of results. mysqli_fetch_array will fetch the first result, compare it to false and then discard it. The next mysqli_fetch_array will then fetch the second result, which is not existing.
If you want to check if any clients where found, you can use mysqli_num_rows like this:
$idcard = mysqli_escape_string($dbc, $idcard); // See below: Prevents SQL injection
$query = "SELECT * FROM clients where idcard = '$idcard'";
$result = mysqli_query($dbc, $query) or die("Error quering database.");
if(mysqli_num_rows($result) == 0) {
echo "Sorry, no clients found";
} else {
while($row = mysqli_fetch_array($result)) {
// Do whatever you want
}
}
If $idcard is a user supplied value, please look out for SQL injection attacks.
Im starting to learn PHP. When I run the script it had an error that said: "Assigned Employee:resource(6) of type (mysql result)" . Please help me and sorry for my bad English Here is the code:
include_once 'rnheader.php';
include_once 'rnfunctions.php';
</tr><tr><td><label for="AssignedEmp"> Assigned Employee:</label></td><td>';
$query = "SELECT UserName FROM employee where Classification_ClassificationID = '2'";
$result = queryMysql($query);
if (!queryMysql($query)) {
echo "Query fail: $query<br />" .
mysql_error() . "<br /><br />";
}
else
{
var_dump($result);
exit;
<select name = "UserName", "Name" size = "1">'; // or name="toinsert[]"
while ($row = mysqli_fetch_array($result)) {
'<option value="' . htmlspecialchars($row['UserName']) . '" >'
. htmlspecialchars($row['UserName'])
. '</option>';
}
}
'</select>';
?>
I isn't error. That output is produced by this line:
var_dump($result);
exit;
Since you are dumping the result of a query directly it is dumping a resource object and then you are immediately exiting the application. See after a query, you get data in a resource object, which is why we use the while loop that you have later. Remove the
exit;
And see what you get after you see
resource(6) of type (mysql result)
What is the queryMysql function that you have build? Can we see that?
Also, you have quotes here:
Classification_ClassificationID = '2'
Quotes are for strings, varchars, blobs, etc. An ID is typically an integer. Is your Classification_ClassificationID a varchar in your database or an integer. If it is an integer, take out the single quotes.
about my system the university complaint..stud or staff can use this system to complaint.
first user fill the form complaint and submit after submit user can view the complaint.now the problem is the complaint can't display....
this code for user complaint(userCampus.php):
?php // ------------------------------------------------------PROCESS -------------------------- START. ?>
<?php
$page_title='userCampus';
if(isset($_POST['submit'])){
if($_POST['secname']){
//$sn=escape_data($_POST['secname']);
$sn=$_POST['secname'];
// echo '<br> sn is : ' . $sn;
}else{
$sn=FALSE;
$message .='<p>You forgot to select section name!</p>';
}
if($_POST['subject']){
//$s=escape_data($_POST['subject']);
$s=$_POST['subject'];
}else{
$s=FALSE;
$message .='<p>you forgot to enter subject!</p>';
}
if($_POST['comment']){
//$c=escape_data($_POST['comment']);
$c=$_POST['comment'];
}else{
$c=FALSE;
$message .='<p>you forgot to enter comment!</p>';
}
}
if($sn && $s && $c ){
$userid = $_SESSION['username'];
$groupid = $_SESSION['secname'];
$query=" INSERT INTO campuscomplaint (secname, subject, comment, nameuser, groupid, userid)" .
" VALUES (" . "'" . $sn . "','" . $s . "','" . $c . "','" . $nameuser . "','" . $groupid . "','" . $userid . "')";
//echo 'query is : ' . $query . '<br>';
include "connectioncomplaint.php";
mysql_query($query);
echo'<p><b></b></p>';
include('done.php');
exit();
}
?>
<?php //------------------------------------------------ PROCESS ------------------------------------ end. ?>
<form action="<?php echo$_SERVER['PHP_SELF'];?>" method="post">
this code for view the complaint-userView.php(use for other page):
<?php //======================================================================================================================= PROCESS DATA ======================================================= START.
include "connectioncomplaint.php";
?>
<?php
$userid = $_GET['userid'];
$secname = $_GET['secname'];
$subject = $_GET['subject'];
$comment = $_GET['comment'];
//echo 'test : ' . $subject;
//Tarik data dari sini
$queryDetail = " SELECT * FROM campuscomplaint " .
" WHERE subject = '" . $subject . "' AND comment = '" . $comment . "' ";
//echo 'QUERY DETAIL :' . $queryDetail . '<br>' ;
$resultDetail = mysql_query($queryDetail);
//echo 'RESULT DETAIL :' . $resultDetail + 0 . '<br>' ;
$detail = mysql_fetch_array($resultDetail);
//echo $detail . '<br>';
//echo 'detail subject is : ' . $detail['subject'] . '<br>';
//echo 'detail comment is : ' . $detail['comment'] . '<br>';
//echo $detail[$x] . '<br>';
?>
i hope u all can help me....becoz i zero php.......
Let's see if we can check everything in on snip of code:
Paste the debugging code right after the line:
$detail = mysql_fetch_array($resultDetail);
Debugging code:
echo '<pre>';
echo '$userid = '.$userid."\n";
echo '$secname = '.$secname."\n\n";
echo 'Query: '.$queryDetail."\n\n";
echo 'Query results:'."\n\n";
print_r($detail);
echo '</pre>';
die();
That should make it clear where your problem is.
Also you should understand why you need to use mysql_real_escape_string() It's very important to make sure people don't do bad things to your website. Never send anything that can be changed by the user (such as GET or POST data) straight to a database without at least using this function. This escapes characters that would otherwise allow them to change your query (making it do something you don't want). To learn more about this google "sql injection attack"
one thing, from my experience. if something wrong with your query, just try it on mysql. ran your query in sql, and instead of your variables put some values, so you can easaly see what is your problem.
Looks like you forgot a $ sign before secname and you don't sanitize variables going to the query. So, try make it this way:
<?php
include "connectioncomplaint.php";
$userid = mysql_real_escape_string($_GET['userid']);
$secname = mysql_real_escape_string($_GET['secname']);
//Tarik data dari sini
$queryDetail = "SELECT * FROM campuscomplaint " .
"WHERE userid = '$userid' AND secname = '$secname'";
$resultDetail = mysql_query($queryDetail) or trigger_error(mysql_error()." in ".$queryDetail);
$detail = mysql_fetch_array($resultDetail);
?>
It looks you're not using a primary key on your campuscomplaint table, and using the various data fields as the identifier.
Since you say the data's inserted fine, you have to look at how you're retrieving it:
$userid = $_GET['userid'];
$secname = $_GET['secname'];
$subject = $_GET['subject'];
$comment = $_GET['comment'];
and then using these as your WHERE clause in the SQL query:
$queryDetail = " SELECT * FROM campuscomplaint " .
" WHERE subject = '" . $subject . "' AND comment = '" . $comment . "' ";
For one, this is vulnerable to SQL injection, and any $subject or $comment that contains single quotes will break the query. You are not checking to see if the query succeeded by calling mysql_error() after the mysql_query() call.
Also consider that you're retrieving these record "identifiers" from a GET query. These do have a limited length (different for various browsers). What if someone's comment is 10 kilobytes of data, but the browser will only send 1024 characters? Even if the database query succeeds, it will return no data because the comment fields will never match.
Let's say that the query string is limited to 100 characters (just for example purposes). You generate a list of complaints that looks something like this:
View complaint
Now remember, our query string is limited to 32 characters, so when the user clicks on the link, this is what will be sent to the server:
GET http://www.example.com/viewcomplaint.php?userid=7&secname=12&subject=This class sucks!!!&comment=Who hired this professor? He doesn't know a
and you'll end up with the following "identifiers"
$userid= 7;
$secname = 12;
$subject = "This class sucks!!!";
$comment = "Who hired this professor? He doesn't know a";
Notice how the $comment has been cut off. It will never match what is stored in the database, so your retrieval query will fail. Furthermore, notice that there is a single quote in it (doesn't). Inserting $comment into your query verbatim will now cause an SQL syntax error because of the imbalanced single-quote.
Add an auto_incrementing primary key field to your campuscomplaint table, like this:
ALTER TABLE campuscomplaint ADD id int unsigned not null auto_increment primary key;
and then all your complains can be identified by a single number, and you can retrieve them like this:
$id = (int)$_GET['id']; // force $id to be a number. better than just blindly using the value in a query
$query = "SELECT * FROM campuscomplaint WHERE id = $id;";
$result = mysql_query($query);
if (mysql_error()) {
// did the query fail? Say why!
die("MySQL query failed! Error cause: " . mysql_error());
}
etc....
The use of a numeric identifier will easily keep your query string very short (unless the people registering complaints file so many you get up into numbers hundreds or thousands of digits long).