<?php
/*
Plugin Name: Sociable
Plugin URI: http://push.cx/sociable
Description: Automatically add links on your posts to popular <a href="http://www.maxpower.ca/bookmarking">social bookmarking sites</a>.
Version: 1.2
Author: Peter Harkins
Author URI: http://push.cx
*/
$sociable_date = '2006-03-26'; // date this version was released, beats a version #

/*
Copyright 2006 Peter Harkins (ph@malaprop.org)

This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
*/

$sociable_builtin_known_sites = Array(

	'blinkbits' => Array(
		'favicon' => 'blinkbits.png',
		'url' => 'http://www.blinkbits.com/bookmarklets/save.php?v=1&amp;source_url=PERMALINK&amp;title=TITLE&amp;body=TITLE',
	),

	'BlinkList' => Array(
		'favicon' => 'blinklist.png',
		'url' => 'http://www.blinklist.com/index.php?Action=Blink/addblink.php&amp;Description=&amp;Url=PERMALINK&amp;Title=TITLE',
	),


	'blogmarks' => Array(
		'favicon' => 'blogmarks.png',
		'url' => 'http://blogmarks.net/my/new.php?mini=1&amp;simple=1&amp;url=PERMALINK&amp;title=TITLE',
	),

	'co.mments' => Array(
		'favicon' => 'co.mments.gif',
		'url' => 'http://co.mments.com/track?url=PERMALINK&amp;title=TITLE',
	),

	'connotea' => Array(
		'favicon' => 'connotea.png',
		'url' => 'http://www.connotea.org/addpopup?continue=confirm&amp;uri=PERMALINK&amp;title=TITLE',
	),


	'del.icio.us' => Array(
		'favicon' => 'delicious.png',
		'url' => 'http://del.icio.us/post?url=PERMALINK&amp;title=TITLE',
	),

	'De.lirio.us' => Array(
		'favicon' => 'delirious.png',
		'url' => 'http://de.lirio.us/rubric/post?uri=PERMALINK;title=TITLE;when_done=go_back',
	),

	'digg' => Array(
		'favicon' => 'digg.png',
		'url' => 'http://digg.com/submit?phase=2&amp;url=PERMALINK&amp;title=TITLE',
	),

	'Fark' => Array(
		'favicon' => 'fark.png',
		'url' => 'http://cgi.fark.com/cgi/fark/edit.pl?new_url=PERMALINK&amp;new_comment=TITLE&amp;new_comment=BLOGNAME&amp;linktype=Misc',
		// To post to a different category, see the drop-down box labeled "Link Type" at
		// http://cgi.fark.com/cgi/fark/submit.pl for a complete list
	),

	'feedmelinks' => Array(
		'favicon' => 'feedmelinks.png',
		'url' => 'http://feedmelinks.com/categorize?from=toolbar&amp;op=submit&amp;url=PERMALINK&amp;name=TITLE',
	),

	'Furl' => Array(
		'favicon' => 'furl.png',
		'url' => 'http://www.furl.net/storeIt.jsp?u=PERMALINK&amp;t=TITLE',
	),

	'LinkaGoGo' => Array(
		'favicon' => 'linkagogo.png',
		'url' => 'http://www.linkagogo.com/go/AddNoPopup?url=PERMALINK&amp;title=TITLE',
	),

	'Ma.gnolia' => Array(
		'favicon' => 'magnolia.png',
		'url' => 'http://ma.gnolia.com/beta/bookmarklet/add?url=PERMALINK&amp;title=TITLE&amp;description=TITLE',
	),

	'NewsVine' => Array(
		'favicon' => 'newsvine.png',
		'url' => 'http://www.newsvine.com/_tools/seed&amp;save?u=PERMALINK&amp;h=TITLE',
	),

	'Netvouz' => Array(
		'favicon' => 'netvouz.png',
		'url' => 'http://www.netvouz.com/action/submitBookmark?url=PERMALINK&amp;title=TITLE&amp;description=TITLE',
	),

	'RawSugar' => Array(
		'favicon' => 'rawsugar.png',
		'url' => 'http://www.rawsugar.com/tagger/?turl=PERMALINK&amp;tttl=TITTLE',
	),


	'Reddit' => Array(
		'favicon' => 'reddit.png',
		'url' => 'http://reddit.com/submit?url=PERMALINK&amp;title=TITLE',
	),

	'scuttle' => Array(
		'favicon' => 'scuttle.png',
		'url' => 'http://www.scuttle.org/bookmarks.php/maxpower?action=add&amp;address=PERMALINK&amp;title=TITLE&amp;description=TITLE',
	),

	'Shadows' => Array(
		'favicon' => 'shadows.png',
		'url' => 'http://www.shadows.com/features/tcr.htm?url=PERMALINK&amp;title=TITLE',
	),

	'Simpy' => Array(
		'favicon' => 'simpy.png',
		'url' => 'http://www.simpy.com/simpy/LinkAdd.do?href=PERMALINK&amp;title=TITLE',
	),

	'Smarking' => Array(
		'favicon' => 'smarking.png',
		'url' => 'http://smarking.com/editbookmark/?url=PERMALINK&amp;description=TITLE',
	),

	'Spurl' => Array(
		'favicon' => 'spurl.png',
		'url' => 'http://www.spurl.net/spurl.php?url=PERMALINK&amp;title=TITLE',
	),

	'TailRank' => Array(
		'favicon' => 'tailrank.png',
		'url' => 'http://tailrank.com/share/?text=&amp;link_href=PERMALINK&amp;title=TITLE',
	),

	'Wists' => Array(
		'favicon' => 'wists.png',
		'url' => 'http://wists.com/r.php?c=&amp;r=PERMALINK&amp;title=TITLE',
	),

	'YahooMyWeb' => Array(
		'favicon' => 'yahoomyweb.png',
		'url' => 'http://myweb2.search.yahoo.com/myresults/bookmarklet?u=PERMALINK&amp;=TITLE',
	),

);

$sociable_files = Array(
	'sociable.php',
	'sociable.css',
	'sociable-admin.css',
	'images/',
	'images/blinkbits.png',
	'images/blinklist.png',
	'images/blogmarks.png',
	'images/co.mments.gif',
	'images/connotea.png',
	'images/delicious.png',
	'images/delirious.png',
	'images/digg.png',
	'images/fark.png',
	'images/feedmelinks.png',
	'images/furl.png',
	'images/linkagogo.png',
	'images/magnolia.png',
	'images/netvouz.png',
	'images/newsvine.png',
	'images/rawsugar.png',
	'images/reddit.png',
	'images/scuttle.png',
	'images/shadows.png',
	'images/simpy.png',
	'images/smarking.png',
	'images/spurl.png',
	'images/tailrank.png',
	'images/wists.png',
	'images/yahoomyweb.png',
	'tool-man/',
	'tool-man/coordinates.js',
	'tool-man/core.js',
	'tool-man/css.js',
	'tool-man/drag.js',
	'tool-man/dragsort.js',
	'tool-man/events.js',
);

/*
function sociable_html($display=Array()) {
	$known_sites = get_option('sociable_known_sites');
	$active_sites = get_option('sociable_active_sites');

	$html = "";

	$imagepath = get_bloginfo('wpurl') . '/wp-content/plugins/sociable/images/';

	// if no sites are specified, display all active
	// have to check $active_sites has contente because WP
	// won't save an empty array as an option
	if (empty($display) and $active_sites) {
		// have to do this to keep the order from known_sites
		foreach($known_sites as $sitename=>$site) {
			if (in_array($sitename, $active_sites))
				$display[] = $sitename;
		}
	}
	// if no sites are active, display nothing
	if (empty($display))
		return "";

	// Load the post's data
	$blogname = urlencode(get_bloginfo('wpurl'));
	global $wp_query; 
	$post = $wp_query->post;
	$permalink = get_permalink($post->ID);
	$title = urlencode($post->post_title);

	$html .= '<div class="sociable"><span class="sociable_tagline">';
	$html .= get_option("sociable_tagline");
	$html .= '<span>These icons link to social bookmarking sites where readers can share and discover new web pages.</span></span><ul>' . "\n";

	foreach($display as $sitename) {
		// if they specify an unknown or inactive site, ignore it
		if (!in_array($sitename, $active_sites))
			continue;

		$site = $known_sites[$sitename];
		$html .= "\t<li>";

		$url = $site['url'];
		$url = str_replace('PERMALINK', $permalink, $url);
		$url = str_replace('TITLE', $title, $url);
		$url = str_replace('BLOGNAME', $blogname, $url);

		$html .= "<a href=\"$url\" title=\"$sitename\">";
		$html .= "<img src=\"$imagepath{$site['favicon']}\" alt=\"$sitename\" />";
		$html .= "</a></li>\n";
	}

	$html .= "</ul></div>\n";

	return $html;
}

// Hook the_content to output html if we should display on any page
$sociable_contitionals = get_option('sociable_conditionals');
if (is_array($sociable_contitionals) and in_array(true, $sociable_contitionals)) {
	add_filter('the_content', 'sociable_display_hook');
	add_filter('the_excerpt', 'sociable_display_hook');
	
	function sociable_display_hook($content='') {
		$conditionals = get_option('sociable_conditionals');
		if ((is_home() and $conditionals['is_home']) or
		    (is_single() and $conditionals['is_single']) or
		    (is_page() and $conditionals['is_page']) or
		    (is_category() and $conditionals['is_category']) or
		    (is_date() and $conditionals['is_date']) or
		    (is_search() and $conditionals['is_search']) or
	            0)
			$content .= sociable_html();
	
		return $content;
	}
}

// Hook wp_head to add css
add_action('wp_head', 'sociable_wp_head');
function sociable_wp_head() {
	echo '<link rel="stylesheet" type="text/css" media="screen" href="' . get_bloginfo('wpurl') . '/wp-content/plugins/sociable/sociable.css" />';
}

// load wp rss functions for update checking.
require_once(ABSPATH . WPINC . '/rss-functions.php');

// Plugin config/data setup
if (function_exists('register_activation_hook')) {
	// for WP 2
	register_activation_hook(__FILE__, 'sociable_activation_hook');
} else {
	// for WP 1.5, which doesn't have any activation hook
	if (!is_array(get_option('sociable_known_sites')))
		sociable_activation_hook();
}
function sociable_activation_hook() {
	return sociable_restore_config(False);
}

// restore built-in defaults, optionally overwriting existing values
function sociable_restore_config($force=False) {
	// Load defaults, taking care not to smash already-set options
	global $sociable_builtin_known_sites;

	// known_sites defaults to builtin array
	if ($force or !is_array(get_option('sociable_known_sites')))
		update_option('sociable_known_sites', $sociable_builtin_known_sites);

	// active_sites defaults to all known_sites
	if ($force or !is_array(get_option('sociable_active_sites')))
		update_option('sociable_active_sites', array_keys($sociable_builtin_known_sites));

	// tagline defaults to a Hitchiker's Guide to the Galaxy reference
	if ($force or !is_string(get_option('sociable_tagline')))
		update_option('sociable_tagline', "<strong>Share and Enjoy:</strong>");

	// only display on single posts and pages by default
	if ($force or !is_array(get_option('sociable_conditionals')))
		update_option('sociable_conditionals', array(
			'is_home' => False,
			'is_single' => True,
			'is_page' => True,
			'is_category' => False,
			'is_date' => False,
			'is_search' => False,
		));

	// last-updated date defaults to 0000-00-00
	// this is to trigger the update check on first run
	if ($force or !get_option('sociable_updated'))
		update_option('sociable_updated', '0000-00-00');
}

// Hook the admin_menu display to add admin page
add_action('admin_menu', 'sociable_admin_menu');
function sociable_admin_menu() {
	add_submenu_page('options-general.php', 'Sociable', 'Sociable', 8, 'Sociable', 'sociable_submenu');
}

// Admin page header
add_action('admin_head', 'sociable_admin_head');
function sociable_admin_head() {
?>

<!-- The ToolMan lib provides drag and drop: http://tool-man.org/examples/sorting.html -->
<script language="JavaScript" type="text/javascript" src="<?php echo get_bloginfo('wpurl'); ?>/wp-content/plugins/sociable/tool-man/core.js"></script>
<script language="JavaScript" type="text/javascript" src="<?php echo get_bloginfo('wpurl'); ?>/wp-content/plugins/sociable/tool-man/coordinates.js"></script>
<script language="JavaScript" type="text/javascript" src="<?php echo get_bloginfo('wpurl'); ?>/wp-content/plugins/sociable/tool-man/css.js"></script>
<script language="JavaScript" type="text/javascript" src="<?php echo get_bloginfo('wpurl'); ?>/wp-content/plugins/sociable/tool-man/drag.js"></script>
<script language="JavaScript" type="text/javascript" src="<?php echo get_bloginfo('wpurl'); ?>/wp-content/plugins/sociable/tool-man/dragsort.js"></script>
<script language="JavaScript" type="text/javascript" src="<?php echo get_bloginfo('wpurl'); ?>/wp-content/plugins/sociable/tool-man/events.js"></script>
<script language="JavaScript" type="text/javascript"><!--
var dragsort = ToolMan.dragsort();
var junkdrawer = ToolMan.junkdrawer();
window.onload = function() {
	dragsort.makeListSortable(document.getElementById("sociable_site_list"));
}
*/
/* make checkbox action prettier */
/*function toggle_checkbox(id) {
	var checkbox = document.getElementById(id);
	if (checkbox.checked)
		checkbox.parentNode.className = 'active';
	else
		checkbox.parentNode.className = 'inactive';
}
--></script>

<link rel="stylesheet" type="text/css" media="screen" href="<?php echo get_bloginfo('wpurl'); ?>/wp-content/plugins/sociable/sociable-admin.css" />
<?
}

function sociable_update_version() {
	global $sociable_date;

	$known_update = get_option('sociable_known_update');
	$found_update = $known_update;

	// check for new versions if it's been a week
	if (date("Y-m-d", time() + 7 * 24 * 60 * 60) > get_option('sociable_updated')) {
		// note the updating and fetch potential updates
		update_option('sociable_updated', date("Y-m-d"));
		$update = fetch_rss("http://push.cx/tag/sociable/feed");

		if ($update === False) {
			echo '<div id="message" class="updated fade"><p>Sociable tried to check for updates but couldn\'t. This might be the way PHP is set up, or just random network issues. Please <a href="http://push.cx/sociable">visit the Sociable website</a> to update manually if needed.</p></div>';
			return;
		}

		// loop through feed, pulling out any updates
		foreach($update->items as $item) {
			$updates = Array();
			if (preg_match('|<!-- Sociable:Update date="(\d{4}-\d{2}-\d{2})" -->|', $item['content']['encoded'], $updates)) {
				// if this is the newest update, save it
				if ($updates[1] > $found_update)
					$found_update = $updates[1];
			}
		}
	}

	// if an newer update was found, save it
	if ($found_update > $known_update)
		update_option('sociable_known_update', $found_update);

	// if the best-known update is newer than this ver, tell user
	if ($found_update > $sociable_date)
		echo '<div id="message" class="updated fade"><p>A <a href="http://push.cx/sociable">new version of Sociable is available</a> (as of ' . $found_update . ').</p></div>';
}

// Sanity check the upload worked
function sociable_upload_errors() {
	global $sociable_files;

	$cwd = getcwd(); // store current dir for restoration
	if (!@chdir('../wp-content/plugins'))
		return "Couldn't find wp-admin/plugins folder. Please make sure WordPress is installed correctly.";
	if (!is_dir('sociable'))
		return "Can't find sociable folder.";
	chdir('sociable');

	foreach($sociable_files as $file) {
		if (substr($file, -1) == '/') {
			if (!is_dir(substr($file, 0, strlen($file) - 1)))
				return "Can't find folder: <kbd>$file</kbd>";
		} else if (!is_file($file))
			return "Can't find file: <kbd>$file</kbd>";
	}

	chdir($cwd); // restore cwd
	return false;
}

// The admin page
function sociable_submenu() {
	global $sociable_date, $sociable_files;

	// update options in db if requested
	if ($_REQUEST['restore']) {
		sociable_restore_config(True);
		echo '<div id="message" class="updated fade"><p>Restored all settings to defaults.</p></div>';
	} else if ($_REQUEST['save']) {
		// update active sites
		$active_sites = Array();
		if (!$_REQUEST['active_sites'])
			$_REQUEST['active_sites'] = Array();
		foreach(get_option('sociable_known_sites') as $sitename=>$site) {
			if (array_key_exists($sitename, $_REQUEST['active_sites']))
				$active_sites[] = $sitename;
		}
		update_option('sociable_active_sites', $active_sites);

		// update site order
		$reordered_known_sites = Array();
		$known_sites = get_option('sociable_known_sites');
		foreach(explode('|', $_REQUEST['site_order']) as $sitename) {
			$reordered_known_sites[$sitename] = $known_sites[$sitename];
		}
		// have to delete and re-add because update doesn't hit the db for identical arrays
		// (sorting does not influence associated array equality in PHP)
		delete_option('sociable_known_sites', $reordered_known_sites);
		add_option('sociable_known_sites', $reordered_known_sites);

		// update conditional displays
		$conditionals = Array();
		if (!$_REQUEST['conditionals'])
			$_REQUEST['conditionals'] = Array();
		foreach(get_option('sociable_conditionals') as $condition=>$toggled)
			$conditionals[$condition] = array_key_exists($condition, $_REQUEST['conditionals']);
		update_option('sociable_conditionals', $conditionals);

		// update tagline
		if (!$_REQUEST['tagline'])
			$_REQUEST['tagline'] = "";
		update_option('sociable_tagline', $_REQUEST['tagline']);
		
		echo '<div id="message" class="updated fade"><p>Saved changes.</p></div>';
	}

	if ($str = sociable_upload_errors())
		echo '<div id="message" class="updated fade"><p>' . $str . '</p><p>In your plugins/sociable folder, you must have these files: <pre>' . implode("\n", $sociable_files) . '</pre></div>';
	sociable_update_version();

	// load options from db to display
	$known_sites = get_option('sociable_known_sites');
	$active_sites = get_option('sociable_active_sites');
	$tagline = get_option('sociable_tagline');
	$conditionals = get_option('sociable_conditionals');
	$updated = get_option('sociable_updated');

	// display options
?>
<form action="<?php echo $_SERVER['REQUEST_URI']; ?>" method="post">

<div class="wrap" id="sociable_options">
<fieldset id="sociable_sites">

<h3>Sociable Options</h3>

<p>Drag and drop sites to reorder them. Only the sites you check will appear
publicly.</p>

<ul id="sociable_site_list">
<?php foreach ($known_sites as $sitename=>$site) { ?>
	<li class="sociable_site <?php echo (in_array($sitename, $active_sites)) ? "active" : "inactive"; ?>" id="<?php echo $sitename; ?>" onMouseUp="javascript:document.getElementById('site_order').value=junkdrawer.serializeList(document.getElementById('sociable_site_list'));">
		<input type="checkbox" id="cb_<?php echo $sitename; ?>" name="active_sites[<?php echo $sitename; ?>]"<?php echo (in_array($sitename, $active_sites)) ? " checked" : ""; ?> onClick="javascript:toggle_checkbox('cb_<?php echo $sitename; ?>');" />
		<img src="../wp-content/plugins/sociable/images/<?php echo $site['favicon']?>" width="16" height="16" alt="" />
		<?php print $sitename; ?>
	</li>
<?php } ?>
</ul>
<input type="hidden" id="site_order" name="site_order" value="<?php echo join('|', array_keys($known_sites)) ?>" />

</fieldset>
<div style="clear: left; display: none;"><br/></div>

<fieldset id="sociable_tagline">
<p>
Change the text displayed in front of the icons below. For complete
customization, edit <i>sociable.css</i> in the Sociable plugin directory.
</p>
<input type="text" name="tagline" value="<?php echo htmlspecialchars($tagline); ?>" />
</fieldset>


<fieldset id="sociable_conditionals">
<p>The icons appear at the end of each blog post, and while posts may show on
many different types of pages. Depending on your theme and audience, it may be tacky to display icons on all types of pages.</p>

<ul style="list-style-type: none">
	<li><input type="checkbox" name="conditionals[is_home]"<?php echo ($conditionals['is_home']) ? " checked" : ""; ?>> Front page of the blog</li>
	<li><input type="checkbox" name="conditionals[is_single]"<?php echo ($conditionals['is_single']) ? " checked" : ""; ?>> Individual blog posts</li>
	<li><input type="checkbox" name="conditionals[is_page]"<?php echo ($conditionals['is_page']) ? " checked" : ""; ?>> Individual WordPress "Pages"</li>
	<li><input type="checkbox" name="conditionals[is_category]"<?php echo ($conditionals['is_category']) ? " checked" : ""; ?>> Category archives</li>
	<li><input type="checkbox" name="conditionals[is_date]"<?php echo ($conditionals['is_date']) ? " checked" : ""; ?>> Date-based archives</li>
	<li><input type="checkbox" name="conditionals[is_search]"<?php echo ($conditionals['is_search']) ? " checked" : ""; ?>> Search results</li>
</ul>
</fieldset>

<p class="submit"><input name="save" id="save" tabindex="3" value="Save Changes" type="submit" /></p>
<p class="submit"><input name="restore" id="restore" tabindex="3" value="Restore Built-in Defaults" type="submit" style="border: 2px solid #e00;" /></p>

</div>

<div class="wrap">
<h3>Automatic Updates</h3>
<p>
Sociable checks for new versions when you bring up this page. (At most once per week.)
</p>

<p>This copy of Sociable is from <b><?php echo $sociable_date; ?></b>.</p>
<p>Last checked on <b><?php echo $updated; ?></b>.</p>
</div>

<div class="wrap">
<p>
<a href="http://push.cx/sociable">Sociable</a> is copyright 2006 by <a
href="http://push.cx/">Peter Harkins</a>, released under the GNU GPL version 2
or later. If you like Sociable, please send a link my way so other folks can
find out about it. If you have any problems or good ideas, <a
href="mailto:ph@malaprop.org">mail me</a>.
</p>
</div>

</form>

<?php
}
*/
?>
