I lose some session variables in Chrome only
After reading every similar question and answer on this site, I have to note:
It is not a 404 / missing favicon issue
Also not a redirect issue. The session is started and closed properly.
I have a $_SESSION['customer'] and $_SESSION['order'] variable, for instance.
As expected, $_SESSION['customer'] holds an object of customer data, $_SESSION['order'] holds an array of products.
When I add a product to the order, I need to look up any customer discounts for this specific product. Then it turns out in Chrome, the $_SESSION['customer'] variable is missing, and the sql query returns no discounts, since there is no customer number.
Let's give you some code to work with:
I am on the update order page, where I still have my customer and order variable.
I call this function with an ajax request to return a list of products:
public function live_search_product(){
$this->load->model('orders', 'orders');
$qry = $_GET['qry'];
if (strlen($qry)>0) {
$products = $this->orders_model->search_products($qry, false);
if ($products){
foreach ($products as $product){
echo ''.$product['short_title'] . '<br>';
}
}
}
}
I select the product from the dropdown list, and end up in this function, where I suddenly have lost my $_SESSION['customer'] object and $_SESSION['order'] array. Please note that all my other session variables still exist.
public function add_product() {
$this->load->model('orders', 'orders');
$product = $this->orders_model->get_product_by_id($this->router->id);
$discount = $this->discount->get_discount($product->id, $product->product_group_id, $_SESSION['customer']->id, $_SESSION['customer']->group_id );
$_SESSION['order'][$this->router->id] = array('product' => $product ,
'quantity' => 1,
'rental' => 0,
'bruto' => $product->price_ex,
'discount' => $discount->discount_percentage,
'netto' => ((100 - $discount->discount_percentage)/100) * $product->price_ex,
'total' => ((100 - $discount->discount_percentage)/100) * $product->price_ex);
$this->calculate_order_totals();
}
In firefox and iexplorer and edge there is no problem, it works.
I really hope you have any other suggestions.
**** EDIT ****
Every controller has an index function that is called automatically. route orders/orders will call orders/orders/index, and for instance route orders/orders/add_product, will call the function add_product in the orders controller (residing in the orders folder).
It turns out that in Chrome, somehow I get routed to the index function of this orders controller. Which is an overview orders function where I reset all order variables, to make sure nothing is left when I open a new order.
I have changed that, so this specific situation is solved.
However, can not understand why I get redirected to this function, when calling the add_product function directly.
Any ideas?
Related
I am trying to implement a shopping cart object for the user, storing a serialized version of the cart in the $_SESSION super global at the index 'user_cart', however I am running into an issue where the data I have stored at that index no longer exists when I move to a new page.
I do have session_start at the top of every page, and when I echo session_id(), I do get the same session id across multiple pages. In addition, when I echo $_SESSION on both pages, the page the object gets created on displays correctly as follows:
Array ( [user_cart] => Array ( [count] => 0 [items] => Array ( ) ) )
However, once I actually click on add to cart to order something, then navigate to my 'view cart' page, I get the following as my $_SESSION variable:
Array ( [user_cart] => )
Where it recognizes that my $_SESSION array has an index 'user_cart' however nothing is stored inside of it.
This ONLY happens if I add something to cart first, if I were to just go to the view cart page without adding anything to the cart, I get the same array printed as I did on the homepage where the session is created.
Here is some of the code I have in my 'add_to_cart_handler.php' file where I think the issue is arises:
$serialized=$_SESSION['user_cart'];
$cartobj=new ShoppingCart();
$cartobj->__unserialize($serialized);
$cartobj->addToCart($new_item_id, 1);
$_SESSION['user_cart']=$cartobj->__serialize();
header('Location: http://localhost/website/heroku/order.php');
Here is a snippet of both my __serialize() and __unserialize():
public function __serialize() {
return [
'count'=>$this->count,
'items'=>$this->serialize_items()
];
}
public function __unserialize(array $data) {
$this->count=$data[0];
$this->items=$this->unserialize_items($data[1]);
}
public function serialize_items() {
$serialized=array();
foreach($this->items as $item) {
$serialized[]=$item->__serialize();
}
return $serialized;
}
public function unserialize_items() {
$unserialized=array();
foreach($unserialized as $item){
$tmpItem=new CartItem();
$tmpItem->unserialize($item);
$unserialized[]=$tmpItem;
}
}
Where unserialize_items() and serialize_items() are essentially the same thing, but with the CartItem object.
EDIT:
It might be worth noting that my $_SESSION['user_cart'] has a value of null.
The solution can be found here: PHP session lost after redirect
The issue was that the script was still running in the addtocart_handler, and when redirected back to the most previous page, the script was still running.
I'm currently trying to add a custom option to a specific orderline on add to cart via the following:
public function addToPackageQuote()
{
$cart = Mage::getSingleton("checkout/cart");
$quote = Mage::getSingleton("checkout/session")->getQuote();
$packageId = Mage::getModel('MyTuxedo_OPP/Package')->checkPackageId();
$products = $this->sortArray();
foreach ($products as $productInfo) {
try {
$split = explode(",", $productInfo);
$_product = Mage::getModel('catalog/product')->load($split[0]);
if($_product->isConfigurable()) {
$simpleId = $this->getConfigurableSimple($split[1],$split[3],$split[0]);
} else {
$simpleId = $split[0];
}
$product = Mage::getModel('catalog/product')->load($simpleId);
$options = new Varien_Object(array(
"qty" => 1,
"custom_options" => array(
"package" => $packageId,
"packageName" => Mage::helper('MyTuxedo_OPP')->getPackageName()
)
));
$quote->addProduct($product, $options);
$this->_getSession()->setCartWasUpdated(true);
$quote->save();
} catch (Exception $e) {
echo $e->getMessage();
}
$this->addFreeItems();
}
$cart->save();
unset($_SESSION['products']);
unset($_SESSION['productId']);
$cart->save();
// Let's unset all the package sessions (apart from a few that are needed!).
$this->kill();
}
This method is completely seperate from the generic add to cart handler, and is used purely in a packages system so that it adds simple products exclusively (also breaks down configurables super attribute to find the simple product too).
These simple products have no custom options attached to them in the Magento backend, nor is it a goal to add custom options to the product itself. What I would like to do is attach custom options to the order-line that is then transferred over to the order if a purchase is made. So effectively data that is added at the add to cart method and no where else!
The add to cart method works as expected it's just not including the custom options I am trying to attach. I have also tried defining the options object as simply:
$options = new Varien_Object(array(
"qty" => 1,
"package" => $packageId,
"packageName" => Mage::helper('MyTuxedo_OPP')->getPackageName()
)
The above info, not including qty is not in the orderline object at all, and I can't seem to work out where to move on from here.
Endlessly googling at the moment so some help would be most appreciated!!
I do appreciate I’m instantiating the product model object twice in this, however the plan is to just get it working then optimise! :)
You have to set the custom options for the product before adding it to cart.
$product->setCustomOptions($options);
The in Mage_Sales_Model_Quote::_addCatalogProduct() the custom options will be added to the cart item.
See also here: http://www.magentocommerce.com/boards/viewthread/49659/
By the way: Your code may be pretty slow because you are loading products twice in a foreach loop. You should consider some refactoring by using the product collection instead. Also it looks kind of hackish to directly access the $_SESSION variable here. You could rather use the Checkout Session for that (Mage::getSingleton('checkout/session')).
I have now resolved this, after much headache. You can add a custom option to the cart and not have to instantiate the product object and save a custom option to do this, it can be done via tacking onto an observer, and pulling the quote items.
After tacking onto: sales_quote_add_item
I then used:
public function addCustomData($observer) {
$event = $observer->getEvent();
$quote_item = $event->getQuoteItem();
$quote = $session->getQuote();
$quote_item->addOption(array("product_id" => $quote_item->getProduct()->getId(),
"product" => $quote_item->getProduct(),
"code" => 'PackageId',
"value" => Mage::getModel('MyTuxedo_OPP/Package')->checkPackageId()
));
$quote->save();
}
It is most important to include the product object and id, as the function doesn't use the loaded object for some reason.
You can then get at the object via:
$_item->getOptionByCode('PackageId')->getValue();
Quick piece of handy info, if it dumps a stack trace in front of you it can't find the defined option, lose the getValue() (if using var_dump) function to see if you are getting a null value, otherwise xdebug will give you a ton of hints to get around it.
Im building an e-commerce site for wholesale foods and the pricing for products change depending on the user logged in. Ive looked at member pricing and basically every module i could find to do with altering the price but they are either for drupal 6 or not really what im after. Im using Drupal 7 with ubercart 3.
Ive found this module http://drupal.org/project/uc_custom_price. It adds a field within product creation that allows custom php code to be added to each individual product which is exactly what im after. however im not that good with php which is why ive been hunting modules instead of changing code.
What ive got at the moment is:
if ([roles] == 'test company') {
$item->price = $item->price*0.8;
}
Except the [roles] part is the wrong thing to use there and it just throws errors. Ive tried using things like $users->uid =='1' to try to hook onto a user like that but that didnt work either.
what would be the correct variable to put there?
thanks
try this Drupal 7 global $user object
global $user; // access the global user object
if(in_array("administrator",$user->roles)){ // if its administrator
$item->price = $item->price*0.8;
}elseif(in_array("vip",$user->roles)){ // if its a vip
//..
}elseif(in_array("UserCompanyX",$user->roles)){ // if its a user from company X
//..
}
or
if($user->roles[OFFSET] == "ROLE"){
// price calculation
}
$user->roles is an array of the roles assigned to the user.
hope it helped
Make your own module with UC Price API:
http://www.ubercart.org/docs/developer/11375/price_api
function example_uc_price_handler() {
return array(
'alter' => array(
'title' => t('Reseller price handler'),
'description' => t('Handles price markups by customer roles.'),
'callback' => 'example_price_alterer',
),
);
}
function example_price_alterer(&$price_info, $context, $options = array()){
global $user;
if (in_array("reseller", $user->roles)) { //Apply 30% reseller discount
$price_info["price"] = $context["subject"]["node"]->sell_price - (
$context["subject"]["node"]->sell_price * 0.30) ;
}
return;
}
See also: http://www.ubercart.org/forum/development/14381/price_alteration_hook
I’m using a cart library to get orders in my web bookstore. But when I call a addCart function on one of my book it’s works, but not all the time. Please, help
There is my model function:
function get_books_by_ID($id)
{
$this->db->where('BOOK_ID', $id);
$query = $this->db->get('books');
return $query;
echo vardump($query);
}
Controller:
function addCards($id=1)
{
$query = $this->Kategorie_model->get_books_by_ID($id);
if($query->num_rows() > 0)
{
$item = $query->row();
$data = array(
'id' => $item->BOOK_ID,
'qty' => 1,
'price' => $item->BOOK_Price,
'name' => $item->BOOK_Title
);
$this->cart->insert($data);
}
}
View:
<tr>
<td class="color"><b>Cena: </b><?php echo $data->BOOK_Price;?>zł</td>
<td class="border" id="koszyk" ><?php echo anchor('ksiegarnia/addCards/'.$data->BOOK_ID, 'Koszyk'); ?></td>
</tr>
UPDATE:
vardump is nothing necessary. I want to use var_dump. But the problem is related with adding items to the session with carts library. I have a bookstore, and when I call a addCarts function, sometimes items is added to Carts, and cart function total() and total_items displaying it, but sometimes when I call function, nothing is happened. The items not add into carts. I don't now why this thing have a place. Why the carts library works randomly?
I just ran into this issue and it seems that in the codeigniter cart library the insert function checks the product(s) id and name against a regex only allow alpha-numeric, dashes, underscores and periods
Adjust the regex to what may come up:
$this->cart->product_id_rules = '.a-z0-9_';
$this->cart->product_name_rules = '.\:-_ a-z0-9';
In my case it would randomly add thing to carts too. If you turn on logging and check you'll be able to see that the name or id may contain invalid chars
i am doing as you did, and like you said, the cart is randomly works,
it seems can only contain 3 product in cart when i add another product, the product i added wont get into cart..
i am so hopeless, i get mind to change cart libraries with 3rd party
it is because i did not setting session to save to database, like in the tutorial (cart & session) the cart need session to write to database in order to work.
when i set session write to database, the problem solved
you can try...
Hmmmmm I worked on some PHP code that pulls stock levels from my supplier and inserts the stock level into the database based on the product's SKU. I've inserted it into the class.product.php file which contains all the code used for the individual product page. The issue I'm having is that when the product page loads, it doesn't show the updated inventory levels unless you hit refresh. I've moved the code all over the place and can't get it to update the database and have the updated number loaded before the page is displayed.
Even when placed before all other code, I still have to refresh the page to see the update. I don't know what else to do about this. I feel like perhaps, I don't truly understand how PHP loads code. I've been working on this every day for weeks. I tried running it as an include file, on a separate page, at the top, in the middle, all over the place.
In the class file, it looks like I have the code before it calls the code to display the stock levels, that's why I'm so confused as to why it won't load the updates.
Any thoughts on why I'm unable to see the changes unless I refresh the page?
Thanks!
PHP loads the content when you request it ,
so opening a page gets the content ONCE,
The thing you want to do to get data updated is have AJAX calls to a php function that return data in JSON or XML format
Here you can see some examples but consider googling around for more detailed examples.
The problem was my code was not running until after the code to get and display the product data because I was using info from the product data that was only being called once. So the product data had be be called first in order for my code to run. So to fix this, I had to create a new function that would get the sku and pass it to my code before the code that called the product data to be displayed on the page. I copied the existing function to get the product data, renamed it to GetRealTimeStockLevels and added my code to the bottom of it. I put the call for the function above the call for the product data and it worked like I wanted. I'm glad I got this worked out, now I can add the same feature to the checkout page.
Below is the function call at the start of the page and then the function I created to run my update code.
public function __construct($productid=0)
{
// Get the stock level from supplier and update the database
$this->_GetRealtimeStockLevels($productid);
// Load the data for this product
$this->_SetProductData($productid);
public function _GetRealtimeStockLevels($productid=0)
{
if ($productid == 0) {
// Retrieve the query string variables. Can't use the $_GET array
// because of SEO friendly links in the URL
SetPGQVariablesManually();
if (isset($_REQUEST['product'])) {
$product = $_REQUEST['product'];
}
else if(isset($GLOBALS['PathInfo'][1])) {
$product = preg_replace('#\.html$#i', '', $GLOBALS['PathInfo'][1]);
}
else {
$product = '';
}
$product = $GLOBALS['ISC_CLASS_DB']->Quote(MakeURLNormal($product));
$productSQL = sprintf("p.prodname='%s'", $product);
}
else {
$productSQL = sprintf("p.productid='%s'", (int)$productid);
}
$query = "
SELECT p.*, FLOOR(prodratingtotal/prodnumratings) AS prodavgrating, pi.*, ".GetProdCustomerGroupPriceSQL().",
(SELECT COUNT(fieldid) FROM [|PREFIX|]product_customfields WHERE fieldprodid=p.productid) AS numcustomfields,
(SELECT COUNT(reviewid) FROM [|PREFIX|]reviews WHERE revstatus='1' AND revproductid=p.productid AND revstatus='1') AS numreviews,
(SELECT brandname FROM [|PREFIX|]brands WHERE brandid=p.prodbrandid) AS prodbrandname,
(SELECT COUNT(imageid) FROM [|PREFIX|]product_images WHERE imageprodid=p.productid) AS numimages,
(SELECT COUNT(discountid) FROM [|PREFIX|]product_discounts WHERE discountprodid=p.productid) AS numbulkdiscounts
FROM [|PREFIX|]products p
LEFT JOIN [|PREFIX|]product_images pi ON (pi.imageisthumb=1 AND p.productid=pi.imageprodid)
WHERE ".$productSQL;
if(!isset($_COOKIE['STORESUITE_CP_TOKEN'])) {
// ISC-1073: don't check visibility if we are on control panel
$query .= " AND p.prodvisible='1'";
}
$result = $GLOBALS['ISC_CLASS_DB']->Query($query);
$row = $GLOBALS['ISC_CLASS_DB']->Fetch($result);
if (!$row) {
return;
}
$this->_product = $row;
$this->_prodid = $row['productid'];
$this->_prodname = $row['prodname'];
$this->_prodsku = $row['prodcode'];
$GLOBALS['CurrentProductLink'] = ProdLink($this->_prodname);
$server_url = "http://ms.com/fgy/webservices/index.php";
$request = xmlrpc_encode_request("catalog.getStockQuantity", array($this->_prodsku));
$context = stream_context_create(array('http' => array(
'method' => "POST",
'header' => "Content-Type: text/xml",
'content' => $request
)));
$file = file_get_contents($server_url, false, $context);
$response = xmlrpc_decode($file);
$query = sprintf("UPDATE [|PREFIX|]products SET prodcurrentinv='$response' where prodcode='%s'", $GLOBALS['ISC_CLASS_DB']->Quote($this->_prodsku));
$result = $GLOBALS['ISC_CLASS_DB']->Query($query);
}