cart.php (21068B)
1 <?php 2 namespace Cart; 3 class Cart { 4 private $data = array(); 5 6 public function __construct($registry) { 7 $this->config = $registry->get('config'); 8 $this->customer = $registry->get('customer'); 9 $this->session = $registry->get('session'); 10 $this->db = $registry->get('db'); 11 $this->tax = $registry->get('tax'); 12 $this->weight = $registry->get('weight'); 13 14 // Remove all the expired carts with no customer ID 15 $this->db->query("DELETE FROM " . DB_PREFIX . "cart WHERE (api_id > '0' OR customer_id = '0') AND date_added < DATE_SUB(NOW(), INTERVAL 1 HOUR)"); 16 17 if ($this->customer->getId()) { 18 // We want to change the session ID on all the old items in the customers cart 19 $this->db->query("UPDATE " . DB_PREFIX . "cart SET session_id = '" . $this->db->escape($this->session->getId()) . "' WHERE api_id = '0' AND customer_id = '" . (int)$this->customer->getId() . "'"); 20 21 // Once the customer is logged in we want to update the customers cart 22 $cart_query = $this->db->query("SELECT * FROM " . DB_PREFIX . "cart WHERE api_id = '0' AND customer_id = '0' AND session_id = '" . $this->db->escape($this->session->getId()) . "'"); 23 24 foreach ($cart_query->rows as $cart) { 25 $this->db->query("DELETE FROM " . DB_PREFIX . "cart WHERE cart_id = '" . (int)$cart['cart_id'] . "'"); 26 27 // The advantage of using $this->add is that it will check if the products already exist and increaser the quantity if necessary. 28 $this->add($cart['product_id'], $cart['quantity'], json_decode($cart['option']), $cart['recurring_id']); 29 } 30 } 31 } 32 33 public function getProducts() { 34 $product_data = array(); 35 36 $cart_query = $this->db->query("SELECT * FROM " . DB_PREFIX . "cart WHERE api_id = '" . (isset($this->session->data['api_id']) ? (int)$this->session->data['api_id'] : 0) . "' AND customer_id = '" . (int)$this->customer->getId() . "' AND session_id = '" . $this->db->escape($this->session->getId()) . "'"); 37 38 foreach ($cart_query->rows as $cart) { 39 $stock = true; 40 41 $product_query = $this->db->query("SELECT * FROM " . DB_PREFIX . "product_to_store p2s LEFT JOIN " . DB_PREFIX . "product p ON (p2s.product_id = p.product_id) LEFT JOIN " . DB_PREFIX . "product_description pd ON (p.product_id = pd.product_id) WHERE p2s.store_id = '" . (int)$this->config->get('config_store_id') . "' AND p2s.product_id = '" . (int)$cart['product_id'] . "' AND pd.language_id = '" . (int)$this->config->get('config_language_id') . "' AND p.date_available <= NOW() AND p.status = '1'"); 42 43 if ($product_query->num_rows && ($cart['quantity'] > 0)) { 44 $option_price = 0; 45 $option_points = 0; 46 $option_weight = 0; 47 48 $option_data = array(); 49 50 foreach (json_decode($cart['option']) as $product_option_id => $value) { 51 $option_query = $this->db->query("SELECT po.product_option_id, po.option_id, od.name, o.type FROM " . DB_PREFIX . "product_option po LEFT JOIN `" . DB_PREFIX . "option` o ON (po.option_id = o.option_id) LEFT JOIN " . DB_PREFIX . "option_description od ON (o.option_id = od.option_id) WHERE po.product_option_id = '" . (int)$product_option_id . "' AND po.product_id = '" . (int)$cart['product_id'] . "' AND od.language_id = '" . (int)$this->config->get('config_language_id') . "'"); 52 53 if ($option_query->num_rows) { 54 if ($option_query->row['type'] == 'select' || $option_query->row['type'] == 'radio') { 55 $option_value_query = $this->db->query("SELECT pov.option_value_id, ovd.name, pov.quantity, pov.subtract, pov.price, pov.price_prefix, pov.points, pov.points_prefix, pov.weight, pov.weight_prefix FROM " . DB_PREFIX . "product_option_value pov LEFT JOIN " . DB_PREFIX . "option_value ov ON (pov.option_value_id = ov.option_value_id) LEFT JOIN " . DB_PREFIX . "option_value_description ovd ON (ov.option_value_id = ovd.option_value_id) WHERE pov.product_option_value_id = '" . (int)$value . "' AND pov.product_option_id = '" . (int)$product_option_id . "' AND ovd.language_id = '" . (int)$this->config->get('config_language_id') . "'"); 56 57 if ($option_value_query->num_rows) { 58 if ($option_value_query->row['price_prefix'] == '+') { 59 $option_price += $option_value_query->row['price']; 60 } elseif ($option_value_query->row['price_prefix'] == '-') { 61 $option_price -= $option_value_query->row['price']; 62 } 63 64 if ($option_value_query->row['points_prefix'] == '+') { 65 $option_points += $option_value_query->row['points']; 66 } elseif ($option_value_query->row['points_prefix'] == '-') { 67 $option_points -= $option_value_query->row['points']; 68 } 69 70 if ($option_value_query->row['weight_prefix'] == '+') { 71 $option_weight += $option_value_query->row['weight']; 72 } elseif ($option_value_query->row['weight_prefix'] == '-') { 73 $option_weight -= $option_value_query->row['weight']; 74 } 75 76 if ($option_value_query->row['subtract'] && (!$option_value_query->row['quantity'] || ($option_value_query->row['quantity'] < $cart['quantity']))) { 77 $stock = false; 78 } 79 80 $option_data[] = array( 81 'product_option_id' => $product_option_id, 82 'product_option_value_id' => $value, 83 'option_id' => $option_query->row['option_id'], 84 'option_value_id' => $option_value_query->row['option_value_id'], 85 'name' => $option_query->row['name'], 86 'value' => $option_value_query->row['name'], 87 'type' => $option_query->row['type'], 88 'quantity' => $option_value_query->row['quantity'], 89 'subtract' => $option_value_query->row['subtract'], 90 'price' => $option_value_query->row['price'], 91 'price_prefix' => $option_value_query->row['price_prefix'], 92 'points' => $option_value_query->row['points'], 93 'points_prefix' => $option_value_query->row['points_prefix'], 94 'weight' => $option_value_query->row['weight'], 95 'weight_prefix' => $option_value_query->row['weight_prefix'] 96 ); 97 } 98 } elseif ($option_query->row['type'] == 'checkbox' && is_array($value)) { 99 foreach ($value as $product_option_value_id) { 100 $option_value_query = $this->db->query("SELECT pov.option_value_id, pov.quantity, pov.subtract, pov.price, pov.price_prefix, pov.points, pov.points_prefix, pov.weight, pov.weight_prefix, ovd.name FROM " . DB_PREFIX . "product_option_value pov LEFT JOIN " . DB_PREFIX . "option_value_description ovd ON (pov.option_value_id = ovd.option_value_id) WHERE pov.product_option_value_id = '" . (int)$product_option_value_id . "' AND pov.product_option_id = '" . (int)$product_option_id . "' AND ovd.language_id = '" . (int)$this->config->get('config_language_id') . "'"); 101 102 if ($option_value_query->num_rows) { 103 if ($option_value_query->row['price_prefix'] == '+') { 104 $option_price += $option_value_query->row['price']; 105 } elseif ($option_value_query->row['price_prefix'] == '-') { 106 $option_price -= $option_value_query->row['price']; 107 } 108 109 if ($option_value_query->row['points_prefix'] == '+') { 110 $option_points += $option_value_query->row['points']; 111 } elseif ($option_value_query->row['points_prefix'] == '-') { 112 $option_points -= $option_value_query->row['points']; 113 } 114 115 if ($option_value_query->row['weight_prefix'] == '+') { 116 $option_weight += $option_value_query->row['weight']; 117 } elseif ($option_value_query->row['weight_prefix'] == '-') { 118 $option_weight -= $option_value_query->row['weight']; 119 } 120 121 if ($option_value_query->row['subtract'] && (!$option_value_query->row['quantity'] || ($option_value_query->row['quantity'] < $cart['quantity']))) { 122 $stock = false; 123 } 124 125 $option_data[] = array( 126 'product_option_id' => $product_option_id, 127 'product_option_value_id' => $product_option_value_id, 128 'option_id' => $option_query->row['option_id'], 129 'option_value_id' => $option_value_query->row['option_value_id'], 130 'name' => $option_query->row['name'], 131 'value' => $option_value_query->row['name'], 132 'type' => $option_query->row['type'], 133 'quantity' => $option_value_query->row['quantity'], 134 'subtract' => $option_value_query->row['subtract'], 135 'price' => $option_value_query->row['price'], 136 'price_prefix' => $option_value_query->row['price_prefix'], 137 'points' => $option_value_query->row['points'], 138 'points_prefix' => $option_value_query->row['points_prefix'], 139 'weight' => $option_value_query->row['weight'], 140 'weight_prefix' => $option_value_query->row['weight_prefix'] 141 ); 142 } 143 } 144 } elseif ($option_query->row['type'] == 'text' || $option_query->row['type'] == 'textarea' || $option_query->row['type'] == 'file' || $option_query->row['type'] == 'date' || $option_query->row['type'] == 'datetime' || $option_query->row['type'] == 'time') { 145 $option_data[] = array( 146 'product_option_id' => $product_option_id, 147 'product_option_value_id' => '', 148 'option_id' => $option_query->row['option_id'], 149 'option_value_id' => '', 150 'name' => $option_query->row['name'], 151 'value' => $value, 152 'type' => $option_query->row['type'], 153 'quantity' => '', 154 'subtract' => '', 155 'price' => '', 156 'price_prefix' => '', 157 'points' => '', 158 'points_prefix' => '', 159 'weight' => '', 160 'weight_prefix' => '' 161 ); 162 } 163 } 164 } 165 166 $price = $product_query->row['price']; 167 168 // Product Discounts 169 $discount_quantity = 0; 170 171 foreach ($cart_query->rows as $cart_2) { 172 if ($cart_2['product_id'] == $cart['product_id']) { 173 $discount_quantity += $cart_2['quantity']; 174 } 175 } 176 177 $product_discount_query = $this->db->query("SELECT price FROM " . DB_PREFIX . "product_discount WHERE product_id = '" . (int)$cart['product_id'] . "' AND customer_group_id = '" . (int)$this->config->get('config_customer_group_id') . "' AND quantity <= '" . (int)$discount_quantity . "' AND ((date_start = '0000-00-00' OR date_start < NOW()) AND (date_end = '0000-00-00' OR date_end > NOW())) ORDER BY quantity DESC, priority ASC, price ASC LIMIT 1"); 178 179 if ($product_discount_query->num_rows) { 180 $price = $product_discount_query->row['price']; 181 } 182 183 // Product Specials 184 $product_special_query = $this->db->query("SELECT price FROM " . DB_PREFIX . "product_special WHERE product_id = '" . (int)$cart['product_id'] . "' AND customer_group_id = '" . (int)$this->config->get('config_customer_group_id') . "' AND ((date_start = '0000-00-00' OR date_start < NOW()) AND (date_end = '0000-00-00' OR date_end > NOW())) ORDER BY priority ASC, price ASC LIMIT 1"); 185 186 if ($product_special_query->num_rows) { 187 $price = $product_special_query->row['price']; 188 } 189 190 // Reward Points 191 $product_reward_query = $this->db->query("SELECT points FROM " . DB_PREFIX . "product_reward WHERE product_id = '" . (int)$cart['product_id'] . "' AND customer_group_id = '" . (int)$this->config->get('config_customer_group_id') . "'"); 192 193 if ($product_reward_query->num_rows) { 194 $reward = $product_reward_query->row['points']; 195 } else { 196 $reward = 0; 197 } 198 199 // Downloads 200 $download_data = array(); 201 202 $download_query = $this->db->query("SELECT * FROM " . DB_PREFIX . "product_to_download p2d LEFT JOIN " . DB_PREFIX . "download d ON (p2d.download_id = d.download_id) LEFT JOIN " . DB_PREFIX . "download_description dd ON (d.download_id = dd.download_id) WHERE p2d.product_id = '" . (int)$cart['product_id'] . "' AND dd.language_id = '" . (int)$this->config->get('config_language_id') . "'"); 203 204 foreach ($download_query->rows as $download) { 205 $download_data[] = array( 206 'download_id' => $download['download_id'], 207 'name' => $download['name'], 208 'filename' => $download['filename'], 209 'mask' => $download['mask'] 210 ); 211 } 212 213 // Stock 214 if (!$product_query->row['quantity'] || ($product_query->row['quantity'] < $cart['quantity'])) { 215 $stock = false; 216 } 217 218 $recurring_query = $this->db->query("SELECT * FROM " . DB_PREFIX . "recurring r LEFT JOIN " . DB_PREFIX . "product_recurring pr ON (r.recurring_id = pr.recurring_id) LEFT JOIN " . DB_PREFIX . "recurring_description rd ON (r.recurring_id = rd.recurring_id) WHERE r.recurring_id = '" . (int)$cart['recurring_id'] . "' AND pr.product_id = '" . (int)$cart['product_id'] . "' AND rd.language_id = " . (int)$this->config->get('config_language_id') . " AND r.status = 1 AND pr.customer_group_id = '" . (int)$this->config->get('config_customer_group_id') . "'"); 219 220 if ($recurring_query->num_rows) { 221 $recurring = array( 222 'recurring_id' => $cart['recurring_id'], 223 'name' => $recurring_query->row['name'], 224 'frequency' => $recurring_query->row['frequency'], 225 'price' => $recurring_query->row['price'], 226 'cycle' => $recurring_query->row['cycle'], 227 'duration' => $recurring_query->row['duration'], 228 'trial' => $recurring_query->row['trial_status'], 229 'trial_frequency' => $recurring_query->row['trial_frequency'], 230 'trial_price' => $recurring_query->row['trial_price'], 231 'trial_cycle' => $recurring_query->row['trial_cycle'], 232 'trial_duration' => $recurring_query->row['trial_duration'] 233 ); 234 } else { 235 $recurring = false; 236 } 237 238 $product_data[] = array( 239 'cart_id' => $cart['cart_id'], 240 'product_id' => $product_query->row['product_id'], 241 'name' => $product_query->row['name'], 242 'model' => $product_query->row['model'], 243 'shipping' => $product_query->row['shipping'], 244 'image' => $product_query->row['image'], 245 'option' => $option_data, 246 'download' => $download_data, 247 'quantity' => $cart['quantity'], 248 'minimum' => $product_query->row['minimum'], 249 'subtract' => $product_query->row['subtract'], 250 'stock' => $stock, 251 'price' => ($price + $option_price), 252 'total' => ($price + $option_price) * $cart['quantity'], 253 'reward' => $reward * $cart['quantity'], 254 'points' => ($product_query->row['points'] ? ($product_query->row['points'] + $option_points) * $cart['quantity'] : 0), 255 'tax_class_id' => $product_query->row['tax_class_id'], 256 'weight' => ($product_query->row['weight'] + $option_weight) * $cart['quantity'], 257 'weight_class_id' => $product_query->row['weight_class_id'], 258 'length' => $product_query->row['length'], 259 'width' => $product_query->row['width'], 260 'height' => $product_query->row['height'], 261 'length_class_id' => $product_query->row['length_class_id'], 262 'recurring' => $recurring 263 ); 264 } else { 265 $this->remove($cart['cart_id']); 266 } 267 } 268 269 return $product_data; 270 } 271 272 public function add($product_id, $quantity = 1, $option = array(), $recurring_id = 0) { 273 $query = $this->db->query("SELECT COUNT(*) AS total FROM " . DB_PREFIX . "cart WHERE api_id = '" . (isset($this->session->data['api_id']) ? (int)$this->session->data['api_id'] : 0) . "' AND customer_id = '" . (int)$this->customer->getId() . "' AND session_id = '" . $this->db->escape($this->session->getId()) . "' AND product_id = '" . (int)$product_id . "' AND recurring_id = '" . (int)$recurring_id . "' AND `option` = '" . $this->db->escape(json_encode($option)) . "'"); 274 275 if (!$query->row['total']) { 276 $this->db->query("INSERT " . DB_PREFIX . "cart SET api_id = '" . (isset($this->session->data['api_id']) ? (int)$this->session->data['api_id'] : 0) . "', customer_id = '" . (int)$this->customer->getId() . "', session_id = '" . $this->db->escape($this->session->getId()) . "', product_id = '" . (int)$product_id . "', recurring_id = '" . (int)$recurring_id . "', `option` = '" . $this->db->escape(json_encode($option)) . "', quantity = '" . (int)$quantity . "', date_added = NOW()"); 277 } else { 278 $this->db->query("UPDATE " . DB_PREFIX . "cart SET quantity = (quantity + " . (int)$quantity . ") WHERE api_id = '" . (isset($this->session->data['api_id']) ? (int)$this->session->data['api_id'] : 0) . "' AND customer_id = '" . (int)$this->customer->getId() . "' AND session_id = '" . $this->db->escape($this->session->getId()) . "' AND product_id = '" . (int)$product_id . "' AND recurring_id = '" . (int)$recurring_id . "' AND `option` = '" . $this->db->escape(json_encode($option)) . "'"); 279 } 280 } 281 282 public function update($cart_id, $quantity) { 283 $this->db->query("UPDATE " . DB_PREFIX . "cart SET quantity = '" . (int)$quantity . "' WHERE cart_id = '" . (int)$cart_id . "' AND api_id = '" . (isset($this->session->data['api_id']) ? (int)$this->session->data['api_id'] : 0) . "' AND customer_id = '" . (int)$this->customer->getId() . "' AND session_id = '" . $this->db->escape($this->session->getId()) . "'"); 284 } 285 286 public function remove($cart_id) { 287 $this->db->query("DELETE FROM " . DB_PREFIX . "cart WHERE cart_id = '" . (int)$cart_id . "' AND api_id = '" . (isset($this->session->data['api_id']) ? (int)$this->session->data['api_id'] : 0) . "' AND customer_id = '" . (int)$this->customer->getId() . "' AND session_id = '" . $this->db->escape($this->session->getId()) . "'"); 288 } 289 290 public function clear() { 291 $this->db->query("DELETE FROM " . DB_PREFIX . "cart WHERE api_id = '" . (isset($this->session->data['api_id']) ? (int)$this->session->data['api_id'] : 0) . "' AND customer_id = '" . (int)$this->customer->getId() . "' AND session_id = '" . $this->db->escape($this->session->getId()) . "'"); 292 } 293 294 public function getRecurringProducts() { 295 $product_data = array(); 296 297 foreach ($this->getProducts() as $value) { 298 if ($value['recurring']) { 299 $product_data[] = $value; 300 } 301 } 302 303 return $product_data; 304 } 305 306 public function getWeight() { 307 $weight = 0; 308 309 foreach ($this->getProducts() as $product) { 310 if ($product['shipping']) { 311 $weight += $this->weight->convert($product['weight'], $product['weight_class_id'], $this->config->get('config_weight_class_id')); 312 } 313 } 314 315 return $weight; 316 } 317 318 public function getSubTotal() { 319 $total = 0; 320 321 foreach ($this->getProducts() as $product) { 322 $total += $product['total']; 323 } 324 325 return $total; 326 } 327 328 public function getTaxes() { 329 $tax_data = array(); 330 331 foreach ($this->getProducts() as $product) { 332 if ($product['tax_class_id']) { 333 $tax_rates = $this->tax->getRates($product['price'], $product['tax_class_id']); 334 335 foreach ($tax_rates as $tax_rate) { 336 if (!isset($tax_data[$tax_rate['tax_rate_id']])) { 337 $tax_data[$tax_rate['tax_rate_id']] = ($tax_rate['amount'] * $product['quantity']); 338 } else { 339 $tax_data[$tax_rate['tax_rate_id']] += ($tax_rate['amount'] * $product['quantity']); 340 } 341 } 342 } 343 } 344 345 return $tax_data; 346 } 347 348 public function getTotal() { 349 $total = 0; 350 351 foreach ($this->getProducts() as $product) { 352 $total += $this->tax->calculate($product['price'], $product['tax_class_id'], $this->config->get('config_tax')) * $product['quantity']; 353 } 354 355 return $total; 356 } 357 358 public function countProducts() { 359 $product_total = 0; 360 361 $products = $this->getProducts(); 362 363 foreach ($products as $product) { 364 $product_total += $product['quantity']; 365 } 366 367 return $product_total; 368 } 369 370 public function hasProducts() { 371 return count($this->getProducts()); 372 } 373 374 public function hasRecurringProducts() { 375 return count($this->getRecurringProducts()); 376 } 377 378 public function hasStock() { 379 foreach ($this->getProducts() as $product) { 380 if (!$product['stock']) { 381 return false; 382 } 383 } 384 385 return true; 386 } 387 388 public function hasShipping() { 389 foreach ($this->getProducts() as $product) { 390 if ($product['shipping']) { 391 return true; 392 } 393 } 394 395 return false; 396 } 397 398 public function hasDownload() { 399 foreach ($this->getProducts() as $product) { 400 if ($product['download']) { 401 return true; 402 } 403 } 404 405 return false; 406 } 407 }