rate.admin.inc in Rate 6.2
Same filename and directory in other branches
Rating admin
File
rate.admin.incView source
<?php
/**
* @file
* Rating admin
*/
/**
* Menu callback.
*
* Generates the admin page which contains the widget listing.
*/
function rate_admin_page() {
$widgets = variable_get(RATE_VAR_WIDGETS, array());
uasort($widgets, '_rate_sort');
$header = array(
t('Title'),
t('Name'),
t('Operations'),
);
$rows = array();
foreach ($widgets as $id => $widget) {
$edit = l(t('Edit'), str_replace('%', $id, RATE_PATH_ADMIN_PAGE_EDIT));
$delete = l(t('Delete'), str_replace('%', $id, RATE_PATH_ADMIN_PAGE_DELETE));
$rows[] = array(
$widget->title,
$widget->name,
"{$edit} {$delete}",
);
}
$output = '';
$output .= '<h3>' . t('Add widget') . '</h3>';
$output .= drupal_get_form('rate_choose_template_form');
if ($rows) {
$output .= theme('table', $header, $rows);
}
else {
$text = t('You do not have any rate widgets defined yet.');
$output .= '<p>' . check_plain($text) . '</p>';
}
return $output;
}
/**
* Callback for uasort().
*
* @see rate_admin_page()
* @see http://php.net/uasort
*/
function _rate_sort($a, $b) {
if ($a->title == $b->title) {
return 0;
}
return $a->title < $b->title ? -1 : 1;
}
/**
* Form for choosing a template before the user goes to the add widget form.
*/
function rate_choose_template_form(&$form_state, $id = NULL) {
$form = array();
if ($id) {
$form['#widget_id'] = $id;
$widgets = variable_get(RATE_VAR_WIDGETS, array());
$widget = $widgets[$id];
isset($widget->template) or $widget->template = 'custom';
$selected = $widget->template;
}
else {
$selected = 'custom';
}
$options = array(
'custom' => t('Custom'),
);
foreach (module_implements('rate_templates') as $module) {
foreach (module_invoke($module, 'rate_templates') as $name => $widget) {
$options[$name] = $widget->template_title;
}
}
$form['template'] = array(
'#type' => 'select',
'#title' => t('Widget type'),
'#options' => $options,
'#default_value' => $selected,
);
$form['submit'] = array(
'#type' => 'submit',
'#value' => t('Next'),
);
return $form;
}
/**
* Form submit callback for the choose_template_form.
*/
function rate_choose_template_form_submit($form, &$form_state) {
$template = $form_state['values']['template'];
$query = 'template=' . urlencode($template);
if (isset($form['#widget_id'])) {
/**
* @todo: Copy over the options array from the template to the widget.
*/
$path = str_replace('%', $form['#widget_id'], RATE_PATH_ADMIN_PAGE_EDIT);
}
else {
$path = RATE_PATH_ADMIN_PAGE_ADD;
}
drupal_goto($path, $query);
}
/**
* Form for adding and editing widgets.
*/
function rate_widget_form(&$form_state, $id = NULL) {
$form = array();
// Workaround core issue #591696 in AHAH forms.
// See http://drupal.org/node/591696#comment-3369036 for details.
if ($id) {
$form['#action'] = url(str_replace('%', $id, RATE_PATH_ADMIN_PAGE_EDIT));
}
else {
$form['#action'] = url(RATE_PATH_ADMIN_PAGE_ADD);
}
if ($id) {
$widgets = variable_get(RATE_VAR_WIDGETS, array());
if (!isset($widgets[$id])) {
drupal_not_found();
module_invoke_all('exit') & exit;
}
$widget = $widgets[$id];
}
else {
$widget = new stdClass();
$widget->name = '';
$widget->tag = 'vote';
$widget->title = '';
$widget->node_types = array();
$widget->comment_types = array();
$widget->value_type = 'percent';
$widget->options = array();
$widget->template = 'custom';
$widget->node_display = RATE_DISPLAY_BELOW_CONTENT;
$widget->teaser_display = FALSE;
$widget->node_display_mode = RATE_FULL;
$widget->teaser_display_mode = RATE_FULL;
$widget->comment_display_mode = RATE_FULL;
$widget->comment_display = RATE_DISPLAY_BELOW_CONTENT;
$widget->roles = array();
$widget->allow_voting_by_author = TRUE;
$widget->noperm_behaviour = RATE_NOPERM_REDIRECT_WITH_MESSAGE;
$widget->displayed = RATE_AVERAGE;
$widget->displayed_just_voted = RATE_USER;
}
// Determine the template from GET (which is only available before the form
// was post) or from post values (only available after the form was posted).
if (isset($form_state['post']['widget_template'])) {
$widget->template = $form_state['post']['widget_template'];
}
elseif (isset($_GET['template'])) {
// The template can be overridden (also used for changing templates).
$widget->template = $_GET['template'];
}
// Check widget for missing values (legacy).
_rate_check_widget($widget);
if ($widget->template != 'custom') {
if (!($template = _rate_get_template($widget->template))) {
$form['error'] = array(
'#value' => t('You cannot edit this widget because it was built using the template %template which does not exists anymore.', array(
'%template' => $widget->template,
)),
);
return $form;
}
$widget->customizable = isset($template->customizable) ? $template->customizable : TRUE;
if ($widget->customizable && !$id) {
$widget->options = $template->options;
$widget->value_type = $template->value_type;
}
}
if ($id) {
$form['#widget_id'] = $id;
}
// The GET value for the template is not available anymore after posting,
// so we need to add the template as a hidden value.
$form['widget_template'] = array(
'#type' => 'hidden',
'#value' => $widget->template,
);
$form['#widget_customizable'] = $widget->customizable;
if ($id) {
$link = l(t('change the widget type'), str_replace('%', $id, RATE_PATH_ADMIN_PAGE_TEMPLATE));
if ($widget->template == 'custom') {
$text = t('This is a custom widget. You may !change.', array(
'!change' => $link,
));
}
else {
$template = _rate_get_template($widget->template);
$text = t('This is a %type widget. You may !change.', array(
'%type' => $template->template_title,
'!change' => $link,
));
}
$text = filter_xss($text);
$form['template'] = array(
'#type' => 'fieldset',
'#title' => t('Widget type'),
);
$form['template']['switch'] = array(
'#value' => $text,
);
}
$form['title'] = array(
'#type' => 'textfield',
'#title' => t('Title'),
'#default_value' => $widget->title,
'#required' => TRUE,
);
/**
* @todo Implement http://drupal.org/node/302054#comment-1110505
*/
$form['name'] = array(
'#type' => 'textfield',
'#title' => t('Machine readable name'),
'#default_value' => $widget->name,
'#required' => TRUE,
);
$form['tag'] = array(
'#type' => 'textfield',
'#title' => t('Tag'),
'#default_value' => $widget->tag,
'#description' => t('Tag used for VotingAPI. Widgets with the same tag share their voting results.'),
'#required' => TRUE,
);
if ($widget->customizable) {
$options = array(
'percent' => t('Percentage'),
'points' => t('Points'),
'option' => t('Options'),
);
$form['value_type'] = array(
'#type' => 'radios',
'#title' => t('Value type'),
'#options' => $options,
'#default_value' => $widget->value_type,
'#required' => TRUE,
);
$form['options'] = array(
'#type' => 'fieldset',
'#title' => t('Options'),
'#description' => t('Define the available voting buttons.'),
'#collapsible' => TRUE,
'#collapsed' => FALSE,
);
$form['options']['options'] = array(
'#theme' => 'rate_admin_options',
'#prefix' => "<div id=\"rate-options\">",
'#suffix' => '</div>',
);
if ($form_state['submitted']) {
$option_count = (int) $form_state['values']['option_count'];
if ($form_state['clicked_button']['#id'] == 'edit-add-another') {
++$option_count;
}
}
else {
$option_count = max(2, count($widget->options));
}
$id = 0;
$c = $option_count;
for ($i = 0; $i < $c; $i++) {
if ($form_state['submitted'] && !empty($form_state['values']['delete' . $i])) {
--$option_count;
continue;
}
$form['options']['options']['option' . $id] = array();
if (isset($form_state['values']['value' . $i])) {
$default_value = $form_state['values']['value' . $i];
$default_label = $form_state['values']['label' . $i];
}
elseif (isset($widget->options[$i]) && !$form_state['submitted']) {
$default_value = $widget->options[$i][0];
$default_label = $widget->options[$i][1];
}
else {
$default_value = '';
$default_label = '';
}
$form['options']['options']['option' . $id]['value' . $id] = array(
'#type' => 'textfield',
'#title' => t('Value'),
'#default_value' => $default_value,
'#size' => 16,
);
$form['options']['options']['option' . $id]['label' . $id] = array(
'#type' => 'textfield',
'#title' => t('Label'),
'#default_value' => $default_label,
'#size' => 40,
);
$form['options']['options']['option' . $id]['delete' . $id] = array(
'#type' => 'checkbox',
'#title' => t('Delete'),
'#default_value' => FALSE,
);
++$id;
}
$form['options']['option_count'] = array(
'#type' => 'hidden',
'#value' => $option_count,
);
$form['options']['add_another'] = array(
'#type' => 'submit',
'#value' => t('Add another option'),
'#ahah' => array(
'path' => RATE_PATH_ADMIN_AHAH,
'wrapper' => 'rate-options',
'method' => 'replace',
'effect' => 'none',
),
);
$form['translate'] = array(
'#type' => 'checkbox',
'#title' => t('Translate options'),
'#default_value' => $widget->translate,
);
}
$form['types'] = array(
'#type' => 'fieldset',
'#title' => t('Node types'),
'#description' => t('Select the node types on which to enable this widget.'),
'#collapsible' => TRUE,
'#collapsed' => FALSE,
'#theme' => 'rate_admin_types',
);
$sql = 'SELECT type, name FROM {node_type} ORDER BY name ASC';
$res = db_query($sql);
while ($rec = db_fetch_array($res)) {
$form['types'][$rec['type']] = array(
'#type' => 'fieldset',
'#title' => $rec['name'],
);
$form['types'][$rec['type']]['node_type_' . $rec['type']] = array(
'#type' => 'checkbox',
'#title' => $rec['name'],
'#default_value' => in_array($rec['type'], $widget->node_types),
);
$form['types'][$rec['type']]['comment_type_' . $rec['type']] = array(
'#type' => 'checkbox',
'#title' => $rec['name'],
'#default_value' => in_array($rec['type'], $widget->comment_types),
);
}
$form['display'] = array(
'#type' => 'fieldset',
'#title' => t('Display settings'),
'#collapsible' => TRUE,
'#collapsed' => TRUE,
);
$display_options = array(
RATE_DISPLAY_DISABLE => t('Do not add automatically'),
RATE_DISPLAY_ABOVE_CONTENT => t('Above the content'),
RATE_DISPLAY_BELOW_CONTENT => t('Below the content'),
RATE_DISPLAY_LINKS => t('Within the Links'),
);
$form['display']['node_display'] = array(
'#type' => 'radios',
'#title' => t('Node display'),
'#options' => $display_options,
'#default_value' => $widget->node_display,
);
$form['display']['teaser_display'] = array(
'#type' => 'checkbox',
'#title' => t('Display in teaser'),
'#default_value' => $widget->teaser_display,
);
$display_mode_options = array(
RATE_FULL => t('Full widget'),
RATE_DISABLED => t('Display only'),
RATE_COMPACT_DISABLED => t('Display only, compact'),
RATE_COMPACT => t('Compact'),
);
$form['display']['node_display_mode'] = array(
'#type' => 'select',
'#title' => t('Appearance in full node'),
'#options' => $display_mode_options,
'#default_value' => $widget->node_display_mode,
);
$form['display']['teaser_display_mode'] = array(
'#type' => 'select',
'#title' => t('Appearance in teaser'),
'#options' => $display_mode_options,
'#default_value' => $widget->teaser_display_mode,
);
$form['display']['comment_display'] = array(
'#type' => 'radios',
'#title' => t('Comment display'),
'#options' => $display_options,
'#default_value' => $widget->comment_display,
);
$form['display']['comment_display_mode'] = array(
'#type' => 'select',
'#title' => t('Appearance in comments'),
'#options' => $display_mode_options,
'#default_value' => $widget->comment_display_mode,
);
$form['interaction'] = array(
'#type' => 'fieldset',
'#title' => t('Interaction'),
'#collapsible' => TRUE,
'#collapsed' => TRUE,
'#description' => t('Note that these settings do not apply for rate widgets inside views. Widgets in views will display the average voting when a relationship to the voting results is used and the users vote in case of a relationship to the votes.'),
);
$options = array(
RATE_AVERAGE => t('Average rating'),
RATE_USER => t('Users vote if available, empty otherwise'),
RATE_USER_OR_AVERAGE => t('Users vote if available, average otherwise'),
);
$form['interaction']['displayed'] = array(
'#type' => 'radios',
'#title' => t('Which rating should be displayed?'),
'#options' => $options,
'#default_value' => $widget->displayed,
);
$options = array(
RATE_AVERAGE => t('Average rating'),
RATE_USER => t('Users vote'),
);
$form['interaction']['displayed_just_voted'] = array(
'#type' => 'radios',
'#title' => t('Which rating should be displayed when the user just voted?'),
'#options' => $options,
'#default_value' => $widget->displayed_just_voted,
);
$form['permissions'] = array(
'#type' => 'fieldset',
'#title' => t('Permissions'),
'#collapsible' => TRUE,
'#collapsed' => TRUE,
);
$sql = 'SELECT rid, name FROM {role} ORDER BY name ASC';
$res = db_query($sql);
$options = array();
while ($rec = db_fetch_array($res)) {
$options[$rec['rid']] = $rec['name'];
}
$form['permissions']['roles'] = array(
'#type' => 'checkboxes',
'#title' => t('Roles'),
'#options' => $options,
'#default_value' => $widget->roles,
'#description' => t('Allow voting only for the selected role(s). If you select no roles, all users are allowed to vote.'),
);
$form['permissions']['allow_voting_by_author'] = array(
'#type' => 'checkbox',
'#title' => t('Allow author to rate his / her own content'),
'#default_value' => $widget->allow_voting_by_author,
'#description' => t('Will change the state to disabled. Always true for anonymous users.'),
);
$options = array(
RATE_NOPERM_REDIRECT_WITH_MESSAGE => t('Redirect to login and show message'),
RATE_NOPERM_REDIRECT_WITHOUT_MESSAGE => t('Redirect to login but do not show a message'),
RATE_NOPERM_SHOW_DISABLED_WIDGET => t('Show a disabled widget (with non clickable buttons)'),
RATE_NOPERM_HIDE_WIDGET => t('Hide widget'),
);
$form['permissions']['noperm_behaviour'] = array(
'#type' => 'radios',
'#title' => t('Behaviour when user has no permission to vote'),
'#options' => $options,
'#default_value' => $widget->noperm_behaviour,
'#description' => t('Choose an action what will happen if a user clicks on the widget but doesn\'t have the permission to vote.'),
);
$form['submit'] = array(
'#type' => 'submit',
'#value' => t('Save'),
'#weight' => 50,
);
return $form;
}
/**
* Form validate.
*/
function rate_widget_form_validate($form, &$form_state) {
// Validate machine readable name
if (!preg_match('/^[a-z\\_0-9]+$/i', $form_state['values']['name'])) {
form_set_error('name', t('The machine readable name may only contain alphanumeric characters and underscores.'));
}
// Validate vote tag
if (!preg_match('/^[a-z\\_0-9]+$/i', $form_state['values']['tag'])) {
form_set_error('tag', t('The vote tag may only contain alphanumeric characters and underscores.'));
}
if ($form['#widget_customizable']) {
// Validate option values
$used_values = array();
foreach ($form_state['values'] as $name => $value) {
if (preg_match('/^value([0-9]+)$/', $name, $match)) {
if (empty($value)) {
continue;
}
if (!preg_match('/^\\-?[0-9]+$/', $value)) {
form_set_error($name, t('Values must be integers'));
continue;
}
if (in_array($value, $used_values)) {
form_set_error($name, t('You may not use the same value twice.'));
}
$used_values[] = $value;
if ($form_state['values']['value_type'] == 'percent') {
if ($value < 0 || $value > 100) {
form_set_error($name, t('Percentages must be between 0 and 100'));
}
}
}
}
if (!count($used_values)) {
form_set_error('', t('Each widget must have at least one option.'));
}
}
}
/**
* Form submit handler.
*/
function rate_widget_form_submit($form, &$form_state) {
if ($form_state['clicked_button']['#id'] == 'edit-add-another') {
$form_state['rebuild'] = TRUE;
return $form_state['values'];
}
$widget = new stdClass();
$widget->name = $form_state['values']['name'];
$widget->tag = $form_state['values']['tag'];
$widget->title = $form_state['values']['title'];
$widget->node_types = array();
$widget->comment_types = array();
$widget->options = array();
$widget->template = $form_state['values']['widget_template'];
$widget->node_display = $form_state['values']['node_display'];
$widget->teaser_display = (bool) $form_state['values']['teaser_display'];
$widget->comment_display = $form_state['values']['comment_display'];
$widget->node_display_mode = $form_state['values']['node_display_mode'];
$widget->teaser_display_mode = $form_state['values']['teaser_display_mode'];
$widget->comment_display_mode = $form_state['values']['comment_display_mode'];
$widget->roles = $form_state['values']['roles'];
$widget->allow_voting_by_author = $form_state['values']['allow_voting_by_author'];
$widget->noperm_behaviour = $form_state['values']['noperm_behaviour'];
$widget->displayed = $form_state['values']['displayed'];
$widget->displayed_just_voted = $form_state['values']['displayed_just_voted'];
if ($widget->template != 'custom') {
// Take over the values from the template.
$template = _rate_get_template($widget->template);
if (!$template->customizable) {
$widget->options = $template->options;
}
$widget->value_type = $template->value_type;
!isset($template->theme) or $widget->theme = $template->theme;
!isset($template->css) or $widget->css = $template->css;
!isset($template->js) or $widget->js = $template->js;
$widget->translate = $template->translate;
if (isset($form_state['values']['translate'])) {
$widget->translate = (bool) $form_state['values']['translate'];
}
}
else {
$widget->value_type = $form_state['values']['value_type'];
$widget->translate = (bool) $form_state['values']['translate'];
}
foreach ($form_state['values'] as $name => $value) {
if (preg_match('/^value([0-9]+)$/', $name, $match) && preg_match('/^\\-?[0-9]+$/', $value)) {
$widget->options[] = array(
$value,
$form_state['values']['label' . $match[1]],
);
}
if (preg_match('/^node_type_(.+)$/', $name, $match) && $value) {
$widget->node_types[] = $match[1];
}
if (preg_match('/^comment_type_(.+)$/', $name, $match) && $value) {
$widget->comment_types[] = $match[1];
}
}
// Let other modules alter the rate widget.
foreach (module_implements('rate_widget') as $module) {
$hook = "{$module}_rate_widget";
$op = empty($form['#widget_id']) ? 'insert' : 'update';
$hook($op, $widget, $form_state['values']);
}
// Save the widget.
$widgets = variable_get(RATE_VAR_WIDGETS, array());
if (!empty($form['#widget_id'])) {
$id = (int) $form['#widget_id'];
}
else {
$id = 1;
while (isset($widgets[$id])) {
++$id;
}
}
$widgets[$id] = $widget;
variable_set(RATE_VAR_WIDGETS, $widgets);
drupal_set_message(t('The widget has been saved.'));
$form_state['redirect'] = RATE_PATH_ADMIN_PAGE;
}
/**
* AHAH callback for widget form.
*/
function rate_widget_form_ahah() {
$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);
$container = $form['options']['options'];
unset($container['#prefix'], $container['#suffix']);
// Prevent duplicate wrappers.
$javascript = drupal_add_js(NULL, NULL, 'header');
drupal_json(array(
'status' => TRUE,
'data' => theme('status_messages') . drupal_render($container),
'settings' => call_user_func_array('array_merge_recursive', $javascript['setting']),
));
}
/**
* Theming function for the node / comment types list in the widget form.
*
* @ingroup themeable
*/
function theme_rate_admin_types($element) {
$header = array(
t('Name'),
t('Node'),
t('Comment'),
);
$rows = array();
foreach ($element as $name => $subelement) {
if ($name[0] != '#') {
unset($subelement['node_type_' . $name]['#title']);
unset($subelement['comment_type_' . $name]['#title']);
$rows[] = array(
check_plain($subelement['#title']),
drupal_render($subelement['node_type_' . $name]),
drupal_render($subelement['comment_type_' . $name]),
);
}
}
return theme('table', $header, $rows);
}
/**
* Theme the options list in the widget form.
*
* @ingroup themeable
*/
function theme_rate_admin_options($element) {
$header = array(
t('Value'),
t('Label'),
t('Delete'),
);
$rows = array();
foreach ($element as $name => $subelement) {
if (preg_match('/^option([0-9]+)$/', $name, $match)) {
$id = $match[1];
unset($subelement['value' . $id]['#title']);
unset($subelement['label' . $id]['#title']);
unset($subelement['delete' . $id]['#title']);
$rows[] = array(
drupal_render($subelement['value' . $id]),
drupal_render($subelement['label' . $id]),
drupal_render($subelement['delete' . $id]),
);
}
}
return theme('table', $header, $rows);
}
/**
* Form for deleting widgets.
*/
function rate_widget_delete_form(&$form_state, $id) {
$form = array();
$widgets = variable_get(RATE_VAR_WIDGETS, array());
$form['#widget_id'] = $id;
if (!($title = $widgets[$id]->title)) {
drupal_not_found();
module_invoke_all('exit') & exit;
}
$form['info'] = array(
'#value' => '<p>' . t('Are you sure you want to delete widget %title?', array(
'%title' => $title,
)) . '</p>',
);
$form['buttons']['submit'] = array(
'#type' => 'submit',
'#value' => t('Delete'),
);
$form['buttons']['cancel'] = array(
'#value' => l('Cancel', RATE_PATH_ADMIN_PAGE),
);
return $form;
}
/**
* Submit handler.
*/
function rate_widget_delete_form_submit($form, &$form_state) {
$widgets = variable_get(RATE_VAR_WIDGETS, array());
if ($title = $widgets[$form['#widget_id']]->title) {
unset($widgets[$form['#widget_id']]);
variable_set(RATE_VAR_WIDGETS, $widgets);
drupal_set_message(t('Widget %title has been deleted.', array(
'%title' => $title,
)));
// Let other modules act on this action.
foreach (module_implements('rate_widget') as $module) {
$hook = "{$module}_rate_widget";
$hook('delete', $widgets[$form['#widget_id']], $form_state['values']);
}
}
$form_state['redirect'] = RATE_PATH_ADMIN_PAGE;
}
Functions
Name | Description |
---|---|
rate_admin_page | Menu callback. |
rate_choose_template_form | Form for choosing a template before the user goes to the add widget form. |
rate_choose_template_form_submit | Form submit callback for the choose_template_form. |
rate_widget_delete_form | Form for deleting widgets. |
rate_widget_delete_form_submit | Submit handler. |
rate_widget_form | Form for adding and editing widgets. |
rate_widget_form_ahah | AHAH callback for widget form. |
rate_widget_form_submit | Form submit handler. |
rate_widget_form_validate | Form validate. |
theme_rate_admin_options | Theme the options list in the widget form. |
theme_rate_admin_types | Theming function for the node / comment types list in the widget form. |
_rate_sort | Callback for uasort(). |