How to email $_SESSION variables - php

I'm have a function which shows the user which products he has added to his cart. In this function I simply echo all the $_SESSION data. The problem is that I want to email all the $_SESSION data. I can't store the function in a variable and simple use $message = $function because in the email I get nothing is being displayed. So my question is: what's the easiest way to email $_SESSION data?
I use this code to display all sessions in a php file:
function cart_summary() {
foreach($_SESSION as $name => $value) {
if ($value>0) {
if (substr($name, 0, 5)=='cart_') {
$id = substr($name, 5, (strlen($name)-5));
$id2 = mysql_real_escape_string((int)$id);
$get_colour_size_category = "SELECT * FROM products WHERE id='$id2'";
$result_colour_size_category = mysql_query($get_colour_size_category);
while ($get_colour_size_category_row = mysql_fetch_assoc($result_colour_size_category)) {
$get_webshop_category = $get_colour_size_category_row['webshop_category'];
$get_webshop_category2 = mysql_real_escape_string((int)$get_webshop_category);
$get_name_and_price = "SELECT * FROM webshop_categories WHERE id='$get_webshop_category2'";
$result_name_and_price = mysql_query($get_name_and_price);
$row_name_and_price = mysql_fetch_assoc($result_name_and_price);
$sub = $row_name_and_price['price'] *$value;
echo '<tr><td>'. $row_name_and_price['ev_name'] .' '. $get_colour_size_category_row['colour'].' '. $get_colour_size_category_row['size'].'</td><td class="value"> '. $value .' </td><td> €'.number_format($row_name_and_price['price'], 2).'</td><td> €'.number_format($sub, 2).'</td><td></td></tr>';
}
?><?
}
$total += $sub;
}
}
I want to email the output of this

The easiest way would be to store the output of your $_SESSION array using print_r() (by using the optional parameter to return the information, rather than print it):
$session_data = print_r($_SESSION, TRUE);
Now it is a string containing all the session data and you can use it however you wish.

Managed to put the $_SESSION data in an email by doing the following:
function cart_summary() {
$message = "";
foreach($_SESSION as $name => $value) {
if ($value>0) {
if (substr($name, 0, 5)=='cart_') {
$id = substr($name, 5, (strlen($name)-5));
$id2 = mysql_real_escape_string((int)$id);
$get_colour_size_category = "SELECT * FROM products WHERE id='$id2'";
$result_colour_size_category = mysql_query($get_colour_size_category);
while ($get_colour_size_category_row = mysql_fetch_assoc($result_colour_size_category)) {
$get_webshop_category = $get_colour_size_category_row['webshop_category'];
$get_webshop_category2 = mysql_real_escape_string((int)$get_webshop_category);
$get_name_and_price = "SELECT * FROM webshop_categories WHERE id='$get_webshop_category2'";
$result_name_and_price = mysql_query($get_name_and_price);
$row_name_and_price = mysql_fetch_assoc($result_name_and_price);
$sub = $row_name_and_price['price'] *$value;
$message .= '<tr><td>'. $row_name_and_price['ev_name'] .' '. $get_colour_size_category_row['colour'].' '. $get_colour_size_category_row['size'].'</td><td class="value"> '. $value .' </td><td> €'.number_format($row_name_and_price['price'], 2).'</td><td> €'.number_format($sub, 2).'</td><td></td></tr>';
}
?><?
}
$total += $sub;
}
return $message
}
After I did this I was able to email the output of the function with
$message .= cart_email() . "\n";

Related

Using an If statement in PHP but not working

What I want to do is When I enter all my information (for client ID 199 in the picture) In my account being submit it, it goes into the database. BUT I want it to change to something and so i added an if statement
Here the code im adding to the existing code already at the BOTTOM of the code
if ($vpr_clid == 199) {
$vpr_cl_name = "Shelley Madsen And Associates";
}
if the ($vpr_clid = 199)
i want the clname to be "Shelley Madsen And Associates" then what is show in the table below instead of "Nice and White Smiles" (that an example of the results look like)
but when i chcek the database it not changing it and still show "Nice and White Smiles :(
I dont see any error, so it might be the placement of the code i have to put the IF statement in the huge php file? Dont know how to fix this issue
Thanks (the code below is the base code before i added the If statement)
I also insert the if statement before the function were called but still didnt work example
if ($vpr_clid == 199) {
$vpr_cl_name = "Shelley Madsen And Associates";
}
$result = InsertIntoPayReminder($link, $vars);
$result = GetVpr_Id($link, $vars);
<?php
session_start();
if ($_SESSION['company'] != "ACB") {
// redirect to the logout page
$redirect = 'logout.php';
include './includes/redirect.php';
}
class variables_obj {
var $vpr_plan = '';
var $vpr_id = '';
var $vpr_clid = '';
var $vpr_cl_name = '';
var $vpr_cl_phone = '';
var $vpr_call_start_date = '';
var $vpr_db_account = '';
var $vpr_db_fname = '';
var $vpr_db_mname = '';
var $vpr_db_lname = '';
var $vpr_rp_fname = '';
var $vpr_rp_mname = '';
var $vpr_rp_lname = '';
var $vpr_rp_address = '';
var $vpr_rp_city = '';
var $vpr_rp_state = '';
var $vpr_rp_zipcode = '';
var $vpr_rp_phonenum = '';
var $vpr_rp_phonetype = '';
var $vpr_date_entered = '';
var $newrecdt = '';
var $vpl_day_offset = '';
var $vpl_action = '';
var $vpr_promocode = '';
}
function ScrubPhone($old_phone_num) {
$phone_length = strlen($old_phone_num);
$new_phone_num = "";
for($i = 0; $i < $phone_length; $i = $i + 1) {
if(is_numeric($old_phone_num[$i])) {
$new_phone_num .= $old_phone_num[$i];
}
}
return $new_phone_num;
}
function ScheduleCreated($link, $vars) {
$query = "UPDATE v_payreminder SET vpr_schedule_created = '1' WHERE vpr_id='".$vars->vpr_id."'";
if (!mysql_query($query,$link)) {
die('Error: ' . mysql_error());
}
return true;
}
function CreateScheduleRow($link, $vars){
// echo "vpl_day_offset: ".$vars->vpl_day_offset."<br>";
// echo "vpl_action: ".$vars->vpl_action."<br>";
$plus_days = " +".$vars->vpl_day_offset." days";
// echo "plus days: ".$plus_days."<br>";
$date_offset = strtotime(date("Y-m-d", strtotime($vars->vpr_date_entered)).$plus_days);
$date_offset = date("Y-m-d", $date_offset);
// echo "date_offset: ".$date_offset."<br>";
// $date_offset = strtotime(date("Y-m-d",strtotime($vars->vpr_date_entered))." +".$vars->vpl_day_offset." days");
// $date_offset = strtotime(date("Y-m-d", strtotime($date)) . " +1 day");
// echo "date_offset: ".$date_offset."<br>";
$query = "INSERT INTO v_pr_schedule (
vpr_id,
vsc_plan,
vsc_date_entered,
vsc_action,
vsc_action_date,
vsc_status
) VALUES (
'$vars->vpr_id',
'$vars->vpr_plan',
'$vars->vpr_date_entered',
'$vars->vpl_action',
'$date_offset',
'VACT')";
//echo "query: ".$query."<br>";
if (!mysql_query($query,$link)) {
die('Error: ' . mysql_error());
}
return true;
}
function CreateSchedule($link, &$vars) {
// CREATE SCHEDULE
$query = " SELECT vpl_day_offset, vpl_action, vpl_condition
FROM v_plan
WHERE vpl_plan = '".$vars->vpr_plan."'";
// echo "query: ".$query."<br>";
$qresult = mysql_query($query);
if (!$qresult) {
print(mysql_error());
}
if ($qresult && mysql_num_rows($qresult) > 0 ) {
while ($row = mysql_fetch_array($qresult, MYSQL_ASSOC)) {
$vars->vpl_day_offset = $row['vpl_day_offset'];
$vars->vpl_action = $row['vpl_action'];
if ($row['vpl_condition'] == 'OO') {
CreateScheduleRow($link, $vars);
}
}
}
return true;
}
function InsertIntoPayReminder($link, &$vars) {
$vars->vpr_cl_name = strtr($vars->vpr_cl_name, "'", " ");
//echo "Client Name: ".$vars->vpr_cl_name."<br><br>";
//exit();
$sql="INSERT INTO v_payreminder (
vpr_clid,
vpr_cl_name,
vpr_cl_phone,
vpr_call_start_date,
vpr_db_account,
vpr_db_fname,
vpr_db_mname,
vpr_db_lname,
vpr_rp_fname,
vpr_rp_mname,
vpr_rp_lname,
vpr_rp_phonenum,
vpr_rp_phonetype,
vpr_rp_address,
vpr_rp_city,
vpr_rp_state,
vpr_rp_zipcode,
vpr_promo,
vpr_date_entered) VALUES (
'$vars->vpr_clid',
'$vars->vpr_cl_name',
'$vars->vpr_cl_phone',
'$vars->vpr_call_start_date',
'$vars->vpr_db_account',
'$vars->vpr_db_fname',
'$vars->vpr_db_mname',
'$vars->vpr_db_lname',
'$vars->vpr_rp_fname',
'$vars->vpr_rp_mname',
'$vars->vpr_rp_lname',
'$vars->vpr_rp_phonenum',
'$vars->vpr_rp_phonetype',
'$vars->vpr_rp_address',
'$vars->vpr_rp_city',
'$vars->vpr_rp_state',
'$vars->vpr_rp_zipcode',
'$vars->vpr_promocode',
'$vars->vpr_date_entered')";
if (!mysql_query($sql,$link)) {
die('Error2: ' . mysql_error());
}
return true;
}
function GetVpr_Id($link, &$vars) {
// Find out what vpr_id is
$query = "SELECT vpr_id FROM v_payreminder ";
$query .= "WHERE vpr_clid = '".$vars->vpr_clid."' AND vpr_date_entered = '".$vars->vpr_date_entered."'";
$qresult = mysql_query($query);
if (!$qresult) {
print(mysql_error());
}
if ($qresult && mysql_num_rows($qresult) > 0 ) {
$row = mysql_fetch_array($qresult, MYSQL_ASSOC);
$vars->vpr_id = $row['vpr_id'];
}
}
function InsertInActivity($link, $vars) {
// ENTER INTO ACTIVITY
$vaction_desc = 'PATIENT ENTERED';
$sql = "INSERT INTO v_pr_activity (
vpr_id,
va_plan,
va_action_dttm,
va_action_code,
va_action_desc,
va_disposition_code,
va_disposition_desc,
va_status_code,
va_status_desc
) VALUES (
'$vars->vpr_id',
'$vars->vpr_plan',
'$vars->vpr_date_entered',
'VINIT',
'$vaction_desc',
'SUCCESS',
'SUCCESS',
'VACT',
'ACTIVE'
)";
if (!mysql_query($sql,$link)) {
die('Error: ' . mysql_error());
}
}
include './includes/dblogin.php';
$vars = new variables_obj();
$vars->vpr_plan = 'VP01';
$vars->vpr_clid = $_SESSION['userid'];
//-------------------------------------------------------
// No commas can be in client name or they will
// mess up the Global Connect CSV file.
//-------------------------------------------------------
$vpr_cl_name = $_SESSION['username'];
$vpr_cl_name = str_replace(",", " ", $vpr_cl_name);
$vars->vpr_cl_name = $vpr_cl_name;
//-------------------------------------------------------
//-------------------------------------------------------
$vars->vpr_cl_phone = ScrubPhone($_SESSION['uphone']);
$vars->vpr_call_start_date = '0000-00-00';
$vars->vpr_db_account = $_POST['ndaccnum'];
$vars->vpr_db_fname = $_POST['ndfreqname'];
$vars->vpr_db_mname = $_POST['ndmname'];
$vars->vpr_db_lname = $_POST['ndlreqname'];
$vars->vpr_rp_fname = $_POST['ndrfreqname'];
$vars->vpr_rp_mname = $_POST['ndrmname'];
$vars->vpr_rp_lname = $_POST['ndrlreqname'];
$vars->vpr_rp_address = '';
$vars->vpr_rp_city = '';
$vars->vpr_rp_state = $_POST['ndrstatereqname'];
$vars->vpr_rp_zipcode = $_POST['ndrreqzipcode'];
$phonenumber = $_POST['1ndrreqphone'].$_POST['2ndrreqphone'].$_POST['3ndrreqphone'];
$vars->vpr_rp_phonenum = $phonenumber;
$vars->vpr_rp_phonetype = $_POST['treqphone'];
$vars->vpr_date_entered = date('Y-m-d H:i:s');
$vars->newrecdt = date('Ymd');
$vars->vpr_promocode = $_POST['promocode'];
// echo "vpr_plan: ".$vars->vpr_plan."<br>";
// echo "vpr_date_entered: ".$vars->vpr_date_entered."<br>";
// echo "newrecdt: ".$vars->newrecdt."<br>";
// echo "vpr_clid: ".$vars->vpr_clid."<br>";
// echo "vpr_id: ".$vars->vpr_id."<br>";
$result = InsertIntoPayReminder($link, $vars);
$result = GetVpr_Id($link, $vars);
$result = InsertInActivity($link, $vars);
$result = CreateSchedule($link, $vars);
$result = ScheduleCreated($link, $vars);
// echo "vpr_id: ".$vars->vpr_id."<br>";
mysql_close($link);
// redirect
$redirect = 'vpayremind.php';
include './includes/redirect.php';
?>
okay referencing the following lines..
if ( $vpr_clid == 199 ) {
$vpr_cl_name = "Shelley Madsen And Associates";
}
$result = InsertIntoPayReminder($link, $vars);
...and then:
function InsertIntoPayReminder($link, &$vars) {
$vars->vpr_cl_name = strtr($vars->vpr_cl_name, "'", " ");
so on and so forth... }
it doesnt seem as if you are actually setting the value of the class object. You seem to be setting some arbitrary php variable to the name you want, and then passing a totally different ' $vars ' object into the function. I don't see any reason to believe that the ' $vars ' you are passing into the function call contains the name value you want it to contain. You should be assigning the value of ' $vars ' before passing it in.
For instance:
if ( $vpr_clid == 199 ) {
$vars[ 'vpr_cl_name' ] = "Shelley Madsen And Associates";
}
then you can get rid of this line all together:
$vars->vpr_cl_name = strtr($vars->vpr_cl_name, "'", " ");

Invalid argument supplied for foreach() inside shopping cart ,

I am trying to get more than 1 item in my shopping cart array but I run into an issue
This is my database after inserting 1 item with post method
Items is defined in db as text
After trying to insert second product the items result gets overwritten.
My developers tools output after clicking add to cart
ADD
I am using add to cart button from my modal >https://pastebin.com/HKSRTG4L that is submitting via ajax and parsed to add-cart.php
Where I have add to cart function : https://pastebin.com/guv0rB6x
This is my code from cart.php :
<?php
include_once $_SERVER['DOCUMENT_ROOT']."/EcomApp/konfiguracija.php";
require_once $_SERVER['DOCUMENT_ROOT'].'/EcomApp/config.php';
include 'include/head.php';
include 'include/izbornik.php';
if($cart_id != ''){
$cartQ = $veza->prepare("SELECT * FROM cart WHERE id = '$cart_id';");
$cartQ->execute();
$result= $cartQ->fetch(PDO::FETCH_ASSOC);
$items = json_decode($result['items'],true);var_dump($items) ;
$i = 1;
$sub_total = 0;
$item_count = 0;
}
?>
<div class="col-md-12">
<div class="row">
<h2 class ="text-center">Your Shopping Cart </h2><hr>
<?php if($cart_id =='') :?>
<div class="bg-danger">
<p class="text-center text-danger">
Your shopping cart is empty!
</p>
</div>
<?php else: ?>
<table class="table" >
<thead><th>#</th><th>Item</th><th>Price</th><th>Quantity</th><th>Size</th><th>Sub Total</th></thead>
<tbody>
<?php
foreach ($items as $item){
$product_id =$item['id'];
$productQ = $veza ->prepare("SELECT * FROM products WHERE id = '$product_id'");
$productQ ->execute();
$product= $productQ->fetch(PDO::FETCH_ASSOC);
$sArray = explode (',',$product['sizes']);
foreach($sArray as $sizeString){
$s = explode(':',$sizeString);
if($s[0] ==$item['size']){
$available = $s[1];
}
}
?>
<tr>
<td><?=$i;?></td>
<td><?=$product['title'];?></td>
<td><?=$product['price'];?></td>
<td><?=$item['quantity'];?></td>
<td><?=$item['size'];?></td>
<td><?=$item['quantity'] * $product['price'];?></td>
</t>
<?php } ?>
</tbody>
</table>
<?php endif; ?>
</div>
<?php include 'include/footer.php';?>
I am 93% sure the problem is with array merge since currently the insert is overwriting the row with new results and not adding to the array.
<?php
require_once $_SERVER['DOCUMENT_ROOT'].'/EcomApp/konfiguracija.php';
require_once $_SERVER['DOCUMENT_ROOT'].'/EcomApp/config.php';
$product_id = sanitize($_POST['product_id']);
$size = sanitize($_POST['size']);
$available = sanitize($_POST['available']);
$quantity = sanitize($_POST['quantity']);
$item = array();
$item[]= array(
'id' => $product_id,
'size' => $size,
'quantity' => $quantity,
);
$domain = ($_SERVER['HTTP_HOST'] != 'localhost')?'.'.$_SERVER['HTTP_HOST']:false;
$query = $veza->prepare("SELECT * FROM products WHERE id = '$product_id'");
$query ->execute();
$product = $query->fetch(PDO::FETCH_ASSOC);
$_SESSION['success_launch'] = $product['title']. 'was added to your cart.';
//check does cookie cart exist
if($cart_id != ''){
$cartQ= $veza->prepare("SELECT * FROM cart WHERE id = '$cart_id'");
$cart = $cartQ->fetch(PDO::FETCH_ASSOC);
$previous_items = json_decode($cart['items'],true);
$item_match = 0;
$new_items = array();
foreach ($prevous_items as $pitem){
if($item[0]['id']==$pitem['id'] && $item[0]['size'] == $pitem['size']){
$pitem ['quantity']= $pitem['quantity']+$item[0]['quantity'];
if ($pitem['quantity']>$available){
$pitem['quantity'] = $available;
}
$item_match = 1;
}
$new_items[] = $pitem;
}
if($item_match != 1){
$new_items = array_merge($item,(array)$previous_items);
}
$items_json = json_encode($new_items);
$cart_expire = date("Y-m-d H:i:s", strtotime("+30 days"));
$something=$veza->prepare("UPDATE cart SET items = '$items_json',expire_date= '$cart_expire'WHERE id ='$cart_id'");
$something ->execute();
setcookie(CART_COOKIE,'',1,'/',$domain,false);
setcookie(CART_COOKIE,$cart_id,CART_COOKIE_EXPIRE,'/',$domain,false);
}else {
INSERT
//add cart inside database
$items_json = json_encode($item);
$cart_expire = date("Y-m-d H:i:s",strtotime("+30 days"));
$smth=$veza->prepare("INSERT INTO cart (items,expire_date) VALUES ('$items_json','$cart_expire')");
$smth->execute();
$cart_id = $veza->lastInsertId();
setcookie(CART_COOKIE,$cart_id,CART_COOKIE_EXPIRE,'/',$domain,false);
}
var_dump($cart_id);
?>
add to cart function : https://pastebin.com/guv0rB6x
function add_to_cart(){
jQuery('#modal_errors').html("");
var size = jQuery('#size').val();
var quantity = jQuery('#quantity').val();
var available = jQuery('#available').val();
var error = '';
var data = jQuery("#add_product_form").serialize();
if(size == '' || quantity == '' || quantity == 0){
error += '<p class= "bg-danger text-center">You must choose a size and quantity</p>';
jQuery('#modal_errors').html(error);
return;
}else if (quantity>available){
error += '<p class= "bg-danger text-center">There are only '+available+' available.</p>';
jQuery('#modal_errors').html(error);
return;
}else{
jQuery.ajax({
url: '/EcomApp/admin/parsers/add_cart.php',
method : 'post',
data : data,
success : function(){
location.reload();
},
error : function(){alert("Something went wrong");}
});
}
}
konfiguracija.php there is a (Undefined offset: 1) on line 65
$user_data['last'] = $fn1;
but I think it is not directly connected to the functionality
try{
$veza = new PDO("mysql:host=" . $host . ";dbname=" . $dbname,$dbuser,$dbpass);
$veza->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$veza->setAttribute(PDO::MYSQL_ATTR_INIT_COMMAND, "SET NAMES 'utf8';");
$veza->exec("SET NAMES 'utf8';");
}catch(PDOException $e){
switch($e->getCode()){
case 1049:
header("location: " . $eone . "error/wrongDBname.html");
exit;
break;
default:
header("location: " . $eone . "error/error.php?code=" . $e->getCode());
exit;
break;
}
}
require_once $_SERVER['DOCUMENT_ROOT'].'/EcomApp/config.php';
require_once BASEURL.'helpers/helpers.php';
session_start();
//
$cart_id = '';
if(isset($_COOKIE[CART_COOKIE])){
$cart_id = sanitize($_COOKIE[CART_COOKIE]);
}
if(isset($_SESSION['SDUser'])){
$user_id =$_SESSION['SDUser'];
$query = $veza->prepare("SELECT* FROM korisnik WHERE id ='$user_id'");
$query->execute();
$user_data = $query->fetch(PDO::FETCH_ASSOC);
$fn = explode(' ', $user_data['full_name']);
$user_data['first'] = $fn[0];
$user_data['last'] = $fn[1];
// print_r($user_data);
}
if(isset($_SESSION['success_launch'])){
echo '<h1><p class="text-success">'.$_SESSION['success_launch'].'</p></h1>';
unset($_SESSION['success_launch']);
}
if(isset($_SESSION['error_launch'])){
echo '<div class="success"><p class="text-success">'.$_SESSION['error_launch'].'</p></div>';
unset($_SESSION['error_launch']);
}
In add_cart.php:
$previous_items = json_decode($cart['items'],true);
$item_match = 0;
$new_items = array();
foreach ($prevous_items as $pitem){
Notice that $previous_items and $prevous_items are different.
That's why you're getting:
Notice: Undefined variable: prevous_items in
/opt/lampp/htdocs/EcomApp/admin/parsers/add_cart.php on line 29
You didn't take my previous advice to make your life easier.
Apparently working code is not enough. Always validate and fail fast ( http://www.practical-programming.org/ppl/docs/articles/fail_fast_principle/fail_fast_principle.html ):
if(!$cart_id){
$cartQ = $veza->prepare("SELECT * FROM cart WHERE id = ?");
$cartQ->execute([(int)$cart_id]);
$result= $cartQ->fetch(PDO::FETCH_ASSOC);
if (!isset($result['items'])) {
throw new \RuntimeException("The items were not found.");
}
$items = json_decode($result['items'],true);
if (!$items) {
throw new \RuntimeException("Invalid items format.");
}
$i = 1;
$sub_total = 0;
$item_count = 0;
}
As said, do something like this:
<?php
$validKeys = ['product_id', 'size', 'available', 'quantity'];
foreach ($validKeys as $key) {
if (!isset($_POST[$key])) {
throw new RuntimeException("Parameter $key is missing.");
}
}
require_once $_SERVER['DOCUMENT_ROOT'].'/EcomApp/konfiguracija.php';
require_once $_SERVER['DOCUMENT_ROOT'].'/EcomApp/config.php';
$product_id = sanitize($_POST['product_id']);
$size = sanitize($_POST['size']);
$available = sanitize($_POST['available']);
$quantity = sanitize($_POST['quantity']);
Most probably you missed something in the client side (javascript or HTML form), for instance, you might have misspelled "product_id".
ADDED:
https://pastebin.com/guv0rB6x
function add_to_cart(){
jQuery('#modal_errors').html("");
var size = jQuery('#size').val();
var quantity = jQuery('#quantity').val();
var available = jQuery('#available').val();
var error = '';
var data = jQuery("#add_product_form").serialize();
if(size == '' || quantity == '' || quantity == 0){
error += '<p class= "bg-danger text-center">You must choose a size and quantity</p>';
jQuery('#modal_errors').html(error);
return;
}else if (quantity>available){
error += '<p class= "bg-danger text-center">There are only '+available+' available.</p>';
jQuery('#modal_errors').html(error);
return;
}else{
jQuery.ajax({
url: '/EcomApp/admin/parsers/add_cart.php',
method : 'post',
data : data,
success : function(){
location.reload();
},
error : function(){alert("Something went wrong");}
});
}
}
You're not checking if the "product_id" field is empty.
ADDED:
Replace:
$previous_items = json_decode($cart['items'],true);
$item_match = 0;
$new_items = array();
foreach ($prevous_items as $pitem){
if($item[0]['id']==$pitem['id'] && $item[0]['size'] == $pitem['size']){
$pitem ['quantity']= $pitem['quantity']+$item[0]['quantity'];
if ($pitem['quantity']>$available){
$pitem['quantity'] = $available;
}
$item_match = 1;
}
$new_items[] = $pitem;
}
if($item_match != 1){
$new_items = array_merge($item,(array)$previous_items);
}
With something like this:
$previous_items = json_decode($cart['items'], true);
if (!$previous_items) {
$previous_items = array();
}
$items_by_unique = array();
foreach (array_merge($item, $previous_items) as $item) {
if (!isset($item['id'], $item['size'], $item['quantity'])) {
throw new RuntimeException('Found a invalid invalid data: ' . json_encode($item));
}
$unique = $item['id'] . '-' . $item['size'];
if (isset($items_by_unique[$unique])) {
$old_item = $items_by_unique[$unique];
$item['quantity'] = $old_item['quantity'];
}
if ($item['quantity'] > $available) {
$item['quantity'] = $available;
}
$items_by_unique[$unique] = $item;
}
$items_json = json_encode(array_values($items_by_unique));
The code has lots of issues that make very hard to find the mistakes and it's very hard to answer a question which is really several questions which are always increasing, as if we're making a debugging service for free... We could be discussing here for several hours and days, like a job, until everything is corrected. In that case, it's going to be very hard to help and take care of our personal lives and jobs.
Anyway, I'm going to enumerate some issues that make the code very hard to debug.
Most of the returned values are not validated, assuming that they're what's expected, instead failing immediately when there's an error. That means that you may only notice there's a mistake a lot later and hunt for the its source, which might be in a different file.
For instance, when you do something like this:
$query = $veza->prepare("SELECT * FROM products WHERE id = '$product_id'");
$query->execute();
$product = $query->fetch(PDO::FETCH_ASSOC);
You should always check if $product is at least not empty:
if (!$product) {
throw new RuntimeException("The product #$product_id" was not found.");
}
Also, putting variables inside SQL statements can be very dangerous. If you're using prepared statements you should do something like this:
$query = $veza->prepare("SELECT * FROM products WHERE id = ? LIMIT 1");
$query->execute([$product_id]);
The code does not take advantage of reusability. You can implement classes or functions and test them independently.
For instance, you could have done something like this:
<?php
/**
* Add a new item ...
*
* If it's being requested more items then available ...
*
* #param array $newItem The new item that should be added.
* #param array $items The list of items where the item should be added.
* #param integer $available Available items.
* #return void
*/
function add_item(array $newItem, array &$items, int $available=MAX_INT_MAX)
{
throw_error_if_invalid_item($newItem);
$unique = $newItem['id'] . '-' . $newItem['size'];
if (isset($items_by_unique[$unique])) {
add_item_quantity(
$items_by_unique[$unique],
$item['quantity'],
$available
);
} else {
$items[] = $newItem;
}
}
/**
* Add quantity ...
*
* #param array $item ...
* #param integer $moreQuantity ...
* #param integer $available ...
* #return void
*/
function add_item_quantity(array &$item, int $moreQuantity, int $available=MAX_INT_MAX)
{
$item['quantity'] += $moreQuantity;
if ($item['quantity'] > $available) {
$item['quantity'] = $available;
}
}
/**
* ...
*
* #param array $item ...
* #return void
*/
function throw_error_if_invalid_item(array $item)
{
if (!isset($item['id'], $item['size'], $item['quantity'])) {
throw new RuntimeException(
'Found a invalid invalid item data: ' . json_encode($item)
);
}
}
Then you can make individual test in isolated files:
<?php
$item = array(
'id' => 10,
'size' => 'm',
'quantity' => 2,
);
add_item_quantity($item, 3, 10);
if ($item['quantity'] != 5) {
echo "wrong! quantity = {$item['quantity']}\n";
} else {
echo "correct!\n";
}
If you put your classes or functions in dedicated files, you can reuse them as a library making the code easy to read, testable and secure:
<?php
throw_error_if_invalid_item($_POST);
$newItem = create_item($_POST);
$items = fetch_cart_items($cart_id);
add_item($newItem, $items, 10);
save_cart_items($items);
show_json_items($json);
With classes it would be much easier (eg: you wouldn't have to worry about missing array keys) and you could use PHPUnit to test all the functions and methods automatically. Check how I did that for a simple project:
https://github.com/pedroac/nonce4php
You can also make any error or warning halt the script:
<?php
set_error_handler(
function (int $errno , string $errstr, string $errfile, int $errline) {
http_response_code(500);
echo "ERROR #$errono:$errfile:$errline: $errstr";
die();
}
);
set_exception_handler(
function (Throwable $exception) {
http_response_code(500);
echo $exception->getMessage();
die();
}
);
If you follow the good practices, it will be much easier to found mistakes and let others help you.
I fixed this issue by casting the second argument of array_merge to an array:
$new_items = array_merge($item, (array)$previous_items);

Why doesn't my shopping cart count products of the same type?

This is the code so far.
I know its not very secure for injections, I'll take care of that later.
but my problem is that my cart adds product but sometimes i get the:
Unsupported operand types in E:\HostingSpaces\Knoppers1\topjop.nl\wwwroot\portal\core\tj_functions.php on line 358
error and i can't add multiple items of the same type.
line 358: $_SESSION['cart'][$uid] += 1;//
Maybe some of you know because other related questions didn't helped me.
function toevoegen(){
session_start();
if(!isset($_SESSION['cart'])){
$_SESSION['cart'] = array();
}
if(isset($_GET['add'])) {
$info = 'U heeft een product toegevoegd <META HTTP-EQUIV=REFRESH CONTENT="1; URL=http://topjop.nl/portal/winkelmandje.php">';
$uid = 0; //update id
foreach($_SESSION['cart'] as $id => $data){
if($data[0]==$_GET['add']){
$uid = $id;//
}
}
if($uid == 0){
array_push($_SESSION['cart'],array($_GET['add'],1));//
}else{
$_SESSION['cart'][$uid] += 1;//
}
}
else {
$info = '';
}
return $info;
}
function winkelmandje(){
mysql_connect("mysql8.mijnhostingpartner.nl","","");
mysql_select_db("Knoppers1_portal");
session_start();
$mand = '<table id="winkelmandje_tabel"><tr><td>Product</td>
<td>Stukprijs</td><td>Aantal</td><td>Totaal bedrag</td><td></td></tr>';
foreach($_SESSION['cart'] as $data){
$id = $data[0];//
$value = $data[1];//
if($value>0){
$get = mysql_query('SELECT id, name, price FROM products WHERE id='.mysql_real_escape_string((int)$id));
while ($get_row = mysql_fetch_assoc($get)) {
$totaal = $get_row['price']*$value;
$totaalprijs = number_format($totaal,2,',','.');
$mand .= '<tr><td>'.$get_row['name'].'</td>
<td>€'.$get_row['price'].'</td><td>'. $value .'</td> <td>€'.$totaalprijs.'</td></tr>';
}
}
else{
}
}
$aantal = '';
$kosten = '';
return $mand.'<tr><td><b>Totaal:</b></td><td></td><td><b>'. $aantal .'</b></td><td><b>'. $kosten .'</b></td></tr></table>';
}
toevoegen = ADD<br>
winkelmandje = SHOPPINGCART
Seems like $_SESSION['cart'][$uid] is an array containing id and value as you read it like that in the follwoing snippet:
$id = $data[0];//
$value = $data[1];//
it seems $_SESSION['cart'][$uid] is an array. so you can't do +=1
maybe do
$_SESSION['cart'][$uid][1] += 1; // increment $value

PHP concated string is blank at the end

I am trying to concatenate a string in a loop and when its is over the string is blank (or whatever value it was before). I am not exactly sure what is happening but I can't seem to find a similar issue.
$toItem = "";
$recpItem = "";
if(is_array($to))
{
foreach($to as $key=>$email)
{
$recpItem = $recpItem.'<item><recip dn="'.$email.'" sa="'.$email.'" ra="'.$email.'" al="" rt="SMTP" id="" ao="3" rf="0" ei="0" uri=""/></item>';
$email = htmlentities($email);
$toItem = $toItem.'<item><Rcp DN="'.$email.'" EM="'.$email.'" RT="SMTP" AO="3"/></item>';
}
}
I would add the code to an array then implode() it:
$to = array(
'bob#gmail.com',
'sally#gmail.com'
);
if(is_array($to)){
$recpItem = array();
$toItem = array();
foreach($to as $email){
$recpItem[] = '<item><recip dn="'.$email.'" sa="'.$email.'" ra="'.$email.'" al="" rt="SMTP" id="" ao="3" rf="0" ei="0" uri=""/></item>';
$email = htmlentities($email);
$toItem[] = '<item><Rcp DN="'.$email.'" EM="'.$email.'" RT="SMTP" AO="3"/></item>';
}
$recpHtml = implode($recpItem);
$toHtml = implode($toItem);
echo $recpHtml;
echo '<hr />';
echo $toHtml;
}

Delete all sublevels of categories in select using PHP

Problem:
I am trying to delete all sublevels of a category by using a class. Currently I can only make it delete two sublevels, not three.
The database table:
CREATE TABLE betyg_category (
CID int(11) NOT NULL AUTO_INCREMENT,
Item varchar(100) NOT NULL,
Parent int(11) NOT NULL DEFAULT '0',
PRIMARY KEY (CID)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
The PHP class:
<?php
class ItemTree
{
var $itemlist = array();
function ItemTree($query)
{
$result = mysql_query($query) or die ('Database Error (' . mysql_errno() . ') ' . mysql_error());
while ($row = mysql_fetch_assoc($result))
{
$this->itemlist[$row['CID']] = array(
'name' => $row['Name'],
'parent' => $row['Parent']
);
}
}
function get_tree($parent, $with_parent=0)
{
$item_tree = array();
if ($with_parent == 1 && $parent != 0)
{
$item_tree[$parent]['name'] = $this->itemlist[$parent]['name'];
$item_tree[$parent]['parent'] = $this->itemlist[$parent]['parent'];
$item_tree[$parent]['child'] = $this->get_tree($parent);
return $item_tree;
}
foreach ($this->itemlist as $key => $val)
{
if ($val['parent'] == $parent)
{
$item_tree[$key]['name'] = $val['name'];
$item_tree[$key]['parent'] = $val['parent'];
$item_tree[$key]['child'] = $this->get_tree($key);
}
}
return $item_tree;
}
function make_optionlist ($id, $class='', $delimiter='/')
{
$option_list = '';
$item_tree = $this->get_tree(0);
$options = $this->make_options($item_tree, '', $delimiter);
if (!is_array($id))
{
$id = array($id);
}
foreach($options as $row)
{
list($index, $text) = $row;
$selected = in_array($index, $id) ? ' selected="selected"' : '';
$option_list .= "<option value=\"$index\" class=\"$class\"$selected>$text</option>\n";
}
return $option_list;
}
function make_options ($item_tree, $before, $delimiter='/')
{
$before .= empty($before) ? '' : $delimiter;
$options = array();
foreach ($item_tree as $key => $val)
{
$options[] = array($key, '- '.$before.$val['name']);
if (!empty($val['child'])) {
$options = array_merge($options, $this->make_options($val['child'], $before.$val['name'], $delimiter));
}
}
return $options;
}
function get_navlinks ($navid, $tpl, $startlink='', $delimiter=' » ')
{
// $tpl typ: {name}
$search = array('{id}', '{name}');
$navlink = array();
while (isset($this->itemlist[$navid]))
{
$replace = array($navid, $this->itemlist[$navid]['name']);
$navlink[] = str_replace($search, $replace, $tpl);
$navid = $this->itemlist[$navid]['parent'];
}
if (!empty($startlink))
{
$navlink[] = str_replace($search, array(0, $startlink), $tpl);
}
$navlink = array_reverse($navlink);
return implode($delimiter, $navlink);
}
function show_tree ($parent=0, $tpl='%s', $ul_class='', $li_class='')
{
$item_tree = $this->get_tree($parent);
return $this->get_node($item_tree, $parent, $tpl, $ul_class, $li_class);
}
function get_node ($item_tree, $parent, $tpl, $ul_class, $li_class)
{
// $tpl typ: {name}
$search = array('{id}', '{name}');
$output = "\n<ul class=\"$ul_class\">\n";
foreach ($item_tree as $id => $item)
{
$replace = array($id, $item['name']);
$output .= "<li class=\"$li_class\">".str_replace($search, $replace, $tpl);
$output .= !empty($item['child']) ? "<br />".$this->get_node ($item['child'], $id, $tpl, $ul_class, $li_class) : '';
$output .= "</li>\n";
}
return $output . "</ul>\n";
}
function get_id_in_node ($id)
{
$id_list = array($id);
if (isset($this->itemlist[$id]))
{
foreach ($this->itemlist as $key => $row)
{
if ($row['parent'] == $id)
{
if (!empty($row['child']))
{
$id_list = array_merge($id_list, get_id_in_node($key));
} else
{
$id_list[] = $key;
}
}
}
}
return $id_list;
}
function get_parent ($id)
{
return isset($this->itemlist[$id]) ? $this->itemlist[$id]['parent'] : false;
}
function get_item_name ($id)
{
return isset($this->itemlist[$id]) ? $this->itemlist[$id]['name'] : false;
}
}
?>
Scenario:
Say you have the following structure in a :
Literature
-- Integration of sources
---- Test 1
It will result in the following in the database table:
When I try to delete this sublevel, it will leave the last sublevel in the database while it should delete it. The result will be:
The PHP code:
//Check if delete button is set
if (isset($_POST['submit-deletecategory']))
{
//Get $_POST variables for category id
$CategoryParent = intval($_POST['CategoryList']);
//Check if category is selected
if ($CategoryParent != "#")
{
//Get parent category and subsequent child categories
$query = "SELECT CID, Item AS Name, Parent FROM " . TB_CATEGORY . " ORDER BY Name";
$items = new ItemTree($query);
if ($items->get_item_name($_POST['CategoryList']) !== false)
{
//Build up erase list
$CategoryErase = $items->get_id_in_node($CategoryParent);
$CategoryEraseList = implode(", ", $CategoryErase);
}
else
{
$CategoryEraseList = 0;
}
//Remove categories from database
$query = "DELETE FROM " . TB_CATEGORY . " WHERE CID IN ($CategoryEraseList)";
$result = mysql_query($query) or die ('Database Error (' . mysql_errno() . ') ' . mysql_error());
//Return a confirmation notice
header("Location: settings.php");
exit;
}
}
Thank you in advance for any guidance I can get to solve the issue.
Here is a way to do it : use a recursive function, which will first look for the leaf item (the deepest in your tree). You remove children first, then the parent. And for each child, you remove child's children first, etc...
deleteSub(1);
function deleteSub($cat_id) {
$request = "SELECT * FROM ". TB_CATEGORY ." WHERE Parent = ".$cat_id;
$results = mysql_query($request);
while($child = mysql_fetch_array($results))
{
deleteSub($child["CID"]);
}
$request = "DELETE FROM ". TB_CATEGORY ." WHERE CID = ".$cat_id;
return mysql_query($request);
}
A better way could be use this kind of recursive function to store CIDs in an array, then make a single DELETE request, but I think you'll be able to adapt this code.
I'm not going to read or try to understand the entire code, but it seems to me you need some sort of recursion function. What I basicly would do is create a function that goes up in the hierachy and one that goes down.
Note: It has been a while since i've written anything in procedural mysql, so please check if the mysql_num_rows(),mysql_fetch_array and so on is written in the correct manner
EDIT: I've just noticed you only wanted a downwards deletion and therefore zessx's answer is more valid
<?php
function recursiveParent($id) {
$sql = 'SELECT parent FROM betyg_category WHERE CID=' . $id;
$result = mysql_query($sql);
if(mysql_num_rows($result) > 0) {
while($r = mysql_fetch_array($result,MYSQLI_ASSOC)) {
recursiveParent($r['parent']);
}
}
$sql = 'DELETE FROM betyg_category WHERE CID=' . $id;
mysql_query($sql);
}
function recursiveChild($parent) {
$sql = 'SELECT CID FROM betyg_category WHERE parent=' . $parent;
$result = mysql_query($sql);
if(mysql_num_rows($result) > 0) {
while($r = mysql_fetch_array($result,MYSQLI_ASSOC)) {
recursiveChild($r['CID']);
}
}
$sql = 'DELETE FROM betyg_category WHERE parent=' . $parent;
mysql_query($sql);
}
function delete($id) {
recursiveParent($id);
recursiveChild($id);
}
?>
This is my way to do. instead of recursive the query to run, i get all the child's id first then only run query. here the code refer:-
First, defined a variable called $delete_node_list as array. (to store all node id that need to be delete)
function delete_child_nodes($node_id)
{
$childs_node = $this->edirectory_model->get_child_nodes($node_id);
if(!empty($childs_node))
{
foreach($childs_node as $node)
{
$this->delete_child_nodes($node['id']);
}
}
$this->delete_node_list[] = $node_id;
}
in mysql..
$sql = 'DELETE FROM betyg_category WHERE CID IN '.$this->delete_node_list;
mysql_query($sql);

Categories