commerce_stock_local.module in Commerce Stock 8
Commerce Stock Local module.
File
modules/local_storage/commerce_stock_local.moduleView source
<?php
/**
* @file
* Commerce Stock Local module.
*/
use Drupal\Core\Render\Element;
use Drupal\Core\Entity\EntityTypeInterface;
use Drupal\Core\Field\BaseFieldDefinition;
/**
* Implements hook_entity_base_field_info().
*/
function commerce_stock_local_entity_base_field_info(EntityTypeInterface $entity_type) {
// Get class of entity type.
if (in_array('Drupal\\commerce\\PurchasableEntityInterface', class_implements($entity_type
->getOriginalClass()))) {
$fields['commerce_stock_always_in_stock'] = BaseFieldDefinition::create('boolean')
->setLabel(t('Always in stock?'))
->setDescription(t('Should this product be considered "always in stock"?'))
->setDisplayConfigurable('form', TRUE)
->setDisplayOptions('form', [
'type' => 'boolean_checkbox',
'weight' => 5,
])
->setDefaultValue(FALSE);
return $fields;
}
}
/**
* Implements hook_cron().
*/
function commerce_stock_local_cron() {
$next = \Drupal::state()
->get('commerce_stock_local.update_level_next') ?: 0;
$request_time = \Drupal::time()
->getRequestTime();
if ($request_time >= $next) {
$cron_run_mode = \Drupal::config('commerce_stock_local.cron')
->get('cron_run_mode');
if ($cron_run_mode == 'legacy') {
_commerce_stock_local_update_stock_level_queue_legacy();
}
else {
_commerce_stock_local_update_stock_level_queue();
}
// Set the next run time.
$interval = \Drupal::config('commerce_stock_local.cron')
->get('update_interval');
\Drupal::state()
->set('commerce_stock_local.update_level_next', $request_time + $interval);
}
}
/**
* Updates the stock level update queue.
*
* Adds purchasable entities from the latest unprocessed stock transactions
* to the queue worker responsible for totaling location stock levels.
*
* @todo Support all purchasable entities - not just product variations.
* @see https://www.drupal.org/node/2844010
*/
function _commerce_stock_local_update_stock_level_queue() {
// Get the queue.
$queue = \Drupal::queue('commerce_stock_local_stock_level_updater');
// If we have unprocessed items.
if ($queue
->numberOfItems() > 0) {
// We do not want to add more items until all qued items are processed.
return;
}
// Build the query to return only variations with new transactions.
$db = \Drupal::database();
$query = $db
->select('commerce_stock_transaction', 'st_t');
// Join the location level table.
$query
->leftjoin('commerce_stock_location_level', 'st_l', ' st_l.location_id = st_t.location_id and st_l.entity_id = st_t.entity_id');
// We only return the entity ID.
$query
->fields('st_t', [
'entity_id',
]);
// Create the OR Condition group
$group = $query
->orConditionGroup()
->isNull('st_l.entity_id')
->where('st_l.last_transaction_id < st_t.id');
// Add OR group as a condition.
$query
->condition($group);
$result = $query
->distinct()
->execute()
->fetchAll();
/** @var \Drupal\Core\Entity\EntityStorageInterface $storage */
$storage = \Drupal::entityTypeManager()
->getStorage('commerce_product_variation');
// Cycle the returned entity IDs and add them to the queue.
foreach ($result as $pid) {
$entity = $storage
->load($pid->entity_id);
$data = [
'entity_id' => $entity
->id(),
'entity_type' => $entity
->getEntityTypeId(),
];
$queue
->createItem($data);
}
}
/**
* Updates the stock level update queue legacy system.
*
* This will systematically check all products on the site.
* Adds purchasable entities from the latest unprocessed stock transactions
* to the queue worker responsible for totaling location stock levels.
*/
function _commerce_stock_local_update_stock_level_queue_legacy() {
$queue = \Drupal::queue('commerce_stock_local_stock_level_updater');
// Get the last processed product id.
$level_last_id = \Drupal::state()
->get('commerce_stock_local.update_last_id');
$level_last_id = !empty($level_last_id) ? $level_last_id : 0;
// Check if Q empty and not initialized to 0.
if ($queue
->numberOfItems() == 0 && $level_last_id != 0) {
// Set the Q reset state.
\Drupal::state()
->set('commerce_stock_local.llq_reset', TRUE);
$llq_reset = TRUE;
}
else {
// Get the Q reset state.
$llq_reset = \Drupal::state()
->get('commerce_stock_local.llq_reset');
$llq_reset = !empty($llq_reset) ? $llq_reset : FALSE;
}
// Get the batch size.
$llq_batchsize = \Drupal::config('commerce_stock_local.cron')
->get('update_batch_size');
$llq_batchsize = !empty($llq_batchsize) ? $llq_batchsize : 50;
/** @var \Drupal\Core\Entity\EntityStorageInterface $storage */
$storage = \Drupal::entityTypeManager()
->getStorage('commerce_product_variation');
$result = $storage
->getQuery()
->condition('variation_id', $level_last_id, '>')
->condition('status', 1, '=')
->sort('variation_id', 'ASC')
->range(0, $llq_batchsize)
->execute();
foreach ($result as $pid) {
$entity = $storage
->load($pid);
$data = [
'entity_id' => $entity
->id(),
'entity_type' => $entity
->getEntityTypeId(),
];
$queue
->createItem($data);
}
// Check if we can restrt processing products from the top.
if ($llq_reset && count($result) < $llq_batchsize) {
// Set reset to FALSE.
\Drupal::state()
->set('commerce_stock_local.llq_reset', FALSE);
// Set last product id to 0.
\Drupal::state()
->set('commerce_stock_local.update_last_id', 0);
}
else {
// Set the last product id for the Q bookmark.
if (!empty($result)) {
\Drupal::state()
->set('commerce_stock_local.update_last_id', $pid);
}
}
}
/**
* Implements hook_theme().
*/
function commerce_stock_local_theme() {
$theme = [];
$theme['commerce_stock_location'] = [
'render element' => 'elements',
];
$theme['commerce_stock_location_content_add_list'] = [
'render element' => 'content',
'variables' => [
'content' => NULL,
],
];
return $theme;
}
/**
* Implements hook_theme_suggestions_HOOK().
*/
function commerce_stock_local_theme_suggestions_commerce_stock_location(array $variables) {
return _commerce_entity_theme_suggestions('commerce_stock_location', $variables);
}
/**
* Prepares variables for Stock location templates.
*
* Default template: commerce-stock-location.html.twig.
*
* @param array $variables
* An associative array containing:
* - elements: An associative array containing the user information and any
* - attributes: HTML attributes for the containing element.
*/
function template_preprocess_commerce_stock_location(array &$variables) {
// Fetch StockLocation Entity Object.
$commerce_stock_location = $variables['elements']['#commerce_stock_location'];
$variables['commerce_stock_location_entity'] = $commerce_stock_location;
$variables['commerce_stock_location_url'] = $commerce_stock_location
->toUrl();
$variables['commerce_stock_location'] = [];
// Helpful $content variable for templates.
foreach (Element::children($variables['elements']) as $key) {
$variables['commerce_stock_location'][$key] = $variables['elements'][$key];
}
}
Functions
Name | Description |
---|---|
commerce_stock_local_cron | Implements hook_cron(). |
commerce_stock_local_entity_base_field_info | Implements hook_entity_base_field_info(). |
commerce_stock_local_theme | Implements hook_theme(). |
commerce_stock_local_theme_suggestions_commerce_stock_location | Implements hook_theme_suggestions_HOOK(). |
template_preprocess_commerce_stock_location | Prepares variables for Stock location templates. |
_commerce_stock_local_update_stock_level_queue | Updates the stock level update queue. |
_commerce_stock_local_update_stock_level_queue_legacy | Updates the stock level update queue legacy system. |