diff --git a/actions/publictagcloud.php b/actions/publictagcloud.php new file mode 100644 index 0000000000..ec28edbadc --- /dev/null +++ b/actions/publictagcloud.php @@ -0,0 +1,149 @@ +. + * + * @category Public + * @package Laconica + * @author Mike Cochrane + * @author Evan Prodromou + * @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 + * @author Evan Prodromou + * @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 3096b75b39..039cd9660b 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 prepare($args) + { + parent::prepare($args); + $this->tag = $this->trimmed('tag'); + + if (!$this->tag) { + common_redirect(common_local_url('publictagcloud'), 301); + return false; + } + + $this->page = ($this->arg('page')) ? ($this->arg('page')+0) : 1; + return true; + } + + function title() + { + 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 handle($args) { - 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(); - } - - common_show_footer(); + $this->showPage(); } - function show_header($tag = false) + function showFeeds() { - 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))); - } + $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 get_instructions() + function showPageNotice() { - return _('Showing most popular tags from the last week'); + return sprintf(_('Messages tagged "%s", most recent first'), $this->tag); } - function show_top($tag = false) + function showExportData() { - 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'))); - } + $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_tags() + function showContent() { - # This should probably be cached rather than recalculated - $tags = DB_DataObject::factory('Notice_tag'); + $notice = Notice_tag::getStream($this->tag, (($this->page-1)*NOTICES_PER_PAGE), NOTICES_PER_PAGE + 1); - #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'); + $nl = new NoticeList($notice, $this); - #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'); + $cnt = $nl->show(); - # $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'); - } - } - - function show_tag($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(' '); - } - - function show_notices($tag) - { - - $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); - - $cnt = $this->show_notice_list($notice); - - 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 10e51b5b06..b0e3e93e00 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 97b57ec17c..8dd97a3b78 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 d67c649728..73c4cdcc88 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']);