commerce_physical.module in Commerce Physical Product 7
API for working with physical product types in Drupal Commerce.
File
commerce_physical.moduleView source
<?php
/**
* @file
* API for working with physical product types in Drupal Commerce.
*/
/**
* Determines the weight field to use for a given entity.
*
* @param string $entity_type
* The type of entity passed to the function.
* @param object $entity
* The actual entity whose weight field name should be determined.
*
* @return string
* The name of the field to use on the entity to find a weight value or NULL
* if none was found.
*/
function commerce_physical_entity_weight_field_name($entity_type, $entity) {
$field_name = commerce_physical_entity_field_name($entity_type, $entity, 'physical_weight');
// Allow other modules to specify a different field name.
drupal_alter('commerce_physical_entity_weight_field_name', $field_name, $entity_type, $entity);
return $field_name;
}
/**
* Determines the dimensions field to use for a given entity.
*
* @param string $entity_type
* The type of entity passed to the function.
* @param object $entity
* The actual entity whose weight field name should be determined.
*
* @return string
* The name of the field to use on the entity to find a weight value or NULL
* if none was found.
*/
function commerce_physical_entity_dimensions_field_name($entity_type, $entity) {
$field_name = commerce_physical_entity_field_name($entity_type, $entity, 'physical_dimensions');
// Allow other modules to specify a different field name.
drupal_alter('commerce_physical_entity_dimensions_field_name', $field_name, $entity_type, $entity);
return $field_name;
}
/**
* Determines the field of a certain type to use for a given entity.
*
* @param string $entity_type
* The type of entity passed to the function.
* @param object $entity
* The actual entity whose weight field name should be determined.
* @param string $field_type
* The field type to use.
*
* @return string
* The name of the field to use on the entity to find a weight value or NULL
* if none was found.
*/
function commerce_physical_entity_field_name($entity_type, $entity, $field_type) {
$bundle = field_extract_bundle($entity_type, $entity);
$field_name = NULL;
// Look for the first field available for the entity.
foreach (field_info_instances($entity_type, $bundle) as $instance_name => $instance) {
// Load the field info for the current instance.
$field = field_info_field($instance['field_name']);
// If it's of the proper type...
if ($field['type'] == $field_type) {
// Save its name and exit the loop.
$field_name = $instance_name;
break;
}
}
return $field_name;
}
/**
* Determines the weight to use for a product line item on an order.
*
* @param commerce_line_item $line_item
* A product line item whose weight should be determined.
*
* @return array
* A weight field value array representing the weight of the product line item
* or NULL if none was found.
*/
function commerce_physical_product_line_item_weight($line_item) {
$line_item_wrapper = entity_metadata_wrapper('commerce_line_item', $line_item);
$weight = NULL;
// If the line item references a valid product...
if (!empty($line_item_wrapper->commerce_product)) {
$product = $line_item_wrapper->commerce_product
->value();
if (!empty($product)) {
// If the product has a valid weight field...
$field_name = commerce_physical_entity_weight_field_name('commerce_product', $product);
if (!empty($field_name) && !empty($product->{$field_name})) {
// Extract the weight value from the product.
$product_wrapper = entity_metadata_wrapper('commerce_product', $product);
$weight = $product_wrapper->{$field_name}
->value();
// Multiply the weight value by the quantity of the line item.
$weight['weight'] *= $line_item->quantity;
}
}
}
// Allow other modules to alter the weight if necessary.
drupal_alter('commerce_physical_product_line_item_weight', $weight, $line_item);
return $weight;
}
/**
* Determines the dimensions of a product line item on an order.
*
* @param commerce_line_item $line_item
* A product line item whose dimensions should be determined.
*
* @return array
* An array of dimensions field value arrays. There'll be one entry in the
* array per product, with the entry being an array of that product's
* dimensions. If this line item contains no products with dimensions, an
* empty array will be returned.
*/
function commerce_physical_product_line_item_dimensions($line_item) {
$line_item_wrapper = entity_metadata_wrapper('commerce_line_item', $line_item);
$dimensions = array();
// If the line item references a valid product...
if (!empty($line_item_wrapper->commerce_product)) {
$product = $line_item_wrapper->commerce_product
->value();
if (!empty($product)) {
// If the product has a valid dimensions field...
$field_name = commerce_physical_entity_dimensions_field_name('commerce_product', $product);
if (!empty($field_name) && !empty($product->{$field_name})) {
$product_wrapper = entity_metadata_wrapper('commerce_product', $product);
// Add dimension values per product in the line item.
for ($i = 0; $i < $line_item_wrapper->quantity
->value(); $i++) {
$dimensions[] = $product_wrapper->{$field_name}
->value();
}
}
}
}
// Allow other modules to alter the weight if necessary.
drupal_alter('commerce_physical_product_line_item_dimensions', $dimensions, $line_item);
return $dimensions;
}
/**
* Determines the weight of an entire order.
*
* @param commerce_order $order
* The order object whose weight value should be calculated.
* @param string $unit
* The unit of measurement to use for the returned weight of the order.
*
* @return array
* A weight field value array representing the total weight of the order using
* the specified unit of measurement or NULL if no weight could be determined.
*/
function commerce_physical_order_weight($order, $unit = 'lb') {
$order_wrapper = entity_metadata_wrapper('commerce_order', $order);
$weight = NULL;
// Loop over each line item on the order.
foreach ($order_wrapper->commerce_line_items as $delta => $line_item_wrapper) {
// Get the weight value of product line items.
if (in_array($line_item_wrapper
->getBundle(), commerce_product_line_item_types())) {
$line_item_weight = commerce_physical_product_line_item_weight($line_item_wrapper
->value());
// Add it to the running total converting it to the required weight unit.
if (!empty($line_item_weight['weight'])) {
$converted_weight = physical_weight_convert($line_item_weight, $unit);
if (empty($weight['weight'])) {
$weight = $converted_weight;
}
else {
$weight['weight'] += $converted_weight['weight'];
}
}
}
}
// Allow other modules to alter the weight if necessary.
drupal_alter('commerce_physical_order_weight', $weight, $order, $unit);
return $weight;
}
/**
* Determines the volume of an entire order.
*
* @param commerce_order $order
* The order object whose volume should be calculated.
* @param string $unit
* The unit of measurement to convert dimensions to before calculating the
* volume of the order in the related cubic unit.
*
* @return array
* A volume value array with keys representing the total 'volume' of the order
* in the 'unit' specified or NULL if no volume could be determined.
*/
function commerce_physical_order_volume($order, $unit = 'in') {
$order_wrapper = entity_metadata_wrapper('commerce_order', $order);
$volume = NULL;
// Loop over each line item on the order.
foreach ($order_wrapper->commerce_line_items as $delta => $line_item_wrapper) {
// Get the dimensions value of product line items.
if (in_array($line_item_wrapper->type
->value(), commerce_product_line_item_types())) {
$line_item_dimensions = commerce_physical_product_line_item_dimensions($line_item_wrapper
->value());
// Each product in a line item has the same dimensions, so we index into
// only the first product.
$line_item_dimensions = reset($line_item_dimensions);
// Add it to the running total converting it to the required weight unit.
if (!physical_field_is_empty($line_item_dimensions, array(
'type' => 'physical_dimensions',
))) {
$converted_dimensions = physical_dimensions_convert($line_item_dimensions, $unit);
$converted_dimensions['volume'] = $converted_dimensions['width'] * $converted_dimensions['length'] * $converted_dimensions['height'] * $line_item_wrapper->quantity
->value();
if (empty($volume['volume'])) {
// Create a volume value array using the converted unit type.
$volume = array(
'volume' => $converted_dimensions['volume'],
'unit' => $unit,
);
}
else {
$volume['volume'] += $converted_dimensions['volume'];
}
}
}
}
// Allow other modules to alter the volume if necessary.
drupal_alter('commerce_physical_order_volume', $volume, $order, $unit);
return $volume;
}
/**
* Determines the dimensions of each product in an entire order.
*
* Other code can then use this data to figure out things like what the maximum
* dimensions of any product in the order is, or what size shipping container
* everything will fit into.
*
* @param commerce_order $order
* The order object whose dimensions should be returned.
* @param string $unit
* The unit of measurement to use for the returned dimensions.
*
* @return array
* An array of dimension arrays. One per product in the order.
* weight field value array representing the total weight of the order using
* the specified unit of measurement or NULL if no weight could be determined.
*/
function commerce_physical_order_dimensions($order, $unit = 'cm') {
$order_wrapper = entity_metadata_wrapper('commerce_order', $order);
$order_dimensions = array();
// Loop over each line item on the order.
foreach ($order_wrapper->commerce_line_items as $delta => $line_item_wrapper) {
// Get the weight value of product line items.
if (in_array($line_item_wrapper->type
->value(), commerce_product_line_item_types())) {
$line_item_dimensions = commerce_physical_product_line_item_dimensions($line_item_wrapper
->value());
$order_dimensions = array_merge($order_dimensions, $line_item_dimensions);
}
}
// Now ensure that all dimensions supplied are in the requested units.
foreach ($order_dimensions as $key => $dimensions) {
$order_dimensions[$key] = physical_dimensions_convert($dimensions, $unit);
}
// Allow other modules to alter the weight if necessary.
drupal_alter('commerce_physical_order_dimensions', $order_dimensions, $order, $unit);
return $order_dimensions;
}
/**
* Determines whether or not a line item should be considered shippable.
*
* @param commerce_line_item $line_item
* The line item object whose shippability is being determined.
*
* @return bool
* Boolean indicating whether or not the given line item represents something
* shippable; defaults to FALSE unless the line item represents a product line
* item with a discernible weight.
*/
function commerce_physical_line_item_shippable($line_item) {
$shippable = FALSE;
// If this is a product line item...
if (in_array($line_item->type, commerce_product_line_item_types())) {
// Mark this line item as shippable if we can determine its weight.
$weight = commerce_physical_product_line_item_weight($line_item);
if (!empty($weight)) {
$shippable = TRUE;
}
}
// Allow other modules to alter the shippability of the line item.
drupal_alter('commerce_physical_line_item_shippable', $shippable, $line_item);
return $shippable;
}
/**
* Determines whether or not an order should be considered shippable.
*
* @param commerce_order $order
* The order object whose shippability should be determined.
*
* @return bool
* Boolean indicating whether or not the given order is shippable; defaults to
* FALSE unless any line item on the order is determined to be shippable.
*/
function commerce_physical_order_shippable($order) {
$order_wrapper = entity_metadata_wrapper('commerce_order', $order);
$shippable = FALSE;
// Loop over all the line items on the order.
foreach ($order_wrapper->commerce_line_items as $delta => $line_item_wrapper) {
// Mark the order as shippable if the current line item is determined to be
// shippable.
if (commerce_physical_line_item_shippable($line_item_wrapper
->value())) {
$shippable = TRUE;
}
}
// Allow other modules to alter the shippability of the line item.
drupal_alter('commerce_physical_order_shippable', $shippable, $order);
return $shippable;
}
/**
* Name of the shipping customer profile reference field for the given order.
*
* @param commerce_order $order
* The order whose shipping customer profile reference field name should be
* determined.
*
* @return string
* The name of the field to use on the order to find shipping information or
* NULL if none was found; defaults to commerce_customer_shipping if available
* or another customer profile reference if not (preferring profiles other
* than the default billing profile if available).
*/
function commerce_physical_order_shipping_field_name($order) {
$field_name = NULL;
if (!empty($order->commerce_customer_shipping)) {
$field_name = 'commerce_customer_shipping';
}
else {
// Look for customer profile references fields available for the order.
foreach (field_info_instances('commerce_order', $order->type) as $instance_name => $instance) {
// Load the field info for the current instance.
$field = field_info_field($instance['field_name']);
// If it's of the proper type...
if ($field['type'] == 'commerce_customer_profile_reference') {
// Save its name and exit the loop if it isn't the billing profile.
$field_name = $instance_name;
if ($field_name != 'commerce_customer_billing') {
break;
}
}
}
}
// Allow other modules to specify a different field name.
drupal_alter('commerce_physical_order_shipping_field_name', $field_name, $order);
return $field_name;
}
/**
* Determines the name of the phone number field of a customer profile.
*
* @param commerce_cutomer_profile $profile
* The customer profile whose phone number field name should be determined.
*
* @return string
* The name of the field to use on the customer profile to find a phone number
* or NULL if none was found. Defaults to field_phone or field_phone_number if
* available; otherwise it's up to you to alter it in a custom module since we
* don't want to depend on an actual phone number field.
*/
function commerce_physical_customer_profile_phone_number_field_name($profile) {
if (!empty($profile->field_phone)) {
$field_name = 'field_phone';
}
elseif (!empty($profile->field_phone_number)) {
$field_name = 'field_phone_number';
}
else {
$field_name = '';
}
// Allow other modules to specify a different field name.
drupal_alter('commerce_physical_customer_profile_phone_number_field_name', $field_name, $profile);
return $field_name;
}
/**
* Whether or not a shipping customer profile is a residential address.
*
* @param commerce_customer_profile $profile
* The customer profile whose residential status should be determined.
*
* @return bool
* Boolean indicating whether or not the given profile has a residential
* address; defaults to TRUE unless otherwise determined by a custom module.
*/
function commerce_physical_customer_profile_residential($profile) {
$residential = TRUE;
// Allow other modules to determine if the profile has a residential address.
drupal_alter('commerce_physical_customer_profile_residential', $residential, $profile);
return $residential;
}
Functions
Name | Description |
---|---|
commerce_physical_customer_profile_phone_number_field_name | Determines the name of the phone number field of a customer profile. |
commerce_physical_customer_profile_residential | Whether or not a shipping customer profile is a residential address. |
commerce_physical_entity_dimensions_field_name | Determines the dimensions field to use for a given entity. |
commerce_physical_entity_field_name | Determines the field of a certain type to use for a given entity. |
commerce_physical_entity_weight_field_name | Determines the weight field to use for a given entity. |
commerce_physical_line_item_shippable | Determines whether or not a line item should be considered shippable. |
commerce_physical_order_dimensions | Determines the dimensions of each product in an entire order. |
commerce_physical_order_shippable | Determines whether or not an order should be considered shippable. |
commerce_physical_order_shipping_field_name | Name of the shipping customer profile reference field for the given order. |
commerce_physical_order_volume | Determines the volume of an entire order. |
commerce_physical_order_weight | Determines the weight of an entire order. |
commerce_physical_product_line_item_dimensions | Determines the dimensions of a product line item on an order. |
commerce_physical_product_line_item_weight | Determines the weight to use for a product line item on an order. |