tweet.module in Tweet 5.2
Same filename and directory in other branches
Builds links to post pages to twitter.
File
tweet.moduleView source
<?php
/**
* @file
* Builds links to post pages to twitter.
*/
/**
* Implementation of hook_help().
*/
function tweet_help($section = '') {
$output = '';
switch ($section) {
case "admin/help#tweet":
$output = '<p>' . t("This module builds links to post pages to twitter. See the function tweet_to_twitter() in the module file for an explanation of how to use it.") . '</p>';
break;
}
return $output;
}
/**
* Implementation of hook_link().
*/
function tweet_link($type, $node = NULL, $teaser = FALSE) {
if ($type == 'node' && in_array($node->type, variable_get('tweet_types', _tweet_node_types())) && !_tweet_exclude($node->nid)) {
$title = variable_get('tweet_title', 1);
if (!$teaser) {
$link_type = variable_get('tweet_node', 'icon');
if ($link_type != 'none') {
$links['tweet'] = _tweet_to_twitter($link_type, '', $node->nid);
return $links;
}
}
else {
$link_type = variable_get('tweet_teaser', 'none');
if ($link_type != 'none') {
$links['tweet'] = _tweet_to_twitter($link_type, '', $node->nid);
return $links;
}
}
}
}
/**
* Implementation of hook_menu().
*/
function tweet_menu($may_cache) {
$items = array();
if (!$may_cache) {
$items[] = array(
'path' => 'admin/settings/tweet',
'title' => t('Tweet settings'),
'description' => t('Allows administrators to adjust certain display settings for Tweet.'),
'callback' => 'drupal_get_form',
'callback arguments' => 'tweet_admin',
'access' => user_access('access administration pages'),
'type' => MENU_NORMAL_ITEM,
);
}
return $items;
}
/**
* Returns a link from _tweet_to_twitter().
* @see _tweet_to_twitter()
*/
function tweet_to_twitter($type = 'icon', $title = TRUE, $nid = '', $q = '') {
$array = _tweet_to_twitter($type, $title, $nid, $q);
return l($array['title'], $array['href'], $array['attributes'], $array['query'], NULL, TRUE, $array['html']);
}
/**
* Creates a link to post a URL and optionally title to twitter. Uses the current page by default.
*
* @param $type
* Specifies what will show up in the link: the twitter icon, the twitter icon and text, or just text.
* Pass 'icon' to show just the icon, 'icon_text' to show the icon and text, and 'text' to show just the text.
* Required if display options for nodes are set to 'none' on the settings page.
* @param $format
* A string representing the tweet text, optionally with the case-insensitive tokens [url] and [title].
* If not passed, the format from the settings page will be used.
* @param $nid
* The NID of the node for which the twitter link should be constructed.
* @param $q
* The absolute URL of the page for which the twitter link should be constructed.
* If this is not the current page, the title must be set manually, or it will be incorrect.
* @see _tweet_make_url()
* @see _tweet_get_title()
* @see _tweet_process()
* @see tweet_to_twitter()
* @see tweet_link()
* @return
* A themed link to post the specified or current page to twitter.
*/
function _tweet_to_twitter($type = '', $format = '', $nid = '', $q = '') {
if ($nid && !$q) {
$q = url('node/' . $nid, array(
'absolute' => TRUE,
));
}
$url = _tweet_make_url($q);
$title = _tweet_get_title($nid);
if (!$format) {
$format = variable_get('tweet_format', '[url] [title]');
}
$tweet = _tweet_process($format, array(
'[url]' => $url,
'[title]' => $title,
));
$path = 'http://twitter.com/home';
$text = t('Post to Twitter');
$image_location = drupal_get_path('module', 'tweet') . '/icon.png';
global $base_url;
$image = '<img src="' . $base_url . base_path() . check_plain(variable_get('tweet_image', $image_location)) . '" alt="' . $text . '" title="' . $text . '" />';
if (!$type) {
//Note that $type can be 'none', in which case nothing shows up.
$type = variable_get('tweet_node', 'icon');
}
if ($type == 'icon') {
$show = $image;
}
else {
if ($type == 'icon_text') {
$show = $image . ' ' . $text;
}
else {
if ($type == 'text') {
$show = $text;
}
}
}
$attributes = array(
'class' => 'tweet',
'rel' => 'nofollow',
);
if (variable_get('tweet_new_window', 'target') == 'target') {
$attributes['target'] = '_blank';
}
else {
if (variable_get('tweet_new_window', 'target') == 'js') {
$attributes['onClick'] = "window.open('{$path}?status={$tweet}','twitter','')";
$path = $_GET['q'];
$tweet = 'sent';
}
}
return array(
'title' => $show,
'href' => $path,
'attributes' => $attributes,
'query' => 'status=' . $tweet,
'html' => TRUE,
);
}
/**
* Determines what will be in the tweet itself.
*
* @param $format
* A string containing the text of the tweet before it gets processed.
* @param $tokens
* An associative array where keys represent text that will be replaced by their value in $format.
* @see _tweet_to_twitter()
* @return
* The URL-ready tweet text.
*/
function _tweet_process($format = '', $tokens = array()) {
if (!$format) {
$format = variable_get('tweet_format', '[url] [title]');
}
foreach ($tokens as $search => $replace) {
$format = str_ireplace($search, $replace, $format);
}
$format = drupal_urlencode($format);
//The #, &, and / characters get double-encoded by drupal_urlencode, but they must appear single-encoded for Twitter to recognize them.
//Spaces are manually encoded to plus signs for clarity of whitespace at the end of the tweet.
$format = str_replace(array(
'%2523',
'%2526',
'%252F',
'%20',
), array(
'%23',
'%26',
'%2F',
'+',
), $format);
return $format;
}
/**
* Returns the title of the node for which the NID was passed or the current page.
* Note that there is no good way to get the page title for a page that is not the current page.
* We assume the title is the same as the title of the node if a node is being viewed, but this is often not the case when certain modules are being used.
* In this case, it is recommended that you manually pass the title to tweet_to_twitter().
*
* @param $nid
* The NID of the node for which to return the title. If not passed, uses the current page.
* @see _tweet_to_twitter()
* @return
* The title of the node for the NID passed or the title of the current page.
*/
function _tweet_get_title($nid = '') {
if ($nid) {
$node = node_load(array(
'nid' => $nid,
));
$title = $node->title;
}
else {
$title = drupal_get_title();
}
if (drupal_strlen($title) > 120) {
$title = drupal_substr($title, 0, 119) . '';
}
return $title;
}
/**
* Retrieves and beautifies the abbreviated URL.
*
* @param $q
* The URL of the page for which to create the abbreviated URL. If not passed uses the current page.
* @see _tweet_to_twitter()
* @see _tweet_get_url()
* @return
* An abbreviated URL.
*/
function _tweet_make_url($q = '') {
if (!$q) {
$q = url($_GET['q'], array(
'absolute' => TRUE,
));
}
$cached = cache_get($q);
if ($cached->data) {
return $cached->data;
}
$url = _tweet_get_url($q);
//If the primary service fails, try the secondary service.
if (!$url) {
$url = _tweet_get_url($q, variable_get('tweet_service_backup', 'TinyURL'));
//If the secondary service fails, use the original URL.
if (!$url) {
$url = $q;
}
}
//Replace "http://" with "www." if the URL is abbreviated because it's shorter.
if ($url != $q) {
$url = drupal_substr($url, 7);
$url = 'www.' . $url;
}
$expire = time() + 60 * 60 * 24 * 7 * 3;
cache_set($q, 'cache', $url, $expire);
return $url;
}
/**
* Gets an abbreviated URL using either CURL or PHP from the appropriate service.
* Times out after three (3) seconds.
*
* @param $original
* The URL of the page for which to retrieve the abbreviated URL.
* @param $service
* The service to use to abbreviate the URL.
* For services available by default, see tweet_tweet_service().
* @see _tweet_make_url()
* @return
* An abbreviated URL.
*/
function _tweet_get_url($original, $service = '') {
if (!$service) {
$service = variable_get('tweet_service', 'is.gd');
}
$skip = FALSE;
$services = module_invoke_all('tweet_service', $original);
foreach ($services as $name => $api) {
if ($service == $name) {
if (is_string($api)) {
$url = $api . $original;
break;
}
else {
if (is_array($api) && $api['custom'] == FALSE) {
$url = $api['url'] . $original;
break;
}
else {
if (is_array($api) && $api['custom'] == TRUE) {
$url = $api['url'];
$skip = TRUE;
}
}
}
}
}
//If the service isn't found, use the original.
if (!$url) {
return $original;
}
if (variable_get('tweet_method', 'curl') == 'php' && !$skip) {
$context = stream_context_create(array(
'http' => array(
'timeout' => 3,
),
));
$contents = file_get_contents($url, 0, $context);
}
else {
if (variable_get('tweet_method', 'curl') == 'curl' && !$skip) {
$c = curl_init();
curl_setopt($c, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($c, CURLOPT_CONNECTTIMEOUT, 3);
curl_setopt($c, CURLOPT_URL, $url);
$contents = curl_exec($c);
curl_close($c);
}
else {
$contents = $url;
}
}
if ($contents && drupal_substr($contents, 0, 7) == 'http://') {
return $contents;
}
$method = drupal_strtoupper(variable_get('tweet_method', 'curl'));
if ($skip) {
$method = t('A custom method');
}
watchdog('tweet', t('%method failed to return an abbreviated URL from %service.', array(
'%method' => $method,
'%service' => $service,
)), WATCHDOG_NOTICE, $url);
return FALSE;
}
/**
* Implementation of hook_tweet_service().
*/
function tweet_tweet_service($original) {
return array(
'hex.io' => 'http://hex.io/api-create.php?url=',
'idek.net' => 'http://idek.net/c.php?idek-api=true&idek-ref=drupal_tweet_module&idek-url=',
'is.gd' => 'http://is.gd/api.php?longurl=',
'lin.cr' => 'http://lin.cr/?mode=api&full=1&l=',
'ri.ms' => 'http://ri.ms/api-create.php?url=',
'th8.us' => 'http://th8.us/api.php?url=',
'TinyURL' => 'http://tinyurl.com/api-create.php?url=',
'tr.im' => 'http://api.tr.im/api/trim_simple?url=',
);
}
/**
* Excludes certain Node IDs from displaying links.
*
* @param $nid
* The NID to check for exclusion.
* @return
* TRUE if the node should be excluded, or FALSE if it should not.
*/
function _tweet_exclude($nid) {
$exclude = explode(',', variable_get('tweet_exclude', ''));
$excludes = array();
foreach ($exclude as $check) {
$excludes[] = trim($check);
}
if (!empty($excludes)) {
if (in_array($nid, $excludes)) {
return TRUE;
}
}
return FALSE;
}
/**
* Settings page.
*/
function tweet_admin() {
$form['node_type'] = array(
'#type' => 'select',
'#title' => t('Type of link to show on nodes'),
'#default_value' => variable_get('tweet_node', 'icon'),
'#options' => array(
'icon' => 'icon',
'icon_text' => 'icon_text',
'text' => 'text',
'none' => 'none',
),
);
$form['teaser_type'] = array(
'#type' => 'select',
'#title' => t('Type of link to show on teasers'),
'#default_value' => variable_get('tweet_teaser', 'none'),
'#options' => array(
'icon' => 'icon',
'icon_text' => 'icon_text',
'text' => 'text',
'none' => 'none',
),
);
$form['tweet_new_window'] = array(
'#type' => 'radios',
'#title' => t('Open Twitter'),
'#default_value' => variable_get('tweet_new_window', 'target'),
'#options' => array(
0 => t('In same window'),
'target' => t('In new window with target="_blank" (not XHTML 1.0 Strict compliant)'),
'js' => t('In new window with JavaScript'),
),
);
$methods = array();
if (function_exists('file_get_contents')) {
$methods['php'] = t('PHP');
}
if (function_exists('curl_exec')) {
$methods['curl'] = t('cURL');
}
if (empty($methods)) {
if (variable_get('tweet_method', 'curl') != 'none') {
variable_set('tweet_method', 'none');
}
$form['tweet_method'] = array(
'#type' => 'radios',
'#title' => t('Method'),
'#description' => '<p>' . t('The method to use to retrieve the abbreviated URL.') . '</p>' . '<p><strong>' . t('Your PHP installation does not support the URL abbreviation feature of the Tweet module.') . '</strong> ' . t('You must compile PHP with either the cURL library or the file_get_contents() function to use this option.') . '</p>',
'#default_value' => 'none',
'#options' => array(
'none' => t('None'),
),
'#disabled' => TRUE,
);
$form['tweet_service'] = array(
'#type' => 'radios',
'#title' => t('Service'),
'#description' => t('The service to use to create the abbreviated URL.'),
'#default_value' => 'none',
'#options' => array(
'none' => t('None'),
),
);
$form['tweet_service_backup'] = array(
'#type' => 'radios',
'#title' => t('Backup Service'),
'#description' => t('The service to use to create the abbreviated URL if the primary service is down.'),
'#default_value' => 'none',
'#options' => array(
'none' => t('None'),
),
);
}
else {
$form['tweet_method'] = array(
'#type' => 'radios',
'#title' => t('Method'),
'#description' => t('The method to use to retrieve the abbreviated URL.'),
'#default_value' => variable_get('tweet_method', 'curl'),
'#options' => $methods,
);
$all_services = module_invoke_all('tweet_service', $original);
$services = array();
foreach ($all_services as $key => $value) {
$services[$key] = $key;
}
$services['none'] = t('None');
$form['tweet_service'] = array(
'#type' => 'select',
'#title' => t('Service'),
'#description' => t('The service to use to create the abbreviated URL.'),
'#default_value' => variable_get('tweet_service', 'is.gd'),
'#options' => $services,
);
$form['tweet_service_backup'] = array(
'#type' => 'select',
'#title' => t('Backup Service'),
'#description' => t('The service to use to create the abbreviated URL if the primary service is down.'),
'#default_value' => variable_get('tweet_service_backup', 'TinyURL'),
'#options' => $services,
);
}
$node_types = variable_get('tweet_types', array());
//If all types are selected, un-select them, because the system will still save the result as all selected and it looks better.
if ($node_types == _tweet_node_types()) {
$node_types = array();
}
$form['types'] = array(
'#type' => 'select',
'#multiple' => TRUE,
'#title' => t('Node types on which to display link'),
'#description' => t('If no types are selected, the link will appear on all types. To stop links from appearing on all nodes, choose "none" in the teaser and node display options above.'),
'#default_value' => $node_types,
'#options' => _tweet_node_types(),
);
$image_location = drupal_get_path('module', 'tweet') . '/icon.png';
$form['tweet_image'] = array(
'#type' => 'textfield',
'#title' => t('Image'),
'#description' => t('Enter the URL for the image you want to show up if you allow images to appear in your links, relative to your Drupal installation. Ex.: sites/all/modules/tweet/icon.png'),
'#default_value' => variable_get('tweet_image', $image_location),
);
$form['tweet_exclude'] = array(
'#type' => 'textfield',
'#title' => t('Exclude nodes'),
'#description' => t('Enter the NIDs of nodes which should not have Tweet links, separated by commas.'),
'#default_value' => variable_get('tweet_exclude', ''),
);
$form['tweet_format'] = array(
'#type' => 'textfield',
'#title' => t('Format'),
'#description' => t('Manipulate the elements of the tweet by changing their order, removing them, or adding them (like hashtags). You can use the case-insensitive tokens [url] and [title].'),
'#maxlength' => 140,
'#default_value' => variable_get('tweet_format', '[url] [title]'),
);
return system_settings_form($form);
}
/**
* Validation handler for tweet_admin().
* @see tweet_admin()
* @see tweet_admin_validate()
*/
function tweet_admin_validate($form_id, $form_values) {
if ($form_values['tweet_service'] == $form_values['tweet_service_backup'] && $form_values['tweet_service_backup'] != 'none') {
form_set_error('tweet_service_backup', t('You must select a backup abbreviation service that is different than your primary service.'));
}
if ($form_values['tweet_service'] == 'none' && $form_values['tweet_service_backup'] != 'none') {
drupal_set_message(t('You have selected a backup URL abbreviation service, but no primary service. Your URLs will not be abbreviated with these settings.'));
}
}
/**
* Submit handler for tweet_admin().
* @see tweet_admin()
* @see tweet_admin_validate()
*/
function tweet_admin_submit($form_id, $form_values) {
variable_set('tweet_node', $form_values['node_type']);
variable_set('tweet_teaser', $form_values['teaser_type']);
variable_set('tweet_new_window', $form_values['tweet_new_window']);
variable_set('tweet_method', $form_values['tweet_method']);
variable_set('tweet_service', $form_values['tweet_service']);
variable_set('tweet_service_backup', $form_values['tweet_service_backup']);
variable_set('tweet_image', $form_values['tweet_image']);
variable_set('tweet_exclude', $form_values['tweet_exclude']);
variable_set('tweet_format', $form_values['tweet_format']);
//If no types are selected, assign all types.
if ($form_values['types'] == array()) {
$form_values['types'] = _tweet_node_types();
}
variable_set('tweet_types', $form_values['types']);
//Clear the general cache because changed settings may mean that different URLs should be used.
cache_clear_all('*', 'cache', TRUE);
drupal_set_message(t('The configuration options have been saved.'));
}
/**
* Helper function to provide node types in the format array(TYPE => TYPE).
*/
function _tweet_node_types() {
$a = array_keys(node_get_types());
$return = drupal_map_assoc($a);
return $return;
}
Functions
Name![]() |
Description |
---|---|
tweet_admin | Settings page. |
tweet_admin_submit | Submit handler for tweet_admin(). |
tweet_admin_validate | Validation handler for tweet_admin(). |
tweet_help | Implementation of hook_help(). |
tweet_link | Implementation of hook_link(). |
tweet_menu | Implementation of hook_menu(). |
tweet_to_twitter | Returns a link from _tweet_to_twitter(). |
tweet_tweet_service | Implementation of hook_tweet_service(). |
_tweet_exclude | Excludes certain Node IDs from displaying links. |
_tweet_get_title | Returns the title of the node for which the NID was passed or the current page. Note that there is no good way to get the page title for a page that is not the current page. We assume the title is the same as the title of the node if a node is being… |
_tweet_get_url | Gets an abbreviated URL using either CURL or PHP from the appropriate service. Times out after three (3) seconds. |
_tweet_make_url | Retrieves and beautifies the abbreviated URL. |
_tweet_node_types | Helper function to provide node types in the format array(TYPE => TYPE). |
_tweet_process | Determines what will be in the tweet itself. |
_tweet_to_twitter | Creates a link to post a URL and optionally title to twitter. Uses the current page by default. |