FALSE, '#type' => 'fieldset', '#title' => t('Widget display'), '#description' => t('Choose a widget set to be used on your site. Widgets supporting custom colors can be further customized by adjusting the color scheme.'), '#weight' => -2, ); $widgets = module_invoke_all('fivestar_widgets'); $classic_widgets = array(); $color_widgets = array(); foreach ($widgets as $path => $name) { $directory = dirname($path); $matches = file_scan_directory($directory, '-template.'); if (empty($matches)) { $classic_widgets[$path] = $name; } else { $color_widgets[$path] = $name; } } // If using a color widget, set the default value to the original path. $default_value = variable_get('fivestar_widget', 'default'); foreach ($color_widgets as $path => $name) { if (basename($path) == basename($default_value)) { $default_value = $path; } } $form['widget']['fivestar_widget'] = array( '#type' => 'radios', '#options' => array('default' => t('Default')) + $classic_widgets + $color_widgets, '#default_value' => $default_value, '#attributes' => array('class' => 'fivestar-widgets'), ); $form['widget']['fivestar_color_widget'] = array( '#type' => 'radios', '#title' => t('Custom color widgets'), '#options' => $color_widgets, '#attributes' => array('class' => 'fivestar-widgets'), ); $form['tags'] = array( '#tree' => FALSE, '#type' => 'fieldset', '#title' => t('Voting tags'), '#description' => t('Choose the voting tags that will be available for node rating. A tag is simply a category of vote. If you only need to rate one thing per node, leave this as the default "vote".'), '#weight' => 3, ); $form['tags']['tags'] = array( '#type' => 'textfield', '#title' => t('Tags'), '#default_value' => variable_get('fivestar_tags', 'vote'), '#required' => TRUE, '#description' => t('Separate multiple tags with commas.'), ); $form['color'] = fivestar_color_form(); $form['#validate'][] = 'fivestar_color_form_validate'; $form['#submit'][] = 'fivestar_color_form_submit'; $form['#submit'][] ='fivestar_settings_submit'; $form['submit'] = array( '#type' => 'submit', '#value' => t('Save configuration'), '#weight' => 45, ); return $form; } function fivestar_settings_submit($form, &$form_state) { // TODO We could delete all variables for removed tags variable_set('fivestar_tags', $form_state['values']['tags']); variable_set('fivestar_widget', $form_state['values']['fivestar_widget']); // Rebuild the menu in case tags were changed menu_rebuild(); } function theme_fivestar_settings($form) { drupal_add_css(drupal_get_path('module', 'fivestar') .'/css/fivestar-admin.css', 'module', 'all', FALSE); drupal_set_title(t('Fivestar Settings')); // Default preview. $form['widget']['fivestar_widget']['default']['#description'] = 'Default '. t('Preview') .':
'. theme('fivestar_preview_widget', 'default'); // Preview for each classic widget. foreach (element_children($form['widget']['fivestar_widget']) as $widget_key) { if ($widget_key != 'default') { $form['widget']['fivestar_widget'][$widget_key]['#description'] = $form['widget']['fivestar_widget'][$widget_key]['#title'] .' '. t('Preview') .':
'. theme('fivestar_preview_widget', $widget_key); } } // Preview for each color-enabled widget. foreach (element_children($form['widget']['fivestar_color_widget']) as $widget_key) { $form['widget']['fivestar_color_widget'][$widget_key] = $form['widget']['fivestar_widget'][$widget_key]; $form['widget']['fivestar_color_widget'][$widget_key]['#description'] = $form['widget']['fivestar_color_widget'][$widget_key]['#title'] .' '. t('Preview') .':
'. theme('fivestar_preview_widget', $widget_key); unset($form['widget']['fivestar_widget'][$widget_key]); } // Add the new styles to the page. drupal_set_html_head(""); $form['widget']['fivestar_widget']['#attributes']['class'] .= ' clear-block'; $form['widget']['fivestar_color_widget']['#attributes']['class'] .= ' fivestar-color-widgets clear-block'; return drupal_render($form); } /** * Show a preview of a widget using a custom CSS file. */ function theme_fivestar_preview_widget($css_file) { static $default_css_added = FALSE; // Add the default CSS to the page to ensure the defaults take precedence. if (!$default_css_added) { $css = file_get_contents(drupal_get_path('module', 'fivestar') .'/css/fivestar.css'); // Prepend the classes with the unique widget div. $css = preg_replace('/((div)?\.fivestar-widget)/', 'div.fivestar-widgets $1', $css); // Update relative URLs with absolute locations. $css = preg_replace('/url\(\.\.\/(.*?)\)/', 'url('. base_path() . drupal_get_path('module', 'fivestar') .'/$1)', $css); fivestar_add_inline_css('default', $css); $default_css_added = TRUE; } // Add widget specific CSS to the page. $widget_name = str_replace('.css', '', basename($css_file)); $widget_path = dirname($css_file); if ($widget_name != 'default') { $css = file_get_contents($css_file); // Prepend the classes with the unique widget div. $css = preg_replace('/((div)?\.fivestar-widget)/', 'div#fivestar-preview-'. $widget_name .' $1', $css); // Update relative URLs with absolute locations. $css = preg_replace('/url\((.*?)\)/', 'url('. base_path() . $widget_path .'/$1)', $css); fivestar_add_inline_css($widget_name, $css); } $form = array( '#post' => array(), '#programmed' => FALSE, '#tree' => FALSE, ); $form_state = array(); $form['vote'] = array( '#type' => 'fivestar', '#stars' => 5, '#auto_submit' => FALSE, '#allow_clear' => TRUE, ); $form = form_builder('fivestar_preview', $form, $form_state); $output = '
'; $output .= drupal_render($form); $output .= '
'; return $output; } /** * Adds fivestar enaable and position to the node-type configuration form. */ function fivestar_node_type_tag_form(&$form_state, $type_name, $tag = 'vote') { $form = array(); $settings = fivestar_get_settings($type_name, $tag); $form_state['fivestar_tag'] = $tag; $form_state['fivestar_node_type'] = $type_name; $form['fivestar'] = array( '#type' => 'checkbox', '#title' => t('Enable Fivestar rating for the "@tag" tag', array('@tag' => $tag)), '#default_value' => $settings['fivestar'], '#weight' => -5, '#return_value' => 1, ); $form['fivestar_stars'] = array( '#type' => 'select', '#title' => t('Number of stars'), '#options' => drupal_map_assoc(range(1, 10)), '#default_value' => $settings['stars'], '#weight' => -4, ); $form['labels'] = array( '#type' => 'fieldset', '#title' => t('Star Labels'), '#collapsible' => TRUE, '#collapsed' => TRUE, '#description' => t('These star labels appear as the link title when javascript is enabled as well as the select list options when javascript is disabled.'), ); $form['labels']['fivestar_labels_enable'] = array( '#type' => 'checkbox', '#title' => t('Display labels on mouse over'), '#default_value' => $settings['labels_enable'], '#return_value' => 1, '#weight' => -5, '#description' => t('When enabled, the star labels will dynamically appear underneath the stars as the user hovers over each star to provide a more descriptive qualitative meaning for each star value.'), ); // Create the Mouseover text forms for each of the rating options // This form depends on the number of stars, and these extra textfields will be hidden with javascript for ($n = 0; $n <= 10; $n++) { $form['labels']['fivestar_label_'. $n] = array( '#type' => 'textfield', '#title' => $n > 0 ? t('Star @star label', array('@star' => $n)) : t('Cancel label'), '#default_value' => $settings['labels'][$n], '#prefix' => '
', '#suffix' => '
', '#size' => 30, ); } $form['direct'] = array( '#type' => 'fieldset', '#title' => t('Direct rating widget'), '#collapsible' => FALSE, '#description' => t('These settings allow you to display a rating widget to your users while they are viewing content of this type. Rating will immediately register a vote for that piece of content.'), '#weight' => 2, ); $form['direct']['fivestar_style'] = array( '#type' => 'select', '#title' => t('Star display style'), '#default_value' => $settings['star_display'], '#options' => array( 'average' => t('Display average vote value'), 'user' => t('Display user vote value'), 'smart' => t('User vote if available, average otherwise'), 'dual' => t('Both user and average vote'), ), ); $form['direct']['fivestar_text'] = array( '#type' => 'select', '#title' => t('Text display style'), '#default_value' => $settings['text_display'], '#options' => array( 'none' => t('Display no text beneath stars'), 'average' => t('Current average in text'), 'user' => t('User current vote in text'), 'smart' => t('User vote if available, average otherwise'), 'dual' => t('Both user and average vote'), ), ); $form['direct']['fivestar_title'] = array( '#type' => 'checkbox', '#title' => t('Show widget title'), '#default_value' => $settings['title_display'], '#return_value' => 1, ); $form['direct']['fivestar_feedback'] = array( '#type' => 'checkbox', '#title' => t('Enable feedback during vote saving and deletion'), '#default_value' => $settings['feedback_enable'], '#return_value' => 1 ); $form['direct']['fivestar_unvote'] = array( '#type' => 'checkbox', '#title' => t('Allow users to undo their votes'), '#default_value' => $settings['unvote_enable'], '#return_value' => 1, ); $form['direct']['fivestar_position_teaser'] = array( '#type' => 'select', '#title' => t('Teaser display'), '#default_value' => $settings['position_teaser'], '#options' => array( 'above' => t('Clickable widget above teaser'), 'below' => t('Clickable widget below teaser'), 'above_static' => t('Static display above teaser'), 'below_static' => t('Static display below teaser'), 'link' => t('Teaser link to full node widget'), 'hidden' => '<'. t('hidden') .'>', ), ); $form['direct']['fivestar_position'] = array( '#type' => 'select', '#title' => t('Full node display'), '#default_value' => $settings['position'], '#options' => array( 'above' => t('Clickable widget above node body'), 'below' => t('Clickable widget below node body'), 'above_static' => t('Static display above node body'), 'below_static' => t('Static display below node body'), 'hidden' => '<'. t('hidden') .'>', ), ); $form['direct']['fivestar_direct_preview'] = array( '#type' => 'item', '#title' => t('Direct rating widget preview'), '#value' => theme( 'fivestar_preview', $form['direct']['fivestar_style']['#default_value'], $form['direct']['fivestar_text']['#default_value'], $form['fivestar_stars']['#default_value'], $form['direct']['fivestar_unvote']['#default_value'], $form['direct']['fivestar_title']['#default_value'] ? NULL : FALSE, $form['labels']['fivestar_labels_enable']['#default_value'], $settings['labels'] ), ); if (!$form['fivestar']['#default_value']) { $form['direct']['fivestar_direct_preview']['#value'] = theme('fivestar_preview_wrapper', ''); } else { $form['direct']['fivestar_direct_preview']['#value'] = theme('fivestar_preview_wrapper', $form['direct']['fivestar_direct_preview']['#value']); } $form['submit'] = array( '#type' => 'submit', '#value' => t('Save'), ); return $form; } /** * Additional submit handler for the node type form. */ function fivestar_node_type_tag_form_submit($form, &$form_state) { $tag = $form_state['fivestar_tag']; $type_name = $form_state['fivestar_node_type']; $suffix = fivestar_get_suffix($type_name, $tag); // Do not save any fivestar variables if fivestar is disabled. if (isset($form_state['values']['fivestar']) && $form_state['values']['fivestar'] === 0) { foreach ($form_state['values'] as $key => $value) { if (strpos($key, 'fivestar') === 0) { variable_del($key . '_' . $suffix); } } } else { if ($form_state['values']['fivestar_labels_enable']) { // Merge labels into a single variable. $labels = array(); for ($n = 0; $n <= 10; $n++) { $labels[] = $form_state['values']['fivestar_label_' . $n]; unset($form_state['values']['fivestar_label_' . $n]); } variable_set('fivestar_labels_' . $suffix, $labels); } else { variable_del('fivestar_labels_' . $suffix); } // Now save the remaining variables foreach ($form_state['values'] as $key => $value) { if (strpos($key, 'fivestar') === 0) { variable_set($key . '_' . $suffix, $value); } } } drupal_set_message('Your changes have been saved.'); } /** * Theme function to add the Fivestar preview to the node type form. */ function theme_fivestar_node_type_tag_form($form) { drupal_add_js(drupal_get_path('module', 'fivestar') .'/js/fivestar-admin.js'); drupal_add_js(array('fivestar' => array('preview_url' => url('fivestar/preview/node'))), 'setting'); drupal_add_css(drupal_get_path('module', 'fivestar') .'/css/fivestar-admin.css', 'module', 'all', FALSE); $output = ''; $output .= drupal_render($form['fivestar']); $output .= '
'; $output .= drupal_render($form['fivestar_stars']); // Star labels. $output .= drupal_render($form['labels']); // Direct rating settings form. $direct = ''; $direct .= '
'; $direct .= drupal_render($form['direct']['fivestar_style']); $direct .= drupal_render($form['direct']['fivestar_text']); $direct .= drupal_render($form['direct']['fivestar_title']); $direct .= drupal_render($form['direct']['fivestar_unvote']); $direct .= drupal_render($form['direct']['fivestar_feedback']); $direct .= drupal_render($form['direct']['fivestar_position_teaser']); $direct .= drupal_render($form['direct']['fivestar_position']); $direct .= '
'; $direct .= '
'; $direct .= drupal_render($form['direct']['fivestar_direct_preview']); $direct .= '
'; $form['direct']['#children'] = $direct; $output .= drupal_render($form['direct']); // Comment settings form. if (module_exists('fivestar_comment')) { $comment = ''; $comment .= '
'; $comment .= drupal_render($form['comment']['fivestar_comment']); $comment .= '
'; $comment .= '
'; $comment .= drupal_render($form['comment']['fivestar_comment_preview']); $comment .= '
'; $form['comment']['#children'] = $comment; $output .= drupal_render($form['comment']); } $output .= '
'; $output .= drupal_render($form['submit']); // Any remaining cruft (should be empty). $output .= drupal_render($form); return $output; } /** * Menu callback function for fivestar/preview/node. * * Outputs a JSON page containing a Fivestar preview of a node rating widget. */ function fivestar_preview() { // Perform a few basic security checks. $style = check_plain($_POST['style']); $text = check_plain($_POST['text']); $stars = (int)$_POST['stars']; $unvote = (boolean)$_POST['unvote']; $title = (boolean)$_POST['title']; $feedback_enable = (boolean)$_POST['feedback']; $labels_enable = (boolean)$_POST['labels_enable']; $labels = (array)$_POST['labels']; foreach ($labels as $key => $label) { $labels[$key] = filter_xss_admin($label); } $output = theme('fivestar_preview', $style, $text, $stars, $unvote, $title ? NULL : FALSE, $feedback_enable, $labels_enable, $labels); drupal_set_header('Content-Type: text/javascript; charset=utf-8'); print drupal_to_js(array('status' => TRUE, 'data' => $output)); } function theme_fivestar_preview($style = NULL, $text = NULL, $stars = NULL, $unvote = NULL, $title = NULL, $feedback_enable = TRUE, $labels_enable = TRUE, $labels = array()) { $values = array( 'average' => 50, 'user' => 80, 'count' => 20, ); $settings = array( 'stars' => $stars, 'allow_clear' => $unvote, 'style' => $style, 'text' => $text, 'title' => $title, 'autosubmit' => FALSE, 'feedback_enable' => $feedback_enable, 'labels_enable' => $labels_enable, 'labels' => $labels, 'tag' => 'vote', ); $form = drupal_get_form('fivestar_custom_widget', $values, $settings); // This regex is sadly necessary because having duplicate form_tokens or // form_id elements can cause the content type form to choke. Forms inside of // forms is also frowned upon, so this removes the wrapping form tag as well. $form = str_replace(array(''), array(''), $form); $form = preg_replace('/( method=".*?")|( action=".*?")|()/', '', $form); return $form; } function theme_fivestar_preview_wrapper($content, $type = 'direct') { return '
'. $content .'
'; }