array(
'title' => t('Smartqueue per User'),
'description' => t('Provides a nodequeue for each user of one or more specified roles.'),
)
);
}
/**
* Implementation of hook_nodequeue_form().
*/
function smartqueue_users_nodequeue_form($queue, &$form) {
$qid = $queue->qid;
$form['placeholder']['smartqueue_users'] = array(
'#type' => 'fieldset',
'#title' => t('Smartqueue per user settings'),
);
$form['placeholder']['smartqueue_users']['restrict_by_author'] = array(
'#type' => 'checkbox',
'#title' => t("Restrict contents of user nodequeue to content that is created by the nodequeue's owner"),
'#description' => t("When this box is checked, each user subqueue can only contain content created by that subqueue's author."),
'#default_value' => (int)_smartqueue_users_settings_get('restrict_by_author', $qid),
);
$form['placeholder']['smartqueue_users']['subqueue_limit'] = array(
'#type' => 'textfield',
'#title' => t('Maximum number of subqueues per user'),
'#description' => t('Set this to limit the number of subqueues a user can create. Leave blank or 0 for unlimited.'),
'#default_value' => (int)_smartqueue_users_settings_get('subqueue_limit', $qid),
'#maxlength' => 2,
'#size' => 2,
);
$form['placeholder']['smartqueue_users']['subqueue_privacy_default'] = array(
'#type' => 'radios',
'#title' => t('Default privacy of subqueues'),
'#description' => t("Select the default privacy for each user's subqueues."),
'#options' => _smartqueue_users_form_privacy_options(),
'#default_value' => (int)_smartqueue_users_settings_get('subqueue_privacy_default', $qid),
);
$form['placeholder']['smartqueue_users']['subqueue_privacy_changeable'] = array(
'#type' => 'checkbox',
'#title' => t('Users can change the default privacy on their own subqueues.'),
'#default_value' => (int)_smartqueue_users_settings_get('subqueue_privacy_changeable', $qid),
);
$form['placeholder']['smartqueue_users']['manipulation_method'] = array(
'#type' => 'radios',
'#title' => t('Manipulation method'),
'#description' => t('Choose how the subqueue manipulation will be displayed at the bottom of the subqueue view page.'),
'#options' => _smartqueue_users_form_manipulation_options(),
'#default_value' => (int)_smartqueue_users_settings_get('manipulation_method', $qid),
);
if (module_exists('views')) {
$form['placeholder']['smartqueue_users']['view'] = array(
'#type' => 'select',
'#title' => t('Display view'),
'#description' => t('Select the view to use for displaying the content of subqueues. It will use the "default" display and the Subqueue ID as the first parameter.'),
'#options' => _smartqueue_users_views_options(),
'#default_value' => _smartqueue_users_settings_get('view', $qid),
);
}
}
/**
* Implementation of hook_nodequeue_form_validate().
*/
function smartqueue_users_nodequeue_form_validate(&$queue, $form_state, &$form) {
// Validate that subqueue limit is either empty or a number.
$subqueue_limit = $form_state['values']['subqueue_limit'];
if (empty($subqueue_limit)) {
$form_state['values']['subqueue_limit'] = 0;
} else if (!is_numeric($subqueue_limit)) {
form_set_error('subqueue_limit', t('The maximum number of subqueues per user must be a number or blank.'));
}
}
/**
* Implementation of hook_nodequeue_form_submit_finish().
*/
function smartqueue_users_nodequeue_form_submit_finish(&$queue, $form_state) {
$qid = $queue->qid;
_smartqueue_users_settings_set('restrict_by_author', $qid, (bool)$form_state['values']['restrict_by_author']);
_smartqueue_users_settings_set('subqueue_limit', $qid, (int)$form_state['values']['subqueue_limit']);
_smartqueue_users_settings_set('subqueue_privacy_default', $qid, (int)$form_state['values']['subqueue_privacy_default']);
_smartqueue_users_settings_set('subqueue_privacy_changeable', $qid, (bool)$form_state['values']['subqueue_privacy_changeable']);
_smartqueue_users_settings_set('manipulation_method', $qid, (int)$form_state['values']['manipulation_method']);
_smartqueue_users_settings_set('view', $qid, $form_state['values']['view']);
}
/**
* Implementation of hook_queue_access().
*/
function smartqueue_users_queue_access($queue, $account = NULL) {
return (user_access('manipulate all queues', $account) || user_access('manipulate all user queues', $account)
|| user_access('manipulate own user queue', $account));
}
/**
* Implementation of hook_subqueue_access().
*/
function smartqueue_users_subqueue_access($subqueue, $account, $queue) {
// Load the subqueue's account.
$subqueue_account = user_load(smartqueue_users_get_subqueue_owner($subqueue));
return smartqueue_users_can_manipulate($subqueue_account, $account);
}
/**
* Implementation of hook_nodequeue_subqueues().
*
* We provide only subqueues that belong to the current user, to
* prevent too much subqueues from appearing.
*/
function smartqueue_users_nodequeue_subqueues(&$queue, $node) {
global $user;
if (($node->uid != $user->uid) && _smartqueue_users_settings_get('restrict_by_author', $queue->qid)) {
// This queue restricts content of subqueues to same owners, and this node is not owned by $user.
return FALSE;
}
return array_shift(smartqueue_users_get_subqueue_references($user, $queue));
}
/**
* Implementation of hook_nodequeue_autocomplete().
*/
function smartqueue_users_nodequeue_autocomplete($queue, $subqueue, $string, $where, $where_args) {
$matches = array();
// Add a filter to restrict by auther when relevant.
if (_smartqueue_users_settings_get('restrict_by_author', $queue->qid)) {
$where .= ' AND uid = %d';
$where_args[] = smartqueue_users_get_subqueue_owner($subqueue);
}
$result = db_query_range(db_rewrite_sql("SELECT n.nid, n.title FROM {node} n WHERE $where"), $where_args, 0, 10);
while ($node = db_fetch_object($result)) {
$matches[$node->nid] = check_plain($node->title) ." [nid: $node->nid]";
}
return $matches;
}
/**
* Implementation of hook_nodequeue_table().
*/
function smartqueue_users_nodequeue_table($table_id, &$header, &$rows, &$attributes, &$caption, $queue = NULL, $subqueues = NULL) {
if ($table_id == 'nodequeue_view_subqueues' && $queue->owner == 'smartqueue_users') {
// Add Users column
array_splice($header, -1, 0, t('User'));
// Add the users to the Users column
$i = 0;
foreach ($subqueues as $subqueue) {
$account = user_load(smartqueue_users_get_subqueue_owner($subqueue));
array_splice($rows[$i], -1, 0, theme('username', $account));
$i++;
}
}
}
/**
* Menu hooks.
*/
/**
* Implementation of hook_menu().
*/
function smartqueue_users_menu() {
$items = array();
$items['user/%user_uid_optional/queue'] = array(
'title' => 'My Queues',
'page arguments' => array(1),
'page callback' => 'smartqueue_users_profile_page',
'access arguments' => array(1),
'access callback' => 'user_view_access',
'type' => MENU_LOCAL_TASK | MENU_SUGGESTED_ITEM,
'file' => 'includes/pages.inc',
);
$items['user/%user/queue/%nodequeue/add'] = array(
'title' => 'Add a subqueue to a user queue',
'page arguments' => array(1, 3),
'page callback' => 'smartqueue_users_subqueue_add',
'access arguments' => array(1),
'access callback' => 'smartqueue_users_can_manipulate',
'type' => MENU_CALLBACK,
'file' => 'includes/manipulate.inc',
);
$items['user/%user/queue/%nodequeue/view/%subqueue'] = array(
'title' => 'View a subqueue from a user queue',
'page arguments' => array(1, 3, 5),
'page callback' => 'smartqueue_users_subqueue_view',
'access arguments' => array(1, 3, 5),
'access callback' => 'smartqueue_users_can_view',
'type' => MENU_CALLBACK,
'file' => 'includes/pages.inc',
);
$items['user/%user/queue/%nodequeue/edit/%subqueue'] = array(
'title' => 'Edit a subqueue in a user queue',
'page arguments' => array(1, 3, 5),
'page callback' => 'smartqueue_users_subqueue_edit',
'access arguments' => array(1),
'access callback' => 'smartqueue_users_can_manipulate',
'type' => MENU_CALLBACK,
'file' => 'includes/manipulate.inc',
);
$items['user/%user/queue/%nodequeue/delete/%subqueue'] = array(
'title' => 'Delete a subqueue from a user queue',
'page arguments' => array(1, 3, 5),
'page callback' => 'smartqueue_users_subqueue_remove',
'access arguments' => array(1),
'access callback' => 'smartqueue_users_can_manipulate',
'type' => MENU_CALLBACK,
'file' => 'includes/manipulate.inc',
);
return $items;
}
/**
* Theme hooks.
*/
/**
* Implementation of hook_theme().
*/
function smartqueue_users_theme($existing, $type, $theme, $path) {
$path = drupal_get_path('module', 'smartqueue_users') . '/theme';
$base = array(
'file' => 'theme.inc',
'path' => $path,
);
return array(
'smartqueue_users_profile_page' => $base + array(
'arguments' => array('account' => array(), 'queues' => array(), 'subqueues' => array()),
'template' => 'smartqueue-users-profile-page',
),
'smartqueue_users_subqueue_empty' => $base + array(
'arguments' => array('subqueue'),
),
'smartqueue_users_privacy' => $base + array(
'arguments' => array('privacy'),
),
);
}
/**
* User hooks.
*/
/**
* Implementation of hook_perm().
*/
function smartqueue_users_perm() {
return array('manipulate own user queue', 'manipulate all user queues');
}
/**
* Implementation of hook_user().
*/
function smartqueue_users_user($op, &$edit, &$account, $category = NULL) {
switch ($op) {
case 'delete':
// Remove all the subqueues that belong to this user.
$db_result = db_query("SELECT sqid FROM {nodequeue_subqueue} WHERE reference LIKE '%d-%%' AND qid IN (SELECT qid FROM {nodequeue_queue} WHERE owner = 'smartqueue_users')", $account->uid);
while ($sqid = db_result($db_result)) {
smartqueue_users_remove_subqueue($sqid);
}
break;
}
}
/**
* Block hooks.
*/
/**
* Implementation of hook_block().
*/
function smartqueue_users_block($op = 'list', $delta = 0, $edit = array()) {
switch ($op) {
case 'list':
return array(
array(
'info' => t('User queues'),
'cache' => BLOCK_CACHE_PER_PAGE,
'title' => t('Queues'),
),
);
break;
case 'configure':
$form = array();
if (user_access('use PHP for block visibility')) {
$form['argument_php'] = array(
'#type' => 'textarea',
'#title' => t('Argument PHP'),
'#description' => t('PHP code that returns a user ID. Return 0 to hide the block. You can use the arg() function to get URL arguments.'),
'#default_value' => _smartqueue_users_variable_get('block_argument_php'),
);
}
else {
$form['argument_php'] = array(
'#type' => 'markup',
'#value' => '
' . _smartqueue_users_variable_get('block_argument_php') . '
',
'#prefix' => '',
);
}
return $form;
break;
case 'save':
_smartqueue_users_variable_set('block_argument_php', $edit['argument_php']);
break;
case 'view':
// Get the URL from the PHP code
$uid = drupal_eval('');
// If we got a relevant uid then we continue
if (is_numeric($uid) && $uid > 0) {
// Load the given account
$account = user_load($uid);
// Get the smartqueue_users queues.
$queues = smartqueue_users_get_all_queues();
// Get the existing subqueues for each smartqueue_users queue.
$subqueues = array();
foreach ($queues as $qid => $queue) {
$subqueues[$qid] = nodequeue_load_subqueues_by_reference(smartqueue_users_get_subqueue_references($account, $queue));
// Add the privacy setting for each subqueue.
foreach ($subqueues[$qid] as $sqid => $subqueue) {
$subqueues[$qid][$sqid]->privacy = smartqueue_users_subqueue_get_privacy($subqueue);
}
}
// Get the themed content.
$content = theme('smartqueue_users_profile_page', $account, $queues, $subqueues);
return array(
'subject' => t("!user's queues", array('!user' => $account->name)),
'content' => $content,
);
}
break;
}
}
/**
* External modules integration hooks.
*/
/**
* Implementation of hook_views_api().
*
* Integration with Views.
*/
function smartqueue_users_views_api() {
return array(
'api' => 2.0,
'path' => drupal_get_path('module', 'smartqueue_users') .'/includes/views',
);
}
/**
* User access related functions.
*/
/**
* Check whether a given user account has reached the subqueue limit
* for the given queue.
*
* @return
* TRUE if the user has reached the limit. FALSE otherwise.
*/
function smartqueue_users_reached_subqueue_limit($uid, $qid) {
// Get the subqueue limit setting for this queue.
$limit = _smartqueue_users_settings_get('subqueue_limit', $qid);
// $limit == 0 means no limit, so always false.
if ($limit == 0) {
return FALSE;
}
// Count how many subqueues exist for this user in this queue.
$num_existing = db_result(db_query("SELECT COUNT(sqid) FROM {nodequeue_subqueue} WHERE qid = %d AND reference LIKE '%d-%%'", $qid, $uid));
return !($num_existing < $limit);
}
/**
* Check whether a user can manipulate the the subqueues of the first argument account.
*/
function smartqueue_users_can_manipulate($subqueue_account, $checking_account = NULL) {
// If no account to check against was provided, default to current user.
if (empty($checking_account)) {
global $user;
$checking_account = $user;
}
$can_manipulate = user_access('manipulate all user queues', $checking_account) || user_access('manipulate all queues', $checking_account);
$can_manipulate = $can_manipulate || (($subqueue_account->uid == $checking_account->uid) && user_access('manipulate own user queue', $checking_account));
return $can_manipulate;
}
/**
* Check wether the current user can view the provided subqueue.
*/
function smartqueue_users_can_view($account, $queue, $subqueue) {
$checking_account = $account;
$subqueue_account = user_load(smartqueue_users_get_subqueue_owner($subqueue));
if ($subqueue->qid != $queue->qid) {
return FALSE; // Sanity check.
}
if (_smartqueue_users_sanity_check($checking_account, $queue, $subqueue, TRUE)) {
return TRUE; // Users can always view their own subqueues.
}
// Allow viewing for public subqueues.
if (smartqueue_users_subqueue_get_privacy($subqueue) == SMARTQUEUE_USERS_PRIVACY_PUBLIC) {
return TRUE;
}
// Allow viewing for users who can manipulate this user's subqueues.
if (smartqueue_users_can_manipulate($subqueue_account, $checking_account)) {
return TRUE;
}
// If all else fails, disallow viewing.
return FALSE;
}
/**
* Getters and filters for queues and subqueues lists.
*/
/**
* Get all the queues that belong to smartqueue_users.
*
* @return
* An array of queue objects where the key is the qid.
*/
function smartqueue_users_get_all_queues() {
// Get a list of qids that belong to smartqueue_users.
$db_result = db_query("SELECT qid FROM {nodequeue_queue} WHERE owner = 'smartqueue_users'");
$qids = array();
while ($qid = db_result($db_result)) {
$qids[] = $qid;
}
return nodequeue_load_queues($qids);
}
/**
* Filter out subqueues that are not viewable by the provided user.
*
* @param $account
* The user account to check viewing permissions for.
* @param $queue
* The queue that the subqueues belong to.
* @param $subqueues
* A keyed array of subqueues. (sqid => subqueue object)
* @return The $subqueues array without the unviewable subqueues.
*/
function smartqueue_users_subqueue_filter_viewable($account, $queue, $subqueues) {
$filtered = array();
foreach ($subqueues as $sqid => $subqueue) {
if (smartqueue_users_can_view($account, $queue, $subqueue)) {
$filtered[$sqid] = $subqueue;
}
}
return $filtered;
}
/**
* Subqueue manipulators.
*/
/**
* Set the privacy of a subqueue.
*/
function smartqueue_users_subqueue_set_privacy($subqueue, $privacy) {
if (db_result(db_query('SELECT COUNT(privacy) FROM {smartqueue_users_subqueue} WHERE sqid = %d', $subqueue->sqid)) == 0) {
db_query('INSERT INTO {smartqueue_users_subqueue} (sqid, privacy) VALUES (%d, %d)', $subqueue->sqid, $privacy);
}
else {
db_query('UPDATE {smartqueue_users_subqueue} SET privacy = %d WHERE sqid = %d LIMIT 1', $privacy, $subqueue->sqid);
}
}
/**
* Get the privacy of a subqueue.
*/
function smartqueue_users_subqueue_get_privacy($subqueue) {
// Only return a subqueue specific privacy setting if users can change the default privacy of subqueue in that queue.
if (_smartqueue_users_settings_get('subqueue_privacy_changeable', $subqueue->qid)) {
// If the result is a strict FALSE then there is no subqueue specific privacy setting.
if (($privacy = db_result(db_query('SELECT privacy FROM {smartqueue_users_subqueue} WHERE sqid = %d', $subqueue->sqid))) !== FALSE) {
return $privacy;
}
}
// Otherwise, return the default privacy for subqueues in this queue
return _smartqueue_users_settings_get('subqueue_privacy_default', $subqueue->qid);
}
/**
* Removes a subqueue.
*/
function smartqueue_users_remove_subqueue($sqid) {
nodequeue_remove_subqueue($sqid);
db_query('DELETE FROM {smartqueue_users_subqueue} WHERE sqid = %d LIMIT 1', $sqid);
}
/**
* Get the uid of this subqueue owner.
*/
function smartqueue_users_get_subqueue_owner($subqueue) {
return (int)array_shift(explode('-', $subqueue->reference));
}
/**
* Calculate the next unique reference string for the provided uid/qid.
*/
function smartqueue_users_get_next_reference_string($uid, $qid) {
$max_reference = db_result(db_query("SELECT MAX(reference) FROM {nodequeue_subqueue} WHERE qid = %d AND reference LIKE '%d-%%'", $qid, $uid));
$rfid = ((int)array_pop(explode('-', $max_reference))) + 1;
return "$uid-$rfid";
}
/**
* Calculate an array to be used for nodequeue_load_subqueues_by_reference().
*/
function smartqueue_users_get_subqueue_references($account, $queue) {
$db_result = db_query("SELECT reference FROM {nodequeue_subqueue} WHERE qid = %d AND reference LIKE '%d-%%'", $queue->qid, $account->uid);
$references = array($queue->qid => array());
while ($reference = db_result($db_result)) {
$references[$queue->qid][] = $reference;
}
return $references;
}
/**
* Private functions.
*/
/**
* Sanity check.
* This function check that the provided subqueue is a subqueue of
* the provided queue, and that it references the provided account.
*
* If it isn't, then we probably shouldn't proceed, and we invoke a
* 404.
* If the return argument is set, simply return FALSE on error,
* Otherwise, always return TRUE.
*/
function _smartqueue_users_sanity_check($account, $queue, $subqueue, $return = FALSE) {
if ($subqueue->qid != $queue->qid || smartqueue_users_get_subqueue_owner($subqueue) != $account->uid) {
if ($return) {
return FALSE;
}
else {
drupal_not_found();
}
}
return TRUE;
}
/**
* Privacy options for the nodequeue form.
*/
function _smartqueue_users_form_privacy_options() {
return array(
SMARTQUEUE_USERS_PRIVACY_PUBLIC => t('Public'),
SMARTQUEUE_USERS_PRIVACY_PRIVATE => t('Private'),
);
}
/**
* Manipulation options for the nodequeue form.
*/
function _smartqueue_users_form_manipulation_options() {
return array(
SMARTQUEUE_USERS_MANIPULATION_UI => t("Inline (Nodequeue's default UI)"),
SMARTQUEUE_USERS_MANIPULATION_LINK => t("External (Link to nodequeue's default UI)"),
SMARTQUEUE_USERS_MANIPULATION_HIDDEN => t('Hidden (provide your own)'),
);
}
/**
* Views options for the nodequeue form.
*/
function _smartqueue_users_views_options() {
$views = array(-1 => t('-Default display-'));
foreach (views_get_all_views() as $view_id => $view) {
if ($view->base_table == 'node' && !$view->disabled) {
$views[$view_id] = $view_id;
}
}
return $views;
}
/**
* Smartqueue per user's persistent variables helper getter function.
*/
function _smartqueue_users_variable_get($var) {
// If a value is returned by variable_get, return that value
if (($value = variable_get("smartqueue_users_$var", NULL)) !== NULL) {
return $value;
}
// Otherwise, return the default value for this variable
switch ($var) {
case 'restrict_by_author':
case 'subqueue_limit':
case 'subqueue_privacy_default':
case 'subqueue_privacy_changeable':
case 'manipulation_method':
case 'view':
return array();
break;
case 'block_argument_php':
return
"if (arg(0) == 'user' && is_numeric(arg(1))) {\n".
" return arg(1);\n".
"}\n".
"return 0;";
default:
return NULL;
break;
}
}
/**
* Smartqueue per user's persistent variables helper setter function.
*/
function _smartqueue_users_variable_set($var, $value) {
variable_set("smartqueue_users_$var", $value);
}
/**
* Smartqueue per user's settings getter.
*/
function _smartqueue_users_settings_get($var, $qid) {
$qid = (int)$qid;
if ($qid) {
// $qid is present, editing an existing nodequeue, get the settings
$setting = _smartqueue_users_variable_get($var);
if (isset($setting[$qid])) {
return $setting[$qid];
}
}
// No $qid (new nodequeue) or no existing setting, get the defaults
switch ($var) {
case 'restrict_by_author':
return FALSE;
break;
case 'subqueue_limit':
return 1;
break;
case 'subqueue_privacy_default':
return SMARTQUEUE_USERS_PRIVACY_PUBLIC;
break;
case 'subqueue_privacy_changeable':
return FALSE;
break;
case 'manipulation_method':
return SMARTQUEUE_USERS_MANIPULATION_UI;
break;
case 'view':
return -1;
break;
}
}
/**
* Smartqueue per user's settings setter.
*/
function _smartqueue_users_settings_set($var, $qid, $value) {
$qid = (int)$qid;
$setting = _smartqueue_users_variable_get($var);
$setting[$qid] = $value;
_smartqueue_users_variable_set($var, $setting);
}