diff --git a/sharethis.module b/sharethis.module index b11b052..fbacdb3 100644 --- a/sharethis.module +++ b/sharethis.module @@ -9,9 +9,9 @@ * * Displays help and module information. * - * @param path + * @param path * Which path of the site we're using to display help - * @param arg + * @param arg * Array that holds the current path as returned from arg() function */ function sharethis_help($path, $arg) { @@ -38,7 +38,7 @@ function sharethis_help($path, $arg) { function sharethis_permission() { return array( 'administer sharethis' => array( - 'title' => t('Administer ShareThis'), + 'title' => t('Administer ShareThis'), 'description' => t('Change the settings for how ShareThis behaves on the site.'), ), ); @@ -59,7 +59,7 @@ function sharethis_configuration_form($form, &$form_state) { drupal_add_css($my_path . '/stlib_picker.css'); $current_options_array = sharethis_get_options_array(); global $base_url; - + // Create the variables related to widget choice. $widget_type = $current_options_array['widget']; $widget_markup = ""; @@ -77,21 +77,10 @@ function sharethis_configuration_form($form, &$form_state) { $service_string_markup .= "\"" . $key . "\","; } $service_string_markup = substr($service_string_markup, 0, -1); - - // Create an array of node types. - $node_type_array = node_type_get_types(); - $node_type_options = array(); - foreach ($node_type_array as $k => $v) { - $node_type_options[$k] = $v->name; - } - // Figure out which nodeTypes are currently selected - $nodes_string = $current_options_array['nodeType']; - $nodes_selected = explode(",", $nodes_string); + // Create the variables for publisher keys. $publisher = $current_options_array['publisherID']; - // Create the variables for teasers. - $teaser = $current_options_array['viewMode'] == "1" ? TRUE : FALSE; - + $form = array(); $form['options'] = array( '#type' => 'fieldset', @@ -153,27 +142,7 @@ function sharethis_configuration_form($form, &$form_state) { '#group' => 'additional_settings', '#description' => t('Configure where the ShareThis widget should appear.'), ); - $form['context']['sharethis_node_option'] = array( - '#title' => t("Node types"), - '#description' => t('Select which nodes the ShareThis widget should appear on.'), - '#required' => TRUE, - '#type' => 'checkboxes', - '#options' => $node_type_options, - '#default_value' => $nodes_selected - ); - $form['context']['sharethis_teaser_option'] = array( - '#title' => t('Only full view'), - '#type' => 'checkbox', - '#default_value' => $teaser ? 1 : 0, - '#description' => t('When checked, will not show the widget on node teasers.'), - ); - $form['context']['sharethis_comments'] = array( - '#title' => t('Comments'), - '#type' => 'checkbox', - '#default_value' => variable_get('sharethis_comments', FALSE), - '#description' => t('Display ShareThis on comments.'), - '#access' => module_exists('comment'), - ); + $form['context']['sharethis_location'] = array( '#title' => t('Location'), '#type' => 'radios', @@ -185,6 +154,65 @@ function sharethis_configuration_form($form, &$form_state) { '#default_value' => variable_get('sharethis_location', 'content'), '#description' => t('Select where the ShareThis widget should appear. When selected to display as a block, you must choose which region to display the ShareThis block in from the Blocks administration.', array('@blocksadmin' => url('admin/structure/block'))), ); + + // Add an information section for each location type, each dependent on the + // currently selected location. + foreach (array('links', 'content', 'block') as $location_type) { + $form['context'][$location_type]['#type'] = 'container'; + $form['context'][$location_type]['#states']['visible'][':input[name="sharethis_location"]'] = array('value' => $location_type); + } + + // Add help text for the 'content' location. + $form['context']['content']['help'] = array( + '#markup' => t('When using the Content location, you must place the ShareThis links in the Manage Display section of each content type.', array('@url' => url('admin/structure/types'))), + '#weight' => 10, + '#prefix' => '', + '#suffix' => '', + ); + // Add help text for the 'block' location. + $form['context']['block']['#children'] = t('You must choose which region to display the ShareThis block in from the Blocks administration.', array('@blocksadmin' => url('admin/structure/block'))); + + // Add checkboxes for each view mode of each bundle. + $entity_info = entity_get_info('node'); + $modes = array(); + foreach ($entity_info['view modes'] as $mode => $mode_info) { + $modes[$mode] = $mode_info['label']; + } + // Get a list of content types and view modes + $view_modes_selected = $current_options_array['view_modes']; + foreach ($entity_info['bundles'] as $bundle => $bundle_info) { + $form['context']['links']['sharethis_' . $bundle . '_options'] = array( + '#title' => t('%label View Modes', array('%label' => $bundle_info['label'])), + '#description' => t('Select which view modes the ShareThis widget should appear on for %label nodes.', array('%label' => $bundle_info['label'])), + '#type' => 'checkboxes', + '#options' => $modes, + '#default_value' => $view_modes_selected[$bundle], + ); + } + + // Allow the user to choose which content types will have ShareThis added + // when using the 'Content' location. + $content_types = array(); + $enabled_content_types = variable_get('sharethis_node_types', array()); + foreach($entity_info['bundles'] as $bundle => $bundle_info) { + $content_types[$bundle] = t($bundle_info['label']); + } + $form['context']['content']['sharethis_node_types'] = array( + '#title' => t('Node Types'), + '#description' => t('Select which node types the ShareThis widget should appear on.'), + '#type' => 'checkboxes', + '#options' => $content_types, + '#default_value' => $enabled_content_types, + ); + $form['context']['sharethis_comments'] = array( + '#title' => t('Comments'), + '#type' => 'checkbox', + '#default_value' => variable_get('sharethis_comments', FALSE), + '#description' => t('Display ShareThis on comments.'), + '#access' => module_exists('comment'), + ); + + $form['context']['sharethis_weight'] = array( '#title' => t('Weight'), '#description' => t('The weight of the widget determines the location on the page where it will appear.'), @@ -223,27 +251,22 @@ function sharethis_configuration_form($form, &$form_state) { '#type' => 'textfield', '#default_value' => variable_get('sharethis_twitter_handle', ''), ); + $form['#submit'][] = 'sharethis_configuration_form_submit'; return system_settings_form($form); } /** - * Form submission handler for sharethis_configuration_form(). + * Form validation handler for sharethis_configuration_form(). */ function sharethis_configuration_form_validate($form, &$form_state) { //Additional filters for the service option input - + // Sanitize the publisher ID option. Since it's a text field, remove anything that resembles code $form_state['values']['sharethis_service_option'] = filter_xss($form_state['values']['sharethis_service_option'], array()); //Additional filters for the option extras input $form_state['values']['sharethis_option_extras'] = (isset($form_state['values']['sharethis_option_extras'])) ? $form_state['values']['sharethis_option_extras'] : array(); - // Implode the node options - $form_state['values']['sharethis_node_option'] = implode(',', $form_state['values']['sharethis_node_option']); - - // Set a default value for the teaser option - $form_state['values']['sharethis_teaser_option'] = (isset($form_state['values']['sharethis_teaser_option'])) ? $form_state['values']['sharethis_teaser_option'] : 0; - // Sanitize the publisher ID option. Since it's a text field, remove anything that resembles code $form_state['values']['sharethis_publisherID'] = filter_xss($form_state['values']['sharethis_publisherID'], array()); @@ -253,7 +276,7 @@ function sharethis_configuration_form_validate($form, &$form_state) { // Ensure default value for twitter handle $form_state['values']['sharethis_twitter_handle'] = (isset($form_state['values']['sharethis_twitter_handle'])) ? $form_state['values']['sharethis_twitter_handle'] : ''; } - + /** * Implements hook_menu. * @@ -270,15 +293,27 @@ function sharethis_menu() { return $items; } +/** + * Form submission handler for sharethis_configuration_form(). + */ +function sharethis_configuration_form_submit($form, &$form_state) { + // If the location is changing to/from 'content', clear the Field Info cache. + $current_location = variable_get('sharethis_location', 'content'); + $new_location = $form_state['values']['sharethis_location']; + if (($current_location == 'content' || $new_location == 'content') && $current_location != $new_location) { + field_info_cache_clear(); + } +} + /** * Implements hook_node_view. * * Inserts ShareThis widget code onto each node view. * TODO: Want to add the option somewhere to select nodes. * - * @param node + * @param node * The node that is being acted upon - * @param view_mode + * @param view_mode * The type of view (teaser, full, etc) * @param langcode * Information about the language @@ -293,7 +328,7 @@ function sharethis_node_view($node, $view_mode, $langcode) { } // First get all of the options for the sharethis widget from the database: $data_options = sharethis_get_options_array(); - + // This looks to see if the path variable has been posted by some rewrite module. // This is not super efficient, O(N), but N is often less than 20. $is_path = FALSE; @@ -319,47 +354,85 @@ function sharethis_node_view($node, $view_mode, $langcode) { // Get the full path to insert into the Share Buttons. $mPath = $base_url . $path_module; $mTitle = $node->title; - - // Only display the ShareThis buttons if this node fits all the requirements - if (strpos($data_options['nodeType'], $node->type) !== FALSE) { // Make sure this is the right type of node. - if (($data_options['viewMode'] == "1") && ($view_mode == "teaser")) { // If "don't show for teaser" is enabled, and this is a teaser, don't do anything - // Do nothing. - } - else { - // Check where we want to display the ShareThis widget. - switch (variable_get('sharethis_location', 'content')) { - case 'content': - $node->content['sharethis'] = array( - '#tag' => 'div', // Wrap it in a div. - '#type' => 'html_tag', - '#attributes' => array('class' => 'sharethis-buttons'), - '#value' => sharethis_get_button_HTML($data_options, $mPath, $mTitle), - '#weight' => intval(variable_get('sharethis_weight', 10)), - ); - break; - case 'links': - $links['sharethis'] = array( - 'html' => TRUE, - 'title' => sharethis_get_button_HTML($data_options, $mPath, $mTitle), - 'attributes' => array('class' => 'sharethis-buttons'), - ); - $node->content['links']['sharethis'] = array( - '#theme' => 'links', - '#links' => $links, - '#attributes' => array( - 'class' => array('links', 'inline'), - ), - '#tag' => 'div', // Wrap it in a div. - '#type' => 'html_tag', - '#weight' => intval(variable_get('sharethis_weight', 10)), - ); - break; + + // Check where we want to display the ShareThis widget. + switch (variable_get('sharethis_location', 'content')) { + case 'content': + $enabled_types = variable_get('sharethis_node_types', array()); + if (isset($enabled_types[$node->type]) && $enabled_types[$node->type] == $node->type) { + $node->content['sharethis'] = array( + '#tag' => 'div', // Wrap it in a div. + '#type' => 'html_tag', + '#attributes' => array('class' => 'sharethis-buttons'), + '#value' => theme('sharethis', array('data_options' => $data_options, 'm_path' => $mPath, 'm_title' => $mTitle)), + '#weight' => intval(variable_get('sharethis_weight', 10)), + ); } - } + break; + case 'links': + $enabled_view_modes = variable_get('sharethis_' . $node->type . '_options', array()); + if (isset($enabled_view_modes[$view_mode]) && $enabled_view_modes[$view_mode]) { + $links['sharethis'] = array( + 'html' => TRUE, + 'title' => theme('sharethis', array('data_options' => $data_options, 'm_path' => $mPath, 'm_title' => $mTitle)), + 'attributes' => array('class' => 'sharethis-buttons'), + ); + $node->content['links']['sharethis'] = array( + '#theme' => 'links', + '#links' => $links, + '#attributes' => array( + 'class' => array('links', 'inline'), + ), + '#tag' => 'div', // Wrap it in a div. + '#type' => 'html_tag', + '#weight' => intval(variable_get('sharethis_weight', 10)), + ); + } + break; } } /** + * Implements hook_theme(). + */ +function sharethis_theme($existing, $type, $theme, $path) { + $theme = array(); + $theme['sharethis'] = array( + 'variables' => array( + 'data_options' => NULL, + 'm_path' => NULL, + 'm_title' => NULL, + ), + ); + return $theme; +} + + +/** + +/** + * Implements hook_field_extra_fields(). + */ +function sharethis_field_extra_fields() { + $extra = array(); + // Only add extra fields if the location is the node content. + if (variable_get('sharethis_location', 'content') == 'content') { + $entity_info = entity_get_info('node'); + foreach ($entity_info['bundles'] as $bundle => $bundle_info) { + $extra['node'][$bundle]['display'] = array( + 'sharethis' => array( + 'label' => t('ShareThis'), + 'description' => t('ShareThis links'), + 'weight' => intval(variable_get('sharethis_weight', 10)), + ), + ); + } + } + return $extra; +} + + +/** * sharethisGetOptionArray is a helper function for DB access. * * Returns options that have been stored in the database. @@ -367,17 +440,20 @@ function sharethis_node_view($node, $view_mode, $langcode) { * @TODO: Switch from this function to just straight variable_get() calls. */ function sharethis_get_options_array() { + $view_modes = array(); + foreach (array_keys(node_type_get_types()) as $type) { + $view_modes[$type] = variable_get('sharethis_' . $type . '_options', array()); + } return array( 'buttons' => variable_get('sharethis_button_option', 'stbc_large'), - 'nodeType' => variable_get('sharethis_node_option', 'page,article'), 'publisherID' => variable_get('sharethis_publisherID', ''), 'services' => variable_get('sharethis_service_option', '"Tweet:twitter","Facebook:facebook","ShareThis:sharethis"'), 'option_extras' => variable_get('sharethis_option_extras', array()), - 'viewMode' => variable_get('sharethis_teaser_option', 0), 'widget' => variable_get('sharethis_widget_option', 'st_multi'), 'twitter_suffix' => variable_get('sharethis_twitter_suffix', ''), 'twitter_handle' => variable_get('sharethis_twitter_handle', ''), 'late_load' => variable_get('sharethis_late_load', FALSE), + 'view_modes' => $view_modes, ); } @@ -555,3 +631,112 @@ function sharethis_views_api() { 'path' => drupal_get_path('module', 'sharethis') . '/views', ); } + + +/** + * Theme function for ShareThis code based on settings. + */ +function theme_sharethis($variables) { + $data_options = $variables['data_options']; + $m_path = $variables['m_path']; + $m_title = $variables['m_title']; + + // Inject the extra services. + foreach ($data_options['option_extras'] as $service) { + $data_options['services'] .= ',"' . $service . '"'; + } + + // The share buttons are simply spans of the form class='st_SERVICE_BUTTONTYPE' -- "st" stands for ShareThis. + $type = drupal_substr($data_options['buttons'], 4); + $type = $type == "_" ? "" : check_plain($type); + $service_array = explode(",", $data_options['services']); + $st_spans = ""; + foreach ($service_array as $service_full) { + // Strip the quotes from the element in the array (They are there for javascript) + $service = explode(":", $service_full); + + // Service names are expected to be parsed by Name:machine_name. If only one + // element in the array is given, it's an invalid service. + if (count($service) < 2) { + continue; + } + + // Find the service code name. + $serviceCodeName = drupal_substr($service[1], 0, -1); + + // Switch the title on a per-service basis if required. + $title = $m_title; + switch ($serviceCodeName) { + case 'twitter': + $title = empty($data_options['twitter_suffix']) ? $title : check_plain($title) . ' ' . check_plain($data_options['twitter_suffix']); + break; + } + + // Sanitize the service code for display. + $display = check_plain($serviceCodeName); + + // Put together the span attributes. + $attributes = array( + 'st_url' => $m_path, + 'st_title' => $title, + 'class' => 'st_' . $display . $type, + ); + if ($serviceCodeName == 'twitter') { + if (!empty($data_options['twitter_handle'])) { + $attributes['st_via'] = $data_options['twitter_handle']; + $attributes['st_username'] = $data_options['twitter_recommends']; + } + } + // Only show the display text if the type is set. + if (!empty($type)) { + $attributes['displaytext'] = check_plain($display); + } + // Render the span tag. + $st_spans .= theme('html_tag', array( + 'element' => array( + '#tag' => 'span', + '#attributes' => $attributes, + '#value' => '', // It's an empty span tag. + ), + )); + } + + // These are the ShareThis scripts: + $st_js_options['switchTo5x'] = $data_options['widget'] == 'st_multi' ? TRUE : FALSE; + if ($data_options['late_load']) { + $st_js_options['__st_loadLate'] = TRUE; + } + $st_js = "'; + + // Check if we're using SSL or not. + if (isset($_SERVER['HTTPS']) && strtolower($_SERVER['HTTPS']) == 'on') { + $st_js .= ""; + } + else { + $st_js .= ""; + } + + // Provide the stLight options. + $options = array( + 'publisher' => $data_options['publisherID'], + ); + if (isset($data_options['onhover']) && $data_options['onhover'] == FALSE) { + $options['onhover'] = FALSE; + } + if (!empty($data_options['neworzero'])) { + $options['newOrZero'] = "zero"; + } + if (!empty($data_options['donotcopy'])) { + $options['doNotCopy'] = "true"; + } + + $stlight = drupal_json_encode($options); + + // Output the embedded JavaScript. + $st_js .= ""; + return '
' . $st_spans . $st_js . '
'; +}