ExpressionEngine CMS
Open, Free, Amazing

Thread

This is an archived forum and the content is probably no longer relevant, but is provided here for posterity.

The active forums are here.

Something wrong when I try add data to cart

March 16, 2013 3:20am

Subscribe [2]
  • #1 / Mar 16, 2013 3:20am

    greedyman

    48 posts

    I’m trying to add product to my shopping cart, this is my code:

    public function add_to_cart() {
                $data = array(
                    'id' => $this->input->post('productId'),
                    'name' => 'Name',
                    'price' => $this->input->post('productPrice'),
                    'qty' => 1
                );
                
                $this->cart->insert($data);
                
                //print_r($this->cart->contents());
                redirect($_SERVER['HTTP_REFERER']);
            }

    As you can see, name variable, if I assign a string (Name) to it, I can add data to my cart. But when I assign a string like this “Sữa tươi”, it has sign - utf8, I can’t do that. How I can fix?

  • #2 / Mar 16, 2013 5:14am

    davidMC1982

    54 posts

    Extend the cart class and override the _insert method.

  • #3 / Mar 16, 2013 12:03pm

    greedyman

    48 posts

    Extend the cart class and override the _insert method.

    Could you give me an example?

  • #4 / Mar 16, 2013 1:18pm

    davidMC1982

    54 posts

    Create a file MY_Cart.php in you application/libraries folder.

    Then do this:

    class MY_Cart extends CI_Cart {
    
        // These are the regular expression rules that we use to validate the product ID and product name
        var $product_id_rules = '\.a-z0-9_-'; // alpha-numeric, dashes, underscores, or periods
        var $product_name_rules = '\.\:\-_ a-z0-9'; // alpha-numeric, dashes, underscores, colons or periods
    
        public function __construct()
        {
            parent::__construct();
        }
    
     function _insert($items = array())
     {
      // Was any cart data passed? No? Bah…
      if ( ! is_array($items) OR count($items) == 0)
      {
       log_message('error', 'The insert method must be passed an array containing data.');
       return FALSE;
      }
    
      // --------------------------------------------------------------------
    
      // Does the $items array contain an id, quantity, price, and name?  These are required
      if ( ! isset($items['id']) OR ! isset($items['qty']) OR ! isset($items['price']) OR ! isset($items['name']))
      {
       log_message('error', 'The cart array must contain a product ID, quantity, price, and name.');
       return FALSE;
      }
    
      // --------------------------------------------------------------------
    
      // Prep the quantity. It can only be a number.  Duh…
      $items['qty'] = trim(preg_replace('/([^0-9])/i', '', $items['qty']));
      // Trim any leading zeros
      $items['qty'] = trim(preg_replace('/(^[0]+)/i', '', $items['qty']));
    
      // If the quantity is zero or blank there's nothing for us to do
      if ( ! is_numeric($items['qty']) OR $items['qty'] == 0)
      {
       return FALSE;
      }
    
      // --------------------------------------------------------------------
    
      // Validate the product ID. It can only be alpha-numeric, dashes, underscores or periods
      // Not totally sure we should impose this rule, but it seems prudent to standardize IDs.
      // Note: These can be user-specified by setting the $this->product_id_rules variable.
      if ( ! preg_match("/^[".$this->product_id_rules."]+$/i", $items['id']))
      {
       log_message('error', 'Invalid product ID.  The product ID can only contain alpha-numeric characters, dashes, and underscores');
       return FALSE;
      }
    
      // --------------------------------------------------------------------
    
      // Validate the product name. It can only be alpha-numeric, dashes, underscores, colons or periods.
      // Note: These can be user-specified by setting the $this->product_name_rules variable.
      if ( ! preg_match("/^[".$this->product_name_rules."]+$/i", $items['name']))
      {
       log_message('error', 'An invalid name was submitted as the product name: '.$items['name'].' The name can only contain alpha-numeric characters, dashes, underscores, colons, and spaces');
       return FALSE;
      }
    
      // --------------------------------------------------------------------
    
      // Prep the price.  Remove anything that isn't a number or decimal point.
      $items['price'] = trim(preg_replace('/([^0-9\.])/i', '', $items['price']));
      // Trim any leading zeros
      $items['price'] = trim(preg_replace('/(^[0]+)/i', '', $items['price']));
    
      // Is the price a valid number?
      if ( ! is_numeric($items['price']))
      {
       log_message('error', 'An invalid price was submitted for product ID: '.$items['id']);
       return FALSE;
      }
    
      // --------------------------------------------------------------------
    
      // We now need to create a unique identifier for the item being inserted into the cart.
      // Every time something is added to the cart it is stored in the master cart array.
      // Each row in the cart array, however, must have a unique index that identifies not only
      // a particular product, but makes it possible to store identical products with different options.
      // For example, what if someone buys two identical t-shirts (same product ID), but in
      // different sizes?  The product ID (and other attributes, like the name) will be identical for
      // both sizes because it's the same shirt. The only difference will be the size.
      // Internally, we need to treat identical submissions, but with different options, as a unique product.
      // Our solution is to convert the options array to a string and MD5 it along with the product ID.
      // This becomes the unique "row ID"
      if (isset($items['options']) AND count($items['options']) > 0)
      {
       $rowid = md5($items['id'].implode('', $items['options']));
      }
      else
      {
       // No options were submitted so we simply MD5 the product ID.
       // Technically, we don't need to MD5 the ID in this case, but it makes
       // sense to standardize the format of array indexes for both conditions
       $rowid = md5($items['id']);
      }
    
      // --------------------------------------------------------------------
    
      // Now that we have our unique "row ID", we'll add our cart items to the master array
    
      // let's unset this first, just to make sure our index contains only the data from this submission
      unset($this->_cart_contents[$rowid]);
    
      // Create a new index with our new row ID
      $this->_cart_contents[$rowid]['rowid'] = $rowid;
    
      // And add the new items to the cart array
      foreach ($items as $key => $val)
      {
       $this->_cart_contents[$rowid][$key] = $val;
      }
    
      // Woot!
      return $rowid;
     }
    }

    You can edit the _insert function to do whatever you want, or just edit the $product_name_rules member variable.

  • #5 / Mar 17, 2013 3:34am

    greedyman

    48 posts

    Create a file MY_Cart.php in you application/libraries folder.

    Then do this:

    class MY_Cart extends CI_Cart {
    
    }

    You can edit the _insert function to do whatever you want, or just edit the $product_name_rules member variable.

    I think that the core of CI, in this case it’s CI_Cart, we can not change it. CI_Cart don’t let me add a string with sign into my shopping cart, so why this code above can help me? At first glance, I feel that your code only test input.

  • #6 / Mar 17, 2013 6:26am

    davidMC1982

    54 posts

    You change the core by extending the existing libraries. I have copied the _insert function from the core CI_Cart class into the MY_Cart class. You then edit the _insert function to do what you need or just the $product_name_rules variable. Your new MY_Cart class inherits all the methods and properties of the CI_Cart class and your MY_Cart _insert function overrides the CI_Cart _insert function.

    Try what I said above. Create a file called MY_Cart.php in your application/libraries folder. Copy and paste the code above. Your cart will behave exactly as before. As a really fast test to show that what I’m saying works, just comment out the following code from the _insert function:

    // Validate the product name. It can only be alpha-numeric, dashes, underscores, colons or periods.
      // Note: These can be user-specified by setting the $this->product_name_rules variable.
      if ( ! preg_match("/^[".$this->product_name_rules."]+$/i", $items['name']))
      {
       log_message('error', 'An invalid name was submitted as the product name: '.$items['name'].' The name can only contain alpha-numeric characters, dashes, underscores, colons, and spaces');
       return FALSE;
      }

    You need to read about inheritance in php generally and extending Codeigniter libraries, which helpfully, is in the user guide:

    http://ellislab.com/codeigniter/user-guide/general/creating_libraries.html

  • #7 / Mar 17, 2013 10:20am

    greedyman

    48 posts

    I’m so sorry. I copy your code and create My_Cart.php file but I still can’t add product to my shopping cart, that means it’s not work . Here is code to insert:

    public function add_to_cart() {
                $this->load->library('My_Cart');
                $data = array(
                    'id' => $this->input->post('productId'),
                    'name' => 'Sữa tươi',
                    'price' => $this->input->post('productPrice'),
                    'qty' => 1
                );
                
                $this->My_Cart->_insert($data);
                
                redirect($_SERVER['HTTP_REFERER']);
            }

    How I can use this file?

  • #8 / Mar 17, 2013 10:35am

    davidMC1982

    54 posts

    Yes, it is the same, hence why you still can’t add your item to the cart. You need to either edit the _insert function in My_Cart.php to perform whatever checks you want (if any), or edit the $product_name_rules variable to allow whichever characters you want to allow.

    As I said before, the fastest way to get what you want working would be to comment out these lines of code from the _insert() function in MY_cart.php:

    // Validate the product name. It can only be alpha-numeric, dashes, underscores, colons or periods.
      // Note: These can be user-specified by setting the $this->product_name_rules variable.
      if ( ! preg_match("/^[".$this->product_name_rules."]+$/i", $items['name']))
      {
       log_message('error', 'An invalid name was submitted as the product name: '.$items['name'].' The name can only contain alpha-numeric characters, dashes, underscores, colons, and spaces');
       return FALSE;
      }

    It won’t be safe, and you should eventually edit the $product_name_rules or add some validation for the product name, but it will work.

  • #9 / Mar 17, 2013 10:55am

    greedyman

    48 posts

    @davidMC1982: I see. Session in CI using cookie and can I use session ($_SESSION) as php generally?

  • #10 / Mar 17, 2013 11:00am

    davidMC1982

    54 posts

    You can use $_SESSION, but you are much better off using $this->session. See here:

    http://ellislab.com/codeigniter/user-guide/libraries/sessions.html

    Personally, I always setup Codeigniter sessions to use the db.

  • #11 / Mar 17, 2013 11:06am

    greedyman

    48 posts

    You can use $_SESSION, but you are much better off using $this->session. See here:

    http://ellislab.com/codeigniter/user-guide/libraries/sessions.html

    Personally, I always setup Codeigniter sessions to use the db.

    But session in CI is cookie (~4KB), I can only add about 8 products and it full. Can I extend session capacity?

  • #12 / Mar 17, 2013 11:21am

    davidMC1982

    54 posts

    Setup the Codeigniter sessions to use a table in your database. Everything you need to know to do it is in the user guide.

    Also, the Cart class requires that you store your sessions in your db:

    http://ellislab.com/codeigniter/user-guide/libraries/cart.html

  • #13 / Mar 17, 2013 11:24am

    greedyman

    48 posts

    Setup the Codeigniter sessions to use a table in your database. Everything you need to know to do it is in the user guide.

    Also, the Cart class requires that you store your sessions in your db:

    http://ellislab.com/codeigniter/user-guide/libraries/cart.html

    Hi! Thank for your help.

.(JavaScript must be enabled to view this email address)

ExpressionEngine News!

#eecms, #events, #releases