diff --git a/actions/editgroup.php b/actions/editgroup.php index 35dd25b896..7439b9d030 100644 --- a/actions/editgroup.php +++ b/actions/editgroup.php @@ -159,7 +159,7 @@ class EditgroupAction extends GroupAction function showScripts() { parent::showScripts(); - $this->autofocus('nickname'); + $this->autofocus('newnickname'); } function trySave() @@ -173,7 +173,7 @@ class EditgroupAction extends GroupAction if (Event::handle('StartGroupSaveForm', array($this))) { - $nickname = Nickname::normalize($this->trimmed('nickname')); + $nickname = Nickname::normalize($this->trimmed('newnickname')); $fullname = $this->trimmed('fullname'); $homepage = $this->trimmed('homepage'); $description = $this->trimmed('description'); diff --git a/actions/newgroup.php b/actions/newgroup.php index c54e24ed95..cf3125fd87 100644 --- a/actions/newgroup.php +++ b/actions/newgroup.php @@ -122,7 +122,7 @@ class NewgroupAction extends Action { if (Event::handle('StartGroupSaveForm', array($this))) { try { - $nickname = Nickname::normalize($this->trimmed('nickname')); + $nickname = Nickname::normalize($this->trimmed('newnickname')); } catch (NicknameException $e) { $this->showForm($e->getMessage()); } diff --git a/actions/top.php b/actions/top.php new file mode 100644 index 0000000000..39abe3df26 --- /dev/null +++ b/actions/top.php @@ -0,0 +1,86 @@ +. + * + * @category Top + * @package StatusNet + * @author Evan Prodromou + * @copyright 2010 StatusNet, Inc. + * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0 + * @link http://status.net/ + */ + +if (!defined('STATUSNET')) { + // This check helps protect against security problems; + // your code file can't be executed directly from the web. + exit(1); +} + +/** + * An action to redirect to the top of the site + * + * @category Action + * @package StatusNet + * @author Evan Prodromou + * @copyright 2010 StatusNet, Inc. + * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0 + * @link http://status.net/ + */ + +class TopAction extends Action +{ + /** + * For initializing members of the class. + * + * @param array $argarray misc. arguments + * + * @return boolean true + */ + + function prepare($argarray) + { + parent::prepare($argarray); + return true; + } + + /** + * Handler method + * + * @param array $argarray is ignored since it's now passed in in prepare() + * + * @return void + */ + + function handle($argarray=null) + { + if (common_config('singleuser', 'enabled')) { + $url = common_local_url('showstream', array('nickname' => User::singleUserNickname())); + } else { + $url = common_local_url('public'); + } + + // XXX: Permanent? I think so. + + common_redirect($url, 301); + + return; + } +} diff --git a/actions/usergroups.php b/actions/usergroups.php index 178a3586fd..9d5946b484 100644 --- a/actions/usergroups.php +++ b/actions/usergroups.php @@ -104,7 +104,7 @@ class UsergroupsAction extends ProfileAction return false; } - $this->page = ($this->arg('page')) ? ($this->arg('page')+0) : 1; + $this->page = $this->trimmed('page', 1); return true; } diff --git a/classes/File.php b/classes/File.php index f716a9d64c..80fbdb181c 100644 --- a/classes/File.php +++ b/classes/File.php @@ -85,14 +85,22 @@ class File extends Managed_DataObject * @return File */ function saveNew(array $redir_data, $given_url) { - $x = new File; - $x->url = $given_url; - if (!empty($redir_data['protected'])) $x->protected = $redir_data['protected']; - if (!empty($redir_data['title'])) $x->title = $redir_data['title']; - if (!empty($redir_data['type'])) $x->mimetype = $redir_data['type']; - if (!empty($redir_data['size'])) $x->size = intval($redir_data['size']); - if (isset($redir_data['time']) && $redir_data['time'] > 0) $x->date = intval($redir_data['time']); - $file_id = $x->insert(); + + // I don't know why we have to keep doing this but I'm adding this last check to avoid + // uniqueness bugs. + + $x = File::staticGet('url', $given_url); + + if (empty($x)) { + $x = new File; + $x->url = $given_url; + if (!empty($redir_data['protected'])) $x->protected = $redir_data['protected']; + if (!empty($redir_data['title'])) $x->title = $redir_data['title']; + if (!empty($redir_data['type'])) $x->mimetype = $redir_data['type']; + if (!empty($redir_data['size'])) $x->size = intval($redir_data['size']); + if (isset($redir_data['time']) && $redir_data['time'] > 0) $x->date = intval($redir_data['time']); + $file_id = $x->insert(); + } $x->saveOembed($redir_data, $given_url); return $x; @@ -192,7 +200,7 @@ class File extends Managed_DataObject } if (empty($x)) { - $x = File::staticGet($file_id); + $x = File::staticGet('id', $file_id); if (empty($x)) { // @todo FIXME: This could possibly be a clearer message :) // TRANS: Server exception thrown when... Robin thinks something is impossible! diff --git a/classes/Profile.php b/classes/Profile.php index 938c5357c2..3b3e43025b 100644 --- a/classes/Profile.php +++ b/classes/Profile.php @@ -350,6 +350,10 @@ class Profile extends Managed_DataObject self::cacheSet($keypart, implode(',', $ids)); } + if (!is_null($offset) && !is_null($limit)) { + $ids = array_slice($ids, $offset, $limit); + } + return User_group::multiGet('id', $ids); } diff --git a/doc-src/contact b/doc-src/contact index 75c3aa8364..a713d7c5b9 100644 --- a/doc-src/contact +++ b/doc-src/contact @@ -10,7 +10,7 @@ Post a notice If you have a question about how to do something, just post a notice with your question. People here like to answer messages. Watch the -[public timeline](%%action.public%%) for answers; they'll usually start +[public timeline](%%action.top%%) for answers; they'll usually start with "@" plus your user name. Bugs diff --git a/doc-src/help b/doc-src/help index 92d5d05afa..0e39082ad0 100644 --- a/doc-src/help +++ b/doc-src/help @@ -7,7 +7,7 @@ character) notices which are broadcast to their friends and fans using the Web, RSS, or instant messages. If you'd like to try it out, first [register](%%action.register%%) a new account. -Then, on the [public timeline](%%action.public%%), enter your message into +Then, on the [public timeline](%%action.top%%), enter your message into the textbox at the top of the page, and click "Send". It will go out on the public timeline and to anyone who is subscribed to your notices (probably nobody, at first). diff --git a/doc-src/tos b/doc-src/tos index 8d5bac57fc..e54da049b7 100644 --- a/doc-src/tos +++ b/doc-src/tos @@ -14,7 +14,7 @@ particular, make sure that none of the prohibited items listed below appear in your notice stream or get linked to from your notice stream (things like spam, viruses, or hate content). -You can review our [Public Stream](%%action.public%%) to get a sense +You can review our [Public Stream](%%action.top%%) to get a sense of the types of notices that are welcome on our service (or not!). If you find a %%site.name%% account that you believe violates our terms of service, please check our [Contact](%%doc.contact%%) documentation. diff --git a/lib/framework.php b/lib/framework.php index 642617564c..d68693868d 100644 --- a/lib/framework.php +++ b/lib/framework.php @@ -20,12 +20,12 @@ if (!defined('STATUSNET') && !defined('LACONICA')) { exit(1); } define('STATUSNET_BASE_VERSION', '1.0.0'); -define('STATUSNET_LIFECYCLE', 'rc1'); // 'dev', 'alpha[0-9]+', 'beta[0-9]+', 'rc[0-9]+', 'release' +define('STATUSNET_LIFECYCLE', ''); // 'dev', 'alpha[0-9]+', 'beta[0-9]+', 'rc[0-9]+', 'release' define('STATUSNET_VERSION', STATUSNET_BASE_VERSION . STATUSNET_LIFECYCLE); define('LACONICA_VERSION', STATUSNET_VERSION); // compatibility -define('STATUSNET_CODENAME', 'The Sounds of Science'); +define('STATUSNET_CODENAME', 'It\'s the End of the World as We Know It'); define('AVATAR_PROFILE_SIZE', 96); define('AVATAR_STREAM_SIZE', 48); @@ -151,10 +151,19 @@ function PEAR_ErrorToPEAR_Exception($err) if ($err->getCode() == DB_DATAOBJECT_ERROR_NODATA) { return; } + + $msg = $err->getMessage(); + $userInfo = $err->getUserInfo(); + + // Log this; push the message up as an exception + + common_log(LOG_ERR, "PEAR Error: $msg ($userInfo)"); + if ($err->getCode()) { - throw new PEAR_Exception($err->getMessage(), $err->getCode()); + throw new PEAR_Exception($msg, $err, $err->getCode()); + } else { + throw new PEAR_Exception($msg, $err); } - throw new PEAR_Exception($err->getMessage()); } PEAR::setErrorHandling(PEAR_ERROR_CALLBACK, 'PEAR_ErrorToPEAR_Exception'); diff --git a/lib/groupeditform.php b/lib/groupeditform.php index b795c1387d..e943dcd19a 100644 --- a/lib/groupeditform.php +++ b/lib/groupeditform.php @@ -144,8 +144,8 @@ class GroupEditForm extends Form $this->out->elementStart('li'); $this->out->hidden('groupid', $id); // TRANS: Field label on group edit form. - $this->out->input('nickname', _('Nickname'), - ($this->out->arg('nickname')) ? $this->out->arg('nickname') : $nickname, + $this->out->input('newnickname', _('Nickname'), + ($this->out->arg('newnickname')) ? $this->out->arg('newnickname') : $nickname, // TRANS: Field title on group edit form. _('1-64 lowercase letters or numbers, no punctuation or spaces.')); $this->out->elementEnd('li'); diff --git a/lib/groupprofileblock.php b/lib/groupprofileblock.php index fc0679247b..58e553a4c2 100644 --- a/lib/groupprofileblock.php +++ b/lib/groupprofileblock.php @@ -153,4 +153,23 @@ class GroupProfileBlock extends ProfileBlock } $this->out->elementEnd('div'); } + + function showName() + { + parent::showName(); + $this->showAliases(); + } + + function showAliases() + { + $aliases = $this->group->getAliases(); + + if (!empty($aliases)) { + $this->out->elementStart('ul', 'group_aliases'); + foreach ($aliases as $alias) { + $this->out->element('li', 'group_alias', $alias); + } + $this->out->elementEnd('ul'); + } + } } diff --git a/lib/profileaction.php b/lib/profileaction.php index eaf515e04a..1bc1494557 100644 --- a/lib/profileaction.php +++ b/lib/profileaction.php @@ -259,7 +259,7 @@ class ProfileAction extends Action // TRANS: H2 text for user group membership statistics. $this->statsSectionLink('usergroups', _('Groups')); $this->text(' '); - $this->text($this->profile->getGroups()->N); + $this->text($this->profile->getGroups(0, null)->N); $this->elementEnd('h2'); if ($groups) { diff --git a/lib/profileblock.php b/lib/profileblock.php index 4e5539496a..1162b78422 100644 --- a/lib/profileblock.php +++ b/lib/profileblock.php @@ -125,7 +125,10 @@ abstract class ProfileBlock extends Widget $homepage = $this->homepage(); if (!empty($homepage)) { - $this->out->element('a', 'profile_block_homepage', $homepage); + $this->out->element('a', + array('href' => $homepage, + 'class' => 'profile_block_homepage'), + $homepage); } } diff --git a/lib/profileminilist.php b/lib/profileminilist.php index 2c3fc4642d..7418c89232 100644 --- a/lib/profileminilist.php +++ b/lib/profileminilist.php @@ -47,6 +47,7 @@ define('PROFILES_PER_MINILIST', 8); class ProfileMiniList extends ProfileList { + const MAX_PROFILES = PROFILES_PER_MINILIST; // put it in the class function startList() { diff --git a/lib/router.php b/lib/router.php index 09121c561c..25c436ac92 100644 --- a/lib/router.php +++ b/lib/router.php @@ -156,6 +156,7 @@ class Router 'backupaccount', 'deleteaccount', 'restoreaccount', + 'top', ); foreach ($main as $a) { @@ -334,6 +335,10 @@ class Router array('action' => 'showgroup'), array('nickname' => Nickname::DISPLAY_FMT)); + $m->connect('group/:nickname/', + array('action' => 'showgroup'), + array('nickname' => Nickname::DISPLAY_FMT)); + $m->connect('group/', array('action' => 'groups')); $m->connect('group', array('action' => 'groups')); $m->connect('groups/', array('action' => 'groups')); @@ -1068,6 +1073,10 @@ class Router $m->connect(':nickname', array('action' => 'showstream'), array('nickname' => Nickname::DISPLAY_FMT)); + + $m->connect(':nickname/', + array('action' => 'showstream'), + array('nickname' => Nickname::DISPLAY_FMT)); } // AtomPub API diff --git a/lib/threadednoticelist.php b/lib/threadednoticelist.php index dbf3de642d..f0854767d6 100644 --- a/lib/threadednoticelist.php +++ b/lib/threadednoticelist.php @@ -569,17 +569,35 @@ class ThreadedNoticeListRepeatsItem extends NoticeListActorsItem return $profiles; } + function magicList($items) + { + if (count($items) > 4) { + return parent::magicList(array_slice($items, 0, 3)); + } else { + return parent::magicList($items); + } + } + function getListMessage($count, $you) { if ($count == 1 && $you) { // darn first person being different from third person! // TRANS: List message for notice repeated by logged in user. - return _m('REPEATLIST', 'You have repeated this notice.'); + return _m('REPEATLIST', 'You repeated this.'); + } else if ($count > 4) { + // TRANS: List message for when more than 4 people repeat something. + // TRANS: %%s is a list of users liking a notice, %d is the number over 4 that like the notice. + // TRANS: Plural is decided on the total number of users liking the notice (count of %%s + %d). + return sprintf(_m('%%s and %d other repeated this.', + '%%s and %d others repeated this.', + $count - 3), + $count - 3); } else { - // TRANS: List message for repeated notices. - // TRANS: %d is the number of users that have repeated a notice. - return sprintf(_m('One person has repeated this notice.', - '%d people have repeated this notice.', + // TRANS: List message for favoured notices. + // TRANS: %%s is a list of users liking a notice. + // TRANS: Plural is based on the number of of users that have favoured a notice. + return sprintf(_m('%%s repeated this.', + '%%s repeated this.', $count), $count); } diff --git a/plugins/Bookmark/bookmarkforurl.php b/plugins/Bookmark/bookmarkforurl.php index 018bd5c9e4..e4dedf4a48 100644 --- a/plugins/Bookmark/bookmarkforurl.php +++ b/plugins/Bookmark/bookmarkforurl.php @@ -78,7 +78,13 @@ class BookmarkforurlAction extends Action throw new ClientException(_('Invalid URL.'), 400); } - $f = File::processNew($this->url); + $f = File::staticGet('url', $this->url); + + if (empty($url)) { + $f = File::processNew($this->url); + } + + // How about now? if (!empty($f)) { $this->oembed = File_oembed::staticGet('file_id', $f->id); diff --git a/plugins/Bookmark/bookmarklet b/plugins/Bookmark/bookmarklet index fc1f8b9d05..31a0ac4935 100644 --- a/plugins/Bookmark/bookmarklet +++ b/plugins/Bookmark/bookmarklet @@ -6,4 +6,4 @@ A bookmarklet is a small piece of javascript code used as a bookmark. This one w Drag-and-drop the following link to your bookmarks bar or right-click it and add it to your browser favorites to keep it handy. -Bookmark on %%site.name%% +Bookmark on %%site.name%% diff --git a/plugins/Bookmark/bookmarkpopup.php b/plugins/Bookmark/bookmarkpopup.php index 3defe08d30..1400c0a1ea 100644 --- a/plugins/Bookmark/bookmarkpopup.php +++ b/plugins/Bookmark/bookmarkpopup.php @@ -70,7 +70,7 @@ class BookmarkpopupAction extends NewbookmarkAction $this->elementStart('div', array('id' => 'header')); $this->elementStart('address'); $this->element('a', array('class' => 'url', - 'href' => common_local_url('public')), + 'href' => common_local_url('top')), ''); $this->elementEnd('address'); if (common_logged_in()) { diff --git a/plugins/Event/eventlistitem.php b/plugins/Event/eventlistitem.php index 2f0710f01f..b563e228f9 100644 --- a/plugins/Event/eventlistitem.php +++ b/plugins/Event/eventlistitem.php @@ -174,9 +174,8 @@ class EventListItem extends NoticeListItemAdapter foreach ($responses as $response) { $ids[] = $response->profile_id; } - common_debug("IDS = " . implode(',', $ids)); + $ids = array_slice($ids, 0, ProfileMiniList::MAX_PROFILES + 1); $profiles = Profile::pivotGet('id', $ids); - common_debug("Profiles = " . print_r($profiles, true)); $profile = new ArrayWrapper(array_values($profiles)); $minilist = new ProfileMiniList($profile, $out); $minilist->show(); diff --git a/theme/base/css/display.css b/theme/base/css/display.css index 7f96d846c1..d2d07c4cec 100644 --- a/theme/base/css/display.css +++ b/theme/base/css/display.css @@ -1976,6 +1976,12 @@ display:block; width:auto; } +.profile_block .group_aliases .group_alias { + display:inline; + list-style-type: none; + font-style: italic; +} + .profile_block .entity_tags dt { display: inline; margin-right: 3px;