Adding products with attributes to cart programmatically using Ubercart
Adding products with attributes to cart programmatically using Ubercart
Post date:
Sun, 01/03/2016 - 00:00
Difficulty:
Piece of Cake
While still using Ubercart on some legacy application, I found the need to add a product to the cart programmatically with attributes already set. So I uncovered the dust from this old Ubercart utility library and thought it would be nice to share.
There are a few interesting methods in it:
- GetProductAttributeByName: when dealing with attributes Ubercart will not use attribute name's in the stored data. Instead, it will use numeric ID's. Use this to retrieve attribute information from a product by using it's friendly name.
- GetProductAttributes: just a cached wrapper for uc_product_get_attributes.
- AddProductToCartWithAttributes: add a product to the user's cart while specifing attribute values.
- UbercartProductAddAttribute: Add an attribute - with value - to a product object.
<?php
namespace Drupal\pi\Managers;
use \Drupal\fdf\Utilities\UtilsEntity;
class ManagerUbercart {
/**
* Get product attribute from it's name.
*
* @param int $nid
* @param mixed $cart_item
* @param string $attribute_name
*
* @return array
*/
public static function GetProductAttributeByName($nid, $cart_item, $attribute_name) {
$attributes = static::GetProductAttributes($nid);
$inscription_id = null;
$inscription_attribute_key = null;
foreach($attributes as $key => $attribute) {
if ($attribute->name !== $attribute_name) {
continue;
}
$aid = $attribute->aid;
if (isset($cart_item->data['attributes'][$aid])) {
$inscription_id = $cart_item->data['attributes'][$aid];
$inscription_attribute_key = $aid;
break;
}
// Once an order is complete, attribute data is stored differently.
if (isset($cart_item->data['attributes_detail'][$aid])) {
$inscription_id = $cart_item->data['attributes_detail'][$aid]['option']['name'];
$inscription_attribute_key = null;
break;
}
}
$result = array('key' => $inscription_attribute_key, 'value' => $inscription_id);
return $result;
}
/**
* Cached version of get product attributes.
*/
private static function GetProductAttributes($nid) {
$key = 'managerubercart:' . $nid;
if ($cache = cache_get($key)) {
return $cache->data;
}
$data = uc_product_get_attributes($nid);
// We have no true invalidation mechanism here, so just
// set a time based expiration of 24H.
cache_set($key, $data, 'cache', time() + (3600 * 24));
return $data;
}
/**
* Add an attribute to a product.
*
* @param mixed $product
* Product object.
* @param array $attributes
* Attribute values, keyed by friendly name.
*/
public static function UbercartProductAddAttribute(&$product, array $attributes) {
$atts = static::GetProductAttributes($product->nid);
$data = $product->data;
if (empty($data)) {
$data = array();
}
foreach($attributes as $name => $value) {
foreach($atts as $key => $attribute) {
if (strcasecmp($attribute->name, $name) != 0) {
continue;
}
$aid = $attribute->aid;
$data['attributes'][$aid] = $value;
unset($attributes[$name]);
break;
}
}
$product->data = $data;
}
/**
* Add a product to the current cart with attributes.
*
* @param $nid int
* Id of the product.
*
* @param $attributes array
* Associative array with attributes name's as keys.
*
* @return void
*/
public static function AddProductToCartWithAttributes($nid, array $attributes, $qty = 1) {
$data = array();
$atts = static::GetProductAttributes($nid);
foreach($attributes as $name => $value) {
foreach($atts as $key => $attribute) {
if ($attribute->name !== $name) {
continue;
}
$aid = $attribute->aid;
$data['attributes'][$aid] = $value;
unset($attributes[$name]);
break;
}
}
if(!empty($attributes)) {
drupal_set_message('Not all product attributes could be binded.');
}
uc_cart_add_item($nid, $qty, $data, NULL, TRUE, TRUE, TRUE);
}
}
Add new comment