diff --git a/plugins/ShareNotice/ShareNoticePlugin.php b/plugins/ShareNotice/ShareNoticePlugin.php new file mode 100644 index 0000000000..d44e234529 --- /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 0000000000..a3f4661973 --- /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 0000000000..3105e30696 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 0000000000..5be2b46c8a 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 0000000000..a7b39090d0 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 0000000000..f9e778d9a6 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 0000000000..f4f847e66c --- /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; +}