View source
<?php
define('PM_BLOCK_USER_DISALLOW_BLOCKING', 0);
define('PM_BLOCK_USER_DISALLOW_SENDING', 1);
function pm_block_user_help($path) {
switch ($path) {
case 'admin/settings/messages/block':
return '<p>' . t('This area is used to define user blocking rules for the Privatemsg module. Rules allow control of who may block messages from whom. By default all users are allowed to block messages from anyone else. However, a site may have groups of users that need to contact or get information to others, for example: the site may have administrative staff or be a forum with moderators. Groups of users are defined by roles, which can be managed on the <a href="@roles">roles configuration page</a>.', array(
'@roles' => url('admin/user/roles'),
)) . '</p>';
}
}
function pm_block_user_menu() {
$items['messages/block/%user'] = array(
'title' => 'Block user messages',
'page callback' => 'drupal_get_form',
'page arguments' => array(
'pm_block_user_form',
2,
),
'access callback' => '_pm_block_user_access',
'access arguments' => array(
2,
),
'type' => MENU_CALLBACK,
'weight' => -10,
);
$items['admin/settings/messages/block'] = array(
'title' => 'User blocking rules',
'description' => 'Configure rules for which users may block each other.',
'page callback' => 'drupal_get_form',
'page arguments' => array(
'pm_block_user_settings',
),
'access arguments' => array(
'administer privatemsg settings',
),
'type' => MENU_LOCAL_TASK,
);
$items['messages/block/js'] = array(
'title' => 'Javascript block actions form',
'page callback' => 'pm_block_user_js',
'access arguments' => array(
'administer privatemsg settings',
),
'type' => MENU_CALLBACK,
);
return $items;
}
function pm_block_user_settings(&$form_state) {
drupal_add_css(drupal_get_path('module', 'pm_block_user') . '/pm_block_user.css');
$form = array(
'#cache' => TRUE,
);
$form['block_actions'] = array(
'#tree' => TRUE,
'#prefix' => '<div id="block-actions">',
'#suffix' => '</div>',
'#theme' => 'pm_block_user_actions',
);
if (!isset($form_state['pm_block_user']['block_actions'])) {
$block_actions = variable_get('pm_block_user_actions', array());
}
else {
$block_actions = $form_state['pm_block_user']['block_actions'];
}
foreach ($block_actions as $delta => $details) {
$details['delta'] = $delta;
$form['block_actions'][$delta] = _pm_block_user_actions_form($details);
}
$form['pm_block_actions_more'] = array(
'#type' => 'submit',
'#value' => t('More'),
'#weight' => 1,
'#prefix' => '<div id="add-rule-button">',
'#suffix' => '<label for="edit-pm-block-actions-more">' . t('Add new rule') . '</label></div>',
'#submit' => array(
'pm_block_user_more_submit',
),
'#ahah' => array(
'path' => 'messages/block/js',
'wrapper' => 'block-actions',
'method' => 'replace',
'effect' => 'fade',
),
);
$form['submit_form'] = array(
'#type' => 'submit',
'#weight' => 10,
'#value' => t('Save configuration'),
);
return $form;
}
function _pm_block_user_actions_form($details, $blacklist = TRUE) {
$form = array(
'#tree' => TRUE,
);
$delta = $details['delta'];
$row_disabled = isset($details['enabled']) ? !$details['enabled'] : FALSE;
$form['author'] = array(
'#type' => 'select',
'#options' => user_roles(TRUE),
'#default_value' => isset($details['author']) ? $details['author'] : DRUPAL_AUTHENTICATED_RID,
'#disabled' => $row_disabled,
);
$form['recipient'] = array(
'#type' => 'select',
'#options' => user_roles(TRUE),
'#default_value' => isset($details['recipient']) ? $details['recipient'] : DRUPAL_AUTHENTICATED_RID,
'#disabled' => $row_disabled,
);
if ($blacklist) {
$options = array(
PM_BLOCK_USER_DISALLOW_BLOCKING => t('Disallow blocking author'),
PM_BLOCK_USER_DISALLOW_SENDING => t('Disallow sending message'),
);
$default_value = isset($details['action']) ? $details['action'] : PM_BLOCK_USER_DISALLOW_BLOCKING;
}
else {
}
$form['action'] = array(
'#type' => 'radios',
'#options' => $options,
'#disabled' => $row_disabled,
'#default_value' => $default_value,
);
$form['enabled'] = array(
'#type' => 'checkbox',
'#default_value' => isset($details['enabled']) ? $details['enabled'] : TRUE,
);
$form['remove'] = array(
'#type' => 'submit',
'#submit' => array(
'pm_block_user_remove_submit',
),
'#value' => t('Remove'),
'#attributes' => array(
'class' => 'remove-action',
),
'#prefix' => '<div id="remove-rule-button">',
'#suffix' => '<label for="edit-remove">' . t('Remove rule') . '</label></div>',
'#ahah' => array(
'path' => 'messages/block/js',
'wrapper' => 'block-actions',
'method' => 'replace',
'effect' => 'fade',
),
);
return $form;
}
function pm_block_user_more_submit($form, &$form_state) {
unset($form_state['submit_handlers']);
form_execute_handlers('submit', $form, $form_state);
$submitted_values = $form_state['values'];
$submitted_values['block_actions'][] = array();
$form_state['pm_block_user'] = $submitted_values;
$form_state['rebuild'] = TRUE;
}
function pm_block_user_remove_submit($form, &$form_state) {
unset($form_state['submit_handlers']);
form_execute_handlers('submit', $form, $form_state);
$submitted_values = $form_state['values'];
$delta = $form_state['clicked_button']['#parents'][1];
unset($submitted_values['block_actions'][$delta]);
$form_state['pm_block_user'] = $submitted_values;
$form_state['rebuild'] = TRUE;
}
function pm_block_user_settings_submit($form, &$form_state) {
if ($form_state['clicked_button']['#id'] == 'edit-submit-form') {
if (isset($form_state['values']['block_actions'])) {
variable_set('pm_block_user_actions', _pm_block_user_settings_filter($form_state['values']['block_actions']));
}
else {
variable_set('pm_block_user_actions', array());
}
drupal_set_message(t('The configuration options have been saved.'));
}
}
function _pm_block_user_settings_filter($settings) {
$save_keys = array(
'author',
'recipient',
'action',
'enabled',
);
$matching = array();
foreach ($save_keys as $save_key) {
if (isset($settings[$save_key])) {
$matching[$save_key] = $settings[$save_key];
}
}
if (count($matching) > 0) {
return $matching;
}
else {
return array_map('_pm_block_user_settings_filter', $settings);
}
}
function pm_block_user_js() {
$form_state = array(
'storage' => NULL,
'submitted' => FALSE,
);
$form_build_id = $_POST['form_build_id'];
$form = form_get_cache($form_build_id, $form_state);
$args = $form['#parameters'];
$form_id = array_shift($args);
$form['#post'] = $_POST;
$form['#redirect'] = FALSE;
$form['#programmed'] = FALSE;
$form_state['post'] = $_POST;
drupal_process_form($form_id, $form, $form_state);
$form = drupal_rebuild_form($form_id, $form_state, $args, $form_build_id);
$output_form = $form['block_actions'];
unset($output_form['#prefix'], $output_form['#suffix']);
$output = theme('status_messages') . drupal_render($output_form);
$javascript = drupal_add_js(NULL, NULL, 'header');
drupal_json(array(
'status' => TRUE,
'data' => $output,
));
}
function pm_block_user_theme() {
return array(
'pm_block_user_actions' => array(
'arguments' => array(
'form' => NULL,
),
),
);
}
function theme_pm_block_user_actions($form) {
$rows = array();
$headers = array(
t('If the author has the role'),
t('And the recipient has the role'),
t('Action'),
t('Enabled'),
'',
);
$form_data = element_children($form);
foreach ($form_data as $key) {
$row = array(
'data' => array(
array(
'data' => drupal_render($form[$key]['author']),
),
array(
'data' => drupal_render($form[$key]['recipient']),
),
array(
'data' => drupal_render($form[$key]['action']),
),
array(
'data' => drupal_render($form[$key]['enabled']),
),
array(
'data' => drupal_render($form[$key]['remove']),
),
),
);
if (isset($form[$key]['#attributes'])) {
$row = array_merge($row, $form[$key]['#attributes']);
}
$rows[] = $row;
}
if (empty($form_data)) {
$rows[] = array(
array(
'data' => t("No rules have been added. All users may block private messages from each other. To limit which users may be blocked, click 'Add new rule'."),
'colspan' => '5',
),
);
}
$output = theme('table', $headers, $rows);
$output .= drupal_render($form);
return $output;
}
function _pm_block_user_access($account) {
global $user;
if (!privatemsg_user_access('read privatemsg', $user)) {
return FALSE;
}
if (_pm_block_user_rule_exists($account, $user, PM_BLOCK_USER_DISALLOW_BLOCKING)) {
return FALSE;
}
return TRUE;
}
function _pm_block_user_rule_exists($author, $recipient, $action = PM_BLOCK_USER_DISALLOW_BLOCKING) {
$block_actions = variable_get('pm_block_user_actions', array());
foreach ($block_actions as $delta => $details) {
if ($details['action'] != $action || !$details['enabled']) {
continue;
}
if ($author->uid == 1 && $action == PM_BLOCK_USER_DISALLOW_SENDING) {
continue;
}
if ($recipient->uid == 1 && $action == PM_BLOCK_USER_DISALLOW_BLOCKING) {
continue;
}
if (isset($author->roles[$details['author']]) && isset($recipient->roles[$details['recipient']])) {
return TRUE;
}
}
return FALSE;
}
function pm_block_user_form($form_state, $author) {
global $user;
$form['author'] = array(
'#type' => 'value',
'#value' => $author->uid,
);
$form['recipient'] = array(
'#type' => 'value',
'#value' => $user->uid,
);
$form['author_name'] = array(
'#type' => 'value',
'#value' => $author->name,
);
$form['destination'] = array(
'#type' => 'value',
'#value' => isset($_GET['destination']) ? $_GET['destination'] : 'messages/',
);
if (db_result(db_query('SELECT COUNT(recipient) FROM {pm_block_user} WHERE author = %d AND recipient = %d', $author->uid, $user->uid))) {
$form['block_action'] = array(
'#type' => 'value',
'#value' => 'unblock_user',
);
return confirm_form($form, t('You have previously blocked "@author" from sending you any more messages. Are you sure you want to unblock this user?', array(
'@author' => $author->name,
)), isset($_GET['destination']) ? $_GET['destination'] : 'messages/', t('This action cannot be undone.'), t('Unblock @author', array(
'@author' => $author->name,
)), t('Cancel'));
}
else {
$form['block_action'] = array(
'#type' => 'value',
'#value' => 'block_user',
);
return confirm_form($form, t('Are you sure you want to block "@author" from sending you any more messages?', array(
'@author' => $author->name,
)), isset($_GET['destination']) ? $_GET['destination'] : 'messages/', '', t('Block @author', array(
'@author' => $author->name,
)), t('Cancel'));
}
}
function pm_block_user_form_submit($form, &$form_state) {
if ($form_state['values']['confirm']) {
switch ($form_state['values']['block_action']) {
case 'block_user':
db_query('INSERT INTO {pm_block_user} (author, recipient) VALUES (%d, %d)', $form_state['values']['author'], $form_state['values']['recipient']);
drupal_set_message(t('@author has been blocked from sending you any further messages.', array(
'@author' => $form_state['values']['author_name'],
)));
break;
case 'unblock_user':
db_query('DELETE FROM {pm_block_user} WHERE author = %d AND recipient = %d', $form_state['values']['author'], $form_state['values']['recipient']);
drupal_set_message(t('@author is now allowed to send you new messages.', array(
'@author' => $form_state['values']['author_name'],
)));
break;
}
}
$form_state['redirect'] = $form_state['values']['destination'];
}
function pm_block_user_privatemsg_block_message($author, $recipients) {
$blocked = array();
foreach (array_keys($recipients) as $uid) {
if (!isset($recipients[$uid]->roles)) {
$recipients[$uid] = user_load($uid);
}
if (_pm_block_user_rule_exists($author, $recipients[$uid], PM_BLOCK_USER_DISALLOW_SENDING)) {
$blocked[] = array(
'uid' => $uid,
'message' => t('Sorry, private messaging rules forbid sending messages to !name.', array(
'!name' => $recipients[$uid]->name,
)),
);
}
}
$args = array_merge(array(
$author->uid,
), array_keys($recipients));
$result = db_query('SELECT recipient FROM {pm_block_user} WHERE author = %d AND recipient IN (' . db_placeholders($recipients) . ') GROUP BY recipient', $args);
while ($row = db_fetch_array($result)) {
$recipient = $recipients[$row['recipient']];
if (_pm_block_user_rule_exists($author, $recipient, PM_BLOCK_USER_DISALLOW_BLOCKING)) {
continue;
}
$blocked[] = array(
'uid' => $row['recipient'],
'message' => t('%name has chosen to not recieve any more messages from you.', array(
'%name' => $recipients[$row['recipient']]->name,
)),
);
}
return $blocked;
}
function pm_block_user_privatemsg_sql_load_alter(&$fragments, $pmid, $uid) {
$fragments['select'][] = 'pmbu.recipient AS is_blocked';
$fragments['inner_join'][] = 'LEFT JOIN {pm_block_user} pmbu ON (pm.author = pmbu.author AND pmi.uid = pmbu.recipient)';
}
function pm_block_user_privatemsg_message_view_alter(&$vars) {
global $user;
$author = $vars['message']['author'];
if (_pm_block_user_rule_exists($author, $user, PM_BLOCK_USER_DISALLOW_BLOCKING)) {
return;
}
if (!isset($vars['message']['thread_id'])) {
return;
}
$thread_id = $vars['message']['thread_id'];
if ($user->uid != $author->uid) {
if ($vars['message']['is_blocked']) {
$vars['message_actions']['unblock_author'] = array(
'title' => t('Unblock author'),
'href' => 'messages/block/' . $author->uid,
'query' => 'destination=messages/view/' . $thread_id,
);
}
else {
$vars['message_actions']['block_author'] = array(
'title' => t('Block author'),
'href' => 'messages/block/' . $author->uid,
'query' => 'destination=messages/view/' . $thread_id,
);
}
}
}
function pm_block_user_user($op, &$edit, &$account, $category = NULL) {
switch ($op) {
case 'delete':
db_query("DELETE FROM {pm_block_user} WHERE author = %d OR recipient = %d", $account->uid, $account->uid);
break;
}
}