diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/arraywrapper.php | 79 | ||||
-rw-r--r-- | lib/gallery.php | 346 | ||||
-rw-r--r-- | lib/galleryaction.php | 168 | ||||
-rw-r--r-- | lib/grouplist.php | 22 | ||||
-rw-r--r-- | lib/groupsbypostssection.php | 78 | ||||
-rw-r--r-- | lib/groupsection.php | 103 | ||||
-rw-r--r-- | lib/noticesection.php | 107 | ||||
-rw-r--r-- | lib/popularnoticesection.php | 83 | ||||
-rw-r--r-- | lib/profilelist.php | 27 | ||||
-rw-r--r-- | lib/profilesection.php | 101 | ||||
-rw-r--r-- | lib/section.php | 108 | ||||
-rw-r--r-- | lib/subgroupnav.php | 111 | ||||
-rw-r--r-- | lib/topposterssection.php | 106 |
13 files changed, 1068 insertions, 371 deletions
diff --git a/lib/arraywrapper.php b/lib/arraywrapper.php new file mode 100644 index 000000000..ef0eeffa5 --- /dev/null +++ b/lib/arraywrapper.php @@ -0,0 +1,79 @@ +<?php +/* + * Laconica - a distributed open-source microblogging tool + * Copyright (C) 2008, Controlez-Vous, Inc. + * + * 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/>. + */ + +if (!defined('LACONICA')) { + exit(1); +} + +class ArrayWrapper +{ + var $_items = null; + var $_count = 0; + var $_i = -1; + + function __construct($items) + { + $this->_items = $items; + $this->_count = count($this->_items); + } + + function fetch() + { + if (!$this->_items) { + return false; + } + $this->_i++; + if ($this->_i < $this->_count) { + return true; + } else { + return false; + } + } + + function __set($name, $value) + { + $item =& $this->_items[$this->_i]; + $item->$name = $value; + return $item->$name; + } + + function __get($name) + { + $item =& $this->_items[$this->_i]; + return $item->$name; + } + + function __isset($name) + { + $item =& $this->_items[$this->_i]; + return isset($item->$name); + } + + function __unset($name) + { + $item =& $this->_items[$this->_i]; + unset($item->$name); + } + + function __call($name, $args) + { + $item =& $this->_items[$this->_i]; + return call_user_func_array(array($item, $name), $args); + } +}
\ No newline at end of file diff --git a/lib/gallery.php b/lib/gallery.php deleted file mode 100644 index 34b58518c..000000000 --- a/lib/gallery.php +++ /dev/null @@ -1,346 +0,0 @@ -<?php -/** - * Laconica - a distributed open-source microblogging tool - * Copyright (C) 2008, Controlez-Vous, Inc. - * - * 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/>. - */ - -if (!defined('LACONICA')) { - exit(1); -} - -require_once INSTALLDIR.'/lib/profilelist.php'; - -// 10x8 - -define('AVATARS_PER_PAGE', 80); - -class GalleryAction extends Action -{ - function is_readonly() - { - return true; - } - - function handle($args) - { - parent::handle($args); - - // Post from the tag dropdown; redirect to a GET - - if ($_SERVER['REQUEST_METHOD'] == 'POST') { - common_redirect($this->self_url(), 307); - } - - $nickname = common_canonical_nickname($this->arg('nickname')); - - $user = User::staticGet('nickname', $nickname); - - if (!$user) { - $this->no_such_user(); - return; - } - - $profile = $user->getProfile(); - - if (!$profile) { - $this->server_error(_('User without matching profile in system.')); - return; - } - - $page = $this->arg('page'); - - if (!$page) { - $page = 1; - } - - $display = $this->arg('display'); - - if (!$display) { - $display = 'list'; - } - - $tag = $this->arg('tag'); - - common_show_header($profile->nickname . ": " . $this->gallery_type(), - null, $profile, - array($this, 'show_top')); - - $this->display_links($profile, $page, $display); - $this->show_tags_dropdown($profile); - - $this->show_gallery($profile, $page, $display, $tag); - common_show_footer(); - } - - function no_such_user() - { - $this->client_error(_('No such user.')); - } - - function show_tags_dropdown($profile) - { - $tag = $this->trimmed('tag'); - - list($lst, $usr) = $this->fields(); - - $tags = $this->get_all_tags($profile, $lst, $usr); - - $content = array(); - - foreach ($tags as $t) { - $content[$t] = $t; - } - if ($tags) { - common_element_start('dl', array('id'=>'filter_tags')); - common_element('dt', null, _('Filter tags')); - common_element_start('dd'); - common_element_start('ul'); - common_element_start('li', array('id' => 'filter_tags_all', - 'class' => 'child_1')); - common_element('a', - array('href' => - common_local_url($this->trimmed('action'), - array('nickname' => - $profile->nickname))), - _('All')); - common_element_end('li'); - common_element_start('li', array('id'=>'filter_tags_item')); - common_element_start('form', array('name' => 'bytag', - 'id' => 'bytag', - 'method' => 'post')); - common_dropdown('tag', _('Tag'), $content, - _('Choose a tag to narrow list'), false, $tag); - common_submit('go', _('Go')); - common_element_end('form'); - common_element_end('li'); - common_element_end('ul'); - common_element_end('dd'); - common_element_end('dl'); - } - } - - function show_top($profile) - { - common_element('div', 'instructions', - $this->get_instructions($profile)); - $this->show_menu(); - } - - function show_menu() - { - // action => array('prompt', 'title', $args) - $action = $this->trimmed('action'); - $nickname = $this->trimmed('nickname'); - - $menu = - array('subscriptions' => - array( _('Subscriptions'), - _('Subscriptions'), - array('nickname' => $nickname)), - 'subscribers' => - array( - _('Subscribers'), - _('Subscribers'), - array('nickname' => $nickname)), - ); - $this->nav_menu($menu); - } - - function show_gallery($profile, $page, $display='list', $tag=null) - { - $other = new Profile(); - - list($lst, $usr) = $this->fields(); - - $per_page = ($display == 'list') ? PROFILES_PER_PAGE : AVATARS_PER_PAGE; - - $offset = ($page-1)*$per_page; - $limit = $per_page + 1; - - if (common_config('db', 'type') == 'pgsql') { - $lim = ' LIMIT ' . $limit . ' OFFSET ' . $offset; - } else { - $lim = ' LIMIT ' . $offset . ', ' . $limit; - } - - // XXX: memcached results - // FIXME: SQL injection on $tag - - $other->query('SELECT profile.* ' . - 'FROM profile JOIN subscription ' . - 'ON profile.id = subscription.' . $lst . ' ' . - (($tag) ? 'JOIN profile_tag ON (profile.id = profile_tag.tagged AND subscription.'.$usr.'= profile_tag.tagger) ' : '') . - 'WHERE ' . $usr . ' = ' . $profile->id . ' ' . - 'AND subscriber != subscribed ' . - (($tag) ? 'AND profile_tag.tag= "' . $tag . '" ': '') . - 'ORDER BY subscription.created DESC, profile.id DESC ' . - $lim); - - if ($display == 'list') { - $cls = $this->profile_list_class(); - $profile_list = new $cls($other, $profile, $this->trimmed('action')); - $cnt = $profile_list->show_list(); - } else { - $cnt = $this->icon_list($other); - } - - // For building the pagination URLs - - $args = array('nickname' => $profile->nickname); - - if ($display != 'list') { - $args['display'] = $display; - } - - common_pagination($page > 1, - $cnt > $per_page, - $page, - $this->trimmed('action'), - $args); - } - - function profile_list_class() - { - return 'ProfileList'; - } - - function icon_list($other) - { - common_element_start('ul', $this->div_class()); - - $cnt = 0; - - while ($other->fetch()) { - - $cnt++; - - if ($cnt > AVATARS_PER_PAGE) { - break; - } - - common_element_start('li'); - - common_element_start('a', array('title' => ($other->fullname) ? - $other->fullname : - $other->nickname, - 'href' => $other->profileurl, - 'class' => 'subscription')); - $avatar = $other->getAvatar(AVATAR_STREAM_SIZE); - common_element('img', - array('src' => - (($avatar) ? common_avatar_display_url($avatar) : - common_default_avatar(AVATAR_STREAM_SIZE)), - 'width' => AVATAR_STREAM_SIZE, - 'height' => AVATAR_STREAM_SIZE, - 'class' => 'avatar stream', - 'alt' => ($other->fullname) ? - $other->fullname : - $other->nickname)); - common_element_end('a'); - - // XXX: subscribe form here - - common_element_end('li'); - } - - common_element_end('ul'); - - return $cnt; - } - - function gallery_type() - { - return null; - } - - function get_instructions(&$profile) - { - return null; - } - - function fields() - { - return null; - } - - function div_class() - { - return ''; - } - - function display_links($profile, $page, $display) - { - $tag = $this->trimmed('tag'); - - common_element_start('dl', array('id'=>'subscriptions_nav')); - common_element('dt', null, _('Subscriptions navigation')); - common_element_start('dd'); - common_element_start('ul', array('class'=>'nav')); - - switch ($display) { - case 'list': - common_element('li', array('class'=>'child_1'), _('List')); - common_element_start('li'); - $url_args = array('display' => 'icons', - 'nickname' => $profile->nickname, - 'page' => 1 + floor((($page - 1) * PROFILES_PER_PAGE) / AVATARS_PER_PAGE)); - if ($tag) { - $url_args['tag'] = $tag; - } - $url = common_local_url($this->trimmed('action'), $url_args); - common_element('a', array('href' => $url), - _('Icons')); - common_element_end('li'); - break; - default: - common_element_start('li', array('class'=>'child_1')); - $url_args = array('nickname' => $profile->nickname, - 'page' => 1 + floor((($page - 1) * AVATARS_PER_PAGE) / PROFILES_PER_PAGE)); - if ($tag) { - $url_args['tag'] = $tag; - } - $url = common_local_url($this->trimmed('action'), $url_args); - common_element('a', array('href' => $url), - _('List')); - common_element_end('li'); - common_element('li', null, _('Icons')); - break; - } - - common_element_end('ul'); - common_element_end('dd'); - common_element_end('dl'); - } - - // Get list of tags we tagged other users with - - function get_all_tags($profile, $lst, $usr) - { - $profile_tag = new Notice_tag(); - $profile_tag->query('SELECT DISTINCT(tag) ' . - 'FROM profile_tag, subscription ' . - 'WHERE tagger = ' . $profile->id . ' ' . - 'AND ' . $usr . ' = ' . $profile->id . ' ' . - 'AND ' . $lst . ' = tagged ' . - 'AND tagger != tagged'); - $tags = array(); - while ($profile_tag->fetch()) { - $tags[] = $profile_tag->tag; - } - $profile_tag->free(); - return $tags; - } -}
\ No newline at end of file diff --git a/lib/galleryaction.php b/lib/galleryaction.php new file mode 100644 index 000000000..a277762a6 --- /dev/null +++ b/lib/galleryaction.php @@ -0,0 +1,168 @@ +<?php +/** + * Laconica - a distributed open-source microblogging tool + * Copyright (C) 2008, Controlez-Vous, Inc. + * + * 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/>. + */ + +if (!defined('LACONICA')) { + exit(1); +} + +require_once INSTALLDIR.'/lib/profilelist.php'; + +// 10x8 + +define('AVATARS_PER_PAGE', 80); + +class GalleryAction extends Action +{ + var $profile = null; + var $user = null; + var $page = null; + + function prepare($args) + { + parent::prepare($args); + + // FIXME very similar code below + + $nickname_arg = $this->arg('nickname'); + $nickname = common_canonical_nickname($nickname_arg); + + // Permanent redirect on non-canonical nickname + + if ($nickname_arg != $nickname) { + $args = array('nickname' => $nickname); + if ($this->arg('page') && $this->arg('page') != 1) { + $args['page'] = $this->arg['page']; + } + common_redirect(common_local_url('subscriptions', $args), 301); + return false; + } + + $this->user = User::staticGet('nickname', $nickname); + + if (!$this->user) { + $this->clientError(_('No such user.'), 404); + return false; + } + + $this->profile = $this->user->getProfile(); + + if (!$this->profile) { + $this->serverError(_('User has no profile.')); + return false; + } + + $this->page = ($this->arg('page')) ? ($this->arg('page')+0) : 1; + + return true; + } + + function isReadOnly() + { + return true; + } + + function handle($args) + { + parent::handle($args); + + # Post from the tag dropdown; redirect to a GET + + if ($_SERVER['REQUEST_METHOD'] == 'POST') { + common_redirect($this->self_url(), 307); + return; + } + + $this->showPage(); + } + + function showLocalNav() + { + $nav = new SubGroupNav($this, $this->user); + $nav->show(); + } + + function showContent() + { + $this->showTagsDropdown(); + } + + function showTagsDropdown() + { + $tag = $this->trimmed('tag'); + + $tags = $this->getAllTags(); + + $content = array(); + + foreach ($tags as $t) { + $content[$t] = $t; + } + if ($tags) { + $this->elementStart('dl', array('id'=>'filter_tags')); + $this->element('dt', null, _('Filter tags')); + $this->elementStart('dd'); + $this->elementStart('ul'); + $this->elementStart('li', array('id' => 'filter_tags_all', + 'class' => 'child_1')); + $this->element('a', + array('href' => + common_local_url($this->trimmed('action'), + array('nickname' => + $profile->nickname))), + _('All')); + $this->elementEnd('li'); + $this->elementStart('li', array('id'=>'filter_tags_item')); + $this->elementStart('form', array('name' => 'bytag', + 'id' => 'bytag', + 'method' => 'post')); + $this->dropdown('tag', _('Tag'), $content, + _('Choose a tag to narrow list'), false, $tag); + $this->submit('go', _('Go')); + $this->elementEnd('form'); + $this->elementEnd('li'); + $this->elementEnd('ul'); + $this->elementEnd('dd'); + $this->elementEnd('dl'); + } + } + + // Get list of tags we tagged other users with + + function getTags($lst, $usr) + { + $profile_tag = new Notice_tag(); + $profile_tag->query('SELECT DISTINCT(tag) ' . + 'FROM profile_tag, subscription ' . + 'WHERE tagger = ' . $this->profile->id . ' ' . + 'AND ' . $usr . ' = ' . $this->profile->id . ' ' . + 'AND ' . $lst . ' = tagged ' . + 'AND tagger != tagged'); + $tags = array(); + while ($profile_tag->fetch()) { + $tags[] = $profile_tag->tag; + } + $profile_tag->free(); + return $tags; + } + + function getAllTags() + { + return array(); + } +}
\ No newline at end of file diff --git a/lib/grouplist.php b/lib/grouplist.php index dd10a2753..869e44897 100644 --- a/lib/grouplist.php +++ b/lib/grouplist.php @@ -66,7 +66,7 @@ class GroupList extends Widget function show() { - $this->out->elementStart('ul', 'groups'); + $this->out->elementStart('ul', 'profiles groups xoxo'); $cnt = 0; @@ -85,19 +85,19 @@ class GroupList extends Widget function showGroup() { - $this->out->elementStart('li', array('class' => 'group', + $this->out->elementStart('li', array('class' => 'profile', 'id' => 'group-' . $this->group->id)); $user = common_current_user(); - $this->out->elementStart('div', array('id' => 'group_group', - 'class' => 'vcard')); + $this->out->elementStart('div', 'entity_profile vcard'); $logo = ($this->group->stream_logo) ? $this->group->stream_logo : User_group::defaultLogo(AVATAR_STREAM_SIZE); $this->out->elementStart('a', array('href' => $this->group->homeUrl(), - 'class' => 'url')); + 'class' => 'url', + 'rel' => 'group')); $this->out->element('img', array('src' => $logo, 'class' => 'photo avatar', 'width' => AVATAR_STREAM_SIZE, @@ -105,24 +105,24 @@ class GroupList extends Widget 'alt' => ($this->group->fullname) ? $this->group->fullname : $this->group->nickname)); - $hasFN = ($this->group->fullname) ? 'nickname' : 'fn nickname'; + $hasFN = ($this->group->fullname) ? 'nickname url uid' : 'fn org nickname url uid'; $this->out->elementStart('span', $hasFN); $this->out->raw($this->highlight($this->group->nickname)); $this->out->elementEnd('span'); $this->out->elementEnd('a'); if ($this->group->fullname) { - $this->out->elementStart('dl', 'group_fn'); + $this->out->elementStart('dl', 'entity_fn'); $this->out->element('dt', null, 'Full name'); $this->out->elementStart('dd'); - $this->out->elementStart('span', 'fn'); + $this->out->elementStart('span', 'fn org'); $this->out->raw($this->highlight($this->group->fullname)); $this->out->elementEnd('span'); $this->out->elementEnd('dd'); $this->out->elementEnd('dl'); } if ($this->group->location) { - $this->out->elementStart('dl', 'group_location'); + $this->out->elementStart('dl', 'entity_location'); $this->out->element('dt', null, _('Location')); $this->out->elementStart('dd', 'location'); $this->out->raw($this->highlight($this->group->location)); @@ -130,7 +130,7 @@ class GroupList extends Widget $this->out->elementEnd('dl'); } if ($this->group->homepage) { - $this->out->elementStart('dl', 'group_url'); + $this->out->elementStart('dl', 'entity_url'); $this->out->element('dt', null, _('URL')); $this->out->elementStart('dd'); $this->out->elementStart('a', array('href' => $this->group->homepage, @@ -141,7 +141,7 @@ class GroupList extends Widget $this->out->elementEnd('dl'); } if ($this->group->description) { - $this->out->elementStart('dl', 'group_note'); + $this->out->elementStart('dl', 'entity_note'); $this->out->element('dt', null, _('Note')); $this->out->elementStart('dd', 'note'); $this->out->raw($this->highlight($this->group->description)); diff --git a/lib/groupsbypostssection.php b/lib/groupsbypostssection.php new file mode 100644 index 000000000..a5e33a93d --- /dev/null +++ b/lib/groupsbypostssection.php @@ -0,0 +1,78 @@ +<?php +/** + * Laconica, the distributed open-source microblogging tool + * + * Groups with the most posts section + * + * 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 Widget + * @package Laconica + * @author Evan Prodromou <evan@controlyourself.ca> + * @copyright 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); +} + +/** + * Groups with the most posts section + * + * @category Widget + * @package Laconica + * @author Evan Prodromou <evan@controlyourself.ca> + * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0 + * @link http://laconi.ca/ + */ + +class GroupsByPostsSection extends GroupSection +{ + function getGroups() + { + $qry = 'SELECT user_group.*, count(*) as value ' . + 'FROM user_group JOIN group_inbox '. + 'ON user_group.id = group_inbox.group_id ' . + 'GROUP BY user_group.id ' . + 'ORDER BY value DESC '; + + $limit = GROUPS_PER_SECTION; + $offset = 0; + + if (common_config('db','type') == 'pgsql') { + $qry .= ' LIMIT ' . $limit . ' OFFSET ' . $offset; + } else { + $qry .= ' LIMIT ' . $offset . ', ' . $limit; + } + + $group = Memcached_DataObject::cachedQuery('User_group', + $qry, + 3600); + return $group; + } + + function title() + { + return _('Groups with most posts'); + } + + function divId() + { + return 'top_groups_by_post'; + } +} diff --git a/lib/groupsection.php b/lib/groupsection.php new file mode 100644 index 000000000..bf26ab48c --- /dev/null +++ b/lib/groupsection.php @@ -0,0 +1,103 @@ +<?php +/** + * Laconica, the distributed open-source microblogging tool + * + * Base class for sections showing lists of groups + * + * 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 Widget + * @package Laconica + * @author Evan Prodromou <evan@controlyourself.ca> + * @copyright 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('GROUPS_PER_SECTION', 6); + +/** + * Base class for sections + * + * These are the widgets that show interesting data about a person + * group, or site. + * + * @category Widget + * @package Laconica + * @author Evan Prodromou <evan@controlyourself.ca> + * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0 + * @link http://laconi.ca/ + */ + +class GroupSection extends Section +{ + function showContent() + { + $profiles = $this->getGroups(); + + if (!$profiles) { + return false; + } + + $cnt = 0; + + $this->out->elementStart('ul', 'entities group xoxo'); + + while ($profiles->fetch() && ++$cnt <= GROUPS_PER_SECTION) { + $this->showGroup($profiles); + } + + $this->out->elementEnd('ul'); + + return ($cnt > GROUPS_PER_SECTION); + } + + function getGroups() + { + return null; + } + + function showGroup($group) + { + $this->out->elementStart('li', 'vcard'); + $this->out->elementStart('a', array('title' => ($group->fullname) ? + $group->fullname : + $group->nickname, + 'href' => $group->homeUrl(), + 'rel' => 'contact group', + 'class' => 'url')); + $logo = ($group->stream_logo) ? + $group->stream_logo : User_group::defaultLogo(AVATAR_STREAM_SIZE); + + $this->out->element('img', array('src' => $logo, + 'width' => AVATAR_MINI_SIZE, + 'height' => AVATAR_MINI_SIZE, + 'class' => 'avatar photo', + 'alt' => ($group->fullname) ? + $group->fullname : + $group->nickname)); + $this->out->element('span', 'fn org nickname', $group->nickname); + $this->out->elementEnd('a'); + if ($group->value) { + $this->out->element('span', 'value', $group->value); + } + $this->out->elementEnd('li'); + } +} diff --git a/lib/noticesection.php b/lib/noticesection.php new file mode 100644 index 000000000..9d1079070 --- /dev/null +++ b/lib/noticesection.php @@ -0,0 +1,107 @@ +<?php +/** + * Laconica, the distributed open-source microblogging tool + * + * Base class for sections showing lists of 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 Widget + * @package Laconica + * @author Evan Prodromou <evan@controlyourself.ca> + * @copyright 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('NOTICES_PER_SECTION', 6); + +/** + * Base class for sections showing lists of notices + * + * These are the widgets that show interesting data about a person + * group, or site. + * + * @category Widget + * @package Laconica + * @author Evan Prodromou <evan@controlyourself.ca> + * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0 + * @link http://laconi.ca/ + */ + +class NoticeSection extends Section +{ + function showContent() + { + $notices = $this->getNotices(); + + $cnt = 0; + + $this->out->elementStart('table', 'notices'); + + while ($notices->fetch() && ++$cnt <= NOTICES_PER_SECTION) { + $this->showNotice($notices); + } + + $this->out->elementEnd('table'); + + return ($cnt > NOTICES_PER_SECTION); + } + + function getNotices() + { + return null; + } + + function showNotice($notice) + { + $profile = $notice->getProfile(); + $this->out->elementStart('tr'); + $this->out->elementStart('td'); + $avatar = $profile->getAvatar(AVATAR_MINI_SIZE); + $this->out->element('img', array('src' => (($avatar) ? common_avatar_display_url($avatar) : common_default_avatar(AVATAR_MINI_SIZE)), + 'width' => AVATAR_MINI_SIZE, + 'height' => AVATAR_MINI_SIZE, + 'class' => 'avatar photo', + 'alt' => ($profile->fullname) ? + $profile->fullname : + $profile->nickname)); + $this->out->elementEnd('a'); + $this->out->elementEnd('td'); + $this->out->elementStart('td'); + $this->out->elementStart('a', array('title' => ($profile->fullname) ? + $profile->fullname : + $profile->nickname, + 'href' => $profile->noticeurl, + 'rel' => 'contact member', + 'class' => 'url')); + $this->out->element('span', 'fn nickname', $profile->nickname); + $this->out->elementEnd('td'); + $this->out->elementStart('td'); + $this->out->raw($notice->rendered); + $this->out->elementEnd('td'); + if ($notice->value) { + $this->out->elementStart('td'); + $this->out->text($notice->value); + $this->out->elementEnd('td'); + } + $this->out->elementEnd('tr'); + } +} diff --git a/lib/popularnoticesection.php b/lib/popularnoticesection.php new file mode 100644 index 000000000..89daaa563 --- /dev/null +++ b/lib/popularnoticesection.php @@ -0,0 +1,83 @@ +<?php +/** + * Laconica, the distributed open-source microblogging tool + * + * Base class for sections showing lists of 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 Widget + * @package Laconica + * @author Evan Prodromou <evan@controlyourself.ca> + * @copyright 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('NOTICES_PER_SECTION', 6); + +/** + * Base class for sections showing lists of notices + * + * These are the widgets that show interesting data about a person + * group, or site. + * + * @category Widget + * @package Laconica + * @author Evan Prodromou <evan@controlyourself.ca> + * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0 + * @link http://laconi.ca/ + */ + +class PopularNoticeSection extends NoticeSection +{ + function getNotices() + { + $qry = 'SELECT notice.*, '. + 'sum(exp(-(now() - fave.modified) / %s)) as weight ' . + 'FROM notice JOIN fave ON notice.id = fave.notice_id ' . + 'GROUP BY fave.notice_id ' . + 'ORDER BY weight DESC'; + + $offset = 0; + $limit = NOTICES_PER_SECTION + 1; + + if (common_config('db', 'type') == 'pgsql') { + $qry .= ' LIMIT ' . $limit . ' OFFSET ' . $offset; + } else { + $qry .= ' LIMIT ' . $offset . ', ' . $limit; + } + + $notice = Memcached_DataObject::cachedQuery('Notice', + sprintf($qry, common_config('popular', 'dropoff')), + 1200); + return $notice; + } + + function title() + { + return _('Popular notices'); + } + + function divId() + { + return 'popular_notices'; + } +} diff --git a/lib/profilelist.php b/lib/profilelist.php index 73c129efe..a510c518c 100644 --- a/lib/profilelist.php +++ b/lib/profilelist.php @@ -92,25 +92,24 @@ class ProfileList extends Widget $user = common_current_user(); - $this->out->elementStart('div', 'entity_profile vcard'); $avatar = $this->profile->getAvatar(AVATAR_STREAM_SIZE); $this->out->elementStart('a', array('href' => $this->profile->profileurl, 'class' => 'url')); $this->out->element('img', array('src' => ($avatar) ? common_avatar_display_url($avatar) : common_default_avatar(AVATAR_STREAM_SIZE), - 'class' => 'photo avatar', - 'width' => AVATAR_STREAM_SIZE, - 'height' => AVATAR_STREAM_SIZE, - 'alt' => - ($this->profile->fullname) ? $this->profile->fullname : - $this->profile->nickname)); + 'class' => 'photo avatar', + 'width' => AVATAR_STREAM_SIZE, + 'height' => AVATAR_STREAM_SIZE, + 'alt' => + ($this->profile->fullname) ? $this->profile->fullname : + $this->profile->nickname)); $hasFN = ($this->profile->fullname) ? 'nickname' : 'fn nickname'; $this->out->elementStart('span', $hasFN); $this->out->raw($this->highlight($this->profile->nickname)); $this->out->elementEnd('span'); $this->out->elementEnd('a'); - + if ($this->profile->fullname) { $this->out->elementStart('dl', 'entity_fn'); $this->out->element('dt', null, 'Full name'); @@ -159,8 +158,8 @@ class ProfileList extends Widget $this->out->elementStart('dt'); if ($user->id == $this->owner->id) { $this->out->element('a', array('href' => common_local_url('tagother', - array('id' => $this->profile->id))), - _('Tags')); + array('id' => $this->profile->id))), + _('Tags')); } else { $this->out->text(_('Tags')); } @@ -172,10 +171,10 @@ class ProfileList extends Widget $this->out->elementStart('li'); $this->element('span', 'mark_hash', '#'); $this->out->element('a', array('rel' => 'tag', - 'href' => common_local_url($this->action, - array('nickname' => $this->owner->nickname, - 'tag' => $tag))), - $tag); + 'href' => common_local_url($this->action, + array('nickname' => $this->owner->nickname, + 'tag' => $tag))), + $tag); $this->out->elementEnd('li'); } $this->out->elementEnd('ul'); diff --git a/lib/profilesection.php b/lib/profilesection.php new file mode 100644 index 000000000..14068b082 --- /dev/null +++ b/lib/profilesection.php @@ -0,0 +1,101 @@ +<?php +/** + * Laconica, the distributed open-source microblogging tool + * + * Base class for sections showing lists of people + * + * 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 Widget + * @package Laconica + * @author Evan Prodromou <evan@controlyourself.ca> + * @copyright 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('PROFILES_PER_SECTION', 6); + +/** + * Base class for sections + * + * These are the widgets that show interesting data about a person + * group, or site. + * + * @category Widget + * @package Laconica + * @author Evan Prodromou <evan@controlyourself.ca> + * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0 + * @link http://laconi.ca/ + */ + +class ProfileSection extends Section +{ + function showContent() + { + $profiles = $this->getProfiles(); + + if (!$profiles) { + return false; + } + + $cnt = 0; + + $this->out->elementStart('ul', 'entities users xoxo'); + + while ($profiles->fetch() && ++$cnt <= PROFILES_PER_SECTION) { + $this->showProfile($profiles); + } + + $this->out->elementEnd('ul'); + + return ($cnt > PROFILES_PER_SECTION); + } + + function getProfiles() + { + return null; + } + + function showProfile($profile) + { + $this->out->elementStart('li', 'vcard'); + $this->out->elementStart('a', array('title' => ($profile->fullname) ? + $profile->fullname : + $profile->nickname, + 'href' => $profile->profileurl, + 'rel' => 'contact member', + 'class' => 'url')); + $avatar = $profile->getAvatar(AVATAR_MINI_SIZE); + $this->out->element('img', array('src' => (($avatar) ? common_avatar_display_url($avatar) : common_default_avatar(AVATAR_MINI_SIZE)), + 'width' => AVATAR_MINI_SIZE, + 'height' => AVATAR_MINI_SIZE, + 'class' => 'avatar photo', + 'alt' => ($profile->fullname) ? + $profile->fullname : + $profile->nickname)); + $this->out->element('span', 'fn nickname', $profile->nickname); + $this->out->elementEnd('a'); + if ($profile->value) { + $this->out->element('span', 'value', $profile->value); + } + $this->out->elementEnd('li'); + } +} diff --git a/lib/section.php b/lib/section.php new file mode 100644 index 000000000..0c32ddcf8 --- /dev/null +++ b/lib/section.php @@ -0,0 +1,108 @@ +<?php +/** + * Laconica, the distributed open-source microblogging tool + * + * Base class for sections (sidebar widgets) + * + * 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 Widget + * @package Laconica + * @author Evan Prodromou <evan@controlyourself.ca> + * @copyright 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); +} + +require_once INSTALLDIR.'/lib/widget.php'; + +/** + * Base class for sections + * + * These are the widgets that show interesting data about a person + * group, or site. + * + * @category Widget + * @package Laconica + * @author Evan Prodromou <evan@controlyourself.ca> + * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0 + * @link http://laconi.ca/ + */ + +class Section extends Widget +{ + /** + * Show the form + * + * Uses a recipe to output the form. + * + * @return void + * @see Widget::show() + */ + + function show() + { + $this->out->elementStart('div', + array('id' => $this->divId(), + 'class' => 'section')); + + $this->out->element('h2', null, + $this->title()); + + $have_more = $this->showContent(); + + if ($have_more) { + $this->out->elementStart('p'); + $this->out->element('a', array('href' => $this->moreUrl(), + 'class' => 'more'), + $this->moreTitle()); + $this->out->elementEnd('p'); + } + + $this->out->elementEnd('div'); + } + + function divId() + { + return 'generic_section'; + } + + function title() + { + return _('Untitled section'); + } + + function showContent() + { + $this->out->element('p', null, + _('(None)')); + return false; + } + + function moreUrl() + { + return null; + } + + function moreTitle() + { + return null; + } +} diff --git a/lib/subgroupnav.php b/lib/subgroupnav.php new file mode 100644 index 000000000..5fd8a72a2 --- /dev/null +++ b/lib/subgroupnav.php @@ -0,0 +1,111 @@ +<?php +/** + * Laconica, the distributed open-source microblogging tool + * + * Local navigation for subscriptions group of pages + * + * 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 Subs + * @package Laconica + * @author Evan Prodromou <evan@controlyourself.ca> + * @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); +} + +require_once INSTALLDIR.'/lib/widget.php'; + +/** + * Local nav menu for subscriptions, subscribers + * + * @category Subs + * @package Laconica + * @author Evan Prodromou <evan@controlyourself.ca> + * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0 + * @link http://laconi.ca/ + */ + +class SubGroupNav extends Widget +{ + var $action = null; + var $user = null; + + /** + * Construction + * + * @param Action $action current action, used for output + */ + + function __construct($action=null, $user=null) + { + parent::__construct($action); + $this->action = $action; + $this->user = $user; + } + + /** + * Show the menu + * + * @return void + */ + + function show() + { + $cur = common_current_user(); + $action = $this->action->trimmed('action'); + + $this->out->elementStart('ul', array('class' => 'nav')); + + $this->out->menuItem(common_local_url('subscriptions', + array('nickname' => + $this->user->nickname)), + _('Subscriptions'), + sprintf(_('People %s subscribes to'), + $this->user->nickname), + $action == 'subscriptions', + 'nav_subscriptions'); + $this->out->menuItem(common_local_url('subscribers', + array('nickname' => + $this->user->nickname)), + _('Subscribers'), + sprintf(_('People subscribed to %s'), + $this->user->nickname), + $action == 'subscribers', + 'nav_subscribers'); + $this->out->menuItem(common_local_url('usergroups', + array('nickname' => + $this->user->nickname)), + _('Groups'), + sprintf(_('Groups %s is a member of'), + $this->user->nickname), + $action == 'usergroups', + 'nav_usergroups'); + if ($this->user->id == $cur->id) { + $this->out->menuItem(common_local_url('invite'), + _('Invite'), + sprintf(_('Invite friends and colleagues to join you on %s'), + common_config('site', 'name')), + $action == 'invite', + 'nav_invite'); + } + $this->out->elementEnd('ul'); + } +} diff --git a/lib/topposterssection.php b/lib/topposterssection.php new file mode 100644 index 000000000..7a3d46aa5 --- /dev/null +++ b/lib/topposterssection.php @@ -0,0 +1,106 @@ +<?php +/** + * Laconica, the distributed open-source microblogging tool + * + * Base class for sections showing lists of people + * + * 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 Widget + * @package Laconica + * @author Evan Prodromou <evan@controlyourself.ca> + * @copyright 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); +} + +/** + * Base class for sections + * + * These are the widgets that show interesting data about a person + * group, or site. + * + * @category Widget + * @package Laconica + * @author Evan Prodromou <evan@controlyourself.ca> + * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0 + * @link http://laconi.ca/ + */ + +class TopPostersSection extends ProfileSection +{ + function getProfiles() + { + $qry = 'SELECT profile.*, count(*) as value ' . + 'FROM profile JOIN notice ON profile.id = notice.profile_id ' . + (common_config('public', 'localonly') ? 'WHERE is_local = 1 ' : '') . + 'GROUP BY profile.id ' . + 'ORDER BY value DESC '; + + $limit = PROFILES_PER_SECTION; + $offset = 0; + + if (common_config('db','type') == 'pgsql') { + $qry .= ' LIMIT ' . $limit . ' OFFSET ' . $offset; + } else { + $qry .= ' LIMIT ' . $offset . ', ' . $limit; + } + + $profile = Memcached_DataObject::cachedQuery('Profile', + $qry, + 6 * 3600); + return $profile; + } + + function showProfile($profile) + { + $this->out->elementStart('li', 'vcard'); + $this->out->elementStart('a', array('title' => ($profile->fullname) ? + $profile->fullname : + $profile->nickname, + 'href' => $profile->profileurl, + 'rel' => 'contact member', + 'class' => 'url')); + $avatar = $profile->getAvatar(AVATAR_MINI_SIZE); + $this->out->element('img', array('src' => (($avatar) ? common_avatar_display_url($avatar) : common_default_avatar(AVATAR_MINI_SIZE)), + 'width' => AVATAR_MINI_SIZE, + 'height' => AVATAR_MINI_SIZE, + 'class' => 'avatar photo', + 'alt' => ($profile->fullname) ? + $profile->fullname : + $profile->nickname)); + $this->out->element('span', 'fn nickname', $profile->nickname); + $this->out->elementEnd('a'); + if ($profile->value) { + $this->out->element('span', 'value', $profile->value); + } + $this->out->elementEnd('li'); + } + + function title() + { + return _('Top posters'); + } + + function divId() + { + return 'top_posters'; + } +} |