monkeytooth Posted February 27, 2010 Share Posted February 27, 2010 I don't know to much about the extract function, or what it does exactly. However in the name of trying to save time I went out and got myself a premade cart script. Ok fine, dandy. Ill work with it. Unfortunately it does not work out of the box. Like I anticipated and hoped it would. The problem is the people who developed it are building it off of custom classes and functions, and I think the class: class jcart { var $total = 0; var $itemcount = 0; var $items = array(); var $itemprices = array(); var $itemqtys = array(); var $itemname = array(); the way it was laid out is incorrect. I could be wrong, I dont know. Anywho I need some eyes to help me out here Ive looked at it a couple times I know enough to diagnose usually what an issue is, but Im stumped maybe to stressed from my upcoming deadline I dont know. Im not necessarily looking for a full rewrite here or anything else of the sort. What I am looking for is some opinions on how I can patch this, maybe catch a glitch Im not catching anything. Here are the 2 lines throwing errors in the script: Line 1 extract($jcart); Line 2 if ($_POST['jcart_update_item'] == $jcart['text']['update_button']) One other thing I have noticed is that the class brackets wrap over all the other functions in the file below is the whole file. <?php // JCART v1.1 // http://conceptlogic.com/jcart/ // SESSION BASED SHOPPING CART CLASS FOR JCART /********************************************************************** Based on Webforce Cart v.1.5 (c) 2004-2005 Webforce Ltd, NZ http://www.webforce.co.nz/cart/ **********************************************************************/ // USER CONFIG include_once('jcart-config.php'); // DEFAULT CONFIG VALUES include_once('jcart-defaults.php'); // JCART class jcart { var $total = 0; var $itemcount = 0; var $items = array(); var $itemprices = array(); var $itemqtys = array(); var $itemname = array(); // CONSTRUCTOR FUNCTION function cart() {} // GET CART CONTENTS function get_contents() { $items = array(); foreach($this->items as $tmp_item) { $item = FALSE; $item['id'] = $tmp_item; $item['qty'] = $this->itemqtys[$tmp_item]; $item['price'] = $this->itemprices[$tmp_item]; $item['name'] = $this->itemname[$tmp_item]; $item['subtotal'] = $item['qty'] * $item['price']; $items[] = $item; } return $items; } // ADD AN ITEM function add_item($item_id, $item_qty=1, $item_price, $item_name) { // VALIDATION $valid_item_qty = $valid_item_price = false; // IF THE ITEM QTY IS AN INTEGER, OR ZERO if (preg_match("/^[0-9-]+$/i", $item_qty)) { $valid_item_qty = true; } // IF THE ITEM PRICE IS A FLOATING POINT NUMBER if (is_numeric($item_price)) { $valid_item_price = true; } // ADD THE ITEM if ($valid_item_qty !== false && $valid_item_price !== false) { // IF THE ITEM IS ALREADY IN THE CART, INCREASE THE QTY if($this->itemqtys[$item_id] > 0) { $this->itemqtys[$item_id] = $item_qty + $this->itemqtys[$item_id]; $this->_update_total(); } // THIS IS A NEW ITEM else { $this->items[] = $item_id; $this->itemqtys[$item_id] = $item_qty; $this->itemprices[$item_id] = $item_price; $this->itemname[$item_id] = $item_name; } $this->_update_total(); return true; } else if ($valid_item_qty !== true) { $error_type = 'qty'; return $error_type; } else if ($valid_item_price !== true) { $error_type = 'price'; return $error_type; } } // UPDATE AN ITEM function update_item($item_id, $item_qty) { // IF THE ITEM QTY IS AN INTEGER, OR ZERO // UPDATE THE ITEM if (preg_match("/^[0-9-]+$/i", $item_qty)) { if($item_qty < 1) { $this->del_item($item_id); } else { $this->itemqtys[$item_id] = $item_qty; } $this->_update_total(); return true; } } // UPDATE THE ENTIRE CART // VISITOR MAY CHANGE MULTIPLE FIELDS BEFORE CLICKING UPDATE // ONLY USED WHEN JAVASCRIPT IS DISABLED // WHEN JAVASCRIPT IS ENABLED, THE CART IS UPDATED ONKEYUP function update_cart() { // POST VALUE IS AN ARRAY OF ALL ITEM IDs IN THE CART if (is_array($_POST['jcart_item_ids'])) { // TREAT VALUES AS A STRING FOR VALIDATION $item_ids = implode($_POST['jcart_item_ids']); } // POST VALUE IS AN ARRAY OF ALL ITEM QUANTITIES IN THE CART if (is_array($_POST['jcart_item_qty'])) { // TREAT VALUES AS A STRING FOR VALIDATION $item_qtys = implode($_POST['jcart_item_qty']); } // IF NO ITEM IDs, THE CART IS EMPTY if ($_POST['jcart_item_id']) { // IF THE ITEM QTY IS AN INTEGER, OR ZERO, OR EMPTY // UPDATE THE ITEM if (preg_match("/^[0-9-]+$/i", $item_qtys) || $item_qtys == '') { // THE INDEX OF THE ITEM AND ITS QUANTITY IN THEIR RESPECTIVE ARRAYS $count = 0; // FOR EACH ITEM IN THE CART foreach ($_POST['jcart_item_id'] as $item_id) { // GET THE ITEM QTY AND DOUBLE-CHECK THAT THE VALUE IS AN INTEGER $update_item_qty = intval($_POST['jcart_item_qty'][$count]); if($update_item_qty < 1) { $this->del_item($item_id); } else { // UPDATE THE ITEM $this->update_item($item_id, $update_item_qty); } // INCREMENT INDEX FOR THE NEXT ITEM $count++; } return true; } } // IF NO ITEMS IN THE CART, RETURN TRUE TO PREVENT UNNECSSARY ERROR MESSAGE else if (!$_POST['jcart_item_id']) { return true; } } // REMOVE AN ITEM /* GET VAR COMES FROM A LINK, WITH THE ITEM ID TO BE REMOVED IN ITS QUERY STRING AFTER AN ITEM IS REMOVED ITS ID STAYS SET IN THE QUERY STRING, PREVENTING THE SAME ITEM FROM BEING ADDED BACK TO THE CART SO WE CHECK TO MAKE SURE ONLY THE GET VAR IS SET, AND NOT THE POST VARS USING POST VARS TO REMOVE ITEMS DOESN'T WORK BECAUSE WE HAVE TO PASS THE ID OF THE ITEM TO BE REMOVED AS THE VALUE OF THE BUTTON IF USING AN INPUT WITH TYPE SUBMIT, ALL BROWSERS DISPLAY THE ITEM ID, INSTEAD OF ALLOWING FOR USER FRIENDLY TEXT SUCH AS 'remove' IF USING AN INPUT WITH TYPE IMAGE, INTERNET EXPLORER DOES NOT SUBMIT THE VALUE, ONLY X AND Y COORDINATES WHERE BUTTON WAS CLICKED CAN'T USE A HIDDEN INPUT EITHER SINCE THE CART FORM HAS TO ENCOMPASS ALL ITEMS TO RECALCULATE TOTAL WHEN A QUANTITY IS CHANGED, WHICH MEANS THERE ARE MULTIPLE REMOVE BUTTONS AND NO WAY TO ASSOCIATE THEM WITH THE CORRECT HIDDEN INPUT */ function del_item($item_id) { $ti = array(); $this->itemqtys[$item_id] = 0; foreach($this->items as $item) { if($item != $item_id) { $ti[] = $item; } } $this->items = $ti; $this->_update_total(); } // EMPTY THE CART function empty_cart() { $this->total = 0; $this->itemcount = 0; $this->items = array(); $this->itemprices = array(); $this->itemqtys = array(); $this->itemname = array(); } // INTERNAL FUNCTION TO RECALCULATE TOTAL function _update_total() { $this->itemcount = 0; $this->total = 0; if(sizeof($this->items > 0)) { foreach($this->items as $item) { $this->total = $this->total + ($this->itemprices[$item] * $this->itemqtys[$item]); // TOTAL ITEMS IN CART (ORIGINAL wfCart COUNTED TOTAL NUMBER OF LINE ITEMS) $this->itemcount += $this->itemqtys[$item]; } } } // PROCESS AND DISPLAY CART function display_cart($jcart) { // JCART ARRAY HOLDS USER CONFIG SETTINGS extract($jcart); // ASSIGN USER CONFIG VALUES AS POST VAR LITERAL INDICES // INDICES ARE THE HTML NAME ATTRIBUTES FROM THE USERS ADD-TO-CART FORM $item_id = $_POST[$item_id]; $item_qty = $_POST[$item_qty]; $item_price = $_POST[$item_price]; $item_name = $_POST[$item_name]; // ADD AN ITEM if ($_POST[$item_add]) { $item_added = $this->add_item($item_id, $item_qty, $item_price, $item_name); // IF NOT TRUE THE ADD ITEM FUNCTION RETURNS THE ERROR TYPE if ($item_added !== true) { $error_type = $item_added; switch($error_type) { case 'qty': $error_message = $text['quantity_error']; break; case 'price': $error_message = $text['price_error']; break; } } } // UPDATE A SINGLE ITEM // CHECKING POST VALUE AGAINST $text ARRAY FAILS?? HAVE TO CHECK AGAINST $jcart ARRAY if ($_POST['jcart_update_item'] == $jcart['text']['update_button']) { $item_updated = $this->update_item($_POST['item_id'], $_POST['item_qty']); if ($item_updated !== true) { $error_message = $text['quantity_error']; } } // UPDATE ALL ITEMS IN THE CART if($_POST['jcart_update_cart'] || $_POST['jcart_checkout']) { $cart_updated = $this->update_cart(); if ($cart_updated !== true) { $error_message = $text['quantity_error']; } } // REMOVE AN ITEM if($_GET['jcart_remove'] && !$_POST[$item_add] && !$_POST['jcart_update_cart'] && !$_POST['jcart_check_out']) { $this->del_item($_GET['jcart_remove']); } // EMPTY THE CART if($_POST['jcart_empty']) { $this->empty_cart(); } // DETERMINE WHICH TEXT TO USE FOR THE NUMBER OF ITEMS IN THE CART if ($this->itemcount >= 0) { $text['items_in_cart'] = $text['multiple_items']; } if ($this->itemcount == 1) { $text['items_in_cart'] = $text['single_item']; } // DETERMINE IF THIS IS THE CHECKOUT PAGE // WE FIRST CHECK THE REQUEST URI AGAINST THE USER CONFIG CHECKOUT (SET WHEN THE VISITOR FIRST CLICKS CHECKOUT) // WE ALSO CHECK FOR THE REQUEST VAR SENT FROM HIDDEN INPUT SENT BY AJAX REQUEST (SET WHEN VISITOR HAS JAVASCRIPT ENABLED AND UPDATES AN ITEM QTY) $is_checkout = strpos($_SERVER['REQUEST_URI'], $form_action); if ($is_checkout !== false || $_REQUEST['jcart_is_checkout'] == 'true') { $is_checkout = true; } else { $is_checkout = false; } // OVERWRITE THE CONFIG FORM ACTION TO POST TO jcart-gateway.php INSTEAD OF POSTING BACK TO CHECKOUT PAGE // THIS ALSO ALLOWS US TO VALIDATE PRICES BEFORE SENDING CART CONTENTS TO PAYPAL if ($is_checkout == true) { $form_action = $path . 'jcart-gateway.php'; } // DEFAULT INPUT TYPE // CAN BE OVERRIDDEN IF USER SETS PATHS FOR BUTTON IMAGES $input_type = 'submit'; // IF THIS ERROR IS TRUE THE VISITOR UPDATED THE CART FROM THE CHECKOUT PAGE USING AN INVALID PRICE FORMAT // PASSED AS A SESSION VAR SINCE THE CHECKOUT PAGE USES A HEADER REDIRECT // IF PASSED VIA GET THE QUERY STRING STAYS SET EVEN AFTER SUBSEQUENT POST REQUESTS if ($_SESSION['quantity_error'] == true) { $error_message = $text['quantity_error']; unset($_SESSION['quantity_error']); } // OUTPUT THE CART // IF THERE'S AN ERROR MESSAGE WRAP IT IN SOME HTML if ($error_message) { $error_message = "<p class='jcart-error'>$error_message</p>"; } // DISPLAY THE CART HEADER echo "<!-- BEGIN JCART -->\n<div id='jcart'>\n"; echo "\t$error_message\n"; echo "\t<form method='post' action='$form_action'>\n"; echo "\t\t<fieldset>\n"; echo "\t\t\t<table border='1'>\n"; echo "\t\t\t\t<tr>\n"; echo "\t\t\t\t\t<th id='jcart-header' colspan='3'>\n"; echo "\t\t\t\t\t\t<strong id='jcart-title'>" . $text['cart_title'] . "</strong> (" . $this->itemcount . " " . $text['items_in_cart'] .")\n"; echo "\t\t\t\t\t</th>\n"; echo "\t\t\t\t</tr>". "\n"; // IF ANY ITEMS IN THE CART if($this->itemcount > 0) { // DISPLAY LINE ITEMS foreach($this->get_contents() as $item) { echo "\t\t\t\t<tr>\n"; // ADD THE ITEM ID AS THE INPUT ID ATTRIBUTE // THIS ALLOWS US TO ACCESS THE ITEM ID VIA JAVASCRIPT ON QTY CHANGE, AND THEREFORE UPDATE THE CORRECT ITEM // NOTE THAT THE ITEM ID IS ALSO PASSED AS A SEPARATE FIELD FOR PROCESSING VIA PHP echo "\t\t\t\t\t<td class='jcart-item-qty'>\n"; echo "\t\t\t\t\t\t<input type='text' size='2' id='jcart-item-id-" . $item['id'] . "' name='jcart_item_qty[ ]' value='" . $item['qty'] . "' />\n"; echo "\t\t\t\t\t</td>\n"; echo "\t\t\t\t\t<td class='jcart-item-name'>\n"; echo "\t\t\t\t\t\t" . $item['name'] . "<input type='hidden' name='jcart_item_name[ ]' value='" . $item['name'] . "' />\n"; echo "\t\t\t\t\t\t<input type='hidden' name='jcart_item_id[ ]' value='" . $item['id'] . "' />\n"; echo "\t\t\t\t\t</td>\n"; echo "\t\t\t\t\t<td class='jcart-item-price'>\n"; echo "\t\t\t\t\t\t<span>" . $text['currency_symbol'] . number_format($item['subtotal'],2) . "</span><input type='hidden' name='jcart_item_price[ ]' value='" . $item['price'] . "' />\n"; echo "\t\t\t\t\t\t<a class='jcart-remove' href='?jcart_remove=" . $item['id'] . "'>" . $text['remove_link'] . "</a>\n"; echo "\t\t\t\t\t</td>\n"; echo "\t\t\t\t</tr>\n"; } } // THE CART IS EMPTY else { echo "\t\t\t\t<tr><td colspan='3' class='empty'>" . $text['empty_message'] . "</td></tr>\n"; } // DISPLAY THE CART FOOTER echo "\t\t\t\t<tr>\n"; echo "\t\t\t\t\t<th id='jcart-footer' colspan='3'>\n"; // IF THIS IS THE CHECKOUT HIDE THE CART CHECKOUT BUTTON if ($is_checkout !== true) { if ($button['checkout']) { $input_type = 'image'; $src = ' src="' . $button['checkout'] . '" alt="' . $text['checkout_button'] . '" title="" '; } echo "\t\t\t\t\t\t<input type='" . $input_type . "' " . $src . "id='jcart-checkout' name='jcart_checkout' class='jcart-button' value='" . $text['checkout_button'] . "' />\n"; } echo "\t\t\t\t\t\t<span id='jcart-subtotal'>" . $text['subtotal'] . ": <strong>" . $text['currency_symbol'] . number_format($this->total,2) . "</strong></span>\n"; echo "\t\t\t\t\t</th>\n"; echo "\t\t\t\t</tr>\n"; echo "\t\t\t</table>\n\n"; echo "\t\t\t<div class='jcart-hide'>\n"; if ($button['update']) { $input_type = 'image'; $src = ' src="' . $button['update'] . '" alt="' . $text['update_button'] . '" title="" '; } echo "\t\t\t\t<input type='" . $input_type . "' " . $src ."name='jcart_update_cart' value='" . $text['update_button'] . "' class='jcart-button' />\n"; if ($button['empty']) { $input_type = 'image'; $src = ' src="' . $button['empty'] . '" alt="' . $text['empty_button'] . '" title="" '; } echo "\t\t\t\t<input type='" . $input_type . "' " . $src ."name='jcart_empty' value='" . $text['empty_button'] . "' class='jcart-button' />\n"; echo "\t\t\t</div>\n"; // IF THIS IS THE CHECKOUT DISPLAY THE PAYPAL CHECKOUT BUTTON if ($is_checkout == true) { // HIDDEN INPUT ALLOWS US TO DETERMINE IF WE'RE ON THE CHECKOUT PAGE // WE NORMALLY CHECK AGAINST REQUEST URI BUT AJAX UPDATE SETS VALUE TO jcart-relay.php echo "\t\t\t<input type='hidden' id='jcart-is-checkout' name='jcart_is_checkout' value='true' />\n"; // SEND THE URL OF THE CHECKOUT PAGE TO jcart-gateway.php // WHEN JAVASCRIPT IS DISABLED WE USE A HEADER REDIRECT AFTER THE UPDATE OR EMPTY BUTTONS ARE CLICKED $protocol = 'http://'; if (!empty($_SERVER['HTTPS'])) { $protocol = 'https://'; } echo "\t\t\t<input type='hidden' id='jcart-checkout-page' name='jcart_checkout_page' value='" . $protocol . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'] . "' />\n"; // PAYPAL CHECKOUT BUTTON if ($button['paypal_checkout']) { $input_type = 'image'; $src = ' src="' . $button['paypal_checkout'] . '" alt="' . $text['checkout_paypal_button'] . '" title="" '; } echo "\t\t\t<input type='" . $input_type . "' " . $src ."id='jcart-paypal-checkout' name='jcart_paypal_checkout' value='" . $text['checkout_paypal_button'] . "'" . $disable_paypal_checkout . " />\n"; } echo "\t\t</fieldset>\n"; echo "\t</form>\n"; // IF UPDATING AN ITEM, FOCUS ON ITS QTY INPUT AFTER THE CART IS LOADED (DOESN'T SEEM TO WORK IN IE7) if ($_POST['jcart_update_item']) { echo "\t" . '<script type="text/javascript">$(function(){$("#jcart-item-id-' . $_POST['item_id'] . '").focus()});</script>' . "\n"; } echo "</div>\n<!-- END JCART -->\n"; } } ?> The Developers solution is turn register_globals off I don't know about the rest of you but last I knew, register globals off is a bad idea Quote Link to comment Share on other sites More sharing options...
jl5501 Posted February 27, 2010 Share Posted February 27, 2010 Can you let us know what the errors are that you are seeing. As far as register_globals is concerned, it is register_globals ON that is a VERY BAD idea, and in the latest versions of PHP it is not even possible. Quote Link to comment Share on other sites More sharing options...
monkeytooth Posted February 27, 2010 Author Share Posted February 27, 2010 On is bad? Yea I can see that... more so after some more reading up on it.. the first few articles I read a while back some time ago made it seem like it was evil to put them off.. but after the recent reads I have been doing in the past couple hours, and after digging through the php.ini on my server I can say yes, I agree with keeping them on is bad. I know this is silly question and the answers most likely right in my face.. but lets say I turn my globals off, are such things like $_GET $_SESSION and $_POST things that wont work any more, with it off? I assume turning it off will at the least make $_GET and $_POST variables pretty much the same exact thing in the script and rather than using $_GET/POST['var'] i can just use $var. But can I still use $_SESSION? With globals off, or do I have to use another method? If none of these work anymore would I be correct to assume I will have to do rewrites or some of my scripts removing $_GET/POST from my scripting, adjusting them accordingly? As for the errors I have gotten they are,. First argument should be an array in /home/campus/public_html/x/inc/jcart/jcart.php on line 244 Fatal error: Cannot use object of type jcart as array in /home/campus/public_html/x/inc/jcart/jcart.php on line 275 244 is the first line of 2 i mentioned earlier, and 275 is the second Quote Link to comment Share on other sites More sharing options...
Andy-H Posted February 27, 2010 Share Posted February 27, 2010 It is because your jcart::display_cart() method expects the argument passed to be an array, however, it is recieving an object. Have you tried casting the jcart object to an array before passing it to jcart::display_cart() as an argument. //nvm Quote Link to comment Share on other sites More sharing options...
jl5501 Posted February 27, 2010 Share Posted February 27, 2010 you seem to have the wrong idea regarding register_globals. The super global arrays GET/POST/COOKIE/SESSION/SERVER will ALWAYS work. It is just that you have to address them using their array names. With register_globals on, their values are avalible in the general namespace. so $_GET['fred'] is avalaible as $fred. This is what is a bad thing, and why register_globals should be off. Regarding your errors, please indicate what is on the lines producing the errors. Quote Link to comment Share on other sites More sharing options...
monkeytooth Posted February 27, 2010 Author Share Posted February 27, 2010 Here are the 2 lines throwing errors in the script: Line 1 (244) Code: [select] extract($jcart); Line 2 (275) Code: [select] if ($_POST['jcart_update_item'] == $jcart['text']['update_button']) As far as superglobals go, I figured they would work.. just the handling of them is what i wasn't sure about meaning would i still code in essence of $var1 = $_POST['var1']; or $_SESSION['var2'] = "something";.. or would i have to handle that in another way. example an if-else statment I might have in my script already... if((isset($_SESSION) AND ($_SESSION == "Tacobell")){/*do something*/}else{ignore} or another example: if(empty($_POST['formdata'])){/*do nothing*/}else{preg_match([abc], $_POST['formdata']){/*good*/} messy concept above but for the sake of example hopefully can convery what I am wondering about how things may or may not change upon globals off vs how (above code sample) i do things no with it on. Quote Link to comment Share on other sites More sharing options...
jl5501 Posted February 27, 2010 Share Posted February 27, 2010 Ok your problem is you are addressing an object as if it were an array, which you cannot do you cannot extract() on an object, or use the $var['element'] syntax you use the $obj->element syntax on an instance of the object. Your code using $_POST and $_SESSION would work the same with register_globals on or off Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.