diff --git a/.gitignore b/.gitignore index 1cde3a6254..217622c84d 100644 --- a/.gitignore +++ b/.gitignore @@ -24,4 +24,4 @@ config-*.php good-config.php lac08.log php.log - +.DS_Store diff --git a/EVENTS.txt b/EVENTS.txt index 5d34a9e13b..d989557e64 100644 --- a/EVENTS.txt +++ b/EVENTS.txt @@ -129,6 +129,9 @@ StartSubGroupNav: Showing the subscriptions group nav menu EndSubGroupNav: At the end of the subscriptions group nav menu - $action: the current action +StartInitializeRouter: Before the router instance has been initialized; good place to add routes +- $m: the Net_URL_Mapper that has just been set up + RouterInitialized: After the router instance has been initialized - $m: the Net_URL_Mapper that has just been set up diff --git a/actions/emailsettings.php b/actions/emailsettings.php index 6eff06c0d6..67b991cdc8 100644 --- a/actions/emailsettings.php +++ b/actions/emailsettings.php @@ -326,7 +326,7 @@ class EmailsettingsAction extends AccountSettingsAction $this->showForm(_('Cannot normalize that email address')); return; } - if (!Validate::email($email, true)) { + if (!Validate::email($email, common_config('email', 'check_domain'))) { $this->showForm(_('Not a valid email address')); return; } else if ($user->email == $email) { diff --git a/actions/invite.php b/actions/invite.php index 788130c582..3015202e9e 100644 --- a/actions/invite.php +++ b/actions/invite.php @@ -68,7 +68,7 @@ class InviteAction extends CurrentUserDesignAction foreach ($addresses as $email) { $email = trim($email); - if (!Validate::email($email, true)) { + if (!Validate::email($email, common_config('email', 'check_domain'))) { $this->showForm(sprintf(_('Invalid email address: %s'), $email)); return; } diff --git a/actions/newnotice.php b/actions/newnotice.php index 9ee031f936..fe7df09382 100644 --- a/actions/newnotice.php +++ b/actions/newnotice.php @@ -160,18 +160,12 @@ class NewnoticeAction extends Action if (!$content) { $this->clientError(_('No content!')); - } else { - $content_shortened = common_shorten_links($content); - if (Notice::contentTooLong($content_shortened)) { - $this->clientError(sprintf(_('That\'s too long. '. - 'Max notice size is %d chars.'), - Notice::maxContent())); - } + return; } $inter = new CommandInterpreter(); - $cmd = $inter->handle_command($user, $content_shortened); + $cmd = $inter->handle_command($user, $content); if ($cmd) { if ($this->boolean('ajax')) { @@ -182,6 +176,13 @@ class NewnoticeAction extends Action return; } + $content_shortened = common_shorten_links($content); + if (Notice::contentTooLong($content_shortened)) { + $this->clientError(sprintf(_('That\'s too long. '. + 'Max notice size is %d chars.'), + Notice::maxContent())); + } + $replyto = $this->trimmed('inreplyto'); #If an ID of 0 is wrongly passed here, it will cause a database error, #so override it... diff --git a/actions/register.php b/actions/register.php index 100ab74242..a6c1a903aa 100644 --- a/actions/register.php +++ b/actions/register.php @@ -191,7 +191,7 @@ class RegisterAction extends Action if (!$this->boolean('license')) { $this->showForm(_('You can\'t register if you don\'t '. 'agree to the license.')); - } else if ($email && !Validate::email($email, true)) { + } else if ($email && !Validate::email($email, common_config('email', 'check_domain'))) { $this->showForm(_('Not a valid email address.')); } else if (!Validate::string($nickname, array('min_length' => 1, 'max_length' => 64, diff --git a/classes/Notice.php b/classes/Notice.php index 7478f945da..fdf5cd4c87 100644 --- a/classes/Notice.php +++ b/classes/Notice.php @@ -179,7 +179,7 @@ class Notice extends Memcached_DataObject throw new ClientException(_('Problem saving notice. Too long.')); } - if (!$profile) { + if (empty($profile)) { throw new ClientException(_('Problem saving notice. Unknown user.')); } @@ -296,7 +296,6 @@ class Notice extends Memcached_DataObject // XXX: do we need to change this for remote users? - $notice->saveReplies(); $notice->saveTags(); $notice->addToInboxes(); @@ -334,11 +333,11 @@ class Notice extends Memcached_DataObject static function checkDupes($profile_id, $content) { $profile = Profile::staticGet($profile_id); - if (!$profile) { + if (empty($profile)) { return false; } $notice = $profile->getNotices(0, NOTICE_CACHE_WINDOW); - if ($notice) { + if (!empty($notice)) { $last = 0; while ($notice->fetch()) { if (time() - strtotime($notice->created) >= common_config('site', 'dupelimit')) { @@ -364,7 +363,7 @@ class Notice extends Memcached_DataObject static function checkEditThrottle($profile_id) { $profile = Profile::staticGet($profile_id); - if (!$profile) { + if (empty($profile)) { return false; } # Get the Nth notice @@ -685,7 +684,7 @@ class Notice extends Memcached_DataObject $cache = common_memcache(); - if (!$cache) { + if (empty($cache)) { return Notice::getStreamDirect($qry, $offset, $limit, null, null, $order, null); } @@ -746,7 +745,7 @@ class Notice extends Memcached_DataObject # If there are no hits, just return the value - if (!$notice) { + if (empty($notice)) { return $notice; } @@ -936,6 +935,18 @@ class Notice extends Memcached_DataObject } } + $recipients = $this->saveReplies(); + + foreach ($recipients as $recipient) { + + if (!array_key_exists($recipient, $ni)) { + $recipientUser = User::staticGet('id', $recipient); + if (!empty($recipientUser)) { + $ni[$recipient] = NOTICE_INBOX_SOURCE_REPLY; + } + } + } + $cnt = 0; $qryhdr = 'INSERT INTO notice_inbox (user_id, notice_id, source, created) VALUES '; @@ -1088,12 +1099,12 @@ class Notice extends Memcached_DataObject for ($i=0; $icreated); - if (!$recipient) { + if (empty($recipient)) { continue; } // Don't save replies from blocked profile to local user $recipient_user = User::staticGet('id', $recipient->id); - if ($recipient_user && $recipient_user->hasBlocked($sender)) { + if (!empty($recipient_user) && $recipient_user->hasBlocked($sender)) { continue; } $reply = new Reply(); @@ -1104,7 +1115,7 @@ class Notice extends Memcached_DataObject $last_error = &PEAR::getStaticProperty('DB_DataObject','lastError'); common_log(LOG_ERR, 'DB error inserting reply: ' . $last_error->message); common_server_error(sprintf(_('DB error inserting reply: %s'), $last_error->message)); - return; + return array(); } else { $replied[$recipient->id] = 1; } @@ -1128,7 +1139,7 @@ class Notice extends Memcached_DataObject $id = $reply->insert(); if (!$id) { common_log_db_error($reply, 'INSERT', __FILE__); - return; + return array(); } else { $replied[$recipient->id] = 1; } @@ -1137,12 +1148,16 @@ class Notice extends Memcached_DataObject } } - foreach (array_keys($replied) as $recipient) { + $recipientIds = array_keys($replied); + + foreach ($recipientIds as $recipient) { $user = User::staticGet('id', $recipient); if ($user) { mail_notify_attn($user, $this); } } + + return $recipientIds; } function asAtomEntry($namespace=false, $source=false) diff --git a/classes/User.php b/classes/User.php index b300c9edb6..3fa9cc1526 100644 --- a/classes/User.php +++ b/classes/User.php @@ -328,6 +328,7 @@ class User extends Memcached_DataObject common_config('site', 'name'), $user->nickname), 'system'); + common_broadcast_notice($notice); } } diff --git a/config.php.sample b/config.php.sample index 997c9d6b0b..9fccb84f3b 100644 --- a/config.php.sample +++ b/config.php.sample @@ -104,6 +104,10 @@ $config['sphinx']['port'] = 3312; // $config['site']['timezone'] = 'Pacific/Auckland'; // $config['site']['language'] = 'en_NZ'; +// When validating user supplied email addresses, validate if the domain +// is running an SMTP server. +// $config['mail']['check_domain'] = true; + // Email info, used for all outbound email // $config['mail']['notifyfrom'] = 'microblog@example.net'; // $config['mail']['domain'] = 'microblog.example.net'; diff --git a/lib/command.php b/lib/command.php index 11d40b8e15..9efa406964 100644 --- a/lib/command.php +++ b/lib/command.php @@ -73,7 +73,7 @@ class UntrackCommand extends UnimplementedCommand } } -class NudgeCommand extends UnimplementedCommand +class NudgeCommand extends Command { var $other = null; function __construct($user, $other) @@ -81,6 +81,26 @@ class NudgeCommand extends UnimplementedCommand parent::__construct($user); $this->other = $other; } + function execute($channel) + { + $recipient = User::staticGet('nickname', $this->other); + if(! $recipient){ + $channel->error($this->user, sprintf(_('Could not find a user with nickname %s'), + $this->other)); + }else{ + if ($recipient->id == $this->user->id) { + $channel->error($this->user, _('It does not make a lot of sense to nudge yourself!')); + }else{ + if ($recipient->email && $recipient->emailnotifynudge) { + mail_notify_nudge($this->user, $recipient); + } + // XXX: notify by IM + // XXX: notify by SMS + $channel->output($this->user, sprintf(_('Nudge sent to %s'), + $recipient->nickname)); + } + } + } } class InviteCommand extends UnimplementedCommand @@ -124,18 +144,30 @@ class FavCommand extends Command function execute($channel) { + if(substr($this->other,0,1)=='#'){ + //favoriting a specific notice_id - $recipient = - common_relative_profile($this->user, common_canonical_nickname($this->other)); + $notice = Notice::staticGet(substr($this->other,1)); + if (!$notice) { + $channel->error($this->user, _('Notice with that id does not exist')); + return; + } + $recipient = $notice->getProfile(); + }else{ + //favoriting a given user's last notice - if (!$recipient) { - $channel->error($this->user, _('No such user.')); - return; - } - $notice = $recipient->getCurrentNotice(); - if (!$notice) { - $channel->error($this->user, _('User has no last notice')); - return; + $recipient = + common_relative_profile($this->user, common_canonical_nickname($this->other)); + + if (!$recipient) { + $channel->error($this->user, _('No such user.')); + return; + } + $notice = $recipient->getCurrentNotice(); + if (!$notice) { + $channel->error($this->user, _('User has no last notice')); + return; + } } $fave = Fave::addNew($this->user, $notice); @@ -347,6 +379,71 @@ class MessageCommand extends Command } } +class ReplyCommand extends Command +{ + var $other = null; + var $text = null; + function __construct($user, $other, $text) + { + parent::__construct($user); + $this->other = $other; + $this->text = $text; + } + + function execute($channel) + { + if(substr($this->other,0,1)=='#'){ + //replying to a specific notice_id + + $notice = Notice::staticGet(substr($this->other,1)); + if (!$notice) { + $channel->error($this->user, _('Notice with that id does not exist')); + return; + } + $recipient = $notice->getProfile(); + }else{ + //replying to a given user's last notice + + $recipient = + common_relative_profile($this->user, common_canonical_nickname($this->other)); + + if (!$recipient) { + $channel->error($this->user, _('No such user.')); + return; + } + $notice = $recipient->getCurrentNotice(); + if (!$notice) { + $channel->error($this->user, _('User has no last notice')); + return; + } + } + + $len = mb_strlen($this->text); + + if ($len == 0) { + $channel->error($this->user, _('No content!')); + return; + } + + $this->text = common_shorten_links($this->text); + + if (Notice::contentTooLong($this->text)) { + $channel->error($this->user, sprintf(_('Notice too long - maximum is %d characters, you sent %d'), + Notice::maxContent(), mb_strlen($this->text))); + return; + } + + $notice = Notice::saveNew($this->user->id, $this->text, $channel->source(), 1, + $notice->id); + if ($notice) { + $channel->output($this->user, sprintf(_('Reply to %s sent'), $recipient->nickname)); + } else { + $channel->error($this->user, _('Error saving notice.')); + } + common_broadcast_notice($notice); + } +} + class GetCommand extends Command { @@ -497,6 +594,9 @@ class HelpCommand extends Command "get - get last notice from user\n". "whois - get profile info on user\n". "fav - add user's last notice as a 'fave'\n". + "fav # - add notice with the given id as a 'fave'\n". + "reply # - reply to notice with a given id\n". + "reply - reply to the last notice from user\n". "join - join group\n". "drop - leave group\n". "stats - get your stats\n". @@ -507,7 +607,7 @@ class HelpCommand extends Command "last - same as 'get'\n". "on - not yet implemented.\n". "off - not yet implemented.\n". - "nudge - not yet implemented.\n". + "nudge - remind a user to update.\n". "invite - not yet implemented.\n". "track - not yet implemented.\n". "untrack - not yet implemented.\n". diff --git a/lib/commandinterpreter.php b/lib/commandinterpreter.php index 60fc4c3c44..b921a17cc2 100644 --- a/lib/commandinterpreter.php +++ b/lib/commandinterpreter.php @@ -134,6 +134,17 @@ class CommandInterpreter } else { return new MessageCommand($user, $other, $extra); } + case 'r': + case 'reply': + if (!$arg) { + return null; + } + list($other, $extra) = $this->split_arg($arg); + if (!$extra) { + return null; + } else { + return new ReplyCommand($user, $other, $extra); + } case 'whois': if (!$arg) { return null; diff --git a/lib/default.php b/lib/default.php index c896d54084..7ec8558b07 100644 --- a/lib/default.php +++ b/lib/default.php @@ -84,7 +84,8 @@ $default = 'image' => 'http://i.creativecommons.org/l/by/3.0/80x15.png'), 'mail' => array('backend' => 'mail', - 'params' => null), + 'params' => null, + 'domain_check' => true), 'nickname' => array('blacklist' => array(), 'featured' => array()), diff --git a/lib/jabber.php b/lib/jabber.php index 3dcdce5dbf..73f2ec6605 100644 --- a/lib/jabber.php +++ b/lib/jabber.php @@ -176,6 +176,7 @@ function jabber_format_entry($profile, $notice) $xs = new XMLStringer(); $xs->elementStart('html', array('xmlns' => 'http://jabber.org/protocol/xhtml-im')); $xs->elementStart('body', array('xmlns' => 'http://www.w3.org/1999/xhtml')); + $xs->element("img", array('src'=> $profile->avatarUrl(AVATAR_MINI_SIZE) , 'alt' => $profile->nickname)); $xs->element('a', array('href' => $profile->profileurl), $profile->nickname); $xs->text(": "); @@ -184,6 +185,11 @@ function jabber_format_entry($profile, $notice) } else { $xs->raw(common_render_content($notice->content, $notice)); } + $xs->raw(" "); + $xs->element('a', array( + 'href'=>common_local_url('conversation', + array('id' => $notice->conversation)).'#notice-'.$notice->id + ),sprintf(_('notice id: %s'),$notice->id)); $xs->elementEnd('body'); $xs->elementEnd('html'); diff --git a/lib/router.php b/lib/router.php index 4fb0834fd0..dedf73c865 100644 --- a/lib/router.php +++ b/lib/router.php @@ -71,563 +71,565 @@ class Router { $m = Net_URL_Mapper::getInstance(); - // In the "root" + if (Event::handle('StartInitializeRouter', array(&$m))) { - $m->connect('', array('action' => 'public')); - $m->connect('rss', array('action' => 'publicrss')); - $m->connect('featuredrss', array('action' => 'featuredrss')); - $m->connect('favoritedrss', array('action' => 'favoritedrss')); - $m->connect('opensearch/people', array('action' => 'opensearch', - 'type' => 'people')); - $m->connect('opensearch/notice', array('action' => 'opensearch', - 'type' => 'notice')); + // In the "root" - // docs + $m->connect('', array('action' => 'public')); + $m->connect('rss', array('action' => 'publicrss')); + $m->connect('featuredrss', array('action' => 'featuredrss')); + $m->connect('favoritedrss', array('action' => 'favoritedrss')); + $m->connect('opensearch/people', array('action' => 'opensearch', + 'type' => 'people')); + $m->connect('opensearch/notice', array('action' => 'opensearch', + 'type' => 'notice')); - $m->connect('doc/:title', array('action' => 'doc')); + // docs - // main stuff is repetitive + $m->connect('doc/:title', array('action' => 'doc')); - $main = array('login', 'logout', 'register', 'subscribe', - 'unsubscribe', 'confirmaddress', 'recoverpassword', - 'invite', 'favor', 'disfavor', 'sup', - 'block', 'unblock', 'subedit', - 'groupblock', 'groupunblock'); + // main stuff is repetitive - foreach ($main as $a) { - $m->connect('main/'.$a, array('action' => $a)); - } + $main = array('login', 'logout', 'register', 'subscribe', + 'unsubscribe', 'confirmaddress', 'recoverpassword', + 'invite', 'favor', 'disfavor', 'sup', + 'block', 'unblock', 'subedit', + 'groupblock', 'groupunblock'); - $m->connect('main/sup/:seconds', array('action' => 'sup'), - array('seconds' => '[0-9]+')); + foreach ($main as $a) { + $m->connect('main/'.$a, array('action' => $a)); + } - $m->connect('main/tagother/:id', array('action' => 'tagother')); + $m->connect('main/sup/:seconds', array('action' => 'sup'), + array('seconds' => '[0-9]+')); - $m->connect('main/oembed', - array('action' => 'oembed')); + $m->connect('main/tagother/:id', array('action' => 'tagother')); - // these take a code + $m->connect('main/oembed', + array('action' => 'oembed')); - foreach (array('register', 'confirmaddress', 'recoverpassword') as $c) { - $m->connect('main/'.$c.'/:code', array('action' => $c)); - } + // these take a code - // exceptional + foreach (array('register', 'confirmaddress', 'recoverpassword') as $c) { + $m->connect('main/'.$c.'/:code', array('action' => $c)); + } - $m->connect('main/remote', array('action' => 'remotesubscribe')); - $m->connect('main/remote?nickname=:nickname', array('action' => 'remotesubscribe'), array('nickname' => '[A-Za-z0-9_-]+')); + // exceptional - foreach (Router::$bare as $action) { - $m->connect('index.php?action=' . $action, array('action' => $action)); - } + $m->connect('main/remote', array('action' => 'remotesubscribe')); + $m->connect('main/remote?nickname=:nickname', array('action' => 'remotesubscribe'), array('nickname' => '[A-Za-z0-9_-]+')); - // settings + foreach (Router::$bare as $action) { + $m->connect('index.php?action=' . $action, array('action' => $action)); + } - foreach (array('profile', 'avatar', 'password', 'im', - 'email', 'sms', 'userdesign', 'other') as $s) { - $m->connect('settings/'.$s, array('action' => $s.'settings')); - } + // settings - // search + foreach (array('profile', 'avatar', 'password', 'im', + 'email', 'sms', 'userdesign', 'other') as $s) { + $m->connect('settings/'.$s, array('action' => $s.'settings')); + } - foreach (array('group', 'people', 'notice') as $s) { - $m->connect('search/'.$s, array('action' => $s.'search')); - $m->connect('search/'.$s.'?q=:q', - array('action' => $s.'search'), + // search + + foreach (array('group', 'people', 'notice') as $s) { + $m->connect('search/'.$s, array('action' => $s.'search')); + $m->connect('search/'.$s.'?q=:q', + array('action' => $s.'search'), + array('q' => '.+')); + } + + // The second of these is needed to make the link work correctly + // when inserted into the page. The first is needed to match the + // route on the way in. Seems to be another Net_URL_Mapper bug to me. + $m->connect('search/notice/rss', array('action' => 'noticesearchrss')); + $m->connect('search/notice/rss?q=:q', array('action' => 'noticesearchrss'), array('q' => '.+')); - } - // The second of these is needed to make the link work correctly - // when inserted into the page. The first is needed to match the - // route on the way in. Seems to be another Net_URL_Mapper bug to me. - $m->connect('search/notice/rss', array('action' => 'noticesearchrss')); - $m->connect('search/notice/rss?q=:q', array('action' => 'noticesearchrss'), - array('q' => '.+')); + $m->connect('attachment/:attachment', + array('action' => 'attachment'), + array('attachment' => '[0-9]+')); - $m->connect('attachment/:attachment', - array('action' => 'attachment'), - array('attachment' => '[0-9]+')); + $m->connect('attachment/:attachment/ajax', + array('action' => 'attachment_ajax'), + array('attachment' => '[0-9]+')); - $m->connect('attachment/:attachment/ajax', - array('action' => 'attachment_ajax'), - array('attachment' => '[0-9]+')); + $m->connect('attachment/:attachment/thumbnail', + array('action' => 'attachment_thumbnail'), + array('attachment' => '[0-9]+')); - $m->connect('attachment/:attachment/thumbnail', - array('action' => 'attachment_thumbnail'), - array('attachment' => '[0-9]+')); + $m->connect('notice/new', array('action' => 'newnotice')); + $m->connect('notice/new?replyto=:replyto', + array('action' => 'newnotice'), + array('replyto' => '[A-Za-z0-9_-]+')); + $m->connect('notice/new?replyto=:replyto&inreplyto=:inreplyto', + array('action' => 'newnotice'), + array('replyto' => '[A-Za-z0-9_-]+'), + array('inreplyto' => '[0-9]+')); - $m->connect('notice/new', array('action' => 'newnotice')); - $m->connect('notice/new?replyto=:replyto', - array('action' => 'newnotice'), - array('replyto' => '[A-Za-z0-9_-]+')); - $m->connect('notice/new?replyto=:replyto&inreplyto=:inreplyto', - array('action' => 'newnotice'), - array('replyto' => '[A-Za-z0-9_-]+'), - array('inreplyto' => '[0-9]+')); + $m->connect('notice/:notice/file', + array('action' => 'file'), + array('notice' => '[0-9]+')); - $m->connect('notice/:notice/file', - array('action' => 'file'), - array('notice' => '[0-9]+')); + $m->connect('notice/:notice', + array('action' => 'shownotice'), + array('notice' => '[0-9]+')); + $m->connect('notice/delete', array('action' => 'deletenotice')); + $m->connect('notice/delete/:notice', + array('action' => 'deletenotice'), + array('notice' => '[0-9]+')); - $m->connect('notice/:notice', - array('action' => 'shownotice'), - array('notice' => '[0-9]+')); - $m->connect('notice/delete', array('action' => 'deletenotice')); - $m->connect('notice/delete/:notice', - array('action' => 'deletenotice'), - array('notice' => '[0-9]+')); + // conversation - // conversation + $m->connect('conversation/:id', + array('action' => 'conversation'), + array('id' => '[0-9]+')); - $m->connect('conversation/:id', - array('action' => 'conversation'), - array('id' => '[0-9]+')); + $m->connect('message/new', array('action' => 'newmessage')); + $m->connect('message/new?to=:to', array('action' => 'newmessage'), array('to' => '[A-Za-z0-9_-]+')); + $m->connect('message/:message', + array('action' => 'showmessage'), + array('message' => '[0-9]+')); - $m->connect('message/new', array('action' => 'newmessage')); - $m->connect('message/new?to=:to', array('action' => 'newmessage'), array('to' => '[A-Za-z0-9_-]+')); - $m->connect('message/:message', - array('action' => 'showmessage'), - array('message' => '[0-9]+')); + $m->connect('user/:id', + array('action' => 'userbyid'), + array('id' => '[0-9]+')); - $m->connect('user/:id', - array('action' => 'userbyid'), - array('id' => '[0-9]+')); + $m->connect('tags/', array('action' => 'publictagcloud')); + $m->connect('tag/', array('action' => 'publictagcloud')); + $m->connect('tags', array('action' => 'publictagcloud')); + $m->connect('tag', array('action' => 'publictagcloud')); + $m->connect('tag/:tag/rss', + array('action' => 'tagrss'), + array('tag' => '[a-zA-Z0-9]+')); + $m->connect('tag/:tag', + array('action' => 'tag'), + array('tag' => '[\pL\pN_\-\.]{1,64}')); - $m->connect('tags/', array('action' => 'publictagcloud')); - $m->connect('tag/', array('action' => 'publictagcloud')); - $m->connect('tags', array('action' => 'publictagcloud')); - $m->connect('tag', array('action' => 'publictagcloud')); - $m->connect('tag/:tag/rss', - array('action' => 'tagrss'), - array('tag' => '[a-zA-Z0-9]+')); - $m->connect('tag/:tag', - array('action' => 'tag'), - array('tag' => '[\pL\pN_\-\.]{1,64}')); + $m->connect('peopletag/:tag', + array('action' => 'peopletag'), + array('tag' => '[a-zA-Z0-9]+')); - $m->connect('peopletag/:tag', - array('action' => 'peopletag'), - array('tag' => '[a-zA-Z0-9]+')); + $m->connect('featured/', array('action' => 'featured')); + $m->connect('featured', array('action' => 'featured')); + $m->connect('favorited/', array('action' => 'favorited')); + $m->connect('favorited', array('action' => 'favorited')); - $m->connect('featured/', array('action' => 'featured')); - $m->connect('featured', array('action' => 'featured')); - $m->connect('favorited/', array('action' => 'favorited')); - $m->connect('favorited', array('action' => 'favorited')); + // groups - // groups + $m->connect('group/new', array('action' => 'newgroup')); - $m->connect('group/new', array('action' => 'newgroup')); + foreach (array('edit', 'join', 'leave') as $v) { + $m->connect('group/:nickname/'.$v, + array('action' => $v.'group'), + array('nickname' => '[a-zA-Z0-9]+')); + } - foreach (array('edit', 'join', 'leave') as $v) { - $m->connect('group/:nickname/'.$v, - array('action' => $v.'group'), + foreach (array('members', 'logo', 'rss', 'designsettings') as $n) { + $m->connect('group/:nickname/'.$n, + array('action' => 'group'.$n), + array('nickname' => '[a-zA-Z0-9]+')); + } + + $m->connect('group/:nickname/foaf', + array('action' => 'foafgroup'), array('nickname' => '[a-zA-Z0-9]+')); - } - foreach (array('members', 'logo', 'rss', 'designsettings') as $n) { - $m->connect('group/:nickname/'.$n, - array('action' => 'group'.$n), + $m->connect('group/:nickname/blocked', + array('action' => 'blockedfromgroup'), array('nickname' => '[a-zA-Z0-9]+')); - } - - $m->connect('group/:nickname/foaf', - array('action' => 'foafgroup'), - array('nickname' => '[a-zA-Z0-9]+')); - - $m->connect('group/:nickname/blocked', - array('action' => 'blockedfromgroup'), - array('nickname' => '[a-zA-Z0-9]+')); - - $m->connect('group/:nickname/makeadmin', - array('action' => 'makeadmin'), - array('nickname' => '[a-zA-Z0-9]+')); - - $m->connect('group/:id/id', - array('action' => 'groupbyid'), - array('id' => '[0-9]+')); - - $m->connect('group/:nickname', - array('action' => 'showgroup'), - array('nickname' => '[a-zA-Z0-9]+')); - - $m->connect('group/', array('action' => 'groups')); - $m->connect('group', array('action' => 'groups')); - $m->connect('groups/', array('action' => 'groups')); - $m->connect('groups', array('action' => 'groups')); - - // Twitter-compatible API - - // statuses API - - $m->connect('api/statuses/public_timeline.:format', - array('action' => 'ApiTimelinePublic', - 'format' => '(xml|json|rss|atom)')); - $m->connect('api/statuses/friends_timeline.:format', - array('action' => 'ApiTimelineFriends', - 'format' => '(xml|json|rss|atom)')); + $m->connect('group/:nickname/makeadmin', + array('action' => 'makeadmin'), + array('nickname' => '[a-zA-Z0-9]+')); + + $m->connect('group/:id/id', + array('action' => 'groupbyid'), + array('id' => '[0-9]+')); + + $m->connect('group/:nickname', + array('action' => 'showgroup'), + array('nickname' => '[a-zA-Z0-9]+')); + + $m->connect('group/', array('action' => 'groups')); + $m->connect('group', array('action' => 'groups')); + $m->connect('groups/', array('action' => 'groups')); + $m->connect('groups', array('action' => 'groups')); + + // Twitter-compatible API + + // statuses API + + $m->connect('api/statuses/public_timeline.:format', + array('action' => 'ApiTimelinePublic', + 'format' => '(xml|json|rss|atom)')); + + $m->connect('api/statuses/friends_timeline.:format', + array('action' => 'ApiTimelineFriends', + 'format' => '(xml|json|rss|atom)')); + + $m->connect('api/statuses/friends_timeline/:id.:format', + array('action' => 'ApiTimelineFriends', + 'id' => '[a-zA-Z0-9]+', + 'format' => '(xml|json|rss|atom)')); + $m->connect('api/statuses/home_timeline.:format', + array('action' => 'ApiTimelineFriends', + 'format' => '(xml|json|rss|atom)')); + + $m->connect('api/statuses/home_timeline/:id.:format', + array('action' => 'ApiTimelineFriends', + 'id' => '[a-zA-Z0-9]+', + 'format' => '(xml|json|rss|atom)')); - $m->connect('api/statuses/friends_timeline/:id.:format', - array('action' => 'ApiTimelineFriends', - 'id' => '[a-zA-Z0-9]+', - 'format' => '(xml|json|rss|atom)')); - $m->connect('api/statuses/home_timeline.:format', - array('action' => 'ApiTimelineFriends', - 'format' => '(xml|json|rss|atom)')); + $m->connect('api/statuses/user_timeline.:format', + array('action' => 'ApiTimelineUser', + 'format' => '(xml|json|rss|atom)')); - $m->connect('api/statuses/home_timeline/:id.:format', - array('action' => 'ApiTimelineFriends', - 'id' => '[a-zA-Z0-9]+', - 'format' => '(xml|json|rss|atom)')); - - $m->connect('api/statuses/user_timeline.:format', - array('action' => 'ApiTimelineUser', - 'format' => '(xml|json|rss|atom)')); - - $m->connect('api/statuses/user_timeline/:id.:format', - array('action' => 'ApiTimelineUser', - 'id' => '[a-zA-Z0-9]+', - 'format' => '(xml|json|rss|atom)')); + $m->connect('api/statuses/user_timeline/:id.:format', + array('action' => 'ApiTimelineUser', + 'id' => '[a-zA-Z0-9]+', + 'format' => '(xml|json|rss|atom)')); + + $m->connect('api/statuses/mentions.:format', + array('action' => 'ApiTimelineMentions', + 'format' => '(xml|json|rss|atom)')); + + $m->connect('api/statuses/mentions/:id.:format', + array('action' => 'ApiTimelineMentions', + 'id' => '[a-zA-Z0-9]+', + 'format' => '(xml|json|rss|atom)')); + + $m->connect('api/statuses/replies.:format', + array('action' => 'ApiTimelineMentions', + 'format' => '(xml|json|rss|atom)')); + + $m->connect('api/statuses/replies/:id.:format', + array('action' => 'ApiTimelineMentions', + 'id' => '[a-zA-Z0-9]+', + 'format' => '(xml|json|rss|atom)')); + + $m->connect('api/statuses/friends.:format', + array('action' => 'ApiUserFriends', + 'format' => '(xml|json)')); + + $m->connect('api/statuses/friends/:id.:format', + array('action' => 'ApiUserFriends', + 'id' => '[a-zA-Z0-9]+', + 'format' => '(xml|json)')); - $m->connect('api/statuses/mentions.:format', - array('action' => 'ApiTimelineMentions', - 'format' => '(xml|json|rss|atom)')); + $m->connect('api/statuses/followers.:format', + array('action' => 'ApiUserFollowers', + 'format' => '(xml|json)')); - $m->connect('api/statuses/mentions/:id.:format', - array('action' => 'ApiTimelineMentions', - 'id' => '[a-zA-Z0-9]+', - 'format' => '(xml|json|rss|atom)')); + $m->connect('api/statuses/followers/:id.:format', + array('action' => 'ApiUserFollowers', + 'id' => '[a-zA-Z0-9]+', + 'format' => '(xml|json)')); - $m->connect('api/statuses/replies.:format', - array('action' => 'ApiTimelineMentions', - 'format' => '(xml|json|rss|atom)')); - - $m->connect('api/statuses/replies/:id.:format', - array('action' => 'ApiTimelineMentions', - 'id' => '[a-zA-Z0-9]+', - 'format' => '(xml|json|rss|atom)')); + $m->connect('api/statuses/show.:format', + array('action' => 'ApiStatusesShow', + 'format' => '(xml|json)')); - $m->connect('api/statuses/friends.:format', - array('action' => 'ApiUserFriends', - 'format' => '(xml|json)')); + $m->connect('api/statuses/show/:id.:format', + array('action' => 'ApiStatusesShow', + 'id' => '[0-9]+', + 'format' => '(xml|json)')); - $m->connect('api/statuses/friends/:id.:format', - array('action' => 'ApiUserFriends', - 'id' => '[a-zA-Z0-9]+', - 'format' => '(xml|json)')); - - $m->connect('api/statuses/followers.:format', - array('action' => 'ApiUserFollowers', - 'format' => '(xml|json)')); - - $m->connect('api/statuses/followers/:id.:format', - array('action' => 'ApiUserFollowers', - 'id' => '[a-zA-Z0-9]+', - 'format' => '(xml|json)')); + $m->connect('api/statuses/update.:format', + array('action' => 'ApiStatusesUpdate', + 'format' => '(xml|json)')); - $m->connect('api/statuses/show.:format', - array('action' => 'ApiStatusesShow', - 'format' => '(xml|json)')); + $m->connect('api/statuses/destroy.:format', + array('action' => 'ApiStatusesDestroy', + 'format' => '(xml|json)')); - $m->connect('api/statuses/show/:id.:format', - array('action' => 'ApiStatusesShow', - 'id' => '[0-9]+', - 'format' => '(xml|json)')); + $m->connect('api/statuses/destroy/:id.:format', + array('action' => 'ApiStatusesDestroy', + 'id' => '[0-9]+', + 'format' => '(xml|json)')); - $m->connect('api/statuses/update.:format', - array('action' => 'ApiStatusesUpdate', - 'format' => '(xml|json)')); + // users - $m->connect('api/statuses/destroy.:format', - array('action' => 'ApiStatusesDestroy', - 'format' => '(xml|json)')); + $m->connect('api/users/show/:id.:format', + array('action' => 'ApiUserShow', + 'id' => '[a-zA-Z0-9]+', + 'format' => '(xml|json)')); - $m->connect('api/statuses/destroy/:id.:format', - array('action' => 'ApiStatusesDestroy', - 'id' => '[0-9]+', - 'format' => '(xml|json)')); + $m->connect('api/users/:method', + array('action' => 'api', + 'apiaction' => 'users'), + array('method' => 'show(\.(xml|json))?')); - // users + // direct messages - $m->connect('api/users/show/:id.:format', - array('action' => 'ApiUserShow', - 'id' => '[a-zA-Z0-9]+', - 'format' => '(xml|json)')); + $m->connect('api/direct_messages.:format', + array('action' => 'ApiDirectMessage', + 'format' => '(xml|json|rss|atom)')); - $m->connect('api/users/:method', - array('action' => 'api', - 'apiaction' => 'users'), - array('method' => 'show(\.(xml|json))?')); + $m->connect('api/direct_messages/sent.:format', + array('action' => 'ApiDirectMessage', + 'format' => '(xml|json|rss|atom)', + 'sent' => true)); - // direct messages + $m->connect('api/direct_messages/new.:format', + array('action' => 'ApiDirectMessageNew', + 'format' => '(xml|json)')); + // friendships - $m->connect('api/direct_messages.:format', - array('action' => 'ApiDirectMessage', - 'format' => '(xml|json|rss|atom)')); + $m->connect('api/friendships/show.:format', + array('action' => 'ApiFriendshipsShow', + 'format' => '(xml|json)')); - $m->connect('api/direct_messages/sent.:format', - array('action' => 'ApiDirectMessage', - 'format' => '(xml|json|rss|atom)', - 'sent' => true)); + $m->connect('api/friendships/exists.:format', + array('action' => 'ApiFriendshipsExists', + 'format' => '(xml|json)')); - $m->connect('api/direct_messages/new.:format', - array('action' => 'ApiDirectMessageNew', - 'format' => '(xml|json)')); + $m->connect('api/friendships/create.:format', + array('action' => 'ApiFriendshipsCreate', + 'format' => '(xml|json)')); - // friendships + $m->connect('api/friendships/destroy.:format', + array('action' => 'ApiFriendshipsDestroy', + 'format' => '(xml|json)')); - $m->connect('api/friendships/show.:format', - array('action' => 'ApiFriendshipsShow', - 'format' => '(xml|json)')); + $m->connect('api/friendships/create/:id.:format', + array('action' => 'ApiFriendshipsCreate', + 'id' => '[a-zA-Z0-9]+', + 'format' => '(xml|json)')); - $m->connect('api/friendships/exists.:format', - array('action' => 'ApiFriendshipsExists', - 'format' => '(xml|json)')); + $m->connect('api/friendships/destroy/:id.:format', + array('action' => 'ApiFriendshipsDestroy', + 'id' => '[a-zA-Z0-9]+', + 'format' => '(xml|json)')); - $m->connect('api/friendships/create.:format', - array('action' => 'ApiFriendshipsCreate', - 'format' => '(xml|json)')); + // Social graph - $m->connect('api/friendships/destroy.:format', - array('action' => 'ApiFriendshipsDestroy', - 'format' => '(xml|json)')); + $m->connect('api/friends/ids/:id.:format', + array('action' => 'apiFriends', + 'ids_only' => true)); - $m->connect('api/friendships/create/:id.:format', - array('action' => 'ApiFriendshipsCreate', - 'id' => '[a-zA-Z0-9]+', - 'format' => '(xml|json)')); + $m->connect('api/followers/ids/:id.:format', + array('action' => 'apiFollowers', + 'ids_only' => true)); - $m->connect('api/friendships/destroy/:id.:format', - array('action' => 'ApiFriendshipsDestroy', - 'id' => '[a-zA-Z0-9]+', - 'format' => '(xml|json)')); + $m->connect('api/friends/ids.:format', + array('action' => 'apiFriends', + 'ids_only' => true)); - // Social graph + $m->connect('api/followers/ids.:format', + array('action' => 'apiFollowers', + 'ids_only' => true)); - $m->connect('api/friends/ids/:id.:format', - array('action' => 'apiFriends', - 'ids_only' => true)); + // account - $m->connect('api/followers/ids/:id.:format', - array('action' => 'apiFollowers', - 'ids_only' => true)); + $m->connect('api/account/verify_credentials.:format', + array('action' => 'ApiAccountVerifyCredentials')); - $m->connect('api/friends/ids.:format', - array('action' => 'apiFriends', - 'ids_only' => true)); + // special case where verify_credentials is called w/out a format - $m->connect('api/followers/ids.:format', - array('action' => 'apiFollowers', - 'ids_only' => true)); + $m->connect('api/account/verify_credentials', + array('action' => 'ApiAccountVerifyCredentials')); - // account + $m->connect('api/account/rate_limit_status.:format', + array('action' => 'ApiAccountRateLimitStatus')); - $m->connect('api/account/verify_credentials.:format', - array('action' => 'ApiAccountVerifyCredentials')); + // favorites - // special case where verify_credentials is called w/out a format + $m->connect('api/favorites.:format', + array('action' => 'ApiTimelineFavorites', + 'format' => '(xml|json|rss|atom)')); - $m->connect('api/account/verify_credentials', - array('action' => 'ApiAccountVerifyCredentials')); + $m->connect('api/favorites/:id.:format', + array('action' => 'ApiTimelineFavorites', + 'id' => '[a-zA-Z0-9]+', + 'format' => '(xmljson|rss|atom)')); - $m->connect('api/account/rate_limit_status.:format', - array('action' => 'ApiAccountRateLimitStatus')); + $m->connect('api/favorites/create/:id.:format', + array('action' => 'ApiFavoriteCreate', + 'id' => '[a-zA-Z0-9]+', + 'format' => '(xml|json)')); - // favorites + $m->connect('api/favorites/destroy/:id.:format', + array('action' => 'ApiFavoriteDestroy', + 'id' => '[a-zA-Z0-9]+', + 'format' => '(xml|json)')); - $m->connect('api/favorites.:format', - array('action' => 'ApiTimelineFavorites', - 'format' => '(xml|json|rss|atom)')); + // notifications - $m->connect('api/favorites/:id.:format', - array('action' => 'ApiTimelineFavorites', - 'id' => '[a-zA-Z0-9]+', - 'format' => '(xmljson|rss|atom)')); + $m->connect('api/notifications/:method/:argument', + array('action' => 'api', + 'apiaction' => 'favorites')); - $m->connect('api/favorites/create/:id.:format', - array('action' => 'ApiFavoriteCreate', - 'id' => '[a-zA-Z0-9]+', - 'format' => '(xml|json)')); + // blocks - $m->connect('api/favorites/destroy/:id.:format', - array('action' => 'ApiFavoriteDestroy', - 'id' => '[a-zA-Z0-9]+', - 'format' => '(xml|json)')); + $m->connect('api/blocks/create/:id.:format', + array('action' => 'ApiBlockCreate', + 'id' => '[a-zA-Z0-9]+', + 'format' => '(xml|json)')); - // notifications + $m->connect('api/blocks/destroy/:id.:format', + array('action' => 'ApiBlockDestroy', + 'id' => '[a-zA-Z0-9]+', + 'format' => '(xml|json)')); + // help - $m->connect('api/notifications/:method/:argument', - array('action' => 'api', - 'apiaction' => 'favorites')); + $m->connect('api/help/test.:format', + array('action' => 'ApiHelpTest', + 'format' => '(xml|json)')); - // blocks + // statusnet - $m->connect('api/blocks/create/:id.:format', - array('action' => 'ApiBlockCreate', - 'id' => '[a-zA-Z0-9]+', - 'format' => '(xml|json)')); + $m->connect('api/statusnet/version.:format', + array('action' => 'ApiStatusnetVersion', + 'format' => '(xml|json)')); - $m->connect('api/blocks/destroy/:id.:format', - array('action' => 'ApiBlockDestroy', - 'id' => '[a-zA-Z0-9]+', - 'format' => '(xml|json)')); - // help + $m->connect('api/statusnet/config.:format', + array('action' => 'ApiStatusnetConfig', + 'format' => '(xml|json)')); - $m->connect('api/help/test.:format', - array('action' => 'ApiHelpTest', - 'format' => '(xml|json)')); + // For older methods, we provide "laconica" base action + + $m->connect('api/laconica/version.:format', + array('action' => 'ApiStatusnetVersion', + 'format' => '(xml|json)')); + + $m->connect('api/laconica/config.:format', + array('action' => 'ApiStatusnetConfig', + 'format' => '(xml|json)')); - // statusnet - - $m->connect('api/statusnet/version.:format', - array('action' => 'ApiStatusnetVersion', - 'format' => '(xml|json)')); - - $m->connect('api/statusnet/config.:format', - array('action' => 'ApiStatusnetConfig', - 'format' => '(xml|json)')); - - // For older methods, we provide "laconica" base action - - $m->connect('api/laconica/version.:format', - array('action' => 'ApiStatusnetVersion', - 'format' => '(xml|json)')); - - $m->connect('api/laconica/config.:format', - array('action' => 'ApiStatusnetConfig', - 'format' => '(xml|json)')); - - // Groups and tags are newer than 0.8.1 so no backward-compatibility - // necessary - - // Groups - //'list' has to be handled differently, as php will not allow a method to be named 'list' - - $m->connect('api/statusnet/groups/timeline/:id.:format', - array('action' => 'ApiTimelineGroup', - 'id' => '[a-zA-Z0-9]+', - 'format' => '(xmljson|rss|atom)')); - - $m->connect('api/statusnet/groups/show.:format', - array('action' => 'ApiGroupShow', - 'format' => '(xml|json)')); - - $m->connect('api/statusnet/groups/show/:id.:format', - array('action' => 'ApiGroupShow', - 'id' => '[a-zA-Z0-9]+', - 'format' => '(xml|json)')); - - $m->connect('api/statusnet/groups/join.:format', - array('action' => 'ApiGroupJoin', - 'id' => '[a-zA-Z0-9]+', - 'format' => '(xml|json)')); - - $m->connect('api/statusnet/groups/join/:id.:format', - array('action' => 'ApiGroupJoin', - 'format' => '(xml|json)')); - - $m->connect('api/statusnet/groups/leave.:format', - array('action' => 'ApiGroupLeave', - 'id' => '[a-zA-Z0-9]+', - 'format' => '(xml|json)')); - - $m->connect('api/statusnet/groups/leave/:id.:format', - array('action' => 'ApiGroupLeave', - 'format' => '(xml|json)')); - - $m->connect('api/statusnet/groups/is_member.:format', - array('action' => 'ApiGroupIsMember', - 'format' => '(xml|json)')); - - $m->connect('api/statusnet/groups/list.:format', - array('action' => 'ApiGroupList', - 'format' => '(xml|json|rss|atom)')); - - $m->connect('api/statusnet/groups/list/:id.:format', - array('action' => 'ApiGroupList', - 'id' => '[a-zA-Z0-9]+', - 'format' => '(xml|json|rss|atom)')); - - $m->connect('api/statusnet/groups/list_all.:format', - array('action' => 'ApiGroupListAll', - 'format' => '(xml|json|rss|atom)')); - - $m->connect('api/statusnet/groups/membership.:format', - array('action' => 'ApiGroupMembership', - 'format' => '(xml|json)')); - - $m->connect('api/statusnet/groups/membership/:id.:format', - array('action' => 'ApiGroupMembership', - 'id' => '[a-zA-Z0-9]+', - 'format' => '(xml|json)')); - - $m->connect('api/statusnet/groups/create.:format', - array('action' => 'ApiGroupCreate', - 'format' => '(xml|json)')); - // Tags - $m->connect('api/statusnet/tags/timeline/:tag.:format', - array('action' => 'ApiTimelineTag', - 'format' => '(xmljson|rss|atom)')); - - // search - $m->connect('api/search.atom', array('action' => 'twitapisearchatom')); - $m->connect('api/search.json', array('action' => 'twitapisearchjson')); - $m->connect('api/trends.json', array('action' => 'twitapitrends')); - - // user stuff - - foreach (array('subscriptions', 'subscribers', - 'nudge', 'all', 'foaf', 'xrds', - 'replies', 'inbox', 'outbox', 'microsummary') as $a) { - $m->connect(':nickname/'.$a, - array('action' => $a), + // Groups and tags are newer than 0.8.1 so no backward-compatibility + // necessary + + // Groups + //'list' has to be handled differently, as php will not allow a method to be named 'list' + + $m->connect('api/statusnet/groups/timeline/:id.:format', + array('action' => 'ApiTimelineGroup', + 'id' => '[a-zA-Z0-9]+', + 'format' => '(xmljson|rss|atom)')); + + $m->connect('api/statusnet/groups/show.:format', + array('action' => 'ApiGroupShow', + 'format' => '(xml|json)')); + + $m->connect('api/statusnet/groups/show/:id.:format', + array('action' => 'ApiGroupShow', + 'id' => '[a-zA-Z0-9]+', + 'format' => '(xml|json)')); + + $m->connect('api/statusnet/groups/join.:format', + array('action' => 'ApiGroupJoin', + 'id' => '[a-zA-Z0-9]+', + 'format' => '(xml|json)')); + + $m->connect('api/statusnet/groups/join/:id.:format', + array('action' => 'ApiGroupJoin', + 'format' => '(xml|json)')); + + $m->connect('api/statusnet/groups/leave.:format', + array('action' => 'ApiGroupLeave', + 'id' => '[a-zA-Z0-9]+', + 'format' => '(xml|json)')); + + $m->connect('api/statusnet/groups/leave/:id.:format', + array('action' => 'ApiGroupLeave', + 'format' => '(xml|json)')); + + $m->connect('api/statusnet/groups/is_member.:format', + array('action' => 'ApiGroupIsMember', + 'format' => '(xml|json)')); + + $m->connect('api/statusnet/groups/list.:format', + array('action' => 'ApiGroupList', + 'format' => '(xml|json|rss|atom)')); + + $m->connect('api/statusnet/groups/list/:id.:format', + array('action' => 'ApiGroupList', + 'id' => '[a-zA-Z0-9]+', + 'format' => '(xml|json|rss|atom)')); + + $m->connect('api/statusnet/groups/list_all.:format', + array('action' => 'ApiGroupListAll', + 'format' => '(xml|json|rss|atom)')); + + $m->connect('api/statusnet/groups/membership.:format', + array('action' => 'ApiGroupMembership', + 'format' => '(xml|json)')); + + $m->connect('api/statusnet/groups/membership/:id.:format', + array('action' => 'ApiGroupMembership', + 'id' => '[a-zA-Z0-9]+', + 'format' => '(xml|json)')); + + $m->connect('api/statusnet/groups/create.:format', + array('action' => 'ApiGroupCreate', + 'format' => '(xml|json)')); + // Tags + $m->connect('api/statusnet/tags/timeline/:tag.:format', + array('action' => 'ApiTimelineTag', + 'format' => '(xmljson|rss|atom)')); + + // search + $m->connect('api/search.atom', array('action' => 'twitapisearchatom')); + $m->connect('api/search.json', array('action' => 'twitapisearchjson')); + $m->connect('api/trends.json', array('action' => 'twitapitrends')); + + // user stuff + + foreach (array('subscriptions', 'subscribers', + 'nudge', 'all', 'foaf', 'xrds', + 'replies', 'inbox', 'outbox', 'microsummary') as $a) { + $m->connect(':nickname/'.$a, + array('action' => $a), + array('nickname' => '[a-zA-Z0-9]{1,64}')); + } + + foreach (array('subscriptions', 'subscribers') as $a) { + $m->connect(':nickname/'.$a.'/:tag', + array('action' => $a), + array('tag' => '[a-zA-Z0-9]+', + 'nickname' => '[a-zA-Z0-9]{1,64}')); + } + + foreach (array('rss', 'groups') as $a) { + $m->connect(':nickname/'.$a, + array('action' => 'user'.$a), + array('nickname' => '[a-zA-Z0-9]{1,64}')); + } + + foreach (array('all', 'replies', 'favorites') as $a) { + $m->connect(':nickname/'.$a.'/rss', + array('action' => $a.'rss'), + array('nickname' => '[a-zA-Z0-9]{1,64}')); + } + + $m->connect(':nickname/favorites', + array('action' => 'showfavorites'), array('nickname' => '[a-zA-Z0-9]{1,64}')); - } - foreach (array('subscriptions', 'subscribers') as $a) { - $m->connect(':nickname/'.$a.'/:tag', - array('action' => $a), - array('tag' => '[a-zA-Z0-9]+', + $m->connect(':nickname/avatar/:size', + array('action' => 'avatarbynickname'), + array('size' => '(original|96|48|24)', 'nickname' => '[a-zA-Z0-9]{1,64}')); - } - foreach (array('rss', 'groups') as $a) { - $m->connect(':nickname/'.$a, - array('action' => 'user'.$a), + $m->connect(':nickname/tag/:tag/rss', + array('action' => 'userrss'), + array('nickname' => '[a-zA-Z0-9]{1,64}'), + array('tag' => '[a-zA-Z0-9]+')); + + $m->connect(':nickname/tag/:tag', + array('action' => 'showstream'), + array('nickname' => '[a-zA-Z0-9]{1,64}'), + array('tag' => '[a-zA-Z0-9]+')); + + $m->connect(':nickname', + array('action' => 'showstream'), array('nickname' => '[a-zA-Z0-9]{1,64}')); + + Event::handle('RouterInitialized', array($m)); } - foreach (array('all', 'replies', 'favorites') as $a) { - $m->connect(':nickname/'.$a.'/rss', - array('action' => $a.'rss'), - array('nickname' => '[a-zA-Z0-9]{1,64}')); - } - - $m->connect(':nickname/favorites', - array('action' => 'showfavorites'), - array('nickname' => '[a-zA-Z0-9]{1,64}')); - - $m->connect(':nickname/avatar/:size', - array('action' => 'avatarbynickname'), - array('size' => '(original|96|48|24)', - 'nickname' => '[a-zA-Z0-9]{1,64}')); - - $m->connect(':nickname/tag/:tag/rss', - array('action' => 'userrss'), - array('nickname' => '[a-zA-Z0-9]{1,64}'), - array('tag' => '[a-zA-Z0-9]+')); - - $m->connect(':nickname/tag/:tag', - array('action' => 'showstream'), - array('nickname' => '[a-zA-Z0-9]{1,64}'), - array('tag' => '[a-zA-Z0-9]+')); - - $m->connect(':nickname', - array('action' => 'showstream'), - array('nickname' => '[a-zA-Z0-9]{1,64}')); - - Event::handle('RouterInitialized', array($m)); - return $m; } diff --git a/plugins/Facebook/facebookaction.php b/plugins/Facebook/facebookaction.php index f5ad3d06b4..a10fdf90d4 100644 --- a/plugins/Facebook/facebookaction.php +++ b/plugins/Facebook/facebookaction.php @@ -83,8 +83,8 @@ class FacebookAction extends Action function showStylesheets() { $this->cssLink('css/display.css', 'base'); - $this->cssLink('css/display.css',null,'screen, projection, tv'); - $this->cssLink('css/facebookapp.css', 'base'); + $this->cssLink('css/display.css', null, 'screen, projection, tv'); + $this->cssLink('plugins/Facebook/facebookapp.css'); } function showScripts() diff --git a/theme/base/css/facebookapp.css b/plugins/Facebook/facebookapp.css similarity index 82% rename from theme/base/css/facebookapp.css rename to plugins/Facebook/facebookapp.css index e6b1c9ee53..8cd06f78a8 100644 --- a/theme/base/css/facebookapp.css +++ b/plugins/Facebook/facebookapp.css @@ -5,8 +5,8 @@ font-family:"Lucida Sans Unicode", "Lucida Grande", sans-serif; #wrap { background-color:#F0F2F5; -padding-left:18px; -padding-right:18px; +padding-left:1.795%; +padding-right:1.795%; width:auto; } @@ -15,8 +15,16 @@ h1,h2,h3,h4,h5,h6 { color:#000; } +#header { +width:131%; +} + #content { -width:95%; +width:92.7%; +} + +#aside_primary { +display:none; } #site_nav_local_views a { @@ -26,6 +34,16 @@ background-color:#D0DFE7; background-color:#FAFBFC; } +#form_notice .form_note + label, +#form_notice #notice_data-attach { +display:none; +} + +#form_notice #notice_action-submit { +height:47px !important; +} + + span.facebook-button { border: 2px solid #aaa; padding: 3px; diff --git a/plugins/Facebook/facebookinvite.php b/plugins/Facebook/facebookinvite.php index ecda1717c3..3380b4c857 100644 --- a/plugins/Facebook/facebookinvite.php +++ b/plugins/Facebook/facebookinvite.php @@ -105,6 +105,7 @@ class FacebookinviteAction extends FacebookAction $multi_params = array('showborder' => 'false'); $multi_params['actiontext'] = $actiontext; $multi_params['bypass'] = 'cancel'; + $multi_params['cols'] = 4; // Get a list of users who are already using the app for exclusion $exclude_ids = $this->facebook->api_client->friends_getAppUsers(); diff --git a/plugins/OpenID/OpenIDPlugin.php b/plugins/OpenID/OpenIDPlugin.php index a933a11555..560da71e7b 100644 --- a/plugins/OpenID/OpenIDPlugin.php +++ b/plugins/OpenID/OpenIDPlugin.php @@ -150,11 +150,15 @@ class OpenIDPlugin extends Plugin * @return void */ - function onEndHeadChildren($action) + function onEndShowHeadElements($action) { - // for client side of OpenID authentication - $action->element('meta', array('http-equiv' => 'X-XRDS-Location', - 'content' => common_local_url('publicxrds'))); + if ($action->trimmed('action') == 'public') { + // for client side of OpenID authentication + $action->element('meta', array('http-equiv' => 'X-XRDS-Location', + 'content' => common_local_url('publicxrds'))); + } + + return true; } /** diff --git a/plugins/OpenID/finishopenidlogin.php b/plugins/OpenID/finishopenidlogin.php index 50a9c15c87..ff0b451d30 100644 --- a/plugins/OpenID/finishopenidlogin.php +++ b/plugins/OpenID/finishopenidlogin.php @@ -265,7 +265,7 @@ class FinishopenidloginAction extends Action $fullname = ''; } - if (!empty($sreg['email']) && Validate::email($sreg['email'], true)) { + if (!empty($sreg['email']) && Validate::email($sreg['email'], common_config('email', 'check_domain'))) { $email = $sreg['email']; } else { $email = ''; diff --git a/plugins/OpenID/openid.php b/plugins/OpenID/openid.php index 0944117c00..b76497c28a 100644 --- a/plugins/OpenID/openid.php +++ b/plugins/OpenID/openid.php @@ -241,7 +241,7 @@ function oid_update_user(&$user, &$sreg) $orig_user = clone($user); - if ($sreg['email'] && Validate::email($sreg['email'], true)) { + if ($sreg['email'] && Validate::email($sreg['email'], common_config('email', 'check_domain'))) { $user->email = $sreg['email']; } diff --git a/theme/default/css/display.css b/theme/default/css/display.css index 6833373b45..a5f1fd6e47 100644 --- a/theme/default/css/display.css +++ b/theme/default/css/display.css @@ -18,7 +18,7 @@ font-family: "Lucida Sans Unicode", "Lucida Grande", sans-serif; font-size:1em; } address { -margin-right:5.8%; +margin-right:5.7%; } input, textarea, select, option {