View source
<?php
define('DEFAULTMSGTEXT', 'Enter Message');
define('DEFAULTNICK', 'Your Name/Nick');
$sShout = variable_get('shoutbox_replace_singular', 'shout');
define('DEFAULTSHOUTSINGULAR', $sShout);
$sShoutCamelCase = substr($sShout, 0, 1) . substr($sShout, 1);
define('DEFAULTSHOUTSINGULAR_CC', $sShoutCamelCase);
$sShout = variable_get('shoutbox_replace_plural', 'shouts');
define('DEFAULTSHOUTPLURAL', $sShout);
$sShoutCamelCase = substr($sShout, 0, 1) . substr($sShout, 1);
define('DEFAULTSHOUTPLURAL_CC', $sShoutCamelCase);
function shoutbox_help($path, $arg) {
switch ($path) {
case 'admin/help#shoutbox':
$output = '';
$output .= '<h3>' . t('About') . '</h3>';
$output .= '<p>' . t('The shoutbox help is under construction. Please visit <a href="@page_url">shoutbox module</a> page for more info.', array(
'@page_url' => 'https://drupal.org/project/shoutbox',
)) . '</p>';
return $output;
}
}
function shoutbox_menu() {
$items = array();
$file = 'shoutbox.pages.inc';
$items['shoutbox'] = array(
'title' => 'Shoutbox',
'page callback' => 'shoutbox_view',
'access arguments' => array(
'access shoutbox',
),
'menu_name' => 'navigation',
'type' => MENU_NORMAL_ITEM,
);
$items['shoutbox/js/view'] = array(
'title' => 'View ' . DEFAULTSHOUTPLURAL,
'page callback' => 'shoutbox_js_view',
'access arguments' => array(
'access shoutbox',
),
'type' => MENU_CALLBACK,
);
$items['shout/%shoutbox_shout/edit'] = array(
'title' => 'Edit ' . DEFAULTSHOUTSINGULAR,
'page callback' => 'drupal_get_form',
'page arguments' => array(
'shoutbox_edit_form',
1,
),
'access callback' => '_shoutbox_user_access',
'access arguments' => array(
'edit own shouts',
1,
),
'type' => MENU_CALLBACK,
'file' => $file,
);
$items['shout/%shoutbox_shout/delete'] = array(
'title' => 'Delete ' . DEFAULTSHOUTSINGULAR,
'page callback' => 'drupal_get_form',
'page arguments' => array(
'shoutbox_delete_form',
1,
),
'access callback' => '_shoutbox_user_access',
'access arguments' => array(
'delete own shouts',
1,
),
'type' => MENU_CALLBACK,
'file' => $file,
);
$items['shout/%shoutbox_shout/publish'] = array(
'title' => 'Publish ' . DEFAULTSHOUTSINGULAR,
'page callback' => 'drupal_get_form',
'page arguments' => array(
'shoutbox_publish_form',
1,
),
'access callback' => '_shoutbox_user_access',
'access arguments' => array(
'moderate shoutbox',
),
'type' => MENU_CALLBACK,
'file' => $file,
);
$items['shout/%shoutbox_shout/unpublish'] = array(
'title' => 'Unpublish ' . DEFAULTSHOUTSINGULAR,
'page callback' => 'drupal_get_form',
'page arguments' => array(
'shoutbox_unpublish_form',
1,
),
'access callback' => '_shoutbox_user_access',
'access arguments' => array(
'moderate shoutbox',
),
'type' => MENU_CALLBACK,
'file' => $file,
);
$items['admin/config/user-interface/shoutbox'] = array(
'title' => 'Shoutbox',
'description' => 'Settings for Shoutbox',
'page callback' => 'drupal_get_form',
'page arguments' => array(
'shoutbox_admin_settings',
),
'access arguments' => array(
'administer shoutbox',
),
'file' => $file,
);
$items['admin/config/user-interface/shoutbox/manage'] = array(
'title' => 'Shoutbox',
'type' => MENU_DEFAULT_LOCAL_TASK,
'description' => 'Settings for Shoutbox',
'file' => $file,
);
return $items;
}
function shoutbox_shout_load($shout_id) {
$shout = FALSE;
if (is_numeric($shout_id)) {
$shout = db_query("SELECT * FROM {shoutbox} WHERE shout_id = :shout_id", array(
':shout_id' => $shout_id,
))
->fetchObject();
}
return $shout;
}
function shoutbox_block_info() {
$blocks['shoutbox']['info'] = t('Shoutbox');
return $blocks;
}
function shoutbox_block_view($delta) {
switch ($delta) {
case 'shoutbox':
if (user_access('access shoutbox')) {
if (arg(0) != 'shoutbox') {
$block['subject'] = t('Shoutbox');
$block['content'] = shoutbox_view(TRUE);
return $block;
}
}
}
}
function shoutbox_cron() {
$expiration = variable_get('shoutbox_expire', 0);
if ($expiration > 0) {
$expiration_val = REQUEST_TIME - 60 * 60 * 24 * $expiration;
$query = db_select('shoutbox', 's')
->fields('s')
->condition('s.created', $expiration_val, '<');
$result = $query
->execute();
foreach ($result as $shout) {
shoutbox_delete_shout($shout);
}
}
}
function shoutbox_permission() {
return array(
'administer shoutbox' => array(
'title' => t('Administer shoutbox'),
'description' => t('Administer shoutbox and ' . DEFAULTSHOUTPLURAL . ' settings.'),
),
'moderate shoutbox' => array(
'title' => t('Moderate ' . DEFAULTSHOUTPLURAL),
'description' => t('Enable/Disable posts from other users.'),
),
'access shoutbox' => array(
'title' => t('View shoutbox'),
),
'post shouts' => array(
'title' => t('Post ' . DEFAULTSHOUTPLURAL),
),
'post shouts without approval' => array(
'title' => t('Skip ' . DEFAULTSHOUTSINGULAR . ' approval'),
),
'edit own shouts' => array(
'title' => t('Edit own ' . DEFAULTSHOUTPLURAL),
),
'delete own shouts' => array(
'title' => t('Delete own ' . DEFAULTSHOUTPLURAL),
),
);
}
function shoutbox_delete_shout($shout) {
shoutbox_invoke('delete', $shout);
db_delete('shoutbox')
->condition('shout_id', $shout->shout_id)
->execute();
}
function shoutbox_js_view() {
switch ($_GET['mode']) {
case 'page':
$show_amount = variable_get('shoutbox_showamount_page', '30');
break;
case 'block':
default:
$show_amount = variable_get('shoutbox_showamount_block', '10');
break;
}
$shoutbox_posts_data = shoutbox_display_posts($show_amount);
$output = drupal_render($shoutbox_posts_data);
return drupal_json_output(array(
'success' => TRUE,
'data' => $output,
));
}
function _shoutbox_js_config() {
$refresh_path = 'shoutbox/js/view';
$shout = new stdClass();
shoutbox_invoke('js path', $shout, $refresh_path);
$js_settings = array(
'mode' => arg(0) == 'shoutbox' ? 'page' : 'block',
'refreshDelay' => shoutbox_get_refresh_rate(TRUE),
'ascending' => variable_get('shoutbox_ascending', TRUE),
'maxLength' => variable_get('shoutbox_max_length', 255),
'refreshPath' => url($refresh_path),
'currentPath' => $_GET['q'],
);
drupal_add_js(array(
'shoutbox' => $js_settings,
), array(
'type' => 'setting',
'scope' => JS_DEFAULT,
));
}
function shoutbox_get_refresh_rate($milliseconds = FALSE) {
if ($_GET['q'] == 'shoutbox' && isset($_GET['page'])) {
return 0;
}
else {
return variable_get('shoutbox_refresh', 0) * ($milliseconds ? 1000 : 1);
}
}
function shoutbox_view($block = FALSE) {
theme('shoutbox_external_files');
$build = array();
if (!$block) {
$show_amount = variable_get('shoutbox_showamount_page', '30');
}
else {
$show_amount = variable_get('shoutbox_showamount_block', '10');
}
$shoutbox_posts_data = shoutbox_display_posts($show_amount, !$block);
$shoutbox_posts_data['#prefix'] = "<div id=\"shoutbox-body\">\n";
$shoutbox_posts_data['#suffix'] = "</div>\n";
$build['posts'] = $shoutbox_posts_data;
if (count($shoutbox_posts_data['#rows'])) {
if ($block) {
$page_path = 'shoutbox';
$shout = new stdClass();
shoutbox_invoke('link', $shout, $page_path);
$build['all-shouts-link'] = array(
'#theme' => 'shoutbox_block_page_link',
'#path' => $page_path,
);
}
else {
$build['pager'] = array(
'#theme' => 'pager',
'#quantity' => 5,
'#weight' => 10,
);
}
}
$build['form'] = drupal_get_form('shoutbox_add_form');
_shoutbox_js_config();
return $build;
}
function shoutbox_get_user_link($shout) {
$link = '';
if ($shout->uid > 0) {
if ($field = variable_get('shoutbox_profile_name', '')) {
$aElements = explode("<split>", $field);
if (count($aElements) == 2) {
if ($aElements[0] == "profile") {
$name = db_query("SELECT v.value FROM {profile_value} v INNER JOIN {profile_field} f ON v.fid = f.fid\n WHERE f.name = :name AND v.uid = :uid", array(
':name' => $aElements[1],
':uid' => $shout->uid,
))
->fetchField();
$shout->nick = $name ? $name : $shout->nick;
}
elseif ($aElements[0] == "custom") {
$name = db_query("SELECT f.field_" . $aElements[1] . "_value FROM field_data_field_" . $aElements[1] . " as f\n WHERE f.entity_type='user' AND f.bundle='user'\n AND f.entity_id=:id", array(
':id' => $shout->uid,
))
->fetchField();
$shout->nick = $name ? $name : $shout->nick;
}
}
}
}
$object = new stdClass();
$object->uid = $shout->uid;
$object->name = $shout->nick;
return theme('username', array(
'account' => $object,
));
}
function shoutbox_theme() {
$registry = array(
'shoutbox_links' => array(
'variables' => array(),
),
'shoutbox_post_forbidden' => array(
'variables' => array(),
),
'shoutbox_interval_message' => array(
'variables' => array(
'interval' => NULL,
),
),
'shoutbox_block_page_link' => array(
'variables' => array(
'path' => NULL,
),
),
'shoutbox_external_files' => array(
'variables' => array(),
),
'shoutbox_post' => array(
'variables' => array(
'shout' => NULL,
'links' => array(),
),
),
'shoutbox_page' => array(
'variables' => array(
'rows' => array(),
),
),
);
$file = 'shoutbox.theme.inc';
foreach ($registry as $key => $entry) {
$registry[$key]['file'] = $file;
}
return $registry;
}
function shoutbox_add_form($form) {
global $user;
if (!(_shoutbox_user_access('post shouts') || _shoutbox_user_access('post shouts without approval'))) {
$form[] = array(
'#type' => 'item',
'#markup' => theme('shoutbox_post_forbidden'),
);
return $form;
}
if ($_GET['q'] == 'shoutbox' && isset($_GET['page'])) {
return array(
'shoutbox_return_link' => array(
'#type' => 'item',
'#markup' => '« ' . l(t('Return to the shoutbox'), $_GET['q']),
),
);
}
$max = variable_get('shoutbox_max_length', 255);
$form['wrapper'] = array(
'#type' => 'fieldset',
'#collapsible' => FALSE,
);
$form['wrapper']['error_message'] = array(
'#type' => 'item',
'#markup' => '<div id="shoutbox-error" class="messages error" title="Click to close"></div>',
);
$form['wrapper']['message'] = array(
'#type' => variable_get('shoutbox_widget_type', 'textfield'),
'#attributes' => array(
'placeholder' => variable_get('shoutbox_default_message'),
),
'#size' => "",
'#maxlength' => $max ? $max : NULL,
);
$form['wrapper']['nick_name_area'] = array(
'#type' => 'item',
);
$form['wrapper']['nick_submit_area'] = array(
'#type' => 'item',
);
$default_nick = t(DEFAULTNICK);
if (variable_get('shoutbox_defaultname', 1) && $user->uid) {
$default_nick = $user->name;
if ($user->uid > 0) {
if ($field = variable_get('shoutbox_profile_name', '')) {
$aElements = explode("<split>", $field);
if (count($aElements) == 2) {
if ($aElements[0] == "profile") {
$name = db_query("SELECT v.value FROM {profile_value} v INNER JOIN {profile_field} f ON v.fid = f.fid\n WHERE f.name = :name AND v.uid = :uid", array(
':name' => $aElements[1],
':uid' => $user->uid,
))
->fetchField();
$default_nick = $name ? $name : $user->name;
}
elseif ($aElements[0] == "custom") {
$name = db_query("SELECT f.field_" . $aElements[1] . "_value FROM field_data_field_" . $aElements[1] . " as f\n WHERE f.entity_type='user' AND f.bundle='user'\n AND f.entity_id=:id", array(
':id' => $user->uid,
))
->fetchField();
$default_nick = $name ? $name : $user->name;
}
}
}
}
$form['wrapper']['nick_name_area']['nick'] = array(
'#type' => 'textfield',
'#default_value' => $default_nick,
'#maxlength' => $max ? $max : NULL,
'#size' => "",
'#attributes' => array(
'disabled' => 'disabled',
),
);
}
else {
if ($default_nick == t(DEFAULTNICK)) {
$form['wrapper']['nick_name_area']['nick'] = array(
'#type' => 'textfield',
'#attributes' => array(
'placeholder' => $default_nick,
),
'#maxlength' => $max ? $max : NULL,
'#size' => "",
);
}
else {
$form['wrapper']['nick_name_area']['nick'] = array(
'#type' => 'textfield',
'#default_value' => $default_nick,
'#maxlength' => $max ? $max : NULL,
'#size' => "",
'#required' => TRUE,
);
}
}
$bAjaxSubmitEnable = variable_get('shoutbox_submit_type', 'post') == 'ajax' ? 1 : 0;
if ($bAjaxSubmitEnable) {
$form['wrapper']['nick_submit_area']['submit'] = array(
'#type' => 'submit',
'#value' => t(DEFAULTSHOUTSINGULAR_CC),
'#ajax' => array(
'callback' => '_handle_form_submit',
'effect' => 'fade',
'progress' => array(
'message' => NULL,
'type' => 'throbber',
),
'event' => 'click',
),
);
}
else {
$form['wrapper']['nick_submit_area']['submit'] = array(
'#type' => 'submit',
'#value' => t(DEFAULTSHOUTSINGULAR_CC),
);
}
$interval = shoutbox_get_refresh_rate();
if ($interval) {
$form['wrapper']['interval_message'] = array(
'#type' => 'item',
'#interval' => $interval,
'#theme' => 'shoutbox_interval_message',
);
}
$form['shoutbox_ajax'] = array(
'#type' => 'hidden',
'#value' => $bAjaxSubmitEnable,
'#attributes' => array(
'id' => 'shoutbox_ajax',
),
);
$shout = new stdClass();
shoutbox_invoke('form', $shout, $form);
$form['#prefix'] = '<div class="shoutbox-add-form">';
$form['#suffix'] = '</div>';
return $form;
}
function _validate_name($form, $form_state) {
if ($form_state['values']['name'] != '') {
$output = 'OK';
}
else {
$output = 'Enter a value';
}
return $output;
}
function _handle_form_submit($form, $form_state) {
$error = form_get_errors();
drupal_get_messages();
if (!empty($error)) {
$errormsg = '';
foreach ($error as $msg) {
$errormsg .= $errormsg != '' ? '<br/>' . $msg : $msg;
}
$commands[] = ajax_command_invoke(NULL, "error_javascript_call");
$commands[] = ajax_command_html('#shoutbox-error', $errormsg);
$commands[] = ajax_command_invoke('#shoutbox-error', 'show');
if (module_exists('captcha')) {
}
return array(
'#type' => 'ajax',
'#commands' => $commands,
);
}
else {
$commands[] = ajax_command_invoke(NULL, "success_javascript_call");
return array(
'#type' => 'ajax',
'#commands' => $commands,
);
}
}
function shoutbox_add_form_submit($form, &$form_state) {
global $user;
if (!_shoutbox_user_access('post shouts without approval')) {
$moderate = 1;
}
else {
$moderate = 0;
}
$shout = new stdClass();
$shout->uid = $user->uid;
$shout->nick = $form_state['values']['nick'] ? $form_state['values']['nick'] : variable_get('anonymous', 'Anonymous');
$shout->shout = $form_state['values']['message'];
$shout->moderate = $moderate;
$shout->created = REQUEST_TIME;
$shout->changed = $shout->created;
$shout->sid = session_id();
$shout->module = 'shoutbox';
$a1 = NULL;
shoutbox_invoke('presave', $shout, $a1, $form_state);
drupal_write_record('shoutbox', $shout);
shoutbox_invoke('insert', $shout, $a1, $form_state);
return;
}
function shoutbox_add_form_validate($form, &$form_state) {
$form_state['values']['message'] = trim($form_state['values']['message']);
$form_state['values']['nick'] = trim($form_state['values']['nick']);
$max = variable_get('shoutbox_max_length', 255);
$bErrorFound = FALSE;
if (!$form_state['values']['nick'] || $form_state['values']['nick'] == t(DEFAULTNICK)) {
form_set_error('nick', t('You must enter a nickname.'));
$bErrorFound = TRUE;
}
if (!$form_state['values']['message'] || $form_state['values']['message'] == t(DEFAULTMSGTEXT)) {
form_set_error('message', t('You must enter a message.'));
$bErrorFound = TRUE;
}
elseif ($max && strlen(utf8_decode($form_state['values']['message'])) > $max) {
form_set_error('message', t('Your ' . DEFAULTSHOUTSINGULAR . ' is too long. Only @max characters are allowed.', array(
'@max' => $max,
)));
$bErrorFound = TRUE;
}
if (!$bErrorFound && !_shoutbox_user_access('post shouts without approval')) {
drupal_set_message(t('Your ' . DEFAULTSHOUTSINGULAR . ' is waiting for approval by a moderator.'), 'warning');
}
}
function shoutbox_display_posts($show_amount, $pager = FALSE) {
$posts = array();
$rows = array();
$ascending = variable_get('shoutbox_ascending', TRUE);
$query = db_select('shoutbox', 's')
->orderBy('created', 'DESC')
->fields('s')
->addTag('shouts');
$contexts = array();
$blank = new stdClass();
shoutbox_invoke('context', $blank, $contexts);
foreach ($contexts as $key => $metaData) {
$query
->addMetaData($key, $metaData);
}
if (variable_get('shoutbox_restrict_general_shouts', 1) && empty($contexts)) {
$query
->condition('s.module', 'shoutbox', '=');
}
$delta = 0;
$weight = $show_amount + $delta;
if ($ascending) {
$delta = 1;
}
else {
$delta = -1;
}
if (!$pager) {
$query
->range(0, $show_amount);
}
else {
$query = $query
->extend('PagerDefault')
->limit($show_amount);
}
$result = $query
->execute();
foreach ($result as $shout) {
if ($shout->moderate == 0 || _shoutbox_user_access('moderate shoutbox') || _shoutbox_is_user_owned($shout)) {
_shoutbox_sanitize_shout($shout);
$shoutlinks = _shoutbox_get_links($shout);
$shout->shout = nl2br($shout->shout);
shoutbox_invoke('view', $shout);
$post = array(
'#theme' => 'shoutbox_post',
'#shout' => $shout,
'#links' => $shoutlinks,
'#weight' => $weight,
);
$rows[] = $post;
$weight += $delta;
}
}
$posts['#theme'] = 'shoutbox_page';
$posts['#rows'] = $rows;
return $posts;
}
function _shoutbox_get_links($shout) {
global $user;
$shoutlinks = array();
$links = theme('shoutbox_links');
if (_shoutbox_user_access('edit own shouts', $shout)) {
$shoutlinks[] = $links['edit'];
}
if (_shoutbox_user_access('delete own shouts', $shout)) {
$shoutlinks[] = $links['delete'];
}
if (_shoutbox_user_access('moderate shoutbox', $shout)) {
if ($shout->moderate == 0) {
$shoutlinks[] = $links['unpublish'];
}
else {
$shoutlinks[] = $links['publish'];
}
}
return $shoutlinks;
}
function _shoutbox_user_access($permission, $shout = NULL) {
global $user;
if (user_access('administer shoutbox')) {
return TRUE;
}
$user_timeout = FALSE;
$user_owned = FALSE;
$access_granted = user_access($permission);
if ($access_granted && ($permission == 'edit own shouts' || $permission == 'delete own shouts')) {
if (_shoutbox_is_user_owned($shout)) {
if ($shout->uid) {
if ($timeout = variable_get('shoutbox_registered_timeout', 0)) {
if ($shout->created < REQUEST_TIME - 60 * $timeout) {
$user_timeout = TRUE;
}
}
}
else {
if ($timeout = variable_get('shoutbox_anonymous_timeout', 20)) {
if ($shout->created < REQUEST_TIME - 60 * $timeout) {
$user_timeout = TRUE;
}
}
}
$user_owned = TRUE;
}
$access_granted = $user_owned && !$user_timeout;
}
drupal_alter('shoutbox_user_access', $access_granted, $permission, $shout);
return $access_granted;
}
function _shoutbox_sanitize_shout(&$shout) {
$shout->nick = check_plain($shout->nick);
if (variable_get('shoutbox_escape_html', 1)) {
$shout->shout = check_plain($shout->shout);
}
else {
$shout->shout = check_markup(htmlspecialchars_decode($shout->shout), variable_get('shoutbox_filter_format', 'full_html'));
}
}
function _shoutbox_filter_form() {
global $user;
$formats = filter_formats($user);
if (count($formats) > 1) {
$form['#title'] = t('Shoutbox input format');
}
return $form;
}
function _shoutbox_is_user_owned($shout) {
global $user;
$user_owned = FALSE;
if ($shout->uid > 0 && $shout->uid == $user->uid) {
$user_owned = TRUE;
}
elseif ($shout->uid == 0 && $user->uid == 0) {
if ($shout->sid == session_id()) {
$user_owned = TRUE;
}
elseif (empty($shout->sid) && !empty($shout->hostname)) {
$user_owned = $shout->hostname == ip_address();
}
}
return $user_owned;
}
function shoutbox_moderate_shout($shout_id, $moderate) {
if (is_numeric($shout_id)) {
$shout = shoutbox_shout_load($shout_id);
$shout->moderate = $moderate ? 1 : 0;
shoutbox_invoke($moderate ? 'unpublish' : 'publish', $shout);
db_update('shoutbox')
->fields(array(
'moderate' => $shout->moderate,
))
->condition('shout_id', $shout->shout_id)
->execute();
if (!$moderate) {
drupal_set_message(t('The ' . DEFAULTSHOUTSINGULAR . ' was published.'));
}
else {
drupal_set_message(t('The ' . DEFAULTSHOUTSINGULAR . ' was unpublished.'));
}
}
}
function shoutbox_invoke($op, &$shout, &$a1 = NULL, $form_state = NULL) {
$hook = 'shoutbox';
foreach (module_implements($hook) as $module) {
$function = $module . '_' . $hook;
$function($op, $shout, $a1, $form_state);
}
}
function shoutbox_views_api() {
return array(
'api' => '3.0',
'path' => drupal_get_path('module', 'shoutbox') . '/views',
);
}
function shoutbox_entity_info() {
return array(
'shout' => array(
'label' => t(DEFAULTSHOUTSINGULAR_CC),
'base table' => 'shoutbox',
'entity keys' => array(
'id' => 'shout_id',
),
),
);
}
function shoutbox_action_info() {
return array(
'shoutbox_shout_delete_action' => array(
'type' => 'shout',
'description' => t('Delete ' . DEFAULTSHOUTPLURAL_CC),
'label' => t('Delete Shoutbox ' . DEFAULTSHOUTSINGULAR),
'configurable' => FALSE,
'hooks' => array(
'shout' => array(
'delete',
),
),
),
);
}
function shoutbox_shout_delete_action(&$object) {
db_delete('shoutbox')
->condition('shout_id', $object->shout_id)
->execute();
}