diff options
-rw-r--r-- | actions/groupmembers.php | 14 | ||||
-rw-r--r-- | actions/showgroup.php | 2 | ||||
-rw-r--r-- | actions/subscribers.php | 32 | ||||
-rw-r--r-- | actions/subscriptions.php | 34 | ||||
-rw-r--r-- | db/laconica.sql | 55 | ||||
-rw-r--r-- | index.php | 21 | ||||
-rw-r--r-- | lib/noticelist.php | 14 | ||||
-rw-r--r-- | lib/peoplesearchresults.php | 15 | ||||
-rw-r--r-- | lib/profileaction.php | 4 | ||||
-rw-r--r-- | lib/profilelist.php | 154 | ||||
-rw-r--r-- | lib/profileminilist.php | 23 | ||||
-rw-r--r-- | lib/subscriptionlist.php | 131 |
12 files changed, 344 insertions, 155 deletions
diff --git a/actions/groupmembers.php b/actions/groupmembers.php index 21e5ebbaa..53fee3129 100644 --- a/actions/groupmembers.php +++ b/actions/groupmembers.php @@ -127,7 +127,7 @@ class GroupmembersAction extends Action $members = $this->group->getMembers($offset, $limit); if ($members) { - $member_list = new ProfileList($members, null, $this); + $member_list = new GroupMemberList($members, $this->group, $this); $cnt = $member_list->show(); } @@ -138,3 +138,15 @@ class GroupmembersAction extends Action array('nickname' => $this->group->nickname)); } } + +class GroupMemberList extends ProfileList { + + var $group = null; + + function __construct($profile, $group=null, $action=null) + { + parent::__construct($profile, $action); + + $this->group = $group; + } +} diff --git a/actions/showgroup.php b/actions/showgroup.php index 29b6fa1e6..3ce45adc6 100644 --- a/actions/showgroup.php +++ b/actions/showgroup.php @@ -344,7 +344,7 @@ class ShowgroupAction extends Action $this->element('h2', null, _('Members')); - $pml = new ProfileMiniList($member, null, $this); + $pml = new ProfileMiniList($member, $this); $cnt = $pml->show(); if ($cnt == 0) { $this->element('p', null, _('(None)')); diff --git a/actions/subscribers.php b/actions/subscribers.php index 4482de9a7..66ac00fb1 100644 --- a/actions/subscribers.php +++ b/actions/subscribers.php @@ -130,18 +130,34 @@ class SubscribersAction extends GalleryAction } } -class SubscribersList extends ProfileList +class SubscribersList extends SubscriptionList { - function showBlockForm() + function newListItem($profile) { - $bf = new BlockForm($this->out, $this->profile, - array('action' => 'subscribers', - 'nickname' => $this->owner->nickname)); - $bf->show(); + return new SubscribersListItem($profile, $this->owner, $this->action); } +} - function isReadOnly($args) +class SubscribersListItem extends SubscriptionListItem +{ + function showActions() { - return true; + $this->startActions(); + $this->showSubscribeButton(); + // Relevant code! + $this->showBlockForm(); + $this->endActions(); + } + + function showBlockForm() + { + $user = common_current_user(); + + if (!empty($user) && $this->owner->id == $user->id) { + $bf = new BlockForm($this->out, $this->profile, + array('action' => 'subscribers', + 'nickname' => $this->owner->nickname)); + $bf->show(); + } } } diff --git a/actions/subscriptions.php b/actions/subscriptions.php index 095b18ad8..4124abea4 100644 --- a/actions/subscriptions.php +++ b/actions/subscriptions.php @@ -137,22 +137,46 @@ class SubscriptionsAction extends GalleryAction } } -class SubscriptionsList extends ProfileList +// XXX SubscriptionsList and SubscriptionList are dangerously close + +class SubscriptionsList extends SubscriptionList { - function showOwnerControls($profile) + function newListItem($profile) + { + return new SubscriptionsListItem($profile, $this->owner, $this->action); + } +} + +class SubscriptionsListItem extends SubscriptionListItem +{ + function showProfile() + { + $this->startProfile(); + $this->showAvatar(); + $this->showFullName(); + $this->showLocation(); + $this->showHomepage(); + $this->showBio(); + $this->showTags(); + // Relevant portion! + $this->showOwnerControls(); + $this->endProfile(); + } + + function showOwnerControls() { $sub = Subscription::pkeyGet(array('subscriber' => $this->owner->id, - 'subscribed' => $profile->id)); + 'subscribed' => $this->profile->id)); if (!$sub) { return; } - $this->out->elementStart('form', array('id' => 'subedit-' . $profile->id, + $this->out->elementStart('form', array('id' => 'subedit-' . $this->profile->id, 'method' => 'post', 'class' => 'form_subscription_edit', 'action' => common_local_url('subedit'))); $this->out->hidden('token', common_session_token()); - $this->out->hidden('profile', $profile->id); + $this->out->hidden('profile', $this->profile->id); $this->out->checkbox('jabber', _('Jabber'), $sub->jabber); $this->out->checkbox('sms', _('SMS'), $sub->sms); $this->out->submit('save', _('Save')); diff --git a/db/laconica.sql b/db/laconica.sql index 3ffe1ed81..bc824fc4d 100644 --- a/db/laconica.sql +++ b/db/laconica.sql @@ -427,49 +427,50 @@ create table group_inbox ( create table file ( id integer primary key auto_increment, - url varchar(255), mimetype varchar(50), - size integer, - title varchar(255), - date integer(11), - protected integer(1), + url varchar(255) comment 'destination URL after following redirections', + mimetype varchar(50) comment 'mime type of resource', + size integer comment 'size of resource when available', + title varchar(255) comment 'title of resource when available', + date integer(11) comment 'date of resource according to http query', + protected integer(1) comment 'true when URL is private (needs login)', unique(url) ) ENGINE=MyISAM CHARACTER SET utf8 COLLATE utf8_general_ci; create table file_oembed ( id integer primary key auto_increment, - file_id integer, - version varchar(20), - type varchar(20), - provider varchar(50), - provider_url varchar(255), - width integer, - height integer, - html text, - title varchar(255), - author_name varchar(50), - author_url varchar(255), - url varchar(255), + file_id integer comment 'oEmbed for that URL/file' references file (id), + version varchar(20) comment 'oEmbed spec. version', + type varchar(20) comment 'oEmbed type: photo, video, link, rich', + provider varchar(50) comment 'name of this oEmbed provider', + provider_url varchar(255) comment 'URL of this oEmbed provider', + width integer comment 'width of oEmbed resource when available', + height integer comment 'height of oEmbed resource when available', + html text comment 'html representation of this oEmbed resource when applicable', + title varchar(255) comment 'title of oEmbed resource when available', + author_name varchar(50) comment 'author name for this oEmbed resource', + author_url varchar(255) comment 'author URL for this oEmbed resource', + url varchar(255) comment 'URL for this oEmbed resource when applicable (photo, link)', unique(file_id) ) ENGINE=MyISAM CHARACTER SET utf8 COLLATE utf8_general_ci; create table file_redirection ( id integer primary key auto_increment, - url varchar(255), - file_id integer, - redirections integer, - httpcode integer, + url varchar(255) comment 'short URL (or any other kind of redirect) for file (id)', + file_id integer comment 'short URL for what URL/file' references file (id), + redirections integer comment 'redirect count', + httpcode integer comment 'HTTP status code (20x, 30x, etc.)', unique(url) ) ENGINE=InnoDB CHARACTER SET utf8 COLLATE utf8_bin; create table file_thumbnail ( id integer primary key auto_increment, - file_id integer, - url varchar(255), - width integer, - height integer, + file_id integer comment 'thumbnail for what URL/file' references file (id), + url varchar(255) comment 'URL of thumbnail', + width integer comment 'width of thumbnail', + height integer comment 'height of thumbnail', unique(file_id), unique(url) @@ -477,8 +478,8 @@ create table file_thumbnail ( create table file_to_post ( id integer primary key auto_increment, - file_id integer, - post_id integer, + file_id integer comment 'id of URL/file' references file (id), + post_id integer comment 'id of the notice it belongs to' references notice (id), unique(file_id, post_id) ) ENGINE=InnoDB CHARACTER SET utf8 COLLATE utf8_bin; @@ -48,13 +48,18 @@ function handleError($error) $logmsg .= " : ". $error->getDebugInfo(); } common_log(LOG_ERR, $logmsg); - $msg = sprintf(_('The database for %s isn\'t responding correctly, '. - 'so the site won\'t work properly. '. - 'The site admins probably know about the problem, '. - 'but you can contact them at %s to make sure. '. - 'Otherwise, wait a few minutes and try again.'), - common_config('site', 'name'), - common_config('site', 'email')); + if ($error instanceof DB_DataObject_Error) { + $msg = sprintf(_('The database for %s isn\'t responding correctly, '. + 'so the site won\'t work properly. '. + 'The site admins probably know about the problem, '. + 'but you can contact them at %s to make sure. '. + 'Otherwise, wait a few minutes and try again.'), + common_config('site', 'name'), + common_config('site', 'email')); + } else { + $msg = _('An important error occured, probably related to email setup. '. + 'Check logfiles for more info..'); + } $dac = new DBErrorAction($msg, 500); $dac->showPage(); @@ -70,7 +75,7 @@ function main() global $user, $action, $config; Snapshot::check(); - + if (!_have_config()) { $msg = sprintf(_("No configuration file found. Try running ". "the installation program first.")); diff --git a/lib/noticelist.php b/lib/noticelist.php index fadc238a4..c312292ab 100644 --- a/lib/noticelist.php +++ b/lib/noticelist.php @@ -206,24 +206,10 @@ class NoticeListItem extends Widget return 'shownotice' !== $this->out->args['action']; } -/* - function attachmentCount($discriminant = true) { - $file_oembed = new File_oembed; - $query = "select count(*) as c from file_oembed join file_to_post on file_oembed.file_id = file_to_post.file_id where post_id=" . $this->notice->id; - $file_oembed->query($query); - $file_oembed->fetch(); - return intval($file_oembed->c); - } -*/ - - function showWithAttachment() { - } - function showNoticeInfo() { $this->out->elementStart('div', 'entry-content'); $this->showNoticeLink(); -// $this->showWithAttachment(); $this->showNoticeSource(); $this->showContext(); $this->out->elementEnd('div'); diff --git a/lib/peoplesearchresults.php b/lib/peoplesearchresults.php index d3f840852..9d9d17299 100644 --- a/lib/peoplesearchresults.php +++ b/lib/peoplesearchresults.php @@ -56,20 +56,25 @@ class PeopleSearchResults extends ProfileList function __construct($profile, $terms, $action) { - parent::__construct($profile, $terms, $action); + parent::__construct($profile, $action); + $this->terms = array_map('preg_quote', array_map('htmlspecialchars', $terms)); + $this->pattern = '/('.implode('|',$terms).')/i'; } - function highlight($text) + function newProfileItem($profile) { - return preg_replace($this->pattern, '<strong>\\1</strong>', htmlspecialchars($text)); + return new PeopleSearchResultItem($profile, $this->action); } +} - function isReadOnly($args) +class PeopleSearchResultItem extends ProfileListItem +{ + function highlight($text) { - return true; + return preg_replace($this->pattern, '<strong>\\1</strong>', htmlspecialchars($text)); } } diff --git a/lib/profileaction.php b/lib/profileaction.php index a3437ff4d..298f34b22 100644 --- a/lib/profileaction.php +++ b/lib/profileaction.php @@ -110,7 +110,7 @@ class ProfileAction extends Action $this->element('h2', null, _('Subscriptions')); if ($profile) { - $pml = new ProfileMiniList($profile, $this->user, $this); + $pml = new ProfileMiniList($profile, $this); $cnt = $pml->show(); if ($cnt == 0) { $this->element('p', null, _('(None)')); @@ -139,7 +139,7 @@ class ProfileAction extends Action $this->element('h2', null, _('Subscribers')); if ($profile) { - $pml = new ProfileMiniList($profile, $this->user, $this); + $pml = new ProfileMiniList($profile, $this); $cnt = $pml->show(); if ($cnt == 0) { $this->element('p', null, _('(None)')); diff --git a/lib/profilelist.php b/lib/profilelist.php index a4cc23555..e2faf10af 100644 --- a/lib/profilelist.php +++ b/lib/profilelist.php @@ -49,23 +49,19 @@ class ProfileList extends Widget { /** Current profile, profile query. */ var $profile = null; - /** Owner of this list */ - var $owner = null; /** Action object using us. */ var $action = null; - function __construct($profile, $owner=null, $action=null) + function __construct($profile, $action=null) { parent::__construct($action); $this->profile = $profile; - $this->owner = $owner; $this->action = $action; } function show() { - $this->out->elementStart('ul', 'profiles'); $cnt = 0; @@ -75,7 +71,8 @@ class ProfileList extends Widget if($cnt > PROFILES_PER_PAGE) { break; } - $this->showProfile(); + $pli = $this->newListItem($this->profile); + $pli->show(); } $this->out->elementEnd('ul'); @@ -83,16 +80,59 @@ class ProfileList extends Widget return $cnt; } - function showProfile() + function newListItem($profile) + { + return new ProfileListItem($this->profile, $this->action); + } +} + +class ProfileListItem extends Widget +{ + /** Current profile. */ + var $profile = null; + /** Action object using us. */ + var $action = null; + + function __construct($profile, $action) + { + parent::__construct($action); + + $this->profile = $profile; + $this->action = $action; + } + + function show() + { + $this->startItem(); + $this->showProfile(); + $this->showActions(); + $this->endItem(); + } + + function startItem() { $this->out->elementStart('li', array('class' => 'profile', 'id' => 'profile-' . $this->profile->id)); + } - $user = common_current_user(); - $is_own = !is_null($user) && isset($this->owner) && ($user->id === $this->owner->id); + function showProfile() + { + $this->startProfile(); + $this->showAvatar(); + $this->showFullName(); + $this->showLocation(); + $this->showHomepage(); + $this->showBio(); + $this->endProfile(); + } + function startProfile() + { $this->out->elementStart('div', 'entity_profile vcard'); + } + function showAvatar() + { $avatar = $this->profile->getAvatar(AVATAR_STREAM_SIZE); $this->out->elementStart('a', array('href' => $this->profile->profileurl, 'class' => 'url')); @@ -108,7 +148,10 @@ class ProfileList extends Widget $this->out->raw($this->highlight($this->profile->nickname)); $this->out->elementEnd('span'); $this->out->elementEnd('a'); + } + function showFullName() + { if (!empty($this->profile->fullname)) { $this->out->elementStart('dl', 'entity_fn'); $this->out->element('dt', null, 'Full name'); @@ -119,6 +162,10 @@ class ProfileList extends Widget $this->out->elementEnd('dd'); $this->out->elementEnd('dl'); } + } + + function showLocation() + { if (!empty($this->profile->location)) { $this->out->elementStart('dl', 'entity_location'); $this->out->element('dt', null, _('Location')); @@ -127,6 +174,10 @@ class ProfileList extends Widget $this->out->elementEnd('dd'); $this->out->elementEnd('dl'); } + } + + function showHomepage() + { if (!empty($this->profile->homepage)) { $this->out->elementStart('dl', 'entity_url'); $this->out->element('dt', null, _('URL')); @@ -138,6 +189,10 @@ class ProfileList extends Widget $this->out->elementEnd('dd'); $this->out->elementEnd('dl'); } + } + + function showBio() + { if (!empty($this->profile->bio)) { $this->out->elementStart('dl', 'entity_note'); $this->out->element('dt', null, _('Note')); @@ -146,57 +201,33 @@ class ProfileList extends Widget $this->out->elementEnd('dd'); $this->out->elementEnd('dl'); } + } - # If we're on a list with an owner (subscriptions or subscribers)... - - if ($this->owner) { - # Get tags - $tags = Profile_tag::getTags($this->owner->id, $this->profile->id); - - $this->out->elementStart('dl', 'entity_tags'); - $this->out->elementStart('dt'); - if ($is_own) { - $this->out->element('a', array('href' => common_local_url('tagother', - array('id' => $this->profile->id))), - _('Tags')); - } else { - $this->out->text(_('Tags')); - } - $this->out->elementEnd('dt'); - $this->out->elementStart('dd'); - if ($tags) { - $this->out->elementStart('ul', 'tags xoxo'); - foreach ($tags as $tag) { - $this->out->elementStart('li'); - $this->out->element('span', 'mark_hash', '#'); - $this->out->element('a', array('rel' => 'tag', - 'href' => common_local_url($this->action->trimmed('action'), - array('nickname' => $this->owner->nickname, - 'tag' => $tag))), - $tag); - $this->out->elementEnd('li'); - } - $this->out->elementEnd('ul'); - } else { - $this->out->text(_('(none)')); - } - $this->out->elementEnd('dd'); - $this->out->elementEnd('dl'); - } - - if ($is_own) { - $this->showOwnerControls($this->profile); - } - + function endProfile() + { $this->out->elementEnd('div'); + } - $this->out->elementStart('div', 'entity_actions'); + function showActions() + { + $this->startActions(); + $this->showSubscribeButton(); + $this->endActions(); + } + function startActions() + { + $this->out->elementStart('div', 'entity_actions'); $this->out->elementStart('ul'); + } + function showSubscribeButton() + { // Is this a logged-in user, looking at someone else's // profile? + $user = common_current_user(); + if (!empty($user) && $this->profile->id != $user->id) { $this->out->elementStart('li', 'entity_subscribe'); if ($user->isSubscribed($this->profile)) { @@ -207,33 +238,22 @@ class ProfileList extends Widget $sf->show(); } $this->out->elementEnd('li'); - $this->out->elementStart('li', 'entity_block'); - if ($user->id == $this->owner->id) { - $this->showBlockForm(); - } - $this->out->elementEnd('li'); } + } + function endActions() + { $this->out->elementEnd('ul'); - $this->out->elementEnd('div'); - - $this->out->elementEnd('li'); } - /* Override this in subclasses. */ - - function showOwnerControls($profile) + function endItem() { - return; + $this->out->elementEnd('li'); } function highlight($text) { return htmlspecialchars($text); } - - function showBlockForm() - { - } } diff --git a/lib/profileminilist.php b/lib/profileminilist.php index 57496d0e9..f11cae8a5 100644 --- a/lib/profileminilist.php +++ b/lib/profileminilist.php @@ -47,26 +47,15 @@ define('PROFILES_PER_MINILIST', 27); class ProfileMiniList extends ProfileList { - function show() + function newListItem($profile) { - $this->out->elementStart('ul', 'entities users xoxo'); - - $cnt = 0; - - while ($this->profile->fetch()) { - $cnt++; - if($cnt > PROFILES_PER_MINILIST) { - break; - } - $this->showProfile(); - } - - $this->out->elementEnd('ul'); - - return $cnt; + return new ProfileMiniListItem($profile, $this->action); } +} - function showProfile() +class ProfileMiniListItem extends ProfileListItem +{ + function show() { $this->out->elementStart('li', 'vcard'); $this->out->elementStart('a', array('title' => $this->profile->getBestName(), diff --git a/lib/subscriptionlist.php b/lib/subscriptionlist.php new file mode 100644 index 000000000..23da64cca --- /dev/null +++ b/lib/subscriptionlist.php @@ -0,0 +1,131 @@ +<?php + +/** + * Laconica, the distributed open-source microblogging tool + * + * Widget to show a list of profiles + * + * 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 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/profilelist.php'; + +/** + * Widget to show a list of subscriptions + * + * @category Public + * @package Laconica + * @author Zach Copley <zach@controlyourself.ca> + * @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 SubscriptionList extends ProfileList +{ + /** Owner of this list */ + var $owner = null; + + function __construct($profile, $owner=null, $action=null) + { + parent::__construct($profile, $action); + + $this->owner = $owner; + } + + function newListItem($profile) + { + return new SubscriptionListItem($profile, $this->owner, $this->action); + } +} + +class SubscriptionListItem extends ProfileListItem +{ + /** Owner of this list */ + var $owner = null; + + function __construct($profile, $owner, $action) + { + parent::__construct($profile, $action); + + $this->owner = $owner; + } + + function showProfile() + { + $this->startProfile(); + $this->showAvatar(); + $this->showFullName(); + $this->showLocation(); + $this->showHomepage(); + $this->showBio(); + // Relevant portion! + $this->showTags(); + $this->endProfile(); + } + + function isOwn() + { + $user = common_current_user(); + return (!empty($user) && ($this->owner->id == $user->id)); + } + + function showTags() + { + $tags = Profile_tag::getTags($this->owner->id, $this->profile->id); + + $this->out->elementStart('dl', 'entity_tags'); + $this->out->elementStart('dt'); + if ($this->isOwn()) { + $this->out->element('a', array('href' => common_local_url('tagother', + array('id' => $this->profile->id))), + _('Tags')); + } else { + $this->out->text(_('Tags')); + } + $this->out->elementEnd('dt'); + $this->out->elementStart('dd'); + if ($tags) { + $this->out->elementStart('ul', 'tags xoxo'); + foreach ($tags as $tag) { + $this->out->elementStart('li'); + $this->out->element('span', 'mark_hash', '#'); + $this->out->element('a', array('rel' => 'tag', + 'href' => common_local_url($this->action->trimmed('action'), + array('nickname' => $this->owner->nickname, + 'tag' => $tag))), + $tag); + $this->out->elementEnd('li'); + } + $this->out->elementEnd('ul'); + } else { + $this->out->text(_('(none)')); + } + $this->out->elementEnd('dd'); + $this->out->elementEnd('dl'); + } +} |