352 lines
12 KiB
Plaintext
352 lines
12 KiB
Plaintext
<?php
|
|
|
|
/**
|
|
* @file
|
|
* Examples demonstrating the Drupal Queue API.
|
|
*/
|
|
|
|
/**
|
|
* @defgroup queue_example Example: Queue
|
|
* @ingroup examples
|
|
* @{
|
|
* Demonstrating the Queue API
|
|
*
|
|
* The Queue API provides a traditional FIFO (first-in-first-out) queue,
|
|
* but also provides the concepts of:
|
|
* - "Creating" a queued item, which means inserting it into a queue.
|
|
* - "Claiming" a queued item, which essentially means requesting the next item
|
|
* from the queue and holding a lock on that item for a specified period of
|
|
* time.
|
|
* - "Releasing" an item, which means giving up a claim but leaving the item in
|
|
* the queue.
|
|
* - "Deleting" an item, which means finally removing it from the queue.
|
|
*
|
|
* This example demonstrates only basic queue functionality, and will use the
|
|
* default queue implementation, which is SystemQueue, managed using
|
|
* persistent database storage.
|
|
*
|
|
* Further resources include the limited @link queue @endlink documentation.
|
|
* More:
|
|
*
|
|
* @link http://www.ent.iastate.edu/it/Batch_and_Queue.pdf Batch vs Queue Presentation slides by John VanDyk @endlink
|
|
* @link http://sf2010.drupal.org/conference/sessions/batch-vs-queue-api-smackdown session video. @endlink
|
|
*
|
|
* @see system.queue.inc
|
|
*/
|
|
|
|
/**
|
|
* Implements hook_menu().
|
|
*/
|
|
function queue_example_menu() {
|
|
$items = array();
|
|
$items['queue_example/insert_remove'] = array(
|
|
'title' => 'Queue Example: Insert and remove',
|
|
'page callback' => 'drupal_get_form',
|
|
'page arguments' => array('queue_example_add_remove_form'),
|
|
'access callback' => TRUE,
|
|
);
|
|
|
|
return $items;
|
|
}
|
|
|
|
/**
|
|
* Form generator for managing the queue.
|
|
*
|
|
* Provides an interface to add items to the queue, to retrieve (claim)
|
|
* an item from the head of the queue, and to claim and delete. Also
|
|
* allows the user to run cron manually, so that claimed items can be
|
|
* released.
|
|
*/
|
|
function queue_example_add_remove_form($form, &$form_state) {
|
|
// Simple counter that makes it possible to put auto-incrementing default
|
|
// string into the string to insert.
|
|
if (empty($form_state['storage']['insert_counter'])) {
|
|
$form_state['storage']['insert_counter'] = 1;
|
|
}
|
|
|
|
$queue_name = !empty($form_state['values']['queue_name']) ? $form_state['values']['queue_name'] : 'queue_example_first_queue';
|
|
$items = queue_example_retrieve_queue($queue_name);
|
|
|
|
// Add CSS to make the form a bit denser.
|
|
$form['#attached']['css'] = array(drupal_get_path('module', 'queue_example') . '/queue_example.css');
|
|
|
|
$form['help'] = array(
|
|
'#type' => 'markup',
|
|
'#markup' => '<div>' . t('This page is an interface on the Drupal queue API. You can add new items to the queue, "claim" one (retrieve the next item and keep a lock on it), and delete one (remove it from the queue). Note that claims are not expired until cron runs, so there is a special button to run cron to perform any necessary expirations.') . '</div>',
|
|
);
|
|
|
|
$form['queue_name'] = array(
|
|
'#type' => 'select',
|
|
'#title' => t('Choose queue to examine'),
|
|
'#options' => drupal_map_assoc(array('queue_example_first_queue', 'queue_example_second_queue')),
|
|
'#default_value' => $queue_name,
|
|
);
|
|
$form['queue_show'] = array(
|
|
'#type' => 'submit',
|
|
'#value' => t('Show queue'),
|
|
'#submit' => array('queue_example_show_queue'),
|
|
);
|
|
$form['status_fieldset'] = array(
|
|
'#type' => 'fieldset',
|
|
'#title' => t('Queue status for @name', array('@name' => $queue_name)),
|
|
'#collapsible' => TRUE,
|
|
);
|
|
$form['status_fieldset']['status'] = array(
|
|
'#type' => 'markup',
|
|
'#markup' => theme('queue_items', array('items' => $items)),
|
|
);
|
|
$form['insert_fieldset'] = array(
|
|
'#type' => 'fieldset',
|
|
'#title' => t('Insert into @name', array('@name' => $queue_name)),
|
|
);
|
|
$form['insert_fieldset']['string_to_add'] = array(
|
|
'#type' => 'textfield',
|
|
'#size' => 10,
|
|
'#default_value' => t('item @counter', array('@counter' => $form_state['storage']['insert_counter'])),
|
|
);
|
|
$form['insert_fieldset']['add_item'] = array(
|
|
'#type' => 'submit',
|
|
'#value' => t('Insert into queue'),
|
|
'#submit' => array('queue_example_add_remove_form_insert'),
|
|
);
|
|
$form['claim_fieldset'] = array(
|
|
'#type' => 'fieldset',
|
|
'#title' => t('Claim from queue'),
|
|
'#collapsible' => TRUE,
|
|
);
|
|
|
|
$form['claim_fieldset']['claim_time'] = array(
|
|
'#type' => 'radios',
|
|
'#title' => t('Claim time, in seconds'),
|
|
'#options' => array(
|
|
0 => t('none'),
|
|
5 => t('5 seconds'),
|
|
60 => t('60 seconds'),
|
|
),
|
|
'#description' => t('This time is only valid if cron runs during this time period. You can run cron manually below.'),
|
|
'#default_value' => !empty($form_state['values']['claim_time']) ? $form_state['values']['claim_time'] : 5,
|
|
);
|
|
$form['claim_fieldset']['claim_item'] = array(
|
|
'#type' => 'submit',
|
|
'#value' => t('Claim the next item from the queue'),
|
|
'#submit' => array('queue_example_add_remove_form_claim'),
|
|
);
|
|
$form['claim_fieldset']['claim_and_delete_item'] = array(
|
|
'#type' => 'submit',
|
|
'#value' => t('Claim the next item and delete it'),
|
|
'#submit' => array('queue_example_add_remove_form_delete'),
|
|
);
|
|
$form['claim_fieldset']['run_cron'] = array(
|
|
'#type' => 'submit',
|
|
'#value' => t('Run cron manually to expire claims'),
|
|
'#submit' => array('queue_example_add_remove_form_run_cron'),
|
|
);
|
|
$form['delete_queue'] = array(
|
|
'#type' => 'submit',
|
|
'#value' => t('Delete the queue and items in it'),
|
|
'#submit' => array('queue_example_add_remove_form_clear_queue'),
|
|
);
|
|
return $form;
|
|
}
|
|
|
|
/**
|
|
* Submit function for the insert-into-queue button.
|
|
*/
|
|
function queue_example_add_remove_form_insert($form, &$form_state) {
|
|
// Get a queue (of the default type) called 'queue_example_queue'.
|
|
// If the default queue class is SystemQueue this creates a queue that stores
|
|
// its items in the database.
|
|
$queue = DrupalQueue::get($form_state['values']['queue_name']);
|
|
// There is no harm in trying to recreate existing.
|
|
$queue->createQueue();
|
|
|
|
// Queue the string.
|
|
$queue->createItem($form_state['values']['string_to_add']);
|
|
$count = $queue->numberOfItems();
|
|
drupal_set_message(t('Queued your string (@string_to_add). There are now @count items in the queue.', array('@count' => $count, '@string_to_add' => $form_state['values']['string_to_add'])));
|
|
// Setting 'rebuild' to TRUE allows us to keep information in $form_state.
|
|
$form_state['rebuild'] = TRUE;
|
|
// Unsetting the string_to_add allows us to set the incremented default value
|
|
// for the user so they don't have to type anything.
|
|
unset($form_state['input']['string_to_add']);
|
|
$form_state['storage']['insert_counter']++;
|
|
}
|
|
|
|
/**
|
|
* Submit function for the show-queue button.
|
|
*/
|
|
function queue_example_show_queue($form, &$form_state) {
|
|
$queue = DrupalQueue::get($form_state['values']['queue_name']);
|
|
// There is no harm in trying to recreate existing.
|
|
$queue->createQueue();
|
|
|
|
// Get the number of items.
|
|
$count = $queue->numberOfItems();
|
|
|
|
// Update the form item counter.
|
|
$form_state['storage']['insert_counter'] = $count + 1;
|
|
|
|
// Unset the string_to_add textbox.
|
|
unset($form_state['input']['string_to_add']);
|
|
|
|
$form_state['rebuild'] = TRUE;
|
|
}
|
|
|
|
/**
|
|
* Submit function for the "claim" button.
|
|
*
|
|
* Claims (retrieves) an item from the queue and reports the results.
|
|
*/
|
|
function queue_example_add_remove_form_claim($form, &$form_state) {
|
|
$queue = DrupalQueue::get($form_state['values']['queue_name']);
|
|
// There is no harm in trying to recreate existing.
|
|
$queue->createQueue();
|
|
$item = $queue->claimItem($form_state['values']['claim_time']);
|
|
$count = $queue->numberOfItems();
|
|
if (!empty($item)) {
|
|
drupal_set_message(
|
|
t('Claimed item id=@item_id string=@string for @seconds seconds. There are @count items in the queue.',
|
|
array(
|
|
'@count' => $count,
|
|
'@item_id' => $item->item_id,
|
|
'@string' => $item->data,
|
|
'@seconds' => $form_state['values']['claim_time'],
|
|
)
|
|
)
|
|
);
|
|
}
|
|
else {
|
|
drupal_set_message(t('There were no items in the queue available to claim. There are @count items in the queue.', array('@count' => $count)));
|
|
}
|
|
$form_state['rebuild'] = TRUE;
|
|
}
|
|
|
|
/**
|
|
* Submit function for "Claim and delete" button.
|
|
*/
|
|
function queue_example_add_remove_form_delete($form, &$form_state) {
|
|
$queue = DrupalQueue::get($form_state['values']['queue_name']);
|
|
// There is no harm in trying to recreate existing.
|
|
$queue->createQueue();
|
|
$count = $queue->numberOfItems();
|
|
$item = $queue->claimItem(60);
|
|
if (!empty($item)) {
|
|
drupal_set_message(
|
|
t('Claimed and deleted item id=@item_id string=@string for @seconds seconds. There are @count items in the queue.',
|
|
array(
|
|
'@count' => $count,
|
|
'@item_id' => $item->item_id,
|
|
'@string' => $item->data,
|
|
'@seconds' => $form_state['values']['claim_time'],
|
|
)
|
|
)
|
|
);
|
|
$queue->deleteItem($item);
|
|
$count = $queue->numberOfItems();
|
|
drupal_set_message(t('There are now @count items in the queue.', array('@count' => $count)));
|
|
}
|
|
else {
|
|
$count = $queue->numberOfItems();
|
|
drupal_set_message(t('There were no items in the queue available to claim/delete. There are currently @count items in the queue.', array('@count' => $count)));
|
|
}
|
|
$form_state['rebuild'] = TRUE;
|
|
}
|
|
|
|
/**
|
|
* Submit function for "run cron" button.
|
|
*
|
|
* Runs cron (to release expired claims) and reports the results.
|
|
*/
|
|
function queue_example_add_remove_form_run_cron($form, &$form_state) {
|
|
drupal_cron_run();
|
|
$queue = DrupalQueue::get($form_state['values']['queue_name']);
|
|
// There is no harm in trying to recreate existing.
|
|
$queue->createQueue();
|
|
$count = $queue->numberOfItems();
|
|
drupal_set_message(t('Ran cron. If claimed items expired, they should be expired now. There are now @count items in the queue', array('@count' => $count)));
|
|
$form_state['rebuild'] = TRUE;
|
|
}
|
|
|
|
/**
|
|
* Submit handler for clearing/deleting the queue.
|
|
*/
|
|
function queue_example_add_remove_form_clear_queue($form, &$form_state) {
|
|
$queue = DrupalQueue::get($form_state['values']['queue_name']);
|
|
$queue->deleteQueue();
|
|
drupal_set_message(t('Deleted the @queue_name queue and all items in it', array('@queue_name' => $form_state['values']['queue_name'])));
|
|
}
|
|
|
|
/**
|
|
* Retrieves the queue from the database for display purposes only.
|
|
*
|
|
* It is not recommended to access the database directly, and this is only here
|
|
* so that the user interface can give a good idea of what's going on in the
|
|
* queue.
|
|
*
|
|
* @param array $queue_name
|
|
* The name of the queue from which to fetch items.
|
|
*/
|
|
function queue_example_retrieve_queue($queue_name) {
|
|
$items = array();
|
|
$result = db_query("SELECT item_id, data, expire, created FROM {queue} WHERE name = :name ORDER BY item_id",
|
|
array(':name' => $queue_name),
|
|
array('fetch' => PDO::FETCH_ASSOC));
|
|
foreach ($result as $item) {
|
|
$items[] = $item;
|
|
}
|
|
return $items;
|
|
}
|
|
|
|
/**
|
|
* Themes the queue display.
|
|
*
|
|
* Again, this is not part of the demonstration of the queue API, but is here
|
|
* just to make the user interface more understandable.
|
|
*
|
|
* @param array $variables
|
|
* Our variables.
|
|
*/
|
|
function theme_queue_items($variables) {
|
|
$items = $variables['items'];
|
|
$rows = array();
|
|
foreach ($items as &$item) {
|
|
if ($item['expire'] > 0) {
|
|
$item['expire'] = t("Claimed: expires %expire", array('%expire' => date('r', $item['expire'])));
|
|
}
|
|
else {
|
|
$item['expire'] = t('Unclaimed');
|
|
}
|
|
$item['created'] = date('r', $item['created']);
|
|
$item['content'] = check_plain(unserialize($item['data']));
|
|
unset($item['data']);
|
|
$rows[] = $item;
|
|
}
|
|
if (!empty($rows)) {
|
|
$header = array(
|
|
t('Item ID'),
|
|
t('Claimed/Expiration'),
|
|
t('Created'),
|
|
t('Content/Data'),
|
|
);
|
|
$output = theme('table', array('header' => $header, 'rows' => $rows));
|
|
return $output;
|
|
}
|
|
else {
|
|
return t('There are no items in the queue.');
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Implements hook_theme().
|
|
*/
|
|
function queue_example_theme() {
|
|
return array(
|
|
'queue_items' => array(
|
|
'variables' => array('items' => NULL),
|
|
),
|
|
);
|
|
}
|
|
/**
|
|
* @} End of "defgroup queue_example".
|
|
*/
|