From 46167d6b3567d49f052a372fc97e43eefbd064d7 Mon Sep 17 00:00:00 2001 From: Brion Vibber Date: Thu, 30 Sep 2010 18:02:02 -0700 Subject: ShareNotice plugin -- basic buttons per-notice to share the text & a link to the notice on other sites. Default settings list Twitter, Facebook, and Identi.ca as targets. Using icons built-in, and no magic offsite JS or anything so it won't slow down or break if third-party site goes down. Default styles are a little limited, but can be customized in theme should one be so inclined. --- plugins/ShareNotice/ShareNoticePlugin.php | 194 +++++++++++++++++++++++++++++ plugins/ShareNotice/css/README | 9 ++ plugins/ShareNotice/css/icon-facebook.png | Bin 0 -> 312 bytes plugins/ShareNotice/css/icon-share.png | Bin 0 -> 3838 bytes plugins/ShareNotice/css/icon-statusnet.png | Bin 0 -> 488 bytes plugins/ShareNotice/css/icon-twitter.png | Bin 0 -> 469 bytes plugins/ShareNotice/css/sharenotice.css | 23 ++++ 7 files changed, 226 insertions(+) create mode 100644 plugins/ShareNotice/ShareNoticePlugin.php create mode 100644 plugins/ShareNotice/css/README create mode 100644 plugins/ShareNotice/css/icon-facebook.png create mode 100644 plugins/ShareNotice/css/icon-share.png create mode 100644 plugins/ShareNotice/css/icon-statusnet.png create mode 100644 plugins/ShareNotice/css/icon-twitter.png create mode 100644 plugins/ShareNotice/css/sharenotice.css (limited to 'plugins') diff --git a/plugins/ShareNotice/ShareNoticePlugin.php b/plugins/ShareNotice/ShareNoticePlugin.php new file mode 100644 index 000000000..d44e23452 --- /dev/null +++ b/plugins/ShareNotice/ShareNoticePlugin.php @@ -0,0 +1,194 @@ +. + */ + +/** + * @package ShareNoticePlugin + * @maintainer Brion Vibber + */ + +if (!defined('STATUSNET')) { exit(1); } + +class ShareNoticePlugin extends Plugin +{ + public $targets = array( + array('Twitter'), + array('Facebook'), + array('StatusNet', array('baseurl' => 'http://identi.ca')) + ); + + function onEndShowStatusNetStyles($action) { + $action->cssLink('plugins/ShareNotice/css/sharenotice.css'); + return true; + } + + function onStartShowNoticeItem($item) + { + $notice = $item->notice; + $out = $item->out; + + $out->elementStart('ul', array('class' => 'notice-share')); + foreach ($this->targets as $data) { + $type = $data[0]; + $args = (count($data) > 1) ? $data[1] : array(); + $target = $this->getShareTarget($type, $notice, $args); + $this->showShareTarget($out, $target); + } + $out->elementEnd('ul'); + } + + private function getShareTarget($type, $notice, $args) + { + $class = ucfirst($type) . 'ShareTarget'; + + return new $class($notice, $args); + } + + private function showShareTarget(HTMLOutputter $out, NoticeShareTarget $target) + { + $class = $target->getClass(); + $text = $target->getText(); + $url = $target->targetUrl(); + + $out->elementStart('li', array('class' => 'notice-share-' . $class)); + $out->elementStart('a', array( + 'href' => $url, + 'title' => $text, + 'target' => '_blank' + )); + $out->element('span', array(), $text); + $out->elementEnd('a'); + $out->elementEnd('li'); + } +} + +abstract class NoticeShareTarget +{ + protected $notice; + + public function __construct($notice) + { + $this->notice = $notice; + } + + public abstract function getClass(); + + public abstract function getText(); + + public abstract function targetUrl(); +} + +abstract class GenericNoticeShareTarget extends NoticeShareTarget +{ + protected function maxLength() + { + return 140; // typical + } + + protected function statusText() + { + $pattern = _m('"%s"'); + $url = $this->notice->bestUrl(); + $suffix = ' ' . $url; + $room = $this->maxLength() - mb_strlen($suffix) - (mb_strlen($pattern) - mb_strlen('%s')); + + $content = $this->notice->content; + if (mb_strlen($content) > $room) { + $content = mb_substr($content, 0, $room - 1) . '…'; + } + + return sprintf($pattern, $content) . $suffix; + } +} + +class TwitterShareTarget extends GenericNoticeShareTarget +{ + public function getClass() + { + return 'twitter'; + } + + public function getText() + { + return _m('Share on Twitter'); + } + + public function targetUrl() + { + $args = array( + 'status' => $this->statusText() + ); + return 'http://twitter.com/home?' . + http_build_query($args, null, '&'); + } +} + +class StatusNetShareTarget extends GenericNoticeShareTarget +{ + protected $baseurl; + + public function __construct($notice, $args) + { + parent::__construct($notice); + $this->baseurl = $args['baseurl']; + } + + public function getClass() + { + return 'statusnet'; + } + + public function getText() + { + $host = parse_url($this->baseurl, PHP_URL_HOST); + return sprintf(_m('Share on %s'), $host); + } + + public function targetUrl() + { + $args = array( + 'status_textarea' => $this->statusText() + ); + return $this->baseurl . '/notice/new?' . + http_build_query($args, null, '&'); + } + +} + +class FacebookShareTarget extends NoticeShareTarget +{ + public function getClass() + { + return 'facebook'; + } + + public function getText() + { + return _m('Share on Facebook'); + } + + public function targetUrl() + { + $args = array( + 'u' => $this->notice->bestUrl(), + 't' => sprintf(_m('"%s"'), $this->notice->content), + ); + return 'http://www.facebook.com/sharer.php?' . + http_build_query($args, null, '&'); + } +} \ No newline at end of file diff --git a/plugins/ShareNotice/css/README b/plugins/ShareNotice/css/README new file mode 100644 index 000000000..a3f466197 --- /dev/null +++ b/plugins/ShareNotice/css/README @@ -0,0 +1,9 @@ +icon-sharing.png is from http://www.openshareicons.com/ + +Shareaholic has made the Open Share Icon freely available for use by others under the +Creative Commons Attribution-Share Alike 3.0 Unported License. + + +icon-twitter.png is from http://twitter.com/favicon.ico and distributed under fair use +icon-facebook.png is from http://facebook.com/favicon.ico and distributed under fair use +icon-statusnet.png is from http://status.net/favicon.ico and distributed under fair use diff --git a/plugins/ShareNotice/css/icon-facebook.png b/plugins/ShareNotice/css/icon-facebook.png new file mode 100644 index 000000000..3105e3069 Binary files /dev/null and b/plugins/ShareNotice/css/icon-facebook.png differ diff --git a/plugins/ShareNotice/css/icon-share.png b/plugins/ShareNotice/css/icon-share.png new file mode 100644 index 000000000..5be2b46c8 Binary files /dev/null and b/plugins/ShareNotice/css/icon-share.png differ diff --git a/plugins/ShareNotice/css/icon-statusnet.png b/plugins/ShareNotice/css/icon-statusnet.png new file mode 100644 index 000000000..a7b39090d Binary files /dev/null and b/plugins/ShareNotice/css/icon-statusnet.png differ diff --git a/plugins/ShareNotice/css/icon-twitter.png b/plugins/ShareNotice/css/icon-twitter.png new file mode 100644 index 000000000..f9e778d9a Binary files /dev/null and b/plugins/ShareNotice/css/icon-twitter.png differ diff --git a/plugins/ShareNotice/css/sharenotice.css b/plugins/ShareNotice/css/sharenotice.css new file mode 100644 index 000000000..f4f847e66 --- /dev/null +++ b/plugins/ShareNotice/css/sharenotice.css @@ -0,0 +1,23 @@ +.notice-share { + width: 24px; + float: right; +} + +.notice-share li a { + display: block; + width: 16px; + height: 16px; + background: url(icon-share.png) no-repeat; +} +.notice-share li.notice-share-twitter a { + background-image: url(icon-twitter.png); +} +.notice-share li.notice-share-facebook a { + background-image: url(icon-facebook.png); +} +.notice-share li.notice-share-statusnet a { + background-image: url(icon-statusnet.png); +} +.notice-share li a span { + display: none; +} -- cgit v1.2.3-54-g00ecf