diff options
-rw-r--r-- | actions/publictagcloud.php | 149 | ||||
-rw-r--r-- | actions/tag.php | 161 | ||||
-rw-r--r-- | htaccess.sample | 2 | ||||
-rw-r--r-- | lib/publicgroupnav.php | 4 | ||||
-rw-r--r-- | lib/util.php | 10 |
5 files changed, 195 insertions, 131 deletions
diff --git a/actions/publictagcloud.php b/actions/publictagcloud.php new file mode 100644 index 000000000..ec28edbad --- /dev/null +++ b/actions/publictagcloud.php @@ -0,0 +1,149 @@ +<?php +/** + * Laconica, the distributed open-source microblogging tool + * + * Public tag cloud for notices + * + * PHP version 5 + * + * LICENCE: This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 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 Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * @category Public + * @package Laconica + * @author Mike Cochrane <mikec@mikenz.geek.nz> + * @author Evan Prodromou <evan@controlyourself.ca> + * @copyright 2008 Mike Cochrane + * @copyright 2008-2009 Control Yourself, Inc. + * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0 + * @link http://laconi.ca/ + */ + +if (!defined('LACONICA')) { exit(1); } + +define('TAGS_PER_PAGE', 100); + +/** + * Public tag cloud for notices + * + * @category Personal + * @package Laconica + * @author Mike Cochrane <mikec@mikenz.geek.nz> + * @author Evan Prodromou <evan@controlyourself.ca> + * @copyright 2008 Mike Cochrane + * @copyright 2008-2009 Control Yourself, Inc. + * @link http://laconi.ca/ + */ + +class PublictagcloudAction extends Action +{ + function isReadOnly() + { + return true; + } + + function title() + { + return _('Public tag cloud'); + } + + function showPageNotice() + { + $this->element('p', 'instructions', + sprintf(_('These are most popular recent tags on %s '), + common_config('site', 'name'))); + } + + function showLocalNav() + { + $nav = new PublicGroupNav($this); + $nav->show(); + } + + function handle($args) + { + parent::handle($args); + $this->showPage(); + } + + function showContent() + { + # This should probably be cached rather than recalculated + $tags = new Notice_tag(); + + #Need to clear the selection and then only re-add the field + #we are grouping by, otherwise it's not a valid 'group by' + #even though MySQL seems to let it slide... + $tags->selectAdd(); + $tags->selectAdd('tag'); + + #Add the aggregated columns... + $tags->selectAdd('max(notice_id) as last_notice_id'); + if(common_config('db','type')=='pgsql') { + $calc='sum(exp(-extract(epoch from (now()-created))/%s)) as weight'; + } else { + $calc='sum(exp(-(now() - created)/%s)) as weight'; + } + $tags->selectAdd(sprintf($calc, common_config('tag', 'dropoff'))); + $tags->groupBy('tag'); + $tags->orderBy('weight DESC'); + + $tags->limit(TAGS_PER_PAGE); + + $cnt = $tags->find(); + + if ($cnt > 0) { + $this->elementStart('p', 'tagcloud'); + + $tw = array(); + $sum = 0; + while ($tags->fetch()) { + $tw[$tags->tag] = $tags->weight; + $sum += $tags->weight; + } + + ksort($tw); + + foreach ($tw as $tag => $weight) { + $this->showTag($tag, $weight, $weight/$sum); + } + + $this->elementEnd('p'); + } + } + + function showTag($tag, $weight, $relative) + { + # XXX: these should probably tune to the size of the site + if ($relative > 0.1) { + $cls = 'largest'; + } else if ($relative > 0.05) { + $cls = 'verylarge'; + } else if ($relative > 0.02) { + $cls = 'large'; + } else if ($relative > 0.01) { + $cls = 'medium'; + } else if ($relative > 0.005) { + $cls = 'small'; + } else if ($relative > 0.002) { + $cls = 'verysmall'; + } else { + $cls = 'smallest'; + } + + $this->element('a', array('class' => "$cls weight-$weight relative-$relative", + 'href' => common_local_url('tag', array('tag' => $tag))), + $tag); + $this->text(' '); + } +} diff --git a/actions/tag.php b/actions/tag.php index 3096b75b3..039cd9660 100644 --- a/actions/tag.php +++ b/actions/tag.php @@ -19,154 +19,71 @@ if (!defined('LACONICA')) { exit(1); } -require_once(INSTALLDIR.'/actions/showstream.php'); -define('TAGS_PER_PAGE', 100); - -class TagAction extends StreamAction +class TagAction extends Action { - - function handle($args) + function prepare($args) { + parent::prepare($args); + $this->tag = $this->trimmed('tag'); - parent::handle($args); - - # Looks like we're good; show the header - - if (isset($args['tag']) && $args['tag']) { - $tag = $args['tag']; - common_show_header(sprintf(_("Notices tagged with %s"), $tag), - array($this, 'show_header'), $tag, - array($this, 'show_top')); - $this->show_notices($tag); - } else { - common_show_header(_("Tags"), - array($this, 'show_header'), '', - array($this, 'show_top')); - $this->show_tags(); + if (!$this->tag) { + common_redirect(common_local_url('publictagcloud'), 301); + return false; } - common_show_footer(); + $this->page = ($this->arg('page')) ? ($this->arg('page')+0) : 1; + return true; } - function show_header($tag = false) + function title() { - if ($tag) { - $this->element('link', array('rel' => 'alternate', - 'href' => common_local_url('tagrss', array('tag' => $tag)), - 'type' => 'application/rss+xml', - 'title' => sprintf(_('Feed for tag %s'), $tag))); + if ($this->page == 1) { + return sprintf(_("Notices tagged with %s"), $this->tag); + } else { + return sprintf(_("Notices tagged with %s, page %d"), + $this->tag, + $this->page); } } - function get_instructions() + function handle($args) { - return _('Showing most popular tags from the last week'); + parent::handle($args); + + $this->showPage(); } - function show_top($tag = false) + function showFeeds() { - if (!$tag) { - $instr = $this->get_instructions(); - $output = common_markup_to_html($instr); - $this->elementStart('div', 'instructions'); - $this->raw($output); - $this->elementEnd('div'); - $this->public_views_menu(); - } - else { - $this->show_feeds_list(array(0=>array('href'=>common_local_url('tagrss'), - 'type' => 'rss', - 'version' => 'RSS 1.0', - 'item' => 'tagrss'))); - } + $this->element('link', array('rel' => 'alternate', + 'href' => common_local_url('tagrss', array('tag' => $this->tag)), + 'type' => 'application/rss+xml', + 'title' => sprintf(_('Feed for tag %s'), $this->tag))); } - function show_tags() + function showPageNotice() { - # This should probably be cached rather than recalculated - $tags = DB_DataObject::factory('Notice_tag'); - - #Need to clear the selection and then only re-add the field - #we are grouping by, otherwise it's not a valid 'group by' - #even though MySQL seems to let it slide... - $tags->selectAdd(); - $tags->selectAdd('tag'); - - #Add the aggregated columns... - $tags->selectAdd('max(notice_id) as last_notice_id'); - if(common_config('db','type')=='pgsql') { - $calc='sum(exp(-extract(epoch from (now()-created))/%s)) as weight'; - } else { - $calc='sum(exp(-(now() - created)/%s)) as weight'; - } - $tags->selectAdd(sprintf($calc, common_config('tag', 'dropoff'))); - $tags->groupBy('tag'); - $tags->orderBy('weight DESC'); - - # $tags->whereAdd('created > "' . strftime('%Y-%m-%d %H:%M:%S', strtotime('-1 MONTH')) . '"'); - - $tags->limit(TAGS_PER_PAGE); - - $cnt = $tags->find(); - - if ($cnt > 0) { - $this->elementStart('p', 'tagcloud'); - - $tw = array(); - $sum = 0; - while ($tags->fetch()) { - $tw[$tags->tag] = $tags->weight; - $sum += $tags->weight; - } - - ksort($tw); - - foreach ($tw as $tag => $weight) { - $this->show_tag($tag, $weight, $weight/$sum); - } - - $this->elementEnd('p'); - } + return sprintf(_('Messages tagged "%s", most recent first'), $this->tag); } - function show_tag($tag, $weight, $relative) + function showExportData() { - - # XXX: these should probably tune to the size of the site - if ($relative > 0.1) { - $cls = 'largest'; - } else if ($relative > 0.05) { - $cls = 'verylarge'; - } else if ($relative > 0.02) { - $cls = 'large'; - } else if ($relative > 0.01) { - $cls = 'medium'; - } else if ($relative > 0.005) { - $cls = 'small'; - } else if ($relative > 0.002) { - $cls = 'verysmall'; - } else { - $cls = 'smallest'; - } - - $this->element('a', array('class' => "$cls weight-$weight relative-$relative", - 'href' => common_local_url('tag', array('tag' => $tag))), - $tag); - $this->text(' '); + $fl = new FeedList($this); + $fl->show(array(0=>array('href'=>common_local_url('tagrss', array('tag' => $this->tag)), + 'type' => 'rss', + 'version' => 'RSS 1.0', + 'item' => 'tagrss'))); } - function show_notices($tag) + function showContent() { + $notice = Notice_tag::getStream($this->tag, (($this->page-1)*NOTICES_PER_PAGE), NOTICES_PER_PAGE + 1); - $cnt = 0; - - $page = ($this->arg('page')) ? ($this->arg('page')+0) : 1; - - $notice = Notice_tag::getStream($tag, (($page-1)*NOTICES_PER_PAGE), NOTICES_PER_PAGE + 1); + $nl = new NoticeList($notice, $this); - $cnt = $this->show_notice_list($notice); + $cnt = $nl->show(); - common_pagination($page > 1, $cnt > NOTICES_PER_PAGE, - $page, 'tag', array('tag' => $tag)); + $this->pagination($this->page > 1, $cnt > NOTICES_PER_PAGE, + $this->page, 'tag', array('tag' => $this->tag)); } } diff --git a/htaccess.sample b/htaccess.sample index 10e51b5b0..b0e3e93e0 100644 --- a/htaccess.sample +++ b/htaccess.sample @@ -76,7 +76,7 @@ RewriteRule ^message/(\d+)$ index.php?action=showmessage&message=$1 [L,QSA] RewriteRule ^user/(\d+)$ index.php?action=userbyid&id=$1 [L,QSA] -RewriteRule ^tags/?$ index.php?action=tag [L,QSA] +RewriteRule ^tags/?$ index.php?action=publictagcloud [L,QSA] RewriteRule ^tag/([a-zA-Z0-9]+)/rss$ index.php?action=tagrss&tag=$1 [L,QSA] RewriteRule ^tag(/(.*))?$ index.php?action=tag&tag=$2 [L,QSA] diff --git a/lib/publicgroupnav.php b/lib/publicgroupnav.php index 97b57ec17..8dd97a3b7 100644 --- a/lib/publicgroupnav.php +++ b/lib/publicgroupnav.php @@ -76,8 +76,8 @@ class PublicGroupNav extends Widget $this->out->menuItem(common_local_url('public'), _('Public'), _('Public timeline'), $action_name == 'public', 'nav_timeline_public'); - $this->out->menuItem(common_local_url('tag'), _('Recent tags'), - _('Recent tags'), $action_name == 'tag', 'nav_recent-tags'); + $this->out->menuItem(common_local_url('publictagcloud'), _('Recent tags'), + _('Recent tags'), $action_name == 'publictagcloud', 'nav_recent-tags'); if (count(common_config('nickname', 'featured')) > 0) { $this->out->menuItem(common_local_url('featured'), _('Featured'), diff --git a/lib/util.php b/lib/util.php index d67c64972..73c4cdcc8 100644 --- a/lib/util.php +++ b/lib/util.php @@ -865,13 +865,11 @@ function common_fancy_url($action, $args=null) case 'avatarbynickname': return common_path($args['nickname'].'/avatar/'.$args['size']); case 'tag': - if (isset($args['tag']) && $args['tag']) { - $path = 'tag/' . $args['tag']; - unset($args['tag']); - } else { - $path = 'tags'; - } + $path = 'tag/' . $args['tag']; + unset($args['tag']); return common_path($path . (($args) ? ('?' . http_build_query($args)) : '')); + case 'publictagcloud': + return common_path('tags'); case 'peopletag': $path = 'peopletag/' . $args['tag']; unset($args['tag']); |