]> git.mxchange.org Git - quix0rs-gnu-social.git/commitdiff
Merge branch 'master' of ../laconica-stable
authorEvan Prodromou <git@evanprodromou.name>
Thu, 8 Jan 2009 21:01:54 +0000 (16:01 -0500)
committerEvan Prodromou <git@evanprodromou.name>
Thu, 8 Jan 2009 21:01:54 +0000 (16:01 -0500)
175 files changed:
.gitignore [new file with mode: 0644]
actions/accesstoken.php
actions/all.php
actions/allrss.php
actions/api.php
actions/avatarbynickname.php
actions/block.php
actions/confirmaddress.php
actions/deletenotice.php
actions/deleteprofile.php
actions/disfavor.php
actions/doc.php
actions/emailsettings.php
actions/facebookhome.php
actions/facebookinvite.php
actions/facebookremove.php
actions/facebooksettings.php
actions/favor.php
actions/favorited.php
actions/favoritesrss.php
actions/featured.php
actions/finishaddopenid.php
actions/finishimmediate.php
actions/finishopenidlogin.php
actions/finishremotesubscribe.php
actions/foaf.php
actions/imsettings.php
actions/inbox.php
actions/invite.php
actions/login.php
actions/logout.php
actions/microsummary.php
actions/newmessage.php
actions/newnotice.php
actions/noticesearch.php
actions/noticesearchrss.php
actions/nudge.php
actions/openidlogin.php
actions/openidsettings.php
actions/opensearch.php
actions/othersettings.php
actions/outbox.php
actions/peoplesearch.php
actions/peopletag.php
actions/postnotice.php
actions/profilesettings.php
actions/public.php
actions/publicrss.php
actions/publicxrds.php
actions/recoverpassword.php
actions/register.php
actions/remotesubscribe.php
actions/replies.php
actions/repliesrss.php
actions/requesttoken.php
actions/showfavorites.php
actions/showmessage.php
actions/shownotice.php
actions/showstream.php
actions/smssettings.php
actions/subedit.php
actions/subscribe.php
actions/subscribers.php
actions/subscriptions.php
actions/sup.php
actions/tag.php
actions/tagother.php
actions/tagrss.php
actions/twitapiaccount.php
actions/twitapiblocks.php
actions/twitapidirect_messages.php
actions/twitapifavorites.php
actions/twitapifriendships.php
actions/twitapihelp.php
actions/twitapilaconica.php [new file with mode: 0644]
actions/twitapinotifications.php
actions/twitapistatuses.php
actions/twitapiusers.php
actions/twittersettings.php
actions/unblock.php
actions/unsubscribe.php
actions/updateprofile.php
actions/userauthorization.php
actions/userbyid.php
actions/userrss.php
actions/xrds.php
avatar/.gitignore [new file with mode: 0644]
classes/Avatar.php
classes/Channel.php
classes/Command.php
classes/CommandInterpreter.php
classes/Confirm_address.php
classes/Consumer.php
classes/Fave.php
classes/Foreign_link.php
classes/Foreign_service.php
classes/Foreign_subscription.php
classes/Foreign_user.php
classes/Invitation.php
classes/Memcached_DataObject.php
classes/Message.php
classes/Nonce.php
classes/Notice.php
classes/NoticeWrapper.php
classes/Notice_inbox.php
classes/Notice_source.php
classes/Notice_tag.php
classes/Profile.php
classes/Profile_block.php
classes/Profile_tag.php
classes/Queue_item.php
classes/Remember_me.php
classes/Remote_profile.php
classes/Reply.php
classes/Sms_carrier.php
classes/Subscription.php
classes/Token.php
classes/User.php
classes/User_openid.php
file/.gitignore [new file with mode: 0644]
htaccess.sample
index.php
js/identica-badge.js [new file with mode: 0644]
js/jcrop/Jcrop.gif [new file with mode: 0644]
js/jcrop/jquery.Jcrop.css [new file with mode: 0644]
js/jcrop/jquery.Jcrop.go.js [new file with mode: 0644]
js/jcrop/jquery.Jcrop.pack.js [new file with mode: 0644]
lib/Shorturl_api.php
lib/action.php
lib/common.php
lib/daemon.php
lib/deleteaction.php
lib/facebookaction.php
lib/facebookutil.php [new file with mode: 0644]
lib/gallery.php
lib/jabber.php
lib/language.php
lib/mail.php
lib/mailbox.php
lib/noticelist.php
lib/oauthstore.php
lib/omb.php
lib/openid.php
lib/personal.php
lib/profilelist.php
lib/queuehandler.php
lib/rssaction.php
lib/search_engines.php
lib/searchaction.php
lib/settingsaction.php
lib/stream.php
lib/subs.php
lib/theme.php
lib/twitter.php
lib/twitterapi.php
lib/util.php
lib/xmppqueuehandler.php
scripts/enjitqueuehandler.php
scripts/fixup_hashtags.php
scripts/fixup_inboxes.php
scripts/fixup_notices_rendered.php
scripts/getpiddir.php
scripts/inbox_users.php
scripts/jabberqueuehandler.php
scripts/maildaemon.php
scripts/ombqueuehandler.php
scripts/publicqueuehandler.php
scripts/sitemap.php
scripts/smsqueuehandler.php
scripts/synctwitterfriends.php
scripts/update_facebook.php [new file with mode: 0755]
scripts/update_translations.php
scripts/xmppconfirmhandler.php
scripts/xmppdaemon.php
theme/default/display.css

diff --git a/.gitignore b/.gitignore
new file mode 100644 (file)
index 0000000..c75c07d
--- /dev/null
@@ -0,0 +1,5 @@
+avatar/*
+files/*
+_darcs/*
+config.php
+.htaccess
index 4907749ce0519dda5a8a6f1f8a38f9e6280caee0..072ce27eb5c5e15d30a4c8c5dd1dfe16f571bf56 100644 (file)
@@ -21,22 +21,24 @@ if (!defined('LACONICA')) { exit(1); }
 
 require_once(INSTALLDIR.'/lib/omb.php');
 
-class AccesstokenAction extends Action {
-       function handle($args) {
-               parent::handle($args);
-               try {
-                       common_debug('getting request from env variables', __FILE__);
-                       common_remove_magic_from_request();
-                       $req = OAuthRequest::from_request();
-                       common_debug('getting a server', __FILE__);
-                       $server = omb_oauth_server();
-                       common_debug('fetching the access token', __FILE__);
-                       $token = $server->fetch_access_token($req);
-                       common_debug('got this token: "'.print_r($token,TRUE).'"', __FILE__);
-                       common_debug('printing the access token', __FILE__);
-                       print $token;
-               } catch (OAuthException $e) {
-                       common_server_error($e->getMessage());
-               }
-       }
+class AccesstokenAction extends Action
+{
+    function handle($args)
+    {
+        parent::handle($args);
+        try {
+            common_debug('getting request from env variables', __FILE__);
+            common_remove_magic_from_request();
+            $req = OAuthRequest::from_request();
+            common_debug('getting a server', __FILE__);
+            $server = omb_oauth_server();
+            common_debug('fetching the access token', __FILE__);
+            $token = $server->fetch_access_token($req);
+            common_debug('got this token: "'.print_r($token,true).'"', __FILE__);
+            common_debug('printing the access token', __FILE__);
+            print $token;
+        } catch (OAuthException $e) {
+            common_server_error($e->getMessage());
+        }
+    }
 }
index 2a26e48d4d3c36543be776a53e93af20beddda42..526ac5f40881257217885ac0b99a68729a164e48 100644 (file)
@@ -21,73 +21,78 @@ if (!defined('LACONICA')) { exit(1); }
 
 require_once(INSTALLDIR.'/actions/showstream.php');
 
-class AllAction extends StreamAction {
+class AllAction extends StreamAction
+{
 
-       function handle($args) {
+    function handle($args)
+    {
 
-               parent::handle($args);
+        parent::handle($args);
 
-               $nickname = common_canonical_nickname($this->arg('nickname'));
-               $user = User::staticGet('nickname', $nickname);
+        $nickname = common_canonical_nickname($this->arg('nickname'));
+        $user = User::staticGet('nickname', $nickname);
 
-               if (!$user) {
-                       $this->client_error(_('No such user.'));
-                       return;
-               }
+        if (!$user) {
+            $this->client_error(_('No such user.'));
+            return;
+        }
 
-               $profile = $user->getProfile();
+        $profile = $user->getProfile();
 
-               if (!$profile) {
-                       common_server_error(_('User has no profile.'));
-                       return;
-               }
+        if (!$profile) {
+            common_server_error(_('User has no profile.'));
+            return;
+        }
 
-               # Looks like we're good; show the header
+        # Looks like we're good; show the header
 
-               common_show_header(sprintf(_("%s and friends"), $profile->nickname),
-                                                  array($this, 'show_header'), $user,
-                                                  array($this, 'show_top'));
+        common_show_header(sprintf(_("%s and friends"), $profile->nickname),
+                           array($this, 'show_header'), $user,
+                           array($this, 'show_top'));
 
-               $this->show_notices($user);
+        $this->show_notices($user);
 
-               common_show_footer();
-       }
+        common_show_footer();
+    }
 
-       function show_header($user) {
-               common_element('link', array('rel' => 'alternate',
-                                                                        'href' => common_local_url('allrss', array('nickname' =>
-                                                                                                                                                          $user->nickname)),
-                                                                        'type' => 'application/rss+xml',
-                                                                        'title' => sprintf(_('Feed for friends of %s'), $user->nickname)));
-       }
+    function show_header($user)
+    {
+        common_element('link', array('rel' => 'alternate',
+                                     'href' => common_local_url('allrss', array('nickname' =>
+                                                                               $user->nickname)),
+                                     'type' => 'application/rss+xml',
+                                     'title' => sprintf(_('Feed for friends of %s'), $user->nickname)));
+    }
 
-       function show_top($user) {
-               $cur = common_current_user();
+    function show_top($user)
+    {
+        $cur = common_current_user();
 
-               if ($cur && $cur->id == $user->id) {
-                       common_notice_form('all');
-               }
+        if ($cur && $cur->id == $user->id) {
+            common_notice_form('all');
+        }
 
-               $this->views_menu();
+        $this->views_menu();
 
-               $this->show_feeds_list(array(0=>array('href'=>common_local_url('allrss', array('nickname' => $user->nickname)),
-                                                                                         'type' => 'rss',
-                                                                                         'version' => 'RSS 1.0',
-                                                                                         'item' => 'allrss')));
-       }
+        $this->show_feeds_list(array(0=>array('href'=>common_local_url('allrss', array('nickname' => $user->nickname)),
+                                              'type' => 'rss',
+                                              'version' => 'RSS 1.0',
+                                              'item' => 'allrss')));
+    }
 
-       function show_notices($user) {
+    function show_notices($user)
+    {
 
-               $page = $this->trimmed('page');
-               if (!$page) {
-                       $page = 1;
-               }
+        $page = $this->trimmed('page');
+        if (!$page) {
+            $page = 1;
+        }
 
-               $notice = $user->noticesWithFriends(($page-1)*NOTICES_PER_PAGE, NOTICES_PER_PAGE + 1);
+        $notice = $user->noticesWithFriends(($page-1)*NOTICES_PER_PAGE, NOTICES_PER_PAGE + 1);
 
         $cnt = $this->show_notice_list($notice);
 
-               common_pagination($page > 1, $cnt > NOTICES_PER_PAGE,
-                                                 $page, 'all', array('nickname' => $user->nickname));
-       }
+        common_pagination($page > 1, $cnt > NOTICES_PER_PAGE,
+                          $page, 'all', array('nickname' => $user->nickname));
+    }
 }
index e49ac55401435d9cd0d4d7e262e0eaac9e58adc2..660afb9e2da095f120b2796185b260e2239cbbbe 100644 (file)
@@ -23,55 +23,60 @@ require_once(INSTALLDIR.'/lib/rssaction.php');
 
 // Formatting of RSS handled by Rss10Action
 
-class AllrssAction extends Rss10Action {
+class AllrssAction extends Rss10Action
+{
 
-       var $user = NULL;
+    var $user = null;
 
-       function init() {
-               $nickname = $this->trimmed('nickname');
-               $this->user = User::staticGet('nickname', $nickname);
+    function init()
+    {
+        $nickname = $this->trimmed('nickname');
+        $this->user = User::staticGet('nickname', $nickname);
 
-               if (!$this->user) {
-                       common_user_error(_('No such user.'));
-                       return false;
-               } else {
-                       return true;
-               }
-       }
+        if (!$this->user) {
+            common_user_error(_('No such user.'));
+            return false;
+        } else {
+            return true;
+        }
+    }
 
-       function get_notices($limit=0) {
+    function get_notices($limit=0)
+    {
 
-               $user = $this->user;
-               
-               $notice = $user->noticesWithFriends(0, $limit);
-                                                                                       
-               while ($notice->fetch()) {
-                       $notices[] = clone($notice);
-               }
+        $user = $this->user;
+        
+        $notice = $user->noticesWithFriends(0, $limit);
+                                            
+        while ($notice->fetch()) {
+            $notices[] = clone($notice);
+        }
 
-               return $notices;
-       }
+        return $notices;
+    }
 
-       function get_channel() {
-               $user = $this->user;
-               $c = array('url' => common_local_url('allrss',
-                                                                                        array('nickname' =>
-                                                                                                  $user->nickname)),
-                                  'title' => sprintf(_('%s and friends'), $user->nickname),
-                                  'link' => common_local_url('all',
-                                                                                        array('nickname' =>
-                                                                                                  $user->nickname)),
-                                  'description' => sprintf(_('Feed for friends of %s'), $user->nickname));
-               return $c;
-       }
+    function get_channel()
+    {
+        $user = $this->user;
+        $c = array('url' => common_local_url('allrss',
+                                             array('nickname' =>
+                                                   $user->nickname)),
+                   'title' => sprintf(_('%s and friends'), $user->nickname),
+                   'link' => common_local_url('all',
+                                             array('nickname' =>
+                                                   $user->nickname)),
+                   'description' => sprintf(_('Feed for friends of %s'), $user->nickname));
+        return $c;
+    }
 
-       function get_image() {
-               $user = $this->user;
-               $profile = $user->getProfile();
-               if (!$profile) {
-                       return NULL;
-               }
-               $avatar = $profile->getAvatar(AVATAR_PROFILE_SIZE);
-               return ($avatar) ? $avatar->url : NULL;
-       }
+    function get_image()
+    {
+        $user = $this->user;
+        $profile = $user->getProfile();
+        if (!$profile) {
+            return null;
+        }
+        $avatar = $profile->getAvatar(AVATAR_PROFILE_SIZE);
+        return ($avatar) ? $avatar->url : null;
+    }
 }
\ No newline at end of file
index 919a515ce9a4f3a359ad9f2d1cd070ae77ce81e0..7a075983158354e53bc2bcc329961954ff639945 100644 (file)
  *
  * 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
+ * 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/>.
+ * along with this program.     If not, see <http://www.gnu.org/licenses/>.
  */
 
 if (!defined('LACONICA')) { exit(1); }
 
-class ApiAction extends Action {
-
-       var $user;
-       var $content_type;
-       var $api_arg;
-       var $api_method;
-       var $api_action;
-
-       function handle($args) {
-               parent::handle($args);
-
-               $this->api_action = $this->arg('apiaction');
-               $method = $this->arg('method');
-               $argument = $this->arg('argument');
-
-               if (isset($argument)) {
-                       $cmdext = explode('.', $argument);
-                       $this->api_arg =  $cmdext[0];
-                       $this->api_method = $method;
-                       $this->content_type = strtolower($cmdext[1]);
-               } else {
-
-                       # Requested format / content-type will be an extension on the method
-                       $cmdext = explode('.', $method);
-                       $this->api_method = $cmdext[0];
-                       $this->content_type = strtolower($cmdext[1]);
-               }
-
-               if ($this->requires_auth()) {
-                       if (!isset($_SERVER['PHP_AUTH_USER'])) {
-
-                               # This header makes basic auth go
-                               header('WWW-Authenticate: Basic realm="Laconica API"');
-
-                               # If the user hits cancel -- bam!
-                               $this->show_basic_auth_error();
-                       } else {
-                               $nickname = $_SERVER['PHP_AUTH_USER'];
-                               $password = $_SERVER['PHP_AUTH_PW'];
-                               $user = common_check_user($nickname, $password);
-
-                               if ($user) {
-                                       $this->user = $user;
-                                       $this->process_command();
-                               } else {
-                                       # basic authentication failed
-                                       $this->show_basic_auth_error();
-                               }
-                       }
-               } else {
-
-                       # Look for the user in the session
-                       if (common_logged_in()) {
-                               $this->user = common_current_user();
-                       }
-
-                       $this->process_command();
-               }
-       }
-
-       function process_command() {
-               $action = "twitapi$this->api_action";
-               $actionfile = INSTALLDIR."/actions/$action.php";
-
-               if (file_exists($actionfile)) {
-                       require_once($actionfile);
-                       $action_class = ucfirst($action)."Action";
-                       $action_obj = new $action_class();
+class ApiAction extends Action
+{
+
+    var $user;
+    var $content_type;
+    var $api_arg;
+    var $api_method;
+    var $api_action;
+
+    function handle($args)
+    {
+        parent::handle($args);
+
+        $this->api_action = $this->arg('apiaction');
+        $method = $this->arg('method');
+        $argument = $this->arg('argument');
+
+        if (isset($argument)) {
+            $cmdext = explode('.', $argument);
+            $this->api_arg =  $cmdext[0];
+            $this->api_method = $method;
+            $this->content_type = strtolower($cmdext[1]);
+        } else {
+
+            # Requested format / content-type will be an extension on the method
+            $cmdext = explode('.', $method);
+            $this->api_method = $cmdext[0];
+            $this->content_type = strtolower($cmdext[1]);
+        }
+
+        if ($this->requires_auth()) {
+            if (!isset($_SERVER['PHP_AUTH_USER'])) {
+
+                # This header makes basic auth go
+                header('WWW-Authenticate: Basic realm="Laconica API"');
+
+                # If the user hits cancel -- bam!
+                $this->show_basic_auth_error();
+            } else {
+                $nickname = $_SERVER['PHP_AUTH_USER'];
+                $password = $_SERVER['PHP_AUTH_PW'];
+                $user = common_check_user($nickname, $password);
+
+                if ($user) {
+                    $this->user = $user;
+                    $this->process_command();
+                } else {
+                    # basic authentication failed
+                    $this->show_basic_auth_error();
+                }
+            }
+        } else {
+
+            # Look for the user in the session
+            if (common_logged_in()) {
+                 $this->user = common_current_user();
+            }
+
+            $this->process_command();
+        }
+    }
+
+    function process_command()
+    {
+        $action = "twitapi$this->api_action";
+        $actionfile = INSTALLDIR."/actions/$action.php";
+
+        if (file_exists($actionfile)) {
+            require_once($actionfile);
+            $action_class = ucfirst($action)."Action";
+            $action_obj = new $action_class();
 
             if (!$action_obj->prepare($this->args)) {
                 return;
             }
 
-                       if (method_exists($action_obj, $this->api_method)) {
-                               $apidata = array(       'content-type' => $this->content_type,
-                                                                       'api_method' => $this->api_method,
-                                                                       'api_arg' => $this->api_arg,
-                                                                       'user' => $this->user);
-
-                               call_user_func(array($action_obj, $this->api_method), $_REQUEST, $apidata);
-                       } else {
-                               common_user_error("API method not found!", $code=404);
-                       }
-               } else {
-                       common_user_error("API method not found!", $code=404);
-               }
-       }
-
-       # Whitelist of API methods that don't need authentication
-       function requires_auth() {
-               static $noauth = array( 'statuses/public_timeline',
-                                                               'statuses/show',
-                                                               'users/show',
-                                                               'help/test',
-                                                               'help/downtime_schedule');
-
-               static $bareauth = array('statuses/user_timeline',
-                                                                'statuses/friends',
-                                                                'statuses/followers',
-                                                                'favorites/favorites');
+            if (method_exists($action_obj, $this->api_method)) {
+                $apidata = array(    'content-type' => $this->content_type,
+                                    'api_method' => $this->api_method,
+                                    'api_arg' => $this->api_arg,
+                                    'user' => $this->user);
+
+                call_user_func(array($action_obj, $this->api_method), $_REQUEST, $apidata);
+            } else {
+                common_user_error("API method not found!", $code=404);
+            }
+        } else {
+            common_user_error("API method not found!", $code=404);
+        }
+    }
+
+    # Whitelist of API methods that don't need authentication
+    function requires_auth()
+    {
+        static $noauth = array( 'statuses/public_timeline',
+                                'statuses/show',
+                                'users/show',
+                                'help/test',
+                                'help/downtime_schedule',
+                                'laconica/version',
+                                'laconica/config',
+                                'laconica/wadl');
+
+        static $bareauth = array('statuses/user_timeline',
+                                 'statuses/friends',
+                                 'statuses/followers',
+                                 'favorites/favorites');
 
         # If the site is "private", all API methods need authentication
 
@@ -126,71 +133,73 @@ class ApiAction extends Action {
             return true;
         }
 
-               $fullname = "$this->api_action/$this->api_method";
-
-               if (in_array($fullname, $bareauth)) {
-                       # bareauth: only needs auth if without an argument
-                       if ($this->api_arg) {
-                               return false;
-                       } else {
-                               return true;
-                       }
-               } else if (in_array($fullname, $noauth)) {
-                       # noauth: never needs auth
-                       return false;
-               } else {
-                       # everybody else needs auth
-                       return true;
-               }
-       }
-
-       function show_basic_auth_error() {
-               header('HTTP/1.1 401 Unauthorized');
-               $msg = 'Could not authenticate you.';
-
-               if ($this->content_type == 'xml') {
-                       header('Content-Type: application/xml; charset=utf-8');
-                       common_start_xml();
-                       common_element_start('hash');
-                       common_element('error', NULL, $msg);
-                       common_element('request', NULL, $_SERVER['REQUEST_URI']);
-                       common_element_end('hash');
-                       common_end_xml();
-               } else if ($this->content_type == 'json')  {
-                       header('Content-Type: application/json; charset=utf-8');
-                       $error_array = array('error' => $msg, 'request' => $_SERVER['REQUEST_URI']);
-                       print(json_encode($error_array));
-               } else {
-                       header('Content-type: text/plain');
-                       print "$msg\n";
-               }
-       }
-
-       function is_readonly() {
-               # NOTE: before handle(), can't use $this->arg
-               $apiaction = $_REQUEST['apiaction'];
-               $method = $_REQUEST['method'];
-               list($cmdtext, $fmt) = explode('.', $method);
-
-               static $write_methods = array(
-                       'account' => array('update_location', 'update_delivery_device', 'end_session'),
-                       'blocks' => array('create', 'destroy'),
-                       'direct_messages' => array('create', 'destroy'),
-                       'favorites' => array('create', 'destroy'),
-                       'friendships' => array('create', 'destroy'),
-                       'help' => array(),
-                       'notifications' => array('follow', 'leave'),
-                       'statuses' => array('update', 'destroy'),
-                       'users' => array()
-               );
-
-               if (array_key_exists($apiaction, $write_methods)) {
-                       if (!in_array($cmdtext, $write_methods[$apiaction])) {
-                               return true;
-                       }
-               }
-
-               return false;
-       }
+        $fullname = "$this->api_action/$this->api_method";
+
+        if (in_array($fullname, $bareauth)) {
+            # bareauth: only needs auth if without an argument
+            if ($this->api_arg) {
+                return false;
+            } else {
+                return true;
+            }
+        } else if (in_array($fullname, $noauth)) {
+            # noauth: never needs auth
+            return false;
+        } else {
+            # everybody else needs auth
+            return true;
+        }
+    }
+
+    function show_basic_auth_error()
+    {
+        header('HTTP/1.1 401 Unauthorized');
+        $msg = 'Could not authenticate you.';
+
+        if ($this->content_type == 'xml') {
+            header('Content-Type: application/xml; charset=utf-8');
+            common_start_xml();
+            common_element_start('hash');
+            common_element('error', null, $msg);
+            common_element('request', null, $_SERVER['REQUEST_URI']);
+            common_element_end('hash');
+            common_end_xml();
+        } else if ($this->content_type == 'json')  {
+            header('Content-Type: application/json; charset=utf-8');
+            $error_array = array('error' => $msg, 'request' => $_SERVER['REQUEST_URI']);
+            print(json_encode($error_array));
+        } else {
+            header('Content-type: text/plain');
+            print "$msg\n";
+        }
+    }
+
+    function is_readonly()
+    {
+        # NOTE: before handle(), can't use $this->arg
+        $apiaction = $_REQUEST['apiaction'];
+        $method = $_REQUEST['method'];
+        list($cmdtext, $fmt) = explode('.', $method);
+
+        static $write_methods = array(
+            'account' => array('update_location', 'update_delivery_device', 'end_session'),
+            'blocks' => array('create', 'destroy'),
+            'direct_messages' => array('create', 'destroy'),
+            'favorites' => array('create', 'destroy'),
+            'friendships' => array('create', 'destroy'),
+            'help' => array(),
+            'notifications' => array('follow', 'leave'),
+            'statuses' => array('update', 'destroy'),
+            'users' => array()
+        );
+
+        if (array_key_exists($apiaction, $write_methods)) {
+            if (!in_array($cmdtext, $write_methods[$apiaction])) {
+                return true;
+            }
+        }
+
+        return false;
+    }
 
 }
index b33cababf72072aa0ced1dd4cda4a8c703877636..666f386f66a19ec1373730fb1cb31adae05488e7 100644 (file)
 
 if (!defined('LACONICA')) { exit(1); }
 
-class AvatarbynicknameAction extends Action {
-    function handle($args) {
+class AvatarbynicknameAction extends Action
+{
+    function handle($args)
+    {
         parent::handle($args);
         $nickname = $this->trimmed('nickname');
         if (!$nickname) {
-               $this->client_error(_('No nickname.'));
-                       return;
-               }
-               $size = $this->trimmed('size');
+            $this->client_error(_('No nickname.'));
+            return;
+        }
+        $size = $this->trimmed('size');
         if (!$size) {
-               $this->client_error(_('No size.'));
-                       return;
-               }
-               $size = strtolower($size);
-               if (!in_array($size, array('original', '96', '48', '24'))) {
-               $this->client_error(_('Invalid size.'));
-                       return;
-               }
+            $this->client_error(_('No size.'));
+            return;
+        }
+        $size = strtolower($size);
+        if (!in_array($size, array('original', '96', '48', '24'))) {
+            $this->client_error(_('Invalid size.'));
+            return;
+        }
 
-               $user = User::staticGet('nickname', $nickname);
-               if (!$user) {
-               $this->client_error(_('No such user.'));
-                       return;
-               }
-               $profile = $user->getProfile();
-               if (!$profile) {
-               $this->client_error(_('User has no profile.'));
-                       return;
-               }
-               if ($size == 'original') {
-                       $avatar = $profile->getOriginal();
-               } else {
-                       $avatar = $profile->getAvatar($size+0);
-               }
+        $user = User::staticGet('nickname', $nickname);
+        if (!$user) {
+            $this->client_error(_('No such user.'));
+            return;
+        }
+        $profile = $user->getProfile();
+        if (!$profile) {
+            $this->client_error(_('User has no profile.'));
+            return;
+        }
+        if ($size == 'original') {
+            $avatar = $profile->getOriginal();
+        } else {
+            $avatar = $profile->getAvatar($size+0);
+        }
 
-               if ($avatar) {
-                       $url = $avatar->url;
-               } else {
-                       if ($size == 'original') {
-                               $url = common_default_avatar(AVATAR_PROFILE_SIZE);
-                       } else {
-                               $url = common_default_avatar($size+0);
-                       }
-               }
-               common_redirect($url, 302);
-       }
+        if ($avatar) {
+            $url = $avatar->url;
+        } else {
+            if ($size == 'original') {
+                $url = common_default_avatar(AVATAR_PROFILE_SIZE);
+            } else {
+                $url = common_default_avatar($size+0);
+            }
+        }
+        common_redirect($url, 302);
+    }
 }
index e6d2b7e49e96bc685b8751c6ea454350dc47619c..c1ff7c04462308ef20af2332a268ed2b4b95369b 100644 (file)
 
 if (!defined('LACONICA')) { exit(1); }
 
-class BlockAction extends Action {
+class BlockAction extends Action
+{
 
-    var $profile = NULL;
+    var $profile = null;
 
-    function prepare($args) {
+    function prepare($args)
+    {
 
         parent::prepare($args);
 
@@ -32,12 +34,12 @@ class BlockAction extends Action {
             return false;
         }
 
-               $token = $this->trimmed('token');
+        $token = $this->trimmed('token');
 
-               if (!$token || $token != common_session_token()) {
-                       $this->client_error(_('There was a problem with your session token. Try again, please.'));
-                       return;
-               }
+        if (!$token || $token != common_session_token()) {
+            $this->client_error(_('There was a problem with your session token. Try again, please.'));
+            return;
+        }
 
         $id = $this->trimmed('blockto');
 
@@ -56,7 +58,8 @@ class BlockAction extends Action {
         return true;
     }
 
-    function handle($args) {
+    function handle($args)
+    {
         parent::handle($args);
         if ($_SERVER['REQUEST_METHOD'] == 'POST') {
             if ($this->arg('block')) {
@@ -71,13 +74,14 @@ class BlockAction extends Action {
         }
     }
 
-    function are_you_sure_form() {
+    function are_you_sure_form()
+    {
 
         $id = $this->profile->id;
 
-               common_show_header(_('Block user'));
+        common_show_header(_('Block user'));
 
-        common_element('p', NULL,
+        common_element('p', null,
                        _('Are you sure you want to block this user? '.
                          'Afterwards, they will be unsubscribed from you, '.
                          'unable to subscribe to you in the future, and '.
@@ -109,7 +113,8 @@ class BlockAction extends Action {
         common_show_footer();
     }
 
-    function block_profile() {
+    function block_profile()
+    {
 
         $cur = common_current_user();
 
index 44280e08a7543cf15dc373244042c5a489b63ec0..1d5c53ff2e3319313d9883b2cbc75cfcd0092da3 100644 (file)
 
 if (!defined('LACONICA')) { exit(1); }
 
-class ConfirmaddressAction extends Action {
+class ConfirmaddressAction extends Action
+{
 
-    function handle($args) {
+    function handle($args)
+    {
         parent::handle($args);
         if (!common_logged_in()) {
             common_set_returnto($this->self_url());
@@ -43,44 +45,44 @@ class ConfirmaddressAction extends Action {
             $this->client_error(_('That confirmation code is not for you!'));
             return;
         }
-               $type = $confirm->address_type;
-               if (!in_array($type, array('email', 'jabber', 'sms'))) {
-                       $this->server_error(sprintf(_('Unrecognized address type %s'), $type));
-                       return;
-               }
+        $type = $confirm->address_type;
+        if (!in_array($type, array('email', 'jabber', 'sms'))) {
+            $this->server_error(sprintf(_('Unrecognized address type %s'), $type));
+            return;
+        }
         if ($cur->$type == $confirm->address) {
             $this->client_error(_('That address has already been confirmed.'));
-                       return;
-               }
+            return;
+        }
 
         $cur->query('BEGIN');
 
         $orig_user = clone($cur);
 
-               $cur->$type = $confirm->address;
+        $cur->$type = $confirm->address;
 
-               if ($type == 'sms') {
-                       $cur->carrier = ($confirm->address_extra)+0;
-                       $carrier = Sms_carrier::staticGet($cur->carrier);
-                       $cur->smsemail = $carrier->toEmailAddress($cur->sms);
-               }
+        if ($type == 'sms') {
+            $cur->carrier = ($confirm->address_extra)+0;
+            $carrier = Sms_carrier::staticGet($cur->carrier);
+            $cur->smsemail = $carrier->toEmailAddress($cur->sms);
+        }
 
-               $result = $cur->updateKeys($orig_user);
+        $result = $cur->updateKeys($orig_user);
 
         if (!$result) {
-                       common_log_db_error($cur, 'UPDATE', __FILE__);
+            common_log_db_error($cur, 'UPDATE', __FILE__);
             $this->server_error(_('Couldn\'t update user.'));
             return;
         }
 
-               if ($type == 'email') {
-                   $cur->emailChanged();
-               }
+        if ($type == 'email') {
+            $cur->emailChanged();
+        }
 
         $result = $confirm->delete();
 
         if (!$result) {
-                       common_log_db_error($confirm, 'DELETE', __FILE__);
+            common_log_db_error($confirm, 'DELETE', __FILE__);
             $this->server_error(_('Couldn\'t delete email confirmation.'));
             return;
         }
@@ -88,7 +90,7 @@ class ConfirmaddressAction extends Action {
         $cur->query('COMMIT');
 
         common_show_header(_('Confirm Address'));
-        common_element('p', NULL,
+        common_element('p', null,
                        sprintf(_('The address "%s" has been confirmed for your account.'), $cur->$type));
         common_show_footer();
     }
index 64746283ae5103f18b06823d095412711eeafca4..e9b4b32549b47719a152acc2331b42e39c8eeed5 100644 (file)
@@ -21,81 +21,87 @@ if (!defined('LACONICA')) { exit(1); }
 
 require_once(INSTALLDIR.'/lib/deleteaction.php');
 
-class DeletenoticeAction extends DeleteAction {
-       function handle($args) {
-               parent::handle($args);
-               # XXX: Ajax!
+class DeletenoticeAction extends DeleteAction
+{
+    function handle($args)
+    {
+        parent::handle($args);
+        # XXX: Ajax!
 
-               if ($_SERVER['REQUEST_METHOD'] == 'POST') {
-                       $this->delete_notice();
-               } else if ($_SERVER['REQUEST_METHOD'] == 'GET') {
-                       $this->show_form();
-               }
-       }
+        if ($_SERVER['REQUEST_METHOD'] == 'POST') {
+            $this->delete_notice();
+        } else if ($_SERVER['REQUEST_METHOD'] == 'GET') {
+            $this->show_form();
+        }
+    }
 
-       function get_instructions() {
-               return _('You are about to permanently delete a notice.  Once this is done, it cannot be undone.');
-       }
+    function get_instructions()
+    {
+        return _('You are about to permanently delete a notice.  Once this is done, it cannot be undone.');
+    }
 
-       function get_title() {
-               return _('Delete notice');
-       }
+    function get_title()
+    {
+        return _('Delete notice');
+    }
 
-       function show_form($error=NULL) {
-               $user = common_current_user();
+    function show_form($error=null)
+    {
+        $user = common_current_user();
 
-               common_show_header($this->get_title(), array($this, 'show_header'), $error,
-                                                  array($this, 'show_top'));
-               common_element_start('form', array('id' => 'notice_delete_form',
-                                                                  'method' => 'post',
-                                                                  'action' => common_local_url('deletenotice')));
-               common_hidden('token', common_session_token());
-               common_hidden('notice', $this->trimmed('notice'));
-               common_element_start('p');
-               common_element('span', array('id' => 'confirmation_text'), _('Are you sure you want to delete this notice?'));
+        common_show_header($this->get_title(), array($this, 'show_header'), $error,
+                           array($this, 'show_top'));
+        common_element_start('form', array('id' => 'notice_delete_form',
+                                   'method' => 'post',
+                                   'action' => common_local_url('deletenotice')));
+        common_hidden('token', common_session_token());
+        common_hidden('notice', $this->trimmed('notice'));
+        common_element_start('p');
+        common_element('span', array('id' => 'confirmation_text'), _('Are you sure you want to delete this notice?'));
 
-               common_element('input', array('id' => 'submit_no',
-                                                 'name' => 'submit',
-                                                 'type' => 'submit',
-                                                 'value' => _('No')));
-               common_element('input', array('id' => 'submit_yes',
-                                                 'name' => 'submit',
-                                                 'type' => 'submit',
-                                                 'value' => _('Yes')));
-               common_element_end('p');
-               common_element_end('form');
-               common_show_footer();
-       }
+        common_element('input', array('id' => 'submit_no',
+                          'name' => 'submit',
+                          'type' => 'submit',
+                          'value' => _('No')));
+        common_element('input', array('id' => 'submit_yes',
+                          'name' => 'submit',
+                          'type' => 'submit',
+                          'value' => _('Yes')));
+        common_element_end('p');
+        common_element_end('form');
+        common_show_footer();
+    }
 
-       function delete_notice() {
-               # CSRF protection
-               $token = $this->trimmed('token');
-               if (!$token || $token != common_session_token()) {
-                       $this->show_form(_('There was a problem with your session token. Try again, please.'));
-                       return;
-               }
-               $url = common_get_returnto();
-               $confirmed = $this->trimmed('submit');
-               if ($confirmed == _('Yes')) {
-                       $user = common_current_user();
-                       $notice_id = $this->trimmed('notice');
-                       $notice = Notice::staticGet($notice_id);
-                       $replies = new Reply;
-                       $replies->get('notice_id', $notice_id);
+    function delete_notice()
+    {
+        # CSRF protection
+        $token = $this->trimmed('token');
+        if (!$token || $token != common_session_token()) {
+            $this->show_form(_('There was a problem with your session token. Try again, please.'));
+            return;
+        }
+        $url = common_get_returnto();
+        $confirmed = $this->trimmed('submit');
+        if ($confirmed == _('Yes')) {
+            $user = common_current_user();
+            $notice_id = $this->trimmed('notice');
+            $notice = Notice::staticGet($notice_id);
+            $replies = new Reply;
+            $replies->get('notice_id', $notice_id);
 
-                       common_dequeue_notice($notice);
-                       if (common_config('memcached', 'enabled')) {
-                               $notice->blowSubsCache();
-                       }
-                       $replies->delete();
-                       $notice->delete();
-               } else {
-                       if ($url) {
-                               common_set_returnto(NULL);
-                       } else {
-                               $url = common_local_url('public');
-                       }
-               }
-               common_redirect($url);
-       }
+            common_dequeue_notice($notice);
+            if (common_config('memcached', 'enabled')) {
+                $notice->blowSubsCache();
+            }
+            $replies->delete();
+            $notice->delete();
+        } else {
+            if ($url) {
+                common_set_returnto(null);
+            } else {
+                $url = common_local_url('public');
+            }
+        }
+        common_redirect($url);
+    }
 }
index 418ac998d0671fc5c0d502c596aab3ed41f4ab6f..e12fe131a73aeaba4322d82beeb53bcb2086f550 100644 (file)
 
 if (!defined('LACONICA')) { exit(1); }
 
-class DeleteprofileAction extends Action {
-    function handle($args) {
+class DeleteprofileAction extends Action
+{
+    function handle($args)
+    {
         parent::handle($args);
         $this->server_error(_('Code not yet ready.'));
         return;
@@ -32,101 +34,108 @@ class DeleteprofileAction extends Action {
         }
     }
 
-       function get_instructions() {
-               return _('Export and delete your user information.');
-       }
-
-       function form_header($title, $msg=NULL, $success=false) {
-               common_show_header($title,
-                                  NULL,
-                                  array($msg, $success),
-                                                  array($this, 'show_top'));
-       }
-
-       function show_feeds_list($feeds) {
-               common_element_start('div', array('class' => 'feedsdel'));
-               common_element('p', null, 'Feeds:');
-               common_element_start('ul', array('class' => 'xoxo'));
-
-               foreach ($feeds as $key => $value) {
-                       $this->common_feed_item($feeds[$key]);
-               }
-               common_element_end('ul');
-               common_element_end('div');
-       }
+    function get_instructions()
+    {
+        return _('Export and delete your user information.');
+    }
+
+    function form_header($title, $msg=null, $success=false)
+    {
+        common_show_header($title,
+                           null,
+                           array($msg, $success),
+                           array($this, 'show_top'));
+    }
+
+    function show_feeds_list($feeds)
+    {
+        common_element_start('div', array('class' => 'feedsdel'));
+        common_element('p', null, 'Feeds:');
+        common_element_start('ul', array('class' => 'xoxo'));
+
+        foreach ($feeds as $key => $value) {
+            $this->common_feed_item($feeds[$key]);
+        }
+        common_element_end('ul');
+        common_element_end('div');
+    }
 
     //TODO move to common.php (and retrace its origin)
-       function common_feed_item($feed) {
+    function common_feed_item($feed)
+    {
+        $user = common_current_user();
+        $nickname = $user->nickname;
+
+        switch($feed['item']) {
+            case 'notices': default:
+                $feed_classname = $feed['type'];
+                $feed_mimetype = "application/".$feed['type']."+xml";
+                $feed_title = "$nickname's ".$feed['version']." notice feed";
+                $feed['textContent'] = "RSS";
+                break;
+
+            case 'foaf':
+                $feed_classname = "foaf";
+                $feed_mimetype = "application/".$feed['type']."+xml";
+                $feed_title = "$nickname's FOAF file";
+                $feed['textContent'] = "FOAF";
+                break;
+        }
+        common_element_start('li');
+        common_element('a', array('href' => $feed['href'],
+                                  'class' => $feed_classname,
+                                  'type' => $feed_mimetype,
+                                  'title' => $feed_title),
+                            $feed['textContent']);
+        common_element_end('li');
+    }
+
+    function show_form($msg=null, $success=false)
+    {
+        $this->form_header(_('Delete my account'), $msg, $success);
+        common_element('h2', null, _('Delete my account confirmation'));
+        $this->show_confirm_delete_form();
+        common_show_footer();
+    }
+
+    function show_confirm_delete_form()
+    {
         $user = common_current_user();
-               $nickname = $user->nickname;
-
-               switch($feed['item']) {
-                       case 'notices': default:
-                               $feed_classname = $feed['type'];
-                               $feed_mimetype = "application/".$feed['type']."+xml";
-                               $feed_title = "$nickname's ".$feed['version']." notice feed";
-                               $feed['textContent'] = "RSS";
-                               break;
-
-                       case 'foaf':
-                               $feed_classname = "foaf";
-                               $feed_mimetype = "application/".$feed['type']."+xml";
-                               $feed_title = "$nickname's FOAF file";
-                               $feed['textContent'] = "FOAF";
-                               break;
-               }
-               common_element_start('li');
-               common_element('a', array('href' => $feed['href'],
-                                                                 'class' => $feed_classname,
-                                                                 'type' => $feed_mimetype,
-                                                                 'title' => $feed_title),
-                                                       $feed['textContent']);
-               common_element_end('li');
-       }
-
-       function show_form($msg=NULL, $success=false) {
-               $this->form_header(_('Delete my account'), $msg, $success);
-               common_element('h2', NULL, _('Delete my account confirmation'));
-               $this->show_confirm_delete_form();
-               common_show_footer();
-       }
-
-       function show_confirm_delete_form() {
-               $user = common_current_user();
         $notices = DB_DataObject::factory('notice');
         $notices->profile_id = $user->id;
         $notice_count = (int) $notices->count();
 
-               common_element_start('form', array('method' => 'POST',
-                                                                                  'id' => 'delete',
-                                                                                  'action' =>
-                                                                                  common_local_url('deleteprofile')));
+        common_element_start('form', array('method' => 'POST',
+                                           'id' => 'delete',
+                                           'action' =>
+                                           common_local_url('deleteprofile')));
 
-               common_hidden('token', common_session_token());
+        common_hidden('token', common_session_token());
         common_element('p', null, "Last chance to copy your notices and contacts by saving the two links below before deleting your account. Be careful, this operation cannot be undone.");
 
-               $this->show_feeds_list(array(0=>array('href'=>common_local_url('userrss', array('limit' => $notice_count, 'nickname' => $user->nickname)),
-                                                                                         'type' => 'rss',
-                                                                                         'version' => 'RSS 1.0',
-                                                                                         'item' => 'notices'),
-                                                                        1=>array('href'=>common_local_url('foaf',array('nickname' => $user->nickname)),
-                                                                                         'type' => 'rdf',
-                                                                                         'version' => 'FOAF',
-                                                                                         'item' => 'foaf')));
+        $this->show_feeds_list(array(0=>array('href'=>common_local_url('userrss', array('limit' => $notice_count, 'nickname' => $user->nickname)),
+                                              'type' => 'rss',
+                                              'version' => 'RSS 1.0',
+                                              'item' => 'notices'),
+                                     1=>array('href'=>common_local_url('foaf',array('nickname' => $user->nickname)),
+                                              'type' => 'rdf',
+                                              'version' => 'FOAF',
+                                              'item' => 'foaf')));
 
         common_checkbox('confirmation', _('Check if you are sure you want to delete your account.'));
 
-               common_submit('deleteaccount', _('Delete my account'));
-               common_element_end('form');
+        common_submit('deleteaccount', _('Delete my account'));
+        common_element_end('form');
     }
 
-       function handle_post() {
-               # CSRF protection
-               $token = $this->trimmed('token');
-               if (!$token || $token != common_session_token()) {
-                       $this->show_form(_('There was a problem with your session token. Try again, please.'));
-                       return;
-               }
+    function handle_post()
+    {
+        # CSRF protection
+        $token = $this->trimmed('token');
+        if (!$token || $token != common_session_token()) {
+            $this->show_form(_('There was a problem with your session token. Try again, please.'));
+            return;
+        }
 
         if ($this->arg('deleteaccount') && $this->arg('confirmation')) {
             $this->delete_account();
@@ -134,9 +143,10 @@ class DeleteprofileAction extends Action {
         $this->show_form();
     }
 
-       function delete_account() {
-               $user = common_current_user();
-               assert(!is_null($user)); # should already be checked
+    function delete_account()
+    {
+        $user = common_current_user();
+        assert(!is_null($user)); # should already be checked
 
         // deleted later through the profile
         /*
@@ -213,59 +223,61 @@ class DeleteprofileAction extends Action {
         $n_users_deleted = $user->delete();
 
         // logout and redirect to public
-        common_set_user(NULL);
+        common_set_user(null);
         common_real_login(false); # not logged in
         common_forgetme(); # don't log back in!
         common_redirect(common_local_url('public'));
     }
 
-       function show_top($arr) {
-               $msg = $arr[0];
-               $success = $arr[1];
-               if ($msg) {
-                       $this->message($msg, $success);
-               } else {
-                       $inst = $this->get_instructions();
-                       $output = common_markup_to_html($inst);
-                       common_element_start('div', 'instructions');
-                       common_raw($output);
-                       common_element_end('div');
-               }
-               $this->settings_menu();
-       }
-
-    function settings_menu() {
+    function show_top($arr)
+    {
+        $msg = $arr[0];
+        $success = $arr[1];
+        if ($msg) {
+            $this->message($msg, $success);
+        } else {
+            $inst = $this->get_instructions();
+            $output = common_markup_to_html($inst);
+            common_element_start('div', 'instructions');
+            common_raw($output);
+            common_element_end('div');
+        }
+        $this->settings_menu();
+    }
+
+    function settings_menu()
+    {
         # action => array('prompt', 'title')
-               $menu =
-                 array('profilesettings' =>
-                               array(_('Profile'),
-                                         _('Change your profile settings')),
-                               'emailsettings' =>
-                               array(_('Email'),
-                                         _('Change email handling')),
-                               'openidsettings' =>
-                               array(_('OpenID'),
-                                         _('Add or remove OpenIDs')),
-                               'smssettings' =>
-                               array(_('SMS'),
-                                         _('Updates by SMS')),
-                               'imsettings' =>
-                               array(_('IM'),
-                                         _('Updates by instant messenger (IM)')),
-                               'twittersettings' =>
-                               array(_('Twitter'),
-                                         _('Twitter integration options')),
-                               'othersettings' =>
-                               array(_('Other'),
-                                         _('Other options')));
+        $menu =
+          array('profilesettings' =>
+                array(_('Profile'),
+                      _('Change your profile settings')),
+                'emailsettings' =>
+                array(_('Email'),
+                      _('Change email handling')),
+                'openidsettings' =>
+                array(_('OpenID'),
+                      _('Add or remove OpenIDs')),
+                'smssettings' =>
+                array(_('SMS'),
+                      _('Updates by SMS')),
+                'imsettings' =>
+                array(_('IM'),
+                      _('Updates by instant messenger (IM)')),
+                'twittersettings' =>
+                array(_('Twitter'),
+                      _('Twitter integration options')),
+                'othersettings' =>
+                array(_('Other'),
+                      _('Other options')));
 
         $action = $this->trimmed('action');
         common_element_start('ul', array('id' => 'nav_views'));
         foreach ($menu as $menuaction => $menudesc) {
-                       if ($menuaction == 'imsettings' &&
-                               !common_config('xmpp', 'enabled')) {
-                               continue;
-                       }
+            if ($menuaction == 'imsettings' &&
+                !common_config('xmpp', 'enabled')) {
+                continue;
+            }
             common_menu_item(common_local_url($menuaction),
                     $menudesc[0],
                     $menudesc[1],
index be208f65ab2a3d1abd5c27315070e1fde11fc1e2..74aae86cc716e046aa38102852b9a8a85a60ef78 100644 (file)
 
 if (!defined('LACONICA')) { exit(1); }
 
-class DisfavorAction extends Action {
+class DisfavorAction extends Action
+{
 
-       function handle($args) {
+    function handle($args)
+    {
 
-               parent::handle($args);
+        parent::handle($args);
 
-               if (!common_logged_in()) {
-                       common_user_error(_('Not logged in.'));
-                       return;
-               }
+        if (!common_logged_in()) {
+            common_user_error(_('Not logged in.'));
+            return;
+        }
 
-               $user = common_current_user();
+        $user = common_current_user();
 
-               if ($_SERVER['REQUEST_METHOD'] != 'POST') {
-                       common_redirect(common_local_url('showfavorites', array('nickname' => $user->nickname)));
-                       return;
-               }
+        if ($_SERVER['REQUEST_METHOD'] != 'POST') {
+            common_redirect(common_local_url('showfavorites', array('nickname' => $user->nickname)));
+            return;
+        }
 
-               $id = $this->trimmed('notice');
+        $id = $this->trimmed('notice');
 
-               $notice = Notice::staticGet($id);
+        $notice = Notice::staticGet($id);
 
-               $token = $this->trimmed('token-'.$notice->id);
+        $token = $this->trimmed('token-'.$notice->id);
 
-               if (!$token || $token != common_session_token()) {
-                       $this->client_error(_("There was a problem with your session token. Try again, please."));
-                       return;
-               }
+        if (!$token || $token != common_session_token()) {
+            $this->client_error(_("There was a problem with your session token. Try again, please."));
+            return;
+        }
 
-               $fave = new Fave();
-               $fave->user_id = $this->id;
-               $fave->notice_id = $notice->id;
-               if (!$fave->find(true)) {
-                       $this->client_error(_('This notice is not a favorite!'));
-                       return;
-               }
+        $fave = new Fave();
+        $fave->user_id = $this->id;
+        $fave->notice_id = $notice->id;
+        if (!$fave->find(true)) {
+            $this->client_error(_('This notice is not a favorite!'));
+            return;
+        }
 
-               $result = $fave->delete();
+        $result = $fave->delete();
 
-               if (!$result) {
-                       common_log_db_error($fave, 'DELETE', __FILE__);
-                       $this->server_error(_('Could not delete favorite.'));
-                       return;
-               }
-               
-               $user->blowFavesCache();
+        if (!$result) {
+            common_log_db_error($fave, 'DELETE', __FILE__);
+            $this->server_error(_('Could not delete favorite.'));
+            return;
+        }
+        
+        $user->blowFavesCache();
 
-               if ($this->boolean('ajax')) {
-                       common_start_html('text/xml;charset=utf-8', true);
-                       common_element_start('head');
-                       common_element('title', null, _('Add to favorites'));
-                       common_element_end('head');
-                       common_element_start('body');
-                       common_favor_form($notice);
-                       common_element_end('body');
-                       common_element_end('html');
-               } else {
-                       common_redirect(common_local_url('showfavorites',
-                                                                                        array('nickname' => $user->nickname)));
-               }
-       }
+        if ($this->boolean('ajax')) {
+            common_start_html('text/xml;charset=utf-8', true);
+            common_element_start('head');
+            common_element('title', null, _('Add to favorites'));
+            common_element_end('head');
+            common_element_start('body');
+            common_favor_form($notice);
+            common_element_end('body');
+            common_element_end('html');
+        } else {
+            common_redirect(common_local_url('showfavorites',
+                                             array('nickname' => $user->nickname)));
+        }
+    }
 }
index f3327048f271d09c87496f6e124af37996eadc18..856025e665217fca550aae57013eb6383745b218 100644 (file)
 
 if (!defined('LACONICA')) { exit(1); }
 
-class DocAction extends Action {
+class DocAction extends Action
+{
 
-       function handle($args) {
-               parent::handle($args);
-               $title = $this->trimmed('title');
-               $filename = INSTALLDIR.'/doc/'.$title;
-               if (!file_exists($filename)) {
-                       common_user_error(_('No such document.'));
-                       return;
-               }
-               $c = file_get_contents($filename);
-               $output = common_markup_to_html($c);
-               common_show_header(_(ucfirst($title)));
-               common_raw($output);
-               common_show_footer();
-       }
+    function handle($args)
+    {
+        parent::handle($args);
+        $title = $this->trimmed('title');
+        $filename = INSTALLDIR.'/doc/'.$title;
+        if (!file_exists($filename)) {
+            common_user_error(_('No such document.'));
+            return;
+        }
+        $c = file_get_contents($filename);
+        $output = common_markup_to_html($c);
+        common_show_header(_(ucfirst($title)));
+        common_raw($output);
+        common_show_footer();
+    }
 }
index b35b4d28ee1a28c66b82e46454522c50332e5882..3fa8ce2968b3e48089a1f0d873cd88908b987c53 100644 (file)
@@ -21,310 +21,322 @@ if (!defined('LACONICA')) { exit(1); }
 
 require_once(INSTALLDIR.'/lib/settingsaction.php');
 
-class EmailsettingsAction extends SettingsAction {
-
-       function get_instructions() {
-               return _('Manage how you get email from %%site.name%%.');
-       }
-
-       function show_form($msg=NULL, $success=false) {
-               $user = common_current_user();
-               $this->form_header(_('Email Settings'), $msg, $success);
-               common_element_start('form', array('method' => 'post',
-                                                                                  'id' => 'emailsettings',
-                                                                                  'action' =>
-                                                                                  common_local_url('emailsettings')));
-               common_hidden('token', common_session_token());
-
-               common_element('h2', NULL, _('Address'));
-
-               if ($user->email) {
-                       common_element_start('p');
-                       common_element('span', 'address confirmed', $user->email);
-                       common_element('span', 'input_instructions',
-                                      _('Current confirmed email address.'));
-                       common_hidden('email', $user->email);
-                       common_element_end('p');
-                       common_submit('remove', _('Remove'));
-               } else {
-                       $confirm = $this->get_confirmation();
-                       if ($confirm) {
-                               common_element_start('p');
-                               common_element('span', 'address unconfirmed', $confirm->address);
-                               common_element('span', 'input_instructions',
-                                                          _('Awaiting confirmation on this address. Check your inbox (and spam box!) for a message with further instructions.'));
-                               common_hidden('email', $confirm->address);
-                               common_element_end('p');
-                               common_submit('cancel', _('Cancel'));
-                       } else {
-                               common_input('email', _('Email Address'),
-                                                        ($this->arg('email')) ? $this->arg('email') : NULL,
-                                                        _('Email address, like "UserName@example.org"'));
-                               common_submit('add', _('Add'));
-                       }
-               }
-
-               if ($user->email) {
-                       common_element('h2', NULL, _('Incoming email'));
-                       
-                       if ($user->incomingemail) {
-                               common_element_start('p');
-                               common_element('span', 'address', $user->incomingemail);
-                               common_element('span', 'input_instructions',
-                                                          _('Send email to this address to post new notices.'));
-                               common_element_end('p');
-                               common_submit('removeincoming', _('Remove'));
-                       }
-                       
-                       common_element_start('p');
-                       common_element('span', 'input_instructions',
-                                                  _('Make a new email address for posting to; cancels the old one.'));
-                       common_element_end('p');
-                       common_submit('newincoming', _('New'));
-               }
-               
-               common_element('h2', NULL, _('Preferences'));
-
-               common_checkbox('emailnotifysub',
-                               _('Send me notices of new subscriptions through email.'),
-                               $user->emailnotifysub);
-               common_checkbox('emailnotifyfav',
-                               _('Send me email when someone adds my notice as a favorite.'),
-                               $user->emailnotifyfav);
-               common_checkbox('emailnotifymsg',
-                               _('Send me email when someone sends me a private message.'),
-                               $user->emailnotifymsg);
-               common_checkbox('emailnotifynudge',
-                               _('Allow friends to nudge me and send me an email.'),
-                               $user->emailnotifynudge);
-               common_checkbox('emailpost',
-                                               _('I want to post notices by email.'),
-                                               $user->emailpost);
-               common_checkbox('emailmicroid',
-                               _('Publish a MicroID for my email address.'),
-                               $user->emailmicroid);
-
-               common_submit('save', _('Save'));
-               
-               common_element_end('form');
-               common_show_footer();
-       }
-
-       function get_confirmation() {
-               $user = common_current_user();
-               $confirm = new Confirm_address();
-               $confirm->user_id = $user->id;
-               $confirm->address_type = 'email';
-               if ($confirm->find(TRUE)) {
-                       return $confirm;
-               } else {
-                       return NULL;
-               }
-       }
-
-       function handle_post() {
-
-               # CSRF protection
-               $token = $this->trimmed('token');
-               if (!$token || $token != common_session_token()) {
-                       $this->show_form(_('There was a problem with your session token. Try again, please.'));
-                       return;
-               }
-
-               if ($this->arg('save')) {
-                       $this->save_preferences();
-               } else if ($this->arg('add')) {
-                       $this->add_address();
-               } else if ($this->arg('cancel')) {
-                       $this->cancel_confirmation();
-               } else if ($this->arg('remove')) {
-                       $this->remove_address();
-               } else if ($this->arg('removeincoming')) {
-                       $this->remove_incoming();
-               } else if ($this->arg('newincoming')) {
-                       $this->new_incoming();
-               } else {
-                       $this->show_form(_('Unexpected form submission.'));
-               }
-       }
-
-       function save_preferences() {
-
-               $emailnotifysub = $this->boolean('emailnotifysub');
-               $emailnotifyfav = $this->boolean('emailnotifyfav');
-               $emailnotifymsg = $this->boolean('emailnotifymsg');
-               $emailnotifynudge = $this->boolean('emailnotifynudge');
-               $emailmicroid = $this->boolean('emailmicroid');
-               $emailpost = $this->boolean('emailpost');
-
-               $user = common_current_user();
-
-               assert(!is_null($user)); # should already be checked
-
-               $user->query('BEGIN');
-
-               $original = clone($user);
-
-               $user->emailnotifysub = $emailnotifysub;
-               $user->emailnotifyfav = $emailnotifyfav;
-               $user->emailnotifymsg = $emailnotifymsg;
-               $user->emailnotifynudge = $emailnotifynudge;
-               $user->emailmicroid = $emailmicroid;
-               $user->emailpost = $emailpost;
-
-               $result = $user->update($original);
-
-               if ($result === FALSE) {
-                       common_log_db_error($user, 'UPDATE', __FILE__);
-                       common_server_error(_('Couldn\'t update user.'));
-                       return;
-               }
-
-               $user->query('COMMIT');
-
-               $this->show_form(_('Preferences saved.'), true);
-       }
-
-       function add_address() {
-
-               $user = common_current_user();
-
-               $email = $this->trimmed('email');
-
-               # Some validation
-
-               if (!$email) {
-                       $this->show_form(_('No email address.'));
-                       return;
-               }
-
-               $email = common_canonical_email($email);
-
-               if (!$email) {
-                   $this->show_form(_('Cannot normalize that email address'));
-                   return;
-               }
-               if (!Validate::email($email, true)) {
-                   $this->show_form(_('Not a valid email address'));
-                   return;
-               } else if ($user->email == $email) {
-                   $this->show_form(_('That is already your email address.'));
-                   return;
-               } else if ($this->email_exists($email)) {
-                   $this->show_form(_('That email address already belongs to another user.'));
-                   return;
-               }
-
-               $confirm = new Confirm_address();
-               $confirm->address = $email;
-               $confirm->address_type = 'email';
-               $confirm->user_id = $user->id;
-               $confirm->code = common_confirmation_code(64);
-
-               $result = $confirm->insert();
-
-               if ($result === FALSE) {
-                       common_log_db_error($confirm, 'INSERT', __FILE__);
-                       common_server_error(_('Couldn\'t insert confirmation code.'));
-                       return;
-               }
-
-               mail_confirm_address($user, $confirm->code, $user->nickname, $email);
-
-               $msg = _('A confirmation code was sent to the email address you added. Check your inbox (and spam box!) for the code and instructions on how to use it.');
-
-               $this->show_form($msg, TRUE);
-       }
-
-       function cancel_confirmation() {
-               $email = $this->arg('email');
-               $confirm = $this->get_confirmation();
-               if (!$confirm) {
-                       $this->show_form(_('No pending confirmation to cancel.'));
-                       return;
-               }
-               if ($confirm->address != $email) {
-                       $this->show_form(_('That is the wrong IM address.'));
-                       return;
-               }
+class EmailsettingsAction extends SettingsAction
+{
+
+    function get_instructions()
+    {
+        return _('Manage how you get email from %%site.name%%.');
+    }
+
+    function show_form($msg=null, $success=false)
+    {
+        $user = common_current_user();
+        $this->form_header(_('Email Settings'), $msg, $success);
+        common_element_start('form', array('method' => 'post',
+                                           'id' => 'emailsettings',
+                                           'action' =>
+                                           common_local_url('emailsettings')));
+        common_hidden('token', common_session_token());
+
+        common_element('h2', null, _('Address'));
+
+        if ($user->email) {
+            common_element_start('p');
+            common_element('span', 'address confirmed', $user->email);
+            common_element('span', 'input_instructions',
+                           _('Current confirmed email address.'));
+            common_hidden('email', $user->email);
+            common_element_end('p');
+            common_submit('remove', _('Remove'));
+        } else {
+            $confirm = $this->get_confirmation();
+            if ($confirm) {
+                common_element_start('p');
+                common_element('span', 'address unconfirmed', $confirm->address);
+                common_element('span', 'input_instructions',
+                               _('Awaiting confirmation on this address. Check your inbox (and spam box!) for a message with further instructions.'));
+                common_hidden('email', $confirm->address);
+                common_element_end('p');
+                common_submit('cancel', _('Cancel'));
+            } else {
+                common_input('email', _('Email Address'),
+                             ($this->arg('email')) ? $this->arg('email') : null,
+                             _('Email address, like "UserName@example.org"'));
+                common_submit('add', _('Add'));
+            }
+        }
+
+        if ($user->email) {
+            common_element('h2', null, _('Incoming email'));
+            
+            if ($user->incomingemail) {
+                common_element_start('p');
+                common_element('span', 'address', $user->incomingemail);
+                common_element('span', 'input_instructions',
+                               _('Send email to this address to post new notices.'));
+                common_element_end('p');
+                common_submit('removeincoming', _('Remove'));
+            }
+            
+            common_element_start('p');
+            common_element('span', 'input_instructions',
+                           _('Make a new email address for posting to; cancels the old one.'));
+            common_element_end('p');
+            common_submit('newincoming', _('New'));
+        }
+        
+        common_element('h2', null, _('Preferences'));
+
+        common_checkbox('emailnotifysub',
+                        _('Send me notices of new subscriptions through email.'),
+                        $user->emailnotifysub);
+        common_checkbox('emailnotifyfav',
+                        _('Send me email when someone adds my notice as a favorite.'),
+                        $user->emailnotifyfav);
+        common_checkbox('emailnotifymsg',
+                        _('Send me email when someone sends me a private message.'),
+                        $user->emailnotifymsg);
+        common_checkbox('emailnotifynudge',
+                        _('Allow friends to nudge me and send me an email.'),
+                        $user->emailnotifynudge);
+        common_checkbox('emailpost',
+                        _('I want to post notices by email.'),
+                        $user->emailpost);
+        common_checkbox('emailmicroid',
+                        _('Publish a MicroID for my email address.'),
+                        $user->emailmicroid);
+
+        common_submit('save', _('Save'));
+        
+        common_element_end('form');
+        common_show_footer();
+    }
+
+    function get_confirmation()
+    {
+        $user = common_current_user();
+        $confirm = new Confirm_address();
+        $confirm->user_id = $user->id;
+        $confirm->address_type = 'email';
+        if ($confirm->find(true)) {
+            return $confirm;
+        } else {
+            return null;
+        }
+    }
+
+    function handle_post()
+    {
+
+        # CSRF protection
+        $token = $this->trimmed('token');
+        if (!$token || $token != common_session_token()) {
+            $this->show_form(_('There was a problem with your session token. Try again, please.'));
+            return;
+        }
+
+        if ($this->arg('save')) {
+            $this->save_preferences();
+        } else if ($this->arg('add')) {
+            $this->add_address();
+        } else if ($this->arg('cancel')) {
+            $this->cancel_confirmation();
+        } else if ($this->arg('remove')) {
+            $this->remove_address();
+        } else if ($this->arg('removeincoming')) {
+            $this->remove_incoming();
+        } else if ($this->arg('newincoming')) {
+            $this->new_incoming();
+        } else {
+            $this->show_form(_('Unexpected form submission.'));
+        }
+    }
+
+    function save_preferences()
+    {
+
+        $emailnotifysub = $this->boolean('emailnotifysub');
+        $emailnotifyfav = $this->boolean('emailnotifyfav');
+        $emailnotifymsg = $this->boolean('emailnotifymsg');
+        $emailnotifynudge = $this->boolean('emailnotifynudge');
+        $emailmicroid = $this->boolean('emailmicroid');
+        $emailpost = $this->boolean('emailpost');
+
+        $user = common_current_user();
+
+        assert(!is_null($user)); # should already be checked
+
+        $user->query('BEGIN');
+
+        $original = clone($user);
+
+        $user->emailnotifysub = $emailnotifysub;
+        $user->emailnotifyfav = $emailnotifyfav;
+        $user->emailnotifymsg = $emailnotifymsg;
+        $user->emailnotifynudge = $emailnotifynudge;
+        $user->emailmicroid = $emailmicroid;
+        $user->emailpost = $emailpost;
+
+        $result = $user->update($original);
+
+        if ($result === false) {
+            common_log_db_error($user, 'UPDATE', __FILE__);
+            common_server_error(_('Couldn\'t update user.'));
+            return;
+        }
+
+        $user->query('COMMIT');
+
+        $this->show_form(_('Preferences saved.'), true);
+    }
+
+    function add_address()
+    {
+
+        $user = common_current_user();
+
+        $email = $this->trimmed('email');
+
+        # Some validation
+
+        if (!$email) {
+            $this->show_form(_('No email address.'));
+            return;
+        }
+
+        $email = common_canonical_email($email);
+
+        if (!$email) {
+            $this->show_form(_('Cannot normalize that email address'));
+            return;
+        }
+        if (!Validate::email($email, true)) {
+            $this->show_form(_('Not a valid email address'));
+            return;
+        } else if ($user->email == $email) {
+            $this->show_form(_('That is already your email address.'));
+            return;
+        } else if ($this->email_exists($email)) {
+            $this->show_form(_('That email address already belongs to another user.'));
+            return;
+        }
+
+          $confirm = new Confirm_address();
+           $confirm->address = $email;
+           $confirm->address_type = 'email';
+           $confirm->user_id = $user->id;
+           $confirm->code = common_confirmation_code(64);
+
+        $result = $confirm->insert();
+
+        if ($result === false) {
+            common_log_db_error($confirm, 'INSERT', __FILE__);
+            common_server_error(_('Couldn\'t insert confirmation code.'));
+            return;
+        }
+
+        mail_confirm_address($user, $confirm->code, $user->nickname, $email);
+
+        $msg = _('A confirmation code was sent to the email address you added. Check your inbox (and spam box!) for the code and instructions on how to use it.');
+
+        $this->show_form($msg, true);
+    }
+
+    function cancel_confirmation()
+    {
+        $email = $this->arg('email');
+        $confirm = $this->get_confirmation();
+        if (!$confirm) {
+            $this->show_form(_('No pending confirmation to cancel.'));
+            return;
+        }
+        if ($confirm->address != $email) {
+            $this->show_form(_('That is the wrong IM address.'));
+            return;
+        }
 
         $result = $confirm->delete();
 
         if (!$result) {
-                       common_log_db_error($confirm, 'DELETE', __FILE__);
+            common_log_db_error($confirm, 'DELETE', __FILE__);
             $this->server_error(_('Couldn\'t delete email confirmation.'));
             return;
         }
 
-        $this->show_form(_('Confirmation cancelled.'), TRUE);
-       }
-
-       function remove_address() {
-
-               $user = common_current_user();
-               $email = $this->arg('email');
-
-               # Maybe an old tab open...?
-
-               if ($user->email != $email) {
-                   $this->show_form(_('That is not your email address.'));
-                   return;
-               }
-
-               $user->query('BEGIN');
-               $original = clone($user);
-               $user->email = NULL;
-               $result = $user->updateKeys($original);
-               if (!$result) {
-                       common_log_db_error($user, 'UPDATE', __FILE__);
-                       common_server_error(_('Couldn\'t update user.'));
-                       return;
-               }
-               $user->query('COMMIT');
-
-               $this->show_form(_('The address was removed.'), TRUE);
-       }
-
-       function remove_incoming() {
-               $user = common_current_user();
-               
-               if (!$user->incomingemail) {
-                       $this->show_form(_('No incoming email address.'));
-                       return;
-               }
-               
-               $orig = clone($user);
-               $user->incomingemail = NULL;
-
-               if (!$user->updateKeys($orig)) {
-                       common_log_db_error($user, 'UPDATE', __FILE__);
-                       $this->server_error(_("Couldn't update user record."));
-               }
-               
-               $this->show_form(_('Incoming email address removed.'), TRUE);
-       }
-
-       function new_incoming() {
-               $user = common_current_user();
-               
-               $orig = clone($user);
-               $user->incomingemail = mail_new_incoming_address();
-               
-               if (!$user->updateKeys($orig)) {
-                       common_log_db_error($user, 'UPDATE', __FILE__);
-                       $this->server_error(_("Couldn't update user record."));
-               }
-
-               $this->show_form(_('New incoming email address added.'), TRUE);
-       }
-       
-       function email_exists($email) {
-               $user = common_current_user();
-               $other = User::staticGet('email', $email);
-               if (!$other) {
-                       return false;
-               } else {
-                       return $other->id != $user->id;
-               }
-       }
+        $this->show_form(_('Confirmation cancelled.'), true);
+    }
+
+    function remove_address()
+    {
+
+        $user = common_current_user();
+        $email = $this->arg('email');
+
+        # Maybe an old tab open...?
+
+        if ($user->email != $email) {
+            $this->show_form(_('That is not your email address.'));
+            return;
+        }
+
+        $user->query('BEGIN');
+        $original = clone($user);
+        $user->email = null;
+        $result = $user->updateKeys($original);
+        if (!$result) {
+            common_log_db_error($user, 'UPDATE', __FILE__);
+            common_server_error(_('Couldn\'t update user.'));
+            return;
+        }
+        $user->query('COMMIT');
+
+        $this->show_form(_('The address was removed.'), true);
+    }
+
+    function remove_incoming()
+    {
+        $user = common_current_user();
+        
+        if (!$user->incomingemail) {
+            $this->show_form(_('No incoming email address.'));
+            return;
+        }
+        
+        $orig = clone($user);
+        $user->incomingemail = null;
+
+        if (!$user->updateKeys($orig)) {
+            common_log_db_error($user, 'UPDATE', __FILE__);
+            $this->server_error(_("Couldn't update user record."));
+        }
+        
+        $this->show_form(_('Incoming email address removed.'), true);
+    }
+
+    function new_incoming()
+    {
+        $user = common_current_user();
+        
+        $orig = clone($user);
+        $user->incomingemail = mail_new_incoming_address();
+        
+        if (!$user->updateKeys($orig)) {
+            common_log_db_error($user, 'UPDATE', __FILE__);
+            $this->server_error(_("Couldn't update user record."));
+        }
+
+        $this->show_form(_('New incoming email address added.'), true);
+    }
+    
+    function email_exists($email)
+    {
+        $user = common_current_user();
+        $other = User::staticGet('email', $email);
+        if (!$other) {
+            return false;
+        } else {
+            return $other->id != $user->id;
+        }
+    }
 }
index 8ee2d4cd36812392931078833652f4b86d9ebfc6..6206fb6c2704498f3e8300aa47cddb6b52dd5f30 100644 (file)
  *
  * 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
+ * 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/>.
+ * along with this program.     If not, see <http://www.gnu.org/licenses/>.
  */
 
 if (!defined('LACONICA')) { exit(1); }
 
 require_once(INSTALLDIR.'/lib/facebookaction.php');
 
-class FacebookhomeAction extends FacebookAction {
+class FacebookhomeAction extends FacebookAction
+{
 
-       function handle($args) {
-               parent::handle($args);
+    function handle($args)
+    {
+        parent::handle($args);
 
-               $this->login();
-       }
+        $this->login();
+    }
 
-       function login() {
+    function login()
+    {
 
-               $user = null;
+        $user = null;
 
-               $facebook = $this->get_facebook();
-               $fbuid = $facebook->require_login();
+        $facebook = get_facebook();
+        $fbuid = $facebook->require_login();
 
-               # check to see whether there's already a Facebook link for this user
-               $flink = Foreign_link::getByForeignID($fbuid, 2); // 2 == Facebook
+        # check to see whether there's already a Facebook link for this user
+        $flink = Foreign_link::getByForeignID($fbuid, 2); // 2 == Facebook
 
-               if ($flink) {
+        if ($flink) {
 
-                       $user = $flink->getUser();
-                       $this->show_home($facebook, $fbuid, $user);
+            $user = $flink->getUser();
+            $this->show_home($facebook, $fbuid, $user);
 
-               } else {
+        } else {
 
-                       # Make the user put in her Laconica creds
-                       $nickname = common_canonical_nickname($this->trimmed('nickname'));
-                       $password = $this->arg('password');
+            # Make the user put in her Laconica creds
+            $nickname = common_canonical_nickname($this->trimmed('nickname'));
+            $password = $this->arg('password');
 
-                       if ($nickname) {
+            if ($nickname) {
 
-                               if (common_check_user($nickname, $password)) {
+                if (common_check_user($nickname, $password)) {
 
 
-                                       $user = User::staticGet('nickname', $nickname);
+                    $user = User::staticGet('nickname', $nickname);
 
-                                       if (!$user) {
-                                               echo '<fb:error message="Coudln\'t get user!" />';
-                                               $this->show_login_form();
-                                       }
+                    if (!$user) {
+                        echo '<fb:error message="Coudln\'t get user!" />';
+                        $this->show_login_form();
+                    }
 
-                                       $flink = DB_DataObject::factory('foreign_link');
-                                       $flink->user_id = $user->id;
-                                       $flink->foreign_id = $fbuid;
-                                       $flink->service = 2; # Facebook
-                                       $flink->created = common_sql_now();
+                    $flink = DB_DataObject::factory('foreign_link');
+                    $flink->user_id = $user->id;
+                    $flink->foreign_id = $fbuid;
+                    $flink->service = 2; # Facebook
+                    $flink->created = common_sql_now();
+                    $flink->set_flags(true, false, false);
 
-                                       # $this->set_flags($flink, $noticesync, $replysync, $friendsync);
+                    $flink_id = $flink->insert();
 
-                                       $flink_id = $flink->insert();
+                    if ($flink_id) {
+                        echo '<fb:success message="You can now use Identi.ca from Facebook!" />';
+                    }
 
-                                       if ($flink_id) {
-                                               echo '<fb:success message="You can now use the Identi.ca from Facebook!" />';
-                                       }
+                    $this->show_home($facebook, $fbuid, $user);
 
-                                       $this->show_home($facebook, $fbuid, $user);
+                    return;
+                } else {
+                    echo '<fb:error message="Incorrect username or password." />';
+                }
+            }
 
-                                       return;
-                               } else {
-                                       echo '<fb:error message="Incorrect username or password." />';
-                               }
-                       }
+            $this->show_login_form();
+        }
 
-                       $this->show_login_form();
-               }
+    }
 
-       }
+    function show_home($facebook, $fbuid, $user)
+    {
 
-       function show_home($facebook, $fbuid, $user) {
+        $this->show_header('Home');
 
-               $this->show_header('Home');
+        echo $this->show_notices($user);
+        $this->update_profile_box($facebook, $fbuid, $user);
 
-               echo $this->show_notices($user);
-               $this->update_profile_box($facebook, $fbuid, $user);
+        $this->show_footer();
+    }
 
-               $this->show_footer();
-       }
+    function show_notices($user)
+    {
 
-       function show_notices($user) {
+        $page = $this->trimmed('page');
+        if (!$page) {
+            $page = 1;
+        }
 
-               $page = $this->trimmed('page');
-               if (!$page) {
-                       $page = 1;
-               }
+        $notice = $user->noticesWithFriends(($page-1)*NOTICES_PER_PAGE, NOTICES_PER_PAGE + 1);
 
-               $notice = $user->noticesWithFriends(($page-1)*NOTICES_PER_PAGE, NOTICES_PER_PAGE + 1);
+        echo '<ul id="notices">';
 
-               echo '<ul id="notices">';
+        $cnt = 0;
 
-               $cnt = 0;
+        while ($notice->fetch() && $cnt <= NOTICES_PER_PAGE) {
+            $cnt++;
 
-               while ($notice->fetch() && $cnt <= NOTICES_PER_PAGE) {
-                       $cnt++;
+            if ($cnt > NOTICES_PER_PAGE) {
+                break;
+            }
 
-                       if ($cnt > NOTICES_PER_PAGE) {
-                               break;
-                       }
+            echo $this->render_notice($notice);
+        }
 
-                       echo $this->render_notice($notice);
-               }
+        echo '<ul>';
 
-               echo '<ul>';
+        $this->pagination($page > 1, $cnt > NOTICES_PER_PAGE,
+                          $page, 'index.php', array('nickname' => $user->nickname));
 
-               $this->pagination($page > 1, $cnt > NOTICES_PER_PAGE,
-                                                 $page, 'index.php', array('nickname' => $user->nickname));
-
-       }
+    }
 
 }
index 68b351fb93b96b4a967affedca7093cb9029f060..00efa654b12cf41553d2db2a64f06f3302a96de3 100644 (file)
  *
  * 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
+ * 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/>.
+ * along with this program.     If not, see <http://www.gnu.org/licenses/>.
  */
 
 if (!defined('LACONICA')) { exit(1); }
 
 require_once(INSTALLDIR.'/lib/facebookaction.php');
 
-class FacebookinviteAction extends FacebookAction {
+class FacebookinviteAction extends FacebookAction
+{
 
-       function handle($args) {
-               parent::handle($args);
+    function handle($args)
+    {
+        parent::handle($args);
 
-               $this->display();
-       }
+        $this->display();
+    }
 
-       function display() {
+    function display()
+    {
 
-               $facebook = $this->get_facebook();
+        $facebook = get_facebook();
 
-               $fbuid = $facebook->require_login();
+        $fbuid = $facebook->require_login();
 
-               $this->show_header('Invite');
+        $this->show_header('Invite');
 
-               echo '<h2>Coming soon...</h2>';
+        echo '<h2>Coming soon...</h2>';
 
-               $this->show_footer();
+        $this->show_footer();
 
-       }
+    }
 
 }
index 2a7bdd03e0f624060991a8053194726dcaa60a71..a200fefbfe8afebf8df3bb5d4503ced30b68fb92 100644 (file)
  *
  * 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
+ * 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/>.
+ * along with this program.     If not, see <http://www.gnu.org/licenses/>.
  */
 
 if (!defined('LACONICA')) { exit(1); }
 
 require_once(INSTALLDIR.'/lib/facebookaction.php');
 
-class FacebookremoveAction extends FacebookAction {
+class FacebookremoveAction extends FacebookAction
+{
 
-       function handle($args) {
-               parent::handle($args);
+    function handle($args)
+    {
+        parent::handle($args);
 
-               $secret = common_config('facebook', 'secret');
+        $secret = common_config('facebook', 'secret');
 
-               $sig = '';
+        $sig = '';
 
-               ksort($_POST);
+        ksort($_POST);
 
-               foreach ($_POST as $key => $val) {
-                       if (substr($key, 0, 7) == 'fb_sig_') {
-                               $sig .= substr($key, 7) . '=' . $val;
-                       }
-                }
+        foreach ($_POST as $key => $val) {
+            if (substr($key, 0, 7) == 'fb_sig_') {
+                $sig .= substr($key, 7) . '=' . $val;
+            }
+         }
 
-               $sig .= $secret;
-               $verify = md5($sig);
+        $sig .= $secret;
+        $verify = md5($sig);
 
-               if ($verify == $this->arg('fb_sig')) {
+        if ($verify == $this->arg('fb_sig')) {
 
-                       $flink = Foreign_link::getByForeignID($this->arg('fb_sig_user'), 2);
+            $flink = Foreign_link::getByForeignID($this->arg('fb_sig_user'), 2);
 
-                       common_debug("Removing foreign link to Facebook - local user ID: $flink->user_id, Facebook ID: $flink->foreign_id");
+            common_debug("Removing foreign link to Facebook - local user ID: $flink->user_id, Facebook ID: $flink->foreign_id");
 
-                       $result = $flink->delete();
+            $result = $flink->delete();
 
-                       if (!$result) {
-                               common_log_db_error($flink, 'DELETE', __FILE__);
-                               common_server_error(_('Couldn\'t remove Facebook user.'));
-                               return;
-                       }
+            if (!$result) {
+                common_log_db_error($flink, 'DELETE', __FILE__);
+                common_server_error(_('Couldn\'t remove Facebook user.'));
+                return;
+            }
 
-               } else {
-                       # Someone bad tried to remove facebook link?
-                       common_log(LOG_ERR, "Someone from $_SERVER[REMOTE_ADDR] " .
-                               'unsuccessfully tried to remove a foreign link to Facebook!');
-               }
-       }
+        } else {
+            # Someone bad tried to remove facebook link?
+            common_log(LOG_ERR, "Someone from $_SERVER[REMOTE_ADDR] " .
+                'unsuccessfully tried to remove a foreign link to Facebook!');
+        }
+    }
 
 }
index 4d7000d605e9e4e81b7593af0100817d0394a41e..d28b1aa5ca95b7027be03d16b15bcce04b9ac6a3 100644 (file)
  *
  * 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
+ * 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/>.
+ * along with this program.     If not, see <http://www.gnu.org/licenses/>.
  */
 
 if (!defined('LACONICA')) { exit(1); }
 
 require_once(INSTALLDIR.'/lib/facebookaction.php');
 
-class FacebooksettingsAction extends FacebookAction {
+class FacebooksettingsAction extends FacebookAction
+{
 
-       function handle($args) {
-               parent::handle($args);
+    function handle($args)
+    {
+        parent::handle($args);
 
-               $this->display();
-       }
+        if ($this->arg('save')) {
+            $this->save_settings();
+        } else {
+            $this->show_form();
+        }
+    }
 
-       function display() {
 
-               $facebook = $this->get_facebook();
+    function save_settings() {
 
-               $fbuid = $facebook->require_login();
+        $noticesync = $this->arg('noticesync');
+        $replysync = $this->arg('replysync');
 
-               $fbml = '<fb:if-section-not-added section="profile">'
-                       .'<h2>Add an Identi.ca box to your profile!</h2>'
-                       .'<fb:add-section-button section="profile"/>'
-                       .'</fb:if-section-not-added>';
+        $facebook = get_facebook();
+        $fbuid = $facebook->require_login();
 
+        $flink = Foreign_link::getByForeignID($fbuid, 2); // 2 == Facebook
 
-               $this->show_header('Settings');
+        $original = clone($flink);
+        $flink->set_flags($noticesync, $replysync, false);
+        $result = $flink->update($original);
 
-               echo $fbml;
+        if ($result) {
+            echo '<fb:success message="Sync preferences saved." />';
+        }
 
-               $this->show_footer();
+        $this->show_form();
 
-       }
+    }
+
+    function show_form() {
+
+        $facebook = get_facebook();
+        $fbuid = $facebook->require_login();
+
+        $flink = Foreign_link::getByForeignID($fbuid, 2); // 2 == Facebook
+
+        $this->show_header('Settings');
+
+        $fbml = '<fb:if-section-not-added section="profile">'
+            .'<h2>Add an Identi.ca box to my profile</h2>'
+            .'<p><fb:add-section-button section="profile"/></p>'
+            .'</fb:if-section-not-added>';
+
+        $fbml .= '<p><fb:prompt-permission perms="status_update"><h2>Allow Identi.ca to update my Facebook status</h2></fb:prompt-permission></p>';
+
+        if ($facebook->api_client->users_hasAppPermission('status_update')) {
+
+        $fbml .= '<form method="post" id="facebook_settings">'
+        .'<h2>Sync preferences</h2>'
+        .'<p>';
+
+        if ($flink->noticesync & FOREIGN_NOTICE_SEND) {
+            $fbml .= '<input name="noticesync" type="checkbox" class="checkbox" id="noticesync" checked="checked"/>';
+        } else {
+            $fbml .= '<input name="noticesync" type="checkbox" class="checkbox" id="noticesync">';
+        }
+
+        $fbml .= '<label class="checkbox_label" for="noticesync">Automatically update my Facebook status with my notices.</label>'
+        .'</p>'
+        .'<p>';
+
+        if ($flink->noticesync & FOREIGN_NOTICE_SEND_REPLY) {
+            $fbml .= '<input name="replysync" type="checkbox" class="checkbox" id="replysync" checked="checked"/>';
+        } else {
+            $fbml .= '<input name="replysync" type="checkbox" class="checkbox" id="replysync"/>';
+        }
+
+        $fbml .= '<label class="checkbox_label" for="replysync">Send &quot;@&quot; replies to Facebook.</label>'
+        .'</p>'
+        .'<p>'
+        .'<input type="submit" id="save" name="save" class="submit" value="Save"/>'
+        .'</p>'
+        .'</form>';
+
+    }
+
+        echo $fbml;
+
+        $this->show_footer();
+    }
 
 }
index aede32902e62bd287976771e8563f9f5d9070a4c..8103f8181b72a699bdaa36a0b3236bb212f65256 100644 (file)
@@ -21,74 +21,77 @@ if (!defined('LACONICA')) { exit(1); }
 
 require_once(INSTALLDIR.'/lib/mail.php');
 
-class FavorAction extends Action {
-
-       function handle($args) {
-               parent::handle($args);
-
-               if (!common_logged_in()) {
-                       common_user_error(_('Not logged in.'));
-                       return;
-               }
-
-               $user = common_current_user();
-
-               if ($_SERVER['REQUEST_METHOD'] != 'POST') {
-                       common_redirect(common_local_url('showfavorites', array('nickname' => $user->nickname)));
-                       return;
-               }
-
-               $id = $this->trimmed('notice');
-
-               $notice = Notice::staticGet($id);
-
-               # CSRF protection
-
-               $token = $this->trimmed('token-'.$notice->id);
-               if (!$token || $token != common_session_token()) {
-                       $this->client_error(_("There was a problem with your session token. Try again, please."));
-                       return;
-               }
-
-               if ($user->hasFave($notice)) {
-                       $this->client_error(_('This notice is already a favorite!'));
-                       return;
-               }
-
-               $fave = Fave::addNew($user, $notice);
-
-               if (!$fave) {
-                       $this->server_error(_('Could not create favorite.'));
-                       return;
-               }
-
-               $this->notify($fave, $notice, $user);
-               $user->blowFavesCache();
-               
-               if ($this->boolean('ajax')) {
-                       common_start_html('text/xml;charset=utf-8', true);
-                       common_element_start('head');
-                       common_element('title', null, _('Disfavor favorite'));
-                       common_element_end('head');
-                       common_element_start('body');
-                       common_disfavor_form($notice);
-                       common_element_end('body');
-                       common_element_end('html');
-               } else {
-                       common_redirect(common_local_url('showfavorites',
-                                                                                        array('nickname' => $user->nickname)));
-               }
-       }
-
-       function notify($fave, $notice, $user) {
-           $other = User::staticGet('id', $notice->profile_id);
-               if ($other && $other->id != $user->id) {
-                       if ($other->email && $other->emailnotifyfav) {
-                               mail_notify_fave($other, $user, $notice);
-                       }
-                       # XXX: notify by IM
-                       # XXX: notify by SMS
-               }
-       }
+class FavorAction extends Action
+{
+
+    function handle($args)
+    {
+        parent::handle($args);
+
+        if (!common_logged_in()) {
+            common_user_error(_('Not logged in.'));
+            return;
+        }
+
+        $user = common_current_user();
+
+        if ($_SERVER['REQUEST_METHOD'] != 'POST') {
+            common_redirect(common_local_url('showfavorites', array('nickname' => $user->nickname)));
+            return;
+        }
+
+        $id = $this->trimmed('notice');
+
+        $notice = Notice::staticGet($id);
+
+        # CSRF protection
+
+        $token = $this->trimmed('token-'.$notice->id);
+        if (!$token || $token != common_session_token()) {
+            $this->client_error(_("There was a problem with your session token. Try again, please."));
+            return;
+        }
+
+        if ($user->hasFave($notice)) {
+            $this->client_error(_('This notice is already a favorite!'));
+            return;
+        }
+
+        $fave = Fave::addNew($user, $notice);
+
+        if (!$fave) {
+            $this->server_error(_('Could not create favorite.'));
+            return;
+        }
+
+        $this->notify($fave, $notice, $user);
+        $user->blowFavesCache();
+        
+        if ($this->boolean('ajax')) {
+            common_start_html('text/xml;charset=utf-8', true);
+            common_element_start('head');
+            common_element('title', null, _('Disfavor favorite'));
+            common_element_end('head');
+            common_element_start('body');
+            common_disfavor_form($notice);
+            common_element_end('body');
+            common_element_end('html');
+        } else {
+            common_redirect(common_local_url('showfavorites',
+                                             array('nickname' => $user->nickname)));
+        }
+    }
+
+    function notify($fave, $notice, $user)
+    {
+        $other = User::staticGet('id', $notice->profile_id);
+        if ($other && $other->id != $user->id) {
+            if ($other->email && $other->emailnotifyfav) {
+                mail_notify_fave($other, $user, $notice);
+            }
+            # XXX: notify by IM
+            # XXX: notify by SMS
+        }
+    }
 
 }
index dc8070d060b1571f9143bb1b84ede62f8ef17b18..71a9e026e5a7f863c6fa517de644b94449e704d1 100644 (file)
  *
  * 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
+ * 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/>.
+ * along with this program.     If not, see <http://www.gnu.org/licenses/>.
  */
 
 if (!defined('LACONICA')) { exit(1); }
 
 require_once(INSTALLDIR.'/lib/stream.php');
 
-class FavoritedAction extends StreamAction {
+class FavoritedAction extends StreamAction
+{
 
-       function handle($args) {
-               parent::handle($args);
+    function handle($args)
+    {
+        parent::handle($args);
 
-               $page = ($this->arg('page')) ? ($this->arg('page')+0) : 1;
+        $page = ($this->arg('page')) ? ($this->arg('page')+0) : 1;
 
-               common_show_header(_('Popular notices'),
-                                                  array($this, 'show_header'), NULL,
-                                                  array($this, 'show_top'));
+        common_show_header(_('Popular notices'),
+                           array($this, 'show_header'), null,
+                           array($this, 'show_top'));
 
-               $this->show_notices($page);
+        $this->show_notices($page);
 
-               common_show_footer();
-       }
+        common_show_footer();
+    }
 
-       function show_top() {
-               $instr = $this->get_instructions();
-               $output = common_markup_to_html($instr);
-               common_element_start('div', 'instructions');
-               common_raw($output);
-               common_element_end('div');
-               $this->public_views_menu();
-       }
+    function show_top()
+    {
+        $instr = $this->get_instructions();
+        $output = common_markup_to_html($instr);
+        common_element_start('div', 'instructions');
+        common_raw($output);
+        common_element_end('div');
+        $this->public_views_menu();
+    }
 
-       function show_header() {
+    function show_header()
+    {
         return;
-       }
+    }
 
-       function get_instructions() {
-               return _('Showing recently popular notices');
-       }
+    function get_instructions()
+    {
+        return _('Showing recently popular notices');
+    }
 
-       function show_notices($page) {
+    function show_notices($page)
+    {
 
-               $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';
+        $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 = ($page - 1) * NOTICES_PER_PAGE;
-               $limit = NOTICES_PER_PAGE + 1;
+        $offset = ($page - 1) * NOTICES_PER_PAGE;
+        $limit = NOTICES_PER_PAGE + 1;
 
-               if (common_config('db','type') == 'pgsql') {
-                       $qry .= ' LIMIT ' . $limit . ' OFFSET ' . $offset;
-               } else {
-                       $qry .= ' LIMIT ' . $offset . ', ' . $limit;
-               }
+        if (common_config('db','type') == 'pgsql') {
+            $qry .= ' LIMIT ' . $limit . ' OFFSET ' . $offset;
+        } else {
+            $qry .= ' LIMIT ' . $offset . ', ' . $limit;
+        }
 
-               # Figure out how to cache this query
+        # Figure out how to cache this query
 
-               $notice = new Notice;
-               $notice->query(sprintf($qry, common_config('popular', 'dropoff')));
+        $notice = new Notice;
+        $notice->query(sprintf($qry, common_config('popular', 'dropoff')));
 
-               common_element_start('ul', array('id' => 'notices'));
+        common_element_start('ul', array('id' => 'notices'));
 
-               $cnt = 0;
+        $cnt = 0;
 
-               while ($notice->fetch() && $cnt <= NOTICES_PER_PAGE) {
-                       $cnt++;
+        while ($notice->fetch() && $cnt <= NOTICES_PER_PAGE) {
+            $cnt++;
 
-                       if ($cnt > NOTICES_PER_PAGE) {
-                               break;
-                       }
+            if ($cnt > NOTICES_PER_PAGE) {
+                break;
+            }
 
             $item = new NoticeListItem($notice);
             $item->show();
-               }
+        }
 
-               common_element_end('ul');
+        common_element_end('ul');
 
-               common_pagination($page > 1, $cnt > NOTICES_PER_PAGE,
-                                                 $page, 'favorited');
-       }
+        common_pagination($page > 1, $cnt > NOTICES_PER_PAGE,
+                          $page, 'favorited');
+    }
 
 }
index 25dd3861fa29fed97076d0bcad6974bd5ffc0e18..8c7ce52bf16c667a1786383a092e79376a172bfa 100644 (file)
@@ -23,51 +23,56 @@ require_once(INSTALLDIR.'/lib/rssaction.php');
 
 // Formatting of RSS handled by Rss10Action
 
-class FavoritesrssAction extends Rss10Action {
+class FavoritesrssAction extends Rss10Action
+{
 
-       var $user = NULL;
-       
-       function init() {
-               $nickname = $this->trimmed('nickname');
-               $this->user = User::staticGet('nickname', $nickname);
+    var $user = null;
+    
+    function init()
+    {
+        $nickname = $this->trimmed('nickname');
+        $this->user = User::staticGet('nickname', $nickname);
 
-               if (!$this->user) {
-                       common_user_error(_('No such user.'));
-                       return false;
-               } else {
-                       return true;
-               }
-       }
+        if (!$this->user) {
+            common_user_error(_('No such user.'));
+            return false;
+        } else {
+            return true;
+        }
+    }
 
-       function get_notices($limit=0) {
+    function get_notices($limit=0)
+    {
 
-               $user = $this->user;
+        $user = $this->user;
 
-               $notice = $user->favoriteNotices(0, $limit);
+        $notice = $user->favoriteNotices(0, $limit);
 
-               $notices = array();
+        $notices = array();
 
-               while ($notice->fetch()) {
-                       $notices[] = clone($notice);
-               }
+        while ($notice->fetch()) {
+            $notices[] = clone($notice);
+        }
 
-               return $notices;
-       }
+        return $notices;
+    }
 
-       function get_channel() {
-               $user = $this->user;
-               $c = array('url' => common_local_url('favoritesrss',
-                                                                                        array('nickname' =>
-                                                                                                  $user->nickname)),
-                                  'title' => sprintf(_("%s favorite notices"), $user->nickname),
-                                  'link' => common_local_url('showfavorites',
-                                                                                        array('nickname' =>
-                                                                                                  $user->nickname)),
-                                  'description' => sprintf(_('Feed of favorite notices of %s'), $user->nickname));
-               return $c;
-       }
+    function get_channel()
+    {
+        $user = $this->user;
+        $c = array('url' => common_local_url('favoritesrss',
+                                             array('nickname' =>
+                                                   $user->nickname)),
+                   'title' => sprintf(_("%s favorite notices"), $user->nickname),
+                   'link' => common_local_url('showfavorites',
+                                             array('nickname' =>
+                                                   $user->nickname)),
+                   'description' => sprintf(_('Feed of favorite notices of %s'), $user->nickname));
+        return $c;
+    }
 
-       function get_image() {
-               return NULL;
-       }
+    function get_image()
+    {
+        return null;
+    }
 }
\ No newline at end of file
index 96fbd89ab7d05440cd7bc3f588d20464a89b3ee2..2bf8b0b815cf2c8f1e909260b7694fd0ff79cbeb 100644 (file)
  *
  * 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
+ * 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/>.
+ * along with this program.     If not, see <http://www.gnu.org/licenses/>.
  */
 
 if (!defined('LACONICA')) { exit(1); }
@@ -22,81 +22,87 @@ if (!defined('LACONICA')) { exit(1); }
 require_once(INSTALLDIR.'/lib/stream.php');
 require_once(INSTALLDIR.'/lib/profilelist.php');
 
-class FeaturedAction extends StreamAction {
+class FeaturedAction extends StreamAction
+{
 
-       function handle($args) {
-               parent::handle($args);
+    function handle($args)
+    {
+        parent::handle($args);
 
-               $page = ($this->arg('page')) ? ($this->arg('page')+0) : 1;
+        $page = ($this->arg('page')) ? ($this->arg('page')+0) : 1;
 
-               common_show_header(_('Featured users'),
-                                                  array($this, 'show_header'), NULL,
-                                                  array($this, 'show_top'));
+        common_show_header(_('Featured users'),
+                           array($this, 'show_header'), null,
+                           array($this, 'show_top'));
 
-               $this->show_notices($page);
+        $this->show_notices($page);
 
-               common_show_footer();
-       }
+        common_show_footer();
+    }
 
-       function show_top() {
-               $instr = $this->get_instructions();
-               $output = common_markup_to_html($instr);
-               common_element_start('div', 'instructions');
-               common_raw($output);
-               common_element_end('div');
-               $this->public_views_menu();
-       }
+    function show_top()
+    {
+        $instr = $this->get_instructions();
+        $output = common_markup_to_html($instr);
+        common_element_start('div', 'instructions');
+        common_raw($output);
+        common_element_end('div');
+        $this->public_views_menu();
+    }
 
-       function show_header() {
-       }
+    function show_header()
+    {
+    }
 
-       function get_instructions() {
-               return _('Featured users');
-       }
+    function get_instructions()
+    {
+        return _('Featured users');
+    }
 
-       function show_notices($page) {
+    function show_notices($page)
+    {
 
-               // XXX: Note I'm doing it this two-stage way because a raw query
-               // with a JOIN was *not* working. --Zach
+        // XXX: Note I'm doing it this two-stage way because a raw query
+        // with a JOIN was *not* working. --Zach
 
-               $featured_nicks = common_config('nickname', 'featured');
+        $featured_nicks = common_config('nickname', 'featured');
 
-               if (count($featured_nicks) > 0) {
+        if (count($featured_nicks) > 0) {
 
-                       $quoted = array();
+            $quoted = array();
 
-                       foreach ($featured_nicks as $nick) {
-                               $quoted[] = "'$nick'";
-                       }
+            foreach ($featured_nicks as $nick) {
+                $quoted[] = "'$nick'";
+            }
 
-                       $user = new User;
-                       $user->whereAdd(sprintf('nickname IN (%s)', implode(',', $quoted)));
-                       $user->limit(($page - 1) * PROFILES_PER_PAGE, PROFILES_PER_PAGE + 1);
-                       $user->orderBy('user.nickname ASC');
+            $user = new User;
+            $user->whereAdd(sprintf('nickname IN (%s)', implode(',', $quoted)));
+            $user->limit(($page - 1) * PROFILES_PER_PAGE, PROFILES_PER_PAGE + 1);
+            $user->orderBy('user.nickname ASC');
 
-                       $user->find();
+            $user->find();
 
-                       $profile_ids = array();
+            $profile_ids = array();
 
-                       while ($user->fetch()) {
-                               $profile_ids[] = $user->id;
-                       }
+            while ($user->fetch()) {
+                $profile_ids[] = $user->id;
+            }
 
-                       $profile = new Profile;
-                       $profile->whereAdd(sprintf('profile.id IN (%s)', implode(',', $profile_ids)));
-                       $profile->orderBy('nickname ASC');
+            $profile = new Profile;
+            $profile->whereAdd(sprintf('profile.id IN (%s)', implode(',', $profile_ids)));
+            $profile->orderBy('nickname ASC');
 
-                       $cnt = $profile->find();
+            $cnt = $profile->find();
 
-                       if ($cnt > 0) {
-                               $featured = new ProfileList($profile);
-                               $featured->show_list();
-                       }
+            if ($cnt > 0) {
+                $featured = new ProfileList($profile);
+                $featured->show_list();
+            }
 
-                       $profile->free();
+            $profile->free();
 
-                       common_pagination($page > 1, $cnt > PROFILES_PER_PAGE, $page, 'featured');
-               }
-       }
+            common_pagination($page > 1, $cnt > PROFILES_PER_PAGE, $page, 'featured');
+        }
+    }
 
 }
\ No newline at end of file
index 54d81b0b4e538efd0ba3c60d43f7d22566daaf53..0ce1680aa60fbaa135d3ac25d1d8219719e02f01 100644 (file)
@@ -21,83 +21,87 @@ if (!defined('LACONICA')) { exit(1); }
 
 require_once(INSTALLDIR.'/lib/openid.php');
 
-class FinishaddopenidAction extends Action {
-
-       function handle($args) {
-               parent::handle($args);
-               if (!common_logged_in()) {
-                       common_user_error(_('Not logged in.'));
-               } else {
-                       $this->try_login();
-               }
-       }
-       
-       function try_login() {
-
-               $consumer =& oid_consumer();
-
-               $response = $consumer->complete(common_local_url('finishaddopenid'));
-
-               if ($response->status == Auth_OpenID_CANCEL) {
-                       $this->message(_('OpenID authentication cancelled.'));
-                       return;
-               } else if ($response->status == Auth_OpenID_FAILURE) {
-                       // Authentication failed; display the error message.
-                       $this->message(sprintf(_('OpenID authentication failed: %s'), $response->message));
-               } else if ($response->status == Auth_OpenID_SUCCESS) {
-
-                       $display = $response->getDisplayIdentifier();
-                       $canonical = ($response->endpoint && $response->endpoint->canonicalID) ?
-                         $response->endpoint->canonicalID : $display;
-
-                       $sreg_resp = Auth_OpenID_SRegResponse::fromSuccessResponse($response);
-
-                       if ($sreg_resp) {
-                               $sreg = $sreg_resp->contents();
-                       }
-
-                       $cur =& common_current_user();
-                       $other = oid_get_user($canonical);
-
-                       if ($other) {
-                               if ($other->id == $cur->id) {
-                                       $this->message(_('You already have this OpenID!'));
-                               } else {
-                                       $this->message(_('Someone else already has this OpenID.'));
-                               }
-                               return;
-                       }
-
-                       # start a transaction
-
-                       $cur->query('BEGIN');
-
-                       $result = oid_link_user($cur->id, $canonical, $display);
-
-                       if (!$result) {
-                               $this->message(_('Error connecting user.'));
-                               return;
-                       }
-                       if ($sreg) {
-                               if (!oid_update_user($cur, $sreg)) {
-                                       $this->message(_('Error updating profile'));
-                                       return;
-                               }
-                       }
-
-                       # success!
-
-                       $cur->query('COMMIT');
-
-                       oid_set_last($display);
-
-                       common_redirect(common_local_url('openidsettings'));
-               }
-       }
-
-       function message($msg) {
-               common_show_header(_('OpenID Login'));
-               common_element('p', NULL, $msg);
-               common_show_footer();
-       }
+class FinishaddopenidAction extends Action
+{
+
+    function handle($args)
+    {
+        parent::handle($args);
+        if (!common_logged_in()) {
+            common_user_error(_('Not logged in.'));
+        } else {
+            $this->try_login();
+        }
+    }
+    
+    function try_login()
+    {
+
+        $consumer =& oid_consumer();
+
+        $response = $consumer->complete(common_local_url('finishaddopenid'));
+
+        if ($response->status == Auth_OpenID_CANCEL) {
+            $this->message(_('OpenID authentication cancelled.'));
+            return;
+        } else if ($response->status == Auth_OpenID_FAILURE) {
+            // Authentication failed; display the error message.
+            $this->message(sprintf(_('OpenID authentication failed: %s'), $response->message));
+        } else if ($response->status == Auth_OpenID_SUCCESS) {
+
+            $display = $response->getDisplayIdentifier();
+            $canonical = ($response->endpoint && $response->endpoint->canonicalID) ?
+              $response->endpoint->canonicalID : $display;
+
+            $sreg_resp = Auth_OpenID_SRegResponse::fromSuccessResponse($response);
+
+            if ($sreg_resp) {
+                $sreg = $sreg_resp->contents();
+            }
+
+            $cur =& common_current_user();
+            $other = oid_get_user($canonical);
+
+            if ($other) {
+                if ($other->id == $cur->id) {
+                    $this->message(_('You already have this OpenID!'));
+                } else {
+                    $this->message(_('Someone else already has this OpenID.'));
+                }
+                return;
+            }
+
+            # start a transaction
+
+            $cur->query('BEGIN');
+
+            $result = oid_link_user($cur->id, $canonical, $display);
+
+            if (!$result) {
+                $this->message(_('Error connecting user.'));
+                return;
+            }
+            if ($sreg) {
+                if (!oid_update_user($cur, $sreg)) {
+                    $this->message(_('Error updating profile'));
+                    return;
+                }
+            }
+
+            # success!
+
+            $cur->query('COMMIT');
+
+            oid_set_last($display);
+
+            common_redirect(common_local_url('openidsettings'));
+        }
+    }
+
+    function message($msg)
+    {
+        common_show_header(_('OpenID Login'));
+        common_element('p', null, $msg);
+        common_show_footer();
+    }
 }
index 6dbaa3d1c6f0510054721ba5e52e48b76749b2d9..0964c39f44007d14208402cb4baca696e9399448 100644 (file)
@@ -21,45 +21,48 @@ if (!defined('LACONICA')) { exit(1); }
 
 require_once(INSTALLDIR.'/lib/openid.php');
 
-class FinishimmediateAction extends Action {
+class FinishimmediateAction extends Action
+{
 
-       function handle($args) {
-               parent::handle($args);
+    function handle($args)
+    {
+        parent::handle($args);
 
-               $consumer = oid_consumer();
+        $consumer = oid_consumer();
 
-               $response = $consumer->complete(common_local_url('finishimmediate'));
+        $response = $consumer->complete(common_local_url('finishimmediate'));
 
-               if ($response->status == Auth_OpenID_SUCCESS) {
-                       $display = $response->getDisplayIdentifier();
-                       $canonical = ($response->endpoint->canonicalID) ?
-                         $response->endpoint->canonicalID : $response->getDisplayIdentifier();
+        if ($response->status == Auth_OpenID_SUCCESS) {
+            $display = $response->getDisplayIdentifier();
+            $canonical = ($response->endpoint->canonicalID) ?
+              $response->endpoint->canonicalID : $response->getDisplayIdentifier();
 
-                       $user = oid_get_user($canonical);
+            $user = oid_get_user($canonical);
 
-                       if ($user) {
-                               oid_update_user($user, $sreg);
-                               oid_set_last($display); # refresh for another year
-                               common_set_user($user->nickname);
-                               $this->go_backto();
-                               return;
-                       }
-               }
+            if ($user) {
+                oid_update_user($user, $sreg);
+                oid_set_last($display); # refresh for another year
+                common_set_user($user->nickname);
+                $this->go_backto();
+                return;
+            }
+        }
 
-               # Failure! Clear openid so we don't try it again
+        # Failure! Clear openid so we don't try it again
 
-               oid_clear_last();
-               $this->go_backto();
-               return;
-       }
+        oid_clear_last();
+        $this->go_backto();
+        return;
+    }
 
-       function go_backto() {
-               common_ensure_session();
-               $backto = $_SESSION['openid_immediate_backto'];
-               if (!$backto) {
-                       # gar. Well, push them to the public page
-                       $backto = common_local_url('public');
-               }
-               common_redirect($backto);
-       }
+    function go_backto()
+    {
+        common_ensure_session();
+        $backto = $_SESSION['openid_immediate_backto'];
+        if (!$backto) {
+            # gar. Well, push them to the public page
+            $backto = common_local_url('public');
+        }
+        common_redirect($backto);
+    }
 }
index 766a08b208a60778e9edccc3ce1345d86e29a58f..bdb8516a321b1459a5d24abf931dd29e137aa3b4 100644 (file)
@@ -21,416 +21,434 @@ if (!defined('LACONICA')) { exit(1); }
 
 require_once(INSTALLDIR.'/lib/openid.php');
 
-class FinishopenidloginAction extends Action {
-
-       function handle($args) {
-               parent::handle($args);
-               if (common_logged_in()) {
-                       common_user_error(_('Already logged in.'));
-               } else if ($_SERVER['REQUEST_METHOD'] == 'POST') {
-                       $token = $this->trimmed('token');
-                       if (!$token || $token != common_session_token()) {
-                               $this->show_form(_('There was a problem with your session token. Try again, please.'));
-                               return;
-                       }
-                       if ($this->arg('create')) {
-                               if (!$this->boolean('license')) {
-                                       $this->show_form(_('You can\'t register if you don\'t agree to the license.'),
-                                                                        $this->trimmed('newname'));
-                                       return;
-                               }
-                               $this->create_new_user();
-                       } else if ($this->arg('connect')) {
-                               $this->connect_user();
-                       } else {
-                               common_debug(print_r($this->args, true), __FILE__);
-                               $this->show_form(_('Something weird happened.'),
-                                                                $this->trimmed('newname'));
-                       }
-               } else {
-                       $this->try_login();
-               }
-       }
-
-       function show_top($error=NULL) {
-               if ($error) {
-                       common_element('div', array('class' => 'error'), $error);
-               } else {
-                       global $config;
-                       common_element('div', 'instructions',
-                                                  sprintf(_('This is the first time you\'ve logged into %s so we must connect your OpenID to a local account. You can either create a new account, or connect with your existing account, if you have one.'), $config['site']['name']));
-               }
-       }
-
-       function show_form($error=NULL, $username=NULL) {
-               common_show_header(_('OpenID Account Setup'), NULL, $error,
-                                                  array($this, 'show_top'));
-
-               common_element_start('form', array('method' => 'post',
-                                                                                  'id' => 'account_connect',
-                                                                                  'action' => common_local_url('finishopenidlogin')));
-               common_hidden('token', common_session_token());
-               common_element('h2', NULL,
-                                          _('Create new account'));
-               common_element('p', NULL,
-                                          _('Create a new user with this nickname.'));
-               common_input('newname', _('New nickname'),
-                                        ($username) ? $username : '',
-                                        _('1-64 lowercase letters or numbers, no punctuation or spaces'));
-               common_element_start('p');
-               common_element('input', array('type' => 'checkbox',
-                                                                         'id' => 'license',
-                                                                         'name' => 'license',
-                                                                         'value' => 'true'));
-               common_text(_('My text and files are available under '));
-               common_element('a', array(href => common_config('license', 'url')),
-                                          common_config('license', 'title'));
-               common_text(_(' except this private data: password, email address, IM address, phone number.'));
-               common_element_end('p');
-               common_submit('create', _('Create'));
-               common_element('h2', NULL,
-                                          _('Connect existing account'));
-               common_element('p', NULL,
-                                          _('If you already have an account, login with your username and password to connect it to your OpenID.'));
-               common_input('nickname', _('Existing nickname'));
-               common_password('password', _('Password'));
-               common_submit('connect', _('Connect'));
-               common_element_end('form');
-               common_show_footer();
-       }
-
-       function try_login() {
-
-               $consumer = oid_consumer();
-
-               $response = $consumer->complete(common_local_url('finishopenidlogin'));
-
-               if ($response->status == Auth_OpenID_CANCEL) {
-                       $this->message(_('OpenID authentication cancelled.'));
-                       return;
-               } else if ($response->status == Auth_OpenID_FAILURE) {
-                       // Authentication failed; display the error message.
-                       $this->message(sprintf(_('OpenID authentication failed: %s'), $response->message));
-               } else if ($response->status == Auth_OpenID_SUCCESS) {
-                       // This means the authentication succeeded; extract the
-                       // identity URL and Simple Registration data (if it was
-                       // returned).
-                       $display = $response->getDisplayIdentifier();
-                       $canonical = ($response->endpoint->canonicalID) ?
-                         $response->endpoint->canonicalID : $response->getDisplayIdentifier();
-
-                       $sreg_resp = Auth_OpenID_SRegResponse::fromSuccessResponse($response);
-
-                       if ($sreg_resp) {
-                               $sreg = $sreg_resp->contents();
-                       }
-
-                       $user = oid_get_user($canonical);
-
-                       if ($user) {
-                               oid_set_last($display);
-                               # XXX: commented out at @edd's request until better
-                               # control over how data flows from OpenID provider.
-                               # oid_update_user($user, $sreg);
-                               common_set_user($user);
-                               common_real_login(true);
-                               if (isset($_SESSION['openid_rememberme']) && $_SESSION['openid_rememberme']) {
-                                       common_rememberme($user);
-                               }
+class FinishopenidloginAction extends Action
+{
+
+    function handle($args)
+    {
+        parent::handle($args);
+        if (common_logged_in()) {
+            common_user_error(_('Already logged in.'));
+        } else if ($_SERVER['REQUEST_METHOD'] == 'POST') {
+            $token = $this->trimmed('token');
+            if (!$token || $token != common_session_token()) {
+                $this->show_form(_('There was a problem with your session token. Try again, please.'));
+                return;
+            }
+            if ($this->arg('create')) {
+                if (!$this->boolean('license')) {
+                    $this->show_form(_('You can\'t register if you don\'t agree to the license.'),
+                                     $this->trimmed('newname'));
+                    return;
+                }
+                $this->create_new_user();
+            } else if ($this->arg('connect')) {
+                $this->connect_user();
+            } else {
+                common_debug(print_r($this->args, true), __FILE__);
+                $this->show_form(_('Something weird happened.'),
+                                 $this->trimmed('newname'));
+            }
+        } else {
+            $this->try_login();
+        }
+    }
+
+    function show_top($error=null)
+    {
+        if ($error) {
+            common_element('div', array('class' => 'error'), $error);
+        } else {
+            global $config;
+            common_element('div', 'instructions',
+                           sprintf(_('This is the first time you\'ve logged into %s so we must connect your OpenID to a local account. You can either create a new account, or connect with your existing account, if you have one.'), $config['site']['name']));
+        }
+    }
+
+    function show_form($error=null, $username=null)
+    {
+        common_show_header(_('OpenID Account Setup'), null, $error,
+                           array($this, 'show_top'));
+
+        common_element_start('form', array('method' => 'post',
+                                           'id' => 'account_connect',
+                                           'action' => common_local_url('finishopenidlogin')));
+        common_hidden('token', common_session_token());
+        common_element('h2', null,
+                       _('Create new account'));
+        common_element('p', null,
+                       _('Create a new user with this nickname.'));
+        common_input('newname', _('New nickname'),
+                     ($username) ? $username : '',
+                     _('1-64 lowercase letters or numbers, no punctuation or spaces'));
+        common_element_start('p');
+        common_element('input', array('type' => 'checkbox',
+                                      'id' => 'license',
+                                      'name' => 'license',
+                                      'value' => 'true'));
+        common_text(_('My text and files are available under '));
+        common_element('a', array(href => common_config('license', 'url')),
+                       common_config('license', 'title'));
+        common_text(_(' except this private data: password, email address, IM address, phone number.'));
+        common_element_end('p');
+        common_submit('create', _('Create'));
+        common_element('h2', null,
+                       _('Connect existing account'));
+        common_element('p', null,
+                       _('If you already have an account, login with your username and password to connect it to your OpenID.'));
+        common_input('nickname', _('Existing nickname'));
+        common_password('password', _('Password'));
+        common_submit('connect', _('Connect'));
+        common_element_end('form');
+        common_show_footer();
+    }
+
+    function try_login()
+    {
+
+        $consumer = oid_consumer();
+
+        $response = $consumer->complete(common_local_url('finishopenidlogin'));
+
+        if ($response->status == Auth_OpenID_CANCEL) {
+            $this->message(_('OpenID authentication cancelled.'));
+            return;
+        } else if ($response->status == Auth_OpenID_FAILURE) {
+            // Authentication failed; display the error message.
+            $this->message(sprintf(_('OpenID authentication failed: %s'), $response->message));
+        } else if ($response->status == Auth_OpenID_SUCCESS) {
+            // This means the authentication succeeded; extract the
+            // identity URL and Simple Registration data (if it was
+            // returned).
+            $display = $response->getDisplayIdentifier();
+            $canonical = ($response->endpoint->canonicalID) ?
+              $response->endpoint->canonicalID : $response->getDisplayIdentifier();
+
+            $sreg_resp = Auth_OpenID_SRegResponse::fromSuccessResponse($response);
+
+            if ($sreg_resp) {
+                $sreg = $sreg_resp->contents();
+            }
+
+            $user = oid_get_user($canonical);
+
+            if ($user) {
+                oid_set_last($display);
+                # XXX: commented out at @edd's request until better
+                # control over how data flows from OpenID provider.
+                # oid_update_user($user, $sreg);
+                common_set_user($user);
+                common_real_login(true);
+                if (isset($_SESSION['openid_rememberme']) && $_SESSION['openid_rememberme']) {
+                    common_rememberme($user);
+                }
                 unset($_SESSION['openid_rememberme']);
-                               $this->go_home($user->nickname);
-                       } else {
-                               $this->save_values($display, $canonical, $sreg);
-                               $this->show_form(NULL, $this->best_new_nickname($display, $sreg));
-                       }
-               }
-       }
-
-       function message($msg) {
-               common_show_header(_('OpenID Login'));
-               common_element('p', NULL, $msg);
-               common_show_footer();
-       }
-
-       function save_values($display, $canonical, $sreg) {
-               common_ensure_session();
-               $_SESSION['openid_display'] = $display;
-               $_SESSION['openid_canonical'] = $canonical;
-               $_SESSION['openid_sreg'] = $sreg;
-       }
-
-       function get_saved_values() {
-               return array($_SESSION['openid_display'],
-                                        $_SESSION['openid_canonical'],
-                                        $_SESSION['openid_sreg']);
-       }
-
-       function create_new_user() {
+                $this->go_home($user->nickname);
+            } else {
+                $this->save_values($display, $canonical, $sreg);
+                $this->show_form(null, $this->best_new_nickname($display, $sreg));
+            }
+        }
+    }
+
+    function message($msg)
+    {
+        common_show_header(_('OpenID Login'));
+        common_element('p', null, $msg);
+        common_show_footer();
+    }
+
+    function save_values($display, $canonical, $sreg)
+    {
+        common_ensure_session();
+        $_SESSION['openid_display'] = $display;
+        $_SESSION['openid_canonical'] = $canonical;
+        $_SESSION['openid_sreg'] = $sreg;
+    }
+
+    function get_saved_values()
+    {
+        return array($_SESSION['openid_display'],
+                     $_SESSION['openid_canonical'],
+                     $_SESSION['openid_sreg']);
+    }
+
+    function create_new_user()
+    {
 
         # FIXME: save invite code before redirect, and check here
 
-               if (common_config('site', 'closed') || common_config('site', 'inviteonly')) {
-                       common_user_error(_('Registration not allowed.'));
+        if (common_config('site', 'closed') || common_config('site', 'inviteonly')) {
+            common_user_error(_('Registration not allowed.'));
             return;
         }
 
-               $nickname = $this->trimmed('newname');
+        $nickname = $this->trimmed('newname');
 
-               if (!Validate::string($nickname, array('min_length' => 1,
-                                                                                          'max_length' => 64,
-                                                                                          'format' => VALIDATE_NUM . VALIDATE_ALPHA_LOWER))) {
-                       $this->show_form(_('Nickname must have only lowercase letters and numbers and no spaces.'));
-                       return;
-               }
+        if (!Validate::string($nickname, array('min_length' => 1,
+                                               'max_length' => 64,
+                                               'format' => VALIDATE_NUM . VALIDATE_ALPHA_LOWER))) {
+            $this->show_form(_('Nickname must have only lowercase letters and numbers and no spaces.'));
+            return;
+        }
 
-               if (!User::allowed_nickname($nickname)) {
-                       $this->show_form(_('Nickname not allowed.'));
-                       return;
-               }
+        if (!User::allowed_nickname($nickname)) {
+            $this->show_form(_('Nickname not allowed.'));
+            return;
+        }
 
-               if (User::staticGet('nickname', $nickname)) {
-                       $this->show_form(_('Nickname already in use. Try another one.'));
-                       return;
-               }
+        if (User::staticGet('nickname', $nickname)) {
+            $this->show_form(_('Nickname already in use. Try another one.'));
+            return;
+        }
 
-               list($display, $canonical, $sreg) = $this->get_saved_values();
+        list($display, $canonical, $sreg) = $this->get_saved_values();
 
-               if (!$display || !$canonical) {
-                       common_server_error(_('Stored OpenID not found.'));
-                       return;
-               }
+        if (!$display || !$canonical) {
+            common_server_error(_('Stored OpenID not found.'));
+            return;
+        }
 
-               # Possible race condition... let's be paranoid
+        # Possible race condition... let's be paranoid
 
-               $other = oid_get_user($canonical);
+        $other = oid_get_user($canonical);
 
-               if ($other) {
-                       common_server_error(_('Creating new account for OpenID that already has a user.'));
-                       return;
-               }
+        if ($other) {
+            common_server_error(_('Creating new account for OpenID that already has a user.'));
+            return;
+        }
 
-               if ($sreg['country']) {
-                       if ($sreg['postcode']) {
-                               # XXX: use postcode to get city and region
-                               # XXX: also, store postcode somewhere -- it's valuable!
-                               $location = $sreg['postcode'] . ', ' . $sreg['country'];
-                       } else {
-                               $location = $sreg['country'];
-                       }
-               }
+        if ($sreg['country']) {
+            if ($sreg['postcode']) {
+                # XXX: use postcode to get city and region
+                # XXX: also, store postcode somewhere -- it's valuable!
+                $location = $sreg['postcode'] . ', ' . $sreg['country'];
+            } else {
+                $location = $sreg['country'];
+            }
+        }
 
-               if ($sreg['fullname'] && strlen($sreg['fullname']) <= 255) {
-                       $fullname = $sreg['fullname'];
-               }
+        if ($sreg['fullname'] && strlen($sreg['fullname']) <= 255) {
+            $fullname = $sreg['fullname'];
+        }
 
-               if ($sreg['email'] && Validate::email($sreg['email'], true)) {
-                       $email = $sreg['email'];
-               }
+        if ($sreg['email'] && Validate::email($sreg['email'], true)) {
+            $email = $sreg['email'];
+        }
 
-               # XXX: add language
-               # XXX: add timezone
+        # XXX: add language
+        # XXX: add timezone
 
-               $user = User::register(array('nickname' => $nickname,
-                                                                        'email' => $email,
-                                                                        'fullname' => $fullname,
-                                                                        'location' => $location));
+        $user = User::register(array('nickname' => $nickname,
+                                     'email' => $email,
+                                     'fullname' => $fullname,
+                                     'location' => $location));
 
-               $result = oid_link_user($user->id, $canonical, $display);
+        $result = oid_link_user($user->id, $canonical, $display);
 
-               oid_set_last($display);
-               common_set_user($user);
-               common_real_login(true);
+        oid_set_last($display);
+        common_set_user($user);
+        common_real_login(true);
         if (isset($_SESSION['openid_rememberme']) && $_SESSION['openid_rememberme']) {
-                       common_rememberme($user);
-               }
+            common_rememberme($user);
+        }
         unset($_SESSION['openid_rememberme']);
-               common_redirect(common_local_url('showstream', array('nickname' => $user->nickname)));
-       }
+        common_redirect(common_local_url('showstream', array('nickname' => $user->nickname)));
+    }
 
-       function connect_user() {
+    function connect_user()
+    {
 
-               $nickname = $this->trimmed('nickname');
-               $password = $this->trimmed('password');
+        $nickname = $this->trimmed('nickname');
+        $password = $this->trimmed('password');
 
-               if (!common_check_user($nickname, $password)) {
-                       $this->show_form(_('Invalid username or password.'));
-                       return;
-               }
+        if (!common_check_user($nickname, $password)) {
+            $this->show_form(_('Invalid username or password.'));
+            return;
+        }
 
-               # They're legit!
+        # They're legit!
 
-               $user = User::staticGet('nickname', $nickname);
+        $user = User::staticGet('nickname', $nickname);
 
-               list($display, $canonical, $sreg) = $this->get_saved_values();
+        list($display, $canonical, $sreg) = $this->get_saved_values();
 
-               if (!$display || !$canonical) {
-                       common_server_error(_('Stored OpenID not found.'));
-                       return;
-               }
+        if (!$display || !$canonical) {
+            common_server_error(_('Stored OpenID not found.'));
+            return;
+        }
 
-               $result = oid_link_user($user->id, $canonical, $display);
+        $result = oid_link_user($user->id, $canonical, $display);
 
-               if (!$result) {
-                       common_server_error(_('Error connecting user to OpenID.'));
-                       return;
-               }
+        if (!$result) {
+            common_server_error(_('Error connecting user to OpenID.'));
+            return;
+        }
 
-               oid_update_user($user, $sreg);
-               oid_set_last($display);
-               common_set_user($user);
-               common_real_login(true);
+        oid_update_user($user, $sreg);
+        oid_set_last($display);
+        common_set_user($user);
+        common_real_login(true);
         if (isset($_SESSION['openid_rememberme']) && $_SESSION['openid_rememberme']) {
-                       common_rememberme($user);
-               }
-               unset($_SESSION['openid_rememberme']);
-               $this->go_home($user->nickname);
-       }
-
-       function go_home($nickname) {
-               $url = common_get_returnto();
-               if ($url) {
-                       # We don't have to return to it again
-                       common_set_returnto(NULL);
-               } else {
-                       $url = common_local_url('all',
-                                                                       array('nickname' =>
-                                                                                 $nickname));
-               }
-               common_redirect($url);
-       }
-
-       function best_new_nickname($display, $sreg) {
-
-               # Try the passed-in nickname
-
-               if ($sreg['nickname']) {
-                       $nickname = $this->nicknamize($sreg['nickname']);
-                       if ($this->is_new_nickname($nickname)) {
-                               return $nickname;
-                       }
-               }
-
-               # Try the full name
-
-               if ($sreg['fullname']) {
-                       $fullname = $this->nicknamize($sreg['fullname']);
-                       if ($this->is_new_nickname($fullname)) {
-                               return $fullname;
-                       }
-               }
-
-               # Try the URL
-
-               $from_url = $this->openid_to_nickname($display);
-
-               if ($from_url && $this->is_new_nickname($from_url)) {
-                       return $from_url;
-               }
-
-               # XXX: others?
-
-               return NULL;
-       }
-
-       function is_new_nickname($str) {
-               if (!Validate::string($str, array('min_length' => 1,
-                                                                                 'max_length' => 64,
-                                                                                 'format' => VALIDATE_NUM . VALIDATE_ALPHA_LOWER))) {
-                       return false;
-               }
-       if (!User::allowed_nickname($str)) {
-                       return false;
-               }
-               if (User::staticGet('nickname', $str)) {
-                       return false;
-               }
-               return true;
-       }
-
-       function openid_to_nickname($openid) {
+            common_rememberme($user);
+        }
+        unset($_SESSION['openid_rememberme']);
+        $this->go_home($user->nickname);
+    }
+
+    function go_home($nickname)
+    {
+        $url = common_get_returnto();
+        if ($url) {
+            # We don't have to return to it again
+            common_set_returnto(null);
+        } else {
+            $url = common_local_url('all',
+                                    array('nickname' =>
+                                          $nickname));
+        }
+        common_redirect($url);
+    }
+
+    function best_new_nickname($display, $sreg)
+    {
+
+        # Try the passed-in nickname
+
+        if ($sreg['nickname']) {
+            $nickname = $this->nicknamize($sreg['nickname']);
+            if ($this->is_new_nickname($nickname)) {
+                return $nickname;
+            }
+        }
+
+        # Try the full name
+
+        if ($sreg['fullname']) {
+            $fullname = $this->nicknamize($sreg['fullname']);
+            if ($this->is_new_nickname($fullname)) {
+                return $fullname;
+            }
+        }
+
+        # Try the URL
+
+        $from_url = $this->openid_to_nickname($display);
+
+        if ($from_url && $this->is_new_nickname($from_url)) {
+            return $from_url;
+        }
+
+        # XXX: others?
+
+        return null;
+    }
+
+    function is_new_nickname($str)
+    {
+        if (!Validate::string($str, array('min_length' => 1,
+                                          'max_length' => 64,
+                                          'format' => VALIDATE_NUM . VALIDATE_ALPHA_LOWER))) {
+            return false;
+        }
+    if (!User::allowed_nickname($str)) {
+            return false;
+        }
+        if (User::staticGet('nickname', $str)) {
+            return false;
+        }
+        return true;
+    }
+
+    function openid_to_nickname($openid)
+    {
         if (Auth_Yadis_identifierScheme($openid) == 'XRI') {
-                       return $this->xri_to_nickname($openid);
-               } else {
-                       return $this->url_to_nickname($openid);
-               }
-       }
-
-       # We try to use an OpenID URL as a legal Laconica user name in this order
-       # 1. Plain hostname, like http://evanp.myopenid.com/
-       # 2. One element in path, like http://profile.typekey.com/EvanProdromou/
-       #    or http://getopenid.com/evanprodromou
-
-    function url_to_nickname($openid) {
-               static $bad = array('query', 'user', 'password', 'port', 'fragment');
-
-           $parts = parse_url($openid);
-
-               # If any of these parts exist, this won't work
-
-               foreach ($bad as $badpart) {
-                       if (array_key_exists($badpart, $parts)) {
-                               return NULL;
-                       }
-               }
-
-               # We just have host and/or path
-
-               # If it's just a host...
-               if (array_key_exists('host', $parts) &&
-                       (!array_key_exists('path', $parts) || strcmp($parts['path'], '/') == 0))
-               {
-                       $hostparts = explode('.', $parts['host']);
-
-                       # Try to catch common idiom of nickname.service.tld
-
-                       if ((count($hostparts) > 2) &&
-                               (strlen($hostparts[count($hostparts) - 2]) > 3) && # try to skip .co.uk, .com.au
-                               (strcmp($hostparts[0], 'www') != 0))
-                       {
-                               return $this->nicknamize($hostparts[0]);
-                       } else {
-                               # Do the whole hostname
-                               return $this->nicknamize($parts['host']);
-                       }
-               } else {
-                       if (array_key_exists('path', $parts)) {
-                               # Strip starting, ending slashes
-                               $path = preg_replace('@/$@', '', $parts['path']);
-                               $path = preg_replace('@^/@', '', $path);
-                               if (strpos($path, '/') === false) {
-                                       return $this->nicknamize($path);
-                               }
-                       }
-               }
-
-               return NULL;
-       }
-
-       function xri_to_nickname($xri) {
-               $base = $this->xri_base($xri);
-
-               if (!$base) {
-                       return NULL;
-               } else {
-                       # =evan.prodromou
-                       # or @gratis*evan.prodromou
-                       $parts = explode('*', substr($base, 1));
-                       return $this->nicknamize(array_pop($parts));
-               }
-       }
-
-       function xri_base($xri) {
-               if (substr($xri, 0, 6) == 'xri://') {
-                       return substr($xri, 6);
-               } else {
-                       return $xri;
-               }
-       }
-
-       # Given a string, try to make it work as a nickname
-
-       function nicknamize($str) {
-               $str = preg_replace('/\W/', '', $str);
-               return strtolower($str);
-       }
+            return $this->xri_to_nickname($openid);
+        } else {
+            return $this->url_to_nickname($openid);
+        }
+    }
+
+    # We try to use an OpenID URL as a legal Laconica user name in this order
+    # 1. Plain hostname, like http://evanp.myopenid.com/
+    # 2. One element in path, like http://profile.typekey.com/EvanProdromou/
+    #    or http://getopenid.com/evanprodromou
+
+    function url_to_nickname($openid)
+    {
+        static $bad = array('query', 'user', 'password', 'port', 'fragment');
+
+        $parts = parse_url($openid);
+
+        # If any of these parts exist, this won't work
+
+        foreach ($bad as $badpart) {
+            if (array_key_exists($badpart, $parts)) {
+                return null;
+            }
+        }
+
+        # We just have host and/or path
+
+        # If it's just a host...
+        if (array_key_exists('host', $parts) &&
+            (!array_key_exists('path', $parts) || strcmp($parts['path'], '/') == 0))
+        {
+            $hostparts = explode('.', $parts['host']);
+
+            # Try to catch common idiom of nickname.service.tld
+
+            if ((count($hostparts) > 2) &&
+                (strlen($hostparts[count($hostparts) - 2]) > 3) && # try to skip .co.uk, .com.au
+                (strcmp($hostparts[0], 'www') != 0))
+            {
+                return $this->nicknamize($hostparts[0]);
+            } else {
+                # Do the whole hostname
+                return $this->nicknamize($parts['host']);
+            }
+        } else {
+            if (array_key_exists('path', $parts)) {
+                # Strip starting, ending slashes
+                $path = preg_replace('@/$@', '', $parts['path']);
+                $path = preg_replace('@^/@', '', $path);
+                if (strpos($path, '/') === false) {
+                    return $this->nicknamize($path);
+                }
+            }
+        }
+
+        return null;
+    }
+
+    function xri_to_nickname($xri)
+    {
+        $base = $this->xri_base($xri);
+
+        if (!$base) {
+            return null;
+        } else {
+            # =evan.prodromou
+            # or @gratis*evan.prodromou
+            $parts = explode('*', substr($base, 1));
+            return $this->nicknamize(array_pop($parts));
+        }
+    }
+
+    function xri_base($xri)
+    {
+        if (substr($xri, 0, 6) == 'xri://') {
+            return substr($xri, 6);
+        } else {
+            return $xri;
+        }
+    }
+
+    # Given a string, try to make it work as a nickname
+
+    function nicknamize($str)
+    {
+        $str = preg_replace('/\W/', '', $str);
+        return strtolower($str);
+    }
 }
index 58040683fdb44bed058e280b903633f382920902..cee3a181875368ec2197b310a897d4bbfa2c42ba 100644 (file)
@@ -21,176 +21,178 @@ if (!defined('LACONICA')) { exit(1); }
 
 require_once(INSTALLDIR.'/lib/omb.php');
 
-class FinishremotesubscribeAction extends Action {
+class FinishremotesubscribeAction extends Action
+{
 
-       function handle($args) {
+    function handle($args)
+    {
 
-               parent::handle($args);
+        parent::handle($args);
 
-               if (common_logged_in()) {
-                       common_user_error(_('You can use the local subscription!'));
-                   return;
-               }
+        if (common_logged_in()) {
+            common_user_error(_('You can use the local subscription!'));
+            return;
+        }
+
+        $omb = $_SESSION['oauth_authorization_request'];
+
+        if (!$omb) {
+            common_user_error(_('Not expecting this response!'));
+            return;
+        }
+
+        common_debug('stored request: '.print_r($omb,true), __FILE__);
+
+        common_remove_magic_from_request();
+        $req = OAuthRequest::from_request();
 
-               $omb = $_SESSION['oauth_authorization_request'];
+        $token = $req->get_parameter('oauth_token');
 
-               if (!$omb) {
-                       common_user_error(_('Not expecting this response!'));
-                       return;
-               }
+        # I think this is the success metric
 
-               common_debug('stored request: '.print_r($omb,true), __FILE__);
+        if ($token != $omb['token']) {
+            common_user_error(_('Not authorized.'));
+            return;
+        }
 
-               common_remove_magic_from_request();
-               $req = OAuthRequest::from_request();
+        $version = $req->get_parameter('omb_version');
+
+        if ($version != OMB_VERSION_01) {
+            common_user_error(_('Unknown version of OMB protocol.'));
+            return;
+        }
 
-               $token = $req->get_parameter('oauth_token');
+        $nickname = $req->get_parameter('omb_listener_nickname');
 
-               # I think this is the success metric
+        if (!$nickname) {
+            common_user_error(_('No nickname provided by remote server.'));
+            return;
+        }
 
-               if ($token != $omb['token']) {
-                       common_user_error(_('Not authorized.'));
-                       return;
-               }
-
-               $version = $req->get_parameter('omb_version');
-
-               if ($version != OMB_VERSION_01) {
-                       common_user_error(_('Unknown version of OMB protocol.'));
-                       return;
-               }
-
-               $nickname = $req->get_parameter('omb_listener_nickname');
-
-               if (!$nickname) {
-                       common_user_error(_('No nickname provided by remote server.'));
-                       return;
-               }
-
-               $profile_url = $req->get_parameter('omb_listener_profile');
-
-               if (!$profile_url) {
-                       common_user_error(_('No profile URL returned by server.'));
-                       return;
-               }
-
-               if (!Validate::uri($profile_url, array('allowed_schemes' => array('http', 'https')))) {
-                       common_user_error(_('Invalid profile URL returned by server.'));
-                       return;
-               }
-
-               if ($profile_url == common_local_url('showstream', array('nickname' => $nickname))) {
-                       common_user_error(_('You can use the local subscription!'));
-                   return;
-               }
-
-               common_debug('listenee: "'.$omb['listenee'].'"', __FILE__);
-
-               $user = User::staticGet('nickname', $omb['listenee']);
-
-               if (!$user) {
-                       common_user_error(_('User being listened to doesn\'t exist.'));
-                       return;
-               }
-
-               $other = User::staticGet('uri', $omb['listener']);
-
-               if ($other) {
-                       common_user_error(_('You can use the local subscription!'));
-                       return;
-               }
-
-               $fullname = $req->get_parameter('omb_listener_fullname');
-               $homepage = $req->get_parameter('omb_listener_homepage');
-               $bio = $req->get_parameter('omb_listener_bio');
-               $location = $req->get_parameter('omb_listener_location');
-               $avatar_url = $req->get_parameter('omb_listener_avatar');
-
-               list($newtok, $newsecret) = $this->access_token($omb);
-
-               if (!$newtok || !$newsecret) {
-                       common_user_error(_('Couldn\'t convert request tokens to access tokens.'));
-                       return;
-               }
-
-               # XXX: possible attack point; subscribe and return someone else's profile URI
-
-               $remote = Remote_profile::staticGet('uri', $omb['listener']);
-
-               if ($remote) {
-                       $exists = true;
-                       $profile = Profile::staticGet($remote->id);
-                       $orig_remote = clone($remote);
-                       $orig_profile = clone($profile);
-                       # XXX: compare current postNotice and updateProfile URLs to the ones
-                       # stored in the DB to avoid (possibly...) above attack
-               } else {
-                       $exists = false;
-                       $remote = new Remote_profile();
-                       $remote->uri = $omb['listener'];
-                       $profile = new Profile();
-               }
-
-               $profile->nickname = $nickname;
-               $profile->profileurl = $profile_url;
-
-               if ($fullname) {
-                       $profile->fullname = $fullname;
-               }
-               if ($homepage) {
-                       $profile->homepage = $homepage;
-               }
-               if ($bio) {
-                       $profile->bio = $bio;
-               }
-               if ($location) {
-                       $profile->location = $location;
-               }
-
-               if ($exists) {
-                       $profile->update($orig_profile);
-               } else {
-                       $profile->created = DB_DataObject_Cast::dateTime(); # current time
-                       $id = $profile->insert();
-                       if (!$id) {
-                               common_server_error(_('Error inserting new profile'));
-                               return;
-                       }
-                       $remote->id = $id;
-               }
-
-               if ($avatar_url) {
-                       if (!$this->add_avatar($profile, $avatar_url)) {
-                               common_server_error(_('Error inserting avatar'));
-                               return;
-                       }
-               }
-
-               $remote->postnoticeurl = $omb['post_notice_url'];
-               $remote->updateprofileurl = $omb['update_profile_url'];
-
-               if ($exists) {
-                       if (!$remote->update($orig_remote)) {
-                               common_server_error(_('Error updating remote profile'));
-                               return;
-                       }
-               } else {
-                       $remote->created = DB_DataObject_Cast::dateTime(); # current time
-                       if (!$remote->insert()) {
-                               common_server_error(_('Error inserting remote profile'));
-                               return;
-                       }
-               }
+        $profile_url = $req->get_parameter('omb_listener_profile');
+
+        if (!$profile_url) {
+            common_user_error(_('No profile URL returned by server.'));
+            return;
+        }
+
+        if (!Validate::uri($profile_url, array('allowed_schemes' => array('http', 'https')))) {
+            common_user_error(_('Invalid profile URL returned by server.'));
+            return;
+        }
+
+        if ($profile_url == common_local_url('showstream', array('nickname' => $nickname))) {
+            common_user_error(_('You can use the local subscription!'));
+            return;
+        }
+
+        common_debug('listenee: "'.$omb['listenee'].'"', __FILE__);
+
+        $user = User::staticGet('nickname', $omb['listenee']);
+
+        if (!$user) {
+            common_user_error(_('User being listened to doesn\'t exist.'));
+            return;
+        }
+
+        $other = User::staticGet('uri', $omb['listener']);
+
+        if ($other) {
+            common_user_error(_('You can use the local subscription!'));
+            return;
+        }
+
+        $fullname = $req->get_parameter('omb_listener_fullname');
+        $homepage = $req->get_parameter('omb_listener_homepage');
+        $bio = $req->get_parameter('omb_listener_bio');
+        $location = $req->get_parameter('omb_listener_location');
+        $avatar_url = $req->get_parameter('omb_listener_avatar');
+
+        list($newtok, $newsecret) = $this->access_token($omb);
+
+        if (!$newtok || !$newsecret) {
+            common_user_error(_('Couldn\'t convert request tokens to access tokens.'));
+            return;
+        }
+
+        # XXX: possible attack point; subscribe and return someone else's profile URI
+
+        $remote = Remote_profile::staticGet('uri', $omb['listener']);
+
+        if ($remote) {
+            $exists = true;
+            $profile = Profile::staticGet($remote->id);
+            $orig_remote = clone($remote);
+            $orig_profile = clone($profile);
+            # XXX: compare current postNotice and updateProfile URLs to the ones
+            # stored in the DB to avoid (possibly...) above attack
+        } else {
+            $exists = false;
+            $remote = new Remote_profile();
+            $remote->uri = $omb['listener'];
+            $profile = new Profile();
+        }
+
+        $profile->nickname = $nickname;
+        $profile->profileurl = $profile_url;
+
+        if ($fullname) {
+            $profile->fullname = $fullname;
+        }
+        if ($homepage) {
+            $profile->homepage = $homepage;
+        }
+        if ($bio) {
+            $profile->bio = $bio;
+        }
+        if ($location) {
+            $profile->location = $location;
+        }
+
+        if ($exists) {
+            $profile->update($orig_profile);
+        } else {
+            $profile->created = DB_DataObject_Cast::dateTime(); # current time
+            $id = $profile->insert();
+            if (!$id) {
+                common_server_error(_('Error inserting new profile'));
+                return;
+            }
+            $remote->id = $id;
+        }
+
+        if ($avatar_url) {
+            if (!$this->add_avatar($profile, $avatar_url)) {
+                common_server_error(_('Error inserting avatar'));
+                return;
+            }
+        }
+
+        $remote->postnoticeurl = $omb['post_notice_url'];
+        $remote->updateprofileurl = $omb['update_profile_url'];
+
+        if ($exists) {
+            if (!$remote->update($orig_remote)) {
+                common_server_error(_('Error updating remote profile'));
+                return;
+            }
+        } else {
+            $remote->created = DB_DataObject_Cast::dateTime(); # current time
+            if (!$remote->insert()) {
+                common_server_error(_('Error inserting remote profile'));
+                return;
+            }
+        }
 
         if ($user->hasBlocked($profile)) {
             $this->client_error(_('That user has blocked you from subscribing.'));
             return;
         }
 
-               $sub = new Subscription();
+        $sub = new Subscription();
 
-               $sub->subscriber = $remote->id;
-               $sub->subscribed = $user->id;
+        $sub->subscriber = $remote->id;
+        $sub->subscribed = $user->id;
 
         $sub_exists = false;
 
@@ -202,8 +204,8 @@ class FinishremotesubscribeAction extends Action {
             $sub->created = DB_DataObject_Cast::dateTime(); # current time
         }
 
-               $sub->token = $newtok;
-               $sub->secret = $newsecret;
+        $sub->token = $newtok;
+        $sub->secret = $newsecret;
 
         if ($sub_exists) {
             $result = $sub->update($orig_sub);
@@ -211,78 +213,80 @@ class FinishremotesubscribeAction extends Action {
             $result = $sub->insert();
         }
 
-               if (!$result) {
+        if (!$result) {
             common_log_db_error($sub, ($sub_exists) ? 'UPDATE' : 'INSERT', __FILE__);
-                       common_user_error(_('Couldn\'t insert new subscription.'));
-                       return;
-               }
+            common_user_error(_('Couldn\'t insert new subscription.'));
+            return;
+        }
 
-               # Notify user, if necessary
+        # Notify user, if necessary
 
-               mail_subscribe_notify_profile($user, $profile);
+        mail_subscribe_notify_profile($user, $profile);
 
-               # Clear the data
-               unset($_SESSION['oauth_authorization_request']);
+        # Clear the data
+        unset($_SESSION['oauth_authorization_request']);
 
-               # If we show subscriptions in reverse chron order, this should
-               # show up close to the top of the page
+        # If we show subscriptions in reverse chron order, this should
+        # show up close to the top of the page
 
-               common_redirect(common_local_url('subscribers', array('nickname' =>
-                                                                                                                        $user->nickname)));
-       }
+        common_redirect(common_local_url('subscribers', array('nickname' =>
+                                                             $user->nickname)));
+    }
 
-       function add_avatar($profile, $url) {
-               $temp_filename = tempnam(sys_get_temp_dir(), 'listener_avatar');
-               copy($url, $temp_filename);
-               return $profile->setOriginal($temp_filename);
-       }
+    function add_avatar($profile, $url)
+    {
+        $temp_filename = tempnam(sys_get_temp_dir(), 'listener_avatar');
+        copy($url, $temp_filename);
+        return $profile->setOriginal($temp_filename);
+    }
 
-       function access_token($omb) {
+    function access_token($omb)
+    {
 
-               common_debug('starting request for access token', __FILE__);
+        common_debug('starting request for access token', __FILE__);
 
-               $con = omb_oauth_consumer();
-               $tok = new OAuthToken($omb['token'], $omb['secret']);
+        $con = omb_oauth_consumer();
+        $tok = new OAuthToken($omb['token'], $omb['secret']);
 
-               common_debug('using request token "'.$tok.'"', __FILE__);
+        common_debug('using request token "'.$tok.'"', __FILE__);
 
-               $url = $omb['access_token_url'];
+        $url = $omb['access_token_url'];
 
-               common_debug('using access token url "'.$url.'"', __FILE__);
+        common_debug('using access token url "'.$url.'"', __FILE__);
 
-               # XXX: Is this the right thing to do? Strip off GET params and make them
-               # POST params? Seems wrong to me.
+        # XXX: Is this the right thing to do? Strip off GET params and make them
+        # POST params? Seems wrong to me.
 
-               $parsed = parse_url($url);
-               $params = array();
-               parse_str($parsed['query'], $params);
+        $parsed = parse_url($url);
+        $params = array();
+        parse_str($parsed['query'], $params);
 
-               $req = OAuthRequest::from_consumer_and_token($con, $tok, "POST", $url, $params);
+        $req = OAuthRequest::from_consumer_and_token($con, $tok, "POST", $url, $params);
 
-               $req->set_parameter('omb_version', OMB_VERSION_01);
+        $req->set_parameter('omb_version', OMB_VERSION_01);
 
-               # XXX: test to see if endpoint accepts this signature method
+        # XXX: test to see if endpoint accepts this signature method
 
-               $req->sign_request(omb_hmac_sha1(), $con, $tok);
+        $req->sign_request(omb_hmac_sha1(), $con, $tok);
 
-               # We re-use this tool's fetcher, since it's pretty good
+        # We re-use this tool's fetcher, since it's pretty good
 
-               common_debug('posting to access token url "'.$req->get_normalized_http_url().'"', __FILE__);
-               common_debug('posting request data "'.$req->to_postdata().'"', __FILE__);
+        common_debug('posting to access token url "'.$req->get_normalized_http_url().'"', __FILE__);
+        common_debug('posting request data "'.$req->to_postdata().'"', __FILE__);
 
-               $fetcher = Auth_Yadis_Yadis::getHTTPFetcher();
-               $result = $fetcher->post($req->get_normalized_http_url(),
-                                                                $req->to_postdata(),
+        $fetcher = Auth_Yadis_Yadis::getHTTPFetcher();
+        $result = $fetcher->post($req->get_normalized_http_url(),
+                                 $req->to_postdata(),
                                  array('User-Agent' => 'Laconica/' . LACONICA_VERSION));
 
-               common_debug('got result: "'.print_r($result,TRUE).'"', __FILE__);
+        common_debug('got result: "'.print_r($result,true).'"', __FILE__);
 
-               if ($result->status != 200) {
-                       return NULL;
-               }
+        if ($result->status != 200) {
+            return null;
+        }
 
-               parse_str($result->body, $return);
+        parse_str($result->body, $return);
 
-               return array($return['oauth_token'], $return['oauth_token_secret']);
-       }
+        return array($return['oauth_token'], $return['oauth_token_secret']);
+    }
 }
index 6811fc05af647808fd384934c79e20d0bfc44f57..30e98960c170209b2b50cb32f860d41d50e2907a 100644 (file)
@@ -23,180 +23,185 @@ define('LISTENER', 1);
 define('LISTENEE', -1);
 define('BOTH', 0);
 
-class FoafAction extends Action {
-
-       function is_readonly() {
-               return true;
-       }
-
-       function handle($args) {
-               parent::handle($args);
-
-               $nickname = $this->trimmed('nickname');
-
-               $user = User::staticGet('nickname', $nickname);
-
-               if (!$user) {
-                       common_user_error(_('No such user.'), 404);
-                       return;
-               }
-
-               $profile = $user->getProfile();
-
-               if (!$profile) {
-                       common_server_error(_('User has no profile.'), 500);
-                       return;
-               }
-
-               header('Content-Type: application/rdf+xml');
-
-               common_start_xml();
-               common_element_start('rdf:RDF', array('xmlns:rdf' =>
-                                                                                         'http://www.w3.org/1999/02/22-rdf-syntax-ns#',
-                                                                                         'xmlns:rdfs' =>
-                                                                                         'http://www.w3.org/2000/01/rdf-schema#',
-                                                                                         'xmlns:geo' =>
-                                                                                         'http://www.w3.org/2003/01/geo/wgs84_pos#',
-                                                                                         'xmlns' => 'http://xmlns.com/foaf/0.1/'));
-
-               # This is the document about the user
-
-               $this->show_ppd('', $user->uri);
-
-               # XXX: might not be a person
-               common_element_start('Person', array('rdf:about' =>
-                                                                                        $user->uri));
-               common_element('mbox_sha1sum', NULL, sha1('mailto:' . $user->email));
-               if ($profile->fullname) {
-                       common_element('name', NULL, $profile->fullname);
-               }
-               if ($profile->homepage) {
-                       common_element('homepage', array('rdf:resource' => $profile->homepage));
-               }
-               if ($profile->bio) {
-                       common_element('rdfs:comment', NULL, $profile->bio);
-               }
-               # XXX: more structured location data
-               if ($profile->location) {
-                       common_element_start('based_near');
-                       common_element_start('geo:SpatialThing');
-                       common_element('name', NULL, $profile->location);
-                       common_element_end('geo:SpatialThing');
-                       common_element_end('based_near');
-               }
-
-               $this->show_microblogging_account($profile, common_root_url());
-
-               $avatar = $profile->getOriginalAvatar();
-
-               if ($avatar) {
-                       common_element_start('img');
-                       common_element_start('Image', array('rdf:about' => $avatar->url));
-                       foreach (array(AVATAR_PROFILE_SIZE, AVATAR_STREAM_SIZE, AVATAR_MINI_SIZE) as $size) {
-                               $scaled = $profile->getAvatar($size);
-                               if (!$scaled->original) { # sometimes the original has one of our scaled sizes
-                                       common_element_start('thumbnail');
-                                       common_element('Image', array('rdf:about' => $scaled->url));
-                                       common_element_end('thumbnail');
-                               }
-                       }
-                       common_element_end('Image');
-                       common_element_end('img');
-               }
-
-               # Get people user is subscribed to
-
-               $person = array();
-
-               $sub = new Subscription();
-               $sub->subscriber = $profile->id;
-               $sub->whereAdd('subscriber != subscribed');
-               
-               if ($sub->find()) {
-                       while ($sub->fetch()) {
-                               if ($sub->token) {
-                                       $other = Remote_profile::staticGet('id', $sub->subscribed);
-                               } else {
-                                       $other = User::staticGet('id', $sub->subscribed);
-                               }
-                               if (!$other) {
-                                       common_debug('Got a bad subscription: '.print_r($sub,TRUE));
-                                       continue;
-                               }
-                               common_element('knows', array('rdf:resource' => $other->uri));
-                               $person[$other->uri] = array(LISTENEE, $other);
-                       }
-               }
-
-               # Get people who subscribe to user
-
-               $sub = new Subscription();
-               $sub->subscribed = $profile->id;
-               $sub->whereAdd('subscriber != subscribed');
-
-               if ($sub->find()) {
-                       while ($sub->fetch()) {
-                               if ($sub->token) {
-                                       $other = Remote_profile::staticGet('id', $sub->subscriber);
-                               } else {
-                                       $other = User::staticGet('id', $sub->subscriber);
-                               }
-                               if (!$other) {
-                                       common_debug('Got a bad subscription: '.print_r($sub,TRUE));
-                                       continue;
-                               }
-                               if (array_key_exists($other->uri, $person)) {
-                                       $person[$other->uri][0] = BOTH;
-                               } else {
-                                       $person[$other->uri] = array(LISTENER, $other);
-                               }
-                       }
-               }
-
-               common_element_end('Person');
-
-               foreach ($person as $uri => $p) {
-                       $foaf_url = NULL;
-                       if ($p[1] instanceof User) {
-                               $foaf_url = common_local_url('foaf', array('nickname' => $p[1]->nickname));
-                       }
-                       $profile = Profile::staticGet($p[1]->id);
-                       common_element_start('Person', array('rdf:about' => $uri));
-                       if ($p[0] == LISTENER || $p[0] == BOTH) {
-                               common_element('knows', array('rdf:resource' => $user->uri));
-                       }
-                       $this->show_microblogging_account($profile, ($p[1] instanceof User) ?
-                                                                                         common_root_url() : NULL);
-                       if ($foaf_url) {
-                               common_element('rdfs:seeAlso', array('rdf:resource' => $foaf_url));
-                       }
-                       common_element_end('Person');
-                       if ($foaf_url) {
-                               $this->show_ppd($foaf_url, $uri);
-                       }
-               }
-
-               common_element_end('rdf:RDF');
-       }
-
-       function show_ppd($foaf_url, $person_uri) {
-               common_element_start('PersonalProfileDocument', array('rdf:about' => $foaf_url));
-               common_element('maker', array('rdf:resource' => $person_uri));
-               common_element('primaryTopic', array('rdf:resource' => $person_uri));
-               common_element_end('PersonalProfileDocument');
-       }
-
-       function show_microblogging_account($profile, $service=NULL) {
-               # Their account
-               common_element_start('holdsAccount');
-               common_element_start('OnlineAccount');
-               if ($service) {
-                       common_element('accountServiceHomepage', array('rdf:resource' =>
-                                                                                                                  $service));
-               }
-               common_element('accountName', NULL, $profile->nickname);
-               common_element('homepage', array('rdf:resource' => $profile->profileurl));
-               common_element_end('OnlineAccount');
-               common_element_end('holdsAccount');
-       }
+class FoafAction extends Action
+{
+
+    function is_readonly()
+    {
+        return true;
+    }
+
+    function handle($args)
+    {
+        parent::handle($args);
+
+        $nickname = $this->trimmed('nickname');
+
+        $user = User::staticGet('nickname', $nickname);
+
+        if (!$user) {
+            common_user_error(_('No such user.'), 404);
+            return;
+        }
+
+        $profile = $user->getProfile();
+
+        if (!$profile) {
+            common_server_error(_('User has no profile.'), 500);
+            return;
+        }
+
+        header('Content-Type: application/rdf+xml');
+
+        common_start_xml();
+        common_element_start('rdf:RDF', array('xmlns:rdf' =>
+                                              'http://www.w3.org/1999/02/22-rdf-syntax-ns#',
+                                              'xmlns:rdfs' =>
+                                              'http://www.w3.org/2000/01/rdf-schema#',
+                                              'xmlns:geo' =>
+                                              'http://www.w3.org/2003/01/geo/wgs84_pos#',
+                                              'xmlns' => 'http://xmlns.com/foaf/0.1/'));
+
+        # This is the document about the user
+
+        $this->show_ppd('', $user->uri);
+
+        # XXX: might not be a person
+        common_element_start('Person', array('rdf:about' =>
+                                             $user->uri));
+        common_element('mbox_sha1sum', null, sha1('mailto:' . $user->email));
+        if ($profile->fullname) {
+            common_element('name', null, $profile->fullname);
+        }
+        if ($profile->homepage) {
+            common_element('homepage', array('rdf:resource' => $profile->homepage));
+        }
+        if ($profile->bio) {
+            common_element('rdfs:comment', null, $profile->bio);
+        }
+        # XXX: more structured location data
+        if ($profile->location) {
+            common_element_start('based_near');
+            common_element_start('geo:SpatialThing');
+            common_element('name', null, $profile->location);
+            common_element_end('geo:SpatialThing');
+            common_element_end('based_near');
+        }
+
+        $this->show_microblogging_account($profile, common_root_url());
+
+        $avatar = $profile->getOriginalAvatar();
+
+        if ($avatar) {
+            common_element_start('img');
+            common_element_start('Image', array('rdf:about' => $avatar->url));
+            foreach (array(AVATAR_PROFILE_SIZE, AVATAR_STREAM_SIZE, AVATAR_MINI_SIZE) as $size) {
+                $scaled = $profile->getAvatar($size);
+                if (!$scaled->original) { # sometimes the original has one of our scaled sizes
+                    common_element_start('thumbnail');
+                    common_element('Image', array('rdf:about' => $scaled->url));
+                    common_element_end('thumbnail');
+                }
+            }
+            common_element_end('Image');
+            common_element_end('img');
+        }
+
+        # Get people user is subscribed to
+
+        $person = array();
+
+        $sub = new Subscription();
+        $sub->subscriber = $profile->id;
+        $sub->whereAdd('subscriber != subscribed');
+        
+        if ($sub->find()) {
+            while ($sub->fetch()) {
+                if ($sub->token) {
+                    $other = Remote_profile::staticGet('id', $sub->subscribed);
+                } else {
+                    $other = User::staticGet('id', $sub->subscribed);
+                }
+                if (!$other) {
+                    common_debug('Got a bad subscription: '.print_r($sub,true));
+                    continue;
+                }
+                common_element('knows', array('rdf:resource' => $other->uri));
+                $person[$other->uri] = array(LISTENEE, $other);
+            }
+        }
+
+        # Get people who subscribe to user
+
+        $sub = new Subscription();
+        $sub->subscribed = $profile->id;
+        $sub->whereAdd('subscriber != subscribed');
+
+        if ($sub->find()) {
+            while ($sub->fetch()) {
+                if ($sub->token) {
+                    $other = Remote_profile::staticGet('id', $sub->subscriber);
+                } else {
+                    $other = User::staticGet('id', $sub->subscriber);
+                }
+                if (!$other) {
+                    common_debug('Got a bad subscription: '.print_r($sub,true));
+                    continue;
+                }
+                if (array_key_exists($other->uri, $person)) {
+                    $person[$other->uri][0] = BOTH;
+                } else {
+                    $person[$other->uri] = array(LISTENER, $other);
+                }
+            }
+        }
+
+        common_element_end('Person');
+
+        foreach ($person as $uri => $p) {
+            $foaf_url = null;
+            if ($p[1] instanceof User) {
+                $foaf_url = common_local_url('foaf', array('nickname' => $p[1]->nickname));
+            }
+            $profile = Profile::staticGet($p[1]->id);
+            common_element_start('Person', array('rdf:about' => $uri));
+            if ($p[0] == LISTENER || $p[0] == BOTH) {
+                common_element('knows', array('rdf:resource' => $user->uri));
+            }
+            $this->show_microblogging_account($profile, ($p[1] instanceof User) ?
+                                              common_root_url() : null);
+            if ($foaf_url) {
+                common_element('rdfs:seeAlso', array('rdf:resource' => $foaf_url));
+            }
+            common_element_end('Person');
+            if ($foaf_url) {
+                $this->show_ppd($foaf_url, $uri);
+            }
+        }
+
+        common_element_end('rdf:RDF');
+    }
+
+    function show_ppd($foaf_url, $person_uri)
+    {
+        common_element_start('PersonalProfileDocument', array('rdf:about' => $foaf_url));
+        common_element('maker', array('rdf:resource' => $person_uri));
+        common_element('primaryTopic', array('rdf:resource' => $person_uri));
+        common_element_end('PersonalProfileDocument');
+    }
+
+    function show_microblogging_account($profile, $service=null)
+    {
+        # Their account
+        common_element_start('holdsAccount');
+        common_element_start('OnlineAccount');
+        if ($service) {
+            common_element('accountServiceHomepage', array('rdf:resource' =>
+                                                           $service));
+        }
+        common_element('accountName', null, $profile->nickname);
+        common_element('homepage', array('rdf:resource' => $profile->profileurl));
+        common_element_end('OnlineAccount');
+        common_element_end('holdsAccount');
+    }
 }
index 0aa7631dc2c2fc59314ce269aad42cf65a4985cb..8ecf200ec9182cd735575a4c9412229009e70e9d 100644 (file)
@@ -22,249 +22,259 @@ if (!defined('LACONICA')) { exit(1); }
 require_once(INSTALLDIR.'/lib/settingsaction.php');
 require_once(INSTALLDIR.'/lib/jabber.php');
 
-class ImsettingsAction extends SettingsAction {
-
-       function get_instructions() {
-               return _('You can send and receive notices through Jabber/GTalk [instant messages](%%doc.im%%). Configure your address and settings below.');
-       }
-
-       function show_form($msg=NULL, $success=false) {
-               $user = common_current_user();
-               $this->form_header(_('IM Settings'), $msg, $success);
-               common_element_start('form', array('method' => 'post',
-                                                                                  'id' => 'imsettings',
-                                                                                  'action' =>
-                                                                                  common_local_url('imsettings')));
-               common_hidden('token', common_session_token());
-
-               common_element('h2', NULL, _('Address'));
-
-               if ($user->jabber) {
-                       common_element_start('p');
-                       common_element('span', 'address confirmed', $user->jabber);
-                       common_element('span', 'input_instructions',
-                                      _('Current confirmed Jabber/GTalk address.'));
-                       common_hidden('jabber', $user->jabber);
-                       common_element_end('p');
-                       common_submit('remove', _('Remove'));
-               } else {
-                       $confirm = $this->get_confirmation();
-                       if ($confirm) {
-                               common_element_start('p');
-                               common_element('span', 'address unconfirmed', $confirm->address);
-                               common_element('span', 'input_instructions',
-                                             sprintf(_('Awaiting confirmation on this address. Check your Jabber/GTalk account for a message with further instructions. (Did you add %s to your buddy list?)'), jabber_daemon_address()));
-                               common_hidden('jabber', $confirm->address);
-                               common_element_end('p');
-                               common_submit('cancel', _('Cancel'));
-                       } else {
-                               common_input('jabber', _('IM Address'),
-                                                       ($this->arg('jabber')) ? $this->arg('jabber') : NULL,
-                                                sprintf(_('Jabber or GTalk address, like "UserName@example.org". First, make sure to add %s to your buddy list in your IM client or on GTalk.'), jabber_daemon_address()));
-                               common_submit('add', _('Add'));
-                       }
-               }
-
-               common_element('h2', NULL, _('Preferences'));
-
-               common_checkbox('jabbernotify',
-                               _('Send me notices through Jabber/GTalk.'),
-                               $user->jabbernotify);
-               common_checkbox('updatefrompresence',
-                               _('Post a notice when my Jabber/GTalk status changes.'),
-                               $user->updatefrompresence);
-               common_checkbox('jabberreplies',
-                               _('Send me replies through Jabber/GTalk from people I\'m not subscribed to.'),
-                               $user->jabberreplies);
-               common_checkbox('jabbermicroid',
-                               _('Publish a MicroID for my Jabber/GTalk address.'),
-                               $user->jabbermicroid);
-               common_submit('save', _('Save'));
-
-               common_element_end('form');
-               common_show_footer();
-       }
-
-       function get_confirmation() {
-               $user = common_current_user();
-               $confirm = new Confirm_address();
-               $confirm->user_id = $user->id;
-               $confirm->address_type = 'jabber';
-               if ($confirm->find(TRUE)) {
-                       return $confirm;
-               } else {
-                       return NULL;
-               }
-       }
-
-       function handle_post() {
-
-               # CSRF protection
-               $token = $this->trimmed('token');
-               if (!$token || $token != common_session_token()) {
-                       $this->show_form(_('There was a problem with your session token. Try again, please.'));
-                       return;
-               }
-
-               if ($this->arg('save')) {
-                       $this->save_preferences();
-               } else if ($this->arg('add')) {
-                       $this->add_address();
-               } else if ($this->arg('cancel')) {
-                       $this->cancel_confirmation();
-               } else if ($this->arg('remove')) {
-                       $this->remove_address();
-               } else {
-                       $this->show_form(_('Unexpected form submission.'));
-               }
-       }
-
-       function save_preferences() {
-
-               $jabbernotify = $this->boolean('jabbernotify');
-               $updatefrompresence = $this->boolean('updatefrompresence');
-               $jabberreplies = $this->boolean('jabberreplies');
-               $jabbermicroid = $this->boolean('jabbermicroid');
-
-               $user = common_current_user();
-
-               assert(!is_null($user)); # should already be checked
-
-               $user->query('BEGIN');
-
-               $original = clone($user);
-
-               $user->jabbernotify = $jabbernotify;
-               $user->updatefrompresence = $updatefrompresence;
-               $user->jabberreplies = $jabberreplies;
-               $user->jabbermicroid = $jabbermicroid;
-
-               $result = $user->update($original);
-
-               if ($result === FALSE) {
-                       common_log_db_error($user, 'UPDATE', __FILE__);
-                       common_server_error(_('Couldn\'t update user.'));
-                       return;
-               }
-
-               $user->query('COMMIT');
-
-               $this->show_form(_('Preferences saved.'), true);
-       }
-
-       function add_address() {
-
-               $user = common_current_user();
-
-               $jabber = $this->trimmed('jabber');
-
-               # Some validation
-
-               if (!$jabber) {
-                       $this->show_form(_('No Jabber ID.'));
-                       return;
-               }
-
-               $jabber = jabber_normalize_jid($jabber);
-
-               if (!$jabber) {
-                   $this->show_form(_('Cannot normalize that Jabber ID'));
-                   return;
-               }
-               if (!jabber_valid_base_jid($jabber)) {
-                   $this->show_form(_('Not a valid Jabber ID'));
-                   return;
-               } else if ($user->jabber == $jabber) {
-                   $this->show_form(_('That is already your Jabber ID.'));
-                   return;
-               } else if ($this->jabber_exists($jabber)) {
-                   $this->show_form(_('Jabber ID already belongs to another user.'));
-                   return;
-               }
-
-               $confirm = new Confirm_address();
-               $confirm->address = $jabber;
-               $confirm->address_type = 'jabber';
-               $confirm->user_id = $user->id;
-               $confirm->code = common_confirmation_code(64);
-
-               $result = $confirm->insert();
-
-               if ($result === FALSE) {
-                       common_log_db_error($confirm, 'INSERT', __FILE__);
-                       common_server_error(_('Couldn\'t insert confirmation code.'));
-                       return;
-               }
-
-               if (!common_config('queue', 'enabled')) {
-                       jabber_confirm_address($confirm->code,
-                                                                  $user->nickname,
-                                                                  $jabber);
-               }
-
-               $msg = sprintf(_('A confirmation code was sent to the IM address you added. You must approve %s for sending messages to you.'), jabber_daemon_address());
-
-               $this->show_form($msg, TRUE);
-       }
-
-       function cancel_confirmation() {
-               $jabber = $this->arg('jabber');
-               $confirm = $this->get_confirmation();
-               if (!$confirm) {
-                       $this->show_form(_('No pending confirmation to cancel.'));
-                       return;
-               }
-               if ($confirm->address != $jabber) {
-                       $this->show_form(_('That is the wrong IM address.'));
-                       return;
-               }
+class ImsettingsAction extends SettingsAction
+{
+
+    function get_instructions()
+    {
+        return _('You can send and receive notices through Jabber/GTalk [instant messages](%%doc.im%%). Configure your address and settings below.');
+    }
+
+    function show_form($msg=null, $success=false)
+    {
+        $user = common_current_user();
+        $this->form_header(_('IM Settings'), $msg, $success);
+        common_element_start('form', array('method' => 'post',
+                                           'id' => 'imsettings',
+                                           'action' =>
+                                           common_local_url('imsettings')));
+        common_hidden('token', common_session_token());
+
+        common_element('h2', null, _('Address'));
+
+        if ($user->jabber) {
+            common_element_start('p');
+            common_element('span', 'address confirmed', $user->jabber);
+            common_element('span', 'input_instructions',
+                           _('Current confirmed Jabber/GTalk address.'));
+            common_hidden('jabber', $user->jabber);
+            common_element_end('p');
+            common_submit('remove', _('Remove'));
+        } else {
+            $confirm = $this->get_confirmation();
+            if ($confirm) {
+                common_element_start('p');
+                common_element('span', 'address unconfirmed', $confirm->address);
+                common_element('span', 'input_instructions',
+                                sprintf(_('Awaiting confirmation on this address. Check your Jabber/GTalk account for a message with further instructions. (Did you add %s to your buddy list?)'), jabber_daemon_address()));
+                common_hidden('jabber', $confirm->address);
+                common_element_end('p');
+                common_submit('cancel', _('Cancel'));
+            } else {
+                common_input('jabber', _('IM Address'),
+                             ($this->arg('jabber')) ? $this->arg('jabber') : null,
+                         sprintf(_('Jabber or GTalk address, like "UserName@example.org". First, make sure to add %s to your buddy list in your IM client or on GTalk.'), jabber_daemon_address()));
+                common_submit('add', _('Add'));
+            }
+        }
+
+        common_element('h2', null, _('Preferences'));
+
+        common_checkbox('jabbernotify',
+                        _('Send me notices through Jabber/GTalk.'),
+                        $user->jabbernotify);
+        common_checkbox('updatefrompresence',
+                        _('Post a notice when my Jabber/GTalk status changes.'),
+                        $user->updatefrompresence);
+        common_checkbox('jabberreplies',
+                        _('Send me replies through Jabber/GTalk from people I\'m not subscribed to.'),
+                        $user->jabberreplies);
+        common_checkbox('jabbermicroid',
+                        _('Publish a MicroID for my Jabber/GTalk address.'),
+                        $user->jabbermicroid);
+        common_submit('save', _('Save'));
+
+        common_element_end('form');
+        common_show_footer();
+    }
+
+    function get_confirmation()
+    {
+        $user = common_current_user();
+        $confirm = new Confirm_address();
+        $confirm->user_id = $user->id;
+        $confirm->address_type = 'jabber';
+        if ($confirm->find(true)) {
+            return $confirm;
+        } else {
+            return null;
+        }
+    }
+
+    function handle_post()
+    {
+
+        # CSRF protection
+        $token = $this->trimmed('token');
+        if (!$token || $token != common_session_token()) {
+            $this->show_form(_('There was a problem with your session token. Try again, please.'));
+            return;
+        }
+
+        if ($this->arg('save')) {
+            $this->save_preferences();
+        } else if ($this->arg('add')) {
+            $this->add_address();
+        } else if ($this->arg('cancel')) {
+            $this->cancel_confirmation();
+        } else if ($this->arg('remove')) {
+            $this->remove_address();
+        } else {
+            $this->show_form(_('Unexpected form submission.'));
+        }
+    }
+
+    function save_preferences()
+    {
+
+        $jabbernotify = $this->boolean('jabbernotify');
+        $updatefrompresence = $this->boolean('updatefrompresence');
+        $jabberreplies = $this->boolean('jabberreplies');
+        $jabbermicroid = $this->boolean('jabbermicroid');
+
+        $user = common_current_user();
+
+        assert(!is_null($user)); # should already be checked
+
+        $user->query('BEGIN');
+
+        $original = clone($user);
+
+        $user->jabbernotify = $jabbernotify;
+        $user->updatefrompresence = $updatefrompresence;
+        $user->jabberreplies = $jabberreplies;
+        $user->jabbermicroid = $jabbermicroid;
+
+        $result = $user->update($original);
+
+        if ($result === false) {
+            common_log_db_error($user, 'UPDATE', __FILE__);
+            common_server_error(_('Couldn\'t update user.'));
+            return;
+        }
+
+        $user->query('COMMIT');
+
+        $this->show_form(_('Preferences saved.'), true);
+    }
+
+    function add_address()
+    {
+
+        $user = common_current_user();
+
+        $jabber = $this->trimmed('jabber');
+
+        # Some validation
+
+        if (!$jabber) {
+            $this->show_form(_('No Jabber ID.'));
+            return;
+        }
+
+        $jabber = jabber_normalize_jid($jabber);
+
+        if (!$jabber) {
+            $this->show_form(_('Cannot normalize that Jabber ID'));
+            return;
+        }
+        if (!jabber_valid_base_jid($jabber)) {
+            $this->show_form(_('Not a valid Jabber ID'));
+            return;
+        } else if ($user->jabber == $jabber) {
+            $this->show_form(_('That is already your Jabber ID.'));
+            return;
+        } else if ($this->jabber_exists($jabber)) {
+            $this->show_form(_('Jabber ID already belongs to another user.'));
+            return;
+        }
+
+          $confirm = new Confirm_address();
+           $confirm->address = $jabber;
+           $confirm->address_type = 'jabber';
+           $confirm->user_id = $user->id;
+           $confirm->code = common_confirmation_code(64);
+
+        $result = $confirm->insert();
+
+        if ($result === false) {
+            common_log_db_error($confirm, 'INSERT', __FILE__);
+            common_server_error(_('Couldn\'t insert confirmation code.'));
+            return;
+        }
+
+        if (!common_config('queue', 'enabled')) {
+            jabber_confirm_address($confirm->code,
+                                   $user->nickname,
+                                   $jabber);
+        }
+
+        $msg = sprintf(_('A confirmation code was sent to the IM address you added. You must approve %s for sending messages to you.'), jabber_daemon_address());
+
+        $this->show_form($msg, true);
+    }
+
+    function cancel_confirmation()
+    {
+        $jabber = $this->arg('jabber');
+        $confirm = $this->get_confirmation();
+        if (!$confirm) {
+            $this->show_form(_('No pending confirmation to cancel.'));
+            return;
+        }
+        if ($confirm->address != $jabber) {
+            $this->show_form(_('That is the wrong IM address.'));
+            return;
+        }
 
         $result = $confirm->delete();
 
         if (!$result) {
-                       common_log_db_error($confirm, 'DELETE', __FILE__);
+            common_log_db_error($confirm, 'DELETE', __FILE__);
             $this->server_error(_('Couldn\'t delete email confirmation.'));
             return;
         }
 
-        $this->show_form(_('Confirmation cancelled.'), TRUE);
-       }
-
-       function remove_address() {
-
-               $user = common_current_user();
-               $jabber = $this->arg('jabber');
-
-               # Maybe an old tab open...?
-
-               if ($user->jabber != $jabber) {
-                   $this->show_form(_('That is not your Jabber ID.'));
-                   return;
-               }
-
-               $user->query('BEGIN');
-               $original = clone($user);
-               $user->jabber = NULL;
-               $result = $user->updateKeys($original);
-               if (!$result) {
-                       common_log_db_error($user, 'UPDATE', __FILE__);
-                       common_server_error(_('Couldn\'t update user.'));
-                       return;
-               }
-               $user->query('COMMIT');
-
-               # XXX: unsubscribe to the old address
-
-               $this->show_form(_('The address was removed.'), TRUE);
-       }
-
-       function jabber_exists($jabber) {
-               $user = common_current_user();
-               $other = User::staticGet('jabber', $jabber);
-               if (!$other) {
-                       return false;
-               } else {
-                       return $other->id != $user->id;
-               }
-       }
+        $this->show_form(_('Confirmation cancelled.'), true);
+    }
+
+    function remove_address()
+    {
+
+        $user = common_current_user();
+        $jabber = $this->arg('jabber');
+
+        # Maybe an old tab open...?
+
+        if ($user->jabber != $jabber) {
+            $this->show_form(_('That is not your Jabber ID.'));
+            return;
+        }
+
+        $user->query('BEGIN');
+        $original = clone($user);
+        $user->jabber = null;
+        $result = $user->updateKeys($original);
+        if (!$result) {
+            common_log_db_error($user, 'UPDATE', __FILE__);
+            common_server_error(_('Couldn\'t update user.'));
+            return;
+        }
+        $user->query('COMMIT');
+
+        # XXX: unsubscribe to the old address
+
+        $this->show_form(_('The address was removed.'), true);
+    }
+
+    function jabber_exists($jabber)
+    {
+        $user = common_current_user();
+        $other = User::staticGet('jabber', $jabber);
+        if (!$other) {
+            return false;
+        } else {
+            return $other->id != $user->id;
+        }
+    }
 }
index c752e404e9dc258b1a313274eaf46331c27d1489..da27814a6e1541715d26e366cea3ef61b4b1ab9c 100644 (file)
@@ -1,9 +1,12 @@
 <?php
-/*
- * Laconica - a distributed open-source microblogging tool
- * Copyright (C) 2008, Controlez-Vous, Inc.
+/**
+ * Laconica, the distributed open-source microblogging tool
  *
- * This program is free software: you can redistribute it and/or modify
+ * action handler for message inbox
+ *
+ * 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.
  *
  * 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  Message
+ * @package   Laconica
+ * @author    Evan Prodromou <evan@controlyourself.ca>
+ * @copyright 2008 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/mailbox.php';
+
+/**
+ * action handler for message inbox
+ *
+ * @category Message
+ * @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/
+ * @see      MailboxAction
  */
 
-if (!defined('LACONICA')) { exit(1); }
-
-require_once(INSTALLDIR.'/lib/mailbox.php');
-
-class InboxAction extends MailboxAction {
-       
-       function get_title($user, $page) {
-               if ($page > 1) {
-                       $title = sprintf(_("Inbox for %s - page %d"), $user->nickname, $page);
-               } else {
-                       $title = sprintf(_("Inbox for %s"), $user->nickname);
-               }
-               return $title;
-       }
-       
-       function get_messages($user, $page) {
-               $message = new Message();
-               $message->to_profile = $user->id;
-               $message->orderBy('created DESC, id DESC');
-               $message->limit((($page-1)*MESSAGES_PER_PAGE), MESSAGES_PER_PAGE + 1);
-
-               if ($message->find()) {
-                       return $message;
-               } else {
-                       return NULL;
-               }
-       }
-       
-       function get_message_profile($message) {
-               return $message->getFrom();
-       }
-       
-       function get_instructions() {
-               return _('This is your inbox, which lists your incoming private messages.');
-       }
+class InboxAction extends MailboxAction
+{
+    /**
+     * returns the title of the page
+     *
+     * @param User $user current user
+     * @param int  $page current page
+     *
+     * @return string localised title of the page
+     *
+     * @see MailboxAction::getTitle()
+     */
+
+    function getTitle($user, $page)
+    {
+        if ($page > 1) {
+            $title = sprintf(_("Inbox for %s - page %d"), $user->nickname, $page);
+        } else {
+            $title = sprintf(_("Inbox for %s"), $user->nickname);
+        }
+        return $title;
+    }
+
+    /**
+     * retrieve the messages for this user and this page
+     *
+     * Does a query for the right messages
+     *
+     * @param User $user The current user
+     * @param int  $page The page the user is on
+     *
+     * @return Message data object with stream for messages
+     *
+     * @see MailboxAction::getMessages()
+     */
+
+    function getMessages($user, $page)
+    {
+        $message = new Message();
+
+        $message->to_profile = $user->id;
+
+        $message->orderBy('created DESC, id DESC');
+        $message->limit((($page-1)*MESSAGES_PER_PAGE), MESSAGES_PER_PAGE + 1);
+
+        if ($message->find()) {
+            return $message;
+        } else {
+            return null;
+        }
+    }
+
+    /**
+     * returns the profile we want to show with the message
+     *
+     * For inboxes, we show the sender.
+     *
+     * @param Message $message The message to get the profile for
+     *
+     * @return Profile The profile of the message sender
+     *
+     * @see MailboxAction::getMessageProfile()
+     */
+
+    function getMessageProfile($message)
+    {
+        return $message->getFrom();
+    }
+
+    /**
+     * instructions for using this page
+     *
+     * @return string localised instructions for using the page
+     */
+
+    function getInstructions()
+    {
+        return _('This is your inbox, which lists your incoming private messages.');
+    }
 }
index c7d92085c163faff7999baba8f08186e6ae79e35..80e022a3df26b3602eadec59a954a4b865219ef3 100644 (file)
 
 if (!defined('LACONICA')) { exit(1); }
 
-class InviteAction extends Action {
+class InviteAction extends Action
+{
 
-       function is_readonly() {
-               return false;
-       }
+    function is_readonly()
+    {
+        return false;
+    }
 
-    function handle($args) {
+    function handle($args)
+    {
         parent::handle($args);
-               if (!common_logged_in()) {
-                       $this->client_error(sprintf(_('You must be logged in to invite other users to use %s'),
-                                                                               common_config('site', 'name')));
-                       return;
-               } else if ($_SERVER['REQUEST_METHOD'] == 'POST') {
-                       $this->send_invitations();
-               } else {
-                       $this->show_form();
-               }
-       }
-
-       function send_invitations() {
-
-               # CSRF protection
-               $token = $this->trimmed('token');
-               if (!$token || $token != common_session_token()) {
-                       $this->show_form(_('There was a problem with your session token. Try again, please.'));
-                       return;
-               }
-
-               $user = common_current_user();
-               $profile = $user->getProfile();
-
-               $bestname = $profile->getBestName();
-               $sitename = common_config('site', 'name');
-               $personal = $this->trimmed('personal');
-
-               $addresses = explode("\n", $this->trimmed('addresses'));
-
-               foreach ($addresses as $email) {
-                       $email = trim($email);
-                       if (!Validate::email($email, true)) {
-                               $this->show_form(sprintf(_('Invalid email address: %s'), $email));
-                               return;
-                       }
-               }
-
-               $already = array();
-               $subbed = array();
-
-               foreach ($addresses as $email) {
-                       $email = common_canonical_email($email);
-                       $other = User::staticGet('email', $email);
-                       if ($other) {
-                               if ($user->isSubscribed($other)) {
-                                       $already[] = $other;
-                               } else {
-                                       subs_subscribe_to($user, $other);
-                                       $subbed[] = $other;
-                               }
-                       } else {
-                               $sent[] = $email;
-                               $this->send_invitation($email, $user, $personal);
-                       }
-               }
-
-               common_show_header(_('Invitation(s) sent'));
-               if ($already) {
-                       common_element('p', NULL, _('You are already subscribed to these users:'));
-                       common_element_start('ul');
-                       foreach ($already as $other) {
-                               common_element('li', NULL, sprintf(_('%s (%s)'), $other->nickname, $other->email));
-                       }
-                       common_element_end('ul');
-               }
-               if ($subbed) {
-                       common_element('p', NULL, _('These people are already users and you were automatically subscribed to them:'));
-                       common_element_start('ul');
-                       foreach ($subbed as $other) {
-                               common_element('li', NULL, sprintf(_('%s (%s)'), $other->nickname, $other->email));
-                       }
-                       common_element_end('ul');
-               }
-               if ($sent) {
-                       common_element('p', NULL, _('Invitation(s) sent to the following people:'));
-                       common_element_start('ul');
-                       foreach ($sent as $other) {
-                               common_element('li', NULL, $other);
-                       }
-                       common_element_end('ul');
-                       common_element('p', NULL, _('You will be notified when your invitees accept the invitation and register on the site. Thanks for growing the community!'));
-               }
-               common_show_footer();
-       }
-
-       function show_top($error=NULL) {
-               if ($error) {
-                       common_element('p', 'error', $error);
-               } else {
-                       common_element_start('div', 'instructions');
-                       common_element('p', NULL,
-                                                  _('Use this form to invite your friends and colleagues to use this service.'));
-                       common_element_end('div');
-               }
-       }
-
-       function show_form($error=NULL) {
-
-               global $config;
-
-               common_show_header(_('Invite new users'), NULL, $error, array($this, 'show_top'));
-
-               common_element_start('form', array('method' => 'post',
-                                                                                  'id' => 'invite',
-                                                                                  'action' => common_local_url('invite')));
-               common_hidden('token', common_session_token());
-
-               common_textarea('addresses', _('Email addresses'),
-                                               $this->trimmed('addresses'),
-                                               _('Addresses of friends to invite (one per line)'));
-
-               common_textarea('personal', _('Personal message'),
-                                               $this->trimmed('personal'),
-                                               _('Optionally add a personal message to the invitation.'));
-
-               common_submit('send', _('Send'));
-
-               common_element_end('form');
-
-               common_show_footer();
-       }
-
-       function send_invitation($email, $user, $personal) {
-
-               $profile = $user->getProfile();
-               $bestname = $profile->getBestName();
-
-               $sitename = common_config('site', 'name');
-
-               $invite = new Invitation();
-
-               $invite->address = $email;
-               $invite->address_type = 'email';
-               $invite->code = common_confirmation_code(128);
-               $invite->user_id = $user->id;
-               $invite->created = common_sql_now();
-
-               if (!$invite->insert()) {
-                       common_log_db_error($invite, 'INSERT', __FILE__);
-                       return false;
-               }
-
-               $recipients = array($email);
-
-               $headers['From'] = mail_notify_from();
-               $headers['To'] = $email;
-               $headers['Subject'] = sprintf(_('%1$s has invited you to join them on %2$s'), $bestname, $sitename);
-
-               $body = sprintf(_("%1\$s has invited you to join them on %2\$s (%3\$s).\n\n".
-                                                 "%2\$s is a micro-blogging service that lets you keep up-to-date with people you know and people who interest you.\n\n".
-                                                 "You can also share news about yourself, your thoughts, or your life online with people who know about you. ".
-                                                 "It's also great for meeting new people who share your interests.\n\n".
-                                                 "%1\$s said:\n\n%4\$s\n\n".
-                                                 "You can see %1\$s's profile page on %2\$s here:\n\n".
-                                                 "%5\$s\n\n".
-                                                 "If you'd like to try the service, click on the link below to accept the invitation.\n\n".
-                                                 "%6\$s\n\n".
-                                                 "If not, you can ignore this message. Thanks for your patience and your time.\n\n".
-                                                 "Sincerely, %2\$s\n"),
-                                               $bestname,
-                                               $sitename,
-                                               common_root_url(),
-                                               $personal,
-                                               common_local_url('showstream', array('nickname' => $user->nickname)),
-                                               common_local_url('register', array('code' => $invite->code)));
-
-               mail_send($recipients, $headers, $body);
-       }
+        if (!common_logged_in()) {
+            $this->client_error(sprintf(_('You must be logged in to invite other users to use %s'),
+                                        common_config('site', 'name')));
+            return;
+        } else if ($_SERVER['REQUEST_METHOD'] == 'POST') {
+            $this->send_invitations();
+        } else {
+            $this->show_form();
+        }
+    }
+
+    function send_invitations()
+    {
+
+        # CSRF protection
+        $token = $this->trimmed('token');
+        if (!$token || $token != common_session_token()) {
+            $this->show_form(_('There was a problem with your session token. Try again, please.'));
+            return;
+        }
+
+        $user = common_current_user();
+        $profile = $user->getProfile();
+
+        $bestname = $profile->getBestName();
+        $sitename = common_config('site', 'name');
+        $personal = $this->trimmed('personal');
+
+        $addresses = explode("\n", $this->trimmed('addresses'));
+
+        foreach ($addresses as $email) {
+            $email = trim($email);
+            if (!Validate::email($email, true)) {
+                $this->show_form(sprintf(_('Invalid email address: %s'), $email));
+                return;
+            }
+        }
+
+        $already = array();
+        $subbed = array();
+
+        foreach ($addresses as $email) {
+            $email = common_canonical_email($email);
+            $other = User::staticGet('email', $email);
+            if ($other) {
+                if ($user->isSubscribed($other)) {
+                    $already[] = $other;
+                } else {
+                    subs_subscribe_to($user, $other);
+                    $subbed[] = $other;
+                }
+            } else {
+                $sent[] = $email;
+                $this->send_invitation($email, $user, $personal);
+            }
+        }
+
+        common_show_header(_('Invitation(s) sent'));
+        if ($already) {
+            common_element('p', null, _('You are already subscribed to these users:'));
+            common_element_start('ul');
+            foreach ($already as $other) {
+                common_element('li', null, sprintf(_('%s (%s)'), $other->nickname, $other->email));
+            }
+            common_element_end('ul');
+        }
+        if ($subbed) {
+            common_element('p', null, _('These people are already users and you were automatically subscribed to them:'));
+            common_element_start('ul');
+            foreach ($subbed as $other) {
+                common_element('li', null, sprintf(_('%s (%s)'), $other->nickname, $other->email));
+            }
+            common_element_end('ul');
+        }
+        if ($sent) {
+            common_element('p', null, _('Invitation(s) sent to the following people:'));
+            common_element_start('ul');
+            foreach ($sent as $other) {
+                common_element('li', null, $other);
+            }
+            common_element_end('ul');
+            common_element('p', null, _('You will be notified when your invitees accept the invitation and register on the site. Thanks for growing the community!'));
+        }
+        common_show_footer();
+    }
+
+    function show_top($error=null)
+    {
+        if ($error) {
+            common_element('p', 'error', $error);
+        } else {
+            common_element_start('div', 'instructions');
+            common_element('p', null,
+                           _('Use this form to invite your friends and colleagues to use this service.'));
+            common_element_end('div');
+        }
+    }
+
+    function show_form($error=null)
+    {
+
+        global $config;
+
+        common_show_header(_('Invite new users'), null, $error, array($this, 'show_top'));
+
+        common_element_start('form', array('method' => 'post',
+                                           'id' => 'invite',
+                                           'action' => common_local_url('invite')));
+        common_hidden('token', common_session_token());
+
+        common_textarea('addresses', _('Email addresses'),
+                        $this->trimmed('addresses'),
+                        _('Addresses of friends to invite (one per line)'));
+
+        common_textarea('personal', _('Personal message'),
+                        $this->trimmed('personal'),
+                        _('Optionally add a personal message to the invitation.'));
+
+        common_submit('send', _('Send'));
+
+        common_element_end('form');
+
+        common_show_footer();
+    }
+
+    function send_invitation($email, $user, $personal)
+    {
+
+        $profile = $user->getProfile();
+        $bestname = $profile->getBestName();
+
+        $sitename = common_config('site', 'name');
+
+        $invite = new Invitation();
+
+        $invite->address = $email;
+        $invite->address_type = 'email';
+        $invite->code = common_confirmation_code(128);
+        $invite->user_id = $user->id;
+        $invite->created = common_sql_now();
+
+        if (!$invite->insert()) {
+            common_log_db_error($invite, 'INSERT', __FILE__);
+            return false;
+        }
+
+        $recipients = array($email);
+
+        $headers['From'] = mail_notify_from();
+        $headers['To'] = $email;
+        $headers['Subject'] = sprintf(_('%1$s has invited you to join them on %2$s'), $bestname, $sitename);
+
+        $body = sprintf(_("%1\$s has invited you to join them on %2\$s (%3\$s).\n\n".
+                          "%2\$s is a micro-blogging service that lets you keep up-to-date with people you know and people who interest you.\n\n".
+                          "You can also share news about yourself, your thoughts, or your life online with people who know about you. ".
+                          "It's also great for meeting new people who share your interests.\n\n".
+                          "%1\$s said:\n\n%4\$s\n\n".
+                          "You can see %1\$s's profile page on %2\$s here:\n\n".
+                          "%5\$s\n\n".
+                          "If you'd like to try the service, click on the link below to accept the invitation.\n\n".
+                          "%6\$s\n\n".
+                          "If not, you can ignore this message. Thanks for your patience and your time.\n\n".
+                          "Sincerely, %2\$s\n"),
+                        $bestname,
+                        $sitename,
+                        common_root_url(),
+                        $personal,
+                        common_local_url('showstream', array('nickname' => $user->nickname)),
+                        common_local_url('register', array('code' => $invite->code)));
+
+        mail_send($recipients, $headers, $body);
+    }
 
 }
index ccec9cf8a787818e20cb518f64b44bfd31b30336..8600d44fd3e05f82605ebbce04dd8ab6cc1d0efe 100644 (file)
 
 if (!defined('LACONICA')) { exit(1); }
 
-class LoginAction extends Action {
+class LoginAction extends Action
+{
 
-       function is_readonly() {
-               return true;
-       }
+    function is_readonly()
+    {
+        return true;
+    }
 
-       function handle($args) {
-               parent::handle($args);
-               if (common_is_real_login()) {
-                       common_user_error(_('Already logged in.'));
-               } else if ($_SERVER['REQUEST_METHOD'] == 'POST') {
-                       $this->check_login();
-               } else {
-                       $this->show_form();
-               }
-       }
+    function handle($args)
+    {
+        parent::handle($args);
+        if (common_is_real_login()) {
+            common_user_error(_('Already logged in.'));
+        } else if ($_SERVER['REQUEST_METHOD'] == 'POST') {
+            $this->check_login();
+        } else {
+            $this->show_form();
+        }
+    }
 
-       function check_login() {
-               # XXX: login throttle
+    function check_login()
+    {
+        # XXX: login throttle
 
-               # CSRF protection - token set in common_notice_form()
-               $token = $this->trimmed('token');
-               if (!$token || $token != common_session_token()) {
-                       $this->client_error(_('There was a problem with your session token. Try again, please.'));
-                       return;
-               }
+        # CSRF protection - token set in common_notice_form()
+        $token = $this->trimmed('token');
+        if (!$token || $token != common_session_token()) {
+            $this->client_error(_('There was a problem with your session token. Try again, please.'));
+            return;
+        }
 
-               $nickname = common_canonical_nickname($this->trimmed('nickname'));
-               $password = $this->arg('password');
-               if (common_check_user($nickname, $password)) {
-                       # success!
-                       if (!common_set_user($nickname)) {
-                               common_server_error(_('Error setting user.'));
-                               return;
-                       }
-                       common_real_login(true);
-                       if ($this->boolean('rememberme')) {
-                               common_debug('Adding rememberme cookie for ' . $nickname);
-                               common_rememberme();
-                       }
-                       # success!
-                       $url = common_get_returnto();
-                       if ($url) {
-                               # We don't have to return to it again
-                               common_set_returnto(NULL);
-                       } else {
-                               $url = common_local_url('all',
-                                                                               array('nickname' =>
-                                                                                         $nickname));
-                       }
-                       common_redirect($url);
-               } else {
-                       $this->show_form(_('Incorrect username or password.'));
-                       return;
-               }
+        $nickname = common_canonical_nickname($this->trimmed('nickname'));
+        $password = $this->arg('password');
+        if (common_check_user($nickname, $password)) {
+            # success!
+            if (!common_set_user($nickname)) {
+                common_server_error(_('Error setting user.'));
+                return;
+            }
+            common_real_login(true);
+            if ($this->boolean('rememberme')) {
+                common_debug('Adding rememberme cookie for ' . $nickname);
+                common_rememberme();
+            }
+            # success!
+            $url = common_get_returnto();
+            if ($url) {
+                # We don't have to return to it again
+                common_set_returnto(null);
+            } else {
+                $url = common_local_url('all',
+                                        array('nickname' =>
+                                              $nickname));
+            }
+            common_redirect($url);
+        } else {
+            $this->show_form(_('Incorrect username or password.'));
+            return;
+        }
 
-               # success!
-               if (!common_set_user($user)) {
-                       common_server_error(_('Error setting user.'));
-                       return;
-               }
+        # success!
+        if (!common_set_user($user)) {
+            common_server_error(_('Error setting user.'));
+            return;
+        }
 
-               common_real_login(true);
+        common_real_login(true);
 
-               if ($this->boolean('rememberme')) {
-                       common_debug('Adding rememberme cookie for ' . $nickname);
-                       common_rememberme($user);
-               }
-               # success!
-               $url = common_get_returnto();
-               if ($url) {
-                       # We don't have to return to it again
-                       common_set_returnto(NULL);
-               } else {
-                       $url = common_local_url('all',
-                                                                       array('nickname' =>
-                                                                                 $nickname));
-               }
-               common_redirect($url);
-       }
+        if ($this->boolean('rememberme')) {
+            common_debug('Adding rememberme cookie for ' . $nickname);
+            common_rememberme($user);
+        }
+        # success!
+        $url = common_get_returnto();
+        if ($url) {
+            # We don't have to return to it again
+            common_set_returnto(null);
+        } else {
+            $url = common_local_url('all',
+                                    array('nickname' =>
+                                          $nickname));
+        }
+        common_redirect($url);
+    }
 
-       function show_form($error=NULL) {
-               common_show_header(_('Login'), NULL, $error, array($this, 'show_top'));
-               common_element_start('form', array('method' => 'post',
-                                                                                  'id' => 'login',
-                                                                                  'action' => common_local_url('login')));
-               common_input('nickname', _('Nickname'));
-               common_password('password', _('Password'));
-               common_checkbox('rememberme', _('Remember me'), false,
-                               _('Automatically login in the future; ' .
-                                  'not for shared computers!'));
-               common_submit('submit', _('Login'));
-               common_hidden('token', common_session_token());
-               common_element_end('form');
-               common_element_start('p');
-               common_element('a', array('href' => common_local_url('recoverpassword')),
-                                          _('Lost or forgotten password?'));
-               common_element_end('p');
-               common_show_footer();
-       }
+    function show_form($error=null)
+    {
+        common_show_header(_('Login'), null, $error, array($this, 'show_top'));
+        common_element_start('form', array('method' => 'post',
+                                           'id' => 'login',
+                                           'action' => common_local_url('login')));
+        common_input('nickname', _('Nickname'));
+        common_password('password', _('Password'));
+        common_checkbox('rememberme', _('Remember me'), false,
+                        _('Automatically login in the future; ' .
+                           'not for shared computers!'));
+        common_submit('submit', _('Login'));
+        common_hidden('token', common_session_token());
+        common_element_end('form');
+        common_element_start('p');
+        common_element('a', array('href' => common_local_url('recoverpassword')),
+                       _('Lost or forgotten password?'));
+        common_element_end('p');
+        common_show_footer();
+    }
 
-       function get_instructions() {
-               if (common_logged_in() &&
-                       !common_is_real_login() &&
-                       common_get_returnto())
-               {
-                       # rememberme logins have to reauthenticate before
-                       # changing any profile settings (cookie-stealing protection)
-                       return _('For security reasons, please re-enter your ' .
-                                        'user name and password ' .
-                                        'before changing your settings.');
-               } else {
-                       return _('Login with your username and password. ' .
-                                        'Don\'t have a username yet? ' .
-                                        '[Register](%%action.register%%) a new account, or ' .
-                                        'try [OpenID](%%action.openidlogin%%). ');
-               }
-       }
+    function get_instructions()
+    {
+        if (common_logged_in() &&
+            !common_is_real_login() &&
+            common_get_returnto())
+        {
+            # rememberme logins have to reauthenticate before
+            # changing any profile settings (cookie-stealing protection)
+            return _('For security reasons, please re-enter your ' .
+                     'user name and password ' .
+                     'before changing your settings.');
+        } else {
+            return _('Login with your username and password. ' .
+                     'Don\'t have a username yet? ' .
+                     '[Register](%%action.register%%) a new account, or ' .
+                     'try [OpenID](%%action.openidlogin%%). ');
+        }
+    }
 
-       function show_top($error=NULL) {
-               if ($error) {
-                       common_element('p', 'error', $error);
-               } else {
-                       $instr = $this->get_instructions();
-                       $output = common_markup_to_html($instr);
-                       common_element_start('div', 'instructions');
-                       common_raw($output);
-                       common_element_end('div');
-               }
-       }
+    function show_top($error=null)
+    {
+        if ($error) {
+            common_element('p', 'error', $error);
+        } else {
+            $instr = $this->get_instructions();
+            $output = common_markup_to_html($instr);
+            common_element_start('div', 'instructions');
+            common_raw($output);
+            common_element_end('div');
+        }
+    }
 }
index f00fa0ba7f2f39298e77cdd365099b3d53cb8954..201378730d312403fb6e6af85c6e19205a9b2f7f 100644 (file)
@@ -21,21 +21,24 @@ if (!defined('LACONICA')) { exit(1); }
 
 require_once(INSTALLDIR.'/lib/openid.php');
 
-class LogoutAction extends Action {
-       
-       function is_readonly() {
-               return true;
-       }
-       
-       function handle($args) {
-               parent::handle($args);
-               if (!common_logged_in()) {
-                       common_user_error(_('Not logged in.'));
-               } else {
-                       common_set_user(NULL);
-                       common_real_login(false); # not logged in
-                       common_forgetme(); # don't log back in!
-                       common_redirect(common_local_url('public'));
-               }
-       }
+class LogoutAction extends Action
+{
+    
+    function is_readonly()
+    {
+        return true;
+    }
+    
+    function handle($args)
+    {
+        parent::handle($args);
+        if (!common_logged_in()) {
+            common_user_error(_('Not logged in.'));
+        } else {
+            common_set_user(null);
+            common_real_login(false); # not logged in
+            common_forgetme(); # don't log back in!
+            common_redirect(common_local_url('public'));
+        }
+    }
 }
index 104467d2979c33fec91ae1a71301334dc522995d..13ddc4e3ed35bd456bac4665964e0cb2814628f3 100644 (file)
 
 if (!defined('LACONICA')) { exit(1); }
 
-class MicrosummaryAction extends Action {
+class MicrosummaryAction extends Action
+{
 
-       function handle($args) {
+    function handle($args)
+    {
 
-               parent::handle($args);
+        parent::handle($args);
 
-               $nickname = common_canonical_nickname($this->arg('nickname'));
-               $user = User::staticGet('nickname', $nickname);
+        $nickname = common_canonical_nickname($this->arg('nickname'));
+        $user = User::staticGet('nickname', $nickname);
 
-               if (!$user) {
-                       $this->client_error(_('No such user'), 404);
-                       return;
-               }
-               
-               $notice = $user->getCurrentNotice();
-               
-               if (!$notice) {
-                       $this->client_error(_('No current status'), 404);
-               }
-               
-               header('Content-Type: text/plain');
-               
-               print $user->nickname . ': ' . $notice->content;
-       }
+        if (!$user) {
+            $this->client_error(_('No such user'), 404);
+            return;
+        }
+        
+        $notice = $user->getCurrentNotice();
+        
+        if (!$notice) {
+            $this->client_error(_('No current status'), 404);
+        }
+        
+        header('Content-Type: text/plain');
+        
+        print $user->nickname . ': ' . $notice->content;
+    }
 }
index da48fc7e7a07ad8806d6d2b0bd807952690585f9..27fa9d5182c3c162afe31d5407c956ac4b1be456 100644 (file)
 
 if (!defined('LACONICA')) { exit(1); }
 
-class NewmessageAction extends Action {
-       
-       function handle($args) {
-               parent::handle($args);
-
-               if (!common_logged_in()) {
-                       $this->client_error(_('Not logged in.'), 403);
-               } else if ($_SERVER['REQUEST_METHOD'] == 'POST') {
-                       $this->save_new_message();
-               } else {
-                       $this->show_form();
-               }
-       }
-
-       function save_new_message() {
-               $user = common_current_user();
-               assert($user); # XXX: maybe an error instead...
-
-               # CSRF protection
-               
-               $token = $this->trimmed('token');
-               if (!$token || $token != common_session_token()) {
-                       $this->show_form(_('There was a problem with your session token. Try again, please.'));
-                       return;
-               }
-               
-               $content = $this->trimmed('content');
-               $to = $this->trimmed('to');
-               
-               if (!$content) {
-                       $this->show_form(_('No content!'));
-                       return;
-               } else {
-                       $content_shortened = common_shorten_links($content);
-
-                       if (mb_strlen($content_shortened) > 140) {
-                               common_debug("Content = '$content_shortened'", __FILE__);
-                               common_debug("mb_strlen(\$content) = " . mb_strlen($content_shortened), __FILE__);
-                               $this->show_form(_('That\'s too long. Max message size is 140 chars.'));
-                               return;
-                       }
-               }
-
-               $other = User::staticGet('id', $to);
-               
-               if (!$other) {
-                       $this->show_form(_('No recipient specified.'));
-                       return;
-               } else if (!$user->mutuallySubscribed($other)) {
-                       $this->client_error(_('You can\'t send a message to this user.'), 404);
-                       return;
-               } else if ($user->id == $other->id) {
-                       $this->client_error(_('Don\'t send a message to yourself; just say it to yourself quietly instead.'), 403);
-                       return;
-               }
-               
-               $message = Message::saveNew($user->id, $other->id, $content, 'web');
-               
-               if (is_string($message)) {
-                       $this->show_form($message);
-                       return;
-               }
-
-               $this->notify($user, $other, $message);
-
-               $url = common_local_url('outbox', array('nickname' => $user->nickname));
-
-               common_redirect($url, 303);
-       }
-
-       function show_top($params) {
-
-               list($content, $user, $to) = $params;
-               
-               assert(!is_null($user));
-
-               common_message_form($content, $user, $to);
-       }
-
-       function show_form($msg=NULL) {
-               
-               $content = $this->trimmed('content');
-               $user = common_current_user();
-
-               $to = $this->trimmed('to');
-               
-               $other = User::staticGet('id', $to);
-
-               if (!$other) {
-                       $this->client_error(_('No such user'), 404);
-                       return;
-               }
-
-               if (!$user->mutuallySubscribed($other)) {
-                       $this->client_error(_('You can\'t send a message to this user.'), 404);
-                       return;
-               }
-               
-               common_show_header(_('New message'), NULL,
-                                                  array($content, $user, $other),
-                                  array($this, 'show_top'));
-               
-               if ($msg) {
-                       common_element('p', array('id'=>'error'), $msg);
-               }
-               
-               common_show_footer();
-       }
-       
-       function notify($from, $to, $message) {
-               mail_notify_message($message, $from, $to);
-               # XXX: Jabber, SMS notifications... probably queued
-       }
+class NewmessageAction extends Action
+{
+    
+    function handle($args)
+    {
+        parent::handle($args);
+
+        if (!common_logged_in()) {
+            $this->client_error(_('Not logged in.'), 403);
+        } else if ($_SERVER['REQUEST_METHOD'] == 'POST') {
+            $this->save_new_message();
+        } else {
+            $this->show_form();
+        }
+    }
+
+    function save_new_message()
+    {
+        $user = common_current_user();
+        assert($user); # XXX: maybe an error instead...
+
+        # CSRF protection
+        
+        $token = $this->trimmed('token');
+        if (!$token || $token != common_session_token()) {
+            $this->show_form(_('There was a problem with your session token. Try again, please.'));
+            return;
+        }
+        
+        $content = $this->trimmed('content');
+        $to = $this->trimmed('to');
+        
+        if (!$content) {
+            $this->show_form(_('No content!'));
+            return;
+        } else {
+            $content_shortened = common_shorten_links($content);
+
+            if (mb_strlen($content_shortened) > 140) {
+                common_debug("Content = '$content_shortened'", __FILE__);
+                common_debug("mb_strlen(\$content) = " . mb_strlen($content_shortened), __FILE__);
+                $this->show_form(_('That\'s too long. Max message size is 140 chars.'));
+                return;
+            }
+        }
+
+        $other = User::staticGet('id', $to);
+        
+        if (!$other) {
+            $this->show_form(_('No recipient specified.'));
+            return;
+        } else if (!$user->mutuallySubscribed($other)) {
+            $this->client_error(_('You can\'t send a message to this user.'), 404);
+            return;
+        } else if ($user->id == $other->id) {
+            $this->client_error(_('Don\'t send a message to yourself; just say it to yourself quietly instead.'), 403);
+            return;
+        }
+        
+        $message = Message::saveNew($user->id, $other->id, $content, 'web');
+        
+        if (is_string($message)) {
+            $this->show_form($message);
+            return;
+        }
+
+        $this->notify($user, $other, $message);
+
+        $url = common_local_url('outbox', array('nickname' => $user->nickname));
+
+        common_redirect($url, 303);
+    }
+
+    function show_top($params)
+    {
+
+        list($content, $user, $to) = $params;
+        
+        assert(!is_null($user));
+
+        common_message_form($content, $user, $to);
+    }
+
+    function show_form($msg=null)
+    {
+        
+        $content = $this->trimmed('content');
+        $user = common_current_user();
+
+        $to = $this->trimmed('to');
+        
+        $other = User::staticGet('id', $to);
+
+        if (!$other) {
+            $this->client_error(_('No such user'), 404);
+            return;
+        }
+
+        if (!$user->mutuallySubscribed($other)) {
+            $this->client_error(_('You can\'t send a message to this user.'), 404);
+            return;
+        }
+        
+        common_show_header(_('New message'), null,
+                           array($content, $user, $other),
+                           array($this, 'show_top'));
+        
+        if ($msg) {
+            common_element('p', array('id'=>'error'), $msg);
+        }
+        
+        common_show_footer();
+    }
+    
+    function notify($from, $to, $message)
+    {
+        mail_notify_message($message, $from, $to);
+        # XXX: Jabber, SMS notifications... probably queued
+    }
 }
index 42b48923f56b8d104f68a58bc57b9e3410e224ba..c412e893decb675e01aa74a9b86a4fe14a947243 100644 (file)
  *
  * 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
+ * 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/>.
+ * along with this program.     If not, see <http://www.gnu.org/licenses/>.
  */
 
 if (!defined('LACONICA')) { exit(1); }
 
 require_once INSTALLDIR . '/lib/noticelist.php';
 
-class NewnoticeAction extends Action {
-
-       function handle($args) {
-               parent::handle($args);
-
-               if (!common_logged_in()) {
-                       common_user_error(_('Not logged in.'));
-               } else if ($_SERVER['REQUEST_METHOD'] == 'POST') {
-
-                       # CSRF protection - token set in common_notice_form()
-                       $token = $this->trimmed('token');
-                       if (!$token || $token != common_session_token()) {
-                               $this->client_error(_('There was a problem with your session token. Try again, please.'));
-                               return;
-                       }
-
-                       $this->save_new_notice();
-               } else {
-                       $this->show_form();
-               }
-       }
-
-       function save_new_notice() {
-
-               $user = common_current_user();
-               assert($user); # XXX: maybe an error instead...
-               $content = $this->trimmed('status_textarea');
-
-               if (!$content) {
-                       $this->show_form(_('No content!'));
-                       return;
-               } else {
-                       $content_shortened = common_shorten_links($content);
-
-                       if (mb_strlen($content_shortened) > 140) {
-                               common_debug("Content = '$content_shortened'", __FILE__);
-                               common_debug("mb_strlen(\$content) = " . mb_strlen($content_shortened), __FILE__);
-                               $this->show_form(_('That\'s too long. Max notice size is 140 chars.'));
-                               return;
-                       }
-               }
-
-               $inter = new CommandInterpreter();
-
-               $cmd = $inter->handle_command($user, $content_shortened);
-
-               if ($cmd) {
-                       if ($this->boolean('ajax')) {
-                               $cmd->execute(new AjaxWebChannel());
-                       } else {
-                               $cmd->execute(new WebChannel());
-                       }
-                       return;
-               }
-
-               $replyto = $this->trimmed('inreplyto');
-
-               $notice = Notice::saveNew($user->id, $content, 'web', 1, ($replyto == 'false') ? NULL : $replyto);
-
-               if (is_string($notice)) {
-                       $this->show_form($notice);
-                       return;
-               }
-
-               common_broadcast_notice($notice);
-
-               if ($this->boolean('ajax')) {
-                       common_start_html('text/xml;charset=utf-8', true);
-                       common_element_start('head');
-                       common_element('title', null, _('Notice posted'));
-                       common_element_end('head');
-                       common_element_start('body');
-                       $this->show_notice($notice);
-                       common_element_end('body');
-                       common_element_end('html');
-               } else {
-                       $returnto = $this->trimmed('returnto');
-
-                       if ($returnto) {
-                               $url = common_local_url($returnto,
-                                                                               array('nickname' => $user->nickname));
-                       } else {
-                               $url = common_local_url('shownotice',
-                                                                               array('notice' => $notice->id));
-                       }
-                       common_redirect($url, 303);
-               }
-       }
-
-       function ajax_error_msg($msg) {
-               common_start_html('text/xml;charset=utf-8', true);
-               common_element_start('head');
-               common_element('title', null, _('Ajax Error'));
-               common_element_end('head');
-               common_element_start('body');
-               common_element('p', array('id' => 'error'), $msg);
-               common_element_end('body');
-               common_element_end('html');
-       }
-
-       function show_top($content=NULL) {
-               common_notice_form(NULL, $content);
-       }
-
-       function show_form($msg=NULL) {
-               if ($msg && $this->boolean('ajax')) {
-                       $this->ajax_error_msg($msg);
-                       return;
-               }
-               $content = $this->trimmed('status_textarea');
-               if (!$content) {
-                       $replyto = $this->trimmed('replyto');
-                       $profile = Profile::staticGet('nickname', $replyto);
-                       if ($profile) {
-                               $content = '@' . $profile->nickname . ' ';
-                       }
-               }
-               common_show_header(_('New notice'), NULL, $content,
-                                                  array($this, 'show_top'));
-               if ($msg) {
-                       common_element('p', array('id' => 'error'), $msg);
-               }
-               common_show_footer();
-       }
-
-       function show_notice($notice) {
+class NewnoticeAction extends Action
+{
+
+    function handle($args)
+    {
+        parent::handle($args);
+
+        if (!common_logged_in()) {
+            common_user_error(_('Not logged in.'));
+        } else if ($_SERVER['REQUEST_METHOD'] == 'POST') {
+
+            # CSRF protection - token set in common_notice_form()
+            $token = $this->trimmed('token');
+            if (!$token || $token != common_session_token()) {
+                $this->client_error(_('There was a problem with your session token. Try again, please.'));
+                return;
+            }
+
+            $this->save_new_notice();
+        } else {
+            $this->show_form();
+        }
+    }
+
+    function save_new_notice()
+    {
+
+        $user = common_current_user();
+        assert($user); # XXX: maybe an error instead...
+        $content = $this->trimmed('status_textarea');
+
+        if (!$content) {
+            $this->show_form(_('No content!'));
+            return;
+        } else {
+            $content_shortened = common_shorten_links($content);
+
+            if (mb_strlen($content_shortened) > 140) {
+                common_debug("Content = '$content_shortened'", __FILE__);
+                common_debug("mb_strlen(\$content) = " . mb_strlen($content_shortened), __FILE__);
+                $this->show_form(_('That\'s too long. Max notice size is 140 chars.'));
+                return;
+            }
+        }
+
+        $inter = new CommandInterpreter();
+
+        $cmd = $inter->handle_command($user, $content_shortened);
+
+        if ($cmd) {
+            if ($this->boolean('ajax')) {
+                $cmd->execute(new AjaxWebChannel());
+            } else {
+                $cmd->execute(new WebChannel());
+            }
+            return;
+        }
+
+        $replyto = $this->trimmed('inreplyto');
+
+        $notice = Notice::saveNew($user->id, $content, 'web', 1, ($replyto == 'false') ? null : $replyto);
+
+        if (is_string($notice)) {
+            $this->show_form($notice);
+            return;
+        }
+
+        common_broadcast_notice($notice);
+
+        if ($this->boolean('ajax')) {
+            common_start_html('text/xml;charset=utf-8', true);
+            common_element_start('head');
+            common_element('title', null, _('Notice posted'));
+            common_element_end('head');
+            common_element_start('body');
+            $this->show_notice($notice);
+            common_element_end('body');
+            common_element_end('html');
+        } else {
+            $returnto = $this->trimmed('returnto');
+
+            if ($returnto) {
+                $url = common_local_url($returnto,
+                                        array('nickname' => $user->nickname));
+            } else {
+                $url = common_local_url('shownotice',
+                                        array('notice' => $notice->id));
+            }
+            common_redirect($url, 303);
+        }
+    }
+
+    function ajax_error_msg($msg)
+    {
+        common_start_html('text/xml;charset=utf-8', true);
+        common_element_start('head');
+        common_element('title', null, _('Ajax Error'));
+        common_element_end('head');
+        common_element_start('body');
+        common_element('p', array('id' => 'error'), $msg);
+        common_element_end('body');
+        common_element_end('html');
+    }
+
+    function show_top($content=null)
+    {
+        common_notice_form(null, $content);
+    }
+
+    function show_form($msg=null)
+    {
+        if ($msg && $this->boolean('ajax')) {
+            $this->ajax_error_msg($msg);
+            return;
+        }
+        $content = $this->trimmed('status_textarea');
+        if (!$content) {
+            $replyto = $this->trimmed('replyto');
+            $profile = Profile::staticGet('nickname', $replyto);
+            if ($profile) {
+                $content = '@' . $profile->nickname . ' ';
+            }
+        }
+        common_show_header(_('New notice'), null, $content,
+                           array($this, 'show_top'));
+        if ($msg) {
+            common_element('p', array('id' => 'error'), $msg);
+        }
+        common_show_footer();
+    }
+
+    function show_notice($notice)
+    {
         $nli = new NoticeListItem($notice);
         $nli->show();
-       }
+    }
 
 }
index 96e4d777fa3aca01c86ea3a0d39285535e014ffd..b36fc8ad200aa1f5b80bb27abdeeb1c27c66468b 100644 (file)
@@ -23,142 +23,149 @@ require_once(INSTALLDIR.'/lib/searchaction.php');
 
 # XXX common parent for people and content search?
 
-class NoticesearchAction extends SearchAction {
+class NoticesearchAction extends SearchAction
+{
 
-       function get_instructions() {
-               return _('Search for notices on %%site.name%% by their contents. Separate search terms by spaces; they must be 3 characters or more.');
-       }
+    function get_instructions()
+    {
+        return _('Search for notices on %%site.name%% by their contents. Separate search terms by spaces; they must be 3 characters or more.');
+    }
 
-       function get_title() {
-               return _('Text search');
-       }
+    function get_title()
+    {
+        return _('Text search');
+    }
 
-       function show_results($q, $page) {
+    function show_results($q, $page)
+    {
 
-               $notice = new Notice();
+        $notice = new Notice();
 
-               # lcase it for comparison
-               $q = strtolower($q);
+        # lcase it for comparison
+        $q = strtolower($q);
 
         $search_engine = $notice->getSearchEngine('identica_notices');
 
         $search_engine->set_sort_mode('chron');
-               # Ask for an extra to see if there's more.
-               $search_engine->limit((($page-1)*NOTICES_PER_PAGE), NOTICES_PER_PAGE + 1);
+        # Ask for an extra to see if there's more.
+        $search_engine->limit((($page-1)*NOTICES_PER_PAGE), NOTICES_PER_PAGE + 1);
 
         if (false === $search_engine->query($q)) {
             $cnt = 0;
         }
         else {
-               $cnt = $notice->find();
+            $cnt = $notice->find();
         }
-               if ($cnt > 0) {
-                       $terms = preg_split('/[\s,]+/', $q);
-                       common_element_start('ul', array('id' => 'notices'));
-                       for ($i = 0; $i < min($cnt, NOTICES_PER_PAGE); $i++) {
-                               if ($notice->fetch()) {
-                                       $this->show_notice($notice, $terms);
-                               } else {
-                                       // shouldn't happen!
-                                       break;
-                               }
-                       }
-                       common_element_end('ul');
-               } else {
-                       common_element('p', 'error', _('No results'));
-               }
-
-               common_pagination($page > 1, $cnt > NOTICES_PER_PAGE,
-                                                 $page, 'noticesearch', array('q' => $q));
-       }
-
-       function show_header($arr) {
-               if ($arr) {
-                       $q = $arr[0];
-               }
-               if ($q) {
-                       common_element('link', array('rel' => 'alternate',
-                                                                                'href' => common_local_url('noticesearchrss',
-                                                                                                                                       array('q' => $q)),
-                                                                                'type' => 'application/rss+xml',
-                                                                                'title' => _('Search Stream Feed')));
-               }
-       }
-
-       # XXX: refactor and combine with StreamAction::show_notice()
-
-       function show_notice($notice, $terms) {
-               $profile = $notice->getProfile();
-               if (!$profile) {
-                       common_log_db_error($notice, 'SELECT', __FILE__);
-                       $this->server_error(_('Notice without matching profile'));
-                       return;
-               }
-               # XXX: RDFa
-               common_element_start('li', array('class' => 'notice_single',
-                                                                                 'id' => 'notice-' . $notice->id));
-               $avatar = $profile->getAvatar(AVATAR_STREAM_SIZE);
-               common_element_start('a', array('href' => $profile->profileurl));
-               common_element('img', array('src' => ($avatar) ? common_avatar_display_url($avatar) : common_default_avatar(AVATAR_STREAM_SIZE),
-                                                                       'class' => 'avatar stream',
-                                                                       'width' => AVATAR_STREAM_SIZE,
-                                                                       'height' => AVATAR_STREAM_SIZE,
-                                                                       'alt' =>
-                                                                       ($profile->fullname) ? $profile->fullname :
-                                                                       $profile->nickname));
-               common_element_end('a');
-               common_element('a', array('href' => $profile->profileurl,
-                                                                 'class' => 'nickname'),
-                                          $profile->nickname);
-               # FIXME: URL, image, video, audio
-               common_element_start('p', array('class' => 'content'));
-               if ($notice->rendered) {
-                       common_raw($this->highlight($notice->rendered, $terms));
-               } else {
-                       # XXX: may be some uncooked notices in the DB,
-                       # we cook them right now. This should probably disappear in future
-                       # versions (>> 0.4.x)
-                       common_raw($this->highlight(common_render_content($notice->content, $notice), $terms));
-               }
-               common_element_end('p');
-               $noticeurl = common_local_url('shownotice', array('notice' => $notice->id));
-               common_element_start('p', 'time');
-               common_element('a', array('class' => 'permalink',
-                                                                 'href' => $noticeurl,
-                                                                 'title' => common_exact_date($notice->created)),
-                                          common_date_string($notice->created));
-               if ($notice->reply_to) {
-                       $replyurl = common_local_url('shownotice', array('notice' => $notice->reply_to));
-                       common_text(' (');
-                       common_element('a', array('class' => 'inreplyto',
-                                                                         'href' => $replyurl),
-                                                  _('in reply to...'));
-                       common_text(')');
-               }
-               common_element_start('a',
-                                                        array('href' => common_local_url('newnotice',
-                                                                                                                         array('replyto' => $profile->nickname)),
-                                                                  'onclick' => 'doreply("'.$profile->nickname.'"); return false',
-                                                                  'title' => _('reply'),
-                                                                  'class' => 'replybutton'));
-               common_hidden('posttoken', common_session_token());
-               
-               common_raw('&rarr;');
-               common_element_end('a');
-               common_element_end('p');
-               common_element_end('li');
-       }
-
-       function highlight($text, $terms) {
-               /* Highligh serach terms */
-               $pattern = '/('.implode('|',array_map('htmlspecialchars', $terms)).')/i';
-               $result = preg_replace($pattern, '<strong>\\1</strong>', $text);
-
-               /* Remove highlighting from inside links, loop incase multiple highlights in links */
-               $pattern = '/(href="[^"]*)<strong>('.implode('|',array_map('htmlspecialchars', $terms)).')<\/strong>([^"]*")/iU';
-               do {
-                       $result = preg_replace($pattern, '\\1\\2\\3', $result, -1, $count);
-               } while ($count);
-               return $result;
-       }
+        if ($cnt > 0) {
+            $terms = preg_split('/[\s,]+/', $q);
+            common_element_start('ul', array('id' => 'notices'));
+            for ($i = 0; $i < min($cnt, NOTICES_PER_PAGE); $i++) {
+                if ($notice->fetch()) {
+                    $this->show_notice($notice, $terms);
+                } else {
+                    // shouldn't happen!
+                    break;
+                }
+            }
+            common_element_end('ul');
+        } else {
+            common_element('p', 'error', _('No results'));
+        }
+
+        common_pagination($page > 1, $cnt > NOTICES_PER_PAGE,
+                          $page, 'noticesearch', array('q' => $q));
+    }
+
+    function show_header($arr)
+    {
+        if ($arr) {
+            $q = $arr[0];
+        }
+        if ($q) {
+            common_element('link', array('rel' => 'alternate',
+                                         'href' => common_local_url('noticesearchrss',
+                                                                    array('q' => $q)),
+                                         'type' => 'application/rss+xml',
+                                         'title' => _('Search Stream Feed')));
+        }
+    }
+
+    # XXX: refactor and combine with StreamAction::show_notice()
+
+    function show_notice($notice, $terms)
+    {
+        $profile = $notice->getProfile();
+        if (!$profile) {
+            common_log_db_error($notice, 'SELECT', __FILE__);
+            $this->server_error(_('Notice without matching profile'));
+            return;
+        }
+        # XXX: RDFa
+        common_element_start('li', array('class' => 'notice_single',
+                                          'id' => 'notice-' . $notice->id));
+        $avatar = $profile->getAvatar(AVATAR_STREAM_SIZE);
+        common_element_start('a', array('href' => $profile->profileurl));
+        common_element('img', array('src' => ($avatar) ? common_avatar_display_url($avatar) : common_default_avatar(AVATAR_STREAM_SIZE),
+                                    'class' => 'avatar stream',
+                                    'width' => AVATAR_STREAM_SIZE,
+                                    'height' => AVATAR_STREAM_SIZE,
+                                    'alt' =>
+                                    ($profile->fullname) ? $profile->fullname :
+                                    $profile->nickname));
+        common_element_end('a');
+        common_element('a', array('href' => $profile->profileurl,
+                                  'class' => 'nickname'),
+                       $profile->nickname);
+        # FIXME: URL, image, video, audio
+        common_element_start('p', array('class' => 'content'));
+        if ($notice->rendered) {
+            common_raw($this->highlight($notice->rendered, $terms));
+        } else {
+            # XXX: may be some uncooked notices in the DB,
+            # we cook them right now. This should probably disappear in future
+            # versions (>> 0.4.x)
+            common_raw($this->highlight(common_render_content($notice->content, $notice), $terms));
+        }
+        common_element_end('p');
+        $noticeurl = common_local_url('shownotice', array('notice' => $notice->id));
+        common_element_start('p', 'time');
+        common_element('a', array('class' => 'permalink',
+                                  'href' => $noticeurl,
+                                  'title' => common_exact_date($notice->created)),
+                       common_date_string($notice->created));
+        if ($notice->reply_to) {
+            $replyurl = common_local_url('shownotice', array('notice' => $notice->reply_to));
+            common_text(' (');
+            common_element('a', array('class' => 'inreplyto',
+                                      'href' => $replyurl),
+                           _('in reply to...'));
+            common_text(')');
+        }
+        common_element_start('a',
+                             array('href' => common_local_url('newnotice',
+                                                              array('replyto' => $profile->nickname)),
+                                   'onclick' => 'doreply("'.$profile->nickname.'"); return false',
+                                   'title' => _('reply'),
+                                   'class' => 'replybutton'));
+        common_hidden('posttoken', common_session_token());
+        
+        common_raw('&rarr;');
+        common_element_end('a');
+        common_element_end('p');
+        common_element_end('li');
+    }
+
+    function highlight($text, $terms)
+    {
+        /* Highligh serach terms */
+        $pattern = '/('.implode('|',array_map('htmlspecialchars', $terms)).')/i';
+        $result = preg_replace($pattern, '<strong>\\1</strong>', $text);
+
+        /* Remove highlighting from inside links, loop incase multiple highlights in links */
+        $pattern = '/(href="[^"]*)<strong>('.implode('|',array_map('htmlspecialchars', $terms)).')<\/strong>([^"]*")/iU';
+        do {
+            $result = preg_replace($pattern, '\\1\\2\\3', $result, -1, $count);
+        } while ($count);
+        return $result;
+    }
 }
index 0f38515a020f8145fbbd2cd19153e66c60f70f4b..20fe0ff2abddfe337ef78b00d7028e6dbecb98a5 100644 (file)
@@ -23,48 +23,53 @@ require_once(INSTALLDIR.'/lib/rssaction.php');
 
 // Formatting of RSS handled by Rss10Action
 
-class NoticesearchrssAction extends Rss10Action {
+class NoticesearchrssAction extends Rss10Action
+{
 
-       function init() {
-               return true;
-       }
+    function init()
+    {
+        return true;
+    }
 
-       function get_notices($limit=0) {
+    function get_notices($limit=0)
+    {
 
-               $q = $this->trimmed('q');
-               $notices = array();
+        $q = $this->trimmed('q');
+        $notices = array();
 
-               $notice = new Notice();
+        $notice = new Notice();
 
-               # lcase it for comparison
-               $q = strtolower($q);
+        # lcase it for comparison
+        $q = strtolower($q);
 
         $search_engine = $notice->getSearchEngine('identica_notices');
         $search_engine->set_sort_mode('chron');
 
-               if (!$limit) $limit = 20;
+        if (!$limit) $limit = 20;
         $search_engine->limit(0, $limit, true);
         $search_engine->query($q);
-               $notice->find();
+        $notice->find();
 
-               while ($notice->fetch()) {
-                       $notices[] = clone($notice);
-               }
+        while ($notice->fetch()) {
+            $notices[] = clone($notice);
+        }
 
-               return $notices;
-       }
+        return $notices;
+    }
 
-       function get_channel() {
-               global $config;
-               $q = $this->trimmed('q');
-               $c = array('url' => common_local_url('noticesearchrss', array('q' => $q)),
-                                  'title' => $config['site']['name'] . sprintf(_(' Search Stream for "%s"'), $q),
-                                  'link' => common_local_url('noticesearch', array('q' => $q)),
-                                  'description' => sprintf(_('All updates matching search term "%s"'), $q));
-               return $c;
-       }
+    function get_channel()
+    {
+        global $config;
+        $q = $this->trimmed('q');
+        $c = array('url' => common_local_url('noticesearchrss', array('q' => $q)),
+                   'title' => $config['site']['name'] . sprintf(_(' Search Stream for "%s"'), $q),
+                   'link' => common_local_url('noticesearch', array('q' => $q)),
+                   'description' => sprintf(_('All updates matching search term "%s"'), $q));
+        return $c;
+    }
 
-       function get_image() {
-               return NULL;
-       }
+    function get_image()
+    {
+        return null;
+    }
 }
index 677f58800517244a6ae5a507517cccd34667630c..a6480a5827cc8c5bfb094f74d19c5c81ee09771b 100644 (file)
@@ -21,64 +21,67 @@ if (!defined('LACONICA')) { exit(1); }
 
 require_once(INSTALLDIR.'/lib/mail.php');
 
-class NudgeAction extends Action {
+class NudgeAction extends Action
+{
 
-       function handle($args) {
-               parent::handle($args);
+    function handle($args)
+    {
+        parent::handle($args);
 
-               if (!common_logged_in()) {
-                       $this->client_error(_('Not logged in.'));
-                       return;
-               }
+        if (!common_logged_in()) {
+            $this->client_error(_('Not logged in.'));
+            return;
+        }
 
-               $user = common_current_user();
-               $other = User::staticGet('nickname', $this->arg('nickname'));
+        $user = common_current_user();
+        $other = User::staticGet('nickname', $this->arg('nickname'));
 
-               if ($_SERVER['REQUEST_METHOD'] != 'POST') {
-                       common_redirect(common_local_url('showstream', array('nickname' => $other->nickname)));
-                       return;
-               }
+        if ($_SERVER['REQUEST_METHOD'] != 'POST') {
+            common_redirect(common_local_url('showstream', array('nickname' => $other->nickname)));
+            return;
+        }
 
-               # CSRF protection
+        # CSRF protection
 
-               $token = $this->trimmed('token');
-               
-               if (!$token || $token != common_session_token()) {
-                       $this->client_error(_('There was a problem with your session token. Try again, please.'));
-                       return;
-               }
+        $token = $this->trimmed('token');
+        
+        if (!$token || $token != common_session_token()) {
+            $this->client_error(_('There was a problem with your session token. Try again, please.'));
+            return;
+        }
 
         if (!$other->email || !$other->emailnotifynudge) {
             $this->client_error(_('This user doesn\'t allow nudges or hasn\'t confirmed or set his email yet.'));
             return;
         }
 
-               $this->notify($user, $other);
+        $this->notify($user, $other);
 
-               if ($this->boolean('ajax')) {
-                       common_start_html('text/xml;charset=utf-8', true);
-                       common_element_start('head');
-                       common_element('title', null, _('Nudge sent'));
-                       common_element_end('head');
-                       common_element_start('body');
-                       common_nudge_response();
-                       common_element_end('body');
-                       common_element_end('html');
-               } else {
+        if ($this->boolean('ajax')) {
+            common_start_html('text/xml;charset=utf-8', true);
+            common_element_start('head');
+            common_element('title', null, _('Nudge sent'));
+            common_element_end('head');
+            common_element_start('body');
+            common_nudge_response();
+            common_element_end('body');
+            common_element_end('html');
+        } else {
             // display a confirmation to the user
-                       common_redirect(common_local_url('showstream',
-                                                                                        array('nickname' => $other->nickname)));
-               }
-       }
+            common_redirect(common_local_url('showstream',
+                                             array('nickname' => $other->nickname)));
+        }
+    }
 
-       function notify($user, $other) {
-               if ($other->id != $user->id) {
-                       if ($other->email && $other->emailnotifynudge) {
-                               mail_notify_nudge($user, $other);
-                       }
-                       # XXX: notify by IM
-                       # XXX: notify by SMS
-               }
-       }
+    function notify($user, $other)
+    {
+        if ($other->id != $user->id) {
+            if ($other->email && $other->emailnotifynudge) {
+                mail_notify_nudge($user, $other);
+            }
+            # XXX: notify by IM
+            # XXX: notify by SMS
+        }
+    }
 }
 
index 1b289dbeab3ab8e865be36e190890614685b9677..09679e372ebc0aa6f0e54e5f2361cbe0b673af4f 100644 (file)
@@ -21,72 +21,77 @@ if (!defined('LACONICA')) { exit(1); }
 
 require_once(INSTALLDIR.'/lib/openid.php');
 
-class OpenidloginAction extends Action {
+class OpenidloginAction extends Action
+{
 
-       function handle($args) {
-               parent::handle($args);
-               if (common_logged_in()) {
-                       common_user_error(_('Already logged in.'));
-               } else if ($_SERVER['REQUEST_METHOD'] == 'POST') {
-                       $openid_url = $this->trimmed('openid_url');
+    function handle($args)
+    {
+        parent::handle($args);
+        if (common_logged_in()) {
+            common_user_error(_('Already logged in.'));
+        } else if ($_SERVER['REQUEST_METHOD'] == 'POST') {
+            $openid_url = $this->trimmed('openid_url');
 
-                       # CSRF protection
-                       $token = $this->trimmed('token');
-                       if (!$token || $token != common_session_token()) {
-                               $this->show_form(_('There was a problem with your session token. Try again, please.'), $openid_url);
-                               return;
-                       }
+            # CSRF protection
+            $token = $this->trimmed('token');
+            if (!$token || $token != common_session_token()) {
+                $this->show_form(_('There was a problem with your session token. Try again, please.'), $openid_url);
+                return;
+            }
 
-                       $rememberme = $this->boolean('rememberme');
-                       
-                       common_ensure_session();
-                       
-                       $_SESSION['openid_rememberme'] = $rememberme;
-                       
-                       $result = oid_authenticate($openid_url,
-                                                                          'finishopenidlogin');
-                       
-                       if (is_string($result)) { # error message
-                               unset($_SESSION['openid_rememberme']);
-                               $this->show_form($result, $openid_url);
-                       }
-               } else {
-                       $openid_url = oid_get_last();
-                       $this->show_form(NULL, $openid_url);
-               }
-       }
+            $rememberme = $this->boolean('rememberme');
+            
+            common_ensure_session();
+            
+            $_SESSION['openid_rememberme'] = $rememberme;
+            
+            $result = oid_authenticate($openid_url,
+                                       'finishopenidlogin');
+            
+            if (is_string($result)) { # error message
+                unset($_SESSION['openid_rememberme']);
+                $this->show_form($result, $openid_url);
+            }
+        } else {
+            $openid_url = oid_get_last();
+            $this->show_form(null, $openid_url);
+        }
+    }
 
-       function get_instructions() {
-               return _('Login with an [OpenID](%%doc.openid%%) account.');
-       }
+    function get_instructions()
+    {
+        return _('Login with an [OpenID](%%doc.openid%%) account.');
+    }
 
-       function show_top($error=NULL) {
-               if ($error) {
-                       common_element('div', array('class' => 'error'), $error);
-               } else {
-                       $instr = $this->get_instructions();
-                       $output = common_markup_to_html($instr);
-                       common_element_start('div', 'instructions');
-                       common_raw($output);
-                       common_element_end('div');
-               }
-       }
+    function show_top($error=null)
+    {
+        if ($error) {
+            common_element('div', array('class' => 'error'), $error);
+        } else {
+            $instr = $this->get_instructions();
+            $output = common_markup_to_html($instr);
+            common_element_start('div', 'instructions');
+            common_raw($output);
+            common_element_end('div');
+        }
+    }
 
-       function show_form($error=NULL, $openid_url) {
-               common_show_header(_('OpenID Login'), NULL, $error, array($this, 'show_top'));
-               $formaction = common_local_url('openidlogin');
-               common_element_start('form', array('method' => 'post',
-                                                                                  'id' => 'openidlogin',
-                                                                                  'action' => $formaction));
-               common_hidden('token', common_session_token());
-               common_input('openid_url', _('OpenID URL'),
-                                        $openid_url,
-                                        _('Your OpenID URL'));
-               common_checkbox('rememberme', _('Remember me'), false,
-                               _('Automatically login in the future; ' .
-                                  'not for shared computers!'));
-               common_submit('submit', _('Login'));
-               common_element_end('form');
-               common_show_footer();
-       }
+    function show_form($error=null, $openid_url)
+    {
+        common_show_header(_('OpenID Login'), null, $error, array($this, 'show_top'));
+        $formaction = common_local_url('openidlogin');
+        common_element_start('form', array('method' => 'post',
+                                           'id' => 'openidlogin',
+                                           'action' => $formaction));
+        common_hidden('token', common_session_token());
+        common_input('openid_url', _('OpenID URL'),
+                     $openid_url,
+                     _('Your OpenID URL'));
+        common_checkbox('rememberme', _('Remember me'), false,
+                        _('Automatically login in the future; ' .
+                           'not for shared computers!'));
+        common_submit('submit', _('Login'));
+        common_element_end('form');
+        common_show_footer();
+    }
 }
index f539d111f9e302abef5daf1f98c6e5b355839879..039236048ae842affcc3731b483046f2090eb4be 100644 (file)
@@ -22,135 +22,140 @@ if (!defined('LACONICA')) { exit(1); }
 require_once(INSTALLDIR.'/lib/settingsaction.php');
 require_once(INSTALLDIR.'/lib/openid.php');
 
-class OpenidsettingsAction extends SettingsAction {
-
-       function get_instructions() {
-               return _('[OpenID](%%doc.openid%%) lets you log into many sites ' .
-                         ' with the same user account. '.
-                         ' Manage your associated OpenIDs from here.');
-       }
-
-       function show_form($msg=NULL, $success=false) {
-
-               $user = common_current_user();
-
-               $this->form_header(_('OpenID settings'), $msg, $success);
-
-               common_element_start('form', array('method' => 'post',
-                                                                                  'id' => 'openidadd',
-                                                                                  'action' =>
-                                                                                  common_local_url('openidsettings')));
-               common_hidden('token', common_session_token());
-               common_element('h2', NULL, _('Add OpenID'));
-               common_element('p', NULL,
-                                          _('If you want to add an OpenID to your account, ' .
-                                                 'enter it in the box below and click "Add".'));
-               common_element_start('p');
-               common_element('label', array('for' => 'openid_url'),
-                                          _('OpenID URL'));
-               common_element('input', array('name' => 'openid_url',
-                                                                         'type' => 'text',
-                                                                         'id' => 'openid_url'));
-               common_element('input', array('type' => 'submit',
-                                                                         'id' => 'add',
-                                                                         'name' => 'add',
-                                                                         'class' => 'submit',
-                                                                         'value' => _('Add')));
-               common_element_end('p');
-               common_element_end('form');
-
-               $oid = new User_openid();
-               $oid->user_id = $user->id;
-
-               $cnt = $oid->find();
-
-               if ($cnt > 0) {
-
-                       common_element('h2', NULL, _('Remove OpenID'));
-
-                       if ($cnt == 1 && !$user->password) {
-
-                               common_element('p', NULL,
-                                                          _('Removing your only OpenID would make it impossible to log in! ' .
-                                                                 'If you need to remove it, add another OpenID first.'));
-
-                               if ($oid->fetch()) {
-                                       common_element_start('p');
-                                       common_element('a', array('href' => $oid->canonical),
-                                                                  $oid->display);
-                                       common_element_end('p');
-                               }
-
-                       } else {
-
-                               common_element('p', NULL,
-                                                          _('You can remove an OpenID from your account '.
-                                                                 'by clicking the button marked "Remove".'));
-                               $idx = 0;
-
-                               while ($oid->fetch()) {
-                                       common_element_start('form', array('method' => 'POST',
-                                                                                                          'id' => 'openiddelete' . $idx,
-                                                                                                          'action' =>
-                                                                                                          common_local_url('openidsettings')));
-                                       common_element_start('p');
-                                       common_hidden('token', common_session_token());
-                                       common_element('a', array('href' => $oid->canonical),
-                                                                  $oid->display);
-                                       common_element('input', array('type' => 'hidden',
-                                                                                                 'id' => 'openid_url'.$idx,
-                                                                                                 'name' => 'openid_url',
-                                                                                                 'value' => $oid->canonical));
-                                       common_element('input', array('type' => 'submit',
-                                                                                                 'id' => 'remove'.$idx,
-                                                                                                 'name' => 'remove',
-                                                                                                 'class' => 'submit',
-                                                                                                 'value' => _('Remove')));
-                                       common_element_end('p');
-                                       common_element_end('form');
-                                       $idx++;
-                               }
-                       }
-               }
-
-               common_show_footer();
-       }
-
-       function handle_post() {
-               # CSRF protection
-               $token = $this->trimmed('token');
-               if (!$token || $token != common_session_token()) {
-                       $this->show_form(_('There was a problem with your session token. Try again, please.'));
-                       return;
-               }
-
-               if ($this->arg('add')) {
-                       $result = oid_authenticate($this->trimmed('openid_url'), 'finishaddopenid');
-                       if (is_string($result)) { # error message
-                               $this->show_form($result);
-                       }
-               } else if ($this->arg('remove')) {
-                       $this->remove_openid();
-               } else {
-                       $this->show_form(_('Something weird happened.'));
-               }
-       }
-
-       function remove_openid() {
-
-               $openid_url = $this->trimmed('openid_url');
-               $oid = User_openid::staticGet('canonical', $openid_url);
-               if (!$oid) {
-                       $this->show_form(_('No such OpenID.'));
-                       return;
-               }
-               $cur = common_current_user();
-               if (!$cur || $oid->user_id != $cur->id) {
-                       $this->show_form(_('That OpenID does not belong to you.'));
-                       return;
-               }
-               $oid->delete();
-               $this->show_form(_('OpenID removed.'), true);
-               return;
-       }
+class OpenidsettingsAction extends SettingsAction
+{
+
+    function get_instructions()
+    {
+        return _('[OpenID](%%doc.openid%%) lets you log into many sites ' .
+                  ' with the same user account. '.
+                  ' Manage your associated OpenIDs from here.');
+    }
+
+    function show_form($msg=null, $success=false)
+    {
+
+        $user = common_current_user();
+
+        $this->form_header(_('OpenID settings'), $msg, $success);
+
+        common_element_start('form', array('method' => 'post',
+                                           'id' => 'openidadd',
+                                           'action' =>
+                                           common_local_url('openidsettings')));
+        common_hidden('token', common_session_token());
+        common_element('h2', null, _('Add OpenID'));
+        common_element('p', null,
+                       _('If you want to add an OpenID to your account, ' .
+                          'enter it in the box below and click "Add".'));
+        common_element_start('p');
+        common_element('label', array('for' => 'openid_url'),
+                       _('OpenID URL'));
+        common_element('input', array('name' => 'openid_url',
+                                      'type' => 'text',
+                                      'id' => 'openid_url'));
+        common_element('input', array('type' => 'submit',
+                                      'id' => 'add',
+                                      'name' => 'add',
+                                      'class' => 'submit',
+                                      'value' => _('Add')));
+        common_element_end('p');
+        common_element_end('form');
+
+        $oid = new User_openid();
+        $oid->user_id = $user->id;
+
+        $cnt = $oid->find();
+
+        if ($cnt > 0) {
+
+            common_element('h2', null, _('Remove OpenID'));
+
+            if ($cnt == 1 && !$user->password) {
+
+                common_element('p', null,
+                               _('Removing your only OpenID would make it impossible to log in! ' .
+                                  'If you need to remove it, add another OpenID first.'));
+
+                if ($oid->fetch()) {
+                    common_element_start('p');
+                    common_element('a', array('href' => $oid->canonical),
+                                   $oid->display);
+                    common_element_end('p');
+                }
+
+            } else {
+
+                common_element('p', null,
+                               _('You can remove an OpenID from your account '.
+                                  'by clicking the button marked "Remove".'));
+                $idx = 0;
+
+                while ($oid->fetch()) {
+                    common_element_start('form', array('method' => 'POST',
+                                                       'id' => 'openiddelete' . $idx,
+                                                       'action' =>
+                                                       common_local_url('openidsettings')));
+                    common_element_start('p');
+                    common_hidden('token', common_session_token());
+                    common_element('a', array('href' => $oid->canonical),
+                                   $oid->display);
+                    common_element('input', array('type' => 'hidden',
+                                                  'id' => 'openid_url'.$idx,
+                                                  'name' => 'openid_url',
+                                                  'value' => $oid->canonical));
+                    common_element('input', array('type' => 'submit',
+                                                  'id' => 'remove'.$idx,
+                                                  'name' => 'remove',
+                                                  'class' => 'submit',
+                                                  'value' => _('Remove')));
+                    common_element_end('p');
+                    common_element_end('form');
+                    $idx++;
+                }
+            }
+        }
+
+        common_show_footer();
+    }
+
+    function handle_post()
+    {
+        # CSRF protection
+        $token = $this->trimmed('token');
+        if (!$token || $token != common_session_token()) {
+            $this->show_form(_('There was a problem with your session token. Try again, please.'));
+            return;
+        }
+
+        if ($this->arg('add')) {
+            $result = oid_authenticate($this->trimmed('openid_url'), 'finishaddopenid');
+            if (is_string($result)) { # error message
+                $this->show_form($result);
+            }
+        } else if ($this->arg('remove')) {
+            $this->remove_openid();
+        } else {
+            $this->show_form(_('Something weird happened.'));
+        }
+    }
+
+    function remove_openid()
+    {
+
+        $openid_url = $this->trimmed('openid_url');
+        $oid = User_openid::staticGet('canonical', $openid_url);
+        if (!$oid) {
+            $this->show_form(_('No such OpenID.'));
+            return;
+        }
+        $cur = common_current_user();
+        if (!$cur || $oid->user_id != $cur->id) {
+            $this->show_form(_('That OpenID does not belong to you.'));
+            return;
+        }
+        $oid->delete();
+        $this->show_form(_('OpenID removed.'), true);
+        return;
+    }
 }
index 0f366be4ca6f717126f39d41976a4cce1682348f..96691fa6f34d6de96dd27e5263a6cd11c4ed330d 100644 (file)
 
 if (!defined('LACONICA')) { exit(1); }
 
-class OpensearchAction extends Action {
-
-       function handle($args) {
-
-               parent::handle($args);
-
-               $type = $this->trimmed('type');
-
-               $short_name = '';
-               if ($type == 'people') {
-                       $type = 'peoplesearch';
-                       $short_name = _('People Search');
-               } else {
-                       $short_name = _('Notice Search');
-                       $type = 'noticesearch';
-               }
-
-               header('Content-Type: text/html');
-
-               common_start_xml();
-               common_element_start('OpenSearchDescription', array('xmlns' => 'http://a9.com/-/spec/opensearch/1.1/'));
-
-               $short_name =  common_config('site', 'name').' '.$short_name;
-               common_element('ShortName', NULL, $short_name);
-               common_element('Contact', NULL, common_config('site', 'email'));
-               common_element('Url', array('type' => 'text/html', 'method' => 'get',
-                                          'template' => str_replace('---', '{searchTerms}', common_local_url($type, array('q' => '---')))));
-               common_element('Image', array('height' => 16, 'width' => 16, 'type' => 'image/vnd.microsoft.icon'), common_path('favicon.ico'));
-               common_element('Image', array('height' => 50, 'width' => 50, 'type' => 'image/png'), theme_path('logo.png'));
-               common_element('AdultContent', NULL, 'false');
-               common_element('Language', NULL, common_language());
-               common_element('OutputEncoding', NULL, 'UTF-8');
-               common_element('InputEncoding', NULL, 'UTF-8');
-
-               common_element_end('OpenSearchDescription');
-               common_end_xml();
-       }
+class OpensearchAction extends Action
+{
+
+    function handle($args)
+    {
+
+        parent::handle($args);
+
+        $type = $this->trimmed('type');
+
+        $short_name = '';
+        if ($type == 'people') {
+            $type = 'peoplesearch';
+            $short_name = _('People Search');
+        } else {
+            $short_name = _('Notice Search');
+            $type = 'noticesearch';
+        }
+
+        header('Content-Type: text/html');
+
+        common_start_xml();
+        common_element_start('OpenSearchDescription', array('xmlns' => 'http://a9.com/-/spec/opensearch/1.1/'));
+
+        $short_name =  common_config('site', 'name').' '.$short_name;
+        common_element('ShortName', null, $short_name);
+        common_element('Contact', null, common_config('site', 'email'));
+        common_element('Url', array('type' => 'text/html', 'method' => 'get',
+                       'template' => str_replace('---', '{searchTerms}', common_local_url($type, array('q' => '---')))));
+        common_element('Image', array('height' => 16, 'width' => 16, 'type' => 'image/vnd.microsoft.icon'), common_path('favicon.ico'));
+        common_element('Image', array('height' => 50, 'width' => 50, 'type' => 'image/png'), theme_path('logo.png'));
+        common_element('AdultContent', null, 'false');
+        common_element('Language', null, common_language());
+        common_element('OutputEncoding', null, 'UTF-8');
+        common_element('InputEncoding', null, 'UTF-8');
+
+        common_element_end('OpenSearchDescription');
+        common_end_xml();
+    }
 }
index eccf90e91b3a0d7122036d468873e6ec29523f7c..c2f08934c0b20ca84d0302da5deb511e4db86d8f 100644 (file)
@@ -21,161 +21,168 @@ if (!defined('LACONICA')) { exit(1); }
 
 require_once(INSTALLDIR.'/lib/settingsaction.php');
 
-class OthersettingsAction extends SettingsAction {
+class OthersettingsAction extends SettingsAction
+{
 
-       function get_instructions() {
-               return _('Manage various other options.');
-       }
+    function get_instructions()
+    {
+        return _('Manage various other options.');
+    }
 
-       function show_form($msg=NULL, $success=false) {
-               $user = common_current_user();
+    function show_form($msg=null, $success=false)
+    {
+        $user = common_current_user();
 
-               $this->form_header(_('Other Settings'), $msg, $success);
+        $this->form_header(_('Other Settings'), $msg, $success);
 
-               common_element('h2', NULL, _('URL Auto-shortening'));
-               common_element_start('form', array('method' => 'post',
-                                                                                  'id' => 'othersettings',
-                                                                                  'action' =>
-                                                                                  common_local_url('othersettings')));
-               common_hidden('token', common_session_token());
+        common_element('h2', null, _('URL Auto-shortening'));
+        common_element_start('form', array('method' => 'post',
+                                           'id' => 'othersettings',
+                                           'action' =>
+                                           common_local_url('othersettings')));
+        common_hidden('token', common_session_token());
 
-               $services = array(
-                       '' => 'None',
+        $services = array(
+            '' => 'None',
             'ur1.ca' => 'ur1.ca (free service)',
             '2tu.us' => '2tu.us (free service)',
             'ptiturl.com' => 'ptiturl.com',
             'bit.ly' => 'bit.ly',
-                       'tinyurl.com' => 'tinyurl.com',
-                       'is.gd' => 'is.gd',
-                       'snipr.com' => 'snipr.com',
-                       'metamark.net' => 'metamark.net'
-               );
+            'tinyurl.com' => 'tinyurl.com',
+            'is.gd' => 'is.gd',
+            'snipr.com' => 'snipr.com',
+            'metamark.net' => 'metamark.net'
+        );
 
-               common_dropdown('urlshorteningservice', _('Service'), $services, _('Automatic shortening service to use.'), FALSE, $user->urlshorteningservice);
+        common_dropdown('urlshorteningservice', _('Service'), $services, _('Automatic shortening service to use.'), false, $user->urlshorteningservice);
 
-               common_submit('save', _('Save'));
+        common_submit('save', _('Save'));
 
-               common_element_end('form');
+        common_element_end('form');
 
-//             common_element('h2', NULL, _('Delete my account'));
-//             $this->show_delete_form();
+//        common_element('h2', null, _('Delete my account'));
+//        $this->show_delete_form();
 
-               common_show_footer();
-       }
+        common_show_footer();
+    }
 
-       function show_feeds_list($feeds) {
-               common_element_start('div', array('class' => 'feedsdel'));
-               common_element('p', null, 'Feeds:');
-               common_element_start('ul', array('class' => 'xoxo'));
+    function show_feeds_list($feeds)
+    {
+        common_element_start('div', array('class' => 'feedsdel'));
+        common_element('p', null, 'Feeds:');
+        common_element_start('ul', array('class' => 'xoxo'));
 
-               foreach ($feeds as $key => $value) {
-                       $this->common_feed_item($feeds[$key]);
-               }
-               common_element_end('ul');
-               common_element_end('div');
-       }
+        foreach ($feeds as $key => $value) {
+            $this->common_feed_item($feeds[$key]);
+        }
+        common_element_end('ul');
+        common_element_end('div');
+    }
 
     //TODO move to common.php (and retrace its origin)
-       function common_feed_item($feed) {
+    function common_feed_item($feed)
+    {
         $user = common_current_user();
-               $nickname = $user->nickname;
-
-               switch($feed['item']) {
-                       case 'notices': default:
-                               $feed_classname = $feed['type'];
-                               $feed_mimetype = "application/".$feed['type']."+xml";
-                               $feed_title = "$nickname's ".$feed['version']." notice feed";
-                               $feed['textContent'] = "RSS";
-                               break;
-
-                       case 'foaf':
-                               $feed_classname = "foaf";
-                               $feed_mimetype = "application/".$feed['type']."+xml";
-                               $feed_title = "$nickname's FOAF file";
-                               $feed['textContent'] = "FOAF";
-                               break;
-               }
-               common_element_start('li');
-               common_element('a', array('href' => $feed['href'],
-                                                                 'class' => $feed_classname,
-                                                                 'type' => $feed_mimetype,
-                                                                 'title' => $feed_title),
-                                                       $feed['textContent']);
-               common_element_end('li');
-       }
-
-//     function show_delete_form() {
-//             $user = common_current_user();
+        $nickname = $user->nickname;
+
+        switch($feed['item']) {
+            case 'notices': default:
+                $feed_classname = $feed['type'];
+                $feed_mimetype = "application/".$feed['type']."+xml";
+                $feed_title = "$nickname's ".$feed['version']." notice feed";
+                $feed['textContent'] = "RSS";
+                break;
+
+            case 'foaf':
+                $feed_classname = "foaf";
+                $feed_mimetype = "application/".$feed['type']."+xml";
+                $feed_title = "$nickname's FOAF file";
+                $feed['textContent'] = "FOAF";
+                break;
+        }
+        common_element_start('li');
+        common_element('a', array('href' => $feed['href'],
+                                  'class' => $feed_classname,
+                                  'type' => $feed_mimetype,
+                                  'title' => $feed_title),
+                            $feed['textContent']);
+        common_element_end('li');
+    }
+
+//    function show_delete_form() {
+//        $user = common_current_user();
 //      $notices = DB_DataObject::factory('notice');
 //      $notices->profile_id = $user->id;
 //      $notice_count = (int) $notices->count();
 //
-//             common_element_start('form', array('method' => 'POST',
-//                                                                                'id' => 'delete',
-//                                                                                'action' =>
-//                                                                                common_local_url('deleteprofile')));
+//        common_element_start('form', array('method' => 'POST',
+//                                           'id' => 'delete',
+//                                           'action' =>
+//                                           common_local_url('deleteprofile')));
 //
-//             common_hidden('token', common_session_token());
+//        common_hidden('token', common_session_token());
 //      common_element('p', null, "You can copy your notices and contacts by saving the two links below before deleting your account. Be careful, this operation cannot be undone.");
 //
-//             $this->show_feeds_list(array(0=>array('href'=>common_local_url('userrss', array('limit' => $notice_count, 'nickname' => $user->nickname)),
-//                                                                                       'type' => 'rss',
-//                                                                                       'version' => 'RSS 1.0',
-//                                                                                       'item' => 'notices'),
-//                                                                      1=>array('href'=>common_local_url('foaf',array('nickname' => $user->nickname)),
-//                                                                                       'type' => 'rdf',
-//                                                                                       'version' => 'FOAF',
-//                                                                                       'item' => 'foaf')));
+//        $this->show_feeds_list(array(0=>array('href'=>common_local_url('userrss', array('limit' => $notice_count, 'nickname' => $user->nickname)),
+//                                              'type' => 'rss',
+//                                              'version' => 'RSS 1.0',
+//                                              'item' => 'notices'),
+//                                     1=>array('href'=>common_local_url('foaf',array('nickname' => $user->nickname)),
+//                                              'type' => 'rdf',
+//                                              'version' => 'FOAF',
+//                                              'item' => 'foaf')));
 //
-//             common_submit('deleteaccount', _('Delete my account'));
-//             common_element_end('form');
-//     }
+//        common_submit('deleteaccount', _('Delete my account'));
+//        common_element_end('form');
+//    }
 
-       function handle_post() {
+    function handle_post()
+    {
 
-               # CSRF protection
-               $token = $this->trimmed('token');
-               if (!$token || $token != common_session_token()) {
-                       $this->show_form(_('There was a problem with your session token. Try again, please.'));
-                       return;
-               }
+        # CSRF protection
+        $token = $this->trimmed('token');
+        if (!$token || $token != common_session_token()) {
+            $this->show_form(_('There was a problem with your session token. Try again, please.'));
+            return;
+        }
 
-               if ($this->arg('save')) {
-                       $this->save_preferences();
-               }else {
-                       $this->show_form(_('Unexpected form submission.'));
-               }
-       }
+        if ($this->arg('save')) {
+            $this->save_preferences();
+        }else {
+            $this->show_form(_('Unexpected form submission.'));
+        }
+    }
 
-       function save_preferences() {
+    function save_preferences()
+    {
 
-               $urlshorteningservice = $this->trimmed('urlshorteningservice');
+        $urlshorteningservice = $this->trimmed('urlshorteningservice');
 
-               if (!is_null($urlshorteningservice) && strlen($urlshorteningservice) > 50) {
-                       $this->show_form(_('URL shortening service is too long (max 50 chars).'));
-                       return;
-               }
+        if (!is_null($urlshorteningservice) && strlen($urlshorteningservice) > 50) {
+            $this->show_form(_('URL shortening service is too long (max 50 chars).'));
+            return;
+        }
 
-               $user = common_current_user();
+        $user = common_current_user();
 
-               assert(!is_null($user)); # should already be checked
+        assert(!is_null($user)); # should already be checked
 
-               $user->query('BEGIN');
+        $user->query('BEGIN');
 
-               $original = clone($user);
+        $original = clone($user);
 
-               $user->urlshorteningservice = $urlshorteningservice;
+        $user->urlshorteningservice = $urlshorteningservice;
 
-               $result = $user->update($original);
+        $result = $user->update($original);
 
-               if ($result === FALSE) {
-                       common_log_db_error($user, 'UPDATE', __FILE__);
-                       common_server_error(_('Couldn\'t update user.'));
-                       return;
-               }
+        if ($result === false) {
+            common_log_db_error($user, 'UPDATE', __FILE__);
+            common_server_error(_('Couldn\'t update user.'));
+            return;
+        }
 
-               $user->query('COMMIT');
+        $user->query('COMMIT');
 
-               $this->show_form(_('Preferences saved.'), true);
-       }
+        $this->show_form(_('Preferences saved.'), true);
+    }
 }
index c48d9c2062f7c1c7b5a11291b9158f5013ed7a62..9fb6dbf9f8c1132203e17cd69d070f2dace63cbd 100644 (file)
@@ -1,9 +1,12 @@
 <?php
-/*
- * Laconica - a distributed open-source microblogging tool
- * Copyright (C) 2008, Controlez-Vous, Inc.
+/**
+ * Laconica, the distributed open-source microblogging tool
  *
- * This program is free software: you can redistribute it and/or modify
+ * action handler for message inbox
+ *
+ * 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.
  *
  * 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  Message
+ * @package   Laconica
+ * @author    Evan Prodromou <evan@controlyourself.ca>
+ * @copyright 2008 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/mailbox.php';
+
+/**
+ * action handler for message outbox
+ *
+ * @category Message
+ * @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/
+ * @see      MailboxAction
  */
 
-if (!defined('LACONICA')) { exit(1); }
-
-require_once(INSTALLDIR.'/lib/mailbox.php');
-
-class OutboxAction extends MailboxAction {
-       
-       function get_title($user, $page) {
-               if ($page > 1) {
-                       $title = sprintf(_("Outbox for %s - page %d"), $user->nickname, $page);
-               } else {
-                       $title = sprintf(_("Outbox for %s"), $user->nickname);
-               }
-               return $title;
-       }
-       
-       function get_messages($user, $page) {
-               $message = new Message();
-               $message->from_profile = $user->id;
-               $message->orderBy('created DESC, id DESC');
-               $message->limit((($page-1)*MESSAGES_PER_PAGE), MESSAGES_PER_PAGE + 1);
-
-               if ($message->find()) {
-                       return $message;
-               } else {
-                       return NULL;
-               }
-       }
-       
-       function get_message_profile($message) {
-               return $message->getTo();
-       }
-       
-       function get_instructions() {
-               return _('This is your outbox, which lists private messages you have sent.');
-       }
-       
+class OutboxAction extends MailboxAction
+{
+    /**
+     * returns the title of the page
+     *
+     * @param User $user current user
+     * @param int  $page current page
+     *
+     * @return string localised title of the page
+     *
+     * @see MailboxAction::getTitle()
+     */
+
+    function getTitle($user, $page)
+    {
+        if ($page > 1) {
+            $title = sprintf(_("Outbox for %s - page %d"), $user->nickname, $page);
+        } else {
+            $title = sprintf(_("Outbox for %s"), $user->nickname);
+        }
+        return $title;
+    }
+
+    /**
+     * retrieve the messages for this user and this page
+     *
+     * Does a query for the right messages
+     *
+     * @param User $user The current user
+     * @param int  $page The page the user is on
+     *
+     * @return Message data object with stream for messages
+     *
+     * @see MailboxAction::getMessages()
+     */
+
+    function getMessages($user, $page)
+    {
+        $message = new Message();
+
+        $message->from_profile = $user->id;
+        $message->orderBy('created DESC, id DESC');
+        $message->limit((($page-1)*MESSAGES_PER_PAGE), MESSAGES_PER_PAGE + 1);
+
+        if ($message->find()) {
+            return $message;
+        } else {
+            return null;
+        }
+    }
+
+    /**
+     * returns the profile we want to show with the message
+     *
+     * For outboxes, we show the recipient.
+     *
+     * @param Message $message The message to get the profile for
+     *
+     * @return Profile The profile of the message recipient
+     *
+     * @see MailboxAction::getMessageProfile()
+     */
+
+    function getMessageProfile($message)
+    {
+        return $message->getTo();
+    }
+
+    /**
+     * instructions for using this page
+     *
+     * @return string localised instructions for using the page
+     */
+
+    function getInstructions()
+    {
+        return _('This is your outbox, which lists private messages you have sent.');
+    }
 }
index 2e54233ec1c607bb2f112809feec616c0064b450..0d0fae4e5c635f64659807b020f0db49af59f391 100644 (file)
@@ -22,63 +22,70 @@ if (!defined('LACONICA')) { exit(1); }
 require_once(INSTALLDIR.'/lib/searchaction.php');
 require_once(INSTALLDIR.'/lib/profilelist.php');
 
-class PeoplesearchAction extends SearchAction {
+class PeoplesearchAction extends SearchAction
+{
 
-       function get_instructions() {
-               return _('Search for people on %%site.name%% by their name, location, or interests. ' .
-                                 'Separate the terms by spaces; they must be 3 characters or more.');
-       }
+    function get_instructions()
+    {
+        return _('Search for people on %%site.name%% by their name, location, or interests. ' .
+                  'Separate the terms by spaces; they must be 3 characters or more.');
+    }
 
-       function get_title() {
-               return _('People search');
-       }
+    function get_title()
+    {
+        return _('People search');
+    }
 
-       function show_results($q, $page) {
+    function show_results($q, $page)
+    {
 
-               $profile = new Profile();
+        $profile = new Profile();
 
-               # lcase it for comparison
-               $q = strtolower($q);
+        # lcase it for comparison
+        $q = strtolower($q);
 
         $search_engine = $profile->getSearchEngine('identica_people');
 
         $search_engine->set_sort_mode('chron');
-               # Ask for an extra to see if there's more.
+        # Ask for an extra to see if there's more.
         $search_engine->limit((($page-1)*PROFILES_PER_PAGE), PROFILES_PER_PAGE + 1);
         if (false === $search_engine->query($q)) {
             $cnt = 0;
         }
         else {
-                   $cnt = $profile->find();
+            $cnt = $profile->find();
+        }
+        if ($cnt > 0) {
+            $terms = preg_split('/[\s,]+/', $q);
+            $results = new PeopleSearchResults($profile, $terms);
+            $results->show_list();
+        } else {
+            common_element('p', 'error', _('No results'));
         }
-               if ($cnt > 0) {
-                       $terms = preg_split('/[\s,]+/', $q);
-                       $results = new PeopleSearchResults($profile, $terms);
-                       $results->show_list();
-               } else {
-                       common_element('p', 'error', _('No results'));
-               }
 
-               $profile->free();
-               
-               common_pagination($page > 1, $cnt > PROFILES_PER_PAGE,
-                                                 $page, 'peoplesearch', array('q' => $q));
-       }
+        $profile->free();
+        
+        common_pagination($page > 1, $cnt > PROFILES_PER_PAGE,
+                          $page, 'peoplesearch', array('q' => $q));
+    }
 }
 
-class PeopleSearchResults extends ProfileList {
+class PeopleSearchResults extends ProfileList
+{
 
-       var $terms = NULL;
-       var $pattern = NULL;
-       
-       function __construct($profile, $terms) {
-               parent::__construct($profile);
-               $this->terms = array_map('preg_quote', 
-                                                                array_map('htmlspecialchars', $terms));
-               $this->pattern = '/('.implode('|',$terms).')/i';
-       }
-       
-       function highlight($text) {
-               return preg_replace($this->pattern, '<strong>\\1</strong>', htmlspecialchars($text));
-       }
+    var $terms = null;
+    var $pattern = null;
+    
+    function __construct($profile, $terms)
+    {
+        parent::__construct($profile);
+        $this->terms = array_map('preg_quote', 
+                                 array_map('htmlspecialchars', $terms));
+        $this->pattern = '/('.implode('|',$terms).')/i';
+    }
+    
+    function highlight($text)
+    {
+        return preg_replace($this->pattern, '<strong>\\1</strong>', htmlspecialchars($text));
+    }
 }
index c508e05943c50382cb6f9d966a0b7bb31418381a..13a0b7a41324ed9deaa86ba9e13aa667ceabf060 100644 (file)
@@ -21,83 +21,89 @@ if (!defined('LACONICA')) { exit(1); }
 
 require_once(INSTALLDIR.'/lib/profilelist.php');
 
-class PeopletagAction extends Action {
-       
-       function handle($args) {
+class PeopletagAction extends Action
+{
+    
+    function handle($args)
+    {
 
-               parent::handle($args);
+        parent::handle($args);
 
-               $tag = $this->trimmed('tag');
-               
-               if (!common_valid_profile_tag($tag)) {
-                       $this->client_error(sprintf(_('Not a valid people tag: %s'), $tag));
-                       return;
-               }
+        $tag = $this->trimmed('tag');
+        
+        if (!common_valid_profile_tag($tag)) {
+            $this->client_error(sprintf(_('Not a valid people tag: %s'), $tag));
+            return;
+        }
 
-               $page = $this->trimmed('page');
-               
-               if (!$page) {
-                       $page = 1;
-               }
-               
-               # Looks like we're good; show the header
+        $page = $this->trimmed('page');
+        
+        if (!$page) {
+            $page = 1;
+        }
+        
+        # Looks like we're good; show the header
 
-               common_show_header(sprintf(_('Users self-tagged with %s - page %d'), $tag, $page),
-                                                  NULL, $tag, array($this, 'show_top'));
+        common_show_header(sprintf(_('Users self-tagged with %s - page %d'), $tag, $page),
+                           null, $tag, array($this, 'show_top'));
 
-               $this->show_people($tag, $page);
+        $this->show_people($tag, $page);
 
-               common_show_footer();
-       }
+        common_show_footer();
+    }
 
-       function show_people($tag, $page) {
-               
-               $profile = new Profile();
+    function show_people($tag, $page)
+    {
+        
+        $profile = new Profile();
 
-               $offset = ($page-1)*PROFILES_PER_PAGE;
-               $limit = PROFILES_PER_PAGE + 1;
-               
-               if (common_config('db','type') == 'pgsql') {
-                       $lim = ' LIMIT ' . $limit . ' OFFSET ' . $offset;
-               } else {
-                       $lim = ' LIMIT ' . $offset . ', ' . $limit;
-               }
+        $offset = ($page-1)*PROFILES_PER_PAGE;
+        $limit = PROFILES_PER_PAGE + 1;
+        
+        if (common_config('db','type') == 'pgsql') {
+            $lim = ' LIMIT ' . $limit . ' OFFSET ' . $offset;
+        } else {
+            $lim = ' LIMIT ' . $offset . ', ' . $limit;
+        }
 
-               # XXX: memcached this
-               
-               $profile->query(sprintf('SELECT profile.* ' .
-                                                               'FROM profile JOIN profile_tag ' .
-                                                               'ON profile.id = profile_tag.tagger ' .
-                                                               'WHERE profile_tag.tagger = profile_tag.tagged ' .
-                                                               'AND tag = "%s" ' .
-                                                               'ORDER BY profile_tag.modified DESC ' . 
-                                                               $lim, $tag));
+        # XXX: memcached this
+        
+        $profile->query(sprintf('SELECT profile.* ' .
+                                'FROM profile JOIN profile_tag ' .
+                                'ON profile.id = profile_tag.tagger ' .
+                                'WHERE profile_tag.tagger = profile_tag.tagged ' .
+                                'AND tag = "%s" ' .
+                                'ORDER BY profile_tag.modified DESC ' . 
+                                $lim, $tag));
 
-               $pl = new ProfileList($profile);
-               $cnt = $pl->show_list();
-               
-               common_pagination($page > 1,
-                                                 $cnt > PROFILES_PER_PAGE,
-                                                 $page,
-                                                 $this->trimmed('action'),
-                                                 array('tag' => $tag));
-       }
-       
-       function show_top($tag) {
-               $instr = sprintf(_('These are users who have tagged themselves "%s" ' .
-                                                  'to show a common interest, characteristic, hobby or job.'), $tag);
-               common_element_start('div', 'instructions');
-               common_element_start('p');
-               common_text($instr);
-               common_element_end('p');
-               common_element_end('div');
-       }
+        $pl = new ProfileList($profile);
+        $cnt = $pl->show_list();
+        
+        common_pagination($page > 1,
+                          $cnt > PROFILES_PER_PAGE,
+                          $page,
+                          $this->trimmed('action'),
+                          array('tag' => $tag));
+    }
+    
+    function show_top($tag)
+    {
+        $instr = sprintf(_('These are users who have tagged themselves "%s" ' .
+                           'to show a common interest, characteristic, hobby or job.'), $tag);
+        common_element_start('div', 'instructions');
+        common_element_start('p');
+        common_text($instr);
+        common_element_end('p');
+        common_element_end('div');
+    }
 
-       function get_title() {
-               return NULL;
-       }
+    function get_title()
+    {
+        return null;
+    }
 
-       function show_header($arr) {
-               return;
-       }
+    function show_header($arr)
+    {
+        return;
+    }
 }
index 243081f1222540eb00e7a828c1205e881536d4a5..dec62a678f27b2d842f3f060a12f34b866e40cc6 100644 (file)
@@ -21,68 +21,71 @@ if (!defined('LACONICA')) { exit(1); }
 
 require_once(INSTALLDIR.'/lib/omb.php');
 
-class PostnoticeAction extends Action {
-       function handle($args) {
-               parent::handle($args);
-               try {
-                       common_remove_magic_from_request();
-                       $req = OAuthRequest::from_request();
-                       # Note: server-to-server function!
-                       $server = omb_oauth_server();
-                       list($consumer, $token) = $server->verify_request($req);
-                       if ($this->save_notice($req, $consumer, $token)) {
-                               print "omb_version=".OMB_VERSION_01;
-                       }
-               } catch (OAuthException $e) {
-                       common_server_error($e->getMessage());
-                       return;
-               }
-       }
+class PostnoticeAction extends Action
+{
+    function handle($args)
+    {
+        parent::handle($args);
+        try {
+            common_remove_magic_from_request();
+            $req = OAuthRequest::from_request();
+            # Note: server-to-server function!
+            $server = omb_oauth_server();
+            list($consumer, $token) = $server->verify_request($req);
+            if ($this->save_notice($req, $consumer, $token)) {
+                print "omb_version=".OMB_VERSION_01;
+            }
+        } catch (OAuthException $e) {
+            common_server_error($e->getMessage());
+            return;
+        }
+    }
 
-       function save_notice(&$req, &$consumer, &$token) {
-               $version = $req->get_parameter('omb_version');
-               if ($version != OMB_VERSION_01) {
-                       common_user_error(_('Unsupported OMB version'), 400);
-                       return false;
-               }
-               # First, check to see
-               $listenee =  $req->get_parameter('omb_listenee');
-               $remote_profile = Remote_profile::staticGet('uri', $listenee);
-               if (!$remote_profile) {
-                       common_user_error(_('Profile unknown'), 403);
-                       return false;
-               }
-               $sub = Subscription::staticGet('token', $token->key);
-               if (!$sub) {
-                       common_user_error(_('No such subscription'), 403);
-                       return false;
-               }
-               $content = $req->get_parameter('omb_notice_content');
+    function save_notice(&$req, &$consumer, &$token)
+    {
+        $version = $req->get_parameter('omb_version');
+        if ($version != OMB_VERSION_01) {
+            common_user_error(_('Unsupported OMB version'), 400);
+            return false;
+        }
+        # First, check to see
+        $listenee =  $req->get_parameter('omb_listenee');
+        $remote_profile = Remote_profile::staticGet('uri', $listenee);
+        if (!$remote_profile) {
+            common_user_error(_('Profile unknown'), 403);
+            return false;
+        }
+        $sub = Subscription::staticGet('token', $token->key);
+        if (!$sub) {
+            common_user_error(_('No such subscription'), 403);
+            return false;
+        }
+        $content = $req->get_parameter('omb_notice_content');
         $content_shortened = common_shorten_links($content);
         if (mb_strlen($content_shortened) > 140) {
             common_user_error(_('Invalid notice content'), 400);
             return false;
         }
-               $notice_uri = $req->get_parameter('omb_notice');
-               if (!Validate::uri($notice_uri) &&
-                       !common_valid_tag($notice_uri)) {
-                       common_user_error(_('Invalid notice uri'), 400);
-                       return false;
-               }
-               $notice_url = $req->get_parameter('omb_notice_url');
-               if ($notice_url && !common_valid_http_url($notice_url)) {
-                       common_user_error(_('Invalid notice url'), 400);
-                       return false;
-               }
-               $notice = Notice::staticGet('uri', $notice_uri);
-               if (!$notice) {
-                       $notice = Notice::saveNew($remote_profile->id, $content, 'omb', false, 0, $notice_uri);
-                       if (is_string($notice)) {
-                               common_server_serror($notice, 500);
-                               return false;
-                       }
-                       common_broadcast_notice($notice, true);
-               }
-               return true;
-       }
+        $notice_uri = $req->get_parameter('omb_notice');
+        if (!Validate::uri($notice_uri) &&
+            !common_valid_tag($notice_uri)) {
+            common_user_error(_('Invalid notice uri'), 400);
+            return false;
+        }
+        $notice_url = $req->get_parameter('omb_notice_url');
+        if ($notice_url && !common_valid_http_url($notice_url)) {
+            common_user_error(_('Invalid notice url'), 400);
+            return false;
+        }
+        $notice = Notice::staticGet('uri', $notice_uri);
+        if (!$notice) {
+            $notice = Notice::saveNew($remote_profile->id, $content, 'omb', false, 0, $notice_uri);
+            if (is_string($notice)) {
+                common_server_serror($notice, 500);
+                return false;
+            }
+            common_broadcast_notice($notice, true);
+        }
+        return true;
+    }
 }
index ed2623c9bbedce124bcb8661881583904ef141db..d861919b920e7f18e5ed3fe89a515faff95eb118 100644 (file)
@@ -21,419 +21,464 @@ if (!defined('LACONICA')) { exit(1); }
 
 require_once(INSTALLDIR.'/lib/settingsaction.php');
 
-class ProfilesettingsAction extends SettingsAction {
-
-       function get_instructions() {
-               return _('You can update your personal profile info here '.
-                                 'so people know more about you.');
-       }
-
-       function show_form($msg=NULL, $success=false) {
-               $this->form_header(_('Profile settings'), $msg, $success);
-               $this->show_settings_form();
-               common_element('h2', NULL, _('Avatar'));
-               $this->show_avatar_form();
-               common_element('h2', NULL, _('Change password'));
-               $this->show_password_form();
-//             common_element('h2', NULL, _('Delete my account'));
-//             $this->show_delete_form();
-               common_show_footer();
-       }
-
-       function handle_post() {
-
-               # CSRF protection
-
-               $token = $this->trimmed('token');
-               if (!$token || $token != common_session_token()) {
-                       $this->show_form(_('There was a problem with your session token. Try again, please.'));
-                       return;
-               }
-
-               if ($this->arg('save')) {
-                       $this->save_profile();
-               } else if ($this->arg('upload')) {
-                       $this->upload_avatar();
-               } else if ($this->arg('changepass')) {
-                       $this->change_password();
-               }
-
-       }
-
-       function show_settings_form() {
-
-               $user = common_current_user();
-               $profile = $user->getProfile();
-
-               common_element_start('form', array('method' => 'POST',
-                                                                                  'id' => 'profilesettings',
-                                                                                  'action' =>
-                                                                                  common_local_url('profilesettings')));
-               common_hidden('token', common_session_token());
-               
-               # too much common patterns here... abstractable?
-               
-               common_input('nickname', _('Nickname'),
-                                        ($this->arg('nickname')) ? $this->arg('nickname') : $profile->nickname,
-                                        _('1-64 lowercase letters or numbers, no punctuation or spaces'));
-               common_input('fullname', _('Full name'),
-                                        ($this->arg('fullname')) ? $this->arg('fullname') : $profile->fullname);
-               common_input('homepage', _('Homepage'),
-                                        ($this->arg('homepage')) ? $this->arg('homepage') : $profile->homepage,
-                                        _('URL of your homepage, blog, or profile on another site'));
-               common_textarea('bio', _('Bio'),
-                                               ($this->arg('bio')) ? $this->arg('bio') : $profile->bio,
-                                               _('Describe yourself and your interests in 140 chars'));
-               common_input('location', _('Location'),
-                                        ($this->arg('location')) ? $this->arg('location') : $profile->location,
-                                        _('Where you are, like "City, State (or Region), Country"'));
-               common_input('tags', _('Tags'),
-                                        ($this->arg('tags')) ? $this->arg('tags') : implode(' ', $user->getSelfTags()),
-                                        _('Tags for yourself (letters, numbers, -, ., and _), comma- or space- separated'));
-
-               $language = common_language();
-               common_dropdown('language', _('Language'), get_nice_language_list(), _('Preferred language'), TRUE, $language);
-               $timezone = common_timezone();
-               $timezones = array();
-               foreach(DateTimeZone::listIdentifiers() as $k => $v) {
-                       $timezones[$v] = $v;
-               }
-               common_dropdown('timezone', _('Timezone'), $timezones, _('What timezone are you normally in?'), TRUE, $timezone);
-
-               common_checkbox('autosubscribe', _('Automatically subscribe to whoever subscribes to me (best for non-humans)'),
-                                               ($this->arg('autosubscribe')) ? $this->boolean('autosubscribe') : $user->autosubscribe);
-
-               common_submit('save', _('Save'));
-
-               common_element_end('form');
-
-
-       }
-
-       function show_avatar_form() {
-
-               $user = common_current_user();
-               $profile = $user->getProfile();
-
-               if (!$profile) {
-                       common_log_db_error($user, 'SELECT', __FILE__);
-                       $this->server_error(_('User without matching profile'));
-                       return;
-               }
-               
-               $original = $profile->getOriginalAvatar();
-
-
-               common_element_start('form', array('enctype' => 'multipart/form-data',
-                                                                                  'method' => 'POST',
-                                                                                  'id' => 'avatar',
-                                                                                  'action' =>
-                                                                                  common_local_url('profilesettings')));
-               common_hidden('token', common_session_token());
-
-               if ($original) {
-                       common_element('img', array('src' => $original->url,
-                                                                               'class' => 'avatar original',
-                                                                               'width' => $original->width,
-                                                                               'height' => $original->height,
-                                                                               'alt' => $user->nickname));
-               }
-
-               $avatar = $profile->getAvatar(AVATAR_PROFILE_SIZE);
-
-               if ($avatar) {
-                       common_element('img', array('src' => $avatar->url,
-                                                                               'class' => 'avatar profile',
-                                                                               'width' => AVATAR_PROFILE_SIZE,
-                                                                               'height' => AVATAR_PROFILE_SIZE,
-                                                                               'alt' => $user->nickname));
-               }
-
-
-               common_element('input', array('name' => 'MAX_FILE_SIZE',
-                                                                         'type' => 'hidden',
-                                                                         'id' => 'MAX_FILE_SIZE',
-                                                                         'value' => MAX_AVATAR_SIZE));
-
-               common_element_start('p');
-
-
-               common_element('input', array('name' => 'avatarfile',
-                                                                         'type' => 'file',
-                                                                         'id' => 'avatarfile'));
-               common_element_end('p');
-
-               common_submit('upload', _('Upload'));
-               common_element_end('form');
-
-       }
-
-       function show_password_form() {
-
-               $user = common_current_user();
-               common_element_start('form', array('method' => 'POST',
-                                                                                  'id' => 'password',
-                                                                                  'action' =>
-                                                                                  common_local_url('profilesettings')));
-
-               common_hidden('token', common_session_token());
-
-               # Users who logged in with OpenID won't have a pwd
-               if ($user->password) {
-                       common_password('oldpassword', _('Old password'));
-               }
-               common_password('newpassword', _('New password'),
-                                               _('6 or more characters'));
-               common_password('confirm', _('Confirm'),
-                                               _('same as password above'));
-               common_submit('changepass', _('Change'));
-               common_element_end('form');
-       }
-
-       function save_profile() {
-               $nickname = $this->trimmed('nickname');
-               $fullname = $this->trimmed('fullname');
-               $homepage = $this->trimmed('homepage');
-               $bio = $this->trimmed('bio');
-               $location = $this->trimmed('location');
-               $autosubscribe = $this->boolean('autosubscribe');
-               $language = $this->trimmed('language');
-               $timezone = $this->trimmed('timezone');
-               $tagstring = $this->trimmed('tags');
-               
-               # Some validation
-
-               if (!Validate::string($nickname, array('min_length' => 1,
-                                                                                          'max_length' => 64,
-                                                                                          'format' => VALIDATE_NUM . VALIDATE_ALPHA_LOWER))) {
-                       $this->show_form(_('Nickname must have only lowercase letters and numbers and no spaces.'));
-                       return;
-               } else if (!User::allowed_nickname($nickname)) {
-                       $this->show_form(_('Not a valid nickname.'));
-                       return;
-               } else if (!is_null($homepage) && (strlen($homepage) > 0) &&
-                                  !Validate::uri($homepage, array('allowed_schemes' => array('http', 'https')))) {
-                       $this->show_form(_('Homepage is not a valid URL.'));
-                       return;
-               } else if (!is_null($fullname) && strlen($fullname) > 255) {
-                       $this->show_form(_('Full name is too long (max 255 chars).'));
-                       return;
-               } else if (!is_null($bio) && strlen($bio) > 140) {
-                       $this->show_form(_('Bio is too long (max 140 chars).'));
-                       return;
-               } else if (!is_null($location) && strlen($location) > 255) {
-                       $this->show_form(_('Location is too long (max 255 chars).'));
-                       return;
-               }  else if (is_null($timezone) || !in_array($timezone, DateTimeZone::listIdentifiers())) {
-                       $this->show_form(_('Timezone not selected.'));
-                       return;
-               } else if ($this->nickname_exists($nickname)) {
-                       $this->show_form(_('Nickname already in use. Try another one.'));
-                       return;
+class ProfilesettingsAction extends SettingsAction
+{
+
+    function get_instructions()
+    {
+        return _('You can update your personal profile info here '.
+                  'so people know more about you.');
+    }
+
+    function show_form($msg=null, $success=false)
+    {
+        $this->form_header(_('Profile settings'), $msg, $success);
+        $this->show_settings_form();
+        common_element('h2', null, _('Avatar'));
+        $this->show_avatar_form();
+        common_element('h2', null, _('Change password'));
+        $this->show_password_form();
+//        common_element('h2', null, _('Delete my account'));
+//        $this->show_delete_form();
+        common_show_footer();
+    }
+
+    function handle_post()
+    {
+
+        # CSRF protection
+
+        $token = $this->trimmed('token');
+        if (!$token || $token != common_session_token()) {
+            $this->show_form(_('There was a problem with your session token. Try again, please.'));
+            return;
+        }
+
+        if ($this->arg('save')) {
+            $this->save_profile();
+        } else if ($this->arg('upload')) {
+            $this->upload_avatar();
+        } else if ($this->arg('crop')) {
+            $this->crop_avatar();
+        } else if ($this->arg('changepass')) {
+            $this->change_password();
+        } else {
+            $this->show_form(_('Unexpected form submission.'));
+        }
+
+    }
+
+    function show_settings_form()
+    {
+
+        $user = common_current_user();
+        $profile = $user->getProfile();
+
+        common_element_start('form', array('method' => 'POST',
+                                           'id' => 'profilesettings',
+                                           'action' => common_local_url('profilesettings')));
+        common_hidden('token', common_session_token());
+        
+        # too much common patterns here... abstractable?
+        
+        common_input('nickname', _('Nickname'),
+                     ($this->arg('nickname')) ? $this->arg('nickname') : $profile->nickname,
+                     _('1-64 lowercase letters or numbers, no punctuation or spaces'));
+        common_input('fullname', _('Full name'),
+                     ($this->arg('fullname')) ? $this->arg('fullname') : $profile->fullname);
+        common_input('homepage', _('Homepage'),
+                     ($this->arg('homepage')) ? $this->arg('homepage') : $profile->homepage,
+                     _('URL of your homepage, blog, or profile on another site'));
+        common_textarea('bio', _('Bio'),
+                        ($this->arg('bio')) ? $this->arg('bio') : $profile->bio,
+                        _('Describe yourself and your interests in 140 chars'));
+        common_input('location', _('Location'),
+                     ($this->arg('location')) ? $this->arg('location') : $profile->location,
+                     _('Where you are, like "City, State (or Region), Country"'));
+        common_input('tags', _('Tags'),
+                     ($this->arg('tags')) ? $this->arg('tags') : implode(' ', $user->getSelfTags()),
+                     _('Tags for yourself (letters, numbers, -, ., and _), comma- or space- separated'));
+
+        $language = common_language();
+        common_dropdown('language', _('Language'), get_nice_language_list(), _('Preferred language'), true, $language);
+        $timezone = common_timezone();
+        $timezones = array();
+        foreach(DateTimeZone::listIdentifiers() as $k => $v) {
+            $timezones[$v] = $v;
+        }
+        common_dropdown('timezone', _('Timezone'), $timezones, _('What timezone are you normally in?'), true, $timezone);
+
+        common_checkbox('autosubscribe', _('Automatically subscribe to whoever subscribes to me (best for non-humans)'),
+                        ($this->arg('autosubscribe')) ? $this->boolean('autosubscribe') : $user->autosubscribe);
+
+        common_submit('save', _('Save'));
+
+        common_element_end('form');
+
+    }
+
+    function show_avatar_form()
+    {
+
+        $user = common_current_user();
+        $profile = $user->getProfile();
+
+        if (!$profile) {
+            common_log_db_error($user, 'SELECT', __FILE__);
+            $this->server_error(_('User without matching profile'));
+            return;
+        }
+        
+        $original = $profile->getOriginalAvatar();
+
+
+        common_element_start('form', array('enctype' => 'multipart/form-data',
+                                           'method' => 'POST',
+                                           'id' => 'avatar',
+                                           'action' =>
+                                           common_local_url('profilesettings')));
+        common_hidden('token', common_session_token());
+
+        if ($original) {
+            common_element_start('div', array('id'=>'avatar_original', 'class'=>'avatar_view'));
+            common_element('h3', null, _("Original:"));
+            common_element_start('div', array('id'=>'avatar_original_view'));
+            common_element('img', array('src' => $original->url,
+                                        'class' => 'avatar original',
+                                        'width' => $original->width,
+                                        'height' => $original->height,
+                                        'alt' => $user->nickname));
+            common_element_end('div');
+            common_element_end('div');
+        }
+
+        $avatar = $profile->getAvatar(AVATAR_PROFILE_SIZE);
+
+        if ($avatar) {
+            common_element_start('div', array('id'=>'avatar_preview', 'class'=>'avatar_view'));
+            common_element('h3', null, _("Preview:"));
+            common_element_start('div', array('id'=>'avatar_preview_view'));
+            common_element('img', array('src' => $original->url,//$avatar->url,
+                                        'class' => 'avatar profile',
+                                        'width' => AVATAR_PROFILE_SIZE,
+                                        'height' => AVATAR_PROFILE_SIZE,
+                                        'alt' => $user->nickname));
+            common_element_end('div');
+            common_element_end('div');
+
+            foreach(array('avatar_crop_x', 'avatar_crop_y', 'avatar_crop_w', 'avatar_crop_h') as $crop_info) {
+                common_element('input', array('name' => $crop_info,
+                                              'type' => 'hidden',
+                                              'id' => $crop_info));
+            }
+            common_submit('crop', _('Crop'));
+        }
+
+        common_element('input', array('name' => 'MAX_FILE_SIZE',
+                                      'type' => 'hidden',
+                                      'id' => 'MAX_FILE_SIZE',
+                                      'value' => MAX_AVATAR_SIZE));
+
+        common_element_start('p');
+
+        common_element('input', array('name' => 'avatarfile',
+                                      'type' => 'file',
+                                      'id' => 'avatarfile'));
+        common_element_end('p');
+
+        common_submit('upload', _('Upload'));
+        common_element_end('form');
+
+    }
+
+    function show_password_form()
+    {
+
+        $user = common_current_user();
+        common_element_start('form', array('method' => 'POST',
+                                           'id' => 'password',
+                                           'action' =>
+                                           common_local_url('profilesettings')));
+
+        common_hidden('token', common_session_token());
+
+        # Users who logged in with OpenID won't have a pwd
+        if ($user->password) {
+            common_password('oldpassword', _('Old password'));
+        }
+        common_password('newpassword', _('New password'),
+                        _('6 or more characters'));
+        common_password('confirm', _('Confirm'),
+                        _('same as password above'));
+        common_submit('changepass', _('Change'));
+        common_element_end('form');
+    }
+
+    function save_profile()
+    {
+        $nickname = $this->trimmed('nickname');
+        $fullname = $this->trimmed('fullname');
+        $homepage = $this->trimmed('homepage');
+        $bio = $this->trimmed('bio');
+        $location = $this->trimmed('location');
+        $autosubscribe = $this->boolean('autosubscribe');
+        $language = $this->trimmed('language');
+        $timezone = $this->trimmed('timezone');
+        $tagstring = $this->trimmed('tags');
+        
+        # Some validation
+
+        if (!Validate::string($nickname, array('min_length' => 1,
+                                               'max_length' => 64,
+                                               'format' => VALIDATE_NUM . VALIDATE_ALPHA_LOWER))) {
+            $this->show_form(_('Nickname must have only lowercase letters and numbers and no spaces.'));
+            return;
+        } else if (!User::allowed_nickname($nickname)) {
+            $this->show_form(_('Not a valid nickname.'));
+            return;
+        } else if (!is_null($homepage) && (strlen($homepage) > 0) &&
+                   !Validate::uri($homepage, array('allowed_schemes' => array('http', 'https')))) {
+            $this->show_form(_('Homepage is not a valid URL.'));
+            return;
+        } else if (!is_null($fullname) && strlen($fullname) > 255) {
+            $this->show_form(_('Full name is too long (max 255 chars).'));
+            return;
+        } else if (!is_null($bio) && strlen($bio) > 140) {
+            $this->show_form(_('Bio is too long (max 140 chars).'));
+            return;
+        } else if (!is_null($location) && strlen($location) > 255) {
+            $this->show_form(_('Location is too long (max 255 chars).'));
+            return;
+        }  else if (is_null($timezone) || !in_array($timezone, DateTimeZone::listIdentifiers())) {
+            $this->show_form(_('Timezone not selected.'));
+            return;
+        } else if ($this->nickname_exists($nickname)) {
+            $this->show_form(_('Nickname already in use. Try another one.'));
+            return;
         } else if (!is_null($language) && strlen($language) > 50) {
-               $this->show_form(_('Language is too long (max 50 chars).'));
-                       return;
-               }
-
-               if ($tagstring) {
-                       $tags = array_map('common_canonical_tag', preg_split('/[\s,]+/', $tagstring));
-               } else {
-                       $tags = array();
-               }
-                       
-               foreach ($tags as $tag) {
-                       if (!common_valid_profile_tag($tag)) {
-                               $this->show_form(sprintf(_('Invalid tag: "%s"'), $tag));
-                               return;
-                       }
-               }
-               
-               $user = common_current_user();
-
-               $user->query('BEGIN');
-
-               if ($user->nickname != $nickname ||
-                       $user->language != $language ||
-                       $user->timezone != $timezone) {
-
-                       common_debug('Updating user nickname from ' . $user->nickname . ' to ' . $nickname,
-                                                __FILE__);
-                       common_debug('Updating user language from ' . $user->language . ' to ' . $language,
-                                                __FILE__);
-                       common_debug('Updating user timezone from ' . $user->timezone . ' to ' . $timezone,
-                                                __FILE__);
-
-                       $original = clone($user);
-
-                       $user->nickname = $nickname;
-                       $user->language = $language;
-                       $user->timezone = $timezone;
-
-                       $result = $user->updateKeys($original);
-
-                       if ($result === FALSE) {
-                               common_log_db_error($user, 'UPDATE', __FILE__);
-                               common_server_error(_('Couldn\'t update user.'));
-                               return;
-                       } else {
-                               # Re-initialize language environment if it changed
-                               common_init_language();
-                       }
-               }
-
-               # XXX: XOR
-
-               if ($user->autosubscribe ^ $autosubscribe) {
-
-                       $original = clone($user);
-
-                       $user->autosubscribe = $autosubscribe;
-
-                       $result = $user->update($original);
-
-                       if ($result === FALSE) {
-                               common_log_db_error($user, 'UPDATE', __FILE__);
-                               common_server_error(_('Couldn\'t update user for autosubscribe.'));
-                               return;
-                       }
-               }
-
-               $profile = $user->getProfile();
-
-               $orig_profile = clone($profile);
-
-               $profile->nickname = $user->nickname;
-               $profile->fullname = $fullname;
-               $profile->homepage = $homepage;
-               $profile->bio = $bio;
-               $profile->location = $location;
-               $profile->profileurl = common_profile_url($nickname);
-
-               common_debug('Old profile: ' . common_log_objstring($orig_profile), __FILE__);
-               common_debug('New profile: ' . common_log_objstring($profile), __FILE__);
-
-               $result = $profile->update($orig_profile);
-
-               if (!$result) {
-                       common_log_db_error($profile, 'UPDATE', __FILE__);
-                       common_server_error(_('Couldn\'t save profile.'));
-                       return;
-               }
-
-               # Set the user tags
-               
-               $result = $user->setSelfTags($tags);
-
-               if (!$result) {
-                       common_server_error(_('Couldn\'t save tags.'));
-                       return;
-               }
-               
-               $user->query('COMMIT');
-
-               common_broadcast_profile($profile);
-
-               $this->show_form(_('Settings saved.'), TRUE);
-       }
-
-
-       function upload_avatar() {
-               switch ($_FILES['avatarfile']['error']) {
-                case UPLOAD_ERR_OK: # success, jump out
-                       break;
-                case UPLOAD_ERR_INI_SIZE:
-                case UPLOAD_ERR_FORM_SIZE:
-                       $this->show_form(_('That file is too big.'));
-                       return;
-                case UPLOAD_ERR_PARTIAL:
-                       @unlink($_FILES['avatarfile']['tmp_name']);
-                       $this->show_form(_('Partial upload.'));
-                       return;
-                default:
-                       $this->show_form(_('System error uploading file.'));
-                       return;
-               }
-
-               $info = @getimagesize($_FILES['avatarfile']['tmp_name']);
-
-               if (!$info) {
-                       @unlink($_FILES['avatarfile']['tmp_name']);
-                       $this->show_form(_('Not an image or corrupt file.'));
-                       return;
-               }
-
-               switch ($info[2]) {
-                case IMAGETYPE_GIF:
-                case IMAGETYPE_JPEG:
-                case IMAGETYPE_PNG:
-                       break;
-                default:
-                       $this->show_form(_('Unsupported image file format.'));
-                       return;
-               }
-
-               $user = common_current_user();
-               $profile = $user->getProfile();
-
-               if ($profile->setOriginal($_FILES['avatarfile']['tmp_name'])) {
-                       $this->show_form(_('Avatar updated.'), true);
-               } else {
-                       $this->show_form(_('Failed updating avatar.'));
-               }
-
-               @unlink($_FILES['avatarfile']['tmp_name']);
-       }
-
-       function nickname_exists($nickname) {
-               $user = common_current_user();
-               $other = User::staticGet('nickname', $nickname);
-               if (!$other) {
-                       return false;
-               } else {
-                       return $other->id != $user->id;
-               }
-       }
-
-       function change_password() {
-
-               $user = common_current_user();
-               assert(!is_null($user)); # should already be checked
-
-               # FIXME: scrub input
-
-               $newpassword = $this->arg('newpassword');
-               $confirm = $this->arg('confirm');
-               $token = $this->arg('token');
-
-               if (0 != strcmp($newpassword, $confirm)) {
-                       $this->show_form(_('Passwords don\'t match.'));
-                       return;
-               }
-
-               if ($user->password) {
-                       $oldpassword = $this->arg('oldpassword');
-
-                       if (!common_check_user($user->nickname, $oldpassword)) {
-                               $this->show_form(_('Incorrect old password'));
-                               return;
-                       }
-               }
-
-               $original = clone($user);
-
-               $user->password = common_munge_password($newpassword, $user->id);
-
-               $val = $user->validate();
-               if ($val !== TRUE) {
-                       $this->show_form(_('Error saving user; invalid.'));
-                       return;
-               }
-
-               if (!$user->update($original)) {
-                       common_server_error(_('Can\'t save new password.'));
-                       return;
-               }
-
-               $this->show_form(_('Password saved.'), true);
-       }
+            $this->show_form(_('Language is too long (max 50 chars).'));
+            return;
+        }
+
+        if ($tagstring) {
+            $tags = array_map('common_canonical_tag', preg_split('/[\s,]+/', $tagstring));
+        } else {
+            $tags = array();
+        }
+            
+        foreach ($tags as $tag) {
+            if (!common_valid_profile_tag($tag)) {
+                $this->show_form(sprintf(_('Invalid tag: "%s"'), $tag));
+                return;
+            }
+        }
+        
+        $user = common_current_user();
+
+        $user->query('BEGIN');
+
+        if ($user->nickname != $nickname ||
+            $user->language != $language ||
+            $user->timezone != $timezone) {
+
+            common_debug('Updating user nickname from ' . $user->nickname . ' to ' . $nickname,
+                         __FILE__);
+            common_debug('Updating user language from ' . $user->language . ' to ' . $language,
+                         __FILE__);
+            common_debug('Updating user timezone from ' . $user->timezone . ' to ' . $timezone,
+                         __FILE__);
+
+            $original = clone($user);
+
+            $user->nickname = $nickname;
+            $user->language = $language;
+            $user->timezone = $timezone;
+
+            $result = $user->updateKeys($original);
+
+            if ($result === false) {
+                common_log_db_error($user, 'UPDATE', __FILE__);
+                common_server_error(_('Couldn\'t update user.'));
+                return;
+            } else {
+                # Re-initialize language environment if it changed
+                common_init_language();
+            }
+        }
+
+        # XXX: XOR
+
+        if ($user->autosubscribe ^ $autosubscribe) {
+
+            $original = clone($user);
+
+            $user->autosubscribe = $autosubscribe;
+
+            $result = $user->update($original);
+
+            if ($result === false) {
+                common_log_db_error($user, 'UPDATE', __FILE__);
+                common_server_error(_('Couldn\'t update user for autosubscribe.'));
+                return;
+            }
+        }
+
+        $profile = $user->getProfile();
+
+        $orig_profile = clone($profile);
+
+        $profile->nickname = $user->nickname;
+        $profile->fullname = $fullname;
+        $profile->homepage = $homepage;
+        $profile->bio = $bio;
+        $profile->location = $location;
+        $profile->profileurl = common_profile_url($nickname);
+
+        common_debug('Old profile: ' . common_log_objstring($orig_profile), __FILE__);
+        common_debug('New profile: ' . common_log_objstring($profile), __FILE__);
+
+        $result = $profile->update($orig_profile);
+
+        if (!$result) {
+            common_log_db_error($profile, 'UPDATE', __FILE__);
+            common_server_error(_('Couldn\'t save profile.'));
+            return;
+        }
+
+        # Set the user tags
+        
+        $result = $user->setSelfTags($tags);
+
+        if (!$result) {
+            common_server_error(_('Couldn\'t save tags.'));
+            return;
+        }
+        
+        $user->query('COMMIT');
+
+        common_broadcast_profile($profile);
+
+        $this->show_form(_('Settings saved.'), true);
+    }
+
+
+    function upload_avatar()
+    {
+        switch ($_FILES['avatarfile']['error']) {
+         case UPLOAD_ERR_OK: # success, jump out
+            break;
+         case UPLOAD_ERR_INI_SIZE:
+         case UPLOAD_ERR_FORM_SIZE:
+            $this->show_form(_('That file is too big.'));
+            return;
+         case UPLOAD_ERR_PARTIAL:
+            @unlink($_FILES['avatarfile']['tmp_name']);
+            $this->show_form(_('Partial upload.'));
+            return;
+         default:
+            $this->show_form(_('System error uploading file.'));
+            return;
+        }
+
+        $info = @getimagesize($_FILES['avatarfile']['tmp_name']);
+
+        if (!$info) {
+            @unlink($_FILES['avatarfile']['tmp_name']);
+            $this->show_form(_('Not an image or corrupt file.'));
+            return;
+        }
+
+        switch ($info[2]) {
+         case IMAGETYPE_GIF:
+         case IMAGETYPE_JPEG:
+         case IMAGETYPE_PNG:
+            break;
+         default:
+            $this->show_form(_('Unsupported image file format.'));
+            return;
+        }
+
+        $user = common_current_user();
+        $profile = $user->getProfile();
+
+        if ($profile->setOriginal($_FILES['avatarfile']['tmp_name'])) {
+            $this->show_form(_('Avatar updated.'), true);
+        } else {
+            $this->show_form(_('Failed updating avatar.'));
+        }
+
+        @unlink($_FILES['avatarfile']['tmp_name']);
+    }
+
+    function crop_avatar() {
+
+        $user = common_current_user();
+        $profile = $user->getProfile();
+
+        $x = $this->arg('avatar_crop_x');
+        $y = $this->arg('avatar_crop_y');
+        $w = $this->arg('avatar_crop_w');
+        $h = $this->arg('avatar_crop_h');
+
+        if ($profile->crop_avatars($x, $y, $w, $h)) {
+            $this->show_form(_('Avatar updated.'), true);
+        } else {
+            $this->show_form(_('Failed updating avatar.'));
+        }
+    }
+
+    function nickname_exists($nickname)
+    {
+        $user = common_current_user();
+        $other = User::staticGet('nickname', $nickname);
+        if (!$other) {
+            return false;
+        } else {
+            return $other->id != $user->id;
+        }
+    }
+
+    function change_password()
+    {
+
+        $user = common_current_user();
+        assert(!is_null($user)); # should already be checked
+
+        # FIXME: scrub input
+
+        $newpassword = $this->arg('newpassword');
+        $confirm = $this->arg('confirm');
+        $token = $this->arg('token');
+
+        if (0 != strcmp($newpassword, $confirm)) {
+            $this->show_form(_('Passwords don\'t match.'));
+            return;
+        }
+
+        if ($user->password) {
+            $oldpassword = $this->arg('oldpassword');
+
+            if (!common_check_user($user->nickname, $oldpassword)) {
+                $this->show_form(_('Incorrect old password'));
+                return;
+            }
+        }
+
+        $original = clone($user);
+
+        $user->password = common_munge_password($newpassword, $user->id);
+
+        $val = $user->validate();
+        if ($val !== true) {
+            $this->show_form(_('Error saving user; invalid.'));
+            return;
+        }
+
+        if (!$user->update($original)) {
+            common_server_error(_('Can\'t save new password.'));
+            return;
+        }
+
+        $this->show_form(_('Password saved.'), true);
+    }
 }
index 218f801945d6048a2fab29464ae3e641649971ea..039e885e6ba4b53f22fd1fc2dc3298a17e2fb53f 100644 (file)
@@ -21,79 +21,85 @@ if (!defined('LACONICA')) { exit(1); }
 
 require_once(INSTALLDIR.'/lib/stream.php');
 
-class PublicAction extends StreamAction {
-
-       function handle($args) {
-               parent::handle($args);
-
-               $page = ($this->arg('page')) ? ($this->arg('page')+0) : 1;
-
-               header('X-XRDS-Location: '. common_local_url('publicxrds'));
-
-               common_show_header(_('Public timeline'),
-                                                  array($this, 'show_header'), NULL,
-                                                  array($this, 'show_top'));
-
-               # XXX: Public sidebar here?
-
-               $this->show_notices($page);
-
-               common_show_footer();
-       }
-
-       function show_top() {
-               if (common_logged_in()) {
-                       common_notice_form('public');
-               } else {
-                       $instr = $this->get_instructions();
-                       $output = common_markup_to_html($instr);
-                       common_element_start('div', 'instructions');
-                       common_raw($output);
-                       common_element_end('div');
-               }
-
-               $this->public_views_menu();
-
-               $this->show_feeds_list(array(0=>array('href'=>common_local_url('publicrss'),
-                                                                                         'type' => 'rss',
-                                                                                         'version' => 'RSS 1.0',
-                                                                                         'item' => 'publicrss'),
-                                                                        1=>array('href'=>common_local_url('publicatom'),
-                                                                                         'type' => 'atom',
-                                                                                         'version' => 'Atom 1.0',
-                                                                                         'item' => 'publicatom')));
-       }
-
-       function get_instructions() {
-               return _('This is %%site.name%%, a [micro-blogging](http://en.wikipedia.org/wiki/Micro-blogging) service ' .
-                                'based on the Free Software [Laconica](http://laconi.ca/) tool. ' .
-                                '[Join now](%%action.register%%) to share notices about yourself with friends, family, and colleagues! ([Read more](%%doc.help%%))');
-       }
-
-       function show_header() {
-               common_element('link', array('rel' => 'alternate',
-                                                                        'href' => common_local_url('publicrss'),
-                                                                        'type' => 'application/rss+xml',
-                                                                        'title' => _('Public Stream Feed')));
-               # for client side of OpenID authentication
-               common_element('meta', array('http-equiv' => 'X-XRDS-Location',
-                                                                        'content' => common_local_url('publicxrds')));
-       }
-
-       function show_notices($page) {
-
-               $cnt = 0;
-               $notice = Notice::publicStream(($page-1)*NOTICES_PER_PAGE,
-                                                                          NOTICES_PER_PAGE + 1);
-
-               if (!$notice) {
+class PublicAction extends StreamAction
+{
+
+    function handle($args)
+    {
+        parent::handle($args);
+
+        $page = ($this->arg('page')) ? ($this->arg('page')+0) : 1;
+
+        header('X-XRDS-Location: '. common_local_url('publicxrds'));
+
+        common_show_header(_('Public timeline'),
+                           array($this, 'show_header'), null,
+                           array($this, 'show_top'));
+
+        # XXX: Public sidebar here?
+
+        $this->show_notices($page);
+
+        common_show_footer();
+    }
+
+    function show_top()
+    {
+        if (common_logged_in()) {
+            common_notice_form('public');
+        } else {
+            $instr = $this->get_instructions();
+            $output = common_markup_to_html($instr);
+            common_element_start('div', 'instructions');
+            common_raw($output);
+            common_element_end('div');
+        }
+
+        $this->public_views_menu();
+
+        $this->show_feeds_list(array(0=>array('href'=>common_local_url('publicrss'),
+                                              'type' => 'rss',
+                                              'version' => 'RSS 1.0',
+                                              'item' => 'publicrss'),
+                                     1=>array('href'=>common_local_url('publicatom'),
+                                              'type' => 'atom',
+                                              'version' => 'Atom 1.0',
+                                              'item' => 'publicatom')));
+    }
+
+    function get_instructions()
+    {
+        return _('This is %%site.name%%, a [micro-blogging](http://en.wikipedia.org/wiki/Micro-blogging) service ' .
+                 'based on the Free Software [Laconica](http://laconi.ca/) tool. ' .
+                 '[Join now](%%action.register%%) to share notices about yourself with friends, family, and colleagues! ([Read more](%%doc.help%%))');
+    }
+
+    function show_header()
+    {
+        common_element('link', array('rel' => 'alternate',
+                                     'href' => common_local_url('publicrss'),
+                                     'type' => 'application/rss+xml',
+                                     'title' => _('Public Stream Feed')));
+        # for client side of OpenID authentication
+        common_element('meta', array('http-equiv' => 'X-XRDS-Location',
+                                     'content' => common_local_url('publicxrds')));
+    }
+
+    function show_notices($page)
+    {
+
+        $cnt = 0;
+        $notice = Notice::publicStream(($page-1)*NOTICES_PER_PAGE,
+                                       NOTICES_PER_PAGE + 1);
+
+        if (!$notice) {
             $this->server_error(_('Could not retrieve public stream.'));
             return;
-               }
+        }
 
         $cnt = $this->show_notice_list($notice);
 
-               common_pagination($page > 1, $cnt > NOTICES_PER_PAGE,
-                                                 $page, 'public');
-       }
+        common_pagination($page > 1, $cnt > NOTICES_PER_PAGE,
+                          $page, 'public');
+    }
 }
index 1ab6a8be06aa4214397ce5844a5d536e23fed535..822bc2db7618703d6b4221558c73b417bf16cfbf 100644 (file)
@@ -23,35 +23,40 @@ require_once(INSTALLDIR.'/lib/rssaction.php');
 
 // Formatting of RSS handled by Rss10Action
 
-class PublicrssAction extends Rss10Action {
-
-       function init() {
-               return true;
-       }
-
-       function get_notices($limit=0) {
-               
-               $notices = array();
-               
-               $notice = Notice::publicStream(0, ($limit == 0) ? 48 : $limit);
-               
-               while ($notice->fetch()) {
-                       $notices[] = clone($notice);
-               }
-               
-               return $notices;
-       }
-
-       function get_channel() {
-               global $config;
-               $c = array('url' => common_local_url('publicrss'),
-                                  'title' => sprintf(_('%s Public Stream'), $config['site']['name']),
-                                  'link' => common_local_url('public'),
-                                  'description' => sprintf(_('All updates for %s'), $config['site']['name']));
-               return $c;
-       }
-
-       function get_image() {
-               return NULL;
-       }
+class PublicrssAction extends Rss10Action
+{
+
+    function init()
+    {
+        return true;
+    }
+
+    function get_notices($limit=0)
+    {
+        
+        $notices = array();
+        
+        $notice = Notice::publicStream(0, ($limit == 0) ? 48 : $limit);
+        
+        while ($notice->fetch()) {
+            $notices[] = clone($notice);
+        }
+        
+        return $notices;
+    }
+
+    function get_channel()
+    {
+        global $config;
+        $c = array('url' => common_local_url('publicrss'),
+                   'title' => sprintf(_('%s Public Stream'), $config['site']['name']),
+                   'link' => common_local_url('public'),
+                   'description' => sprintf(_('All updates for %s'), $config['site']['name']));
+        return $c;
+    }
+
+    function get_image()
+    {
+        return null;
+    }
 }
\ No newline at end of file
index 951434c8783015f114079d75fd038cfd85e75522..3d731d79fa7e435fb06b17761fcfa8909f038d0c 100644 (file)
@@ -23,57 +23,61 @@ require_once(INSTALLDIR.'/lib/openid.php');
 
 # XXX: factor out similarities with XrdsAction
 
-class PublicxrdsAction extends Action {
+class PublicxrdsAction extends Action
+{
 
-       function is_readonly() {
-               return true;
-       }
+    function is_readonly()
+    {
+        return true;
+    }
 
-       function handle($args) {
+    function handle($args)
+    {
 
-               parent::handle($args);
+        parent::handle($args);
 
-               header('Content-Type: application/xrds+xml');
+        header('Content-Type: application/xrds+xml');
 
-               common_start_xml();
-               common_element_start('XRDS', array('xmlns' => 'xri://$xrds'));
+        common_start_xml();
+        common_element_start('XRDS', array('xmlns' => 'xri://$xrds'));
 
-               common_element_start('XRD', array('xmlns' => 'xri://$xrd*($v*2.0)',
-                                                                                 'xmlns:simple' => 'http://xrds-simple.net/core/1.0',
-                                                                                 'version' => '2.0'));
+        common_element_start('XRD', array('xmlns' => 'xri://$xrd*($v*2.0)',
+                                          'xmlns:simple' => 'http://xrds-simple.net/core/1.0',
+                                          'version' => '2.0'));
 
-               common_element('Type', NULL, 'xri://$xrds*simple');
+        common_element('Type', null, 'xri://$xrds*simple');
 
-               foreach (array('finishopenidlogin', 'finishaddopenid', 'finishimmediate') as $finish) {
-                       $this->show_service(Auth_OpenID_RP_RETURN_TO_URL_TYPE,
-                                                               common_local_url($finish));
-               }
+        foreach (array('finishopenidlogin', 'finishaddopenid', 'finishimmediate') as $finish) {
+            $this->show_service(Auth_OpenID_RP_RETURN_TO_URL_TYPE,
+                                common_local_url($finish));
+        }
 
-               common_element_end('XRD');
+        common_element_end('XRD');
 
-               common_element_end('XRDS');
-               common_end_xml();
-       }
+        common_element_end('XRDS');
+        common_end_xml();
+    }
 
-       function show_service($type, $uri, $params=NULL, $sigs=NULL, $localId=NULL) {
-               common_element_start('Service');
-               if ($uri) {
-                       common_element('URI', NULL, $uri);
-               }
-               common_element('Type', NULL, $type);
-               if ($params) {
-                       foreach ($params as $param) {
-                               common_element('Type', NULL, $param);
-                       }
-               }
-               if ($sigs) {
-                       foreach ($sigs as $sig) {
-                               common_element('Type', NULL, $sig);
-                       }
-               }
-               if ($localId) {
-                       common_element('LocalID', NULL, $localId);
-               }
-               common_element_end('Service');
-       }
+    function show_service($type, $uri, $params=null, $sigs=null, $localId=null)
+    {
+        common_element_start('Service');
+        if ($uri) {
+            common_element('URI', null, $uri);
+        }
+        common_element('Type', null, $type);
+        if ($params) {
+            foreach ($params as $param) {
+                common_element('Type', null, $param);
+            }
+        }
+        if ($sigs) {
+            foreach ($sigs as $sig) {
+                common_element('Type', null, $sig);
+            }
+        }
+        if ($localId) {
+            common_element('LocalID', null, $localId);
+        }
+        common_element_end('Service');
+    }
 }
\ No newline at end of file
index 38c42f41d1b056ac303f723dd324ce7391d3fd82..bb6ef81d602e4dc31a9b3242318716164d9fa6e6 100644 (file)
@@ -23,309 +23,321 @@ if (!defined('LACONICA')) { exit(1); }
 
 define(MAX_RECOVERY_TIME, 24 * 60 * 60);
 
-class RecoverpasswordAction extends Action {
+class RecoverpasswordAction extends Action
+{
 
-    function handle($args) {
+    function handle($args)
+    {
         parent::handle($args);
         if (common_logged_in()) {
-                       $this->client_error(_('You are already logged in!'));
+            $this->client_error(_('You are already logged in!'));
             return;
         } else if ($_SERVER['REQUEST_METHOD'] == 'POST') {
-               if ($this->arg('recover')) {
-               $this->recover_password();
+            if ($this->arg('recover')) {
+                $this->recover_password();
             } else if ($this->arg('reset')) {
-               $this->reset_password();
-                       } else {
-                               $this->client_error(_('Unexpected form submission.'));
-                       }
-               } else {
-                       if ($this->trimmed('code')) {
-                       $this->check_code();
-               } else {
-                       $this->show_form();
-                       }
-               }
-       }
-
-       function check_code() {
-
-               $code = $this->trimmed('code');
-               $confirm = Confirm_address::staticGet('code', $code);
-
-               if (!$confirm) {
-                       $this->client_error(_('No such recovery code.'));
-                       return;
-               }
-               if ($confirm->address_type != 'recover') {
-                       $this->client_error(_('Not a recovery code.'));
-                       return;
-               }
-
-               $user = User::staticGet($confirm->user_id);
-
-               if (!$user) {
-                       $this->server_error(_('Recovery code for unknown user.'));
-                       return;
-               }
-
-               $touched = strtotime($confirm->modified);
-               $email = $confirm->address;
-
-               # Burn this code
-
-               $result = $confirm->delete();
-
-               if (!$result) {
-                       common_log_db_error($confirm, 'DELETE', __FILE__);
-                       common_server_error(_('Error with confirmation code.'));
-                       return;
-               }
-
-               # These should be reaped, but for now we just check mod time
-               # Note: it's still deleted; let's avoid a second attempt!
-
-               if ((time() - $touched) > MAX_RECOVERY_TIME) {
-                       common_log(LOG_WARNING, 
-                                          'Attempted redemption on recovery code ' .
-                                          'that is ' . $touched . ' seconds old. ');
-                       $this->client_error(_('This confirmation code is too old. ' .
-                                              'Please start again.'));
-                       return;
-               }
-
-               # If we used an outstanding confirmation to send the email,
-               # it's been confirmed at this point.
-
-               if (!$user->email) {
-                       $orig = clone($user);
-                       $user->email = $email;
-                       $result = $user->updateKeys($orig);
-                       if (!$result) {
-                               common_log_db_error($user, 'UPDATE', __FILE__);
-                               $this->server_error(_('Could not update user with confirmed email address.'));
-                               return;
-                       }
-               }
-
-               # Success!
-
-               $this->set_temp_user($user);
-               $this->show_password_form();
-       }
-
-       function set_temp_user(&$user) {
-               common_ensure_session();
-               $_SESSION['tempuser'] = $user->id;
-       }
-
-       function get_temp_user() {
-               common_ensure_session();
-               $user_id = $_SESSION['tempuser'];
-               if ($user_id) {
-                       $user = User::staticGet($user_id);
-               }
-               return $user;
-       }
-
-       function clear_temp_user() {
-               common_ensure_session();
-               unset($_SESSION['tempuser']);
-       }
-
-       function show_top($msg=NULL) {
-               if ($msg) {
+                $this->reset_password();
+            } else {
+                $this->client_error(_('Unexpected form submission.'));
+            }
+        } else {
+            if ($this->trimmed('code')) {
+                $this->check_code();
+            } else {
+                $this->show_form();
+            }
+        }
+    }
+
+    function check_code()
+    {
+
+        $code = $this->trimmed('code');
+        $confirm = Confirm_address::staticGet('code', $code);
+
+        if (!$confirm) {
+            $this->client_error(_('No such recovery code.'));
+            return;
+        }
+        if ($confirm->address_type != 'recover') {
+            $this->client_error(_('Not a recovery code.'));
+            return;
+        }
+
+        $user = User::staticGet($confirm->user_id);
+
+        if (!$user) {
+            $this->server_error(_('Recovery code for unknown user.'));
+            return;
+        }
+
+        $touched = strtotime($confirm->modified);
+        $email = $confirm->address;
+
+        # Burn this code
+
+        $result = $confirm->delete();
+
+        if (!$result) {
+            common_log_db_error($confirm, 'DELETE', __FILE__);
+            common_server_error(_('Error with confirmation code.'));
+            return;
+        }
+
+        # These should be reaped, but for now we just check mod time
+        # Note: it's still deleted; let's avoid a second attempt!
+
+        if ((time() - $touched) > MAX_RECOVERY_TIME) {
+            common_log(LOG_WARNING, 
+                       'Attempted redemption on recovery code ' .
+                       'that is ' . $touched . ' seconds old. ');
+            $this->client_error(_('This confirmation code is too old. ' .
+                                   'Please start again.'));
+            return;
+        }
+
+        # If we used an outstanding confirmation to send the email,
+        # it's been confirmed at this point.
+
+        if (!$user->email) {
+            $orig = clone($user);
+            $user->email = $email;
+            $result = $user->updateKeys($orig);
+            if (!$result) {
+                common_log_db_error($user, 'UPDATE', __FILE__);
+                $this->server_error(_('Could not update user with confirmed email address.'));
+                return;
+            }
+        }
+
+        # Success!
+
+        $this->set_temp_user($user);
+        $this->show_password_form();
+    }
+
+    function set_temp_user(&$user)
+    {
+        common_ensure_session();
+        $_SESSION['tempuser'] = $user->id;
+    }
+
+    function get_temp_user()
+    {
+        common_ensure_session();
+        $user_id = $_SESSION['tempuser'];
+        if ($user_id) {
+            $user = User::staticGet($user_id);
+        }
+        return $user;
+    }
+
+    function clear_temp_user()
+    {
+        common_ensure_session();
+        unset($_SESSION['tempuser']);
+    }
+
+    function show_top($msg=null)
+    {
+        if ($msg) {
             common_element('div', 'error', $msg);
-               } else {
-                       common_element_start('div', 'instructions');
-                       common_element('p', NULL, 
-                                                  _('If you\'ve forgotten or lost your' .
-                                                     ' password, you can get a new one sent to' .
-                                                     ' the email address you have stored ' .
-                                                     ' in your account.'));
-                       common_element_end('div');
-               }
-       }
-
-       function show_password_top($msg=NULL) {
-               if ($msg) {
+        } else {
+            common_element_start('div', 'instructions');
+            common_element('p', null, 
+                           _('If you\'ve forgotten or lost your' .
+                              ' password, you can get a new one sent to' .
+                              ' the email address you have stored ' .
+                              ' in your account.'));
+            common_element_end('div');
+        }
+    }
+
+    function show_password_top($msg=null)
+    {
+        if ($msg) {
             common_element('div', 'error', $msg);
-               } else {
-                       common_element('div', 'instructions',
-                                                  _('You\'ve been identified. Enter a ' .
-                                                     ' new password below. '));
-               }
-       }
-
-       function show_form($msg=NULL) {
-
-               common_show_header(_('Recover password'), NULL,
-               $msg, array($this, 'show_top'));
-
-               common_element_start('form', array('method' => 'post',
-                                                                                  'id' => 'recoverpassword',
-                                                                                  'action' => common_local_url('recoverpassword')));
-               common_input('nicknameoremail', _('Nickname or email'),
-                                        $this->trimmed('nicknameoremail'),
-                            _('Your nickname on this server, ' .
-                               'or your registered email address.'));
-               common_submit('recover', _('Recover'));
-               common_element_end('form');
-               common_show_footer();
-       }
-
-       function show_password_form($msg=NULL) {
-
-               common_show_header(_('Reset password'), NULL,
-               $msg, array($this, 'show_password_top'));
-
-               common_element_start('form', array('method' => 'post',
-                                                                                  'id' => 'recoverpassword',
-                                                                                  'action' => common_local_url('recoverpassword')));
-               common_hidden('token', common_session_token());
-               common_password('newpassword', _('New password'),
-                                               _('6 or more characters, and don\'t forget it!'));
-               common_password('confirm', _('Confirm'),
-                                               _('Same as password above'));
-               common_submit('reset', _('Reset'));
-               common_element_end('form');
-               common_show_footer();
-       }
-
-       function recover_password() {
-               $nore = $this->trimmed('nicknameoremail');
-               if (!$nore) {
-                       $this->show_form(_('Enter a nickname or email address.'));
-                       return;
-               }
-
-               $user = User::staticGet('email', common_canonical_email($nore));
-
-               if (!$user) {
-                       $user = User::staticGet('nickname', common_canonical_nickname($nore));
-               }
-
-               # See if it's an unconfirmed email address
-
-               if (!$user) {
-                       $confirm_email = Confirm_address::staticGet('address', common_canonical_email($nore));
-                       if ($confirm_email && $confirm_email->address_type == 'email') {
-                               $user = User::staticGet($confirm_email->user_id);
-                       }
-               }
-
-               if (!$user) {
-                       $this->show_form(_('No user with that email address or username.'));
-                       return;
-               }
-
-               # Try to get an unconfirmed email address if they used a user name
-
-               if (!$user->email && !$confirm_email) {
-                       $confirm_email = Confirm_address::staticGet('user_id', $user->id);
-                       if ($confirm_email && $confirm_email->address_type != 'email') {
-                               # Skip non-email confirmations
-                               $confirm_email = NULL;
-                       }
-               }
-
-               if (!$user->email && !$confirm_email) {
-                       $this->client_error(_('No registered email address for that user.'));
-                       return;
-               }
-
-               # Success! We have a valid user and a confirmed or unconfirmed email address
-
-               $confirm = new Confirm_address();
-               $confirm->code = common_confirmation_code(128);
-               $confirm->address_type = 'recover';
-               $confirm->user_id = $user->id;
-               $confirm->address = (isset($user->email)) ? $user->email : $confirm_email->address;
-
-               if (!$confirm->insert()) {
-                       common_log_db_error($confirm, 'INSERT', __FILE__);
-                       $this->server_error(_('Error saving address confirmation.'));
-                       return;
-               }
-
-               $body = "Hey, $user->nickname.";
-               $body .= "\n\n";
-               $body .= 'Someone just asked for a new password ' .
-                        'for this account on ' . common_config('site', 'name') . '.';
-               $body .= "\n\n";
-               $body .= 'If it was you, and you want to confirm, use the URL below:';
-               $body .= "\n\n";
-               $body .= "\t".common_local_url('recoverpassword',
-                                                                  array('code' => $confirm->code));
-               $body .= "\n\n";
-               $body .= 'If not, just ignore this message.';
-               $body .= "\n\n";
-               $body .= 'Thanks for your time, ';
-               $body .= "\n";
-               $body .= common_config('site', 'name');
-               $body .= "\n";
-
-               mail_to_user($user, _('Password recovery requested'), $body, $confirm->address);
-
-               common_show_header(_('Password recovery requested'));
-               common_element('p', NULL,
-                              _('Instructions for recovering your password ' .
-                                 'have been sent to the email address registered to your ' .
-                                 'account.'));
-               common_show_footer();
-       }
-
-       function reset_password() {
-
-               # CSRF protection
-               $token = $this->trimmed('token');
-               if (!$token || $token != common_session_token()) {
-                       $this->show_form(_('There was a problem with your session token. Try again, please.'));
-                       return;
-               }
-
-               $user = $this->get_temp_user();
-
-               if (!$user) {
-                       $this->client_error(_('Unexpected password reset.'));
-                       return;
-               }
-
-               $newpassword = $this->trimmed('newpassword');
-               $confirm = $this->trimmed('confirm');
-
-               if (!$newpassword || strlen($newpassword) < 6) {
-                       $this->show_password_form(_('Password must be 6 chars or more.'));
-                       return;
-               }
-               if ($newpassword != $confirm) {
-                       $this->show_password_form(_('Password and confirmation do not match.'));
-                       return;
-               }
-
-               # OK, we're ready to go
-
-               $original = clone($user);
-
-               $user->password = common_munge_password($newpassword, $user->id);
-
-               if (!$user->update($original)) {
-                       common_log_db_error($user, 'UPDATE', __FILE__);
-                       common_server_error(_('Can\'t save new password.'));
-                       return;
-               }
-
-               $this->clear_temp_user();
-
-               if (!common_set_user($user->nickname)) {
-                       common_server_error(_('Error setting user.'));
-                       return;
-               }
-
-               common_real_login(true);
-
-               common_show_header(_('Password saved.'));
-               common_element('p', NULL, _('New password successfully saved. ' .
-                                            'You are now logged in.'));
-               common_show_footer();
-       }
+        } else {
+            common_element('div', 'instructions',
+                           _('You\'ve been identified. Enter a ' .
+                              ' new password below. '));
+        }
+    }
+
+    function show_form($msg=null)
+    {
+
+        common_show_header(_('Recover password'), null,
+        $msg, array($this, 'show_top'));
+
+        common_element_start('form', array('method' => 'post',
+                                           'id' => 'recoverpassword',
+                                           'action' => common_local_url('recoverpassword')));
+        common_input('nicknameoremail', _('Nickname or email'),
+                     $this->trimmed('nicknameoremail'),
+                     _('Your nickname on this server, ' .
+                        'or your registered email address.'));
+        common_submit('recover', _('Recover'));
+        common_element_end('form');
+        common_show_footer();
+    }
+
+    function show_password_form($msg=null)
+    {
+
+        common_show_header(_('Reset password'), null,
+        $msg, array($this, 'show_password_top'));
+
+        common_element_start('form', array('method' => 'post',
+                                           'id' => 'recoverpassword',
+                                           'action' => common_local_url('recoverpassword')));
+        common_hidden('token', common_session_token());
+        common_password('newpassword', _('New password'),
+                        _('6 or more characters, and don\'t forget it!'));
+        common_password('confirm', _('Confirm'),
+                        _('Same as password above'));
+        common_submit('reset', _('Reset'));
+        common_element_end('form');
+        common_show_footer();
+    }
+
+    function recover_password()
+    {
+        $nore = $this->trimmed('nicknameoremail');
+        if (!$nore) {
+            $this->show_form(_('Enter a nickname or email address.'));
+            return;
+        }
+
+        $user = User::staticGet('email', common_canonical_email($nore));
+
+        if (!$user) {
+            $user = User::staticGet('nickname', common_canonical_nickname($nore));
+        }
+
+        # See if it's an unconfirmed email address
+
+        if (!$user) {
+            $confirm_email = Confirm_address::staticGet('address', common_canonical_email($nore));
+            if ($confirm_email && $confirm_email->address_type == 'email') {
+                $user = User::staticGet($confirm_email->user_id);
+            }
+        }
+
+        if (!$user) {
+            $this->show_form(_('No user with that email address or username.'));
+            return;
+        }
+
+        # Try to get an unconfirmed email address if they used a user name
+
+        if (!$user->email && !$confirm_email) {
+            $confirm_email = Confirm_address::staticGet('user_id', $user->id);
+            if ($confirm_email && $confirm_email->address_type != 'email') {
+                # Skip non-email confirmations
+                $confirm_email = null;
+            }
+        }
+
+        if (!$user->email && !$confirm_email) {
+            $this->client_error(_('No registered email address for that user.'));
+            return;
+        }
+
+        # Success! We have a valid user and a confirmed or unconfirmed email address
+
+        $confirm = new Confirm_address();
+        $confirm->code = common_confirmation_code(128);
+        $confirm->address_type = 'recover';
+        $confirm->user_id = $user->id;
+        $confirm->address = (isset($user->email)) ? $user->email : $confirm_email->address;
+
+        if (!$confirm->insert()) {
+            common_log_db_error($confirm, 'INSERT', __FILE__);
+            $this->server_error(_('Error saving address confirmation.'));
+            return;
+        }
+
+        $body = "Hey, $user->nickname.";
+        $body .= "\n\n";
+        $body .= 'Someone just asked for a new password ' .
+                 'for this account on ' . common_config('site', 'name') . '.';
+        $body .= "\n\n";
+        $body .= 'If it was you, and you want to confirm, use the URL below:';
+        $body .= "\n\n";
+        $body .= "\t".common_local_url('recoverpassword',
+                                   array('code' => $confirm->code));
+        $body .= "\n\n";
+        $body .= 'If not, just ignore this message.';
+        $body .= "\n\n";
+        $body .= 'Thanks for your time, ';
+        $body .= "\n";
+        $body .= common_config('site', 'name');
+        $body .= "\n";
+
+        mail_to_user($user, _('Password recovery requested'), $body, $confirm->address);
+
+        common_show_header(_('Password recovery requested'));
+        common_element('p', null,
+                       _('Instructions for recovering your password ' .
+                          'have been sent to the email address registered to your ' .
+                          'account.'));
+        common_show_footer();
+    }
+
+    function reset_password()
+    {
+
+        # CSRF protection
+        $token = $this->trimmed('token');
+        if (!$token || $token != common_session_token()) {
+            $this->show_form(_('There was a problem with your session token. Try again, please.'));
+            return;
+        }
+
+        $user = $this->get_temp_user();
+
+        if (!$user) {
+            $this->client_error(_('Unexpected password reset.'));
+            return;
+        }
+
+        $newpassword = $this->trimmed('newpassword');
+        $confirm = $this->trimmed('confirm');
+
+        if (!$newpassword || strlen($newpassword) < 6) {
+            $this->show_password_form(_('Password must be 6 chars or more.'));
+            return;
+        }
+        if ($newpassword != $confirm) {
+            $this->show_password_form(_('Password and confirmation do not match.'));
+            return;
+        }
+
+        # OK, we're ready to go
+
+        $original = clone($user);
+
+        $user->password = common_munge_password($newpassword, $user->id);
+
+        if (!$user->update($original)) {
+            common_log_db_error($user, 'UPDATE', __FILE__);
+            common_server_error(_('Can\'t save new password.'));
+            return;
+        }
+
+        $this->clear_temp_user();
+
+        if (!common_set_user($user->nickname)) {
+            common_server_error(_('Error setting user.'));
+            return;
+        }
+
+        common_real_login(true);
+
+        common_show_header(_('Password saved.'));
+        common_element('p', null, _('New password successfully saved. ' .
+                                     'You are now logged in.'));
+        common_show_footer();
+    }
 }
index a22ffca28e8b53b8cecba0419deb3f5722e20a77..c479816ef5d532b4a98e69f0f5a802eed19a5714 100644 (file)
 
 if (!defined('LACONICA')) { exit(1); }
 
-class RegisterAction extends Action {
-
-       function handle($args) {
-               parent::handle($args);
-
-               if (common_config('site', 'closed')) {
-                       common_user_error(_('Registration not allowed.'));
-               } else if (common_logged_in()) {
-                       common_user_error(_('Already logged in.'));
-               } else if ($_SERVER['REQUEST_METHOD'] == 'POST') {
-                       $this->try_register();
-               } else {
-                       $this->show_form();
-               }
-       }
-
-       function try_register() {
-
-               $token = $this->trimmed('token');
-               if (!$token || $token != common_session_token()) {
-                       $this->show_form(_('There was a problem with your session token. Try again, please.'));
-                       return;
-               }
-
-               $nickname = $this->trimmed('nickname');
-               $email = $this->trimmed('email');
-               $fullname = $this->trimmed('fullname');
-               $homepage = $this->trimmed('homepage');
-               $bio = $this->trimmed('bio');
-               $location = $this->trimmed('location');
-
-               # We don't trim these... whitespace is OK in a password!
-
-               $password = $this->arg('password');
-               $confirm = $this->arg('confirm');
-
-               # invitation code, if any
-
-               $code = $this->trimmed('code');
-
-               if ($code) {
-                       $invite = Invitation::staticGet($code);
-               }
-
-               if (common_config('site', 'inviteonly') && !($code && $invite)) {
-                       $this->client_error(_('Sorry, only invited people can register.'));
-                       return;
-               }
-
-               # Input scrubbing
-
-               $nickname = common_canonical_nickname($nickname);
-               $email = common_canonical_email($email);
-
-               if (!$this->boolean('license')) {
-                       $this->show_form(_('You can\'t register if you don\'t agree to the license.'));
-               } else if ($email && !Validate::email($email, true)) {
-                       $this->show_form(_('Not a valid email address.'));
-               } else if (!Validate::string($nickname, array('min_length' => 1,
-                                                                                                         'max_length' => 64,
-                                                                                                         'format' => VALIDATE_NUM . VALIDATE_ALPHA_LOWER))) {
-                       $this->show_form(_('Nickname must have only lowercase letters and numbers and no spaces.'));
-               } else if ($this->nickname_exists($nickname)) {
-                       $this->show_form(_('Nickname already in use. Try another one.'));
-               } else if (!User::allowed_nickname($nickname)) {
-                       $this->show_form(_('Not a valid nickname.'));
-               } else if ($this->email_exists($email)) {
-                       $this->show_form(_('Email address already exists.'));
-               } else if (!is_null($homepage) && (strlen($homepage) > 0) &&
-                                  !Validate::uri($homepage, array('allowed_schemes' => array('http', 'https')))) {
-                       $this->show_form(_('Homepage is not a valid URL.'));
-                       return;
-               } else if (!is_null($fullname) && strlen($fullname) > 255) {
-                       $this->show_form(_('Full name is too long (max 255 chars).'));
-                       return;
-               } else if (!is_null($bio) && strlen($bio) > 140) {
-                       $this->show_form(_('Bio is too long (max 140 chars).'));
-                       return;
-               } else if (!is_null($location) && strlen($location) > 255) {
-                       $this->show_form(_('Location is too long (max 255 chars).'));
-                       return;
-               } else if (strlen($password) < 6) {
-                       $this->show_form(_('Password must be 6 or more characters.'));
-                       return;
-               } else if ($password != $confirm) {
-                       $this->show_form(_('Passwords don\'t match.'));
-               } else if ($user = User::register(array('nickname' => $nickname, 'password' => $password, 'email' => $email,
-                                                                                               'fullname' => $fullname, 'homepage' => $homepage, 'bio' => $bio,
-                                                                                               'location' => $location, 'code' => $code))) {
-                       if (!$user) {
-                               $this->show_form(_('Invalid username or password.'));
-                               return;
-                       }
-                       # success!
-                       if (!common_set_user($user)) {
-                               common_server_error(_('Error setting user.'));
-                               return;
-                       }
-                       # this is a real login
-                       common_real_login(true);
-                       if ($this->boolean('rememberme')) {
-                               common_debug('Adding rememberme cookie for ' . $nickname);
-                               common_rememberme($user);
-                       }
-                       # Re-init language env in case it changed (not yet, but soon)
-                       common_init_language();
-                       $this->show_success();
-               } else {
-                       $this->show_form(_('Invalid username or password.'));
-               }
-       }
-
-       # checks if *CANONICAL* nickname exists
-
-       function nickname_exists($nickname) {
-               $user = User::staticGet('nickname', $nickname);
-               return ($user !== false);
-       }
-
-       # checks if *CANONICAL* email exists
-
-       function email_exists($email) {
-               $email = common_canonical_email($email);
-               if (!$email || strlen($email) == 0) {
-                       return false;
-               }
-               $user = User::staticGet('email', $email);
-               return ($user !== false);
-       }
-
-       function show_top($error=NULL) {
-               if ($error) {
-                       common_element('p', 'error', $error);
-               } else {
-                       $instr = common_markup_to_html(_('With this form you can create a new account. ' .
-                                                                                        'You can then post notices and link up to friends and colleagues. '.
-                                                                                        '(Have an [OpenID](http://openid.net/)? ' .
-                                                                                        'Try our [OpenID registration](%%action.openidlogin%%)!)'));
-
-                       common_element_start('div', 'instructions');
-                       common_raw($instr);
-                       common_element_end('div');
-               }
-       }
-
-       function show_form($error=NULL) {
-               global $config;
-
-               $code = $this->trimmed('code');
-
-               if ($code) {
-                       $invite = Invitation::staticGet($code);
-               }
-
-               if (common_config('site', 'inviteonly') && !($code && $invite)) {
-                       $this->client_error(_('Sorry, only invited people can register.'));
-                       return;
-               }
-
-               common_show_header(_('Register'), NULL, $error, array($this, 'show_top'));
-               common_element_start('form', array('method' => 'post',
-                                                                                  'id' => 'login',
-                                                                                  'action' => common_local_url('register')));
-
-               common_hidden('token', common_session_token());
-
-               if ($code) {
-                       common_hidden('code', $code);
-               }
-
-               common_input('nickname', _('Nickname'), $this->trimmed('nickname'),
-                                        _('1-64 lowercase letters or numbers, no punctuation or spaces. Required.'));
-               common_password('password', _('Password'),
-                                               _('6 or more characters. Required.'));
-               common_password('confirm', _('Confirm'),
-                                               _('Same as password above. Required.'));
-               if ($invite && $invite->address_type == 'email') {
-                       common_input('email', _('Email'), $invite->address,
-                                        _('Used only for updates, announcements, and password recovery'));
-               } else {
-                       common_input('email', _('Email'), $this->trimmed('email'),
-                                                _('Used only for updates, announcements, and password recovery'));
-               }
-               common_input('fullname', _('Full name'),
-                                        $this->trimmed('fullname'),
-                                         _('Longer name, preferably your "real" name'));
-               common_input('homepage', _('Homepage'),
-                                        $this->trimmed('homepage'),
-                                        _('URL of your homepage, blog, or profile on another site'));
-               common_textarea('bio', _('Bio'),
-                                               $this->trimmed('bio'),
-                                                _('Describe yourself and your interests in 140 chars'));
-               common_input('location', _('Location'),
-                                        $this->trimmed('location'),
-                                        _('Where you are, like "City, State (or Region), Country"'));
-               common_checkbox('rememberme', _('Remember me'),
-                                               $this->boolean('rememberme'),
-                               _('Automatically login in the future; not for shared computers!'));
-               common_element_start('p');
-               $attrs = array('type' => 'checkbox',
-                                          'id' => 'license',
-                                          'name' => 'license',
-                                          'value' => 'true');
-               if ($this->boolean('license')) {
-                       $attrs['checked'] = 'checked';
-               }
-               common_element('input', $attrs);
-           common_text(_('My text and files are available under '));
-               common_element('a', array('href' => $config['license']['url']),
-                                          $config['license']['title']);
-               common_text(_(' except this private data: password, email address, IM address, phone number.'));
-               common_element_end('p');
-               common_submit('submit', _('Register'));
-               common_element_end('form');
-               common_show_footer();
-       }
-
-       function show_success() {
-               $nickname = $this->arg('nickname');
-               common_show_header(_('Registration successful'));
-               common_element_start('div', 'success');
-               $instr = sprintf(_('Congratulations, %s! And welcome to %%%%site.name%%%%. From here, you may want to...'. "\n\n" .
-                                                  '* Go to [your profile](%s) and post your first message.' .  "\n" .
-                                                  '* Add a [Jabber/GTalk address](%%%%action.imsettings%%%%) so you can send notices through instant messages.' . "\n" .
-                                                  '* [Search for people](%%%%action.peoplesearch%%%%) that you may know or that share your interests. ' . "\n" .
-                                                  '* Update your [profile settings](%%%%action.profilesettings%%%%) to tell others more about you. ' . "\n" .
-                                                  '* Read over the [online docs](%%%%doc.help%%%%) for features you may have missed. ' . "\n\n" .
-                                                  'Thanks for signing up and we hope you enjoy using this service.'),
-                                                $nickname, common_local_url('showstream', array('nickname' => $nickname)));
-               common_raw(common_markup_to_html($instr));
-               $have_email = $this->trimmed('email');
-               if ($have_email) {
-                       $emailinstr = _('(You should receive a message by email momentarily, with ' .
-                                                       'instructions on how to confirm your email address.)');
-                       common_raw(common_markup_to_html($emailinstr));
-               }
-               common_element_end('div');
-               common_show_footer();
-       }
+class RegisterAction extends Action
+{
+    function handle($args)
+    {
+        parent::handle($args);
+
+        if (common_config('site', 'closed')) {
+            common_user_error(_('Registration not allowed.'));
+        } else if (common_logged_in()) {
+            common_user_error(_('Already logged in.'));
+        } else if ($_SERVER['REQUEST_METHOD'] == 'POST') {
+            $this->try_register();
+        } else {
+            $this->show_form();
+        }
+    }
+
+    function try_register()
+    {
+        $token = $this->trimmed('token');
+        if (!$token || $token != common_session_token()) {
+            $this->show_form(_('There was a problem with your session token. Try again, please.'));
+            return;
+        }
+
+        $nickname = $this->trimmed('nickname');
+        $email = $this->trimmed('email');
+        $fullname = $this->trimmed('fullname');
+        $homepage = $this->trimmed('homepage');
+        $bio = $this->trimmed('bio');
+        $location = $this->trimmed('location');
+
+        # We don't trim these... whitespace is OK in a password!
+
+        $password = $this->arg('password');
+        $confirm = $this->arg('confirm');
+
+        # invitation code, if any
+
+        $code = $this->trimmed('code');
+
+        if ($code) {
+            $invite = Invitation::staticGet($code);
+        }
+
+        if (common_config('site', 'inviteonly') && !($code && $invite)) {
+            $this->client_error(_('Sorry, only invited people can register.'));
+            return;
+        }
+
+        # Input scrubbing
+
+        $nickname = common_canonical_nickname($nickname);
+        $email = common_canonical_email($email);
+
+        if (!$this->boolean('license')) {
+            $this->show_form(_('You can\'t register if you don\'t agree to the license.'));
+        } else if ($email && !Validate::email($email, true)) {
+            $this->show_form(_('Not a valid email address.'));
+        } else if (!Validate::string($nickname, array('min_length' => 1,
+                                                      'max_length' => 64,
+                                                      'format' => VALIDATE_NUM . VALIDATE_ALPHA_LOWER))) {
+            $this->show_form(_('Nickname must have only lowercase letters and numbers and no spaces.'));
+        } else if ($this->nickname_exists($nickname)) {
+            $this->show_form(_('Nickname already in use. Try another one.'));
+        } else if (!User::allowed_nickname($nickname)) {
+            $this->show_form(_('Not a valid nickname.'));
+        } else if ($this->email_exists($email)) {
+            $this->show_form(_('Email address already exists.'));
+        } else if (!is_null($homepage) && (strlen($homepage) > 0) &&
+                   !Validate::uri($homepage, array('allowed_schemes' => array('http', 'https')))) {
+            $this->show_form(_('Homepage is not a valid URL.'));
+            return;
+        } else if (!is_null($fullname) && strlen($fullname) > 255) {
+            $this->show_form(_('Full name is too long (max 255 chars).'));
+            return;
+        } else if (!is_null($bio) && strlen($bio) > 140) {
+            $this->show_form(_('Bio is too long (max 140 chars).'));
+            return;
+        } else if (!is_null($location) && strlen($location) > 255) {
+            $this->show_form(_('Location is too long (max 255 chars).'));
+            return;
+        } else if (strlen($password) < 6) {
+            $this->show_form(_('Password must be 6 or more characters.'));
+            return;
+        } else if ($password != $confirm) {
+            $this->show_form(_('Passwords don\'t match.'));
+        } else if ($user = User::register(array('nickname' => $nickname, 'password' => $password, 'email' => $email,
+                                                'fullname' => $fullname, 'homepage' => $homepage, 'bio' => $bio,
+                                                'location' => $location, 'code' => $code))) {
+            if (!$user) {
+                $this->show_form(_('Invalid username or password.'));
+                return;
+            }
+            # success!
+            if (!common_set_user($user)) {
+                common_server_error(_('Error setting user.'));
+                return;
+            }
+            # this is a real login
+            common_real_login(true);
+            if ($this->boolean('rememberme')) {
+                common_debug('Adding rememberme cookie for ' . $nickname);
+                common_rememberme($user);
+            }
+            # Re-init language env in case it changed (not yet, but soon)
+            common_init_language();
+            $this->show_success();
+        } else {
+            $this->show_form(_('Invalid username or password.'));
+        }
+    }
+
+    # checks if *CANONICAL* nickname exists
+
+    function nickname_exists($nickname)
+    {
+        $user = User::staticGet('nickname', $nickname);
+        return ($user !== false);
+    }
+
+    # checks if *CANONICAL* email exists
+
+    function email_exists($email)
+    {
+        $email = common_canonical_email($email);
+        if (!$email || strlen($email) == 0) {
+            return false;
+        }
+        $user = User::staticGet('email', $email);
+        return ($user !== false);
+    }
+
+    function show_top($error=null)
+    {
+        if ($error) {
+            common_element('p', 'error', $error);
+        } else {
+            $instr = common_markup_to_html(_('With this form you can create a new account. ' .
+                                             'You can then post notices and link up to friends and colleagues. '.
+                                             '(Have an [OpenID](http://openid.net/)? ' .
+                                             'Try our [OpenID registration](%%action.openidlogin%%)!)'));
+
+            common_element_start('div', 'instructions');
+            common_raw($instr);
+            common_element_end('div');
+        }
+    }
+
+    function show_form($error=null)
+    {
+        global $config;
+
+        $code = $this->trimmed('code');
+
+        if ($code) {
+            $invite = Invitation::staticGet($code);
+        }
+
+        if (common_config('site', 'inviteonly') && !($code && $invite)) {
+            $this->client_error(_('Sorry, only invited people can register.'));
+            return;
+        }
+
+        common_show_header(_('Register'), null, $error, array($this, 'show_top'));
+        common_element_start('form', array('method' => 'post',
+                                           'id' => 'login',
+                                           'action' => common_local_url('register')));
+
+        common_hidden('token', common_session_token());
+
+        if ($code) {
+            common_hidden('code', $code);
+        }
+
+        common_input('nickname', _('Nickname'), $this->trimmed('nickname'),
+                     _('1-64 lowercase letters or numbers, no punctuation or spaces. Required.'));
+        common_password('password', _('Password'),
+                        _('6 or more characters. Required.'));
+        common_password('confirm', _('Confirm'),
+                        _('Same as password above. Required.'));
+        if ($invite && $invite->address_type == 'email') {
+            common_input('email', _('Email'), $invite->address,
+                     _('Used only for updates, announcements, and password recovery'));
+        } else {
+            common_input('email', _('Email'), $this->trimmed('email'),
+                         _('Used only for updates, announcements, and password recovery'));
+        }
+        common_input('fullname', _('Full name'),
+                     $this->trimmed('fullname'),
+                      _('Longer name, preferably your "real" name'));
+        common_input('homepage', _('Homepage'),
+                     $this->trimmed('homepage'),
+                     _('URL of your homepage, blog, or profile on another site'));
+        common_textarea('bio', _('Bio'),
+                        $this->trimmed('bio'),
+                         _('Describe yourself and your interests in 140 chars'));
+        common_input('location', _('Location'),
+                     $this->trimmed('location'),
+                     _('Where you are, like "City, State (or Region), Country"'));
+        common_checkbox('rememberme', _('Remember me'),
+                        $this->boolean('rememberme'),
+                        _('Automatically login in the future; not for shared computers!'));
+        common_element_start('p');
+        $attrs = array('type' => 'checkbox',
+                       'id' => 'license',
+                       'name' => 'license',
+                       'value' => 'true');
+        if ($this->boolean('license')) {
+            $attrs['checked'] = 'checked';
+        }
+        common_element('input', $attrs);
+        common_text(_('My text and files are available under '));
+        common_element('a', array('href' => $config['license']['url']),
+                       $config['license']['title']);
+        common_text(_(' except this private data: password, email address, IM address, phone number.'));
+        common_element_end('p');
+        common_submit('submit', _('Register'));
+        common_element_end('form');
+        common_show_footer();
+    }
+
+    function show_success()
+    {
+        $nickname = $this->arg('nickname');
+        common_show_header(_('Registration successful'));
+        common_element_start('div', 'success');
+        $instr = sprintf(_('Congratulations, %s! And welcome to %%%%site.name%%%%. From here, you may want to...'. "\n\n" .
+                           '* Go to [your profile](%s) and post your first message.' .  "\n" .
+                           '* Add a [Jabber/GTalk address](%%%%action.imsettings%%%%) so you can send notices through instant messages.' . "\n" .
+                           '* [Search for people](%%%%action.peoplesearch%%%%) that you may know or that share your interests. ' . "\n" .
+                           '* Update your [profile settings](%%%%action.profilesettings%%%%) to tell others more about you. ' . "\n" .
+                           '* Read over the [online docs](%%%%doc.help%%%%) for features you may have missed. ' . "\n\n" .
+                           'Thanks for signing up and we hope you enjoy using this service.'),
+                         $nickname, common_local_url('showstream', array('nickname' => $nickname)));
+        common_raw(common_markup_to_html($instr));
+        $have_email = $this->trimmed('email');
+        if ($have_email) {
+            $emailinstr = _('(You should receive a message by email momentarily, with ' .
+                            'instructions on how to confirm your email address.)');
+            common_raw(common_markup_to_html($emailinstr));
+        }
+        common_element_end('div');
+        common_show_footer();
+    }
 
 }
index c3a09bcfc247272676f432dd36dcdc7f11f14c96..a9494772eb707802a9a9a2fef64118d5689c9946 100644 (file)
@@ -21,366 +21,379 @@ if (!defined('LACONICA')) { exit(1); }
 
 require_once(INSTALLDIR.'/lib/omb.php');
 
-class RemotesubscribeAction extends Action {
-
-       function handle($args) {
-
-               parent::handle($args);
-
-               if (common_logged_in()) {
-                       common_user_error(_('You can use the local subscription!'));
-                   return;
-               }
-
-               if ($_SERVER['REQUEST_METHOD'] == 'POST') {
-
-                       # CSRF protection
-                       $token = $this->trimmed('token');
-                       if (!$token || $token != common_session_token()) {
-                               $this->show_form(_('There was a problem with your session token. Try again, please.'));
-                               return;
-                       }
-
-                       $this->remote_subscription();
-               } else {
-                       $this->show_form();
-               }
-       }
-
-       function get_instructions() {
-               return _('To subscribe, you can [login](%%action.login%%),' .
-                         ' or [register](%%action.register%%) a new ' .
-                         ' account. If you already have an account ' .
-                         ' on a [compatible microblogging site](%%doc.openmublog%%), ' .
-                         ' enter your profile URL below.');
-       }
-
-       function show_top($err=NULL) {
-               if ($err) {
-                       common_element('div', 'error', $err);
-               } else {
-                       $instructions = $this->get_instructions();
-                       $output = common_markup_to_html($instructions);
-                       common_element_start('div', 'instructions');
-                       common_raw($output);
-                       common_element_end('p');
-               }
-       }
-
-       function show_form($err=NULL) {
-               $nickname = $this->trimmed('nickname');
-               $profile = $this->trimmed('profile_url');
-               common_show_header(_('Remote subscribe'), NULL, $err,
-                                                  array($this, 'show_top'));
-               # id = remotesubscribe conflicts with the
-               # button on profile page
-               common_element_start('form', array('id' => 'remsub', 'method' => 'post',
-                                                                                  'action' => common_local_url('remotesubscribe')));
-               common_hidden('token', common_session_token());
-               common_input('nickname', _('User nickname'), $nickname,
-                                        _('Nickname of the user you want to follow'));
-               common_input('profile_url', _('Profile URL'), $profile,
-                                        _('URL of your profile on another compatible microblogging service'));
-               common_submit('submit', _('Subscribe'));
-               common_element_end('form');
-               common_show_footer();
-       }
-
-       function remote_subscription() {
-               $user = $this->get_user();
-
-               if (!$user) {
-                       $this->show_form(_('No such user.'));
-                       return;
-               }
-
-               $profile = $this->trimmed('profile_url');
-
-               if (!$profile) {
-                       $this->show_form(_('No such user.'));
-                       return;
-               }
-
-               if (!Validate::uri($profile, array('allowed_schemes' => array('http', 'https')))) {
-                       $this->show_form(_('Invalid profile URL (bad format)'));
-                       return;
-               }
-
-               $fetcher = Auth_Yadis_Yadis::getHTTPFetcher();
-               $yadis = Auth_Yadis_Yadis::discover($profile, $fetcher);
-
-               if (!$yadis || $yadis->failed) {
-                       $this->show_form(_('Not a valid profile URL (no YADIS document).'));
-                       return;
-               }
-
-               # XXX: a little liberal for sites that accidentally put whitespace before the xml declaration
+class RemotesubscribeAction extends Action
+{
+
+    function handle($args)
+    {
+
+        parent::handle($args);
+
+        if (common_logged_in()) {
+            common_user_error(_('You can use the local subscription!'));
+            return;
+        }
+
+        if ($_SERVER['REQUEST_METHOD'] == 'POST') {
+
+            # CSRF protection
+            $token = $this->trimmed('token');
+            if (!$token || $token != common_session_token()) {
+                $this->show_form(_('There was a problem with your session token. Try again, please.'));
+                return;
+            }
+
+            $this->remote_subscription();
+        } else {
+            $this->show_form();
+        }
+    }
+
+    function get_instructions()
+    {
+        return _('To subscribe, you can [login](%%action.login%%),' .
+                  ' or [register](%%action.register%%) a new ' .
+                  ' account. If you already have an account ' .
+                  ' on a [compatible microblogging site](%%doc.openmublog%%), ' .
+                  ' enter your profile URL below.');
+    }
+
+    function show_top($err=null)
+    {
+        if ($err) {
+            common_element('div', 'error', $err);
+        } else {
+            $instructions = $this->get_instructions();
+            $output = common_markup_to_html($instructions);
+            common_element_start('div', 'instructions');
+            common_raw($output);
+            common_element_end('p');
+        }
+    }
+
+    function show_form($err=null)
+    {
+        $nickname = $this->trimmed('nickname');
+        $profile = $this->trimmed('profile_url');
+        common_show_header(_('Remote subscribe'), null, $err,
+                           array($this, 'show_top'));
+        # id = remotesubscribe conflicts with the
+        # button on profile page
+        common_element_start('form', array('id' => 'remsub', 'method' => 'post',
+                                           'action' => common_local_url('remotesubscribe')));
+        common_hidden('token', common_session_token());
+        common_input('nickname', _('User nickname'), $nickname,
+                     _('Nickname of the user you want to follow'));
+        common_input('profile_url', _('Profile URL'), $profile,
+                     _('URL of your profile on another compatible microblogging service'));
+        common_submit('submit', _('Subscribe'));
+        common_element_end('form');
+        common_show_footer();
+    }
+
+    function remote_subscription()
+    {
+        $user = $this->get_user();
+
+        if (!$user) {
+            $this->show_form(_('No such user.'));
+            return;
+        }
+
+        $profile = $this->trimmed('profile_url');
+
+        if (!$profile) {
+            $this->show_form(_('No such user.'));
+            return;
+        }
+
+        if (!Validate::uri($profile, array('allowed_schemes' => array('http', 'https')))) {
+            $this->show_form(_('Invalid profile URL (bad format)'));
+            return;
+        }
+
+        $fetcher = Auth_Yadis_Yadis::getHTTPFetcher();
+        $yadis = Auth_Yadis_Yadis::discover($profile, $fetcher);
+
+        if (!$yadis || $yadis->failed) {
+            $this->show_form(_('Not a valid profile URL (no YADIS document).'));
+            return;
+        }
+
+        # XXX: a little liberal for sites that accidentally put whitespace before the xml declaration
 
         $xrds =& Auth_Yadis_XRDS::parseXRDS(trim($yadis->response_text));
 
-               if (!$xrds) {
-                       $this->show_form(_('Not a valid profile URL (no XRDS defined).'));
-                       return;
-               }
+        if (!$xrds) {
+            $this->show_form(_('Not a valid profile URL (no XRDS defined).'));
+            return;
+        }
 
-               $omb = $this->getOmb($xrds);
+        $omb = $this->getOmb($xrds);
 
-               if (!$omb) {
-                       $this->show_form(_('Not a valid profile URL (incorrect services).'));
-                       return;
-               }
+        if (!$omb) {
+            $this->show_form(_('Not a valid profile URL (incorrect services).'));
+            return;
+        }
 
-               if (omb_service_uri($omb[OAUTH_ENDPOINT_REQUEST]) ==
-                       common_local_url('requesttoken'))
-               {
-                       $this->show_form(_('That\'s a local profile! Login to subscribe.'));
-                       return;
-               }
-
-               if (User::staticGet('uri', omb_local_id($omb[OAUTH_ENDPOINT_REQUEST]))) {
-                       $this->show_form(_('That\'s a local profile! Login to subscribe.'));
-                       return;
-               }
-
-               list($token, $secret) = $this->request_token($omb);
-
-               if (!$token || !$secret) {
-                       $this->show_form(_('Couldn\'t get a request token.'));
-                       return;
-               }
-
-               $this->request_authorization($user, $omb, $token, $secret);
-       }
-
-       function get_user() {
-               $user = NULL;
-               $nickname = $this->trimmed('nickname');
-               if ($nickname) {
-                       $user = User::staticGet('nickname', $nickname);
-               }
-               return $user;
-       }
-
-       function getOmb($xrds) {
-
-           static $omb_endpoints = array(OMB_ENDPOINT_UPDATEPROFILE, OMB_ENDPOINT_POSTNOTICE);
-               static $oauth_endpoints = array(OAUTH_ENDPOINT_REQUEST, OAUTH_ENDPOINT_AUTHORIZE,
-                                                                               OAUTH_ENDPOINT_ACCESS);
-               $omb = array();
-
-               # XXX: the following code could probably be refactored to eliminate dupes
-
-               $oauth_services = omb_get_services($xrds, OAUTH_DISCOVERY);
-
-               if (!$oauth_services) {
-                       return NULL;
-               }
-
-               $oauth_service = $oauth_services[0];
-
-               $oauth_xrd = $this->getXRD($oauth_service, $xrds);
+        if (omb_service_uri($omb[OAUTH_ENDPOINT_REQUEST]) ==
+            common_local_url('requesttoken'))
+        {
+            $this->show_form(_('That\'s a local profile! Login to subscribe.'));
+            return;
+        }
+
+        if (User::staticGet('uri', omb_local_id($omb[OAUTH_ENDPOINT_REQUEST]))) {
+            $this->show_form(_('That\'s a local profile! Login to subscribe.'));
+            return;
+        }
+
+        list($token, $secret) = $this->request_token($omb);
+
+        if (!$token || !$secret) {
+            $this->show_form(_('Couldn\'t get a request token.'));
+            return;
+        }
+
+        $this->request_authorization($user, $omb, $token, $secret);
+    }
+
+    function get_user()
+    {
+        $user = null;
+        $nickname = $this->trimmed('nickname');
+        if ($nickname) {
+            $user = User::staticGet('nickname', $nickname);
+        }
+        return $user;
+    }
+
+    function getOmb($xrds)
+    {
+
+        static $omb_endpoints = array(OMB_ENDPOINT_UPDATEPROFILE, OMB_ENDPOINT_POSTNOTICE);
+        static $oauth_endpoints = array(OAUTH_ENDPOINT_REQUEST, OAUTH_ENDPOINT_AUTHORIZE,
+                                        OAUTH_ENDPOINT_ACCESS);
+        $omb = array();
+
+        # XXX: the following code could probably be refactored to eliminate dupes
+
+        $oauth_services = omb_get_services($xrds, OAUTH_DISCOVERY);
+
+        if (!$oauth_services) {
+            return null;
+        }
+
+        $oauth_service = $oauth_services[0];
+
+        $oauth_xrd = $this->getXRD($oauth_service, $xrds);
+
+        if (!$oauth_xrd) {
+            return null;
+        }
+
+        if (!$this->addServices($oauth_xrd, $oauth_endpoints, $omb)) {
+            return null;
+        }
+
+        $omb_services = omb_get_services($xrds, OMB_NAMESPACE);
 
-               if (!$oauth_xrd) {
-                       return NULL;
-               }
+        if (!$omb_services) {
+            return null;
+        }
+
+        $omb_service = $omb_services[0];
+
+        $omb_xrd = $this->getXRD($omb_service, $xrds);
+
+        if (!$omb_xrd) {
+            return null;
+        }
+
+        if (!$this->addServices($omb_xrd, $omb_endpoints, $omb)) {
+            return null;
+        }
+
+        # XXX: check that we got all the services we needed
+
+        foreach (array_merge($omb_endpoints, $oauth_endpoints) as $type) {
+            if (!array_key_exists($type, $omb) || !$omb[$type]) {
+                return null;
+            }
+        }
+
+        if (!omb_local_id($omb[OAUTH_ENDPOINT_REQUEST])) {
+            return null;
+        }
+
+        return $omb;
+    }
 
-               if (!$this->addServices($oauth_xrd, $oauth_endpoints, $omb)) {
-                       return NULL;
-               }
+    function getXRD($main_service, $main_xrds)
+    {
+        $uri = omb_service_uri($main_service);
+        if (strpos($uri, "#") !== 0) {
+            # FIXME: more rigorous handling of external service definitions
+            return null;
+        }
+        $id = substr($uri, 1);
+        $nodes = $main_xrds->allXrdNodes;
+        $parser = $main_xrds->parser;
+        foreach ($nodes as $node) {
+            $attrs = $parser->attributes($node);
+            if (array_key_exists('xml:id', $attrs) &&
+                $attrs['xml:id'] == $id) {
+                # XXX: trick the constructor into thinking this is the only node
+                $bogus_nodes = array($node);
+                return new Auth_Yadis_XRDS($parser, $bogus_nodes);
+            }
+        }
+        return null;
+    }
+
+    function addServices($xrd, $types, &$omb)
+    {
+        foreach ($types as $type) {
+            $matches = omb_get_services($xrd, $type);
+            if ($matches) {
+                $omb[$type] = $matches[0];
+            } else {
+                # no match for type
+                return false;
+            }
+        }
+        return true;
+    }
 
-               $omb_services = omb_get_services($xrds, OMB_NAMESPACE);
+    function request_token($omb)
+    {
+        $con = omb_oauth_consumer();
 
-               if (!$omb_services) {
-                       return NULL;
-               }
+        $url = omb_service_uri($omb[OAUTH_ENDPOINT_REQUEST]);
 
-               $omb_service = $omb_services[0];
+        # XXX: Is this the right thing to do? Strip off GET params and make them
+        # POST params? Seems wrong to me.
 
-               $omb_xrd = $this->getXRD($omb_service, $xrds);
+        $parsed = parse_url($url);
+        $params = array();
+        parse_str($parsed['query'], $params);
 
-               if (!$omb_xrd) {
-                       return NULL;
-               }
+        $req = OAuthRequest::from_consumer_and_token($con, null, "POST", $url, $params);
 
-               if (!$this->addServices($omb_xrd, $omb_endpoints, $omb)) {
-                       return NULL;
-               }
+        $listener = omb_local_id($omb[OAUTH_ENDPOINT_REQUEST]);
 
-               # XXX: check that we got all the services we needed
+        if (!$listener) {
+            return null;
+        }
 
-               foreach (array_merge($omb_endpoints, $oauth_endpoints) as $type) {
-                       if (!array_key_exists($type, $omb) || !$omb[$type]) {
-                               return NULL;
-                       }
-               }
-
-               if (!omb_local_id($omb[OAUTH_ENDPOINT_REQUEST])) {
-                       return NULL;
-               }
-
-               return $omb;
-       }
-
-       function getXRD($main_service, $main_xrds) {
-               $uri = omb_service_uri($main_service);
-               if (strpos($uri, "#") !== 0) {
-                       # FIXME: more rigorous handling of external service definitions
-                       return NULL;
-               }
-               $id = substr($uri, 1);
-               $nodes = $main_xrds->allXrdNodes;
-               $parser = $main_xrds->parser;
-               foreach ($nodes as $node) {
-                       $attrs = $parser->attributes($node);
-                       if (array_key_exists('xml:id', $attrs) &&
-                               $attrs['xml:id'] == $id) {
-                               # XXX: trick the constructor into thinking this is the only node
-                               $bogus_nodes = array($node);
-                               return new Auth_Yadis_XRDS($parser, $bogus_nodes);
-                       }
-               }
-               return NULL;
-       }
-
-       function addServices($xrd, $types, &$omb) {
-               foreach ($types as $type) {
-                       $matches = omb_get_services($xrd, $type);
-                       if ($matches) {
-                               $omb[$type] = $matches[0];
-                       } else {
-                               # no match for type
-                               return false;
-                       }
-               }
-               return true;
-       }
-
-       function request_token($omb) {
-               $con = omb_oauth_consumer();
-
-               $url = omb_service_uri($omb[OAUTH_ENDPOINT_REQUEST]);
-
-               # XXX: Is this the right thing to do? Strip off GET params and make them
-               # POST params? Seems wrong to me.
-
-               $parsed = parse_url($url);
-               $params = array();
-               parse_str($parsed['query'], $params);
-
-               $req = OAuthRequest::from_consumer_and_token($con, NULL, "POST", $url, $params);
-
-               $listener = omb_local_id($omb[OAUTH_ENDPOINT_REQUEST]);
-
-               if (!$listener) {
-                       return NULL;
-               }
-
-               $req->set_parameter('omb_listener', $listener);
-               $req->set_parameter('omb_version', OMB_VERSION_01);
-
-               # XXX: test to see if endpoint accepts this signature method
-
-               $req->sign_request(omb_hmac_sha1(), $con, NULL);
-
-               # We re-use this tool's fetcher, since it's pretty good
-
-               $fetcher = Auth_Yadis_Yadis::getHTTPFetcher();
-
-               $result = $fetcher->post($req->get_normalized_http_url(),
-                                                                $req->to_postdata(),
+        $req->set_parameter('omb_listener', $listener);
+        $req->set_parameter('omb_version', OMB_VERSION_01);
+
+        # XXX: test to see if endpoint accepts this signature method
+
+        $req->sign_request(omb_hmac_sha1(), $con, null);
+
+        # We re-use this tool's fetcher, since it's pretty good
+
+        $fetcher = Auth_Yadis_Yadis::getHTTPFetcher();
+
+        $result = $fetcher->post($req->get_normalized_http_url(),
+                                 $req->to_postdata(),
                                  array('User-Agent' => 'Laconica/' . LACONICA_VERSION));
 
-               if ($result->status != 200) {
-                       return NULL;
-               }
+        if ($result->status != 200) {
+            return null;
+        }
 
-               parse_str($result->body, $return);
+        parse_str($result->body, $return);
 
-               return array($return['oauth_token'], $return['oauth_token_secret']);
-       }
+        return array($return['oauth_token'], $return['oauth_token_secret']);
+    }
 
-       function request_authorization($user, $omb, $token, $secret) {
-               global $config; # for license URL
+    function request_authorization($user, $omb, $token, $secret)
+    {
+        global $config; # for license URL
 
-               $con = omb_oauth_consumer();
-               $tok = new OAuthToken($token, $secret);
+        $con = omb_oauth_consumer();
+        $tok = new OAuthToken($token, $secret);
 
-               $url = omb_service_uri($omb[OAUTH_ENDPOINT_AUTHORIZE]);
+        $url = omb_service_uri($omb[OAUTH_ENDPOINT_AUTHORIZE]);
 
-               # XXX: Is this the right thing to do? Strip off GET params and make them
-               # POST params? Seems wrong to me.
+        # XXX: Is this the right thing to do? Strip off GET params and make them
+        # POST params? Seems wrong to me.
 
-               $parsed = parse_url($url);
-               $params = array();
-               parse_str($parsed['query'], $params);
+        $parsed = parse_url($url);
+        $params = array();
+        parse_str($parsed['query'], $params);
 
-               $req = OAuthRequest::from_consumer_and_token($con, $tok, 'GET', $url, $params);
+        $req = OAuthRequest::from_consumer_and_token($con, $tok, 'GET', $url, $params);
 
-               # We send over a ton of information. This lets the other
-               # server store info about our user, and it lets the current
-               # user decide if they really want to authorize the subscription.
+        # We send over a ton of information. This lets the other
+        # server store info about our user, and it lets the current
+        # user decide if they really want to authorize the subscription.
 
-               $req->set_parameter('omb_version', OMB_VERSION_01);
-               $req->set_parameter('omb_listener', omb_local_id($omb[OAUTH_ENDPOINT_REQUEST]));
-               $req->set_parameter('omb_listenee', $user->uri);
-               $req->set_parameter('omb_listenee_profile', common_profile_url($user->nickname));
-               $req->set_parameter('omb_listenee_nickname', $user->nickname);
-               $req->set_parameter('omb_listenee_license', $config['license']['url']);
+        $req->set_parameter('omb_version', OMB_VERSION_01);
+        $req->set_parameter('omb_listener', omb_local_id($omb[OAUTH_ENDPOINT_REQUEST]));
+        $req->set_parameter('omb_listenee', $user->uri);
+        $req->set_parameter('omb_listenee_profile', common_profile_url($user->nickname));
+        $req->set_parameter('omb_listenee_nickname', $user->nickname);
+        $req->set_parameter('omb_listenee_license', $config['license']['url']);
 
-               $profile = $user->getProfile();
-               if (!$profile) {
-                       common_log_db_error($user, 'SELECT', __FILE__);
-                       $this->server_error(_('User without matching profile'));
-                       return;
-               }
+        $profile = $user->getProfile();
+        if (!$profile) {
+            common_log_db_error($user, 'SELECT', __FILE__);
+            $this->server_error(_('User without matching profile'));
+            return;
+        }
 
-               if ($profile->fullname) {
-                       $req->set_parameter('omb_listenee_fullname', $profile->fullname);
-               }
-               if ($profile->homepage) {
-                       $req->set_parameter('omb_listenee_homepage', $profile->homepage);
-               }
-               if ($profile->bio) {
-                       $req->set_parameter('omb_listenee_bio', $profile->bio);
-               }
-               if ($profile->location) {
-                       $req->set_parameter('omb_listenee_location', $profile->location);
-               }
-               $avatar = $profile->getAvatar(AVATAR_PROFILE_SIZE);
-               if ($avatar) {
-                       $req->set_parameter('omb_listenee_avatar', $avatar->url);
-               }
+        if ($profile->fullname) {
+            $req->set_parameter('omb_listenee_fullname', $profile->fullname);
+        }
+        if ($profile->homepage) {
+            $req->set_parameter('omb_listenee_homepage', $profile->homepage);
+        }
+        if ($profile->bio) {
+            $req->set_parameter('omb_listenee_bio', $profile->bio);
+        }
+        if ($profile->location) {
+            $req->set_parameter('omb_listenee_location', $profile->location);
+        }
+        $avatar = $profile->getAvatar(AVATAR_PROFILE_SIZE);
+        if ($avatar) {
+            $req->set_parameter('omb_listenee_avatar', $avatar->url);
+        }
 
-               # XXX: add a nonce to prevent replay attacks
+        # XXX: add a nonce to prevent replay attacks
 
-               $req->set_parameter('oauth_callback', common_local_url('finishremotesubscribe'));
+        $req->set_parameter('oauth_callback', common_local_url('finishremotesubscribe'));
 
-               # XXX: test to see if endpoint accepts this signature method
+        # XXX: test to see if endpoint accepts this signature method
 
-               $req->sign_request(omb_hmac_sha1(), $con, $tok);
+        $req->sign_request(omb_hmac_sha1(), $con, $tok);
 
-               # store all our info here
+        # store all our info here
 
-               $omb['listenee'] = $user->nickname;
-               $omb['listener'] = omb_local_id($omb[OAUTH_ENDPOINT_REQUEST]);
-               $omb['token'] = $token;
-               $omb['secret'] = $secret;
-               # call doesn't work after bounce back so we cache; maybe serialization issue...?
-               $omb['access_token_url'] = omb_service_uri($omb[OAUTH_ENDPOINT_ACCESS]);
-               $omb['post_notice_url'] = omb_service_uri($omb[OMB_ENDPOINT_POSTNOTICE]);
-               $omb['update_profile_url'] = omb_service_uri($omb[OMB_ENDPOINT_UPDATEPROFILE]);
+        $omb['listenee'] = $user->nickname;
+        $omb['listener'] = omb_local_id($omb[OAUTH_ENDPOINT_REQUEST]);
+        $omb['token'] = $token;
+        $omb['secret'] = $secret;
+        # call doesn't work after bounce back so we cache; maybe serialization issue...?
+        $omb['access_token_url'] = omb_service_uri($omb[OAUTH_ENDPOINT_ACCESS]);
+        $omb['post_notice_url'] = omb_service_uri($omb[OMB_ENDPOINT_POSTNOTICE]);
+        $omb['update_profile_url'] = omb_service_uri($omb[OMB_ENDPOINT_UPDATEPROFILE]);
 
-               common_ensure_session();
+        common_ensure_session();
 
-               $_SESSION['oauth_authorization_request'] = $omb;
+        $_SESSION['oauth_authorization_request'] = $omb;
 
-               # Redirect to authorization service
+        # Redirect to authorization service
 
-               common_redirect($req->to_url());
-               return;
-       }
+        common_redirect($req->to_url());
+        return;
+    }
 
-       function make_nonce() {
-               return common_good_rand(16);
-       }
+    function make_nonce()
+    {
+        return common_good_rand(16);
+    }
 }
index 835871ffc17b704485390539e88b99571be53d62..eceeb4d650fa7b6aa9c4d14e2031c4b6140df716 100644 (file)
@@ -21,74 +21,80 @@ if (!defined('LACONICA')) { exit(1); }
 
 require_once(INSTALLDIR.'/actions/showstream.php');
 
-class RepliesAction extends StreamAction {
+class RepliesAction extends StreamAction
+{
 
-       function handle($args) {
+    function handle($args)
+    {
 
-               parent::handle($args);
+        parent::handle($args);
 
-               $nickname = common_canonical_nickname($this->arg('nickname'));
-               $user = User::staticGet('nickname', $nickname);
+        $nickname = common_canonical_nickname($this->arg('nickname'));
+        $user = User::staticGet('nickname', $nickname);
 
-               if (!$user) {
-                       $this->no_such_user();
-                       return;
-               }
+        if (!$user) {
+            $this->no_such_user();
+            return;
+        }
 
-               $profile = $user->getProfile();
+        $profile = $user->getProfile();
 
-               if (!$profile) {
-                       common_server_error(_('User has no profile.'));
-                       return;
-               }
+        if (!$profile) {
+            common_server_error(_('User has no profile.'));
+            return;
+        }
 
-               # Looks like we're good; show the header
+        # Looks like we're good; show the header
 
-               common_show_header(sprintf(_("Replies to %s"), $profile->nickname),
-                                                  array($this, 'show_header'), $user,
-                                                  array($this, 'show_top'));
+        common_show_header(sprintf(_("Replies to %s"), $profile->nickname),
+                           array($this, 'show_header'), $user,
+                           array($this, 'show_top'));
 
-               $this->show_replies($user);
+        $this->show_replies($user);
 
-               common_show_footer();
-       }
+        common_show_footer();
+    }
 
-       function no_such_user() {
-               common_user_error(_('No such user.'));
-       }
+    function no_such_user()
+    {
+        common_user_error(_('No such user.'));
+    }
 
-       function show_header($user) {
-               common_element('link', array('rel' => 'alternate',
-                                                                        'href' => common_local_url('repliesrss', array('nickname' =>
-                                                                                                                                                                       $user->nickname)),
-                                                                        'type' => 'application/rss+xml',
-                                                                        'title' => sprintf(_('Feed for replies to %s'), $user->nickname)));
-       }
+    function show_header($user)
+    {
+        common_element('link', array('rel' => 'alternate',
+                                     'href' => common_local_url('repliesrss', array('nickname' =>
+                                                                                    $user->nickname)),
+                                     'type' => 'application/rss+xml',
+                                     'title' => sprintf(_('Feed for replies to %s'), $user->nickname)));
+    }
 
-       function show_top($user) {
-               $cur = common_current_user();
+    function show_top($user)
+    {
+        $cur = common_current_user();
 
-               if ($cur && $cur->id == $user->id) {
-                       common_notice_form('replies');
-               }
+        if ($cur && $cur->id == $user->id) {
+            common_notice_form('replies');
+        }
 
-               $this->views_menu();
+        $this->views_menu();
 
-               $this->show_feeds_list(array(0=>array('href'=>common_local_url('repliesrss', array('nickname' => $user->nickname)),
-                                                                                         'type' => 'rss',
-                                                                                         'version' => 'RSS 1.0',
-                                                                                         'item' => 'repliesrss')));
-       }
+        $this->show_feeds_list(array(0=>array('href'=>common_local_url('repliesrss', array('nickname' => $user->nickname)),
+                                              'type' => 'rss',
+                                              'version' => 'RSS 1.0',
+                                              'item' => 'repliesrss')));
+    }
 
-       function show_replies($user) {
+    function show_replies($user)
+    {
 
-               $page = ($this->arg('page')) ? ($this->arg('page')+0) : 1;
+        $page = ($this->arg('page')) ? ($this->arg('page')+0) : 1;
 
-               $notice = $user->getReplies(($page-1) * NOTICES_PER_PAGE, NOTICES_PER_PAGE + 1);
+        $notice = $user->getReplies(($page-1) * NOTICES_PER_PAGE, NOTICES_PER_PAGE + 1);
 
-               $cnt = $this->show_notice_list($notice);
+        $cnt = $this->show_notice_list($notice);
 
-               common_pagination($page > 1, $cnt > NOTICES_PER_PAGE,
-                                                 $page, 'replies', array('nickname' => $user->nickname));
-       }
+        common_pagination($page > 1, $cnt > NOTICES_PER_PAGE,
+                          $page, 'replies', array('nickname' => $user->nickname));
+    }
 }
index 7369db5e047ae6f16d8ddbf17f53f512512d0a86..5f85f8d2e8b27ebd9096d49dae228a320b511c62 100644 (file)
@@ -23,57 +23,62 @@ require_once(INSTALLDIR.'/lib/rssaction.php');
 
 // Formatting of RSS handled by Rss10Action
 
-class RepliesrssAction extends Rss10Action {
+class RepliesrssAction extends Rss10Action
+{
 
-       var $user = NULL;
+    var $user = null;
 
-       function init() {
-               $nickname = $this->trimmed('nickname');
-               $this->user = User::staticGet('nickname', $nickname);
+    function init()
+    {
+        $nickname = $this->trimmed('nickname');
+        $this->user = User::staticGet('nickname', $nickname);
 
-               if (!$this->user) {
-                       common_user_error(_('No such user.'));
-                       return false;
-               } else {
-                       return true;
-               }
-       }
+        if (!$this->user) {
+            common_user_error(_('No such user.'));
+            return false;
+        } else {
+            return true;
+        }
+    }
 
-       function get_notices($limit=0) {
+    function get_notices($limit=0)
+    {
 
-               $user = $this->user;
+        $user = $this->user;
 
-               $notice = $user->getReplies(0, ($limit == 0) ? 48 : $limit);
+        $notice = $user->getReplies(0, ($limit == 0) ? 48 : $limit);
 
-               $notices = array();
-               
-               while ($notice->fetch()) {
-                       $notices[] = clone($notice);
-               }
+        $notices = array();
+        
+        while ($notice->fetch()) {
+            $notices[] = clone($notice);
+        }
 
-               return $notices;
-       }
+        return $notices;
+    }
 
-       function get_channel() {
-               $user = $this->user;
-               $c = array('url' => common_local_url('repliesrss',
-                                                                                        array('nickname' =>
-                                                                                                  $user->nickname)),
-                                  'title' => sprintf(_("Replies to %s"), $user->nickname),
-                                  'link' => common_local_url('replies',
-                                                                                         array('nickname' =>
-                                                                                                       $user->nickname)),
-                                  'description' => sprintf(_('Feed for replies to %s'), $user->nickname));
-               return $c;
-       }
+    function get_channel()
+    {
+        $user = $this->user;
+        $c = array('url' => common_local_url('repliesrss',
+                                             array('nickname' =>
+                                                   $user->nickname)),
+                   'title' => sprintf(_("Replies to %s"), $user->nickname),
+                   'link' => common_local_url('replies',
+                                              array('nickname' =>
+                                                    $user->nickname)),
+                   'description' => sprintf(_('Feed for replies to %s'), $user->nickname));
+        return $c;
+    }
 
-       function get_image() {
-               $user = $this->user;
-               $profile = $user->getProfile();
-               if (!$profile) {
-                       return NULL;
-               }
-               $avatar = $profile->getAvatar(AVATAR_PROFILE_SIZE);
-               return ($avatar) ? $avatar->url : NULL;
-       }
+    function get_image()
+    {
+        $user = $this->user;
+        $profile = $user->getProfile();
+        if (!$profile) {
+            return null;
+        }
+        $avatar = $profile->getAvatar(AVATAR_PROFILE_SIZE);
+        return ($avatar) ? $avatar->url : null;
+    }
 }
\ No newline at end of file
index 76019a92995126db827b7394ed55bf3588235166..a745487393c4fa7f707eb479e5a05b4aca303f45 100644 (file)
@@ -21,22 +21,25 @@ if (!defined('LACONICA')) { exit(1); }
 
 require_once(INSTALLDIR.'/lib/omb.php');
 
-class RequesttokenAction extends Action {
-       
-       function is_readonly() {
-               return false;
-       }
-       
-       function handle($args) {
-               parent::handle($args);
-               try {
-                       common_remove_magic_from_request();
-                       $req = OAuthRequest::from_request();
-                       $server = omb_oauth_server();
-                       $token = $server->fetch_request_token($req);
-                       print $token;
-               } catch (OAuthException $e) {
-                       common_server_error($e->getMessage());
-               }
-       }
+class RequesttokenAction extends Action
+{
+    
+    function is_readonly()
+    {
+        return false;
+    }
+    
+    function handle($args)
+    {
+        parent::handle($args);
+        try {
+            common_remove_magic_from_request();
+            $req = OAuthRequest::from_request();
+            $server = omb_oauth_server();
+            $token = $server->fetch_request_token($req);
+            print $token;
+        } catch (OAuthException $e) {
+            common_server_error($e->getMessage());
+        }
+    }
 }
index 4de4b12716be71327727deeefa893b49853af4de..f4344833d9ea572c6f5c08908a8c632ef631c31b 100644 (file)
@@ -21,77 +21,82 @@ if (!defined('LACONICA')) { exit(1); }
 
 require_once(INSTALLDIR.'/actions/showstream.php');
 
-class ShowfavoritesAction extends StreamAction {
+class ShowfavoritesAction extends StreamAction
+{
 
-       function handle($args) {
+    function handle($args)
+    {
 
-               parent::handle($args);
+        parent::handle($args);
 
-               $nickname = common_canonical_nickname($this->arg('nickname'));
-               $user = User::staticGet('nickname', $nickname);
+        $nickname = common_canonical_nickname($this->arg('nickname'));
+        $user = User::staticGet('nickname', $nickname);
 
-               if (!$user) {
-                       $this->client_error(_('No such user.'));
-                       return;
-               }
+        if (!$user) {
+            $this->client_error(_('No such user.'));
+            return;
+        }
 
-               $profile = $user->getProfile();
+        $profile = $user->getProfile();
 
-               if (!$profile) {
-                       common_server_error(_('User has no profile.'));
-                       return;
-               }
+        if (!$profile) {
+            common_server_error(_('User has no profile.'));
+            return;
+        }
 
-               # Looks like we're good; show the header
+        # Looks like we're good; show the header
 
-               common_show_header(sprintf(_("%s favorite notices"), $profile->nickname),
-                                                  array($this, 'show_header'), $user,
-                                                  array($this, 'show_top'));
+        common_show_header(sprintf(_("%s favorite notices"), $profile->nickname),
+                           array($this, 'show_header'), $user,
+                           array($this, 'show_top'));
 
-               $this->show_notices($user);
+        $this->show_notices($user);
 
-               common_show_footer();
-       }
+        common_show_footer();
+    }
 
-       function show_header($user) {
-               common_element('link', array('rel' => 'alternate',
-                                                                        'href' => common_local_url('favoritesrss', array('nickname' =>
-                                                                                                                                                                         $user->nickname)),
-                                                                        'type' => 'application/rss+xml',
-                                                                        'title' => sprintf(_('Feed for favorites of %s'), $user->nickname)));
-       }
+    function show_header($user)
+    {
+        common_element('link', array('rel' => 'alternate',
+                                     'href' => common_local_url('favoritesrss', array('nickname' =>
+                                                                                      $user->nickname)),
+                                     'type' => 'application/rss+xml',
+                                     'title' => sprintf(_('Feed for favorites of %s'), $user->nickname)));
+    }
 
-       function show_top($user) {
-               $cur = common_current_user();
+    function show_top($user)
+    {
+        $cur = common_current_user();
 
-               if ($cur && $cur->id == $user->id) {
-                       common_notice_form('all');
-               }
+        if ($cur && $cur->id == $user->id) {
+            common_notice_form('all');
+        }
 
-               $this->show_feeds_list(array(0=>array('href'=>common_local_url('favoritesrss', array('nickname' => $user->nickname)),
-                                                                                         'type' => 'rss',
-                                                                                         'version' => 'RSS 1.0',
-                                                                                         'item' => 'Favorites')));
-               $this->views_menu();
-       }
+        $this->show_feeds_list(array(0=>array('href'=>common_local_url('favoritesrss', array('nickname' => $user->nickname)),
+                                              'type' => 'rss',
+                                              'version' => 'RSS 1.0',
+                                              'item' => 'Favorites')));
+        $this->views_menu();
+    }
 
-       function show_notices($user) {
+    function show_notices($user)
+    {
 
-               $page = $this->trimmed('page');
-               if (!$page) {
-                       $page = 1;
-               }
+        $page = $this->trimmed('page');
+        if (!$page) {
+            $page = 1;
+        }
 
-               $notice = $user->favoriteNotices(($page-1)*NOTICES_PER_PAGE, NOTICES_PER_PAGE + 1);
+        $notice = $user->favoriteNotices(($page-1)*NOTICES_PER_PAGE, NOTICES_PER_PAGE + 1);
 
-               if (!$notice) {
-                       $this->server_error(_('Could not retrieve favorite notices.'));
-                       return;
-               }
+        if (!$notice) {
+            $this->server_error(_('Could not retrieve favorite notices.'));
+            return;
+        }
 
         $cnt = $this->show_notice_list($notice);
 
-               common_pagination($page > 1, $cnt > NOTICES_PER_PAGE,
-                                                 $page, 'showfavorites', array('nickname' => $user->nickname));
-       }
+        common_pagination($page > 1, $cnt > NOTICES_PER_PAGE,
+                          $page, 'showfavorites', array('nickname' => $user->nickname));
+    }
 }
index c171ffe0b596b790bd5b458dbcae1a0393ed9026..25330a568f6d23ea8e56944af1ee7e69cb3c7c65 100644 (file)
@@ -21,80 +21,88 @@ if (!defined('LACONICA')) { exit(1); }
 
 require_once(INSTALLDIR.'/lib/mailbox.php');
 
-class ShowmessageAction extends MailboxAction {
+class ShowmessageAction extends MailboxAction
+{
 
-       function handle($args) {
+    function handle($args)
+    {
 
-               Action::handle($args);
+        Action::handle($args);
 
-               $message = $this->get_message();
+        $message = $this->get_message();
 
-               if (!$message) {
-                       $this->client_error(_('No such message.'), 404);
-                       return;
-               }
-               
-               $cur = common_current_user();
-               
-               if ($cur && ($cur->id == $message->from_profile || $cur->id == $message->to_profile)) {
-                       $this->show_page($cur, 1);
-               } else {
-                       $this->client_error(_('Only the sender and recipient may read this message.'), 403);
-                       return;
-               }
-       }
-       
-       function get_message() {
-               $id = $this->trimmed('message');
-               $message = Message::staticGet('id', $id);
-               return $message;
-       }
-       
-       function get_title($user, $page) {
-               $message = $this->get_message();
-               if (!$message) {
-                       return NULL;
-               }
-               
-               if ($user->id == $message->from_profile) {
-                       $to = $message->getTo();
-                       $title = sprintf(_("Message to %1\$s on %2\$s"),
-                                                        $to->nickname,
-                                                        common_exact_date($message->created));
-               } else if ($user->id == $message->to_profile) {
-                       $from = $message->getFrom();
-                       $title = sprintf(_("Message from %1\$s on %2\$s"),
-                                                        $from->nickname,
-                                                        common_exact_date($message->created));
-               }
-               return $title;
-       }
+        if (!$message) {
+            $this->client_error(_('No such message.'), 404);
+            return;
+        }
+        
+        $cur = common_current_user();
+        
+        if ($cur && ($cur->id == $message->from_profile || $cur->id == $message->to_profile)) {
+            $this->show_page($cur, 1);
+        } else {
+            $this->client_error(_('Only the sender and recipient may read this message.'), 403);
+            return;
+        }
+    }
+    
+    function get_message()
+    {
+        $id = $this->trimmed('message');
+        $message = Message::staticGet('id', $id);
+        return $message;
+    }
+    
+    function get_title($user, $page)
+    {
+        $message = $this->get_message();
+        if (!$message) {
+            return null;
+        }
+        
+        if ($user->id == $message->from_profile) {
+            $to = $message->getTo();
+            $title = sprintf(_("Message to %1\$s on %2\$s"),
+                             $to->nickname,
+                             common_exact_date($message->created));
+        } else if ($user->id == $message->to_profile) {
+            $from = $message->getFrom();
+            $title = sprintf(_("Message from %1\$s on %2\$s"),
+                             $from->nickname,
+                             common_exact_date($message->created));
+        }
+        return $title;
+    }
 
-       function get_messages($user, $page) {
-               $message = new Message();
-               $message->id = $this->trimmed('message');
-               $message->find();
-               return $message;
-       }
-       
-       function get_message_profile($message) {
-               $user = common_current_user();
-               if ($user->id == $message->from_profile) {
-                       return $message->getTo();
-               } else if ($user->id == $message->to_profile) {
-                       return $message->getFrom();
-               } else {
-                       # This shouldn't happen
-                       return NULL;
-               }
-       }
-       
-       function get_instructions() {
-               return '';
-       }
-       
-       function views_menu() {
-               return;
-       }
+    function get_messages($user, $page)
+    {
+        $message = new Message();
+        $message->id = $this->trimmed('message');
+        $message->find();
+        return $message;
+    }
+    
+    function get_message_profile($message)
+    {
+        $user = common_current_user();
+        if ($user->id == $message->from_profile) {
+            return $message->getTo();
+        } else if ($user->id == $message->to_profile) {
+            return $message->getFrom();
+        } else {
+            # This shouldn't happen
+            return null;
+        }
+    }
+    
+    function get_instructions()
+    {
+        return '';
+    }
+    
+    function views_menu()
+    {
+        return;
+    }
 }
-       
\ No newline at end of file
+    
\ No newline at end of file
index 6dea6d7bba69fbe9405c92c6f4744d7ee86a11b3..2df09cb3fcdad121a9536a57de81799fc90dbc5b 100644 (file)
@@ -21,96 +21,104 @@ if (!defined('LACONICA')) { exit(1); }
 
 require_once(INSTALLDIR.'/lib/stream.php');
 
-class ShownoticeAction extends StreamAction {
+class ShownoticeAction extends StreamAction
+{
 
-       var $notice = NULL;
-       var $profile = NULL;
-       var $avatar = NULL;
+    var $notice = null;
+    var $profile = null;
+    var $avatar = null;
 
-       function prepare($args) {
+    function prepare($args)
+    {
 
-               parent::prepare($args);
+        parent::prepare($args);
 
-               $id = $this->arg('notice');
-               $this->notice = Notice::staticGet($id);
+        $id = $this->arg('notice');
+        $this->notice = Notice::staticGet($id);
 
-               if (!$this->notice) {
-                       $this->client_error(_('No such notice.'), 404);
-                       return false;
-               }
+        if (!$this->notice) {
+            $this->client_error(_('No such notice.'), 404);
+            return false;
+        }
 
-               $this->profile = $this->notice->getProfile();
+        $this->profile = $this->notice->getProfile();
 
-               if (!$this->profile) {
-                       $this->server_error(_('Notice has no profile'), 500);
-                       return false;
-               }
+        if (!$this->profile) {
+            $this->server_error(_('Notice has no profile'), 500);
+            return false;
+        }
 
-               $this->avatar = $this->profile->getAvatar(AVATAR_STREAM_SIZE);
+        $this->avatar = $this->profile->getAvatar(AVATAR_STREAM_SIZE);
 
-               return true;
-       }
+        return true;
+    }
 
-       function last_modified() {
-               return max(strtotime($this->notice->created),
-                                  strtotime($this->profile->modified),
-                                  ($this->avatar) ? strtotime($this->avatar->modified) : 0);
-       }
+    function last_modified()
+    {
+        return max(strtotime($this->notice->created),
+                   strtotime($this->profile->modified),
+                   ($this->avatar) ? strtotime($this->avatar->modified) : 0);
+    }
 
-       function etag() {
-               return 'W/"' . implode(':', array($this->arg('action'),
-                                                                                 common_language(),
-                                                                                 $this->notice->id,
-                                                                                 strtotime($this->notice->created),
-                                                                                 strtotime($this->profile->modified),
-                                                                                 ($this->avatar) ? strtotime($this->avatar->modified) : 0)) . '"';
-       }
+    function etag()
+    {
+        return 'W/"' . implode(':', array($this->arg('action'),
+                                          common_language(),
+                                          $this->notice->id,
+                                          strtotime($this->notice->created),
+                                          strtotime($this->profile->modified),
+                                          ($this->avatar) ? strtotime($this->avatar->modified) : 0)) . '"';
+    }
 
-       function handle($args) {
+    function handle($args)
+    {
 
-               parent::handle($args);
+        parent::handle($args);
 
-               common_show_header(sprintf(_('%1$s\'s status on %2$s'),
-                                                                  $this->profile->nickname,
-                                                                  common_exact_date($this->notice->created)),
-                                                  array($this, 'show_header'), NULL,
-                                                  array($this, 'show_top'));
+        common_show_header(sprintf(_('%1$s\'s status on %2$s'),
+                                   $this->profile->nickname,
+                                   common_exact_date($this->notice->created)),
+                           array($this, 'show_header'), null,
+                           array($this, 'show_top'));
 
-               common_element_start('ul', array('id' => 'notices'));
+        common_element_start('ul', array('id' => 'notices'));
         $nli = new NoticeListItem($this->notice);
         $nli->show();
-               common_element_end('ul');
-
-               common_show_footer();
-       }
-
-       function show_header() {
-
-               $user = User::staticGet($this->profile->id);
-
-               if (!$user) {
-                       return;
-               }
-
-               if ($user->emailmicroid && $user->email && $this->notice->uri) {
-                       common_element('meta', array('name' => 'microid',
-                                                                                'content' => "mailto+http:sha1:" . sha1(sha1('mailto:' . $user->email) . sha1($this->notice->uri))));
-               }
-
-               if ($user->jabbermicroid && $user->jabber && $this->notice->uri) {
-                       common_element('meta', array('name' => 'microid',
-                                                                                'content' => "xmpp+http:sha1:" . sha1(sha1('xmpp:' . $user->jabber) . sha1($this->notice->uri))));
-               }
-       }
-
-       function show_top() {
-               $cur = common_current_user();
-               if ($cur && $cur->id == $this->profile->id) {
-                       common_notice_form();
-               }
-       }
-
-       function no_such_notice() {
-               common_user_error(_('No such notice.'));
-       }
+        common_element_end('ul');
+
+        common_show_footer();
+    }
+
+    function show_header()
+    {
+
+        $user = User::staticGet($this->profile->id);
+
+        if (!$user) {
+            return;
+        }
+
+        if ($user->emailmicroid && $user->email && $this->notice->uri) {
+            common_element('meta', array('name' => 'microid',
+                                         'content' => "mailto+http:sha1:" . sha1(sha1('mailto:' . $user->email) . sha1($this->notice->uri))));
+        }
+
+        if ($user->jabbermicroid && $user->jabber && $this->notice->uri) {
+            common_element('meta', array('name' => 'microid',
+                                         'content' => "xmpp+http:sha1:" . sha1(sha1('xmpp:' . $user->jabber) . sha1($this->notice->uri))));
+        }
+    }
+
+    function show_top()
+    {
+        $cur = common_current_user();
+        if ($cur && $cur->id == $this->profile->id) {
+            common_notice_form();
+        }
+    }
+
+    function no_such_notice()
+    {
+        common_user_error(_('No such notice.'));
+    }
 }
index 6d6225661cf13f8eb276b86298069abaf10a72da..e4e5d96d15d1c3e296ebd4fbe5b2c511f8bbe0fa 100644 (file)
@@ -24,14 +24,16 @@ require_once(INSTALLDIR.'/lib/stream.php');
 define('SUBSCRIPTIONS_PER_ROW', 4);
 define('SUBSCRIPTIONS', 80);
 
-class ShowstreamAction extends StreamAction {
+class ShowstreamAction extends StreamAction
+{
 
-       function handle($args) {
+    function handle($args)
+    {
 
-               parent::handle($args);
+        parent::handle($args);
 
         $nickname_arg = $this->arg('nickname');
-               $nickname = common_canonical_nickname($nickname_arg);
+        $nickname = common_canonical_nickname($nickname_arg);
 
         # Permanent redirect on non-canonical nickname
 
@@ -44,163 +46,168 @@ class ShowstreamAction extends StreamAction {
             return;
         }
 
-               $user = User::staticGet('nickname', $nickname);
-
-               if (!$user) {
-                       $this->no_such_user();
-                       return;
-               }
-
-               $profile = $user->getProfile();
-
-               if (!$profile) {
-                       common_server_error(_('User has no profile.'));
-                       return;
-               }
-
-               # Looks like we're good; start output
-
-               # For YADIS discovery, we also have a <meta> tag
-
-               header('X-XRDS-Location: '. common_local_url('xrds', array('nickname' =>
-                                                                                                                                  $user->nickname)));
-
-               common_show_header($profile->nickname,
-                                                  array($this, 'show_header'), $user,
-                                                  array($this, 'show_top'));
-
-               $this->show_profile($profile);
-
-               $this->show_notices($user);
-
-               common_show_footer();
-       }
-
-       function show_top($user) {
-               $cur = common_current_user();
-
-               if ($cur && $cur->id == $user->id) {
-                       common_notice_form('showstream');
-               }
-
-               $this->views_menu();
-
-               $this->show_feeds_list(array(0=>array('href'=>common_local_url('userrss', array('nickname' => $user->nickname)),
-                                                                                         'type' => 'rss',
-                                                                                         'version' => 'RSS 1.0',
-                                                                                         'item' => 'notices'),
-                                                                        1=>array('href'=>common_local_url('usertimeline', array('nickname' => $user->nickname)),
-                                                                                         'type' => 'atom',
-                                                                                         'version' => 'Atom 1.0',
-                                                                                         'item' => 'usertimeline'),
-
-                                                                        2=>array('href'=>common_local_url('foaf',array('nickname' => $user->nickname)),
-                                                                                         'type' => 'rdf',
-                                                                                         'version' => 'FOAF',
-                                                                                         'item' => 'foaf')));
-       }
-
-       function show_header($user) {
-               # Feeds
-               common_element('link', array('rel' => 'alternate',
-                                                                        'href' => common_local_url('api',
-                                                                                                                               array('apiaction' => 'statuses',
-                                                                                                                                         'method' => 'user_timeline.rss',
-                                                                                                                                         'argument' => $user->nickname)),
-                                                                        'type' => 'application/rss+xml',
-                                                                        'title' => sprintf(_('Notice feed for %s'), $user->nickname)));
-               common_element('link', array('rel' => 'alternate feed',
-                                                                        'href' => common_local_url('api',
-                                                                                                                               array('apiaction' => 'statuses',
-                                                                                                                                         'method' => 'user_timeline.atom',
-                                                                                                                                         'argument' => $user->nickname)),
-                                                                        'type' => 'application/atom+xml',
-                                                                        'title' => sprintf(_('Notice feed for %s'), $user->nickname)));
-               common_element('link', array('rel' => 'alternate',
-                                                                        'href' => common_local_url('userrss', array('nickname' =>
-                                                                                                                                                          $user->nickname)),
-                                                                        'type' => 'application/rdf+xml',
-                                                                        'title' => sprintf(_('Notice feed for %s'), $user->nickname)));
-               # FOAF
-               common_element('link', array('rel' => 'meta',
-                                                                        'href' => common_local_url('foaf', array('nickname' =>
-                                                                                                                                                         $user->nickname)),
-                                                                        'type' => 'application/rdf+xml',
-                                                                        'title' => 'FOAF'));
-               # for remote subscriptions etc.
-               common_element('meta', array('http-equiv' => 'X-XRDS-Location',
-                                                                        'content' => common_local_url('xrds', array('nickname' =>
-                                                                                                                                                          $user->nickname))));
-               $profile = $user->getProfile();
-               if ($profile->bio) {
-                       common_element('meta', array('name' => 'description',
-                                                                                'content' => $profile->bio));
-               }
-
-               if ($user->emailmicroid && $user->email && $profile->profileurl) {
-                       common_element('meta', array('name' => 'microid',
-                                                                                'content' => "mailto+http:sha1:" . sha1(sha1('mailto:' . $user->email) . sha1($profile->profileurl))));
-               }
-               if ($user->jabbermicroid && $user->jabber && $profile->profileurl) {
-                       common_element('meta', array('name' => 'microid',
-                                                                                'content' => "xmpp+http:sha1:" . sha1(sha1('xmpp:' . $user->jabber) . sha1($profile->profileurl))));
-               }
-
-               # See https://wiki.mozilla.org/Microsummaries
-
-               common_element('link', array('rel' => 'microsummary',
-                                                                        'href' => common_local_url('microsummary',
-                                                                                                                               array('nickname' => $profile->nickname))));
-       }
-
-       function no_such_user() {
-               $this->client_error(_('No such user.'), 404);
-       }
-
-       function show_profile($profile) {
-
-               common_element_start('div', array('id' => 'profile', 'class' => 'vcard'));
-
-               $this->show_personal($profile);
-
-               $this->show_last_notice($profile);
-
-               $cur = common_current_user();
-
-               $this->show_subscriptions($profile);
-
-               common_element_end('div');
-       }
-
-       function show_personal($profile) {
-
-               $avatar = $profile->getAvatar(AVATAR_PROFILE_SIZE);
-               common_element_start('div', array('id' => 'profile_avatar'));
-               common_element('img', array('src' => ($avatar) ? common_avatar_display_url($avatar) : common_default_avatar(AVATAR_PROFILE_SIZE),
-                                                                       'class' => 'avatar profile photo',
-                                                                       'width' => AVATAR_PROFILE_SIZE,
-                                                                       'height' => AVATAR_PROFILE_SIZE,
-                                                                       'alt' => $profile->nickname));
+        $user = User::staticGet('nickname', $nickname);
+
+        if (!$user) {
+            $this->no_such_user();
+            return;
+        }
+
+        $profile = $user->getProfile();
+
+        if (!$profile) {
+            common_server_error(_('User has no profile.'));
+            return;
+        }
+
+        # Looks like we're good; start output
+
+        # For YADIS discovery, we also have a <meta> tag
+
+        header('X-XRDS-Location: '. common_local_url('xrds', array('nickname' =>
+                                                                   $user->nickname)));
+
+        common_show_header($profile->nickname,
+                           array($this, 'show_header'), $user,
+                           array($this, 'show_top'));
+
+        $this->show_profile($profile);
+
+        $this->show_notices($user);
+
+        common_show_footer();
+    }
+
+    function show_top($user)
+    {
+        $cur = common_current_user();
+
+        if ($cur && $cur->id == $user->id) {
+            common_notice_form('showstream');
+        }
+
+        $this->views_menu();
+
+        $this->show_feeds_list(array(0=>array('href'=>common_local_url('userrss', array('nickname' => $user->nickname)),
+                                              'type' => 'rss',
+                                              'version' => 'RSS 1.0',
+                                              'item' => 'notices'),
+                                     1=>array('href'=>common_local_url('usertimeline', array('nickname' => $user->nickname)),
+                                              'type' => 'atom',
+                                              'version' => 'Atom 1.0',
+                                              'item' => 'usertimeline'),
+
+                                     2=>array('href'=>common_local_url('foaf',array('nickname' => $user->nickname)),
+                                              'type' => 'rdf',
+                                              'version' => 'FOAF',
+                                              'item' => 'foaf')));
+    }
+
+    function show_header($user)
+    {
+        # Feeds
+        common_element('link', array('rel' => 'alternate',
+                                     'href' => common_local_url('api',
+                                                                array('apiaction' => 'statuses',
+                                                                      'method' => 'user_timeline.rss',
+                                                                      'argument' => $user->nickname)),
+                                     'type' => 'application/rss+xml',
+                                     'title' => sprintf(_('Notice feed for %s'), $user->nickname)));
+        common_element('link', array('rel' => 'alternate feed',
+                                     'href' => common_local_url('api',
+                                                                array('apiaction' => 'statuses',
+                                                                      'method' => 'user_timeline.atom',
+                                                                      'argument' => $user->nickname)),
+                                     'type' => 'application/atom+xml',
+                                     'title' => sprintf(_('Notice feed for %s'), $user->nickname)));
+        common_element('link', array('rel' => 'alternate',
+                                     'href' => common_local_url('userrss', array('nickname' =>
+                                                                               $user->nickname)),
+                                     'type' => 'application/rdf+xml',
+                                     'title' => sprintf(_('Notice feed for %s'), $user->nickname)));
+        # FOAF
+        common_element('link', array('rel' => 'meta',
+                                     'href' => common_local_url('foaf', array('nickname' =>
+                                                                              $user->nickname)),
+                                     'type' => 'application/rdf+xml',
+                                     'title' => 'FOAF'));
+        # for remote subscriptions etc.
+        common_element('meta', array('http-equiv' => 'X-XRDS-Location',
+                                     'content' => common_local_url('xrds', array('nickname' =>
+                                                                               $user->nickname))));
+        $profile = $user->getProfile();
+        if ($profile->bio) {
+            common_element('meta', array('name' => 'description',
+                                         'content' => $profile->bio));
+        }
+
+        if ($user->emailmicroid && $user->email && $profile->profileurl) {
+            common_element('meta', array('name' => 'microid',
+                                         'content' => "mailto+http:sha1:" . sha1(sha1('mailto:' . $user->email) . sha1($profile->profileurl))));
+        }
+        if ($user->jabbermicroid && $user->jabber && $profile->profileurl) {
+            common_element('meta', array('name' => 'microid',
+                                         'content' => "xmpp+http:sha1:" . sha1(sha1('xmpp:' . $user->jabber) . sha1($profile->profileurl))));
+        }
+
+        # See https://wiki.mozilla.org/Microsummaries
+
+        common_element('link', array('rel' => 'microsummary',
+                                     'href' => common_local_url('microsummary',
+                                                                array('nickname' => $profile->nickname))));
+    }
+
+    function no_such_user()
+    {
+        $this->client_error(_('No such user.'), 404);
+    }
+
+    function show_profile($profile)
+    {
+
+        common_element_start('div', array('id' => 'profile', 'class' => 'vcard'));
+
+        $this->show_personal($profile);
+
+        $this->show_last_notice($profile);
+
+        $cur = common_current_user();
+
+        $this->show_subscriptions($profile);
+
+        common_element_end('div');
+    }
+
+    function show_personal($profile)
+    {
+
+        $avatar = $profile->getAvatar(AVATAR_PROFILE_SIZE);
+        common_element_start('div', array('id' => 'profile_avatar'));
+        common_element('img', array('src' => ($avatar) ? common_avatar_display_url($avatar) : common_default_avatar(AVATAR_PROFILE_SIZE),
+                                    'class' => 'avatar profile photo',
+                                    'width' => AVATAR_PROFILE_SIZE,
+                                    'height' => AVATAR_PROFILE_SIZE,
+                                    'alt' => $profile->nickname));
 
         common_element_start('ul', array('id' => 'profile_actions'));
 
         common_element_start('li', array('id' => 'profile_subscribe'));
-               $cur = common_current_user();
-               if ($cur) {
-                       if ($cur->id != $profile->id) {
-                               if ($cur->isSubscribed($profile)) {
-                                       common_unsubscribe_form($profile);
-                               } else {
-                                       common_subscribe_form($profile);
-                               }
-                       }
-               } else {
-                       $this->show_remote_subscribe_link($profile);
-               }
+        $cur = common_current_user();
+        if ($cur) {
+            if ($cur->id != $profile->id) {
+                if ($cur->isSubscribed($profile)) {
+                    common_unsubscribe_form($profile);
+                } else {
+                    common_subscribe_form($profile);
+                }
+            }
+        } else {
+            $this->show_remote_subscribe_link($profile);
+        }
         common_element_end('li');
 
-               $user = User::staticGet('id', $profile->id);
-               common_profile_new_message_nudge($cur, $user, $profile);
+        $user = User::staticGet('id', $profile->id);
+        common_profile_new_message_nudge($cur, $user, $profile);
 
         if ($cur && $cur->id != $profile->id) {
             $blocked = $cur->hasBlocked($profile);
@@ -215,236 +222,246 @@ class ShowstreamAction extends StreamAction {
             common_element_end('li');
         }
 
-               common_element_end('ul');
-
-               common_element_end('div');
-
-               common_element_start('div', array('id' => 'profile_information'));
-
-               if ($profile->fullname) {
-                       common_element('h1', array('class' => 'fn'), $profile->fullname . ' (' . $profile->nickname . ')');
-               } else {
-                       common_element('h1', array('class' => 'fn nickname'), $profile->nickname);
-               }
-
-               if ($profile->location) {
-                       common_element('p', 'location', $profile->location);
-               }
-               if ($profile->bio) {
-                       common_element('p', 'description note', $profile->bio);
-               }
-               if ($profile->homepage) {
-                       common_element_start('p', 'website');
-                       common_element('a', array('href' => $profile->homepage,
-                                                                         'rel' => 'me', 'class' => 'url'),
-                                                  $profile->homepage);
-                       common_element_end('p');
-               }
-
-               $this->show_statistics($profile);
-
-               common_element_end('div');
-       }
-
-       function show_remote_subscribe_link($profile) {
-               $url = common_local_url('remotesubscribe',
-                                       array('nickname' => $profile->nickname));
-               common_element('a', array('href' => $url,
-                                                                 'id' => 'remotesubscribe'),
-                                          _('Subscribe'));
-       }
-
-       function show_unsubscribe_form($profile) {
-               common_element_start('form', array('id' => 'unsubscribe', 'method' => 'post',
-                                                                                  'action' => common_local_url('unsubscribe')));
-               common_hidden('token', common_session_token());
-               common_element('input', array('id' => 'unsubscribeto',
-                                                                         'name' => 'unsubscribeto',
-                                                                         'type' => 'hidden',
-                                                                         'value' => $profile->nickname));
-               common_element('input', array('type' => 'submit',
-                                                                         'class' => 'submit',
-                                                                         'value' => _('Unsubscribe')));
-               common_element_end('form');
-       }
-
-       function show_subscriptions($profile) {
-               global $config;
-
-               $subs = DB_DataObject::factory('subscription');
-               $subs->subscriber = $profile->id;
-               $subs->whereAdd('subscribed != ' . $profile->id);
-
-               $subs->orderBy('created DESC');
-
-               # We ask for an extra one to know if we need to do another page
-
-               $subs->limit(0, SUBSCRIPTIONS + 1);
-
-               $subs_count = $subs->find();
-
-               common_element_start('div', array('id' => 'subscriptions'));
-
-               common_element('h2', NULL, _('Subscriptions'));
-
-               if ($subs_count > 0) {
-
-                       common_element_start('ul', array('id' => 'subscriptions_avatars'));
-
-                       for ($i = 0; $i < min($subs_count, SUBSCRIPTIONS); $i++) {
-
-                               if (!$subs->fetch()) {
-                                       common_debug('Weirdly, broke out of subscriptions loop early', __FILE__);
-                                       break;
-                               }
-
-                               $other = Profile::staticGet($subs->subscribed);
-
-                               if (!$other) {
-                                       common_log_db_error($subs, 'SELECT', __FILE__);
-                                       continue;
-                               }
-
-                               common_element_start('li', 'vcard');
-                               common_element_start('a', array('title' => ($other->fullname) ?
-                                                                                               $other->fullname :
-                                                                                               $other->nickname,
-                                                                                               'href' => $other->profileurl,
-                                                                                               'rel' => 'contact',
-                                                                                               'class' => 'subscription fn url'));
-                               $avatar = $other->getAvatar(AVATAR_MINI_SIZE);
-                               common_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 mini photo',
-                                                                                       'alt' =>  ($other->fullname) ?
-                                                                                       $other->fullname :
-                                                                                       $other->nickname));
-                               common_element_end('a');
-                               common_element_end('li');
-                       }
-
-                       common_element_end('ul');
-               }
-
-               if ($subs_count > SUBSCRIPTIONS) {
-                       common_element_start('p', array('id' => 'subscriptions_viewall'));
-
-                       common_element('a', array('href' => common_local_url('subscriptions',
-                                                                                                                                array('nickname' => $profile->nickname)),
-                                                                         'class' => 'moresubscriptions'),
-                                                  _('All subscriptions'));
-                       common_element_end('p');
-               }
-
-               common_element_end('div');
-       }
-
-       function show_statistics($profile) {
-
-               // XXX: WORM cache this
-               $subs = DB_DataObject::factory('subscription');
-               $subs->subscriber = $profile->id;
-               $subs_count = (int) $subs->count() - 1;
-
-               $subbed = DB_DataObject::factory('subscription');
-               $subbed->subscribed = $profile->id;
-               $subbed_count = (int) $subbed->count() - 1;
-
-               $notices = DB_DataObject::factory('notice');
-               $notices->profile_id = $profile->id;
-               $notice_count = (int) $notices->count();
-
-               common_element_start('div', 'statistics');
-               common_element('h2', 'statistics', _('Statistics'));
-
-               # Other stats...?
-               common_element_start('dl', 'statistics');
-               common_element('dt', 'membersince', _('Member since'));
-               common_element('dd', 'membersince', date('j M Y',
-                                                                                                strtotime($profile->created)));
-
-               common_element_start('dt', 'subscriptions');
-               common_element('a', array('href' => common_local_url('subscriptions',
-                                                                                                                        array('nickname' => $profile->nickname))),
-                                          _('Subscriptions'));
-               common_element_end('dt');
-               common_element('dd', 'subscriptions', (is_int($subs_count)) ? $subs_count : '0');
-               common_element_start('dt', 'subscribers');
-               common_element('a', array('href' => common_local_url('subscribers',
-                                                                                                                        array('nickname' => $profile->nickname))),
-                                          _('Subscribers'));
-               common_element_end('dt');
-               common_element('dd', 'subscribers', (is_int($subbed_count)) ? $subbed_count : '0');
-               common_element('dt', 'notices', _('Notices'));
-               common_element('dd', 'notices', (is_int($notice_count)) ? $notice_count : '0');
-               # XXX: link these to something
-               common_element('dt', 'tags', _('Tags'));
-               common_element_start('dd', 'tags');
-               $tags = Profile_tag::getTags($profile->id, $profile->id);
-
-               common_element_start('ul', 'tags xoxo');
-               foreach ($tags as $tag) {
-                       common_element_start('li');
-                       common_element('a', array('rel' => 'bookmark tag',
-                                                                         'href' => common_local_url('peopletag',
-                                                                                                                                array('tag' => $tag))),
-                                                  $tag);
-                       common_element_end('li');
-               }
-               common_element_end('ul');
-           common_element_end('dd');
-
-               common_element_end('dl');
-
-               common_element_end('div');
-       }
-
-       function show_notices($user) {
-
-               $page = ($this->arg('page')) ? ($this->arg('page')+0) : 1;
-
-               $notice = $user->getNotices(($page-1)*NOTICES_PER_PAGE, NOTICES_PER_PAGE + 1);
+        common_element_end('ul');
+
+        common_element_end('div');
+
+        common_element_start('div', array('id' => 'profile_information'));
+
+        if ($profile->fullname) {
+            common_element('h1', array('class' => 'fn'), $profile->fullname . ' (' . $profile->nickname . ')');
+        } else {
+            common_element('h1', array('class' => 'fn nickname'), $profile->nickname);
+        }
+
+        if ($profile->location) {
+            common_element('p', 'location', $profile->location);
+        }
+        if ($profile->bio) {
+            common_element('p', 'description note', $profile->bio);
+        }
+        if ($profile->homepage) {
+            common_element_start('p', 'website');
+            common_element('a', array('href' => $profile->homepage,
+                                      'rel' => 'me', 'class' => 'url'),
+                           $profile->homepage);
+            common_element_end('p');
+        }
+
+        $this->show_statistics($profile);
+
+        common_element_end('div');
+    }
+
+    function show_remote_subscribe_link($profile)
+    {
+        $url = common_local_url('remotesubscribe',
+                                array('nickname' => $profile->nickname));
+        common_element('a', array('href' => $url,
+                                  'id' => 'remotesubscribe'),
+                       _('Subscribe'));
+    }
+
+    function show_unsubscribe_form($profile)
+    {
+        common_element_start('form', array('id' => 'unsubscribe', 'method' => 'post',
+                                           'action' => common_local_url('unsubscribe')));
+        common_hidden('token', common_session_token());
+        common_element('input', array('id' => 'unsubscribeto',
+                                      'name' => 'unsubscribeto',
+                                      'type' => 'hidden',
+                                      'value' => $profile->nickname));
+        common_element('input', array('type' => 'submit',
+                                      'class' => 'submit',
+                                      'value' => _('Unsubscribe')));
+        common_element_end('form');
+    }
+
+    function show_subscriptions($profile)
+    {
+        global $config;
+
+        $subs = DB_DataObject::factory('subscription');
+        $subs->subscriber = $profile->id;
+        $subs->whereAdd('subscribed != ' . $profile->id);
+
+        $subs->orderBy('created DESC');
+
+        # We ask for an extra one to know if we need to do another page
+
+        $subs->limit(0, SUBSCRIPTIONS + 1);
+
+        $subs_count = $subs->find();
+
+        common_element_start('div', array('id' => 'subscriptions'));
+
+        common_element('h2', null, _('Subscriptions'));
+
+        if ($subs_count > 0) {
+
+            common_element_start('ul', array('id' => 'subscriptions_avatars'));
+
+            for ($i = 0; $i < min($subs_count, SUBSCRIPTIONS); $i++) {
+
+                if (!$subs->fetch()) {
+                    common_debug('Weirdly, broke out of subscriptions loop early', __FILE__);
+                    break;
+                }
+
+                $other = Profile::staticGet($subs->subscribed);
+
+                if (!$other) {
+                    common_log_db_error($subs, 'SELECT', __FILE__);
+                    continue;
+                }
+
+                common_element_start('li', 'vcard');
+                common_element_start('a', array('title' => ($other->fullname) ?
+                                                $other->fullname :
+                                                $other->nickname,
+                                                'href' => $other->profileurl,
+                                                'rel' => 'contact',
+                                                 'class' => 'subscription fn url'));
+                $avatar = $other->getAvatar(AVATAR_MINI_SIZE);
+                common_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 mini photo',
+                                            'alt' =>  ($other->fullname) ?
+                                            $other->fullname :
+                                            $other->nickname));
+                common_element_end('a');
+                common_element_end('li');
+            }
+
+            common_element_end('ul');
+        }
+
+        if ($subs_count > SUBSCRIPTIONS) {
+            common_element_start('p', array('id' => 'subscriptions_viewall'));
+
+            common_element('a', array('href' => common_local_url('subscriptions',
+                                                                 array('nickname' => $profile->nickname)),
+                                      'class' => 'moresubscriptions'),
+                           _('All subscriptions'));
+            common_element_end('p');
+        }
+
+        common_element_end('div');
+    }
+
+    function show_statistics($profile)
+    {
+
+        // XXX: WORM cache this
+        $subs = DB_DataObject::factory('subscription');
+        $subs->subscriber = $profile->id;
+        $subs_count = (int) $subs->count() - 1;
+
+        $subbed = DB_DataObject::factory('subscription');
+        $subbed->subscribed = $profile->id;
+        $subbed_count = (int) $subbed->count() - 1;
+
+        $notices = DB_DataObject::factory('notice');
+        $notices->profile_id = $profile->id;
+        $notice_count = (int) $notices->count();
+
+        common_element_start('div', 'statistics');
+        common_element('h2', 'statistics', _('Statistics'));
+
+        # Other stats...?
+        common_element_start('dl', 'statistics');
+        common_element('dt', 'membersince', _('Member since'));
+        common_element('dd', 'membersince', date('j M Y',
+                                                 strtotime($profile->created)));
+
+        common_element_start('dt', 'subscriptions');
+        common_element('a', array('href' => common_local_url('subscriptions',
+                                                             array('nickname' => $profile->nickname))),
+                       _('Subscriptions'));
+        common_element_end('dt');
+        common_element('dd', 'subscriptions', (is_int($subs_count)) ? $subs_count : '0');
+        common_element_start('dt', 'subscribers');
+        common_element('a', array('href' => common_local_url('subscribers',
+                                                             array('nickname' => $profile->nickname))),
+                       _('Subscribers'));
+        common_element_end('dt');
+        common_element('dd', 'subscribers', (is_int($subbed_count)) ? $subbed_count : '0');
+        common_element('dt', 'notices', _('Notices'));
+        common_element('dd', 'notices', (is_int($notice_count)) ? $notice_count : '0');
+        # XXX: link these to something
+        common_element('dt', 'tags', _('Tags'));
+        common_element_start('dd', 'tags');
+        $tags = Profile_tag::getTags($profile->id, $profile->id);
+
+        common_element_start('ul', 'tags xoxo');
+        foreach ($tags as $tag) {
+            common_element_start('li');
+            common_element('a', array('rel' => 'bookmark tag',
+                                      'href' => common_local_url('peopletag',
+                                                                 array('tag' => $tag))),
+                           $tag);
+            common_element_end('li');
+        }
+        common_element_end('ul');
+        common_element_end('dd');
+
+        common_element_end('dl');
+
+        common_element_end('div');
+    }
+
+    function show_notices($user)
+    {
+
+        $page = ($this->arg('page')) ? ($this->arg('page')+0) : 1;
+
+        $notice = $user->getNotices(($page-1)*NOTICES_PER_PAGE, NOTICES_PER_PAGE + 1);
 
         $pnl = new ProfileNoticeList($notice);
         $cnt = $pnl->show();
 
-               common_pagination($page>1, $cnt>NOTICES_PER_PAGE, $page,
-                                                 'showstream', array('nickname' => $user->nickname));
-       }
-
-       function show_last_notice($profile) {
-
-               common_element('h2', NULL, _('Currently'));
-
-               $notice = $profile->getCurrentNotice();
-
-               if ($notice) {
-                       # FIXME: URL, image, video, audio
-                       common_element_start('p', array('class' => 'notice_current'));
-                       if ($notice->rendered) {
-                               common_raw($notice->rendered);
-                       } else {
-                               # XXX: may be some uncooked notices in the DB,
-                               # we cook them right now. This can probably disappear in future
-                               # versions (>> 0.4.x)
-                               common_raw(common_render_content($notice->content, $notice));
-                       }
-                       common_element_end('p');
-               }
-       }
+        common_pagination($page>1, $cnt>NOTICES_PER_PAGE, $page,
+                          'showstream', array('nickname' => $user->nickname));
+    }
+
+    function show_last_notice($profile)
+    {
+
+        common_element('h2', null, _('Currently'));
+
+        $notice = $profile->getCurrentNotice();
+
+        if ($notice) {
+            # FIXME: URL, image, video, audio
+            common_element_start('p', array('class' => 'notice_current'));
+            if ($notice->rendered) {
+                common_raw($notice->rendered);
+            } else {
+                # XXX: may be some uncooked notices in the DB,
+                # we cook them right now. This can probably disappear in future
+                # versions (>> 0.4.x)
+                common_raw(common_render_content($notice->content, $notice));
+            }
+            common_element_end('p');
+        }
+    }
 }
 
 # We don't show the author for a profile, since we already know who it is!
 
-class ProfileNoticeList extends NoticeList {
-    function new_list_item($notice) {
+class ProfileNoticeList extends NoticeList
+{
+    function newListItem($notice)
+    {
         return new ProfileNoticeListItem($notice);
     }
 }
 
-class ProfileNoticeListItem extends NoticeListItem {
-    function show_author() {
+class ProfileNoticeListItem extends NoticeListItem
+{
+    function showAuthor()
+    {
         return;
     }
 }
index 5db26730a50b1c5f05ccb314dc4dab33c3adba7b..fad71135ccecb1610159c697103246a9dc778d61 100644 (file)
@@ -22,310 +22,322 @@ if (!defined('LACONICA')) { exit(1); }
 require_once(INSTALLDIR.'/lib/settingsaction.php');
 require_once(INSTALLDIR.'/actions/emailsettings.php');
 
-class SmssettingsAction extends EmailsettingsAction {
-
-       function get_instructions() {
-               return _('You can receive SMS messages through email from %%site.name%%.');
-       }
-
-       function show_form($msg=NULL, $success=false) {
-               $user = common_current_user();
-               $this->form_header(_('SMS Settings'), $msg, $success);
-               common_element_start('form', array('method' => 'post',
-                                                                                  'id' => 'smssettings',
-                                                                                  'action' =>
-                                                                                  common_local_url('smssettings')));
-               common_hidden('token', common_session_token());
-               common_element('h2', NULL, _('Address'));
-
-               if ($user->sms) {
-                       common_element_start('p');
-                       $carrier = $user->getCarrier();
-                       common_element('span', 'address confirmed', $user->sms . ' (' . $carrier->name . ')');
-                       common_element('span', 'input_instructions',
-                                      _('Current confirmed SMS-enabled phone number.'));
-                       common_hidden('sms', $user->sms);
-                       common_hidden('carrier', $user->carrier);
-                       common_element_end('p');
-                       common_submit('remove', _('Remove'));
-               } else {
-                       $confirm = $this->get_confirmation();
-                       if ($confirm) {
-                               $carrier = Sms_carrier::staticGet($confirm->address_extra);
-                               common_element_start('p');
-                               common_element('span', 'address unconfirmed', $confirm->address . ' (' . $carrier->name . ')');
-                               common_element('span', 'input_instructions',
-                                                          _('Awaiting confirmation on this phone number.'));
-                               common_hidden('sms', $confirm->address);
-                               common_hidden('carrier', $confirm->address_extra);
-                               common_element_end('p');
-                               common_submit('cancel', _('Cancel'));
-                               common_input('code', _('Confirmation code'), NULL,
-                                                        _('Enter the code you received on your phone.'));
-                               common_submit('confirm', _('Confirm'));
-                       } else {
-                               common_input('sms', _('SMS Phone number'),
-                                                        ($this->arg('sms')) ? $this->arg('sms') : NULL,
-                                                        _('Phone number, no punctuation or spaces, with area code'));
-                               $this->carrier_select();
-                               common_submit('add', _('Add'));
-                       }
-               }
-
-               if ($user->sms) {
-                       common_element('h2', NULL, _('Incoming email'));
-                       
-                       if ($user->incomingemail) {
-                               common_element_start('p');
-                               common_element('span', 'address', $user->incomingemail);
-                               common_element('span', 'input_instructions',
-                                                          _('Send email to this address to post new notices.'));
-                               common_element_end('p');
-                               common_submit('removeincoming', _('Remove'));
-                       }
-                       
-                       common_element_start('p');
-                       common_element('span', 'input_instructions',
-                                                  _('Make a new email address for posting to; cancels the old one.'));
-                       common_element_end('p');
-                       common_submit('newincoming', _('New'));
-               }
-               
-               common_element('h2', NULL, _('Preferences'));
-               
-               common_checkbox('smsnotify',
-                                               _('Send me notices through SMS; I understand I may incur exorbitant charges from my carrier.'),
-                                               $user->smsnotify);
-                       
-               common_submit('save', _('Save'));
-               
-               common_element_end('form');
-               common_show_footer();
-       }
-
-       function get_confirmation() {
-               $user = common_current_user();
-               $confirm = new Confirm_address();
-               $confirm->user_id = $user->id;
-               $confirm->address_type = 'sms';
-               if ($confirm->find(TRUE)) {
-                       return $confirm;
-               } else {
-                       return NULL;
-               }
-       }
-
-       function handle_post() {
-
-               # CSRF protection
-
-               $token = $this->trimmed('token');
-               if (!$token || $token != common_session_token()) {
-                       $this->show_form(_('There was a problem with your session token. Try again, please.'));
-                       return;
-               }
-
-               if ($this->arg('save')) {
-                       $this->save_preferences();
-               } else if ($this->arg('add')) {
-                       $this->add_address();
-               } else if ($this->arg('cancel')) {
-                       $this->cancel_confirmation();
-               } else if ($this->arg('remove')) {
-                       $this->remove_address();
-               } else if ($this->arg('removeincoming')) {
-                       $this->remove_incoming();
-               } else if ($this->arg('newincoming')) {
-                       $this->new_incoming();
-               } else if ($this->arg('confirm')) {
-                       $this->confirm_code();
-               } else {
-                       $this->show_form(_('Unexpected form submission.'));
-               }
-       }
-
-       function save_preferences() {
-
-               $smsnotify = $this->boolean('smsnotify');
-               
-               $user = common_current_user();
-
-               assert(!is_null($user)); # should already be checked
-
-               $user->query('BEGIN');
-
-               $original = clone($user);
-
-               $user->smsnotify = $smsnotify;
-
-               $result = $user->update($original);
-
-               if ($result === FALSE) {
-                       common_log_db_error($user, 'UPDATE', __FILE__);
-                       common_server_error(_('Couldn\'t update user.'));
-                       return;
-               }
-
-               $user->query('COMMIT');
-
-               $this->show_form(_('Preferences saved.'), true);
-       }
-
-       function add_address() {
-
-               $user = common_current_user();
-
-               $sms = $this->trimmed('sms');
-               $carrier_id = $this->trimmed('carrier');
-               
-               # Some validation
-
-               if (!$sms) {
-                       $this->show_form(_('No phone number.'));
-                       return;
-               }
-
-               if (!$carrier_id) {
-                       $this->show_form(_('No carrier selected.'));
-                       return;
-               }
-               
-               $sms = common_canonical_sms($sms);
-               
-               if ($user->sms == $sms) {
-                   $this->show_form(_('That is already your phone number.'));
-                   return;
-               } else if ($this->sms_exists($sms)) {
-                   $this->show_form(_('That phone number already belongs to another user.'));
-                   return;
-               }
-
-               $confirm = new Confirm_address();
-               $confirm->address = $sms;
-               $confirm->address_extra = $carrier_id;
-               $confirm->address_type = 'sms';
-               $confirm->user_id = $user->id;
-               $confirm->code = common_confirmation_code(40);
-
-               $result = $confirm->insert();
-
-               if ($result === FALSE) {
-                       common_log_db_error($confirm, 'INSERT', __FILE__);
-                       common_server_error(_('Couldn\'t insert confirmation code.'));
-                       return;
-               }
-
-               $carrier = Sms_carrier::staticGet($carrier_id);
-               
-               mail_confirm_sms($confirm->code,
-                                                $user->nickname,
-                                                $carrier->toEmailAddress($sms));
-
-               $msg = _('A confirmation code was sent to the phone number you added. Check your inbox (and spam box!) for the code and instructions on how to use it.');
-
-               $this->show_form($msg, TRUE);
-       }
-
-       function cancel_confirmation() {
-               
-               $sms = $this->trimmed('sms');
-               $carrier = $this->trimmed('carrier');
-               
-               $confirm = $this->get_confirmation();
-               
-               if (!$confirm) {
-                       $this->show_form(_('No pending confirmation to cancel.'));
-                       return;
-               }
-               if ($confirm->address != $sms) {
-                       $this->show_form(_('That is the wrong confirmation number.'));
-                       return;
-               }
+class SmssettingsAction extends EmailsettingsAction
+{
+
+    function get_instructions()
+    {
+        return _('You can receive SMS messages through email from %%site.name%%.');
+    }
+
+    function show_form($msg=null, $success=false)
+    {
+        $user = common_current_user();
+        $this->form_header(_('SMS Settings'), $msg, $success);
+        common_element_start('form', array('method' => 'post',
+                                           'id' => 'smssettings',
+                                           'action' =>
+                                           common_local_url('smssettings')));
+        common_hidden('token', common_session_token());
+        common_element('h2', null, _('Address'));
+
+        if ($user->sms) {
+            common_element_start('p');
+            $carrier = $user->getCarrier();
+            common_element('span', 'address confirmed', $user->sms . ' (' . $carrier->name . ')');
+            common_element('span', 'input_instructions',
+                           _('Current confirmed SMS-enabled phone number.'));
+            common_hidden('sms', $user->sms);
+            common_hidden('carrier', $user->carrier);
+            common_element_end('p');
+            common_submit('remove', _('Remove'));
+        } else {
+            $confirm = $this->get_confirmation();
+            if ($confirm) {
+                $carrier = Sms_carrier::staticGet($confirm->address_extra);
+                common_element_start('p');
+                common_element('span', 'address unconfirmed', $confirm->address . ' (' . $carrier->name . ')');
+                common_element('span', 'input_instructions',
+                               _('Awaiting confirmation on this phone number.'));
+                common_hidden('sms', $confirm->address);
+                common_hidden('carrier', $confirm->address_extra);
+                common_element_end('p');
+                common_submit('cancel', _('Cancel'));
+                common_input('code', _('Confirmation code'), null,
+                             _('Enter the code you received on your phone.'));
+                common_submit('confirm', _('Confirm'));
+            } else {
+                common_input('sms', _('SMS Phone number'),
+                             ($this->arg('sms')) ? $this->arg('sms') : null,
+                             _('Phone number, no punctuation or spaces, with area code'));
+                $this->carrier_select();
+                common_submit('add', _('Add'));
+            }
+        }
+
+        if ($user->sms) {
+            common_element('h2', null, _('Incoming email'));
+            
+            if ($user->incomingemail) {
+                common_element_start('p');
+                common_element('span', 'address', $user->incomingemail);
+                common_element('span', 'input_instructions',
+                               _('Send email to this address to post new notices.'));
+                common_element_end('p');
+                common_submit('removeincoming', _('Remove'));
+            }
+            
+            common_element_start('p');
+            common_element('span', 'input_instructions',
+                           _('Make a new email address for posting to; cancels the old one.'));
+            common_element_end('p');
+            common_submit('newincoming', _('New'));
+        }
+        
+        common_element('h2', null, _('Preferences'));
+        
+        common_checkbox('smsnotify',
+                        _('Send me notices through SMS; I understand I may incur exorbitant charges from my carrier.'),
+                        $user->smsnotify);
+            
+        common_submit('save', _('Save'));
+        
+        common_element_end('form');
+        common_show_footer();
+    }
+
+    function get_confirmation()
+    {
+        $user = common_current_user();
+        $confirm = new Confirm_address();
+        $confirm->user_id = $user->id;
+        $confirm->address_type = 'sms';
+        if ($confirm->find(true)) {
+            return $confirm;
+        } else {
+            return null;
+        }
+    }
+
+    function handle_post()
+    {
+
+        # CSRF protection
+
+        $token = $this->trimmed('token');
+        if (!$token || $token != common_session_token()) {
+            $this->show_form(_('There was a problem with your session token. Try again, please.'));
+            return;
+        }
+
+        if ($this->arg('save')) {
+            $this->save_preferences();
+        } else if ($this->arg('add')) {
+            $this->add_address();
+        } else if ($this->arg('cancel')) {
+            $this->cancel_confirmation();
+        } else if ($this->arg('remove')) {
+            $this->remove_address();
+        } else if ($this->arg('removeincoming')) {
+            $this->remove_incoming();
+        } else if ($this->arg('newincoming')) {
+            $this->new_incoming();
+        } else if ($this->arg('confirm')) {
+            $this->confirm_code();
+        } else {
+            $this->show_form(_('Unexpected form submission.'));
+        }
+    }
+
+    function save_preferences()
+    {
+
+        $smsnotify = $this->boolean('smsnotify');
+        
+        $user = common_current_user();
+
+        assert(!is_null($user)); # should already be checked
+
+        $user->query('BEGIN');
+
+        $original = clone($user);
+
+        $user->smsnotify = $smsnotify;
+
+        $result = $user->update($original);
+
+        if ($result === false) {
+            common_log_db_error($user, 'UPDATE', __FILE__);
+            common_server_error(_('Couldn\'t update user.'));
+            return;
+        }
+
+        $user->query('COMMIT');
+
+        $this->show_form(_('Preferences saved.'), true);
+    }
+
+    function add_address()
+    {
+
+        $user = common_current_user();
+
+        $sms = $this->trimmed('sms');
+        $carrier_id = $this->trimmed('carrier');
+        
+        # Some validation
+
+        if (!$sms) {
+            $this->show_form(_('No phone number.'));
+            return;
+        }
+
+        if (!$carrier_id) {
+            $this->show_form(_('No carrier selected.'));
+            return;
+        }
+        
+        $sms = common_canonical_sms($sms);
+        
+        if ($user->sms == $sms) {
+            $this->show_form(_('That is already your phone number.'));
+            return;
+        } else if ($this->sms_exists($sms)) {
+            $this->show_form(_('That phone number already belongs to another user.'));
+            return;
+        }
+
+          $confirm = new Confirm_address();
+           $confirm->address = $sms;
+           $confirm->address_extra = $carrier_id;
+           $confirm->address_type = 'sms';
+           $confirm->user_id = $user->id;
+           $confirm->code = common_confirmation_code(40);
+
+        $result = $confirm->insert();
+
+        if ($result === false) {
+            common_log_db_error($confirm, 'INSERT', __FILE__);
+            common_server_error(_('Couldn\'t insert confirmation code.'));
+            return;
+        }
+
+        $carrier = Sms_carrier::staticGet($carrier_id);
+        
+        mail_confirm_sms($confirm->code,
+                         $user->nickname,
+                         $carrier->toEmailAddress($sms));
+
+        $msg = _('A confirmation code was sent to the phone number you added. Check your inbox (and spam box!) for the code and instructions on how to use it.');
+
+        $this->show_form($msg, true);
+    }
+
+    function cancel_confirmation()
+    {
+        
+        $sms = $this->trimmed('sms');
+        $carrier = $this->trimmed('carrier');
+        
+        $confirm = $this->get_confirmation();
+        
+        if (!$confirm) {
+            $this->show_form(_('No pending confirmation to cancel.'));
+            return;
+        }
+        if ($confirm->address != $sms) {
+            $this->show_form(_('That is the wrong confirmation number.'));
+            return;
+        }
 
         $result = $confirm->delete();
 
         if (!$result) {
-                       common_log_db_error($confirm, 'DELETE', __FILE__);
+            common_log_db_error($confirm, 'DELETE', __FILE__);
             $this->server_error(_('Couldn\'t delete email confirmation.'));
             return;
         }
 
-        $this->show_form(_('Confirmation cancelled.'), TRUE);
-       }
-
-       function remove_address() {
-
-               $user = common_current_user();
-               $sms = $this->arg('sms');
-               $carrier = $this->arg('carrier');
-               
-               # Maybe an old tab open...?
-
-               if ($user->sms != $sms) {
-                   $this->show_form(_('That is not your phone number.'));
-                   return;
-               }
-
-               $user->query('BEGIN');
-               $original = clone($user);
-               $user->sms = NULL;
-               $user->carrier = NULL;          
-               $user->smsemail = NULL;         
-               $result = $user->updateKeys($original);
-               if (!$result) {
-                       common_log_db_error($user, 'UPDATE', __FILE__);
-                       common_server_error(_('Couldn\'t update user.'));
-                       return;
-               }
-               $user->query('COMMIT');
-
-               $this->show_form(_('The address was removed.'), TRUE);
-       }
-       
-       function sms_exists($sms) {
-               $user = common_current_user();
-               $other = User::staticGet('sms', $sms);
-               if (!$other) {
-                       return false;
-               } else {
-                       return $other->id != $user->id;
-               }
-       }
-
-       function carrier_select() {
-               $carrier = new Sms_carrier();
-               $cnt = $carrier->find();
-
-               common_element_start('p');
-               common_element('label', array('for' => 'carrier'));
-               common_element_start('select', array('name' => 'carrier',
-                                                                                        'id' => 'carrier'));
-               common_element('option', array('value' => 0),
-                                          _('Select a carrier'));
-               while ($carrier->fetch()) {
-                       common_element('option', array('value' => $carrier->id),
-                                                  $carrier->name);
-               }
-               common_element_end('select');
-               common_element_end('p');
-               common_element('span', 'input_instructions',
-                                          sprintf(_('Mobile carrier for your phone. '.
-                                                                'If you know a carrier that accepts ' . 
-                                                                'SMS over email but isn\'t listed here, ' .
-                                                                'send email to let us know at %s.'),
-                                                          common_config('site', 'email')));
-       }
-
-       function confirm_code() {
-               
-               $code = $this->trimmed('code');
-               
-               if (!$code) {
-                       $this->show_form(_('No code entered'));
-                       return;
-               }
-               
-               common_redirect(common_local_url('confirmaddress', 
-                                                                                array('code' => $code)));
-       }
+        $this->show_form(_('Confirmation cancelled.'), true);
+    }
+
+    function remove_address()
+    {
+
+        $user = common_current_user();
+        $sms = $this->arg('sms');
+        $carrier = $this->arg('carrier');
+        
+        # Maybe an old tab open...?
+
+        if ($user->sms != $sms) {
+            $this->show_form(_('That is not your phone number.'));
+            return;
+        }
+
+        $user->query('BEGIN');
+        $original = clone($user);
+        $user->sms = null;
+        $user->carrier = null;        
+        $user->smsemail = null;        
+        $result = $user->updateKeys($original);
+        if (!$result) {
+            common_log_db_error($user, 'UPDATE', __FILE__);
+            common_server_error(_('Couldn\'t update user.'));
+            return;
+        }
+        $user->query('COMMIT');
+
+        $this->show_form(_('The address was removed.'), true);
+    }
+    
+    function sms_exists($sms)
+    {
+        $user = common_current_user();
+        $other = User::staticGet('sms', $sms);
+        if (!$other) {
+            return false;
+        } else {
+            return $other->id != $user->id;
+        }
+    }
+
+    function carrier_select()
+    {
+        $carrier = new Sms_carrier();
+        $cnt = $carrier->find();
+
+        common_element_start('p');
+        common_element('label', array('for' => 'carrier'));
+        common_element_start('select', array('name' => 'carrier',
+                                             'id' => 'carrier'));
+        common_element('option', array('value' => 0),
+                       _('Select a carrier'));
+        while ($carrier->fetch()) {
+            common_element('option', array('value' => $carrier->id),
+                           $carrier->name);
+        }
+        common_element_end('select');
+        common_element_end('p');
+        common_element('span', 'input_instructions',
+                       sprintf(_('Mobile carrier for your phone. '.
+                                 'If you know a carrier that accepts ' . 
+                                 'SMS over email but isn\'t listed here, ' .
+                                 'send email to let us know at %s.'),
+                               common_config('site', 'email')));
+    }
+
+    function confirm_code()
+    {
+        
+        $code = $this->trimmed('code');
+        
+        if (!$code) {
+            $this->show_form(_('No code entered'));
+            return;
+        }
+        
+        common_redirect(common_local_url('confirmaddress', 
+                                         array('code' => $code)));
+    }
 }
index e7505e3fef44f1c137878c8efa82e6a132720138..1142b7a0323d10aafacdbf62e8558a34da32c1fb 100644 (file)
 
 if (!defined('LACONICA')) { exit(1); }
 
-class SubeditAction extends Action {
+class SubeditAction extends Action
+{
 
-    var $profile = NULL;
+    var $profile = null;
 
-    function prepare($args) {
+    function prepare($args)
+    {
 
         parent::prepare($args);
 
@@ -32,12 +34,12 @@ class SubeditAction extends Action {
             return false;
         }
 
-               $token = $this->trimmed('token');
+        $token = $this->trimmed('token');
 
-               if (!$token || $token != common_session_token()) {
-                       $this->client_error(_('There was a problem with your session token. Try again, please.'));
-                       return;
-               }
+        if (!$token || $token != common_session_token()) {
+            $this->client_error(_('There was a problem with your session token. Try again, please.'));
+            return;
+        }
 
         $id = $this->trimmed('profile');
 
@@ -56,7 +58,8 @@ class SubeditAction extends Action {
         return true;
     }
 
-    function handle($args) {
+    function handle($args)
+    {
         parent::handle($args);
         if ($_SERVER['REQUEST_METHOD'] == 'POST') {
             $cur = common_current_user();
index 64abda00431c0d9fbcf3a060f17510ade1a44849..f33d1d2077b6010fde138502709b30ae3ddf0a14 100644 (file)
 
 if (!defined('LACONICA')) { exit(1); }
 
-class SubscribeAction extends Action {
+class SubscribeAction extends Action
+{
 
-       function handle($args) {
-               parent::handle($args);
+    function handle($args)
+    {
+        parent::handle($args);
 
-               if (!common_logged_in()) {
-                       common_user_error(_('Not logged in.'));
-                       return;
-               }
+        if (!common_logged_in()) {
+            common_user_error(_('Not logged in.'));
+            return;
+        }
 
-               $user = common_current_user();
+        $user = common_current_user();
 
-               if ($_SERVER['REQUEST_METHOD'] != 'POST') {
-                       common_redirect(common_local_url('subscriptions', array('nickname' => $user->nickname)));
-                       return;
-               }
+        if ($_SERVER['REQUEST_METHOD'] != 'POST') {
+            common_redirect(common_local_url('subscriptions', array('nickname' => $user->nickname)));
+            return;
+        }
 
-               # CSRF protection
+        # CSRF protection
 
-               $token = $this->trimmed('token');
+        $token = $this->trimmed('token');
 
-               if (!$token || $token != common_session_token()) {
-                       $this->client_error(_('There was a problem with your session token. Try again, please.'));
-                       return;
-               }
+        if (!$token || $token != common_session_token()) {
+            $this->client_error(_('There was a problem with your session token. Try again, please.'));
+            return;
+        }
 
-               $other_id = $this->arg('subscribeto');
+        $other_id = $this->arg('subscribeto');
 
         $other = User::staticGet('id', $other_id);
 
         if (!$other) {
-                       $this->client_error(_('Not a local user.'));
-                       return;
+            $this->client_error(_('Not a local user.'));
+            return;
         }
 
-               $result = subs_subscribe_to($user, $other);
+        $result = subs_subscribe_to($user, $other);
 
-               if($result != true) {
-                       common_user_error($result);
-                       return;
-               }
+        if($result != true) {
+            common_user_error($result);
+            return;
+        }
 
-               if ($this->boolean('ajax')) {
-                       common_start_html('text/xml;charset=utf-8', true);
-                       common_element_start('head');
-                       common_element('title', null, _('Subscribed'));
-                       common_element_end('head');
-                       common_element_start('body');
-                       common_unsubscribe_form($other->getProfile());
-                       common_element_end('body');
-                       common_element_end('html');
-               } else {
-                   common_redirect(common_local_url('subscriptions', array('nickname' =>
-                                                                                                                               $user->nickname)));
+        if ($this->boolean('ajax')) {
+            common_start_html('text/xml;charset=utf-8', true);
+            common_element_start('head');
+            common_element('title', null, _('Subscribed'));
+            common_element_end('head');
+            common_element_start('body');
+            common_unsubscribe_form($other->getProfile());
+            common_element_end('body');
+            common_element_end('html');
+        } else {
+            common_redirect(common_local_url('subscriptions', array('nickname' =>
+                                                                $user->nickname)));
         }
-       }
+    }
 }
index ae52526e199115ac2d5aae511fe459fdc302be80..31d0468d9018d669d34082b8f0ee32642bd110c9 100644 (file)
@@ -21,40 +21,49 @@ if (!defined('LACONICA')) { exit(1); }
 
 require_once(INSTALLDIR.'/lib/gallery.php');
 
-class SubscribersAction extends GalleryAction {
-
-       function gallery_type() {
-               return _('Subscribers');
-       }
-
-       function get_instructions(&$profile) {
-               $user =& common_current_user();
-               if ($user && ($user->id == $profile->id)) {
-                       return _('These are the people who listen to your notices.');
-               } else {
-                       return sprintf(_('These are the people who listen to %s\'s notices.'), $profile->nickname);
-               }
-       }
-
-       function fields() {
-               return array('subscriber', 'subscribed');
-       }
-
-       function div_class() {
-               return 'subscribers';
-       }
-
-       function get_other(&$subs) {
-               return $subs->subscriber;
-       }
-
-    function profile_list_class() {
+class SubscribersAction extends GalleryAction
+{
+
+    function gallery_type()
+    {
+        return _('Subscribers');
+    }
+
+    function get_instructions(&$profile)
+    {
+        $user =& common_current_user();
+        if ($user && ($user->id == $profile->id)) {
+            return _('These are the people who listen to your notices.');
+        } else {
+            return sprintf(_('These are the people who listen to %s\'s notices.'), $profile->nickname);
+        }
+    }
+
+    function fields()
+    {
+        return array('subscriber', 'subscribed');
+    }
+
+    function div_class()
+    {
+        return 'subscribers';
+    }
+
+    function get_other(&$subs)
+    {
+        return $subs->subscriber;
+    }
+
+    function profile_list_class()
+    {
         return 'SubscribersList';
     }
 }
 
-class SubscribersList extends ProfileList {
-    function show_owner_controls($profile) {
+class SubscribersList extends ProfileList
+{
+    function show_owner_controls($profile)
+    {
         common_block_form($profile, array('action' => 'subscribers',
                                           'nickname' => $this->owner->nickname));
     }
index f518a1f92deac061e950a6b4730c11356067bc3f..afe8fb26095e4a01d4b2fa38cd36f185958e72c3 100644 (file)
@@ -21,44 +21,53 @@ if (!defined('LACONICA')) { exit(1); }
 
 require_once(INSTALLDIR.'/lib/gallery.php');
 
-class SubscriptionsAction extends GalleryAction {
+class SubscriptionsAction extends GalleryAction
+{
 
-       function gallery_type() {
-               return _('Subscriptions');
-       }
+    function gallery_type()
+    {
+        return _('Subscriptions');
+    }
 
-       function get_instructions(&$profile) {
-               $user =& common_current_user();
-               if ($user && ($user->id == $profile->id)) {
-                       return _('These are the people whose notices you listen to.');
-               } else {
-                       return sprintf(_('These are the people whose notices %s listens to.'), $profile->nickname);
-               }
-       }
+    function get_instructions(&$profile)
+    {
+        $user =& common_current_user();
+        if ($user && ($user->id == $profile->id)) {
+            return _('These are the people whose notices you listen to.');
+        } else {
+            return sprintf(_('These are the people whose notices %s listens to.'), $profile->nickname);
+        }
+    }
 
-       function fields() {
-               return array('subscribed', 'subscriber');
-       }
+    function fields()
+    {
+        return array('subscribed', 'subscriber');
+    }
 
-       function div_class() {
-               return 'subscriptions';
-       }
+    function div_class()
+    {
+        return 'subscriptions';
+    }
 
-       function get_other(&$subs) {
-               return $subs->subscribed;
-       }
+    function get_other(&$subs)
+    {
+        return $subs->subscribed;
+    }
 
-    function profile_list_class() {
+    function profile_list_class()
+    {
         return 'SubscriptionsList';
     }
 }
 
-class SubscriptionsList extends ProfileList {
+class SubscriptionsList extends ProfileList
+{
 
-    function show_owner_controls($profile) {
+    function show_owner_controls($profile)
+    {
 
-               $sub = Subscription::pkeyGet(array('subscriber' => $this->owner->id,
-                                                                                  'subscribed' => $profile->id));
+        $sub = Subscription::pkeyGet(array('subscriber' => $this->owner->id,
+                                           'subscribed' => $profile->id));
         if (!$sub) {
             return;
         }
index 887017b2a44b222ad6ac47f78a79d761027f87ec..6a1897585acd959b968873a36bbc9cf5f35eefb3 100644 (file)
 
 if (!defined('LACONICA')) { exit(1); }
 
-class SupAction extends Action {
-       
-       function handle($args) {
-               
-               parent::handle($args);
-               
-               $seconds = $this->trimmed('seconds');
-               
-               if (!$seconds) {
-                       $seconds = 15;
-               }
+class SupAction extends Action
+{
+    
+    function handle($args)
+    {
+        
+        parent::handle($args);
+        
+        $seconds = $this->trimmed('seconds');
+        
+        if (!$seconds) {
+            $seconds = 15;
+        }
 
-               $updates = $this->get_updates($seconds);
-               
-               header('Content-Type: application/json; charset=utf-8');
-               
-               print json_encode(array('updated_time' => date('c'),
-                                                               'since_time' => date('c', time() - $seconds),
-                                                               'available_periods' => $this->available_periods(),
-                                                               'period' => $seconds,
-                                                               'updates' => $updates));
-       }
-       
-       function available_periods() {
-               static $periods = array(86400, 43200, 21600, 7200,
-                                                               3600, 1800,     600, 300, 120,
-                                                               60, 30, 15); 
-               $available = array();
-               foreach ($periods as $period) {
-                       $available[$period] = common_local_url('sup',
-                                                                                                  array('seconds' => $period));
-               }
-               
-               return $available;
-       }
-       
-       function get_updates($seconds) {
-               $notice = new Notice();
+        $updates = $this->get_updates($seconds);
+        
+        header('Content-Type: application/json; charset=utf-8');
+        
+        print json_encode(array('updated_time' => date('c'),
+                                'since_time' => date('c', time() - $seconds),
+                                'available_periods' => $this->available_periods(),
+                                'period' => $seconds,
+                                'updates' => $updates));
+    }
+    
+    function available_periods()
+    {
+        static $periods = array(86400, 43200, 21600, 7200,
+                                3600, 1800,    600, 300, 120,
+                                60, 30, 15); 
+        $available = array();
+        foreach ($periods as $period) {
+            $available[$period] = common_local_url('sup',
+                                                   array('seconds' => $period));
+        }
+        
+        return $available;
+    }
+    
+    function get_updates($seconds)
+    {
+        $notice = new Notice();
 
-               # XXX: cache this. Depends on how big this protocol becomes;
-               # Re-doing this query every 15 seconds isn't the end of the world.
+        # XXX: cache this. Depends on how big this protocol becomes;
+        # Re-doing this query every 15 seconds isn't the end of the world.
 
-               $notice->query('SELECT profile_id, max(id) AS max_id ' .
-                                          'FROM notice ' .
-                                          'WHERE created > (now() - ' . $seconds . ') ' .
-                                          'GROUP BY profile_id');
-               
-               $updates = array();
-               
-               while ($notice->fetch()) {
-                       $updates[] = array($notice->profile_id, $notice->max_id);
-               }
-               
-               return $updates;
-       }
-       
-       function is_readonly() {
-               return true;
-       }
+        $notice->query('SELECT profile_id, max(id) AS max_id ' .
+                       'FROM notice ' .
+                       'WHERE created > (now() - ' . $seconds . ') ' .
+                       'GROUP BY profile_id');
+        
+        $updates = array();
+        
+        while ($notice->fetch()) {
+            $updates[] = array($notice->profile_id, $notice->max_id);
+        }
+        
+        return $updates;
+    }
+    
+    function is_readonly()
+    {
+        return true;
+    }
 }
index 25cc853c458c099b40fc5c6e29b279a8fbe3cb18..8a3f90c16a3a0f14dce52ae1dfb46f36ff95164f 100644 (file)
@@ -22,144 +22,151 @@ if (!defined('LACONICA')) { exit(1); }
 require_once(INSTALLDIR.'/actions/showstream.php');
 define('TAGS_PER_PAGE', 100);
 
-class TagAction extends StreamAction {
-
-       function handle($args) {
-
-               parent::handle($args);
-
-               # Looks like we're good; show the header
-
-               if (isset($args['tag']) && $args['tag']) {
-                       $tag = $args['tag'];
-                       common_show_header(sprintf(_("Notices tagged with %s"), $tag),
-                                                          array($this, 'show_header'), $tag,
-                                                          array($this, 'show_top'));
-                       $this->show_notices($tag);
-               } else {
-                       common_show_header(_("Tags"),
-                                                          array($this, 'show_header'), '',
-                                                          array($this, 'show_top'));
-                       $this->show_tags();
-               }
-
-               common_show_footer();
-       }
-
-       function show_header($tag = false) {
-               if ($tag) {
-                       common_element('link', array('rel' => 'alternate',
-                                                                                'href' => common_local_url('tagrss', array('tag' => $tag)),
-                                                                                'type' => 'application/rss+xml',
-                                                                                'title' => sprintf(_('Feed for tag %s'), $tag)));
-               }
-       }
-
-       function get_instructions() {
-               return _('Showing most popular tags from the last week');
-       }
-
-       function show_top($tag = false) {
-               if (!$tag) {
-                       $instr = $this->get_instructions();
-                       $output = common_markup_to_html($instr);
-                       common_element_start('div', 'instructions');
-                       common_raw($output);
-                       common_element_end('div');
-                       $this->public_views_menu();
-               }
-               else {
-                       $this->show_feeds_list(array(0=>array('href'=>common_local_url('tagrss'),
-                                                                                                 'type' => 'rss',
-                                                                                                 'version' => 'RSS 1.0',
-                                                                                                 'item' => 'tagrss')));
-               }
-       }
-
-       function show_tags()
-       {
-               # This should probably be cached rather than recalculated
-               $tags = DB_DataObject::factory('Notice_tag');
-
-               #Need to clear the selection and then only re-add the field
-               #we are grouping by, otherwise it's not a valid 'group by'
-               #even though MySQL seems to let it slide...
-               $tags->selectAdd();
-               $tags->selectAdd('tag');
-
-               #Add the aggregated columns...
-               $tags->selectAdd('max(notice_id) as last_notice_id');
-               if(common_config('db','type')=='pgsql') {
-                       $calc='sum(exp(-extract(epoch from (now()-created))/%s)) as weight';
-               } else {
-                       $calc='sum(exp(-(now() - created)/%s)) as weight';
-               }
-               $tags->selectAdd(sprintf($calc, common_config('tag', 'dropoff')));
-               $tags->groupBy('tag');
-               $tags->orderBy('weight DESC');
-
-               # $tags->whereAdd('created > "' . strftime('%Y-%m-%d %H:%M:%S', strtotime('-1 MONTH')) . '"');
-
-               $tags->limit(TAGS_PER_PAGE);
-
-               $cnt = $tags->find();
-
-               if ($cnt > 0) {
-                       common_element_start('p', 'tagcloud');
-
-                       $tw = array();
-                       $sum = 0;
-                       while ($tags->fetch()) {
-                               $tw[$tags->tag] = $tags->weight;
-                               $sum += $tags->weight;
-                       }
-
-                       ksort($tw);
-
-                       foreach ($tw as $tag => $weight) {
-                               $this->show_tag($tag, $weight, $weight/$sum);
-                       }
-
-                       common_element_end('p');
-               }
-       }
-
-       function show_tag($tag, $weight, $relative) {
-
-               # XXX: these should probably tune to the size of the site
-               if ($relative > 0.1) {
-                       $cls =  'largest';
-               } else if ($relative > 0.05) {
-                       $cls = 'verylarge';
-               } else if ($relative > 0.02) {
-                       $cls = 'large';
-               } else if ($relative > 0.01) {
-                       $cls = 'medium';
-               } else if ($relative > 0.005) {
-                       $cls = 'small';
-               } else if ($relative > 0.002) {
-                       $cls = 'verysmall';
-               } else {
-                       $cls = 'smallest';
-               }
-
-               common_element('a', array('class' => "$cls weight-$weight relative-$relative",
-                                                                 'href' => common_local_url('tag', array('tag' => $tag))),
-                                          $tag);
-               common_text(' ');
-       }
-
-       function show_notices($tag) {
-
-               $cnt = 0;
-
-               $page = ($this->arg('page')) ? ($this->arg('page')+0) : 1;
-
-               $notice = Notice_tag::getStream($tag, (($page-1)*NOTICES_PER_PAGE), NOTICES_PER_PAGE + 1);
+class TagAction extends StreamAction
+{
+
+    function handle($args)
+    {
+
+        parent::handle($args);
+
+        # Looks like we're good; show the header
+
+        if (isset($args['tag']) && $args['tag']) {
+            $tag = $args['tag'];
+            common_show_header(sprintf(_("Notices tagged with %s"), $tag),
+                               array($this, 'show_header'), $tag,
+                               array($this, 'show_top'));
+            $this->show_notices($tag);
+        } else {
+            common_show_header(_("Tags"),
+                               array($this, 'show_header'), '',
+                               array($this, 'show_top'));
+            $this->show_tags();
+        }
+
+        common_show_footer();
+    }
+
+    function show_header($tag = false)
+    {
+        if ($tag) {
+            common_element('link', array('rel' => 'alternate',
+                                         'href' => common_local_url('tagrss', array('tag' => $tag)),
+                                         'type' => 'application/rss+xml',
+                                         'title' => sprintf(_('Feed for tag %s'), $tag)));
+        }
+    }
+
+    function get_instructions()
+    {
+        return _('Showing most popular tags from the last week');
+    }
+
+    function show_top($tag = false)
+    {
+        if (!$tag) {
+            $instr = $this->get_instructions();
+            $output = common_markup_to_html($instr);
+            common_element_start('div', 'instructions');
+            common_raw($output);
+            common_element_end('div');
+            $this->public_views_menu();
+        }
+        else {
+            $this->show_feeds_list(array(0=>array('href'=>common_local_url('tagrss'),
+                                                  'type' => 'rss',
+                                                  'version' => 'RSS 1.0',
+                                                  'item' => 'tagrss')));
+        }
+    }
+
+    function show_tags()
+    {
+        # This should probably be cached rather than recalculated
+        $tags = DB_DataObject::factory('Notice_tag');
+
+        #Need to clear the selection and then only re-add the field
+        #we are grouping by, otherwise it's not a valid 'group by'
+        #even though MySQL seems to let it slide...
+        $tags->selectAdd();
+        $tags->selectAdd('tag');
+
+        #Add the aggregated columns...
+        $tags->selectAdd('max(notice_id) as last_notice_id');
+        if(common_config('db','type')=='pgsql') {
+            $calc='sum(exp(-extract(epoch from (now()-created))/%s)) as weight';
+        } else {
+            $calc='sum(exp(-(now() - created)/%s)) as weight';
+        }
+        $tags->selectAdd(sprintf($calc, common_config('tag', 'dropoff')));
+        $tags->groupBy('tag');
+        $tags->orderBy('weight DESC');
+
+        # $tags->whereAdd('created > "' . strftime('%Y-%m-%d %H:%M:%S', strtotime('-1 MONTH')) . '"');
+
+        $tags->limit(TAGS_PER_PAGE);
+
+        $cnt = $tags->find();
+
+        if ($cnt > 0) {
+            common_element_start('p', 'tagcloud');
+
+            $tw = array();
+            $sum = 0;
+            while ($tags->fetch()) {
+                $tw[$tags->tag] = $tags->weight;
+                $sum += $tags->weight;
+            }
+
+            ksort($tw);
+
+            foreach ($tw as $tag => $weight) {
+                $this->show_tag($tag, $weight, $weight/$sum);
+            }
+
+            common_element_end('p');
+        }
+    }
+
+    function show_tag($tag, $weight, $relative)
+    {
+
+        # XXX: these should probably tune to the size of the site
+        if ($relative > 0.1) {
+            $cls =  'largest';
+        } else if ($relative > 0.05) {
+            $cls = 'verylarge';
+        } else if ($relative > 0.02) {
+            $cls = 'large';
+        } else if ($relative > 0.01) {
+            $cls = 'medium';
+        } else if ($relative > 0.005) {
+            $cls = 'small';
+        } else if ($relative > 0.002) {
+            $cls = 'verysmall';
+        } else {
+            $cls = 'smallest';
+        }
+
+        common_element('a', array('class' => "$cls weight-$weight relative-$relative",
+                                  'href' => common_local_url('tag', array('tag' => $tag))),
+                       $tag);
+        common_text(' ');
+    }
+
+    function show_notices($tag)
+    {
+
+        $cnt = 0;
+
+        $page = ($this->arg('page')) ? ($this->arg('page')+0) : 1;
+
+        $notice = Notice_tag::getStream($tag, (($page-1)*NOTICES_PER_PAGE), NOTICES_PER_PAGE + 1);
 
         $cnt = $this->show_notice_list($notice);
 
-               common_pagination($page > 1, $cnt > NOTICES_PER_PAGE,
-                                                 $page, 'tag', array('tag' => $tag));
-       }
+        common_pagination($page > 1, $cnt > NOTICES_PER_PAGE,
+                          $page, 'tag', array('tag' => $tag));
+    }
 }
index a4449dd690aa9ecfde08a1ef196156bc420c2b22..ff6788cc620c0c28146e20583ee9ce7cbfc322cc 100644 (file)
@@ -21,173 +21,178 @@ if (!defined('LACONICA')) { exit(1); }
 
 require_once(INSTALLDIR.'/lib/settingsaction.php');
 
-class TagotherAction extends Action {
-
-       function handle($args) {
-
-               parent::handle($args);
-
-               if (!common_logged_in()) {
-                       $this->client_error(_('Not logged in'), 403);
-                       return;
-               }
-
-               if ($_SERVER['REQUEST_METHOD'] == 'POST') {
-                       $this->save_tags();
-               } else {
-                       $id = $this->trimmed('id');
-                       if (!$id) {
-                               $this->client_error(_('No id argument.'));
-                               return;
-                       }
-                       $profile = Profile::staticGet('id', $id);
-                       if (!$profile) {
-                               $this->client_error(_('No profile with that ID.'));
-                               return;
-                       }
-                       $this->show_form($profile);
-               }
-       }
-
-       function show_form($profile, $error=NULL) {
-
-               $user = common_current_user();
-
-               common_show_header(_('Tag a person'),
-                                                  NULL, array($profile, $error), array($this, 'show_top'));
-
-               $avatar = $profile->getAvatar(AVATAR_PROFILE_SIZE);
-
-               common_element('img', array('src' => ($avatar) ? common_avatar_display_url($avatar) : common_default_avatar(AVATAR_PROFILE_SIZE),
-                                                                       'class' => 'avatar stream',
-                                                                       'width' => AVATAR_PROFILE_SIZE,
-                                                                       'height' => AVATAR_PROFILE_SIZE,
-                                                                       'alt' =>
-                                                                       ($profile->fullname) ? $profile->fullname :
-                                                                       $profile->nickname));
-
-               common_element('a', array('href' => $profile->profileurl,
-                                                                 'class' => 'external profile nickname'),
-                                          $profile->nickname);
-
-               if ($profile->fullname) {
-                       common_element_start('div', 'fullname');
-                       if ($profile->homepage) {
-                               common_element('a', array('href' => $profile->homepage),
-                                                          $profile->fullname);
-                       } else {
-                               common_text($profile->fullname);
-                       }
-                       common_element_end('div');
-               }
-               if ($profile->location) {
-                       common_element('div', 'location', $profile->location);
-               }
-               if ($profile->bio) {
-                       common_element('div', 'bio', $profile->bio);
-               }
-
-               common_element_start('form', array('method' => 'post',
-                                                                                  'id' => 'tag_user',
-                                                                                  'name' => 'tagother',
-                                                                                  'action' => $this->self_url()));
-               common_hidden('token', common_session_token());
-               common_hidden('id', $profile->id);
-               common_input('tags', _('Tags'),
-                                        ($this->arg('tags')) ? $this->arg('tags') : implode(' ', Profile_tag::getTags($user->id, $profile->id)),
-                                        _('Tags for this user (letters, numbers, -, ., and _), comma- or space- separated'));
-
-               common_submit('save', _('Save'));
-               common_element_end('form');
-               common_show_footer();
-
-       }
-
-       function save_tags() {
-
-               $id = $this->trimmed('id');
-               $tagstring = $this->trimmed('tags');
-               $token = $this->trimmed('token');
-
-               if (!$token || $token != common_session_token()) {
-                       $this->show_form(_('There was a problem with your session token. Try again, please.'));
-                       return;
-               }
-
-               $profile = Profile::staticGet('id', $id);
-
-               if (!$profile) {
-                       $this->client_error(_('No such profile.'));
-                       return;
-               }
-
-               if (is_string($tagstring) && strlen($tagstring) > 0) {
-
-                       $tags = array_map('common_canonical_tag',
-                                                         preg_split('/[\s,]+/', $tagstring));
-
-                       foreach ($tags as $tag) {
-                               if (!common_valid_profile_tag($tag)) {
-                                       $this->show_form($profile, sprintf(_('Invalid tag: "%s"'), $tag));
-                                       return;
-                               }
-                       }
-               } else {
-                       $tags = array();
-               }
-
-               $user = common_current_user();
-
-               if (!Subscription::pkeyGet(array('subscriber' => $user->id,
-                                                                                'subscribed' => $profile->id)) &&
-                       !Subscription::pkeyGet(array('subscriber' => $profile->id,
-                                                                                'subscribed' => $user->id)))
-               {
-                       $this->client_error(_('You can only tag people you are subscribed to or who are subscribed to you.'));
-                       return;
-               }
-
-               $result = Profile_tag::setTags($user->id, $profile->id, $tags);
-
-               if (!$result) {
-                       $this->client_error(_('Could not save tags.'));
-                       return;
-               }
-
-               $action = $user->isSubscribed($profile) ? 'subscriptions' : 'subscribers';
-
-               if ($this->boolean('ajax')) {
-                       common_start_html('text/xml');
-                       common_element_start('head');
-                       common_element('title', null, _('Tags'));
-                       common_element_end('head');
-                       common_element_start('body');
-                       common_element_start('p', 'subtags');
-                       foreach ($tags as $tag) {
-                               common_element('a', array('href' => common_local_url($action,
-                                                                                                                                        array('nickname' => $user->nickname,
-                                                                                                                                                  'tag' => $tag))),
-                                                          $tag);
-                       }
-                       common_element_end('p');
-                       common_element_end('body');
-                       common_element_end('html');
-               } else {
-                       common_redirect(common_local_url($action, array('nickname' =>
-                                                                                                                       $user->nickname)));
+class TagotherAction extends Action
+{
+
+    function handle($args)
+    {
+
+        parent::handle($args);
+
+        if (!common_logged_in()) {
+            $this->client_error(_('Not logged in'), 403);
+            return;
+        }
+
+        if ($_SERVER['REQUEST_METHOD'] == 'POST') {
+            $this->save_tags();
+        } else {
+            $id = $this->trimmed('id');
+            if (!$id) {
+                $this->client_error(_('No id argument.'));
+                return;
+            }
+            $profile = Profile::staticGet('id', $id);
+            if (!$profile) {
+                $this->client_error(_('No profile with that ID.'));
+                return;
+            }
+            $this->show_form($profile);
+        }
+    }
+
+    function show_form($profile, $error=null)
+    {
+
+        $user = common_current_user();
+
+        common_show_header(_('Tag a person'),
+                           null, array($profile, $error), array($this, 'show_top'));
+
+        $avatar = $profile->getAvatar(AVATAR_PROFILE_SIZE);
+
+        common_element('img', array('src' => ($avatar) ? common_avatar_display_url($avatar) : common_default_avatar(AVATAR_PROFILE_SIZE),
+                                    'class' => 'avatar stream',
+                                    'width' => AVATAR_PROFILE_SIZE,
+                                    'height' => AVATAR_PROFILE_SIZE,
+                                    'alt' =>
+                                    ($profile->fullname) ? $profile->fullname :
+                                    $profile->nickname));
+
+        common_element('a', array('href' => $profile->profileurl,
+                                  'class' => 'external profile nickname'),
+                       $profile->nickname);
+
+        if ($profile->fullname) {
+            common_element_start('div', 'fullname');
+            if ($profile->homepage) {
+                common_element('a', array('href' => $profile->homepage),
+                               $profile->fullname);
+            } else {
+                common_text($profile->fullname);
+            }
+            common_element_end('div');
+        }
+        if ($profile->location) {
+            common_element('div', 'location', $profile->location);
+        }
+        if ($profile->bio) {
+            common_element('div', 'bio', $profile->bio);
+        }
+
+        common_element_start('form', array('method' => 'post',
+                                           'id' => 'tag_user',
+                                           'name' => 'tagother',
+                                           'action' => $this->self_url()));
+        common_hidden('token', common_session_token());
+        common_hidden('id', $profile->id);
+        common_input('tags', _('Tags'),
+                     ($this->arg('tags')) ? $this->arg('tags') : implode(' ', Profile_tag::getTags($user->id, $profile->id)),
+                     _('Tags for this user (letters, numbers, -, ., and _), comma- or space- separated'));
+
+        common_submit('save', _('Save'));
+        common_element_end('form');
+        common_show_footer();
+
+    }
+
+    function save_tags()
+    {
+
+        $id = $this->trimmed('id');
+        $tagstring = $this->trimmed('tags');
+        $token = $this->trimmed('token');
+
+        if (!$token || $token != common_session_token()) {
+            $this->show_form(_('There was a problem with your session token. Try again, please.'));
+            return;
+        }
+
+        $profile = Profile::staticGet('id', $id);
+
+        if (!$profile) {
+            $this->client_error(_('No such profile.'));
+            return;
+        }
+
+        if (is_string($tagstring) && strlen($tagstring) > 0) {
+
+            $tags = array_map('common_canonical_tag',
+                              preg_split('/[\s,]+/', $tagstring));
+
+            foreach ($tags as $tag) {
+                if (!common_valid_profile_tag($tag)) {
+                    $this->show_form($profile, sprintf(_('Invalid tag: "%s"'), $tag));
+                    return;
+                }
+            }
+        } else {
+            $tags = array();
+        }
+
+        $user = common_current_user();
+
+        if (!Subscription::pkeyGet(array('subscriber' => $user->id,
+                                         'subscribed' => $profile->id)) &&
+            !Subscription::pkeyGet(array('subscriber' => $profile->id,
+                                         'subscribed' => $user->id)))
+        {
+            $this->client_error(_('You can only tag people you are subscribed to or who are subscribed to you.'));
+            return;
+        }
+
+        $result = Profile_tag::setTags($user->id, $profile->id, $tags);
+
+        if (!$result) {
+            $this->client_error(_('Could not save tags.'));
+            return;
+        }
+
+        $action = $user->isSubscribed($profile) ? 'subscriptions' : 'subscribers';
+
+        if ($this->boolean('ajax')) {
+            common_start_html('text/xml');
+            common_element_start('head');
+            common_element('title', null, _('Tags'));
+            common_element_end('head');
+            common_element_start('body');
+            common_element_start('p', 'subtags');
+            foreach ($tags as $tag) {
+                common_element('a', array('href' => common_local_url($action,
+                                                                     array('nickname' => $user->nickname,
+                                                                           'tag' => $tag))),
+                               $tag);
+            }
+            common_element_end('p');
+            common_element_end('body');
+            common_element_end('html');
+        } else {
+            common_redirect(common_local_url($action, array('nickname' =>
+                                                            $user->nickname)));
+        }
+    }
+
+    function show_top($arr = null)
+    {
+        list($profile, $error) = $arr;
+        if ($error) {
+            common_element('p', 'error', $error);
+        } else {
+            common_element_start('div', 'instructions');
+            common_element('p', null,
+                           _('Use this form to add tags to your subscribers or subscriptions.'));
+            common_element_end('div');
         }
-       }
-
-       function show_top($arr = NULL) {
-               list($profile, $error) = $arr;
-               if ($error) {
-                       common_element('p', 'error', $error);
-               } else {
-                       common_element_start('div', 'instructions');
-                       common_element('p', NULL,
-                                                  _('Use this form to add tags to your subscribers or subscriptions.'));
-                       common_element_end('div');
-               }
-       }
+    }
 }
 
index 9187bdc873e1f53a21e111192839c3de6d7aee43..912d71413d5d6df2b6359fef9a841a1a9542357b 100644 (file)
@@ -23,43 +23,47 @@ require_once(INSTALLDIR.'/lib/rssaction.php');
 
 // Formatting of RSS handled by Rss10Action
 
-class TagrssAction extends Rss10Action {
+class TagrssAction extends Rss10Action
+{
 
-       function init() {
-               $tag = $this->trimmed('tag');
-               $this->tag = Notice_tag::staticGet('tag', $tag);
+    function init()
+    {
+        $tag = $this->trimmed('tag');
+        $this->tag = Notice_tag::staticGet('tag', $tag);
 
-               if (!$this->tag) {
-                       common_user_error(_('No such tag.'));
-                       return false;
-               } else {
-                       return true;
-               }
-       }
+        if (!$this->tag) {
+            common_user_error(_('No such tag.'));
+            return false;
+        } else {
+            return true;
+        }
+    }
 
-       function get_notices($limit=0) {
-               $tag = $this->tag;
+    function get_notices($limit=0)
+    {
+        $tag = $this->tag;
 
-               if (is_null($tag)) {
-                       return NULL;
-               }
+        if (is_null($tag)) {
+            return null;
+        }
 
-               $notice = Notice_tag::getStream($tag->tag, 0, ($limit == 0) ? NOTICES_PER_PAGE : $limit);
+        $notice = Notice_tag::getStream($tag->tag, 0, ($limit == 0) ? NOTICES_PER_PAGE : $limit);
 
-               while ($notice->fetch()) {
-                       $notices[] = clone($notice);
-               }
+        while ($notice->fetch()) {
+            $notices[] = clone($notice);
+        }
 
-               return $notices;
-       }
+        return $notices;
+    }
 
-       function get_channel() {
-               $tag = $this->tag->tag;
+    function get_channel()
+    {
+        $tag = $this->tag->tag;
 
-               $c = array('url' => common_local_url('tagrss', array('tag' => $tagname)),
-                          'title' => $tagname,
-                          'link' => common_local_url('tagrss', array('tag' => $tagname)),
-                          'description' => sprintf(_('Microblog tagged with %s'), $tagname));
-               return $c;
-       }
+        $c = array('url' => common_local_url('tagrss', array('tag' => $tagname)),
+               'title' => $tagname,
+               'link' => common_local_url('tagrss', array('tag' => $tagname)),
+               'description' => sprintf(_('Microblog tagged with %s'), $tagname));
+        return $c;
+    }
 }
index f6e955828e306b60425d44c9b5fa6867fb98d949..79e1ed990d7ec9ddc063bff410ea278a9dd74e8d 100644 (file)
@@ -21,76 +21,82 @@ if (!defined('LACONICA')) { exit(1); }
 
 require_once(INSTALLDIR.'/lib/twitterapi.php');
 
-class TwitapiaccountAction extends TwitterapiAction {
+class TwitapiaccountAction extends TwitterapiAction
+{
 
-       function verify_credentials($args, $apidata) {
-               parent::handle($args);
+    function verify_credentials($args, $apidata)
+    {
+        parent::handle($args);
 
-               if (!in_array($apidata['content-type'], array('xml', 'json'))) {
-                       common_user_error(_('API method not found!'), $code = 404);
-                       return;
-               }
+        if (!in_array($apidata['content-type'], array('xml', 'json'))) {
+            common_user_error(_('API method not found!'), $code = 404);
+            return;
+        }
 
-               $this->show_extended_profile($apidata['user'], $apidata);
-       }
+        $this->show_extended_profile($apidata['user'], $apidata);
+    }
 
-       function end_session($args, $apidata) {
-               parent::handle($args);
-               common_server_error(_('API method under construction.'), $code=501);
-       }
+    function end_session($args, $apidata)
+    {
+        parent::handle($args);
+        common_server_error(_('API method under construction.'), $code=501);
+    }
 
-       function update_location($args, $apidata) {
-               parent::handle($args);
+    function update_location($args, $apidata)
+    {
+        parent::handle($args);
 
-               if ($_SERVER['REQUEST_METHOD'] != 'POST') {
-                       $this->client_error(_('This method requires a POST.'), 400, $apidata['content-type']);
-                       return;
-               }
+        if ($_SERVER['REQUEST_METHOD'] != 'POST') {
+            $this->client_error(_('This method requires a POST.'), 400, $apidata['content-type']);
+            return;
+        }
 
-               $location = trim($this->arg('location'));
+        $location = trim($this->arg('location'));
 
-               if (!is_null($location) && strlen($location) > 255) {
+        if (!is_null($location) && strlen($location) > 255) {
 
-                       // XXX: But Twitter just truncates and runs with it. -- Zach
-                       $this->client_error(_('That\'s too long. Max notice size is 255 chars.'), 406, $apidate['content-type']);
-                       return;
-               }
+            // XXX: But Twitter just truncates and runs with it. -- Zach
+            $this->client_error(_('That\'s too long. Max notice size is 255 chars.'), 406, $apidate['content-type']);
+            return;
+        }
 
-               $user = $apidata['user'];
-               $profile = $user->getProfile();
+        $user = $apidata['user'];
+        $profile = $user->getProfile();
 
-               if (!$profile) {
-                       common_server_error(_('User has no profile.'));
-                       return;
-               }
+        if (!$profile) {
+            common_server_error(_('User has no profile.'));
+            return;
+        }
 
-               $orig_profile = clone($profile);
-               $profile->location = $location;
+        $orig_profile = clone($profile);
+        $profile->location = $location;
 
-               $result = $profile->update($orig_profile);
+        $result = $profile->update($orig_profile);
 
-               if (!$result) {
-                       common_log_db_error($profile, 'UPDATE', __FILE__);
-                       common_server_error(_('Couldn\'t save profile.'));
-                       return;
-               }
+        if (!$result) {
+            common_log_db_error($profile, 'UPDATE', __FILE__);
+            common_server_error(_('Couldn\'t save profile.'));
+            return;
+        }
 
-               common_broadcast_profile($profile);
-               $type = $apidata['content-type'];
+        common_broadcast_profile($profile);
+        $type = $apidata['content-type'];
 
-               $this->init_document($type);
-               $this->show_profile($profile, $type);
-               $this->end_document($type);
-       }
+        $this->init_document($type);
+        $this->show_profile($profile, $type);
+        $this->end_document($type);
+    }
 
 
-       function update_delivery_device($args, $apidata) {
-               parent::handle($args);
-               common_server_error(_('API method under construction.'), $code=501);
-       }
+    function update_delivery_device($args, $apidata)
+    {
+        parent::handle($args);
+        common_server_error(_('API method under construction.'), $code=501);
+    }
 
-       function rate_limit_status($args, $apidata) {
-               parent::handle($args);
-               common_server_error(_('API method under construction.'), $code=501);
-       }
+    function rate_limit_status($args, $apidata)
+    {
+        parent::handle($args);
+        common_server_error(_('API method under construction.'), $code=501);
+    }
 }
\ No newline at end of file
index 4852ff9388c90f3bfb399cf7a5709e4a48b3f6d1..5d64f2f7d8b7d1fd8edceab4633d8ae4be5aeefc 100644 (file)
@@ -21,17 +21,19 @@ if (!defined('LACONICA')) { exit(1); }
 
 require_once(INSTALLDIR.'/lib/twitterapi.php');
 
-class TwitapiblocksAction extends TwitterapiAction {
+class TwitapiblocksAction extends TwitterapiAction
+{
 
-       function create($args, $apidata) {
+    function create($args, $apidata)
+    {
 
-               parent::handle($args);
+        parent::handle($args);
 
-               $blockee = $this->get_user($apidata['api_arg'], $apidata);
+        $blockee = $this->get_user($apidata['api_arg'], $apidata);
 
         if (!$blockee) {
-                       $this->client_error('Not Found', 404, $apidata['content-type']);
-                       return;
+            $this->client_error('Not Found', 404, $apidata['content-type']);
+            return;
         }
 
         $user = $apidata['user'];
@@ -42,17 +44,18 @@ class TwitapiblocksAction extends TwitterapiAction {
             $this->show_profile($blockee, $type);
             $this->end_document($type);
         } else {
-                       common_server_error(_('Block user failed.'));
+            common_server_error(_('Block user failed.'));
         }
-       }
+    }
 
-       function destroy($args, $apidata) {
-               parent::handle($args);
-               $blockee = $this->get_user($apidata['api_arg'], $apidata);
+    function destroy($args, $apidata)
+    {
+        parent::handle($args);
+        $blockee = $this->get_user($apidata['api_arg'], $apidata);
 
         if (!$blockee) {
-                       $this->client_error('Not Found', 404, $apidata['content-type']);
-                       return;
+            $this->client_error('Not Found', 404, $apidata['content-type']);
+            return;
         }
 
         $user = $apidata['user'];
@@ -63,7 +66,7 @@ class TwitapiblocksAction extends TwitterapiAction {
             $this->show_profile($blockee, $type);
             $this->end_document($type);
         } else {
-                       common_server_error(_('Unblock user failed.'));
+            common_server_error(_('Unblock user failed.'));
         }
-       }
+    }
 }
\ No newline at end of file
index 535795ca4321d6351edca4dbe6d2d2e3ced8ef2b..e0731f66fbb7ed3e78b2670c7dd9071579bc6e45 100644 (file)
@@ -21,267 +21,278 @@ if (!defined('LACONICA')) { exit(1); }
 
 require_once(INSTALLDIR.'/lib/twitterapi.php');
 
-class Twitapidirect_messagesAction extends TwitterapiAction {
-
-       function direct_messages($args, $apidata) {
-               parent::handle($args);
-               return $this->show_messages($args, $apidata, 'received');
-       }
-
-       function sent($args, $apidata) {
-               parent::handle($args);
-               return $this->show_messages($args, $apidata, 'sent');
-       }
-
-       function show_messages($args, $apidata, $type) {
-
-               $user = $apidata['user'];
-
-               $count = $this->arg('count');
-               $since = $this->arg('since');
-               $since_id = $this->arg('since_id');
-               $before_id = $this->arg('before_id');
-
-               $page = $this->arg('page');
-
-               if (!$page) {
-                       $page = 1;
-               }
-
-               if (!$count) {
-                       $count = 20;
-               }
-
-               $message = new Message();
-
-               $title = null;
-               $subtitle = null;
-               $link = null;
-               $server = common_root_url();
-
-               if ($type == 'received') {
-                       $message->to_profile = $user->id;
-                       $title = sprintf(_("Direct messages to %s"), $user->nickname);
-                       $subtitle = sprintf(_("All the direct messages sent to %s"), $user->nickname);
-                       $link = $server . $user->nickname . '/inbox';
-               } else {
-                       $message->from_profile = $user->id;
-                       $title = _('Direct Messages You\'ve Sent');
-                       $subtitle = sprintf(_("All the direct messages sent from %s"), $user->nickname);
-                       $link = $server . $user->nickname . '/outbox';
-               }
-
-               if ($before_id) {
-                       $message->whereAdd("id < $before_id");
-               }
-
-               if ($since_id) {
-                       $message->whereAdd("id > $since_id");
-               }
-
-               $since = strtotime($this->arg('since'));
-
-               if ($since) {
-                       $d = date('Y-m-d H:i:s', $since);
-                       $message->whereAdd("created > '$d'");
-               }
-
-               $message->orderBy('created DESC, id DESC');
-               $message->limit((($page-1)*20), $count);
-               $message->find();
-
-               switch($apidata['content-type']) {
-                case 'xml':
-                       $this->show_xml_dmsgs($message);
-                       break;
-                case 'rss':
-                       $this->show_rss_dmsgs($message, $title, $link, $subtitle);
-                       break;
-                case 'atom':
-                       $this->show_atom_dmsgs($message, $title, $link, $subtitle);
-                       break;
-                case 'json':
-                       $this->show_json_dmsgs($message);
-                       break;
-                default:
-                       common_user_error(_('API method not found!'), $code = 404);
-               }
-
-       }
-
-       // had to change this from "new" to "create" to avoid PHP reserved word
-       function create($args, $apidata) {
-               parent::handle($args);
-
-               if ($_SERVER['REQUEST_METHOD'] != 'POST') {
-                       $this->client_error(_('This method requires a POST.'), 400, $apidata['content-type']);
-                       return;
-               }
-
-               $user = $apidata['user'];
-               $source = $this->trimmed('source');      // Not supported by Twitter.
+class Twitapidirect_messagesAction extends TwitterapiAction
+{
+
+    function direct_messages($args, $apidata)
+    {
+        parent::handle($args);
+        return $this->show_messages($args, $apidata, 'received');
+    }
+
+    function sent($args, $apidata)
+    {
+        parent::handle($args);
+        return $this->show_messages($args, $apidata, 'sent');
+    }
+
+    function show_messages($args, $apidata, $type)
+    {
+
+        $user = $apidata['user'];
+
+        $count = $this->arg('count');
+        $since = $this->arg('since');
+        $since_id = $this->arg('since_id');
+        $before_id = $this->arg('before_id');
+
+        $page = $this->arg('page');
+
+        if (!$page) {
+            $page = 1;
+        }
+
+        if (!$count) {
+            $count = 20;
+        }
+
+        $message = new Message();
+
+        $title = null;
+        $subtitle = null;
+        $link = null;
+        $server = common_root_url();
+
+        if ($type == 'received') {
+            $message->to_profile = $user->id;
+            $title = sprintf(_("Direct messages to %s"), $user->nickname);
+            $subtitle = sprintf(_("All the direct messages sent to %s"), $user->nickname);
+            $link = $server . $user->nickname . '/inbox';
+        } else {
+            $message->from_profile = $user->id;
+            $title = _('Direct Messages You\'ve Sent');
+            $subtitle = sprintf(_("All the direct messages sent from %s"), $user->nickname);
+            $link = $server . $user->nickname . '/outbox';
+        }
+
+        if ($before_id) {
+            $message->whereAdd("id < $before_id");
+        }
+
+        if ($since_id) {
+            $message->whereAdd("id > $since_id");
+        }
+
+        $since = strtotime($this->arg('since'));
+
+        if ($since) {
+            $d = date('Y-m-d H:i:s', $since);
+            $message->whereAdd("created > '$d'");
+        }
+
+        $message->orderBy('created DESC, id DESC');
+        $message->limit((($page-1)*20), $count);
+        $message->find();
+
+        switch($apidata['content-type']) {
+         case 'xml':
+            $this->show_xml_dmsgs($message);
+            break;
+         case 'rss':
+            $this->show_rss_dmsgs($message, $title, $link, $subtitle);
+            break;
+         case 'atom':
+            $this->show_atom_dmsgs($message, $title, $link, $subtitle);
+            break;
+         case 'json':
+            $this->show_json_dmsgs($message);
+            break;
+         default:
+            common_user_error(_('API method not found!'), $code = 404);
+        }
+
+    }
+
+    // had to change this from "new" to "create" to avoid PHP reserved word
+    function create($args, $apidata)
+    {
+        parent::handle($args);
+
+        if ($_SERVER['REQUEST_METHOD'] != 'POST') {
+            $this->client_error(_('This method requires a POST.'), 400, $apidata['content-type']);
+            return;
+        }
+
+        $user = $apidata['user'];
+        $source = $this->trimmed('source');     // Not supported by Twitter.
 
         $reserved_sources = array('web', 'omb', 'mail', 'xmpp', 'api');
-               if (!$source || in_array($source, $reserved_sources)) {
-                       $source = 'api';
-               }
-
-               $content = $this->trimmed('text');
-
-               if (!$content) {
-                       $this->client_error(_('No message text!'), $code = 406, $apidata['content-type']);
-               } else {
-                       $content_shortened = common_shorten_links($content);
-                       if (mb_strlen($content_shortened) > 140) {
-                               $this->client_error(_('That\'s too long. Max message size is 140 chars.'),
-                                       $code = 406, $apidata['content-type']);
-                               return;
-                       }
-               }
-
-               $other = $this->get_user($this->trimmed('user'));
-
-               if (!$other) {
-                       $this->client_error(_('Recipient user not found.'), $code = 403, $apidata['content-type']);
-                       return;
-               } else if (!$user->mutuallySubscribed($other)) {
-                       $this->client_error(_('Can\'t send direct messages to users who aren\'t your friend.'),
-                               $code = 403, $apidata['content-type']);
-                       return;
-               } else if ($user->id == $other->id) {
-                       // Sending msgs to yourself is allowed by Twitter
-                       $this->client_error(_('Don\'t send a message to yourself; just say it to yourself quietly instead.'),
-                               $code = 403, $apidata['content-type']);
-                       return;
-               }
-
-               $message = Message::saveNew($user->id, $other->id,
-                       html_entity_decode($content, ENT_NOQUOTES, 'UTF-8'), $source);
-
-               if (is_string($message)) {
-                       $this->server_error($message);
-                       return;
-               }
-
-               $this->notify($user, $other, $message);
-
-               if ($apidata['content-type'] == 'xml') {
-                       $this->show_single_xml_dmsg($message);
-               } elseif ($apidata['content-type'] == 'json') {
-                       $this->show_single_json_dmsg($message);
-               }
-
-       }
-
-       function destroy($args, $apidata) {
-               parent::handle($args);
-               common_server_error(_('API method under construction.'), $code=501);
-       }
-
-       function show_xml_dmsgs($message) {
-
-               $this->init_document('xml');
-               common_element_start('direct-messages', array('type' => 'array'));
-
-               if (is_array($messages)) {
-                       foreach ($message as $m) {
-                               $twitter_dm = $this->twitter_dmsg_array($m);
-                               $this->show_twitter_xml_dmsg($twitter_dm);
-                       }
-               } else {
-                       while ($message->fetch()) {
-                               $twitter_dm = $this->twitter_dmsg_array($message);
-                               $this->show_twitter_xml_dmsg($twitter_dm);
-                       }
-               }
-
-               common_element_end('direct-messages');
-               $this->end_document('xml');
-
-       }
-
-       function show_json_dmsgs($message) {
-
-               $this->init_document('json');
-
-               $dmsgs = array();
-
-               if (is_array($message)) {
-                       foreach ($message as $m) {
-                               $twitter_dm = $this->twitter_dmsg_array($m);
-                               array_push($dmsgs, $twitter_dm);
-                       }
-               } else {
-                       while ($message->fetch()) {
-                               $twitter_dm = $this->twitter_dmsg_array($message);
-                               array_push($dmsgs, $twitter_dm);
-                       }
-               }
-
-               $this->show_json_objects($dmsgs);
-               $this->end_document('json');
-
-       }
-
-       function show_rss_dmsgs($message, $title, $link, $subtitle) {
-
-               $this->init_document('rss');
-
-               common_element_start('channel');
-               common_element('title', NULL, $title);
-
-               common_element('link', NULL, $link);
-               common_element('description', NULL, $subtitle);
-               common_element('language', NULL, 'en-us');
-               common_element('ttl', NULL, '40');
-
-               if (is_array($message)) {
-                       foreach ($message as $m) {
-                               $entry = $this->twitter_rss_dmsg_array($m);
-                               $this->show_twitter_rss_item($entry);
-                       }
-               } else {
-                       while ($message->fetch()) {
-                               $entry = $this->twitter_rss_dmsg_array($message);
-                               $this->show_twitter_rss_item($entry);
-                       }
-               }
-
-               common_element_end('channel');
-               $this->end_twitter_rss();
-
-       }
-
-       function show_atom_dmsgs($message, $title, $link, $subtitle) {
-
-               $this->init_document('atom');
-
-               common_element('title', NULL, $title);
-               $siteserver = common_config('site', 'server');
-               common_element('id', NULL, "tag:$siteserver,2008:DirectMessage");
-               common_element('link', array('href' => $link, 'rel' => 'alternate', 'type' => 'text/html'), NULL);
-               common_element('updated', NULL, common_date_iso8601(strftime('%c')));
-               common_element('subtitle', NULL, $subtitle);
-
-               if (is_array($message)) {
-                       foreach ($message as $m) {
-                               $entry = $this->twitter_rss_dmsg_array($m);
-                               $this->show_twitter_atom_entry($entry);
-                       }
-               } else {
-                       while ($message->fetch()) {
-                               $entry = $this->twitter_rss_dmsg_array($message);
-                               $this->show_twitter_atom_entry($entry);
-                       }
-               }
-
-               $this->end_document('atom');
-       }
-
-       // swiped from MessageAction. Should it be place in util.php?
-       function notify($from, $to, $message) {
-               mail_notify_message($message, $from, $to);
-               # XXX: Jabber, SMS notifications... probably queued
-       }
+        if (!$source || in_array($source, $reserved_sources)) {
+            $source = 'api';
+        }
+
+        $content = $this->trimmed('text');
+
+        if (!$content) {
+            $this->client_error(_('No message text!'), $code = 406, $apidata['content-type']);
+        } else {
+            $content_shortened = common_shorten_links($content);
+            if (mb_strlen($content_shortened) > 140) {
+                $this->client_error(_('That\'s too long. Max message size is 140 chars.'),
+                    $code = 406, $apidata['content-type']);
+                return;
+            }
+        }
+
+        $other = $this->get_user($this->trimmed('user'));
+
+        if (!$other) {
+            $this->client_error(_('Recipient user not found.'), $code = 403, $apidata['content-type']);
+            return;
+        } else if (!$user->mutuallySubscribed($other)) {
+            $this->client_error(_('Can\'t send direct messages to users who aren\'t your friend.'),
+                $code = 403, $apidata['content-type']);
+            return;
+        } else if ($user->id == $other->id) {
+            // Sending msgs to yourself is allowed by Twitter
+            $this->client_error(_('Don\'t send a message to yourself; just say it to yourself quietly instead.'),
+                $code = 403, $apidata['content-type']);
+            return;
+        }
+
+        $message = Message::saveNew($user->id, $other->id,
+            html_entity_decode($content, ENT_NOQUOTES, 'UTF-8'), $source);
+
+        if (is_string($message)) {
+            $this->server_error($message);
+            return;
+        }
+
+        $this->notify($user, $other, $message);
+
+        if ($apidata['content-type'] == 'xml') {
+            $this->show_single_xml_dmsg($message);
+        } elseif ($apidata['content-type'] == 'json') {
+            $this->show_single_json_dmsg($message);
+        }
+
+    }
+
+    function destroy($args, $apidata)
+    {
+        parent::handle($args);
+        common_server_error(_('API method under construction.'), $code=501);
+    }
+
+    function show_xml_dmsgs($message)
+    {
+
+        $this->init_document('xml');
+        common_element_start('direct-messages', array('type' => 'array'));
+
+        if (is_array($messages)) {
+            foreach ($message as $m) {
+                $twitter_dm = $this->twitter_dmsg_array($m);
+                $this->show_twitter_xml_dmsg($twitter_dm);
+            }
+        } else {
+            while ($message->fetch()) {
+                $twitter_dm = $this->twitter_dmsg_array($message);
+                $this->show_twitter_xml_dmsg($twitter_dm);
+            }
+        }
+
+        common_element_end('direct-messages');
+        $this->end_document('xml');
+
+    }
+
+    function show_json_dmsgs($message)
+    {
+
+        $this->init_document('json');
+
+        $dmsgs = array();
+
+        if (is_array($message)) {
+            foreach ($message as $m) {
+                $twitter_dm = $this->twitter_dmsg_array($m);
+                array_push($dmsgs, $twitter_dm);
+            }
+        } else {
+            while ($message->fetch()) {
+                $twitter_dm = $this->twitter_dmsg_array($message);
+                array_push($dmsgs, $twitter_dm);
+            }
+        }
+
+        $this->show_json_objects($dmsgs);
+        $this->end_document('json');
+
+    }
+
+    function show_rss_dmsgs($message, $title, $link, $subtitle)
+    {
+
+        $this->init_document('rss');
+
+        common_element_start('channel');
+        common_element('title', null, $title);
+
+        common_element('link', null, $link);
+        common_element('description', null, $subtitle);
+        common_element('language', null, 'en-us');
+        common_element('ttl', null, '40');
+
+        if (is_array($message)) {
+            foreach ($message as $m) {
+                $entry = $this->twitter_rss_dmsg_array($m);
+                $this->show_twitter_rss_item($entry);
+            }
+        } else {
+            while ($message->fetch()) {
+                $entry = $this->twitter_rss_dmsg_array($message);
+                $this->show_twitter_rss_item($entry);
+            }
+        }
+
+        common_element_end('channel');
+        $this->end_twitter_rss();
+
+    }
+
+    function show_atom_dmsgs($message, $title, $link, $subtitle)
+    {
+
+        $this->init_document('atom');
+
+        common_element('title', null, $title);
+        $siteserver = common_config('site', 'server');
+        common_element('id', null, "tag:$siteserver,2008:DirectMessage");
+        common_element('link', array('href' => $link, 'rel' => 'alternate', 'type' => 'text/html'), null);
+        common_element('updated', null, common_date_iso8601(strftime('%c')));
+        common_element('subtitle', null, $subtitle);
+
+        if (is_array($message)) {
+            foreach ($message as $m) {
+                $entry = $this->twitter_rss_dmsg_array($m);
+                $this->show_twitter_atom_entry($entry);
+            }
+        } else {
+            while ($message->fetch()) {
+                $entry = $this->twitter_rss_dmsg_array($message);
+                $this->show_twitter_atom_entry($entry);
+            }
+        }
+
+        $this->end_document('atom');
+    }
+
+    // swiped from MessageAction. Should it be place in util.php?
+    function notify($from, $to, $message)
+    {
+        mail_notify_message($message, $from, $to);
+        # XXX: Jabber, SMS notifications... probably queued
+    }
 
 }
index 3eaff327a1c202d684106ad70876ce9fefb9e192..55e04732f526cc36a248b68e630b18e9d279338e 100644 (file)
@@ -21,155 +21,161 @@ if (!defined('LACONICA')) { exit(1); }
 
 require_once(INSTALLDIR.'/lib/twitterapi.php');
 
-class TwitapifavoritesAction extends TwitterapiAction {
-
-       function favorites($args, $apidata) {
-               parent::handle($args);
-
-               $this->auth_user = $apidata['user'];
-               $user = $this->get_user($apidata['api_arg'], $apidata);
-
-               if (!$user) {
-                       $this->client_error('Not Found', 404, $apidata['content-type']);
-                       return;
-               }
-
-               $profile = $user->getProfile();
-
-               if (!$profile) {
-                       common_server_error(_('User has no profile.'));
-                       return;
-               }
-
-               $page = $this->arg('page');
-
-               if (!$page) {
-                       $page = 1;
-               }
-
-               if (!$count) {
-                       $count = 20;
-               }
-
-               $notice = $user->favoriteNotices((($page-1)*20), $count);
-
-               if (!$notice) {
-                       common_server_error(_('Could not retrieve favorite notices.'));
-                       return;
-               }
-
-               $sitename = common_config('site', 'name');
-               $siteserver = common_config('site', 'server');
-
-               $title = sprintf(_('%s / Favorites from %s'), $sitename, $user->nickname);
-               $id = "tag:$siteserver:favorites:".$user->id;
-               $link = common_local_url('favorites', array('nickname' => $user->nickname));
-               $subtitle = sprintf(_('%s updates favorited by %s / %s.'), $sitename, $profile->getBestName(), $user->nickname);
-
-               switch($apidata['content-type']) {
-                case 'xml':
-                       $this->show_xml_timeline($notice);
-                       break;
-                case 'rss':
-                       $this->show_rss_timeline($notice, $title, $link, $subtitle);
-                       break;
-                case 'atom':
-                       $this->show_atom_timeline($notice, $title, $id, $link, $subtitle);
-                       break;
-                case 'json':
-                       $this->show_json_timeline($notice);
-                       break;
-                default:
-                       common_user_error(_('API method not found!'), $code = 404);
-               }
-
-       }
-
-       function create($args, $apidata) {
-               parent::handle($args);
-
-               // Check for RESTfulness
-               if (!in_array($_SERVER['REQUEST_METHOD'], array('POST', 'DELETE'))) {
-                       // XXX: Twitter just prints the err msg, no XML / JSON.
-                       $this->client_error(_('This method requires a POST or DELETE.'), 400, $apidata['content-type']);
-                       return;
-               }
-
-               if (!in_array($apidata['content-type'], array('xml', 'json'))) {
-                       common_user_error(_('API method not found!'), $code = 404);
-                       return;
-               }
-
-               $this->auth_user = $apidata['user'];
-               $user = $this->auth_user;
-               $notice_id = $apidata['api_arg'];
-               $notice = Notice::staticGet($notice_id);
-
-               if (!$notice) {
-                       $this->client_error(_('No status found with that ID.'), 404, $apidata['content-type']);
-                       return;
-               }
-
-               // XXX: Twitter lets you fave things repeatedly via api.
-               if ($user->hasFave($notice)) {
-                       $this->client_error(_('This notice is already a favorite!'), 403, $apidata['content-type']);
-                       return;
-               }
-
-               $fave = Fave::addNew($user, $notice);
-
-               if (!$fave) {
-                       common_server_error(_('Could not create favorite.'));
-                       return;
-               }
-
-               $this->notify($fave, $notice, $user);
-               $user->blowFavesCache();
-
-               if ($apidata['content-type'] == 'xml') {
-                       $this->show_single_xml_status($notice);
-               } elseif ($apidata['content-type'] == 'json') {
-                       $this->show_single_json_status($notice);
-               }
-
-       }
-
-       function destroy($args, $apidata) {
-               parent::handle($args);
-               common_server_error(_('API method under construction.'), $code=501);
-       }
-
-       // XXX: these two funcs swiped from faves.  Maybe put in util.php, or some common base class?
-
-       function notify($fave, $notice, $user) {
-           $other = User::staticGet('id', $notice->profile_id);
-               if ($other && $other->id != $user->id) {
-                       if ($other->email && $other->emailnotifyfav) {
-                               $this->notify_mail($other, $user, $notice);
-                       }
-                       # XXX: notify by IM
-                       # XXX: notify by SMS
-               }
-       }
-
-       function notify_mail($other, $user, $notice) {
-               $profile = $user->getProfile();
-               $bestname = $profile->getBestName();
-               $subject = sprintf(_('%s added your notice as a favorite'), $bestname);
-               $body = sprintf(_("%1\$s just added your notice from %2\$s as one of their favorites.\n\n" .
-                                                 "In case you forgot, you can see the text of your notice here:\n\n" .
-                                                 "%3\$s\n\n" .
-                                                 "You can see the list of %1\$s's favorites here:\n\n" .
-                                                 "%4\$s\n\n" .
-                                                 "Faithfully yours,\n" .
-                                                 "%5\$s\n"),
-                                               $bestname,
-                                               common_exact_date($notice->created),
-                                               common_local_url('shownotice', array('notice' => $notice->id)),
-                                               common_local_url('showfavorites', array('nickname' => $user->nickname)),
-                                               common_config('site', 'name'));
-
-               mail_to_user($other, $subject, $body);
-       }
+class TwitapifavoritesAction extends TwitterapiAction
+{
+
+    function favorites($args, $apidata)
+    {
+        parent::handle($args);
+
+        $this->auth_user = $apidata['user'];
+        $user = $this->get_user($apidata['api_arg'], $apidata);
+
+        if (!$user) {
+            $this->client_error('Not Found', 404, $apidata['content-type']);
+            return;
+        }
+
+        $profile = $user->getProfile();
+
+        if (!$profile) {
+            common_server_error(_('User has no profile.'));
+            return;
+        }
+
+        $page = $this->arg('page');
+
+        if (!$page) {
+            $page = 1;
+        }
+
+        if (!$count) {
+            $count = 20;
+        }
+
+        $notice = $user->favoriteNotices((($page-1)*20), $count);
+
+        if (!$notice) {
+            common_server_error(_('Could not retrieve favorite notices.'));
+            return;
+        }
+
+        $sitename = common_config('site', 'name');
+        $siteserver = common_config('site', 'server');
+
+        $title = sprintf(_('%s / Favorites from %s'), $sitename, $user->nickname);
+        $id = "tag:$siteserver:favorites:".$user->id;
+        $link = common_local_url('favorites', array('nickname' => $user->nickname));
+        $subtitle = sprintf(_('%s updates favorited by %s / %s.'), $sitename, $profile->getBestName(), $user->nickname);
+
+        switch($apidata['content-type']) {
+         case 'xml':
+            $this->show_xml_timeline($notice);
+            break;
+         case 'rss':
+            $this->show_rss_timeline($notice, $title, $link, $subtitle);
+            break;
+         case 'atom':
+            $this->show_atom_timeline($notice, $title, $id, $link, $subtitle);
+            break;
+         case 'json':
+            $this->show_json_timeline($notice);
+            break;
+         default:
+            common_user_error(_('API method not found!'), $code = 404);
+        }
+
+    }
+
+    function create($args, $apidata)
+    {
+        parent::handle($args);
+
+        // Check for RESTfulness
+        if (!in_array($_SERVER['REQUEST_METHOD'], array('POST', 'DELETE'))) {
+            // XXX: Twitter just prints the err msg, no XML / JSON.
+            $this->client_error(_('This method requires a POST or DELETE.'), 400, $apidata['content-type']);
+            return;
+        }
+
+        if (!in_array($apidata['content-type'], array('xml', 'json'))) {
+            common_user_error(_('API method not found!'), $code = 404);
+            return;
+        }
+
+        $this->auth_user = $apidata['user'];
+        $user = $this->auth_user;
+        $notice_id = $apidata['api_arg'];
+        $notice = Notice::staticGet($notice_id);
+
+        if (!$notice) {
+            $this->client_error(_('No status found with that ID.'), 404, $apidata['content-type']);
+            return;
+        }
+
+        // XXX: Twitter lets you fave things repeatedly via api.
+        if ($user->hasFave($notice)) {
+            $this->client_error(_('This notice is already a favorite!'), 403, $apidata['content-type']);
+            return;
+        }
+
+        $fave = Fave::addNew($user, $notice);
+
+        if (!$fave) {
+            common_server_error(_('Could not create favorite.'));
+            return;
+        }
+
+        $this->notify($fave, $notice, $user);
+        $user->blowFavesCache();
+
+        if ($apidata['content-type'] == 'xml') {
+            $this->show_single_xml_status($notice);
+        } elseif ($apidata['content-type'] == 'json') {
+            $this->show_single_json_status($notice);
+        }
+
+    }
+
+    function destroy($args, $apidata)
+    {
+        parent::handle($args);
+        common_server_error(_('API method under construction.'), $code=501);
+    }
+
+    // XXX: these two funcs swiped from faves.  Maybe put in util.php, or some common base class?
+
+    function notify($fave, $notice, $user)
+    {
+        $other = User::staticGet('id', $notice->profile_id);
+        if ($other && $other->id != $user->id) {
+            if ($other->email && $other->emailnotifyfav) {
+                $this->notify_mail($other, $user, $notice);
+            }
+            # XXX: notify by IM
+            # XXX: notify by SMS
+        }
+    }
+
+    function notify_mail($other, $user, $notice)
+    {
+        $profile = $user->getProfile();
+        $bestname = $profile->getBestName();
+        $subject = sprintf(_('%s added your notice as a favorite'), $bestname);
+        $body = sprintf(_("%1\$s just added your notice from %2\$s as one of their favorites.\n\n" .
+                          "In case you forgot, you can see the text of your notice here:\n\n" .
+                          "%3\$s\n\n" .
+                          "You can see the list of %1\$s's favorites here:\n\n" .
+                          "%4\$s\n\n" .
+                          "Faithfully yours,\n" .
+                          "%5\$s\n"),
+                        $bestname,
+                        common_exact_date($notice->created),
+                        common_local_url('shownotice', array('notice' => $notice->id)),
+                        common_local_url('showfavorites', array('nickname' => $user->nickname)),
+                        common_config('site', 'name'));
+
+        mail_to_user($other, $subject, $body);
+    }
 
 }
\ No newline at end of file
index e4b49cbe4a92529cc2c470b2779ec68dfa8b96f4..ba4afe441ee6504ca7f9b7e3a8606355e1d15ac4 100644 (file)
@@ -21,135 +21,139 @@ if (!defined('LACONICA')) { exit(1); }
 
 require_once(INSTALLDIR.'/lib/twitterapi.php');
 
-class TwitapifriendshipsAction extends TwitterapiAction {
+class TwitapifriendshipsAction extends TwitterapiAction
+{
 
-       function create($args, $apidata) {
-               parent::handle($args);
+    function create($args, $apidata)
+    {
+        parent::handle($args);
 
-               if ($_SERVER['REQUEST_METHOD'] != 'POST') {
-                       $this->client_error(_('This method requires a POST.'), 400, $apidata['content-type']);
-                       return;
-               }
+        if ($_SERVER['REQUEST_METHOD'] != 'POST') {
+            $this->client_error(_('This method requires a POST.'), 400, $apidata['content-type']);
+            return;
+        }
 
-               $id = $apidata['api_arg'];
+        $id = $apidata['api_arg'];
 
-               $other = $this->get_user($id);
+        $other = $this->get_user($id);
 
-               if (!$other) {
-                       $this->client_error(_('Could not follow user: User not found.'), 403, $apidata['content-type']);
-                       return;
-               }
+        if (!$other) {
+            $this->client_error(_('Could not follow user: User not found.'), 403, $apidata['content-type']);
+            return;
+        }
 
-               $user = $apidata['user'];
+        $user = $apidata['user'];
 
-               if ($user->isSubscribed($other)) {
-                       $errmsg = sprintf(_('Could not follow user: %s is already on your list.'), $other->nickname);
-                       $this->client_error($errmsg, 403, $apidata['content-type']);
-                       return;
-               }
+        if ($user->isSubscribed($other)) {
+            $errmsg = sprintf(_('Could not follow user: %s is already on your list.'), $other->nickname);
+            $this->client_error($errmsg, 403, $apidata['content-type']);
+            return;
+        }
 
-               $sub = new Subscription();
+        $sub = new Subscription();
 
-               $sub->query('BEGIN');
+        $sub->query('BEGIN');
 
-               $sub->subscriber = $user->id;
-               $sub->subscribed = $other->id;
-               $sub->created = DB_DataObject_Cast::dateTime(); # current time
+        $sub->subscriber = $user->id;
+        $sub->subscribed = $other->id;
+        $sub->created = DB_DataObject_Cast::dateTime(); # current time
 
-               $result = $sub->insert();
+        $result = $sub->insert();
 
-               if (!$result) {
-                       $errmsg = sprintf(_('Could not follow user: %s is already on your list.'), $other->nickname);
-                       $this->client_error($errmsg, 400, $apidata['content-type']);
-                       return;
-               }
+        if (!$result) {
+            $errmsg = sprintf(_('Could not follow user: %s is already on your list.'), $other->nickname);
+            $this->client_error($errmsg, 400, $apidata['content-type']);
+            return;
+        }
 
-               $sub->query('COMMIT');
+        $sub->query('COMMIT');
 
-               mail_subscribe_notify($other, $user);
+        mail_subscribe_notify($other, $user);
 
-               $type = $apidata['content-type'];
-               $this->init_document($type);
-               $this->show_profile($other, $type);
-               $this->end_document($type);
+        $type = $apidata['content-type'];
+        $this->init_document($type);
+        $this->show_profile($other, $type);
+        $this->end_document($type);
 
-       }
+    }
 
-       function destroy($args, $apidata) {
-               parent::handle($args);
+    function destroy($args, $apidata)
+    {
+        parent::handle($args);
 
-               if (!in_array($_SERVER['REQUEST_METHOD'], array('POST', 'DELETE'))) {
-                       $this->client_error(_('This method requires a POST or DELETE.'), 400, $apidata['content-type']);
-                       return;
-               }
+        if (!in_array($_SERVER['REQUEST_METHOD'], array('POST', 'DELETE'))) {
+            $this->client_error(_('This method requires a POST or DELETE.'), 400, $apidata['content-type']);
+            return;
+        }
 
-               $id = $apidata['api_arg'];
+        $id = $apidata['api_arg'];
 
-               # We can't subscribe to a remote person, but we can unsub
+        # We can't subscribe to a remote person, but we can unsub
 
-               $other = $this->get_profile($id);
-               $user = $apidata['user'];
+        $other = $this->get_profile($id);
+        $user = $apidata['user'];
 
-               $sub = new Subscription();
-               $sub->subscriber = $user->id;
-               $sub->subscribed = $other->id;
+        $sub = new Subscription();
+        $sub->subscriber = $user->id;
+        $sub->subscribed = $other->id;
 
-               if ($sub->find(TRUE)) {
-                       $sub->query('BEGIN');
-                       $sub->delete();
-                       $sub->query('COMMIT');
-               } else {
-                       $this->client_error(_('You are not friends with the specified user.'), 403, $apidata['content-type']);
-                       return;
-               }
+        if ($sub->find(true)) {
+            $sub->query('BEGIN');
+            $sub->delete();
+            $sub->query('COMMIT');
+        } else {
+            $this->client_error(_('You are not friends with the specified user.'), 403, $apidata['content-type']);
+            return;
+        }
 
-               $type = $apidata['content-type'];
-               $this->init_document($type);
-               $this->show_profile($other, $type);
-               $this->end_document($type);
+        $type = $apidata['content-type'];
+        $this->init_document($type);
+        $this->show_profile($other, $type);
+        $this->end_document($type);
 
-       }
+    }
 
-       function exists($args, $apidata) {
-               parent::handle($args);
+    function exists($args, $apidata)
+    {
+        parent::handle($args);
 
-               if (!in_array($apidata['content-type'], array('xml', 'json'))) {
-                       common_user_error(_('API method not found!'), $code = 404);
-                       return;
-               }
+        if (!in_array($apidata['content-type'], array('xml', 'json'))) {
+            common_user_error(_('API method not found!'), $code = 404);
+            return;
+        }
 
-               $user_a_id = $this->trimmed('user_a');
-               $user_b_id = $this->trimmed('user_b');
+        $user_a_id = $this->trimmed('user_a');
+        $user_b_id = $this->trimmed('user_b');
 
-               $user_a = $this->get_user($user_a_id);
-               $user_b = $this->get_user($user_b_id);
+        $user_a = $this->get_user($user_a_id);
+        $user_b = $this->get_user($user_b_id);
 
-               if (!$user_a || !$user_b) {
-                       $this->client_error(_('Two user ids or screen_names must be supplied.'), 400, $apidata['content-type']);
-                       return;
-               }
+        if (!$user_a || !$user_b) {
+            $this->client_error(_('Two user ids or screen_names must be supplied.'), 400, $apidata['content-type']);
+            return;
+        }
 
-               if ($user_a->isSubscribed($user_b)) {
-                       $result = 'true';
-               } else {
-                       $result = 'false';
-               }
-
-               switch ($apidata['content-type']) {
-                case 'xml':
-                       $this->init_document('xml');
-                       common_element('friends', NULL, $result);
-                       $this->end_document('xml');
-                       break;
-                case 'json':
-                       $this->init_document('json');
-                       print json_encode($result);
-                       $this->end_document('json');
-                       break;
-                default:
-                       break;
-               }
-
-       }
+        if ($user_a->isSubscribed($user_b)) {
+            $result = 'true';
+        } else {
+            $result = 'false';
+        }
+
+        switch ($apidata['content-type']) {
+         case 'xml':
+            $this->init_document('xml');
+            common_element('friends', null, $result);
+            $this->end_document('xml');
+            break;
+         case 'json':
+            $this->init_document('json');
+            print json_encode($result);
+            $this->end_document('json');
+            break;
+         default:
+            break;
+        }
+
+    }
 
 }
\ No newline at end of file
index c5d503e11864cadd33f23dacaa6cafe4dec17302..1b84cb11bb744df042716ea1fada5e51002619b7 100644 (file)
@@ -21,32 +21,35 @@ if (!defined('LACONICA')) { exit(1); }
 
 require_once(INSTALLDIR.'/lib/twitterapi.php');
 
-class TwitapihelpAction extends TwitterapiAction {
-
-       /* Returns the string "ok" in the requested format with a 200 OK HTTP status code.
-        * URL:http://identi.ca/api/help/test.format
-        * Formats: xml, json
-        */
-       function test($args, $apidata) {
-               parent::handle($args);
-
-               if ($apidata['content-type'] == 'xml') {
-                       $this->init_document('xml');
-                       common_element('ok', NULL, 'true');
-                       $this->end_document('xml');
-               } elseif ($apidata['content-type'] == 'json') {
-                       $this->init_document('json');
-                       print '"ok"';
-                       $this->end_document('json');
-               } else {
-                       common_user_error(_('API method not found!'), $code=404);
-               }
-
-       }
-
-       function downtime_schedule($args, $apidata) {
-               parent::handle($args);
-               common_server_error(_('API method under construction.'), $code=501);
-       }
+class TwitapihelpAction extends TwitterapiAction
+{
+
+    /* Returns the string "ok" in the requested format with a 200 OK HTTP status code.
+     * URL:http://identi.ca/api/help/test.format
+     * Formats: xml, json
+     */
+    function test($args, $apidata)
+    {
+        parent::handle($args);
+
+        if ($apidata['content-type'] == 'xml') {
+            $this->init_document('xml');
+            common_element('ok', null, 'true');
+            $this->end_document('xml');
+        } elseif ($apidata['content-type'] == 'json') {
+            $this->init_document('json');
+            print '"ok"';
+            $this->end_document('json');
+        } else {
+            common_user_error(_('API method not found!'), $code=404);
+        }
+
+    }
+
+    function downtime_schedule($args, $apidata)
+    {
+        parent::handle($args);
+        common_server_error(_('API method under construction.'), $code=501);
+    }
 
 }
\ No newline at end of file
diff --git a/actions/twitapilaconica.php b/actions/twitapilaconica.php
new file mode 100644 (file)
index 0000000..722423f
--- /dev/null
@@ -0,0 +1,174 @@
+<?php
+/**
+ * Laconica, the distributed open-source microblogging tool
+ *
+ * Laconica-only extensions to the Twitter-like API
+ *
+ * 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  Twitter
+ * @package   Laconica
+ * @author    Evan Prodromou <evan@controlyourself.ca>
+ * @copyright 2008 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/twitterapi.php';
+
+/**
+ * Laconica-specific API methods
+ *
+ * This class handles all /laconica/ API methods.
+ *
+ * @category  Twitter
+ * @package   Laconica
+ * @author    Evan Prodromou <evan@controlyourself.ca>
+ * @copyright 2008 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/
+ */
+
+class TwitapilaconicaAction extends TwitterapiAction
+{
+    /**
+     * A version stamp for the API
+     *
+     * Returns a version number for this version of Laconica, which
+     * should make things a bit easier for upgrades.
+     * URL: http://identi.ca/api/laconica/version.(xml|json)
+     * Formats: xml, json
+     *
+     * @param array $args    Web arguments
+     * @param array $apidata Twitter API data
+     *
+     * @return void
+     *
+     * @see ApiAction::process_command()
+     */
+
+    function version($args, $apidata)
+    {
+        parent::handle($args);
+        switch ($apidata['content-type']) {
+         case 'xml':
+            $this->init_document('xml');
+            common_element('version', null, LACONICA_VERSION);
+            $this->end_document('xml');
+            break;
+         case 'json':
+            $this->init_document('json');
+            print '"'.LACONICA_VERSION.'"';
+            $this->end_document('json');
+            break;
+         default:
+            $this->client_error(_('API method not found!'), $code=404);
+        }
+    }
+
+    /**
+     * Dump of configuration variables
+     *
+     * Gives a full dump of configuration variables for this instance
+     * of Laconica, minus variables that may be security-sensitive (like
+     * passwords).
+     * URL: http://identi.ca/api/laconica/config.(xml|json)
+     * Formats: xml, json
+     *
+     * @param array $args    Web arguments
+     * @param array $apidata Twitter API data
+     *
+     * @return void
+     *
+     * @see ApiAction::process_command()
+     */
+
+    function config($args, $apidata)
+    {
+        static $keys = array('site' => array('name', 'server', 'theme', 'path', 'fancy', 'language',
+                                             'email', 'broughtby', 'broughtbyurl', 'closed',
+                                             'inviteonly', 'private'),
+                             'license' => array('url', 'title', 'image'),
+                             'nickname' => array('featured'),
+                             'throttle' => array('enabled', 'count', 'timespan'),
+                             'xmpp' => array('enabled', 'server', 'user'));
+
+        parent::handle($args);
+
+        switch ($apidata['content-type']) {
+         case 'xml':
+            $this->init_document('xml');
+            common_element_start('config');
+            // XXX: check that all sections and settings are legal XML elements
+            foreach ($keys as $section => $settings) {
+                common_element_start($section);
+                foreach ($settings as $setting) {
+                    $value = common_config($section, $setting);
+                    if (is_array($value)) {
+                        $value = implode(',', $value);
+                    } else if ($value === false) {
+                        $value = 'false';
+                    } else if ($value === true) {
+                        $value = 'true';
+                    }
+                    common_element($setting, null, $value);
+                }
+                common_element_end($section);
+            }
+            common_element_end('config');
+            $this->end_document('xml');
+            break;
+         case 'json':
+            $result = array();
+            foreach ($keys as $section => $settings) {
+                $result[$section] = array();
+                foreach ($settings as $setting) {
+                    $result[$section][$setting] = common_config($section, $setting);
+                }
+            }
+            $this->init_document('json');
+            $this->show_json_objects($result);
+            $this->end_document('json');
+            break;
+         default:
+            $this->client_error(_('API method not found!'), $code=404);
+        }
+    }
+
+    /**
+     * WADL description of the API
+     *
+     * Gives a WADL description of the API provided by this version of the
+     * software.
+     *
+     * @param array $args    Web arguments
+     * @param array $apidata Twitter API data
+     *
+     * @return void
+     *
+     * @see ApiAction::process_command()
+     */
+
+    function wadl($args, $apidata)
+    {
+        parent::handle($args);
+        common_server_error(_('API method under construction.'), 501);
+    }
+}
index 8d93309a25a7149db9d18dcf19dda3451d5f8fa1..a19d652c3d71d7146a58e930c4c450543bdd995f 100644 (file)
@@ -22,16 +22,19 @@ if (!defined('LACONICA')) { exit(1); }
 require_once(INSTALLDIR.'/lib/twitterapi.php');
 
 # This naming convention looks real sick
-class TwitapinotificationsAction extends TwitterapiAction {
+class TwitapinotificationsAction extends TwitterapiAction
+{
 
-       function follow($args, $apidata) {
-               parent::handle($args);
-               common_server_error(_('API method under construction.'), $code=501);
-       }
+    function follow($args, $apidata)
+    {
+        parent::handle($args);
+        common_server_error(_('API method under construction.'), $code=501);
+    }
 
-       function leave($args, $apidata) {
-               parent::handle($args);
-               common_server_error(_('API method under construction.'), $code=501);
-       }
+    function leave($args, $apidata)
+    {
+        parent::handle($args);
+        common_server_error(_('API method under construction.'), $code=501);
+    }
 
 }
\ No newline at end of file
index 7b6598b108e8fc8d4d2d74173cf05f63bc20fb35..e629d5cc416d339df999fc9f66f2cd12a36a0db2 100644 (file)
@@ -21,543 +21,557 @@ if (!defined('LACONICA')) { exit(1); }
 
 require_once(INSTALLDIR.'/lib/twitterapi.php');
 
-class TwitapistatusesAction extends TwitterapiAction {
-
-       function public_timeline($args, $apidata) {
-               parent::handle($args);
-
-               $sitename = common_config('site', 'name');
-               $siteserver = common_config('site', 'server');
-               $title = sprintf(_("%s public timeline"), $sitename);
-               $id = "tag:$siteserver:Statuses";
-               $link = common_root_url();
-               $subtitle = sprintf(_("%s updates from everyone!"), $sitename);
-
-               // Number of public statuses to return by default -- Twitter sends 20
-               $MAX_PUBSTATUSES = 20;
-
-               // FIXME: To really live up to the spec we need to build a list
-               // of notices by users who have custom avatars, so fix this SQL -- Zach
-
-               $page = $this->arg('page');
-               $since_id = $this->arg('since_id');
-               $before_id = $this->arg('before_id');
-
-               // NOTE: page, since_id, and before_id are extensions to Twitter API -- TB
-               if (!$page) {
-                       $page = 1;
-               }
-               if (!$since_id) {
-                       $since_id = 0;
-               }
-               if (!$before_id) {
-                       $before_id = 0;
-               }
-
-               $since = strtotime($this->arg('since'));
-
-               $notice = Notice::publicStream((($page-1)*$MAX_PUBSTATUSES), $MAX_PUBSTATUSES, $since_id, $before_id, $since);
-
-               if ($notice) {
-
-                       switch($apidata['content-type']) {
-                               case 'xml':
-                                       $this->show_xml_timeline($notice);
-                                       break;
-                               case 'rss':
-                                       $this->show_rss_timeline($notice, $title, $link, $subtitle);
-                                       break;
-                               case 'atom':
-                                       $this->show_atom_timeline($notice, $title, $id, $link, $subtitle);
-                                       break;
-                               case 'json':
-                                       $this->show_json_timeline($notice);
-                                       break;
-                               default:
-                                       common_user_error(_('API method not found!'), $code = 404);
-                                       break;
-                       }
-
-               } else {
-                       common_server_error(_('Couldn\'t find any statuses.'), $code = 503);
-               }
-
-       }
-
-       function friends_timeline($args, $apidata) {
-               parent::handle($args);
-
-               $since = $this->arg('since');
-               $since_id = $this->arg('since_id');
-               $count = $this->arg('count');
-               $page = $this->arg('page');
-               $before_id = $this->arg('before_id');
-
-               if (!$page) {
-                       $page = 1;
-               }
-
-               if (!$count) {
-                       $count = 20;
-               }
-
-               if (!$since_id) {
-                       $since_id = 0;
-               }
-
-               // NOTE: before_id is an extension to Twitter API -- TB
-               if (!$before_id) {
-                       $before_id = 0;
-               }
-
-               $since = strtotime($this->arg('since'));
-
-               $user = $this->get_user(NULL, $apidata);
-               $this->auth_user = $user;
-
-               $profile = $user->getProfile();
-
-               $sitename = common_config('site', 'name');
-               $siteserver = common_config('site', 'server');
-
-               $title = sprintf(_("%s and friends"), $user->nickname);
-               $id = "tag:$siteserver:friends:" . $user->id;
-               $link = common_local_url('all', array('nickname' => $user->nickname));
-               $subtitle = sprintf(_('Updates from %1$s and friends on %2$s!'), $user->nickname, $sitename);
-
-               $notice = $user->noticesWithFriends(($page-1)*20, $count, $since_id, $before_id, $since);
-
-               switch($apidata['content-type']) {
-                case 'xml':
-                       $this->show_xml_timeline($notice);
-                       break;
-                case 'rss':
-                       $this->show_rss_timeline($notice, $title, $link, $subtitle);
-                       break;
-                case 'atom':
-                       $this->show_atom_timeline($notice, $title, $id, $link, $subtitle);
-                       break;
-                case 'json':
-                       $this->show_json_timeline($notice);
-                       break;
-                default:
-                       common_user_error(_('API method not found!'), $code = 404);
-               }
-
-       }
-
-       function user_timeline($args, $apidata) {
-               parent::handle($args);
-
-               $this->auth_user = $apidata['user'];
-               $user = $this->get_user($apidata['api_arg'], $apidata);
-
-               if (!$user) {
-                       $this->client_error('Not Found', 404, $apidata['content-type']);
-                       return;
-               }
-
-               $profile = $user->getProfile();
-
-               if (!$profile) {
-                       common_server_error(_('User has no profile.'));
-                       return;
-               }
-
-               $count = $this->arg('count');
-               $since = $this->arg('since');
-               $since_id = $this->arg('since_id');
-               $page = $this->arg('page');
-               $before_id = $this->arg('before_id');
-
-               if (!$page) {
-                       $page = 1;
-               }
-
-               if (!$count) {
-                       $count = 20;
-               }
-
-               if (!$since_id) {
-                       $since_id = 0;
-               }
-
-               // NOTE: before_id is an extensions to Twitter API -- TB
-               if (!$before_id) {
-                       $before_id = 0;
-               }
-
-               $since = strtotime($this->arg('since'));
-
-               $sitename = common_config('site', 'name');
-               $siteserver = common_config('site', 'server');
-
-               $title = sprintf(_("%s timeline"), $user->nickname);
-               $id = "tag:$siteserver:user:".$user->id;
-               $link = common_local_url('showstream', array('nickname' => $user->nickname));
-               $subtitle = sprintf(_('Updates from %1$s on %2$s!'), $user->nickname, $sitename);
-
-               # FriendFeed's SUP protocol
-               # Also added RSS and Atom feeds
-
-               $suplink = common_local_url('sup', NULL, $user->id);
-               header('X-SUP-ID: '.$suplink);
-
-               # XXX: since
-
-               $notice = $user->getNotices((($page-1)*20), $count, $since_id, $before_id, $since);
-
-               switch($apidata['content-type']) {
-                case 'xml':
-                       $this->show_xml_timeline($notice);
-                       break;
-                case 'rss':
-                       $this->show_rss_timeline($notice, $title, $link, $subtitle, $suplink);
-                       break;
-                case 'atom':
-                       $this->show_atom_timeline($notice, $title, $id, $link, $subtitle, $suplink);
-                       break;
-                case 'json':
-                       $this->show_json_timeline($notice);
-                       break;
-                default:
-                       common_user_error(_('API method not found!'), $code = 404);
-               }
-
-       }
-
-       function update($args, $apidata) {
-
-               parent::handle($args);
-
-               if (!in_array($apidata['content-type'], array('xml', 'json'))) {
-                       common_user_error(_('API method not found!'), $code = 404);
-                       return;
-               }
-
-               if ($_SERVER['REQUEST_METHOD'] != 'POST') {
-                       $this->client_error(_('This method requires a POST.'), 400, $apidata['content-type']);
-                       return;
-               }
-
-               $this->auth_user = $apidata['user'];
-               $user = $this->auth_user;
-               $status = $this->trimmed('status');
-               $source = $this->trimmed('source');
-               $in_reply_to_status_id = intval($this->trimmed('in_reply_to_status_id'));
+class TwitapistatusesAction extends TwitterapiAction
+{
+
+    function public_timeline($args, $apidata)
+    {
+        parent::handle($args);
+
+        $sitename = common_config('site', 'name');
+        $siteserver = common_config('site', 'server');
+        $title = sprintf(_("%s public timeline"), $sitename);
+        $id = "tag:$siteserver:Statuses";
+        $link = common_root_url();
+        $subtitle = sprintf(_("%s updates from everyone!"), $sitename);
+
+        // Number of public statuses to return by default -- Twitter sends 20
+        $MAX_PUBSTATUSES = 20;
+
+        // FIXME: To really live up to the spec we need to build a list
+        // of notices by users who have custom avatars, so fix this SQL -- Zach
+
+        $page = $this->arg('page');
+        $since_id = $this->arg('since_id');
+        $before_id = $this->arg('before_id');
+
+        // NOTE: page, since_id, and before_id are extensions to Twitter API -- TB
+        if (!$page) {
+            $page = 1;
+        }
+        if (!$since_id) {
+            $since_id = 0;
+        }
+        if (!$before_id) {
+            $before_id = 0;
+        }
+
+        $since = strtotime($this->arg('since'));
+
+        $notice = Notice::publicStream((($page-1)*$MAX_PUBSTATUSES), $MAX_PUBSTATUSES, $since_id, $before_id, $since);
+
+        if ($notice) {
+
+            switch($apidata['content-type']) {
+                case 'xml':
+                    $this->show_xml_timeline($notice);
+                    break;
+                case 'rss':
+                    $this->show_rss_timeline($notice, $title, $link, $subtitle);
+                    break;
+                case 'atom':
+                    $this->show_atom_timeline($notice, $title, $id, $link, $subtitle);
+                    break;
+                case 'json':
+                    $this->show_json_timeline($notice);
+                    break;
+                default:
+                    common_user_error(_('API method not found!'), $code = 404);
+                    break;
+            }
+
+        } else {
+            common_server_error(_('Couldn\'t find any statuses.'), $code = 503);
+        }
+
+    }
+
+    function friends_timeline($args, $apidata)
+    {
+        parent::handle($args);
+
+        $since = $this->arg('since');
+        $since_id = $this->arg('since_id');
+        $count = $this->arg('count');
+        $page = $this->arg('page');
+        $before_id = $this->arg('before_id');
+
+        if (!$page) {
+            $page = 1;
+        }
+
+        if (!$count) {
+            $count = 20;
+        }
+
+        if (!$since_id) {
+            $since_id = 0;
+        }
+
+        // NOTE: before_id is an extension to Twitter API -- TB
+        if (!$before_id) {
+            $before_id = 0;
+        }
+
+        $since = strtotime($this->arg('since'));
+
+        $user = $this->get_user(null, $apidata);
+        $this->auth_user = $user;
+
+        $profile = $user->getProfile();
+
+        $sitename = common_config('site', 'name');
+        $siteserver = common_config('site', 'server');
+
+        $title = sprintf(_("%s and friends"), $user->nickname);
+        $id = "tag:$siteserver:friends:" . $user->id;
+        $link = common_local_url('all', array('nickname' => $user->nickname));
+        $subtitle = sprintf(_('Updates from %1$s and friends on %2$s!'), $user->nickname, $sitename);
+
+        $notice = $user->noticesWithFriends(($page-1)*20, $count, $since_id, $before_id, $since);
+
+        switch($apidata['content-type']) {
+         case 'xml':
+            $this->show_xml_timeline($notice);
+            break;
+         case 'rss':
+            $this->show_rss_timeline($notice, $title, $link, $subtitle);
+            break;
+         case 'atom':
+            $this->show_atom_timeline($notice, $title, $id, $link, $subtitle);
+            break;
+         case 'json':
+            $this->show_json_timeline($notice);
+            break;
+         default:
+            common_user_error(_('API method not found!'), $code = 404);
+        }
+
+    }
+
+    function user_timeline($args, $apidata)
+    {
+        parent::handle($args);
+
+        $this->auth_user = $apidata['user'];
+        $user = $this->get_user($apidata['api_arg'], $apidata);
+
+        if (!$user) {
+            $this->client_error('Not Found', 404, $apidata['content-type']);
+            return;
+        }
+
+        $profile = $user->getProfile();
+
+        if (!$profile) {
+            common_server_error(_('User has no profile.'));
+            return;
+        }
+
+        $count = $this->arg('count');
+        $since = $this->arg('since');
+        $since_id = $this->arg('since_id');
+        $page = $this->arg('page');
+        $before_id = $this->arg('before_id');
+
+        if (!$page) {
+            $page = 1;
+        }
+
+        if (!$count) {
+            $count = 20;
+        }
+
+        if (!$since_id) {
+            $since_id = 0;
+        }
+
+        // NOTE: before_id is an extensions to Twitter API -- TB
+        if (!$before_id) {
+            $before_id = 0;
+        }
+
+        $since = strtotime($this->arg('since'));
+
+        $sitename = common_config('site', 'name');
+        $siteserver = common_config('site', 'server');
+
+        $title = sprintf(_("%s timeline"), $user->nickname);
+        $id = "tag:$siteserver:user:".$user->id;
+        $link = common_local_url('showstream', array('nickname' => $user->nickname));
+        $subtitle = sprintf(_('Updates from %1$s on %2$s!'), $user->nickname, $sitename);
+
+        # FriendFeed's SUP protocol
+        # Also added RSS and Atom feeds
+
+        $suplink = common_local_url('sup', null, $user->id);
+        header('X-SUP-ID: '.$suplink);
+
+        # XXX: since
+
+        $notice = $user->getNotices((($page-1)*20), $count, $since_id, $before_id, $since);
+
+        switch($apidata['content-type']) {
+         case 'xml':
+            $this->show_xml_timeline($notice);
+            break;
+         case 'rss':
+            $this->show_rss_timeline($notice, $title, $link, $subtitle, $suplink);
+            break;
+         case 'atom':
+            $this->show_atom_timeline($notice, $title, $id, $link, $subtitle, $suplink);
+            break;
+         case 'json':
+            $this->show_json_timeline($notice);
+            break;
+         default:
+            common_user_error(_('API method not found!'), $code = 404);
+        }
+
+    }
+
+    function update($args, $apidata)
+    {
+
+        parent::handle($args);
+
+        if (!in_array($apidata['content-type'], array('xml', 'json'))) {
+            common_user_error(_('API method not found!'), $code = 404);
+            return;
+        }
+
+        if ($_SERVER['REQUEST_METHOD'] != 'POST') {
+            $this->client_error(_('This method requires a POST.'), 400, $apidata['content-type']);
+            return;
+        }
+
+        $this->auth_user = $apidata['user'];
+        $user = $this->auth_user;
+        $status = $this->trimmed('status');
+        $source = $this->trimmed('source');
+        $in_reply_to_status_id = intval($this->trimmed('in_reply_to_status_id'));
         $reserved_sources = array('web', 'omb', 'mail', 'xmpp', 'api');
-               if (!$source || in_array($source, $reserved_sources)) {
-                       $source = 'api';
-               }
+        if (!$source || in_array($source, $reserved_sources)) {
+            $source = 'api';
+        }
 
-               if (!$status) {
+        if (!$status) {
 
-                       // XXX: Note: In this case, Twitter simply returns '200 OK'
-                       // No error is given, but the status is not posted to the
-                       // user's timeline.      Seems bad.      Shouldn't we throw an
-                       // errror? -- Zach
-                       return;
+            // XXX: Note: In this case, Twitter simply returns '200 OK'
+            // No error is given, but the status is not posted to the
+            // user's timeline.     Seems bad.     Shouldn't we throw an
+            // errror? -- Zach
+            return;
 
-               } else {
+        } else {
 
-                       $status_shortened = common_shorten_links($status);
+            $status_shortened = common_shorten_links($status);
 
-                       if (mb_strlen($status_shortened) > 140) {
+            if (mb_strlen($status_shortened) > 140) {
 
-                               // XXX: Twitter truncates anything over 140, flags the status
-                               // as "truncated." Sending this error may screw up some clients
-                               // that assume Twitter will truncate for them.  Should we just
-                               // truncate too? -- Zach
-                               $this->client_error(_('That\'s too long. Max notice size is 140 chars.'), $code = 406, $apidata['content-type']);
-                               return;
+                // XXX: Twitter truncates anything over 140, flags the status
+                // as "truncated." Sending this error may screw up some clients
+                // that assume Twitter will truncate for them.    Should we just
+                // truncate too? -- Zach
+                $this->client_error(_('That\'s too long. Max notice size is 140 chars.'), $code = 406, $apidata['content-type']);
+                return;
 
-                       }
-               }
+            }
+        }
 
-               // Check for commands
-               $inter = new CommandInterpreter();
-               $cmd = $inter->handle_command($user, $status_shortened);
+        // Check for commands
+        $inter = new CommandInterpreter();
+        $cmd = $inter->handle_command($user, $status_shortened);
 
-               if ($cmd) {
+        if ($cmd) {
 
-                       if ($this->supported($cmd)) {
-                               $cmd->execute(new Channel());
-                       }
-
-                       // cmd not supported?  Twitter just returns your latest status.
-                       // And, it returns your last status whether the cmd was successful
-                       // or not!
-                       $n = $user->getCurrentNotice();
-                       $apidata['api_arg'] = $n->id;
-               } else {
+            if ($this->supported($cmd)) {
+                $cmd->execute(new Channel());
+            }
+
+            // cmd not supported?  Twitter just returns your latest status.
+            // And, it returns your last status whether the cmd was successful
+            // or not!
+            $n = $user->getCurrentNotice();
+            $apidata['api_arg'] = $n->id;
+        } else {
+
+            $reply_to = null;
 
-                       $reply_to = NULL;
-
-                       if ($in_reply_to_status_id) {
-
-                               // check whether notice actually exists
-                               $reply = Notice::staticGet($in_reply_to_status_id);
-
-                               if ($reply) {
-                                       $reply_to = $in_reply_to_status_id;
-                               } else {
-                                       $this->client_error(_('Not found'), $code = 404, $apidata['content-type']);
-                                       return;
-                               }
-                       }
-
-                       $notice = Notice::saveNew($user->id, html_entity_decode($status, ENT_NOQUOTES, 'UTF-8'),
-                               $source, 1, $reply_to);
-
-                       if (is_string($notice)) {
-                               $this->server_error($notice);
-                               return;
-                       }
-
-                       common_broadcast_notice($notice);
-                       $apidata['api_arg'] = $notice->id;
-               }
-
-               $this->show($args, $apidata);
-       }
-
-       function replies($args, $apidata) {
-
-               parent::handle($args);
-
-               $since = $this->arg('since');
-               $count = $this->arg('count');
-               $page = $this->arg('page');
-               $since_id = $this->arg('since_id');
-               $before_id = $this->arg('before_id');
-
-               $this->auth_user = $apidata['user'];
-               $user = $this->auth_user;
-               $profile = $user->getProfile();
-
-               $sitename = common_config('site', 'name');
-               $siteserver = common_config('site', 'server');
-
-               $title = sprintf(_('%1$s / Updates replying to %2$s'), $sitename, $user->nickname);
-               $id = "tag:$siteserver:replies:".$user->id;
-               $link = common_local_url('replies', array('nickname' => $user->nickname));
-               $subtitle = sprintf(_('%1$s updates that reply to updates from %2$s / %3$s.'), $sitename, $user->nickname, $profile->getBestName());
-
-               if (!$page) {
-                       $page = 1;
-               }
-
-               if (!$count) {
-                       $count = 20;
-               }
-
-               if (!$since_id) {
-                       $since_id = 0;
-               }
-
-               // NOTE: before_id is an extension to Twitter API -- TB
-               if (!$before_id) {
-                       $before_id = 0;
-               }
-
-               $since = strtotime($this->arg('since'));
-
-               $notice = $user->getReplies((($page-1)*20), $count, $since_id, $before_id, $since);
-               $notices = array();
-
-               while ($notice->fetch()) {
-                       $notices[] = clone($notice);
-               }
-
-               switch($apidata['content-type']) {
-                case 'xml':
-                       $this->show_xml_timeline($notices);
-                       break;
-                case 'rss':
-                       $this->show_rss_timeline($notices, $title, $link, $subtitle);
-                       break;
-                case 'atom':
-                       $this->show_atom_timeline($notices, $title, $id, $link, $subtitle);
-                       break;
-                case 'json':
-                       $this->show_json_timeline($notices);
-                       break;
-                default:
-                       common_user_error(_('API method not found!'), $code = 404);
-               }
-
-       }
-
-       function show($args, $apidata) {
-               parent::handle($args);
-
-               if (!in_array($apidata['content-type'], array('xml', 'json'))) {
-                       common_user_error(_('API method not found!'), $code = 404);
-                       return;
-               }
-
-               $this->auth_user = $apidata['user'];
-               $notice_id = $apidata['api_arg'];
-               $notice = Notice::staticGet($notice_id);
-
-               if ($notice) {
-                       if ($apidata['content-type'] == 'xml') {
-                               $this->show_single_xml_status($notice);
-                       } elseif ($apidata['content-type'] == 'json') {
-                               $this->show_single_json_status($notice);
-                       }
-               } else {
-                       // XXX: Twitter just sets a 404 header and doens't bother to return an err msg
-                       $this->client_error(_('No status with that ID found.'), 404, $apidata['content-type']);
-               }
-
-       }
-
-       function destroy($args, $apidata) {
-
-               parent::handle($args);
-
-               if (!in_array($apidata['content-type'], array('xml', 'json'))) {
-                       common_user_error(_('API method not found!'), $code = 404);
-                       return;
-               }
-
-               // Check for RESTfulness
-               if (!in_array($_SERVER['REQUEST_METHOD'], array('POST', 'DELETE'))) {
-                       // XXX: Twitter just prints the err msg, no XML / JSON.
-                       $this->client_error(_('This method requires a POST or DELETE.'), 400, $apidata['content-type']);
-                       return;
-               }
-
-               $this->auth_user = $apidata['user'];
-               $user = $this->auth_user;
-               $notice_id = $apidata['api_arg'];
-               $notice = Notice::staticGet($notice_id);
-
-               if (!$notice) {
-                       $this->client_error(_('No status found with that ID.'), 404, $apidata['content-type']);
-                       return;
-               }
-
-               if ($user->id == $notice->profile_id) {
-                       $replies = new Reply;
-                       $replies->get('notice_id', $notice_id);
-                       common_dequeue_notice($notice);
-                       $replies->delete();
-                       $notice->delete();
-
-                       if ($apidata['content-type'] == 'xml') {
-                               $this->show_single_xml_status($notice);
-                       } elseif ($apidata['content-type'] == 'json') {
-                               $this->show_single_json_status($notice);
-                       }
-               } else {
-                       $this->client_error(_('You may not delete another user\'s status.'), 403, $apidata['content-type']);
-               }
-
-       }
-
-       function friends($args, $apidata) {
-               parent::handle($args);
-               return $this->subscriptions($apidata, 'subscribed', 'subscriber');
-       }
-
-       function followers($args, $apidata) {
-               parent::handle($args);
-
-               return $this->subscriptions($apidata, 'subscriber', 'subscribed');
-       }
-
-       function subscriptions($apidata, $other_attr, $user_attr) {
-
-               # XXX: lite
-
-               $this->auth_user = $apidate['user'];
-               $user = $this->get_user($apidata['api_arg'], $apidata);
-
-               if (!$user) {
-                       $this->client_error('Not Found', 404, $apidata['content-type']);
-                       return;
-               }
-
-               $page = $this->trimmed('page');
-
-               if (!$page || !is_numeric($page)) {
-                       $page = 1;
-               }
-
-               $profile = $user->getProfile();
-
-               if (!$profile) {
-                       common_server_error(_('User has no profile.'));
-                       return;
-               }
-
-               $sub = new Subscription();
-               $sub->$user_attr = $profile->id;
-
-               $since = strtotime($this->trimmed('since'));
-
-               if ($since) {
-                       $d = date('Y-m-d H:i:s', $since);
-                       $sub->whereAdd("created > '$d'");
-               }
-
-               $sub->orderBy('created DESC');
-               $sub->limit(($page-1)*100, 100);
-
-               $others = array();
-
-               if ($sub->find()) {
-                       while ($sub->fetch()) {
-                               $others[] = Profile::staticGet($sub->$other_attr);
-                       }
-               } else {
-                       // user has no followers
-               }
-
-               $type = $apidata['content-type'];
-
-               $this->init_document($type);
-               $this->show_profiles($others, $type);
-               $this->end_document($type);
-       }
-
-       function show_profiles($profiles, $type) {
-               switch ($type) {
-                case 'xml':
-                       common_element_start('users', array('type' => 'array'));
-                       foreach ($profiles as $profile) {
-                               $this->show_profile($profile);
-                       }
-                       common_element_end('users');
-                       break;
-                case 'json':
-                       $arrays = array();
-                       foreach ($profiles as $profile) {
-                               $arrays[] = $this->twitter_user_array($profile, true);
-                       }
-                       print json_encode($arrays);
-                       break;
-                default:
-                       $this->client_error(_('unsupported file type'));
-               }
-       }
-
-       function featured($args, $apidata) {
-               parent::handle($args);
-               common_server_error(_('API method under construction.'), $code=501);
-       }
-
-       function supported($cmd) {
-
-               $cmdlist = array('MessageCommand', 'SubCommand', 'UnsubCommand', 'FavCommand', 'OnCommand', 'OffCommand');
-
-               if (in_array(get_class($cmd), $cmdlist)) {
-                       return true;
-               }
-
-               return false;
-       }
+            if ($in_reply_to_status_id) {
+
+                // check whether notice actually exists
+                $reply = Notice::staticGet($in_reply_to_status_id);
+
+                if ($reply) {
+                    $reply_to = $in_reply_to_status_id;
+                } else {
+                    $this->client_error(_('Not found'), $code = 404, $apidata['content-type']);
+                    return;
+                }
+            }
+
+            $notice = Notice::saveNew($user->id, html_entity_decode($status, ENT_NOQUOTES, 'UTF-8'),
+                $source, 1, $reply_to);
+
+            if (is_string($notice)) {
+                $this->server_error($notice);
+                return;
+            }
+
+            common_broadcast_notice($notice);
+            $apidata['api_arg'] = $notice->id;
+        }
+
+        $this->show($args, $apidata);
+    }
+
+    function replies($args, $apidata)
+    {
+
+        parent::handle($args);
+
+        $since = $this->arg('since');
+        $count = $this->arg('count');
+        $page = $this->arg('page');
+        $since_id = $this->arg('since_id');
+        $before_id = $this->arg('before_id');
+
+        $this->auth_user = $apidata['user'];
+        $user = $this->auth_user;
+        $profile = $user->getProfile();
+
+        $sitename = common_config('site', 'name');
+        $siteserver = common_config('site', 'server');
+
+        $title = sprintf(_('%1$s / Updates replying to %2$s'), $sitename, $user->nickname);
+        $id = "tag:$siteserver:replies:".$user->id;
+        $link = common_local_url('replies', array('nickname' => $user->nickname));
+        $subtitle = sprintf(_('%1$s updates that reply to updates from %2$s / %3$s.'), $sitename, $user->nickname, $profile->getBestName());
+
+        if (!$page) {
+            $page = 1;
+        }
+
+        if (!$count) {
+            $count = 20;
+        }
+
+        if (!$since_id) {
+            $since_id = 0;
+        }
+
+        // NOTE: before_id is an extension to Twitter API -- TB
+        if (!$before_id) {
+            $before_id = 0;
+        }
+
+        $since = strtotime($this->arg('since'));
+
+        $notice = $user->getReplies((($page-1)*20), $count, $since_id, $before_id, $since);
+        $notices = array();
+
+        while ($notice->fetch()) {
+            $notices[] = clone($notice);
+        }
+
+        switch($apidata['content-type']) {
+         case 'xml':
+            $this->show_xml_timeline($notices);
+            break;
+         case 'rss':
+            $this->show_rss_timeline($notices, $title, $link, $subtitle);
+            break;
+         case 'atom':
+            $this->show_atom_timeline($notices, $title, $id, $link, $subtitle);
+            break;
+         case 'json':
+            $this->show_json_timeline($notices);
+            break;
+         default:
+            common_user_error(_('API method not found!'), $code = 404);
+        }
+
+    }
+
+    function show($args, $apidata)
+    {
+        parent::handle($args);
+
+        if (!in_array($apidata['content-type'], array('xml', 'json'))) {
+            common_user_error(_('API method not found!'), $code = 404);
+            return;
+        }
+
+        $this->auth_user = $apidata['user'];
+        $notice_id = $apidata['api_arg'];
+        $notice = Notice::staticGet($notice_id);
+
+        if ($notice) {
+            if ($apidata['content-type'] == 'xml') {
+                $this->show_single_xml_status($notice);
+            } elseif ($apidata['content-type'] == 'json') {
+                $this->show_single_json_status($notice);
+            }
+        } else {
+            // XXX: Twitter just sets a 404 header and doens't bother to return an err msg
+            $this->client_error(_('No status with that ID found.'), 404, $apidata['content-type']);
+        }
+
+    }
+
+    function destroy($args, $apidata)
+    {
+
+        parent::handle($args);
+
+        if (!in_array($apidata['content-type'], array('xml', 'json'))) {
+            common_user_error(_('API method not found!'), $code = 404);
+            return;
+        }
+
+        // Check for RESTfulness
+        if (!in_array($_SERVER['REQUEST_METHOD'], array('POST', 'DELETE'))) {
+            // XXX: Twitter just prints the err msg, no XML / JSON.
+            $this->client_error(_('This method requires a POST or DELETE.'), 400, $apidata['content-type']);
+            return;
+        }
+
+        $this->auth_user = $apidata['user'];
+        $user = $this->auth_user;
+        $notice_id = $apidata['api_arg'];
+        $notice = Notice::staticGet($notice_id);
+
+        if (!$notice) {
+            $this->client_error(_('No status found with that ID.'), 404, $apidata['content-type']);
+            return;
+        }
+
+        if ($user->id == $notice->profile_id) {
+            $replies = new Reply;
+            $replies->get('notice_id', $notice_id);
+            common_dequeue_notice($notice);
+            $replies->delete();
+            $notice->delete();
+
+            if ($apidata['content-type'] == 'xml') {
+                $this->show_single_xml_status($notice);
+            } elseif ($apidata['content-type'] == 'json') {
+                $this->show_single_json_status($notice);
+            }
+        } else {
+            $this->client_error(_('You may not delete another user\'s status.'), 403, $apidata['content-type']);
+        }
+
+    }
+
+    function friends($args, $apidata)
+    {
+        parent::handle($args);
+        return $this->subscriptions($apidata, 'subscribed', 'subscriber');
+    }
+
+    function followers($args, $apidata)
+    {
+        parent::handle($args);
+
+        return $this->subscriptions($apidata, 'subscriber', 'subscribed');
+    }
+
+    function subscriptions($apidata, $other_attr, $user_attr)
+    {
+
+        # XXX: lite
+
+        $this->auth_user = $apidate['user'];
+        $user = $this->get_user($apidata['api_arg'], $apidata);
+
+        if (!$user) {
+            $this->client_error('Not Found', 404, $apidata['content-type']);
+            return;
+        }
+
+        $page = $this->trimmed('page');
+
+        if (!$page || !is_numeric($page)) {
+            $page = 1;
+        }
+
+        $profile = $user->getProfile();
+
+        if (!$profile) {
+            common_server_error(_('User has no profile.'));
+            return;
+        }
+
+        $sub = new Subscription();
+        $sub->$user_attr = $profile->id;
+
+        $since = strtotime($this->trimmed('since'));
+
+        if ($since) {
+            $d = date('Y-m-d H:i:s', $since);
+            $sub->whereAdd("created > '$d'");
+        }
+
+        $sub->orderBy('created DESC');
+        $sub->limit(($page-1)*100, 100);
+
+        $others = array();
+
+        if ($sub->find()) {
+            while ($sub->fetch()) {
+                $others[] = Profile::staticGet($sub->$other_attr);
+            }
+        } else {
+            // user has no followers
+        }
+
+        $type = $apidata['content-type'];
+
+        $this->init_document($type);
+        $this->show_profiles($others, $type);
+        $this->end_document($type);
+    }
+
+    function show_profiles($profiles, $type)
+    {
+        switch ($type) {
+         case 'xml':
+            common_element_start('users', array('type' => 'array'));
+            foreach ($profiles as $profile) {
+                $this->show_profile($profile);
+            }
+            common_element_end('users');
+            break;
+         case 'json':
+            $arrays = array();
+            foreach ($profiles as $profile) {
+                $arrays[] = $this->twitter_user_array($profile, true);
+            }
+            print json_encode($arrays);
+            break;
+         default:
+            $this->client_error(_('unsupported file type'));
+        }
+    }
+
+    function featured($args, $apidata)
+    {
+        parent::handle($args);
+        common_server_error(_('API method under construction.'), $code=501);
+    }
+
+    function supported($cmd)
+    {
+
+        $cmdlist = array('MessageCommand', 'SubCommand', 'UnsubCommand', 'FavCommand', 'OnCommand', 'OffCommand');
+
+        if (in_array(get_class($cmd), $cmdlist)) {
+            return true;
+        }
+
+        return false;
+    }
 
 }
index 9e06efa64286976a5600c262bb303f7cdb34e980..409986985c2302fdb5028f973ed99c37e3d8fef6 100644 (file)
  *
  * 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
+ * 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/>.
+ * along with this program.     If not, see <http://www.gnu.org/licenses/>.
  */
 
 if (!defined('LACONICA')) { exit(1); }
 
 require_once(INSTALLDIR.'/lib/twitterapi.php');
 
-class TwitapiusersAction extends TwitterapiAction {
+class TwitapiusersAction extends TwitterapiAction
+{
 
-       function show($args, $apidata) {
-               parent::handle($args);
+    function show($args, $apidata)
+    {
+        parent::handle($args);
 
-               if (!in_array($apidata['content-type'], array('xml', 'json'))) {
-                       common_user_error(_('API method not found!'), $code = 404);
-                       return;
-               }
+        if (!in_array($apidata['content-type'], array('xml', 'json'))) {
+            common_user_error(_('API method not found!'), $code = 404);
+            return;
+        }
 
-               $user = null;
-               $email = $this->arg('email');
+        $user = null;
+        $email = $this->arg('email');
 
-               if ($email) {
-                       $user = User::staticGet('email', $email);
-               } elseif (isset($apidata['api_arg'])) {
-                       $user = $this->get_user($apidata['api_arg']);
-               }
+        if ($email) {
+            $user = User::staticGet('email', $email);
+        } elseif (isset($apidata['api_arg'])) {
+            $user = $this->get_user($apidata['api_arg']);
+        }
 
-               if (!$user) {
-                       // XXX: Twitter returns a random(?) user instead of throwing and err! -- Zach
-                       $this->client_error(_('Not found.'), 404, $apidata['content-type']);
-                       return;
-               }
+        if (!$user) {
+            // XXX: Twitter returns a random(?) user instead of throwing and err! -- Zach
+            $this->client_error(_('Not found.'), 404, $apidata['content-type']);
+            return;
+        }
 
-               $this->show_extended_profile($user, $apidata);
-       }
+        $this->show_extended_profile($user, $apidata);
+    }
 
 }
index ae3aff877837c80809d5bcf51ff2b18d21cfa965..d664273397b5d3e33be608aea971513fcc1ad8db 100644 (file)
@@ -23,356 +23,345 @@ require_once(INSTALLDIR.'/lib/settingsaction.php');
 
 define('SUBSCRIPTIONS', 80);
 
-class TwittersettingsAction extends SettingsAction {
+class TwittersettingsAction extends SettingsAction
+{
 
-       function get_instructions() {
-               return _('Add your Twitter account to automatically send your notices to Twitter, ' .
-                       'and subscribe to Twitter friends already here.');
-       }
+    function get_instructions()
+    {
+        return _('Add your Twitter account to automatically send your notices to Twitter, ' .
+            'and subscribe to Twitter friends already here.');
+    }
 
-       function show_form($msg=NULL, $success=false) {
-               $user = common_current_user();
-               $profile = $user->getProfile();
-               $fuser = NULL;
-               $flink = Foreign_link::getByUserID($user->id, 1); // 1 == Twitter
+    function show_form($msg=null, $success=false)
+    {
+        $user = common_current_user();
+        $profile = $user->getProfile();
+        $fuser = null;
+        $flink = Foreign_link::getByUserID($user->id, 1); // 1 == Twitter
 
-               if ($flink) {
-                       $fuser = $flink->getForeignUser();
-               }
+        if ($flink) {
+            $fuser = $flink->getForeignUser();
+        }
 
-               $this->form_header(_('Twitter settings'), $msg, $success);
-               common_element_start('form', array('method' => 'post',
-                                                                                  'id' => 'twittersettings',
-                                                                                  'action' =>
-                                                                                  common_local_url('twittersettings')));
-               common_hidden('token', common_session_token());
+        $this->form_header(_('Twitter settings'), $msg, $success);
+        common_element_start('form', array('method' => 'post',
+                                           'id' => 'twittersettings',
+                                           'action' =>
+                                           common_local_url('twittersettings')));
+        common_hidden('token', common_session_token());
 
-               common_element('h2', NULL, _('Twitter Account'));
+        common_element('h2', null, _('Twitter Account'));
 
-               if ($fuser) {
-                       common_element_start('p');
+        if ($fuser) {
+            common_element_start('p');
 
-                       common_element('span', 'twitter_user', $fuser->nickname);
-                       common_element('a', array('href' => $fuser->uri),  $fuser->uri);
-                       common_element('span', 'input_instructions',
-                                      _('Current verified Twitter account.'));
-                       common_hidden('flink_foreign_id', $flink->foreign_id);
-                       common_element_end('p');
-                       common_submit('remove', _('Remove'));
-               } else {
-                       common_input('twitter_username', _('Twitter user name'),
-                                                ($this->arg('twitter_username')) ? $this->arg('twitter_username') : $profile->nickname,
-                                                _('No spaces, please.')); // hey, it's what Twitter says
+            common_element('span', 'twitter_user', $fuser->nickname);
+            common_element('a', array('href' => $fuser->uri),  $fuser->uri);
+            common_element('span', 'input_instructions',
+                           _('Current verified Twitter account.'));
+            common_hidden('flink_foreign_id', $flink->foreign_id);
+            common_element_end('p');
+            common_submit('remove', _('Remove'));
+        } else {
+            common_input('twitter_username', _('Twitter user name'),
+                         ($this->arg('twitter_username')) ? $this->arg('twitter_username') : $profile->nickname,
+                         _('No spaces, please.')); // hey, it's what Twitter says
 
-                       common_password('twitter_password', _('Twitter password'));
-               }
+            common_password('twitter_password', _('Twitter password'));
+        }
 
-               common_element('h2', NULL, _('Preferences'));
+        common_element('h2', null, _('Preferences'));
 
-               common_checkbox('noticesync', _('Automatically send my notices to Twitter.'),
-                                               ($flink) ? ($flink->noticesync & FOREIGN_NOTICE_SEND) : true);
+        common_checkbox('noticesync', _('Automatically send my notices to Twitter.'),
+                        ($flink) ? ($flink->noticesync & FOREIGN_NOTICE_SEND) : true);
 
-               common_checkbox('replysync', _('Send local "@" replies to Twitter.'),
-                                               ($flink) ? ($flink->noticesync & FOREIGN_NOTICE_SEND_REPLY) : true);
+        common_checkbox('replysync', _('Send local "@" replies to Twitter.'),
+                        ($flink) ? ($flink->noticesync & FOREIGN_NOTICE_SEND_REPLY) : true);
 
-               common_checkbox('friendsync', _('Subscribe to my Twitter friends here.'),
-                                               ($flink) ? ($flink->friendsync & FOREIGN_FRIEND_RECV) : false);
+        common_checkbox('friendsync', _('Subscribe to my Twitter friends here.'),
+                        ($flink) ? ($flink->friendsync & FOREIGN_FRIEND_RECV) : false);
 
-               if ($flink) {
-                       common_submit('save', _('Save'));
-               } else {
-                       common_submit('add', _('Add'));
-               }
+        if ($flink) {
+            common_submit('save', _('Save'));
+        } else {
+            common_submit('add', _('Add'));
+        }
 
-               $this->show_twitter_subscriptions();
+        $this->show_twitter_subscriptions();
 
-               common_element_end('form');
+        common_element_end('form');
 
-               common_show_footer();
-       }
+        common_show_footer();
+    }
 
-       function subscribed_twitter_users() {
+    function subscribed_twitter_users()
+    {
 
-               $current_user = common_current_user();
+        $current_user = common_current_user();
+
+        $qry = 'SELECT user.* ' .
+            'FROM subscription ' .
+            'JOIN user ON subscription.subscribed = user.id ' .
+            'JOIN foreign_link ON foreign_link.user_id = user.id ' .
+            'WHERE subscriber = %d ' .
+            'ORDER BY user.nickname';
+
+        $user = new User();
+
+        $user->query(sprintf($qry, $current_user->id));
+
+        $users = array();
+
+        while ($user->fetch()) {
+
+            // Don't include the user's own self-subscription
+            if ($user->id != $current_user->id) {
+                $users[] = clone($user);
+            }
+        }
+
+        return $users;
+    }
+
+    function show_twitter_subscriptions()
+    {
+
+        $friends = $this->subscribed_twitter_users();
+        $friends_count = count($friends);
+
+        if ($friends_count > 0) {
+
+            common_element('h3', null, _('Twitter Friends'));
+            common_element_start('div', array('id' => 'subscriptions'));
+            common_element_start('ul', array('id' => 'subscriptions_avatars'));
+
+            for ($i = 0; $i < min($friends_count, SUBSCRIPTIONS); $i++) {
+
+                $other = Profile::staticGet($friends[$i]->id);
+
+                if (!$other) {
+                    common_log_db_error($subs, 'SELECT', __FILE__);
+                    continue;
+                }
+
+                common_element_start('li');
+                common_element_start('a', array('title' => ($other->fullname) ?
+                                                $other->fullname :
+                                                $other->nickname,
+                                                'href' => $other->profileurl,
+                                                'rel' => 'contact',
+                                                'class' => 'subscription'));
+                $avatar = $other->getAvatar(AVATAR_MINI_SIZE);
+                common_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 mini',
+                                            'alt' =>  ($other->fullname) ?
+                                            $other->fullname :
+                                            $other->nickname));
+                common_element_end('a');
+                common_element_end('li');
+
+            }
+
+            common_element_end('ul');
+            common_element_end('div');
 
-               $qry = 'SELECT user.* ' .
-                       'FROM subscription ' .
-                       'JOIN user ON subscription.subscribed = user.id ' .
-                       'JOIN foreign_link ON foreign_link.user_id = user.id ' .
-                       'WHERE subscriber = %d ' .
-                       'ORDER BY user.nickname';
+        }
 
-               $user = new User();
+        // XXX Figure out a way to show all Twitter friends... ?
 
-               $user->query(sprintf($qry, $current_user->id));
+        /*
+        if ($subs_count > SUBSCRIPTIONS) {
+            common_element_start('p', array('id' => 'subscriptions_viewall'));
 
-               $users = array();
+            common_element('a', array('href' => common_local_url('subscriptions',
+                                                                 array('nickname' => $profile->nickname)),
+                                      'class' => 'moresubscriptions'),
+                           _('All subscriptions'));
+            common_element_end('p');
+        }
+        */
+
+    }
+
+    function handle_post()
+    {
+
+        # CSRF protection
+        $token = $this->trimmed('token');
+        if (!$token || $token != common_session_token()) {
+            $this->show_form(_('There was a problem with your session token. Try again, please.'));
+            return;
+        }
+
+        if ($this->arg('save')) {
+            $this->save_preferences();
+        } else if ($this->arg('add')) {
+            $this->add_twitter_acct();
+        } else if ($this->arg('remove')) {
+            $this->remove_twitter_acct();
+        } else {
+            $this->show_form(_('Unexpected form submission.'));
+        }
+    }
+
+    function add_twitter_acct()
+    {
+
+        $screen_name = $this->trimmed('twitter_username');
+        $password = $this->trimmed('twitter_password');
+        $noticesync = $this->boolean('noticesync');
+        $replysync = $this->boolean('replysync');
+        $friendsync = $this->boolean('friendsync');
+
+        if (!Validate::string($screen_name,
+                array(    'min_length' => 1,
+                        'max_length' => 15,
+                         'format' => VALIDATE_NUM . VALIDATE_ALPHA . '_'))) {
+            $this->show_form(
+                _('Username must have only numbers, upper- and lowercase letters, and underscore (_). 15 chars max.'));
+            return;
+        }
+
+        if (!$this->verify_credentials($screen_name, $password)) {
+            $this->show_form(_('Could not verify your Twitter credentials!'));
+            return;
+        }
+
+        $twit_user = twitter_user_info($screen_name, $password);
+
+        if (!$twit_user) {
+            $this->show_form(sprintf(_('Unable to retrieve account information for "%s" from Twitter.'),
+                $screen_name));
+            return;
+        }
+
+        if (!save_twitter_user($twit_user->id, $screen_name)) {
+            $this->show_form(_('Unable to save your Twitter settings!'));
+            return;
+        }
+
+        $user = common_current_user();
+
+        $flink = DB_DataObject::factory('foreign_link');
+        $flink->user_id = $user->id;
+        $flink->foreign_id = $twit_user->id;
+        $flink->service = 1; // Twitter
+        $flink->credentials = $password;
+        $flink->created = common_sql_now();
+
+        $flink->set_flags($noticesync, $replysync, $friendsync);
+
+        $flink_id = $flink->insert();
+
+        if (!$flink_id) {
+            common_log_db_error($flink, 'INSERT', __FILE__);
+            $this->show_form(_('Unable to save your Twitter settings!'));
+            return;
+        }
 
-               while ($user->fetch()) {
+        if ($friendsync) {
+            save_twitter_friends($user, $twit_user->id, $screen_name, $password);
+        }
 
-                       // Don't include the user's own self-subscription
-                       if ($user->id != $current_user->id) {
-                               $users[] = clone($user);
-                       }
-               }
-
-               return $users;
-       }
-
-       function show_twitter_subscriptions() {
-
-               $friends = $this->subscribed_twitter_users();
-               $friends_count = count($friends);
-
-               if ($friends_count > 0) {
-
-                       common_element('h3', NULL, _('Twitter Friends'));
-                       common_element_start('div', array('id' => 'subscriptions'));
-                       common_element_start('ul', array('id' => 'subscriptions_avatars'));
-
-                       for ($i = 0; $i < min($friends_count, SUBSCRIPTIONS); $i++) {
-
-                               $other = Profile::staticGet($friends[$i]->id);
-
-                               if (!$other) {
-                                       common_log_db_error($subs, 'SELECT', __FILE__);
-                                       continue;
-                               }
-
-                               common_element_start('li');
-                               common_element_start('a', array('title' => ($other->fullname) ?
-                                                                                               $other->fullname :
-                                                                                               $other->nickname,
-                                                                                               'href' => $other->profileurl,
-                                                                                               'rel' => 'contact',
-                                                                                               'class' => 'subscription'));
-                               $avatar = $other->getAvatar(AVATAR_MINI_SIZE);
-                               common_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 mini',
-                                                                                       'alt' =>  ($other->fullname) ?
-                                                                                       $other->fullname :
-                                                                                       $other->nickname));
-                               common_element_end('a');
-                               common_element_end('li');
-
-                       }
+        $this->show_form(_('Twitter settings saved.'), true);
+    }
+
+    function remove_twitter_acct()
+    {
+
+        $user = common_current_user();
+        $flink = Foreign_link::getByUserID($user->id, 1);
+        $flink_foreign_id = $this->arg('flink_foreign_id');
+
+        # Maybe an old tab open...?
+        if ($flink->foreign_id != $flink_foreign_id) {
+            $this->show_form(_('That is not your Twitter account.'));
+            return;
+        }
 
-                       common_element_end('ul');
-                       common_element_end('div');
+        $result = $flink->delete();
 
-               }
+        if (!$result) {
+            common_log_db_error($flink, 'DELETE', __FILE__);
+            common_server_error(_('Couldn\'t remove Twitter user.'));
+            return;
+        }
+
+        $this->show_form(_('Twitter account removed.'), true);
+    }
+
+    function save_preferences()
+    {
 
-               // XXX Figure out a way to show all Twitter friends... ?
+        $noticesync = $this->boolean('noticesync');
+        $friendsync = $this->boolean('friendsync');
+        $replysync = $this->boolean('replysync');
 
-               /*
-               if ($subs_count > SUBSCRIPTIONS) {
-                       common_element_start('p', array('id' => 'subscriptions_viewall'));
+        $user = common_current_user();
 
-                       common_element('a', array('href' => common_local_url('subscriptions',
-                                                                                                                                array('nickname' => $profile->nickname)),
-                                                                         'class' => 'moresubscriptions'),
-                                                  _('All subscriptions'));
-                       common_element_end('p');
-               }
-               */
+        $flink = Foreign_link::getByUserID($user->id, 1);
 
-       }
-
-       function handle_post() {
+        if (!$flink) {
+            common_log_db_error($flink, 'SELECT', __FILE__);
+            $this->show_form(_('Couldn\'t save Twitter preferences.'));
+            return;
+        }
 
-               # CSRF protection
-               $token = $this->trimmed('token');
-               if (!$token || $token != common_session_token()) {
-                       $this->show_form(_('There was a problem with your session token. Try again, please.'));
-                       return;
-               }
-
-               if ($this->arg('save')) {
-                       $this->save_preferences();
-               } else if ($this->arg('add')) {
-                       $this->add_twitter_acct();
-               } else if ($this->arg('remove')) {
-                       $this->remove_twitter_acct();
-               } else {
-                       $this->show_form(_('Unexpected form submission.'));
-               }
-       }
+        $twitter_id = $flink->foreign_id;
+        $password = $flink->credentials;
 
-       function add_twitter_acct() {
+        $fuser = $flink->getForeignUser();
 
-               $screen_name = $this->trimmed('twitter_username');
-               $password = $this->trimmed('twitter_password');
-               $noticesync = $this->boolean('noticesync');
-               $replysync = $this->boolean('replysync');
-               $friendsync = $this->boolean('friendsync');
-
-               if (!Validate::string($screen_name,
-                               array(  'min_length' => 1,
-                                               'max_length' => 15,
-                                               'format' => VALIDATE_NUM . VALIDATE_ALPHA . '_'))) {
-                       $this->show_form(
-                               _('Username must have only numbers, upper- and lowercase letters, and underscore (_). 15 chars max.'));
-                       return;
-               }
-
-               if (!$this->verify_credentials($screen_name, $password)) {
-                       $this->show_form(_('Could not verify your Twitter credentials!'));
-                       return;
-               }
-
-               $twit_user = twitter_user_info($screen_name, $password);
-
-               if (!$twit_user) {
-                       $this->show_form(sprintf(_('Unable to retrieve account information for "%s" from Twitter.'),
-                               $screen_name));
-                       return;
-               }
-
-               if (!save_twitter_user($twit_user->id, $screen_name)) {
-                       $this->show_form(_('Unable to save your Twitter settings!'));
-                       return;
-               }
-
-               $user = common_current_user();
-
-               $flink = DB_DataObject::factory('foreign_link');
-               $flink->user_id = $user->id;
-               $flink->foreign_id = $twit_user->id;
-               $flink->service = 1; // Twitter
-               $flink->credentials = $password;
-               $flink->created = common_sql_now();
-
-               $this->set_flags($flink, $noticesync, $replysync, $friendsync);
-
-               $flink_id = $flink->insert();
-
-               if (!$flink_id) {
-                       common_log_db_error($flink, 'INSERT', __FILE__);
-                       $this->show_form(_('Unable to save your Twitter settings!'));
-                       return;
-               }
+        if (!$fuser) {
+            common_log_db_error($fuser, 'SELECT', __FILE__);
+            $this->show_form(_('Couldn\'t save Twitter preferences.'));
+            return;
+        }
 
-               if ($friendsync) {
-                       save_twitter_friends($user, $twit_user->id, $screen_name, $password);
-               }
+        $screen_name = $fuser->nickname;
 
-               $this->show_form(_('Twitter settings saved.'), true);
-       }
+        $original = clone($flink);
+        $flink->set_flags($noticesync, $replysync, $friendsync);
+        $result = $flink->update($original);
 
-       function remove_twitter_acct() {
-
-               $user = common_current_user();
-               $flink = Foreign_link::getByUserID($user->id, 1);
-               $flink_foreign_id = $this->arg('flink_foreign_id');
-
-               # Maybe an old tab open...?
-               if ($flink->foreign_id != $flink_foreign_id) {
-                   $this->show_form(_('That is not your Twitter account.'));
-                   return;
-               }
-
-               $result = $flink->delete();
-
-               if (!$result) {
-                       common_log_db_error($flink, 'DELETE', __FILE__);
-                       common_server_error(_('Couldn\'t remove Twitter user.'));
-                       return;
-               }
-
-               $this->show_form(_('Twitter account removed.'), TRUE);
-       }
-
-       function save_preferences() {
-
-               $noticesync = $this->boolean('noticesync');
-               $friendsync = $this->boolean('friendsync');
-               $replysync = $this->boolean('replysync');
-
-               $user = common_current_user();
-
-               $flink = Foreign_link::getByUserID($user->id, 1);
-
-               if (!$flink) {
-                       common_log_db_error($flink, 'SELECT', __FILE__);
-                       $this->show_form(_('Couldn\'t save Twitter preferences.'));
-                       return;
-               }
+        if ($result === false) {
+            common_log_db_error($flink, 'UPDATE', __FILE__);
+            $this->show_form(_('Couldn\'t save Twitter preferences.'));
+            return;
+        }
 
-               $twitter_id = $flink->foreign_id;
-               $password = $flink->credentials;
-
-               $fuser = $flink->getForeignUser();
+        if ($friendsync) {
+            save_twitter_friends($user, $flink->foreign_id, $screen_name, $password);
+        }
 
-               if (!$fuser) {
-                       common_log_db_error($fuser, 'SELECT', __FILE__);
-                       $this->show_form(_('Couldn\'t save Twitter preferences.'));
-                       return;
-               }
+        $this->show_form(_('Twitter preferences saved.'));
+    }
 
-               $screen_name = $fuser->nickname;
+    function verify_credentials($screen_name, $password)
+    {
+        $uri = 'http://twitter.com/account/verify_credentials.json';
+        $data = get_twitter_data($uri, $screen_name, $password);
 
-               $original = clone($flink);
-               $this->set_flags($flink, $noticesync, $replysync, $friendsync);
-               $result = $flink->update($original);
+        if (!$data) {
+            return false;
+        }
 
-               if ($result === FALSE) {
-                       common_log_db_error($flink, 'UPDATE', __FILE__);
-                       $this->show_form(_('Couldn\'t save Twitter preferences.'));
-                       return;
-               }
+        $user = json_decode($data);
 
-               if ($friendsync) {
-                       save_twitter_friends($user, $flink->foreign_id, $screen_name, $password);
-               }
+        if (!$user) {
+            return false;
+        }
 
-               $this->show_form(_('Twitter preferences saved.'));
-       }
+         $twitter_id = $user->status->id;
 
-       function verify_credentials($screen_name, $password) {
-               $uri = 'http://twitter.com/account/verify_credentials.json';
-               $data = get_twitter_data($uri, $screen_name, $password);
+        if ($twitter_id) {
+            return $twitter_id;
+        }
 
-               if (!$data) {
-                       return false;
-               }
+        return false;
+    }
 
-               $user = json_decode($data);
-
-               if (!$user) {
-                       return false;
-               }
-
-               $twitter_id = $user->status->id;
-
-               if ($twitter_id) {
-                       return $twitter_id;
-               }
-
-               return false;
-       }
-
-       function set_flags(&$flink, $noticesync, $replysync, $friendsync) {
-               if ($noticesync) {
-                       $flink->noticesync |= FOREIGN_NOTICE_SEND;
-               } else {
-                       $flink->noticesync &= ~FOREIGN_NOTICE_SEND;
-               }
-
-               if ($replysync) {
-                       $flink->noticesync |= FOREIGN_NOTICE_SEND_REPLY;
-               } else {
-                       $flink->noticesync &= ~FOREIGN_NOTICE_SEND_REPLY;
-               }
-
-               if ($friendsync) {
-                       $flink->friendsync |= FOREIGN_FRIEND_RECV;
-               } else {
-                       $flink->friendsync &= ~FOREIGN_FRIEND_RECV;
-               }
-
-               $flink->profilesync = 0;
-       }
 
 }
\ No newline at end of file
index d60cc7088595de49380f17a09635b989f58b2815..112304f71b41331d4aba4b6fb56f4b99b776a306 100644 (file)
 
 if (!defined('LACONICA')) { exit(1); }
 
-class UnblockAction extends Action {
+class UnblockAction extends Action
+{
 
-    var $profile = NULL;
+    var $profile = null;
 
-    function prepare($args) {
+    function prepare($args)
+    {
 
         parent::prepare($args);
 
@@ -32,12 +34,12 @@ class UnblockAction extends Action {
             return false;
         }
 
-               $token = $this->trimmed('token');
+        $token = $this->trimmed('token');
 
-               if (!$token || $token != common_session_token()) {
-                       $this->client_error(_('There was a problem with your session token. Try again, please.'));
-                       return;
-               }
+        if (!$token || $token != common_session_token()) {
+            $this->client_error(_('There was a problem with your session token. Try again, please.'));
+            return;
+        }
 
         $id = $this->trimmed('unblockto');
 
@@ -56,14 +58,16 @@ class UnblockAction extends Action {
         return true;
     }
 
-    function handle($args) {
+    function handle($args)
+    {
         parent::handle($args);
         if ($_SERVER['REQUEST_METHOD'] == 'POST') {
             $this->unblock_profile();
         }
     }
 
-    function unblock_profile() {
+    function unblock_profile()
+    {
 
         $cur = common_current_user();
 
index 98291e897ee198efeaf49b6cdcea811ca94ddc96..1c2e1363593cdf150201f74fd6d7bf486e7c5148 100644 (file)
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 
-class UnsubscribeAction extends Action {
+class UnsubscribeAction extends Action
+{
 
-       function handle($args) {
-               parent::handle($args);
-               if (!common_logged_in()) {
-                       common_user_error(_('Not logged in.'));
-                       return;
-               }
+    function handle($args)
+    {
+        parent::handle($args);
+        if (!common_logged_in()) {
+            common_user_error(_('Not logged in.'));
+            return;
+        }
 
-               $user = common_current_user();
+        $user = common_current_user();
 
-               if ($_SERVER['REQUEST_METHOD'] != 'POST') {
-                       common_redirect(common_local_url('subscriptions', array('nickname' => $user->nickname)));
-                       return;
-               }
+        if ($_SERVER['REQUEST_METHOD'] != 'POST') {
+            common_redirect(common_local_url('subscriptions', array('nickname' => $user->nickname)));
+            return;
+        }
 
-               # CSRF protection
+        # CSRF protection
 
-               $token = $this->trimmed('token');
+        $token = $this->trimmed('token');
 
-               if (!$token || $token != common_session_token()) {
-                       $this->client_error(_('There was a problem with your session token. Try again, please.'));
-                       return;
-               }
+        if (!$token || $token != common_session_token()) {
+            $this->client_error(_('There was a problem with your session token. Try again, please.'));
+            return;
+        }
 
-               $other_id = $this->arg('unsubscribeto');
+        $other_id = $this->arg('unsubscribeto');
 
         if (!$other_id) {
             $this->client_error(_('No profile id in request.'));
@@ -56,25 +58,25 @@ class UnsubscribeAction extends Action {
             return;
         }
 
-               $result = subs_unsubscribe_to($user, $other);
+        $result = subs_unsubscribe_to($user, $other);
 
-               if ($result != true) {
-                       common_user_error($result);
-                       return;
-               }
+        if ($result != true) {
+            common_user_error($result);
+            return;
+        }
 
-               if ($this->boolean('ajax')) {
-                       common_start_html('text/xml;charset=utf-8', true);
-                       common_element_start('head');
-                       common_element('title', null, _('Unsubscribed'));
-                       common_element_end('head');
-                       common_element_start('body');
-                       common_subscribe_form($other);
-                       common_element_end('body');
-                       common_element_end('html');
-               } else {
-               common_redirect(common_local_url('subscriptions', array('nickname' =>
-                                                                                                                               $user->nickname)));
+        if ($this->boolean('ajax')) {
+            common_start_html('text/xml;charset=utf-8', true);
+            common_element_start('head');
+            common_element('title', null, _('Unsubscribed'));
+            common_element_end('head');
+            common_element_start('body');
+            common_subscribe_form($other);
+            common_element_end('body');
+            common_element_end('html');
+        } else {
+            common_redirect(common_local_url('subscriptions', array('nickname' =>
+                                                                    $user->nickname)));
         }
-       }
+    }
 }
index 921e88e635408f54aa51495aa0723a172beec632..abb034c81e2974c9cf5f8319cd0b674fb886d85c 100644 (file)
@@ -21,154 +21,157 @@ if (!defined('LACONICA')) { exit(1); }
 
 require_once(INSTALLDIR.'/lib/omb.php');
 
-class UpdateprofileAction extends Action {
-       
-       function handle($args) {
-               parent::handle($args);
-               try {
-                       common_remove_magic_from_request();
-                       $req = OAuthRequest::from_request();
-                       # Note: server-to-server function!
-                       $server = omb_oauth_server();
-                       list($consumer, $token) = $server->verify_request($req);
-                       if ($this->update_profile($req, $consumer, $token)) {
-                               print "omb_version=".OMB_VERSION_01;
-                       }
-               } catch (OAuthException $e) {
-                       $this->server_error($e->getMessage());
-                       return;
-               }
-       }
+class UpdateprofileAction extends Action
+{
+    
+    function handle($args)
+    {
+        parent::handle($args);
+        try {
+            common_remove_magic_from_request();
+            $req = OAuthRequest::from_request();
+            # Note: server-to-server function!
+            $server = omb_oauth_server();
+            list($consumer, $token) = $server->verify_request($req);
+            if ($this->update_profile($req, $consumer, $token)) {
+                print "omb_version=".OMB_VERSION_01;
+            }
+        } catch (OAuthException $e) {
+            $this->server_error($e->getMessage());
+            return;
+        }
+    }
 
-       function update_profile($req, $consumer, $token) {
-               $version = $req->get_parameter('omb_version');
-               if ($version != OMB_VERSION_01) {
-                       $this->client_error(_('Unsupported OMB version'), 400);
-                       return false;
-               }
-               # First, check to see if listenee exists
-               $listenee =  $req->get_parameter('omb_listenee');
-               $remote = Remote_profile::staticGet('uri', $listenee);
-               if (!$remote) {
-                       $this->client_error(_('Profile unknown'), 404);
-                       return false;
-               }
-               # Second, check to see if they should be able to post updates!
-               # We see if there are any subscriptions to that remote user with
-               # the given token.
+    function update_profile($req, $consumer, $token)
+    {
+        $version = $req->get_parameter('omb_version');
+        if ($version != OMB_VERSION_01) {
+            $this->client_error(_('Unsupported OMB version'), 400);
+            return false;
+        }
+        # First, check to see if listenee exists
+        $listenee =  $req->get_parameter('omb_listenee');
+        $remote = Remote_profile::staticGet('uri', $listenee);
+        if (!$remote) {
+            $this->client_error(_('Profile unknown'), 404);
+            return false;
+        }
+        # Second, check to see if they should be able to post updates!
+        # We see if there are any subscriptions to that remote user with
+        # the given token.
 
-               $sub = new Subscription();
-               $sub->subscribed = $remote->id;
-               $sub->token = $token->key;
-               if (!$sub->find(true)) {
-                       $this->client_error(_('You did not send us that profile'), 403);
-                       return false;
-               }
+        $sub = new Subscription();
+        $sub->subscribed = $remote->id;
+        $sub->token = $token->key;
+        if (!$sub->find(true)) {
+            $this->client_error(_('You did not send us that profile'), 403);
+            return false;
+        }
 
-               $profile = Profile::staticGet('id', $remote->id);
-               if (!$profile) {
-                       # This one is our fault
-                       $this->server_error(_('Remote profile with no matching profile'), 500);
-                       return false;
-               }
-               $nickname = $req->get_parameter('omb_listenee_nickname');
-               if ($nickname && !Validate::string($nickname, array('min_length' => 1,
-                                                                                                                       'max_length' => 64,
-                                                                                                                       'format' => VALIDATE_NUM . VALIDATE_ALPHA_LOWER))) {
-                       $this->client_error(_('Nickname must have only lowercase letters and numbers and no spaces.'));
-                       return false;
-               }
-               $license = $req->get_parameter('omb_listenee_license');
-               if ($license && !common_valid_http_url($license)) {
-                       $this->client_error(sprintf(_("Invalid license URL '%s'"), $license));
-                       return false;
-               }
-               $profile_url = $req->get_parameter('omb_listenee_profile');
-               if ($profile_url && !common_valid_http_url($profile_url)) {
-                       $this->client_error(sprintf(_("Invalid profile URL '%s'."), $profile_url));
-                       return false;
-               }
-               # optional stuff
-               $fullname = $req->get_parameter('omb_listenee_fullname');
-               if ($fullname && strlen($fullname) > 255) {
-                       $this->client_error(_("Full name is too long (max 255 chars)."));
-                       return false;
-               }
-               $homepage = $req->get_parameter('omb_listenee_homepage');
-               if ($homepage && (!common_valid_http_url($homepage) || strlen($homepage) > 255)) {
-                       $this->client_error(sprintf(_("Invalid homepage '%s'"), $homepage));
-                       return false;
-               }
-               $bio = $req->get_parameter('omb_listenee_bio');
-               if ($bio && strlen($bio) > 140) {
-                       $this->client_error(_("Bio is too long (max 140 chars)."));
-                       return false;
-               }
-               $location = $req->get_parameter('omb_listenee_location');
-               if ($location && strlen($location) > 255) {
-                       $this->client_error(_("Location is too long (max 255 chars)."));
-                       return false;
-               }
-               $avatar = $req->get_parameter('omb_listenee_avatar');
-               if ($avatar) {
-                       if (!common_valid_http_url($avatar) || strlen($avatar) > 255) {
-                               $this->client_error(sprintf(_("Invalid avatar URL '%s'"), $avatar));
-                               return false;
-                       }
-                       $size = @getimagesize($avatar);
-                       if (!$size) {
-                               $this->client_error(sprintf(_("Can't read avatar URL '%s'"), $avatar));
-                               return false;
-                       }
-                       if ($size[0] != AVATAR_PROFILE_SIZE || $size[1] != AVATAR_PROFILE_SIZE) {
-                               $this->client_error(sprintf(_("Wrong size image at '%s'"), $avatar));
-                               return false;
-                       }
-                       if (!in_array($size[2], array(IMAGETYPE_GIF, IMAGETYPE_JPEG,
-                                                                                 IMAGETYPE_PNG))) {
-                               $this->client_error(sprintf(_("Wrong image type for '%s'"), $avatar));
-                               return false;
-                       }
-               }
+        $profile = Profile::staticGet('id', $remote->id);
+        if (!$profile) {
+            # This one is our fault
+            $this->server_error(_('Remote profile with no matching profile'), 500);
+            return false;
+        }
+        $nickname = $req->get_parameter('omb_listenee_nickname');
+        if ($nickname && !Validate::string($nickname, array('min_length' => 1,
+                                                            'max_length' => 64,
+                                                            'format' => VALIDATE_NUM . VALIDATE_ALPHA_LOWER))) {
+            $this->client_error(_('Nickname must have only lowercase letters and numbers and no spaces.'));
+            return false;
+        }
+        $license = $req->get_parameter('omb_listenee_license');
+        if ($license && !common_valid_http_url($license)) {
+            $this->client_error(sprintf(_("Invalid license URL '%s'"), $license));
+            return false;
+        }
+        $profile_url = $req->get_parameter('omb_listenee_profile');
+        if ($profile_url && !common_valid_http_url($profile_url)) {
+            $this->client_error(sprintf(_("Invalid profile URL '%s'."), $profile_url));
+            return false;
+        }
+        # optional stuff
+        $fullname = $req->get_parameter('omb_listenee_fullname');
+        if ($fullname && strlen($fullname) > 255) {
+            $this->client_error(_("Full name is too long (max 255 chars)."));
+            return false;
+        }
+        $homepage = $req->get_parameter('omb_listenee_homepage');
+        if ($homepage && (!common_valid_http_url($homepage) || strlen($homepage) > 255)) {
+            $this->client_error(sprintf(_("Invalid homepage '%s'"), $homepage));
+            return false;
+        }
+        $bio = $req->get_parameter('omb_listenee_bio');
+        if ($bio && strlen($bio) > 140) {
+            $this->client_error(_("Bio is too long (max 140 chars)."));
+            return false;
+        }
+        $location = $req->get_parameter('omb_listenee_location');
+        if ($location && strlen($location) > 255) {
+            $this->client_error(_("Location is too long (max 255 chars)."));
+            return false;
+        }
+        $avatar = $req->get_parameter('omb_listenee_avatar');
+        if ($avatar) {
+            if (!common_valid_http_url($avatar) || strlen($avatar) > 255) {
+                $this->client_error(sprintf(_("Invalid avatar URL '%s'"), $avatar));
+                return false;
+            }
+            $size = @getimagesize($avatar);
+            if (!$size) {
+                $this->client_error(sprintf(_("Can't read avatar URL '%s'"), $avatar));
+                return false;
+            }
+            if ($size[0] != AVATAR_PROFILE_SIZE || $size[1] != AVATAR_PROFILE_SIZE) {
+                $this->client_error(sprintf(_("Wrong size image at '%s'"), $avatar));
+                return false;
+            }
+            if (!in_array($size[2], array(IMAGETYPE_GIF, IMAGETYPE_JPEG,
+                                          IMAGETYPE_PNG))) {
+                $this->client_error(sprintf(_("Wrong image type for '%s'"), $avatar));
+                return false;
+            }
+        }
 
-               $orig_profile = clone($profile);
+        $orig_profile = clone($profile);
 
-               if ($nickname) {
-                       $profile->nickname = $nickname;
-               }
-               if ($profile_url) {
-                       $profile->profileurl = $profile_url;
-               }
-               if ($fullname) {
-                       $profile->fullname = $fullname;
-               }
-               if ($homepage) {
-                       $profile->homepage = $homepage;
-               }
-               if ($bio) {
-                       $profile->bio = $bio;
-               }
-               if ($location) {
-                       $profile->location = $location;
-               }
+        if ($nickname) {
+            $profile->nickname = $nickname;
+        }
+        if ($profile_url) {
+            $profile->profileurl = $profile_url;
+        }
+        if ($fullname) {
+            $profile->fullname = $fullname;
+        }
+        if ($homepage) {
+            $profile->homepage = $homepage;
+        }
+        if ($bio) {
+            $profile->bio = $bio;
+        }
+        if ($location) {
+            $profile->location = $location;
+        }
 
-               if (!$profile->update($orig_profile)) {
-                       $this->server_error(_('Could not save new profile info'), 500);
-                       return false;
-               } else {
-                       if ($avatar) {
-                               $temp_filename = tempnam(sys_get_temp_dir(), 'listenee_avatar');
-                               copy($avatar, $temp_filename);
-                               if (!$profile->setOriginal($temp_filename)) {
-                                       $this->server_error(_('Could not save avatar info'), 500);
-                                       return false;
-                               }
-                       }
-                       header('HTTP/1.1 200 OK');
-                       header('Content-type: text/plain');
-                       print 'Updated profile';
-                       print "\n";
-                       return true;
-               }
-       }
+        if (!$profile->update($orig_profile)) {
+            $this->server_error(_('Could not save new profile info'), 500);
+            return false;
+        } else {
+            if ($avatar) {
+                $temp_filename = tempnam(sys_get_temp_dir(), 'listenee_avatar');
+                copy($avatar, $temp_filename);
+                if (!$profile->setOriginal($temp_filename)) {
+                    $this->server_error(_('Could not save avatar info'), 500);
+                    return false;
+                }
+            }
+            header('HTTP/1.1 200 OK');
+            header('Content-type: text/plain');
+            print 'Updated profile';
+            print "\n";
+            return true;
+        }
+    }
 }
index ac0a0728cf29bec374f68ceede10408114aedebe..05efbc16c70ec7ef7d1f125044dde4415be3b58c 100644 (file)
@@ -22,558 +22,580 @@ if (!defined('LACONICA')) { exit(1); }
 require_once(INSTALLDIR.'/lib/omb.php');
 define('TIMESTAMP_THRESHOLD', 300);
 
-class UserauthorizationAction extends Action {
-
-       function handle($args) {
-               parent::handle($args);
-
-               if ($_SERVER['REQUEST_METHOD'] == 'POST') {
-                       # CSRF protection
-                       $token = $this->trimmed('token');
-                       if (!$token || $token != common_session_token()) {
-                               $req = $this->get_stored_request();
-                               $this->show_form(_('There was a problem with your session token. Try again, please.'), $req);
-                               return;
-                       }
-                       # We've shown the form, now post user's choice
-                       $this->send_authorization();
-               } else {
-                       if (!common_logged_in()) {
-                               # Go log in, and then come back
-                               common_debug('saving URL for returnto', __FILE__);
-                               common_set_returnto($_SERVER['REQUEST_URI']);
-
-                               common_debug('redirecting to login', __FILE__);
-                               common_redirect(common_local_url('login'));
-                               return;
-                       }
-                       try {
-                               # this must be a new request
-                               common_debug('getting new request', __FILE__);
-                               $req = $this->get_new_request();
-                               if (!$req) {
-                                       $this->client_error(_('No request found!'));
-                               }
-                               common_debug('validating request', __FILE__);
-                               # XXX: only validate new requests, since nonce is one-time use
-                               $this->validate_request($req);
-                               common_debug('showing form', __FILE__);
-                               $this->store_request($req);
-                               $this->show_form($req);
-                       } catch (OAuthException $e) {
-                               $this->clear_request();
-                               $this->client_error($e->getMessage());
-                               return;
-                       }
-
-               }
-       }
-
-       function show_form($req) {
-
-               $nickname = $req->get_parameter('omb_listenee_nickname');
-               $profile = $req->get_parameter('omb_listenee_profile');
-               $license = $req->get_parameter('omb_listenee_license');
-               $fullname = $req->get_parameter('omb_listenee_fullname');
-               $homepage = $req->get_parameter('omb_listenee_homepage');
-               $bio = $req->get_parameter('omb_listenee_bio');
-               $location = $req->get_parameter('omb_listenee_location');
-               $avatar = $req->get_parameter('omb_listenee_avatar');
-
-               common_show_header(_('Authorize subscription'));
-               common_element('p', NULL, _('Please check these details to make sure '.
-                                                                        'that you want to subscribe to this user\'s notices. '.
-                                                                        'If you didn\'t just ask to subscribe to someone\'s notices, '.
-                                                                        'click "Cancel".'));
-               common_element_start('div', 'profile');
-               if ($avatar) {
-                       common_element('img', array('src' => $avatar,
-                                                                               'class' => 'avatar profile',
-                                                                               'width' => AVATAR_PROFILE_SIZE,
-                                                                               'height' => AVATAR_PROFILE_SIZE,
-                                                                               'alt' => $nickname));
-               }
-               common_element('a', array('href' => $profile,
-                                                                 'class' => 'external profile nickname'),
-                                          $nickname);
-               if ($fullname) {
-                       common_element_start('div', 'fullname');
-                       if ($homepage) {
-                               common_element('a', array('href' => $homepage),
-                                                          $fullname);
-                       } else {
-                               common_text($fullname);
-                       }
-                       common_element_end('div');
-               }
-               if ($location) {
-                       common_element('div', 'location', $location);
-               }
-               if ($bio) {
-                       common_element('div', 'bio', $bio);
-               }
-               common_element_start('div', 'license');
-               common_element('a', array('href' => $license,
-                                                                 'class' => 'license'),
-                                          $license);
-               common_element_end('div');
-               common_element_end('div');
-               common_element_start('form', array('method' => 'post',
-                                                                                  'id' => 'userauthorization',
-                                                                                  'name' => 'userauthorization',
-                                                                                  'action' => common_local_url('userauthorization')));
-               common_hidden('token', common_session_token());
-               common_submit('accept', _('Accept'));
-               common_submit('reject', _('Reject'));
-               common_element_end('form');
-               common_show_footer();
-       }
-
-       function send_authorization() {
-               $req = $this->get_stored_request();
-
-               if (!$req) {
-                       common_user_error(_('No authorization request!'));
-                       return;
-               }
-
-               $callback = $req->get_parameter('oauth_callback');
-
-               if ($this->arg('accept')) {
-                       if (!$this->authorize_token($req)) {
-                               $this->client_error(_('Error authorizing token'));
-                       }
-                       if (!$this->save_remote_profile($req)) {
-                               $this->client_error(_('Error saving remote profile'));
-                       }
-                       if (!$callback) {
-                               $this->show_accept_message($req->get_parameter('oauth_token'));
-                       } else {
-                               $params = array();
-                               $params['oauth_token'] = $req->get_parameter('oauth_token');
-                               $params['omb_version'] = OMB_VERSION_01;
-                               $user = User::staticGet('uri', $req->get_parameter('omb_listener'));
-                               $profile = $user->getProfile();
-                               if (!$profile) {
-                                       common_log_db_error($user, 'SELECT', __FILE__);
-                                       $this->server_error(_('User without matching profile'));
-                                       return;
-                               }
-                               $params['omb_listener_nickname'] = $user->nickname;
-                               $params['omb_listener_profile'] = common_local_url('showstream',
-                                                                                                                                  array('nickname' => $user->nickname));
-                               if ($profile->fullname) {
-                                       $params['omb_listener_fullname'] = $profile->fullname;
-                               }
-                               if ($profile->homepage) {
-                                       $params['omb_listener_homepage'] = $profile->homepage;
-                               }
-                               if ($profile->bio) {
-                                       $params['omb_listener_bio'] = $profile->bio;
-                               }
-                               if ($profile->location) {
-                                       $params['omb_listener_location'] = $profile->location;
-                               }
-                               $avatar = $profile->getAvatar(AVATAR_PROFILE_SIZE);
-                               if ($avatar) {
-                                       $params['omb_listener_avatar'] = $avatar->url;
-                               }
-                               $parts = array();
-                               foreach ($params as $k => $v) {
-                                       $parts[] = $k . '=' . OAuthUtil::urlencodeRFC3986($v);
-                               }
-                               $query_string = implode('&', $parts);
-                               $parsed = parse_url($callback);
-                               $url = $callback . (($parsed['query']) ? '&' : '?') . $query_string;
-                               common_redirect($url, 303);
-                       }
-               } else {
-                       if (!$callback) {
-                               $this->show_reject_message();
-                       } else {
-                               # XXX: not 100% sure how to signal failure... just redirect without token?
-                               common_redirect($callback, 303);
-                       }
-               }
-       }
-
-       function authorize_token(&$req) {
-               $consumer_key = $req->get_parameter('oauth_consumer_key');
-               $token_field = $req->get_parameter('oauth_token');
-               common_debug('consumer key = "'.$consumer_key.'"', __FILE__);
-               common_debug('token field = "'.$token_field.'"', __FILE__);
-               $rt = new Token();
-               $rt->consumer_key = $consumer_key;
-               $rt->tok = $token_field;
-               $rt->type = 0;
-               $rt->state = 0;
-               common_debug('request token to look up: "'.print_r($rt,TRUE).'"');
-               if ($rt->find(true)) {
-                       common_debug('found request token to authorize', __FILE__);
-                       $orig_rt = clone($rt);
-                       $rt->state = 1; # Authorized but not used
-                       if ($rt->update($orig_rt)) {
-                               common_debug('updated request token so it is authorized', __FILE__);
-                               return true;
-                       }
-               }
-               return FALSE;
-       }
-
-       # XXX: refactor with similar code in finishremotesubscribe.php
-
-       function save_remote_profile(&$req) {
-               # FIXME: we should really do this when the consumer comes
-               # back for an access token. If they never do, we've got stuff in a
-               # weird state.
-
-               $nickname = $req->get_parameter('omb_listenee_nickname');
-               $fullname = $req->get_parameter('omb_listenee_fullname');
-               $profile_url = $req->get_parameter('omb_listenee_profile');
-               $homepage = $req->get_parameter('omb_listenee_homepage');
-               $bio = $req->get_parameter('omb_listenee_bio');
-               $location = $req->get_parameter('omb_listenee_location');
-               $avatar_url = $req->get_parameter('omb_listenee_avatar');
-
-               $listenee = $req->get_parameter('omb_listenee');
-               $remote = Remote_profile::staticGet('uri', $listenee);
-
-               if ($remote) {
-                       $exists = true;
-                       $profile = Profile::staticGet($remote->id);
-                       $orig_remote = clone($remote);
-                       $orig_profile = clone($profile);
-               } else {
-                       $exists = false;
-                       $remote = new Remote_profile();
-                       $remote->uri = $listenee;
-                       $profile = new Profile();
-               }
-
-               $profile->nickname = $nickname;
-               $profile->profileurl = $profile_url;
-
-               if ($fullname) {
-                       $profile->fullname = $fullname;
-               }
-               if ($homepage) {
-                       $profile->homepage = $homepage;
-               }
-               if ($bio) {
-                       $profile->bio = $bio;
-               }
-               if ($location) {
-                       $profile->location = $location;
-               }
-
-               if ($exists) {
-                       $profile->update($orig_profile);
-               } else {
-                       $profile->created = DB_DataObject_Cast::dateTime(); # current time
-                       $id = $profile->insert();
-                       if (!$id) {
-                               return FALSE;
-                       }
-                       $remote->id = $id;
-               }
-
-               if ($exists) {
-                       if (!$remote->update($orig_remote)) {
-                               return FALSE;
-                       }
-               } else {
-                       $remote->created = DB_DataObject_Cast::dateTime(); # current time
-                       if (!$remote->insert()) {
-                               return FALSE;
-                       }
-               }
-
-               if ($avatar_url) {
-                       if (!$this->add_avatar($profile, $avatar_url)) {
-                               return FALSE;
-                       }
-               }
-
-               $user = common_current_user();
-               $datastore = omb_oauth_datastore();
-               $consumer = $this->get_consumer($datastore, $req);
-               $token = $this->get_token($datastore, $req, $consumer);
-
-               $sub = new Subscription();
-               $sub->subscriber = $user->id;
-               $sub->subscribed = $remote->id;
-               $sub->token = $token->key; # NOTE: request token, not valid for use!
-               $sub->created = DB_DataObject_Cast::dateTime(); # current time
-
-               if (!$sub->insert()) {
-                       return FALSE;
-               }
-
-               return TRUE;
-       }
-
-       function add_avatar($profile, $url) {
-               $temp_filename = tempnam(sys_get_temp_dir(), 'listenee_avatar');
-               copy($url, $temp_filename);
-               return $profile->setOriginal($temp_filename);
-       }
-
-       function show_accept_message($tok) {
-               common_show_header(_('Subscription authorized'));
-               common_element('p', NULL,
-                                          _('The subscription has been authorized, but no '.
-                                                 'callback URL was passed. Check with the site\'s instructions for '.
-                                                 'details on how to authorize the subscription. Your subscription token is:'));
-               common_element('blockquote', 'token', $tok);
-               common_show_footer();
-       }
-
-       function show_reject_message($tok) {
-               common_show_header(_('Subscription rejected'));
-               common_element('p', NULL,
-                                          _('The subscription has been rejected, but no '.
-                                                 'callback URL was passed. Check with the site\'s instructions for '.
-                                                 'details on how to fully reject the subscription.'));
-               common_show_footer();
-       }
-
-       function store_request($req) {
-               common_ensure_session();
-               $_SESSION['userauthorizationrequest'] = $req;
-       }
-
-       function clear_request() {
-               common_ensure_session();
-               unset($_SESSION['userauthorizationrequest']);
-       }
-
-       function get_stored_request() {
-               common_ensure_session();
-               $req = $_SESSION['userauthorizationrequest'];
-               return $req;
-       }
-
-       function get_new_request() {
-               common_remove_magic_from_request();
-               $req = OAuthRequest::from_request();
-               return $req;
-       }
-
-       # Throws an OAuthException if anything goes wrong
-
-       function validate_request(&$req) {
-               # OAuth stuff -- have to copy from OAuth.php since they're
-               # all private methods, and there's no user-authentication method
-               common_debug('checking version', __FILE__);
-               $this->check_version($req);
-               common_debug('getting datastore', __FILE__);
-               $datastore = omb_oauth_datastore();
-               common_debug('getting consumer', __FILE__);
-               $consumer = $this->get_consumer($datastore, $req);
-               common_debug('getting token', __FILE__);
-               $token = $this->get_token($datastore, $req, $consumer);
-               common_debug('checking timestamp', __FILE__);
-               $this->check_timestamp($req);
-               common_debug('checking nonce', __FILE__);
-               $this->check_nonce($datastore, $req, $consumer, $token);
-               common_debug('checking signature', __FILE__);
-               $this->check_signature($req, $consumer, $token);
-               common_debug('validating omb stuff', __FILE__);
-               $this->validate_omb($req);
-               common_debug('done validating', __FILE__);
-               return true;
-       }
-
-       function validate_omb(&$req) {
-               foreach (array('omb_version', 'omb_listener', 'omb_listenee',
-                                          'omb_listenee_profile', 'omb_listenee_nickname',
-                                          'omb_listenee_license') as $param)
-               {
-                       if (!$req->get_parameter($param)) {
-                               throw new OAuthException("Required parameter '$param' not found");
-                       }
-               }
-               # Now, OMB stuff
-               $version = $req->get_parameter('omb_version');
-               if ($version != OMB_VERSION_01) {
-                       throw new OAuthException("OpenMicroBlogging version '$version' not supported");
-               }
-               $listener =     $req->get_parameter('omb_listener');
-               $user = User::staticGet('uri', $listener);
-               if (!$user) {
-                       throw new OAuthException("Listener URI '$listener' not found here");
-               }
-               $cur = common_current_user();
-               if ($cur->id != $user->id) {
-                       throw new OAuthException("Can't add for another user!");
-               }
-               $listenee = $req->get_parameter('omb_listenee');
-               if (!Validate::uri($listenee) &&
-                       !common_valid_tag($listenee)) {
-                       throw new OAuthException("Listenee URI '$listenee' not a recognizable URI");
-               }
-               if (strlen($listenee) > 255) {
-                       throw new OAuthException("Listenee URI '$listenee' too long");
-               }
-
-               $other = User::staticGet('uri', $listenee);
-               if ($other) {
-                       throw new OAuthException("Listenee URI '$listenee' is local user");
-               }
-
-               $remote = Remote_profile::staticGet('uri', $listenee);
-               if ($remote) {
-                       $sub = new Subscription();
-                       $sub->subscriber = $user->id;
-                       $sub->subscribed = $remote->id;
-                       if ($sub->find(TRUE)) {
-                               throw new OAuthException("Already subscribed to user!");
-                       }
-               }
-               $nickname = $req->get_parameter('omb_listenee_nickname');
-               if (!Validate::string($nickname, array('min_length' => 1,
-                                                                                          'max_length' => 64,
-                                                                                          'format' => VALIDATE_NUM . VALIDATE_ALPHA_LOWER))) {
-                       throw new OAuthException('Nickname must have only letters and numbers and no spaces.');
-               }
-               $profile = $req->get_parameter('omb_listenee_profile');
-               if (!common_valid_http_url($profile)) {
-                       throw new OAuthException("Invalid profile URL '$profile'.");
-               }
-
-               if ($profile == common_local_url('showstream', array('nickname' => $nickname))) {
-                       throw new OAuthException("Profile URL '$profile' is for a local user.");
-               }
-
-               $license = $req->get_parameter('omb_listenee_license');
-               if (!common_valid_http_url($license)) {
-                       throw new OAuthException("Invalid license URL '$license'.");
-               }
-               $site_license = common_config('license', 'url');
-               if (!common_compatible_license($license, $site_license)) {
-                       throw new OAuthException("Listenee stream license '$license' not compatible with site license '$site_license'.");
-               }
-               # optional stuff
-               $fullname = $req->get_parameter('omb_listenee_fullname');
-               if ($fullname && strlen($fullname) > 255) {
-                       throw new OAuthException("Full name '$fullname' too long.");
-               }
-               $homepage = $req->get_parameter('omb_listenee_homepage');
-               if ($homepage && (!common_valid_http_url($homepage) || strlen($homepage) > 255)) {
-                       throw new OAuthException("Invalid homepage '$homepage'");
-               }
-               $bio = $req->get_parameter('omb_listenee_bio');
-               if ($bio && strlen($bio) > 140) {
-                       throw new OAuthException("Bio too long '$bio'");
-               }
-               $location = $req->get_parameter('omb_listenee_location');
-               if ($location && strlen($location) > 255) {
-                       throw new OAuthException("Location too long '$location'");
-               }
-               $avatar = $req->get_parameter('omb_listenee_avatar');
-               if ($avatar) {
-                       if (!common_valid_http_url($avatar) || strlen($avatar) > 255) {
-                               throw new OAuthException("Invalid avatar URL '$avatar'");
-                       }
-                       $size = @getimagesize($avatar);
-                       if (!$size) {
-                               throw new OAuthException("Can't read avatar URL '$avatar'");
-                       }
-                       if ($size[0] != AVATAR_PROFILE_SIZE || $size[1] != AVATAR_PROFILE_SIZE) {
-                               throw new OAuthException("Wrong size image at '$avatar'");
-                       }
-                       if (!in_array($size[2], array(IMAGETYPE_GIF, IMAGETYPE_JPEG,
-                                                                                 IMAGETYPE_PNG))) {
-                               throw new OAuthException("Wrong image type for '$avatar'");
-                       }
-               }
-               $callback = $req->get_parameter('oauth_callback');
-               if ($callback && !common_valid_http_url($callback)) {
-                       throw new OAuthException("Invalid callback URL '$callback'");
-               }
-               if ($callback && $callback == common_local_url('finishremotesubscribe')) {
-                       throw new OAuthException("Callback URL '$callback' is for local site.");
-               }
-       }
-
-       # Snagged from OAuthServer
-
-       function check_version(&$req) {
-               $version = $req->get_parameter("oauth_version");
-               if (!$version) {
-                       $version = 1.0;
-               }
-               if ($version != 1.0) {
-                       throw new OAuthException("OAuth version '$version' not supported");
-               }
-               return $version;
-       }
-
-       # Snagged from OAuthServer
-
-       function get_consumer($datastore, $req) {
-               $consumer_key = @$req->get_parameter("oauth_consumer_key");
-               if (!$consumer_key) {
-                       throw new OAuthException("Invalid consumer key");
-               }
-
-               $consumer = $datastore->lookup_consumer($consumer_key);
-               if (!$consumer) {
-                       throw new OAuthException("Invalid consumer");
-               }
-               return $consumer;
-       }
-
-       # Mostly cadged from OAuthServer
-
-       function get_token($datastore, &$req, $consumer) {/*{{{*/
-               $token_field = @$req->get_parameter('oauth_token');
-               $token = $datastore->lookup_token($consumer, 'request', $token_field);
-               if (!$token) {
-                       throw new OAuthException("Invalid $token_type token: $token_field");
-               }
-               return $token;
-       }
-
-       function check_timestamp(&$req) {
-               $timestamp = @$req->get_parameter('oauth_timestamp');
-               $now = time();
-               if ($now - $timestamp > TIMESTAMP_THRESHOLD) {
-                       throw new OAuthException("Expired timestamp, yours $timestamp, ours $now");
-               }
-       }
-
-       # NOTE: don't call twice on the same request; will fail!
-       function check_nonce(&$datastore, &$req, $consumer, $token) {
-               $timestamp = @$req->get_parameter('oauth_timestamp');
-               $nonce = @$req->get_parameter('oauth_nonce');
-               $found = $datastore->lookup_nonce($consumer, $token, $nonce, $timestamp);
-               if ($found) {
-                       throw new OAuthException("Nonce already used");
-               }
-               return true;
-       }
-
-       function check_signature(&$req, $consumer, $token) {
-               $signature_method = $this->get_signature_method($req);
-               $signature = $req->get_parameter('oauth_signature');
-               $valid_sig = $signature_method->check_signature($req,
-                                                                                                               $consumer,
-                                                                                                               $token,
-                                                                                                               $signature);
-               if (!$valid_sig) {
-                       throw new OAuthException("Invalid signature");
-               }
-       }
-
-       function get_signature_method(&$req) {
-               $signature_method = @$req->get_parameter("oauth_signature_method");
-               if (!$signature_method) {
-                       $signature_method = "PLAINTEXT";
-               }
-               if ($signature_method != 'HMAC-SHA1') {
-                       throw new OAuthException("Signature method '$signature_method' not supported.");
-               }
-               return omb_hmac_sha1();
-       }
+class UserauthorizationAction extends Action
+{
+
+    function handle($args)
+    {
+        parent::handle($args);
+
+        if ($_SERVER['REQUEST_METHOD'] == 'POST') {
+            # CSRF protection
+            $token = $this->trimmed('token');
+            if (!$token || $token != common_session_token()) {
+                $req = $this->get_stored_request();
+                $this->show_form(_('There was a problem with your session token. Try again, please.'), $req);
+                return;
+            }
+            # We've shown the form, now post user's choice
+            $this->send_authorization();
+        } else {
+            if (!common_logged_in()) {
+                # Go log in, and then come back
+                common_debug('saving URL for returnto', __FILE__);
+                common_set_returnto($_SERVER['REQUEST_URI']);
+
+                common_debug('redirecting to login', __FILE__);
+                common_redirect(common_local_url('login'));
+                return;
+            }
+            try {
+                # this must be a new request
+                common_debug('getting new request', __FILE__);
+                $req = $this->get_new_request();
+                if (!$req) {
+                    $this->client_error(_('No request found!'));
+                }
+                common_debug('validating request', __FILE__);
+                # XXX: only validate new requests, since nonce is one-time use
+                $this->validate_request($req);
+                common_debug('showing form', __FILE__);
+                $this->store_request($req);
+                $this->show_form($req);
+            } catch (OAuthException $e) {
+                $this->clear_request();
+                $this->client_error($e->getMessage());
+                return;
+            }
+
+        }
+    }
+
+    function show_form($req)
+    {
+
+        $nickname = $req->get_parameter('omb_listenee_nickname');
+        $profile = $req->get_parameter('omb_listenee_profile');
+        $license = $req->get_parameter('omb_listenee_license');
+        $fullname = $req->get_parameter('omb_listenee_fullname');
+        $homepage = $req->get_parameter('omb_listenee_homepage');
+        $bio = $req->get_parameter('omb_listenee_bio');
+        $location = $req->get_parameter('omb_listenee_location');
+        $avatar = $req->get_parameter('omb_listenee_avatar');
+
+        common_show_header(_('Authorize subscription'));
+        common_element('p', null, _('Please check these details to make sure '.
+                                     'that you want to subscribe to this user\'s notices. '.
+                                     'If you didn\'t just ask to subscribe to someone\'s notices, '.
+                                     'click "Cancel".'));
+        common_element_start('div', 'profile');
+        if ($avatar) {
+            common_element('img', array('src' => $avatar,
+                                        'class' => 'avatar profile',
+                                        'width' => AVATAR_PROFILE_SIZE,
+                                        'height' => AVATAR_PROFILE_SIZE,
+                                        'alt' => $nickname));
+        }
+        common_element('a', array('href' => $profile,
+                                  'class' => 'external profile nickname'),
+                       $nickname);
+        if ($fullname) {
+            common_element_start('div', 'fullname');
+            if ($homepage) {
+                common_element('a', array('href' => $homepage),
+                               $fullname);
+            } else {
+                common_text($fullname);
+            }
+            common_element_end('div');
+        }
+        if ($location) {
+            common_element('div', 'location', $location);
+        }
+        if ($bio) {
+            common_element('div', 'bio', $bio);
+        }
+        common_element_start('div', 'license');
+        common_element('a', array('href' => $license,
+                                  'class' => 'license'),
+                       $license);
+        common_element_end('div');
+        common_element_end('div');
+        common_element_start('form', array('method' => 'post',
+                                           'id' => 'userauthorization',
+                                           'name' => 'userauthorization',
+                                           'action' => common_local_url('userauthorization')));
+        common_hidden('token', common_session_token());
+        common_submit('accept', _('Accept'));
+        common_submit('reject', _('Reject'));
+        common_element_end('form');
+        common_show_footer();
+    }
+
+    function send_authorization()
+    {
+        $req = $this->get_stored_request();
+
+        if (!$req) {
+            common_user_error(_('No authorization request!'));
+            return;
+        }
+
+        $callback = $req->get_parameter('oauth_callback');
+
+        if ($this->arg('accept')) {
+            if (!$this->authorize_token($req)) {
+                $this->client_error(_('Error authorizing token'));
+            }
+            if (!$this->save_remote_profile($req)) {
+                $this->client_error(_('Error saving remote profile'));
+            }
+            if (!$callback) {
+                $this->show_accept_message($req->get_parameter('oauth_token'));
+            } else {
+                $params = array();
+                $params['oauth_token'] = $req->get_parameter('oauth_token');
+                $params['omb_version'] = OMB_VERSION_01;
+                $user = User::staticGet('uri', $req->get_parameter('omb_listener'));
+                $profile = $user->getProfile();
+                if (!$profile) {
+                    common_log_db_error($user, 'SELECT', __FILE__);
+                    $this->server_error(_('User without matching profile'));
+                    return;
+                }
+                $params['omb_listener_nickname'] = $user->nickname;
+                $params['omb_listener_profile'] = common_local_url('showstream',
+                                                                   array('nickname' => $user->nickname));
+                if ($profile->fullname) {
+                    $params['omb_listener_fullname'] = $profile->fullname;
+                }
+                if ($profile->homepage) {
+                    $params['omb_listener_homepage'] = $profile->homepage;
+                }
+                if ($profile->bio) {
+                    $params['omb_listener_bio'] = $profile->bio;
+                }
+                if ($profile->location) {
+                    $params['omb_listener_location'] = $profile->location;
+                }
+                $avatar = $profile->getAvatar(AVATAR_PROFILE_SIZE);
+                if ($avatar) {
+                    $params['omb_listener_avatar'] = $avatar->url;
+                }
+                $parts = array();
+                foreach ($params as $k => $v) {
+                    $parts[] = $k . '=' . OAuthUtil::urlencodeRFC3986($v);
+                }
+                $query_string = implode('&', $parts);
+                $parsed = parse_url($callback);
+                $url = $callback . (($parsed['query']) ? '&' : '?') . $query_string;
+                common_redirect($url, 303);
+            }
+        } else {
+            if (!$callback) {
+                $this->show_reject_message();
+            } else {
+                # XXX: not 100% sure how to signal failure... just redirect without token?
+                common_redirect($callback, 303);
+            }
+        }
+    }
+
+    function authorize_token(&$req)
+    {
+        $consumer_key = $req->get_parameter('oauth_consumer_key');
+        $token_field = $req->get_parameter('oauth_token');
+        common_debug('consumer key = "'.$consumer_key.'"', __FILE__);
+        common_debug('token field = "'.$token_field.'"', __FILE__);
+        $rt = new Token();
+        $rt->consumer_key = $consumer_key;
+        $rt->tok = $token_field;
+        $rt->type = 0;
+        $rt->state = 0;
+        common_debug('request token to look up: "'.print_r($rt,true).'"');
+        if ($rt->find(true)) {
+            common_debug('found request token to authorize', __FILE__);
+            $orig_rt = clone($rt);
+            $rt->state = 1; # Authorized but not used
+            if ($rt->update($orig_rt)) {
+                common_debug('updated request token so it is authorized', __FILE__);
+                return true;
+            }
+        }
+        return false;
+    }
+
+    # XXX: refactor with similar code in finishremotesubscribe.php
+
+    function save_remote_profile(&$req)
+    {
+        # FIXME: we should really do this when the consumer comes
+        # back for an access token. If they never do, we've got stuff in a
+        # weird state.
+
+        $nickname = $req->get_parameter('omb_listenee_nickname');
+        $fullname = $req->get_parameter('omb_listenee_fullname');
+        $profile_url = $req->get_parameter('omb_listenee_profile');
+        $homepage = $req->get_parameter('omb_listenee_homepage');
+        $bio = $req->get_parameter('omb_listenee_bio');
+        $location = $req->get_parameter('omb_listenee_location');
+        $avatar_url = $req->get_parameter('omb_listenee_avatar');
+
+        $listenee = $req->get_parameter('omb_listenee');
+        $remote = Remote_profile::staticGet('uri', $listenee);
+
+        if ($remote) {
+            $exists = true;
+            $profile = Profile::staticGet($remote->id);
+            $orig_remote = clone($remote);
+            $orig_profile = clone($profile);
+        } else {
+            $exists = false;
+            $remote = new Remote_profile();
+            $remote->uri = $listenee;
+            $profile = new Profile();
+        }
+
+        $profile->nickname = $nickname;
+        $profile->profileurl = $profile_url;
+
+        if ($fullname) {
+            $profile->fullname = $fullname;
+        }
+        if ($homepage) {
+            $profile->homepage = $homepage;
+        }
+        if ($bio) {
+            $profile->bio = $bio;
+        }
+        if ($location) {
+            $profile->location = $location;
+        }
+
+        if ($exists) {
+            $profile->update($orig_profile);
+        } else {
+            $profile->created = DB_DataObject_Cast::dateTime(); # current time
+            $id = $profile->insert();
+            if (!$id) {
+                return false;
+            }
+            $remote->id = $id;
+        }
+
+        if ($exists) {
+            if (!$remote->update($orig_remote)) {
+                return false;
+            }
+        } else {
+            $remote->created = DB_DataObject_Cast::dateTime(); # current time
+            if (!$remote->insert()) {
+                return false;
+            }
+        }
+
+        if ($avatar_url) {
+            if (!$this->add_avatar($profile, $avatar_url)) {
+                return false;
+            }
+        }
+
+        $user = common_current_user();
+        $datastore = omb_oauth_datastore();
+        $consumer = $this->get_consumer($datastore, $req);
+        $token = $this->get_token($datastore, $req, $consumer);
+
+        $sub = new Subscription();
+        $sub->subscriber = $user->id;
+        $sub->subscribed = $remote->id;
+        $sub->token = $token->key; # NOTE: request token, not valid for use!
+        $sub->created = DB_DataObject_Cast::dateTime(); # current time
+
+        if (!$sub->insert()) {
+            return false;
+        }
+
+        return true;
+    }
+
+    function add_avatar($profile, $url)
+    {
+        $temp_filename = tempnam(sys_get_temp_dir(), 'listenee_avatar');
+        copy($url, $temp_filename);
+        return $profile->setOriginal($temp_filename);
+    }
+
+    function show_accept_message($tok)
+    {
+        common_show_header(_('Subscription authorized'));
+        common_element('p', null,
+                       _('The subscription has been authorized, but no '.
+                          'callback URL was passed. Check with the site\'s instructions for '.
+                          'details on how to authorize the subscription. Your subscription token is:'));
+        common_element('blockquote', 'token', $tok);
+        common_show_footer();
+    }
+
+    function show_reject_message($tok)
+    {
+        common_show_header(_('Subscription rejected'));
+        common_element('p', null,
+                       _('The subscription has been rejected, but no '.
+                          'callback URL was passed. Check with the site\'s instructions for '.
+                          'details on how to fully reject the subscription.'));
+        common_show_footer();
+    }
+
+    function store_request($req)
+    {
+        common_ensure_session();
+        $_SESSION['userauthorizationrequest'] = $req;
+    }
+
+    function clear_request()
+    {
+        common_ensure_session();
+        unset($_SESSION['userauthorizationrequest']);
+    }
+
+    function get_stored_request()
+    {
+        common_ensure_session();
+        $req = $_SESSION['userauthorizationrequest'];
+        return $req;
+    }
+
+    function get_new_request()
+    {
+        common_remove_magic_from_request();
+        $req = OAuthRequest::from_request();
+        return $req;
+    }
+
+    # Throws an OAuthException if anything goes wrong
+
+    function validate_request(&$req)
+    {
+        # OAuth stuff -- have to copy from OAuth.php since they're
+        # all private methods, and there's no user-authentication method
+        common_debug('checking version', __FILE__);
+        $this->check_version($req);
+        common_debug('getting datastore', __FILE__);
+        $datastore = omb_oauth_datastore();
+        common_debug('getting consumer', __FILE__);
+        $consumer = $this->get_consumer($datastore, $req);
+        common_debug('getting token', __FILE__);
+        $token = $this->get_token($datastore, $req, $consumer);
+        common_debug('checking timestamp', __FILE__);
+        $this->check_timestamp($req);
+        common_debug('checking nonce', __FILE__);
+        $this->check_nonce($datastore, $req, $consumer, $token);
+        common_debug('checking signature', __FILE__);
+        $this->check_signature($req, $consumer, $token);
+        common_debug('validating omb stuff', __FILE__);
+        $this->validate_omb($req);
+        common_debug('done validating', __FILE__);
+        return true;
+    }
+
+    function validate_omb(&$req)
+    {
+        foreach (array('omb_version', 'omb_listener', 'omb_listenee',
+                       'omb_listenee_profile', 'omb_listenee_nickname',
+                       'omb_listenee_license') as $param)
+        {
+            if (!$req->get_parameter($param)) {
+                throw new OAuthException("Required parameter '$param' not found");
+            }
+        }
+        # Now, OMB stuff
+        $version = $req->get_parameter('omb_version');
+        if ($version != OMB_VERSION_01) {
+            throw new OAuthException("OpenMicroBlogging version '$version' not supported");
+        }
+        $listener =    $req->get_parameter('omb_listener');
+        $user = User::staticGet('uri', $listener);
+        if (!$user) {
+            throw new OAuthException("Listener URI '$listener' not found here");
+        }
+        $cur = common_current_user();
+        if ($cur->id != $user->id) {
+            throw new OAuthException("Can't add for another user!");
+        }
+        $listenee = $req->get_parameter('omb_listenee');
+        if (!Validate::uri($listenee) &&
+            !common_valid_tag($listenee)) {
+            throw new OAuthException("Listenee URI '$listenee' not a recognizable URI");
+        }
+        if (strlen($listenee) > 255) {
+            throw new OAuthException("Listenee URI '$listenee' too long");
+        }
+
+        $other = User::staticGet('uri', $listenee);
+        if ($other) {
+            throw new OAuthException("Listenee URI '$listenee' is local user");
+        }
+
+        $remote = Remote_profile::staticGet('uri', $listenee);
+        if ($remote) {
+            $sub = new Subscription();
+            $sub->subscriber = $user->id;
+            $sub->subscribed = $remote->id;
+            if ($sub->find(true)) {
+                throw new OAuthException("Already subscribed to user!");
+            }
+        }
+        $nickname = $req->get_parameter('omb_listenee_nickname');
+        if (!Validate::string($nickname, array('min_length' => 1,
+                                               'max_length' => 64,
+                                               'format' => VALIDATE_NUM . VALIDATE_ALPHA_LOWER))) {
+            throw new OAuthException('Nickname must have only letters and numbers and no spaces.');
+        }
+        $profile = $req->get_parameter('omb_listenee_profile');
+        if (!common_valid_http_url($profile)) {
+            throw new OAuthException("Invalid profile URL '$profile'.");
+        }
+
+        if ($profile == common_local_url('showstream', array('nickname' => $nickname))) {
+            throw new OAuthException("Profile URL '$profile' is for a local user.");
+        }
+
+        $license = $req->get_parameter('omb_listenee_license');
+        if (!common_valid_http_url($license)) {
+            throw new OAuthException("Invalid license URL '$license'.");
+        }
+        $site_license = common_config('license', 'url');
+        if (!common_compatible_license($license, $site_license)) {
+            throw new OAuthException("Listenee stream license '$license' not compatible with site license '$site_license'.");
+        }
+        # optional stuff
+        $fullname = $req->get_parameter('omb_listenee_fullname');
+        if ($fullname && strlen($fullname) > 255) {
+            throw new OAuthException("Full name '$fullname' too long.");
+        }
+        $homepage = $req->get_parameter('omb_listenee_homepage');
+        if ($homepage && (!common_valid_http_url($homepage) || strlen($homepage) > 255)) {
+            throw new OAuthException("Invalid homepage '$homepage'");
+        }
+        $bio = $req->get_parameter('omb_listenee_bio');
+        if ($bio && strlen($bio) > 140) {
+            throw new OAuthException("Bio too long '$bio'");
+        }
+        $location = $req->get_parameter('omb_listenee_location');
+        if ($location && strlen($location) > 255) {
+            throw new OAuthException("Location too long '$location'");
+        }
+        $avatar = $req->get_parameter('omb_listenee_avatar');
+        if ($avatar) {
+            if (!common_valid_http_url($avatar) || strlen($avatar) > 255) {
+                throw new OAuthException("Invalid avatar URL '$avatar'");
+            }
+            $size = @getimagesize($avatar);
+            if (!$size) {
+                throw new OAuthException("Can't read avatar URL '$avatar'");
+            }
+            if ($size[0] != AVATAR_PROFILE_SIZE || $size[1] != AVATAR_PROFILE_SIZE) {
+                throw new OAuthException("Wrong size image at '$avatar'");
+            }
+            if (!in_array($size[2], array(IMAGETYPE_GIF, IMAGETYPE_JPEG,
+                                          IMAGETYPE_PNG))) {
+                throw new OAuthException("Wrong image type for '$avatar'");
+            }
+        }
+        $callback = $req->get_parameter('oauth_callback');
+        if ($callback && !common_valid_http_url($callback)) {
+            throw new OAuthException("Invalid callback URL '$callback'");
+        }
+        if ($callback && $callback == common_local_url('finishremotesubscribe')) {
+            throw new OAuthException("Callback URL '$callback' is for local site.");
+        }
+    }
+
+    # Snagged from OAuthServer
+
+    function check_version(&$req)
+    {
+        $version = $req->get_parameter("oauth_version");
+        if (!$version) {
+            $version = 1.0;
+        }
+        if ($version != 1.0) {
+            throw new OAuthException("OAuth version '$version' not supported");
+        }
+        return $version;
+    }
+
+    # Snagged from OAuthServer
+
+    function get_consumer($datastore, $req)
+    {
+        $consumer_key = @$req->get_parameter("oauth_consumer_key");
+        if (!$consumer_key) {
+            throw new OAuthException("Invalid consumer key");
+        }
+
+        $consumer = $datastore->lookup_consumer($consumer_key);
+        if (!$consumer) {
+            throw new OAuthException("Invalid consumer");
+        }
+        return $consumer;
+    }
+
+    # Mostly cadged from OAuthServer
+
+    function get_token($datastore, &$req, $consumer)
+    {/*{{{*/
+        $token_field = @$req->get_parameter('oauth_token');
+        $token = $datastore->lookup_token($consumer, 'request', $token_field);
+        if (!$token) {
+            throw new OAuthException("Invalid $token_type token: $token_field");
+        }
+        return $token;
+    }
+
+    function check_timestamp(&$req)
+    {
+        $timestamp = @$req->get_parameter('oauth_timestamp');
+        $now = time();
+        if ($now - $timestamp > TIMESTAMP_THRESHOLD) {
+            throw new OAuthException("Expired timestamp, yours $timestamp, ours $now");
+        }
+    }
+
+    # NOTE: don't call twice on the same request; will fail!
+    function check_nonce(&$datastore, &$req, $consumer, $token)
+    {
+        $timestamp = @$req->get_parameter('oauth_timestamp');
+        $nonce = @$req->get_parameter('oauth_nonce');
+        $found = $datastore->lookup_nonce($consumer, $token, $nonce, $timestamp);
+        if ($found) {
+            throw new OAuthException("Nonce already used");
+        }
+        return true;
+    }
+
+    function check_signature(&$req, $consumer, $token)
+    {
+        $signature_method = $this->get_signature_method($req);
+        $signature = $req->get_parameter('oauth_signature');
+        $valid_sig = $signature_method->check_signature($req,
+                                                        $consumer,
+                                                        $token,
+                                                        $signature);
+        if (!$valid_sig) {
+            throw new OAuthException("Invalid signature");
+        }
+    }
+
+    function get_signature_method(&$req)
+    {
+        $signature_method = @$req->get_parameter("oauth_signature_method");
+        if (!$signature_method) {
+            $signature_method = "PLAINTEXT";
+        }
+        if ($signature_method != 'HMAC-SHA1') {
+            throw new OAuthException("Signature method '$signature_method' not supported.");
+        }
+        return omb_hmac_sha1();
+    }
 }
index 38bff2edeee6b3a18640275bcb1319990450cdb5..d57ed21a54d233f4e9c1fda45247b84d0ff6340f 100644 (file)
 
 if (!defined('LACONICA')) { exit(1); }
 
-class UserbyidAction extends Action {
-       
-       function is_readonly() {                                
-               return true;
-       }
-       
-    function handle($args) {
+class UserbyidAction extends Action
+{
+    
+    function is_readonly()
+    {                
+        return true;
+    }
+    
+    function handle($args)
+    {
         parent::handle($args);
         $id = $this->trimmed('id');
         if (!$id) {
-               $this->client_error(_('No id.'));
-               }
-               $user =& User::staticGet($id);
-               if (!$user) {
-                       $this->client_error(_('No such user.'));
+            $this->client_error(_('No id.'));
+        }
+        $user =& User::staticGet($id);
+        if (!$user) {
+            $this->client_error(_('No such user.'));
         }
 
         // support redirecting to FOAF rdf/xml if the agent prefers it
         $page_prefs = 'application/rdf+xml,text/html,application/xhtml+xml,application/xml;q=0.3,text/xml;q=0.2';
-        $httpaccept = isset($_SERVER['HTTP_ACCEPT']) ? $_SERVER['HTTP_ACCEPT'] : NULL;
-       $type = common_negotiate_type(common_accept_to_prefs($httpaccept),
+        $httpaccept = isset($_SERVER['HTTP_ACCEPT']) ? $_SERVER['HTTP_ACCEPT'] : null;
+        $type = common_negotiate_type(common_accept_to_prefs($httpaccept),
                                       common_accept_to_prefs($page_prefs));
-               $page = $type == 'application/rdf+xml' ? 'foaf' : 'showstream';
+        $page = $type == 'application/rdf+xml' ? 'foaf' : 'showstream';
 
-               $url = common_local_url($page, array('nickname' => $user->nickname));
-               common_redirect($url, 303);
-       }
+        $url = common_local_url($page, array('nickname' => $user->nickname));
+        common_redirect($url, 303);
+    }
 }
index e57f861054bc70964b7108092246cf1ceff36077..1e9fe121f0be78719c9947f88eb13b4d20a1e68e 100644 (file)
@@ -23,68 +23,74 @@ require_once(INSTALLDIR.'/lib/rssaction.php');
 
 // Formatting of RSS handled by Rss10Action
 
-class UserrssAction extends Rss10Action {
+class UserrssAction extends Rss10Action
+{
 
-       var $user = NULL;
+    var $user = null;
 
-       function init() {
-               $nickname = $this->trimmed('nickname');
-               $this->user = User::staticGet('nickname', $nickname);
+    function init()
+    {
+        $nickname = $this->trimmed('nickname');
+        $this->user = User::staticGet('nickname', $nickname);
 
-               if (!$this->user) {
-                       common_user_error(_('No such user.'));
-                       return false;
-               } else {
-                       return true;
-               }
-       }
+        if (!$this->user) {
+            common_user_error(_('No such user.'));
+            return false;
+        } else {
+            return true;
+        }
+    }
 
-       function get_notices($limit=0) {
+    function get_notices($limit=0)
+    {
 
-               $user = $this->user;
-               
-               if (is_null($user)) {
-                       return NULL;
-               }
-               
-               $notice = $user->getNotices(0, ($limit == 0) ? NOTICES_PER_PAGE : $limit);
-               
-               while ($notice->fetch()) {
-                       $notices[] = clone($notice);
-               }
+        $user = $this->user;
+        
+        if (is_null($user)) {
+            return null;
+        }
+        
+        $notice = $user->getNotices(0, ($limit == 0) ? NOTICES_PER_PAGE : $limit);
+        
+        while ($notice->fetch()) {
+            $notices[] = clone($notice);
+        }
 
-               return $notices;
-       }
+        return $notices;
+    }
 
-       function get_channel() {
-               $user = $this->user;
-               $profile = $user->getProfile();
-               $c = array('url' => common_local_url('userrss',
-                                                                                        array('nickname' =>
-                                                                                                  $user->nickname)),
-                                  'title' => $user->nickname,
-                                  'link' => $profile->profileurl,
-                                  'description' => sprintf(_('Microblog by %s'), $user->nickname));
-               return $c;
-       }
+    function get_channel()
+    {
+        $user = $this->user;
+        $profile = $user->getProfile();
+        $c = array('url' => common_local_url('userrss',
+                                             array('nickname' =>
+                                                   $user->nickname)),
+                   'title' => $user->nickname,
+                   'link' => $profile->profileurl,
+                   'description' => sprintf(_('Microblog by %s'), $user->nickname));
+        return $c;
+    }
 
-       function get_image() {
-               $user = $this->user;
-               $profile = $user->getProfile();
-               if (!$profile) {
-                       common_log_db_error($user, 'SELECT', __FILE__);
-                       $this->server_error(_('User without matching profile'));
-                       return NULL;
-               }
-               $avatar = $profile->getAvatar(AVATAR_PROFILE_SIZE);
-               return ($avatar) ? $avatar->url : NULL;
-       }
+    function get_image()
+    {
+        $user = $this->user;
+        $profile = $user->getProfile();
+        if (!$profile) {
+            common_log_db_error($user, 'SELECT', __FILE__);
+            $this->server_error(_('User without matching profile'));
+            return null;
+        }
+        $avatar = $profile->getAvatar(AVATAR_PROFILE_SIZE);
+        return ($avatar) ? $avatar->url : null;
+    }
 
-       # override parent to add X-SUP-ID URL
-       
-       function init_rss($limit=0) {
-               $url = common_local_url('sup', NULL, $this->user->id);
-               header('X-SUP-ID: '.$url);
-               parent::init_rss($limit);
-       }
+    # override parent to add X-SUP-ID URL
+    
+    function init_rss($limit=0)
+    {
+        $url = common_local_url('sup', null, $this->user->id);
+        header('X-SUP-ID: '.$url);
+        parent::init_rss($limit);
+    }
 }
\ No newline at end of file
index 1d516aab72e78d6681e7b6d614f71810fc146eb5..7edc6aa39cbbfc6ef8070680017226c7e6cb728b 100644 (file)
@@ -21,112 +21,117 @@ if (!defined('LACONICA')) { exit(1); }
 
 require_once(INSTALLDIR.'/lib/omb.php');
 
-class XrdsAction extends Action {
-
-       function is_readonly() {                                
-               return true;
-       }
-
-       function handle($args) {
-               parent::handle($args);
-               $nickname = $this->trimmed('nickname');
-               $user = User::staticGet('nickname', $nickname);
-               if (!$user) {
-                       common_user_error(_('No such user.'));
-                       return;
-               }
-               $this->show_xrds($user);
-       }
-
-       function show_xrds($user) {
-
-               header('Content-Type: application/xrds+xml');
-
-               common_start_xml();
-               common_element_start('XRDS', array('xmlns' => 'xri://$xrds'));
-
-               common_element_start('XRD', array('xmlns' => 'xri://$xrd*($v*2.0)',
-                                                 'xml:id' => 'oauth',
-                                                                                 'xmlns:simple' => 'http://xrds-simple.net/core/1.0',
-                                                                                 'version' => '2.0'));
-
-               common_element('Type', NULL, 'xri://$xrds*simple');
-
-               $this->show_service(OAUTH_ENDPOINT_REQUEST,
-                                                       common_local_url('requesttoken'),
-                                                       array(OAUTH_AUTH_HEADER, OAUTH_POST_BODY),
-                                                       array(OAUTH_HMAC_SHA1),
-                                                       $user->uri);
-
-               $this->show_service(OAUTH_ENDPOINT_AUTHORIZE,
-                                                       common_local_url('userauthorization'),
-                                                       array(OAUTH_AUTH_HEADER, OAUTH_POST_BODY),
-                                                       array(OAUTH_HMAC_SHA1));
-
-               $this->show_service(OAUTH_ENDPOINT_ACCESS,
-                                                       common_local_url('accesstoken'),
-                                                       array(OAUTH_AUTH_HEADER, OAUTH_POST_BODY),
-                                                       array(OAUTH_HMAC_SHA1));
-
-               $this->show_service(OAUTH_ENDPOINT_RESOURCE,
-                                                       NULL,
-                                                       array(OAUTH_AUTH_HEADER, OAUTH_POST_BODY),
-                                                       array(OAUTH_HMAC_SHA1));
-
-               common_element_end('XRD');
-
-               # XXX: decide whether to include user's ID/nickname in postNotice URL
-
-               common_element_start('XRD', array('xmlns' => 'xri://$xrd*($v*2.0)',
-                                                 'xml:id' => 'omb',
-                                                                                 'xmlns:simple' => 'http://xrds-simple.net/core/1.0',
-                                                                                 'version' => '2.0'));
-
-               common_element('Type', NULL, 'xri://$xrds*simple');
-
-               $this->show_service(OMB_ENDPOINT_POSTNOTICE,
-                                                       common_local_url('postnotice'));
-
-               $this->show_service(OMB_ENDPOINT_UPDATEPROFILE,
-                                                       common_local_url('updateprofile'));
-
-               common_element_end('XRD');
-
-               common_element_start('XRD', array('xmlns' => 'xri://$xrd*($v*2.0)',
-                                                                                 'version' => '2.0'));
-
-               common_element('Type', NULL, 'xri://$xrds*simple');
-
-               $this->show_service(OAUTH_DISCOVERY,
-                                                       '#oauth');
-               $this->show_service(OMB_NAMESPACE,
-                                                       '#omb');
-
-               common_element_end('XRD');
-
-               common_element_end('XRDS');
-               common_end_xml();
-       }
-
-       function show_service($type, $uri, $params=NULL, $sigs=NULL, $localId=NULL) {
-               common_element_start('Service');
-               if ($uri) {
-                       common_element('URI', NULL, $uri);
-               }
-               common_element('Type', NULL, $type);
-               if ($params) {
-                       foreach ($params as $param) {
-                               common_element('Type', NULL, $param);
-                       }
-               }
-               if ($sigs) {
-                       foreach ($sigs as $sig) {
-                               common_element('Type', NULL, $sig);
-                       }
-               }
-               if ($localId) {
-                       common_element('LocalID', NULL, $localId);
-               }
-               common_element_end('Service');
-       }
+class XrdsAction extends Action
+{
+
+    function is_readonly()
+    {                
+        return true;
+    }
+
+    function handle($args)
+    {
+        parent::handle($args);
+        $nickname = $this->trimmed('nickname');
+        $user = User::staticGet('nickname', $nickname);
+        if (!$user) {
+            common_user_error(_('No such user.'));
+            return;
+        }
+        $this->show_xrds($user);
+    }
+
+    function show_xrds($user)
+    {
+
+        header('Content-Type: application/xrds+xml');
+
+        common_start_xml();
+        common_element_start('XRDS', array('xmlns' => 'xri://$xrds'));
+
+        common_element_start('XRD', array('xmlns' => 'xri://$xrd*($v*2.0)',
+                                          'xml:id' => 'oauth',
+                                          'xmlns:simple' => 'http://xrds-simple.net/core/1.0',
+                                          'version' => '2.0'));
+
+        common_element('Type', null, 'xri://$xrds*simple');
+
+        $this->show_service(OAUTH_ENDPOINT_REQUEST,
+                            common_local_url('requesttoken'),
+                            array(OAUTH_AUTH_HEADER, OAUTH_POST_BODY),
+                            array(OAUTH_HMAC_SHA1),
+                            $user->uri);
+
+        $this->show_service(OAUTH_ENDPOINT_AUTHORIZE,
+                            common_local_url('userauthorization'),
+                            array(OAUTH_AUTH_HEADER, OAUTH_POST_BODY),
+                            array(OAUTH_HMAC_SHA1));
+
+        $this->show_service(OAUTH_ENDPOINT_ACCESS,
+                            common_local_url('accesstoken'),
+                            array(OAUTH_AUTH_HEADER, OAUTH_POST_BODY),
+                            array(OAUTH_HMAC_SHA1));
+
+        $this->show_service(OAUTH_ENDPOINT_RESOURCE,
+                            null,
+                            array(OAUTH_AUTH_HEADER, OAUTH_POST_BODY),
+                            array(OAUTH_HMAC_SHA1));
+
+        common_element_end('XRD');
+
+        # XXX: decide whether to include user's ID/nickname in postNotice URL
+
+        common_element_start('XRD', array('xmlns' => 'xri://$xrd*($v*2.0)',
+                                          'xml:id' => 'omb',
+                                          'xmlns:simple' => 'http://xrds-simple.net/core/1.0',
+                                          'version' => '2.0'));
+
+        common_element('Type', null, 'xri://$xrds*simple');
+
+        $this->show_service(OMB_ENDPOINT_POSTNOTICE,
+                            common_local_url('postnotice'));
+
+        $this->show_service(OMB_ENDPOINT_UPDATEPROFILE,
+                            common_local_url('updateprofile'));
+
+        common_element_end('XRD');
+
+        common_element_start('XRD', array('xmlns' => 'xri://$xrd*($v*2.0)',
+                                          'version' => '2.0'));
+
+        common_element('Type', null, 'xri://$xrds*simple');
+
+        $this->show_service(OAUTH_DISCOVERY,
+                            '#oauth');
+        $this->show_service(OMB_NAMESPACE,
+                            '#omb');
+
+        common_element_end('XRD');
+
+        common_element_end('XRDS');
+        common_end_xml();
+    }
+
+    function show_service($type, $uri, $params=null, $sigs=null, $localId=null)
+    {
+        common_element_start('Service');
+        if ($uri) {
+            common_element('URI', null, $uri);
+        }
+        common_element('Type', null, $type);
+        if ($params) {
+            foreach ($params as $param) {
+                common_element('Type', null, $param);
+            }
+        }
+        if ($sigs) {
+            foreach ($sigs as $sig) {
+                common_element('Type', null, $sig);
+            }
+        }
+        if ($localId) {
+            common_element('LocalID', null, $localId);
+        }
+        common_element_end('Service');
+    }
 }
\ No newline at end of file
diff --git a/avatar/.gitignore b/avatar/.gitignore
new file mode 100644 (file)
index 0000000..e69de29
index 901c47c51e8e4c039f15daaeaefe1dcad7d27397..9ae920647adfbae0c7ce6e767eca7fa7ec243c91 100644 (file)
@@ -21,75 +21,121 @@ class Avatar extends Memcached_DataObject
     public $modified;                        // timestamp()   not_null default_CURRENT_TIMESTAMP
 
     /* Static get */
-    function staticGet($k,$v=NULL) { return Memcached_DataObject::staticGet('Avatar',$k,$v); }
+    function staticGet($k,$v=null)
+    { return Memcached_DataObject::staticGet('Avatar',$k,$v); }
 
     /* the code above is auto generated do not remove the tag below */
     ###END_AUTOCODE
 
-       # We clean up the file, too
+    # We clean up the file, too
 
-       function delete() {
-               $filename = $this->filename;
-               if (parent::delete()) {
-                       @unlink(common_avatar_path($filename));
-               }
-       }
+    function delete()
+    {
+        $filename = $this->filename;
+        if (parent::delete()) {
+            @unlink(common_avatar_path($filename));
+        }
+    }
 
-       # Create and save scaled version of this avatar
-       # XXX: maybe break into different methods
+    # Create and save scaled version of this avatar
+    # XXX: maybe break into different methods
 
-       function scale($size) {
+    function scale($size)
+    {
 
-               $image_s = imagecreatetruecolor($size, $size);
-               $image_a = $this->to_image();
-               $square = min($this->width, $this->height);
+        $image_s = imagecreatetruecolor($size, $size);
+        $image_a = $this->to_image();
+        $square = min($this->width, $this->height);
         imagecolortransparent($image_s, imagecolorallocate($image_s, 0, 0, 0));
         imagealphablending($image_s, false);
         imagesavealpha($image_s, true);
-               imagecopyresampled($image_s, $image_a, 0, 0, 0, 0,
-                                                  $size, $size, $square, $square);
-
-               $ext = ($this->mediattype == 'image/jpeg') ? ".jpeg" : ".png";
-
-               $filename = common_avatar_filename($this->profile_id, $ext, $size, common_timestamp());
-
-               if ($this->mediatype == 'image/jpeg') {
-                       imagejpeg($image_s, common_avatar_path($filename));
-               } else {
-                       imagepng($image_s, common_avatar_path($filename));
-               }
-
-               $scaled = DB_DataObject::factory('avatar');
-               $scaled->profile_id = $this->profile_id;
-               $scaled->width = $size;
-               $scaled->height = $size;
-               $scaled->original = false;
-               $scaled->mediatype = ($this->mediattype == 'image/jpeg') ? 'image/jpeg' : 'image/png';
-               $scaled->filename = $filename;
-               $scaled->url = common_avatar_url($filename);
-               $scaled->created = DB_DataObject_Cast::dateTime(); # current time
-
-               if ($scaled->insert()) {
-                       return $scaled;
-               } else {
-                       return NULL;
-               }
-       }
-
-       function to_image() {
-               $filepath = common_avatar_path($this->filename);
-               if ($this->mediatype == 'image/gif') {
-                       return imagecreatefromgif($filepath);
-               } else if ($this->mediatype == 'image/jpeg') {
-                       return imagecreatefromjpeg($filepath);
-               } else if ($this->mediatype == 'image/png') {
-                       return imagecreatefrompng($filepath);
-               } else {
-                       return NULL;
-               }
-       }
-       
-       function &pkeyGet($kv) {
-               return Memcached_DataObject::pkeyGet('Avatar', $kv);
-       }
+        imagecopyresampled($image_s, $image_a, 0, 0, 0, 0,
+                           $size, $size, $square, $square);
+
+        $ext = ($this->mediattype == 'image/jpeg') ? ".jpeg" : ".png";
+
+        $filename = common_avatar_filename($this->profile_id, $ext, $size, common_timestamp());
+
+        if ($this->mediatype == 'image/jpeg') {
+            imagejpeg($image_s, common_avatar_path($filename));
+        } else {
+            imagepng($image_s, common_avatar_path($filename));
+        }
+
+        $scaled = DB_DataObject::factory('avatar');
+        $scaled->profile_id = $this->profile_id;
+        $scaled->width = $size;
+        $scaled->height = $size;
+        $scaled->original = false;
+        $scaled->mediatype = ($this->mediattype == 'image/jpeg') ? 'image/jpeg' : 'image/png';
+        $scaled->filename = $filename;
+        $scaled->url = common_avatar_url($filename);
+        $scaled->created = DB_DataObject_Cast::dateTime(); # current time
+
+        if ($scaled->insert()) {
+            return $scaled;
+        } else {
+            return null;
+        }
+    }
+
+    function scale_and_crop($size, $x, $y, $w, $h) 
+    {
+
+        $image_s = imagecreatetruecolor($size, $size);
+        $image_a = $this->to_image();
+
+        # Retain alpha channel info if possible for .pngs
+        $background = imagecolorallocate($image_s, 0, 0, 0);
+        ImageColorTransparent($image_s, $background);
+        imagealphablending($image_s, false);
+
+        imagecopyresized($image_s, $image_a, 0, 0, $x, $y, $size, $size, $w, $h);
+
+        $ext = ($this->mediattype == 'image/jpeg') ? ".jpeg" : ".png";
+
+        $filename = common_avatar_filename($this->profile_id, $ext, $size, common_timestamp());
+
+        if ($this->mediatype == 'image/jpeg') {
+            imagejpeg($image_s, common_avatar_path($filename));
+        } else {
+            imagepng($image_s, common_avatar_path($filename));
+        }
+
+        $cropped = DB_DataObject::factory('avatar');
+        $cropped->profile_id = $this->profile_id;
+        $cropped->width = $size;
+        $cropped->height = $size;
+        $cropped->original = false;
+        $cropped->mediatype = ($this->mediattype == 'image/jpeg') ? 'image/jpeg' : 'image/png';
+        $cropped->filename = $filename;
+        $cropped->url = common_avatar_url($filename);
+        $cropped->created = DB_DataObject_Cast::dateTime(); # current time
+
+        if ($cropped->insert()) {
+            return $cropped;
+        } else {
+            return NULL;
+        }
+    }
+
+    function to_image() 
+    {
+        $filepath = common_avatar_path($this->filename);
+        if ($this->mediatype == 'image/gif') {
+            return imagecreatefromgif($filepath);
+        } else if ($this->mediatype == 'image/jpeg') {
+            return imagecreatefromjpeg($filepath);
+        } else if ($this->mediatype == 'image/png') {
+            return imagecreatefrompng($filepath);
+        } else {
+            return NULL;
+        }
+    }
+    
+    function &pkeyGet($kv) 
+    {
+        return Memcached_DataObject::pkeyGet('Avatar', $kv);
+    }
+
 }
index bcc0c36b56517a0ac813fcf885bd78bace4b0012..2e3e4e8d4a7cd5c9f44804edf9c10e195bda7189 100644 (file)
 
 if (!defined('LACONICA')) { exit(1); }
 
-class Channel {
-       
-       function on($user) {
-               return false;
-       }
-
-       function off($user) {
-               return false;
-       }
-
-       function output($user, $text) {
-               return false;
-       }
-       
-       function error($user, $text) {
-               return false;
-       }
-       
-       function source() {
-               return NULL;
-       }
+class Channel
+{
+    
+    function on($user)
+    {
+        return false;
+    }
+
+    function off($user)
+    {
+        return false;
+    }
+
+    function output($user, $text)
+    {
+        return false;
+    }
+    
+    function error($user, $text)
+    {
+        return false;
+    }
+    
+    function source()
+    {
+        return null;
+    }
 }
 
-class XMPPChannel extends Channel {
-
-       var $conn = NULL;
-       
-       function source() {
-               return 'xmpp';
-       }
-       
-       function __construct($conn) {
-               $this->conn = $conn;
-       }
-       
-       function on($user) {
-               return $this->set_notify($user, 1);
-       }
-       
-       function off($user) {
-               return $this->set_notify($user, 0);
-       }
-
-       function output($user, $text) {
-               $text = '['.common_config('site', 'name') . '] ' . $text;
-               jabber_send_message($user->jabber, $text);
-       }
-       
-       function error($user, $text) {
-               $text = '['.common_config('site', 'name') . '] ' . $text;
-               jabber_send_message($user->jabber, $text);
-       }
-       
-       function set_notify(&$user, $notify) {
-               $orig = clone($user);
-               $user->jabbernotify = $notify;
-               $result = $user->update($orig);
-               if (!$result) {
-                       $last_error = &PEAR::getStaticProperty('DB_DataObject','lastError');
-                       common_log(LOG_ERR,
-                                          'Could not set notify flag to ' . $notify .
-                                          ' for user ' . common_log_objstring($user) .
-                                          ': ' . $last_error->message);
-                       return false;
-               } else {
-                       common_log(LOG_INFO,
-                                          'User ' . $user->nickname . ' set notify flag to ' . $notify);
-                       return true;
-               }
-       }
+class XMPPChannel extends Channel
+{
+
+    var $conn = null;
+    
+    function source()
+    {
+        return 'xmpp';
+    }
+    
+    function __construct($conn)
+    {
+        $this->conn = $conn;
+    }
+    
+    function on($user)
+    {
+        return $this->set_notify($user, 1);
+    }
+    
+    function off($user)
+    {
+        return $this->set_notify($user, 0);
+    }
+
+    function output($user, $text)
+    {
+        $text = '['.common_config('site', 'name') . '] ' . $text;
+        jabber_send_message($user->jabber, $text);
+    }
+    
+    function error($user, $text)
+    {
+        $text = '['.common_config('site', 'name') . '] ' . $text;
+        jabber_send_message($user->jabber, $text);
+    }
+    
+    function set_notify(&$user, $notify)
+    {
+        $orig = clone($user);
+        $user->jabbernotify = $notify;
+        $result = $user->update($orig);
+        if (!$result) {
+            $last_error = &PEAR::getStaticProperty('DB_DataObject','lastError');
+            common_log(LOG_ERR,
+                       'Could not set notify flag to ' . $notify .
+                       ' for user ' . common_log_objstring($user) .
+                       ': ' . $last_error->message);
+            return false;
+        } else {
+            common_log(LOG_INFO,
+                       'User ' . $user->nickname . ' set notify flag to ' . $notify);
+            return true;
+        }
+    }
 }
 
 
-class WebChannel extends Channel {
-
-       function source() {
-               return 'web';
-       }
-       
-       function on($user) {
-               return false;
-       }
-       
-       function off($user) {
-               return false;
-       }
-
-       function output($user, $text) {
-               # XXX: buffer all output and send it at the end
-               # XXX: even better, redirect to appropriate page
-               #      depending on what command was run
-               common_show_header(_('Command results'));
-               common_element('p', NULL, $text);
-               common_show_footer();
-       }
-       
-       function error($user, $text) {
-               common_user_error($text);
-       }
+class WebChannel extends Channel
+{
+
+    function source()
+    {
+        return 'web';
+    }
+    
+    function on($user)
+    {
+        return false;
+    }
+    
+    function off($user)
+    {
+        return false;
+    }
+
+    function output($user, $text)
+    {
+        # XXX: buffer all output and send it at the end
+        # XXX: even better, redirect to appropriate page
+        #      depending on what command was run
+        common_show_header(_('Command results'));
+        common_element('p', null, $text);
+        common_show_footer();
+    }
+    
+    function error($user, $text)
+    {
+        common_user_error($text);
+    }
 }
 
 
-class AjaxWebChannel extends WebChannel {
-
-       function output($user, $text) {
-               common_start_html('text/xml;charset=utf-8', true);
-               common_element_start('head');
-               common_element('title', null, _('Command results'));
-               common_element_end('head');
-               common_element_start('body');
-               common_element('p', array('id' => 'command_result'), $text);
-               common_element_end('body');
-               common_element_end('html');
-       }
-
-       function error($user, $text) {
-               common_start_html('text/xml;charset=utf-8', true);
-               common_element_start('head');
-               common_element('title', null, _('Ajax Error'));
-               common_element_end('head');
-               common_element_start('body');
-               common_element('p', array('id' => 'error'), $text);
-               common_element_end('body');
-               common_element_end('html');
-       }
+class AjaxWebChannel extends WebChannel
+{
+
+    function output($user, $text)
+    {
+        common_start_html('text/xml;charset=utf-8', true);
+        common_element_start('head');
+        common_element('title', null, _('Command results'));
+        common_element_end('head');
+        common_element_start('body');
+        common_element('p', array('id' => 'command_result'), $text);
+        common_element_end('body');
+        common_element_end('html');
+    }
+
+    function error($user, $text)
+    {
+        common_start_html('text/xml;charset=utf-8', true);
+        common_element_start('head');
+        common_element('title', null, _('Ajax Error'));
+        common_element_end('head');
+        common_element_start('body');
+        common_element('p', array('id' => 'error'), $text);
+        common_element_end('body');
+        common_element_end('html');
+    }
 }
 
 
-class MailChannel extends Channel {
-
-       var $addr = NULL;
-
-       function source() {
-               return 'mail';
-       }
-       
-       function __construct($addr=NULL) {
-               $this->addr = $addr;
-       }
-       
-       function on($user) {
-               return $this->set_notify($user, 1);
-       }
-       
-       function off($user) {
-               return $this->set_notify($user, 0);
-       }
-
-       function output($user, $text) {
-
-               $headers['From'] = $user->incomingemail;
-               $headers['To'] = $this->addr;
-               
-               $headers['Subject'] = _('Command complete');
-
-               return mail_send(array($this->addr), $headers, $text);
-       }
-       
-       function error($user, $text) {
-               
-               $headers['From'] = $user->incomingemail;
-               $headers['To'] = $this->addr;
-               
-               $headers['Subject'] = _('Command failed');
-
-               return mail_send(array($this->addr), $headers, $text);
-       }
-       
-       function set_notify($user, $value) {
-               $orig = clone($user);
-               $user->smsnotify = $value;
-               $result = $user->update($orig);
-               if (!$result) {
-                       common_log_db_error($user, 'UPDATE', __FILE__);
-                       return false;
-               }
-               return true;
-       }
+class MailChannel extends Channel
+{
+
+    var $addr = null;
+
+    function source()
+    {
+        return 'mail';
+    }
+    
+    function __construct($addr=null)
+    {
+        $this->addr = $addr;
+    }
+    
+    function on($user)
+    {
+        return $this->set_notify($user, 1);
+    }
+    
+    function off($user)
+    {
+        return $this->set_notify($user, 0);
+    }
+
+    function output($user, $text)
+    {
+
+        $headers['From'] = $user->incomingemail;
+        $headers['To'] = $this->addr;
+        
+        $headers['Subject'] = _('Command complete');
+
+        return mail_send(array($this->addr), $headers, $text);
+    }
+    
+    function error($user, $text)
+    {
+        
+        $headers['From'] = $user->incomingemail;
+        $headers['To'] = $this->addr;
+        
+        $headers['Subject'] = _('Command failed');
+
+        return mail_send(array($this->addr), $headers, $text);
+    }
+    
+    function set_notify($user, $value)
+    {
+        $orig = clone($user);
+        $user->smsnotify = $value;
+        $result = $user->update($orig);
+        if (!$result) {
+            common_log_db_error($user, 'UPDATE', __FILE__);
+            return false;
+        }
+        return true;
+    }
 }
index c2409d140a2ac152c86ca780ffe36d288833bf42..eacbdacb36528091c5ea6cec60c74967a28ec662 100644 (file)
@@ -21,356 +21,399 @@ if (!defined('LACONICA')) { exit(1); }
 
 require_once(INSTALLDIR.'/classes/Channel.php');
 
-class Command {
-       
-       var $user = NULL;
-       
-       function __construct($user=NULL) {
-               $this->user = $user;
-       }
-       
-       function execute($channel) {
-               return false;
-       }
+class Command
+{
+    
+    var $user = null;
+    
+    function __construct($user=null)
+    {
+        $this->user = $user;
+    }
+    
+    function execute($channel)
+    {
+        return false;
+    }
 }
 
-class UnimplementedCommand extends Command {
-       function execute($channel) {
-               $channel->error($this->user, _("Sorry, this command is not yet implemented."));
-       }
+class UnimplementedCommand extends Command
+{
+    function execute($channel)
+    {
+        $channel->error($this->user, _("Sorry, this command is not yet implemented."));
+    }
 }
 
-class TrackingCommand extends UnimplementedCommand {
+class TrackingCommand extends UnimplementedCommand
+{
 }
 
-class TrackOffCommand extends UnimplementedCommand {
+class TrackOffCommand extends UnimplementedCommand
+{
 }
 
-class TrackCommand extends UnimplementedCommand {
-       var $word = NULL;
-       function __construct($user, $word) {
-               parent::__construct($user);
-               $this->word = $word;
-       }
+class TrackCommand extends UnimplementedCommand
+{
+    var $word = null;
+    function __construct($user, $word)
+    {
+        parent::__construct($user);
+        $this->word = $word;
+    }
 }
 
-class UntrackCommand extends UnimplementedCommand {
-       var $word = NULL;
-       function __construct($user, $word) {
-               parent::__construct($user);
-               $this->word = $word;
-       }
+class UntrackCommand extends UnimplementedCommand
+{
+    var $word = null;
+    function __construct($user, $word)
+    {
+        parent::__construct($user);
+        $this->word = $word;
+    }
 }
 
-class NudgeCommand extends UnimplementedCommand {
-       var $other = NULL;
-       function __construct($user, $other) {
-               parent::__construct($user);
-               $this->other = $other;
-       }
+class NudgeCommand extends UnimplementedCommand
+{
+    var $other = null;
+    function __construct($user, $other)
+    {
+        parent::__construct($user);
+        $this->other = $other;
+    }
 }
 
-class InviteCommand extends UnimplementedCommand {
-       var $other = NULL;
-       function __construct($user, $other) {
-               parent::__construct($user);
-               $this->other = $other;
-       }
+class InviteCommand extends UnimplementedCommand
+{
+    var $other = null;
+    function __construct($user, $other)
+    {
+        parent::__construct($user);
+        $this->other = $other;
+    }
 }
 
-class StatsCommand extends Command {
-       function execute($channel) {
+class StatsCommand extends Command
+{
+    function execute($channel)
+    {
 
-               $subs = new Subscription();
-               $subs->subscriber = $this->user->id;
-               $subs_count = (int) $subs->count() - 1;
+        $subs = new Subscription();
+        $subs->subscriber = $this->user->id;
+        $subs_count = (int) $subs->count() - 1;
 
-               $subbed = new Subscription();
-               $subbed->subscribed = $this->user->id;
-               $subbed_count = (int) $subbed->count() - 1;
+        $subbed = new Subscription();
+        $subbed->subscribed = $this->user->id;
+        $subbed_count = (int) $subbed->count() - 1;
 
-               $notices = new Notice();
-               $notices->profile_id = $this->user->id;
-               $notice_count = (int) $notices->count();
-               
-               $channel->output($this->user, sprintf(_("Subscriptions: %1\$s\n".
-                                                                  "Subscribers: %2\$s\n".
-                                                                  "Notices: %3\$s"),
-                                                                $subs_count,
-                                                                $subbed_count,
-                                                                $notice_count));
-       }
+        $notices = new Notice();
+        $notices->profile_id = $this->user->id;
+        $notice_count = (int) $notices->count();
+        
+        $channel->output($this->user, sprintf(_("Subscriptions: %1\$s\n".
+                                   "Subscribers: %2\$s\n".
+                                   "Notices: %3\$s"),
+                                 $subs_count,
+                                 $subbed_count,
+                                 $notice_count));
+    }
 }
 
-class FavCommand extends Command {
-       
-       var $other = NULL;
-       
-       function __construct($user, $other) {
-               parent::__construct($user);
-               $this->other = $other;
-       }
-       
-       function execute($channel) {
-               
-               $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);
+class FavCommand extends Command
+{
+    
+    var $other = null;
+    
+    function __construct($user, $other)
+    {
+        parent::__construct($user);
+        $this->other = $other;
+    }
+    
+    function execute($channel)
+    {
+        
+        $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);
 
-               if (!$fave) {
-                       $channel->error($this->user, _('Could not create favorite.'));
-                       return;
-               }
+        if (!$fave) {
+            $channel->error($this->user, _('Could not create favorite.'));
+            return;
+        }
 
-           $other = User::staticGet('id', $recipient->id);
-               
-               if ($other && $other->id != $user->id) {
-                       if ($other->email && $other->emailnotifyfav) {
-                               mail_notify_fave($other, $this->user, $notice);
-                       }
-               }
-               
-               $this->user->blowFavesCache();
-               
-               $channel->output($this->user, _('Notice marked as fave.'));
-       }
+        $other = User::staticGet('id', $recipient->id);
+        
+        if ($other && $other->id != $user->id) {
+            if ($other->email && $other->emailnotifyfav) {
+                mail_notify_fave($other, $this->user, $notice);
+            }
+        }
+        
+        $this->user->blowFavesCache();
+        
+        $channel->output($this->user, _('Notice marked as fave.'));
+    }
 }
 
-class WhoisCommand extends Command {
-       var $other = NULL;
-       function __construct($user, $other) {
-               parent::__construct($user);
-               $this->other = $other;
-       }
-       
-       function execute($channel) {
-               $recipient = 
-                 common_relative_profile($this->user, common_canonical_nickname($this->other));
-               
-               if (!$recipient) {
-                       $channel->error($this->user, _('No such user.'));
-                       return;
-               }
-               
-               $whois = sprintf(_("%1\$s (%2\$s)"), $recipient->nickname,
-                                                $recipient->profileurl);
-               if ($recipient->fullname) {
-                       $whois .= "\n" . sprintf(_('Fullname: %s'), $recipient->fullname);
-               }
-               if ($recipient->location) {
-                       $whois .= "\n" . sprintf(_('Location: %s'), $recipient->location);
-               }
-               if ($recipient->homepage) {
-                       $whois .= "\n" . sprintf(_('Homepage: %s'), $recipient->homepage);
-               }
-               if ($recipient->bio) {
-                       $whois .= "\n" . sprintf(_('About: %s'), $recipient->bio);
-               }
-               $channel->output($this->user, $whois);
-       }
+class WhoisCommand extends Command
+{
+    var $other = null;
+    function __construct($user, $other)
+    {
+        parent::__construct($user);
+        $this->other = $other;
+    }
+    
+    function execute($channel)
+    {
+        $recipient = 
+          common_relative_profile($this->user, common_canonical_nickname($this->other));
+        
+        if (!$recipient) {
+            $channel->error($this->user, _('No such user.'));
+            return;
+        }
+        
+        $whois = sprintf(_("%1\$s (%2\$s)"), $recipient->nickname,
+                         $recipient->profileurl);
+        if ($recipient->fullname) {
+            $whois .= "\n" . sprintf(_('Fullname: %s'), $recipient->fullname);
+        }
+        if ($recipient->location) {
+            $whois .= "\n" . sprintf(_('Location: %s'), $recipient->location);
+        }
+        if ($recipient->homepage) {
+            $whois .= "\n" . sprintf(_('Homepage: %s'), $recipient->homepage);
+        }
+        if ($recipient->bio) {
+            $whois .= "\n" . sprintf(_('About: %s'), $recipient->bio);
+        }
+        $channel->output($this->user, $whois);
+    }
 }
 
-class MessageCommand 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) {
-               $other = User::staticGet('nickname', common_canonical_nickname($this->other));
-               $len = mb_strlen($this->text);
-               if ($len == 0) {
-                       $channel->error($this->user, _('No content!'));
-                       return;
-               } else if ($len > 140) {
-                       $content = common_shorten_links($content);
-                       if (mb_strlen($content) > 140) {
-                               $channel->error($this->user, sprintf(_('Message too long - maximum is 140 characters, you sent %d'), $len));
-                               return;
-                       }
-               }
-               
-               if (!$other) {
-                       $channel->error($this->user, _('No such user.'));
-                       return;
-               } else if (!$this->user->mutuallySubscribed($other)) {
-                       $channel->error($this->user, _('You can\'t send a message to this user.'));
-                       return;
-               } else if ($this->user->id == $other->id) {
-                       $channel->error($this->user, _('Don\'t send a message to yourself; just say it to yourself quietly instead.'));
-                       return;
-               }
-               $message = Message::saveNew($this->user->id, $other->id, $this->text, $channel->source());
-               if ($message) {
-                       $channel->output($this->user, sprintf(_('Direct message to %s sent'), $this->other));
-               } else {
-                       $channel->error($this->user, _('Error sending direct message.'));
-               }
-       }
+class MessageCommand 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)
+    {
+        $other = User::staticGet('nickname', common_canonical_nickname($this->other));
+        $len = mb_strlen($this->text);
+        if ($len == 0) {
+            $channel->error($this->user, _('No content!'));
+            return;
+        } else if ($len > 140) {
+            $content = common_shorten_links($content);
+            if (mb_strlen($content) > 140) {
+                $channel->error($this->user, sprintf(_('Message too long - maximum is 140 characters, you sent %d'), $len));
+                return;
+            }
+        }
+        
+        if (!$other) {
+            $channel->error($this->user, _('No such user.'));
+            return;
+        } else if (!$this->user->mutuallySubscribed($other)) {
+            $channel->error($this->user, _('You can\'t send a message to this user.'));
+            return;
+        } else if ($this->user->id == $other->id) {
+            $channel->error($this->user, _('Don\'t send a message to yourself; just say it to yourself quietly instead.'));
+            return;
+        }
+        $message = Message::saveNew($this->user->id, $other->id, $this->text, $channel->source());
+        if ($message) {
+            $channel->output($this->user, sprintf(_('Direct message to %s sent'), $this->other));
+        } else {
+            $channel->error($this->user, _('Error sending direct message.'));
+        }
+    }
 }
 
-class GetCommand extends Command {
-       
-       var $other = NULL;
-       
-       function __construct($user, $other) {
-               parent::__construct($user);
-               $this->other = $other;
-       }
-       
-       function execute($channel) {
-               $target_nickname = common_canonical_nickname($this->other);
-               
-               $target =
-                 common_relative_profile($this->user, $target_nickname);
+class GetCommand extends Command
+{
+    
+    var $other = null;
+    
+    function __construct($user, $other)
+    {
+        parent::__construct($user);
+        $this->other = $other;
+    }
+    
+    function execute($channel)
+    {
+        $target_nickname = common_canonical_nickname($this->other);
+        
+        $target =
+          common_relative_profile($this->user, $target_nickname);
 
-               if (!$target) {
-                       $channel->error($this->user, _('No such user.'));
-                       return;
-               }
-               $notice = $target->getCurrentNotice();
-               if (!$notice) {
-                       $channel->error($this->user, _('User has no last notice'));
-                       return;
-               }
-               $notice_content = $notice->content;
-               
-               $channel->output($this->user, $target_nickname . ": " . $notice_content);
-       }
+        if (!$target) {
+            $channel->error($this->user, _('No such user.'));
+            return;
+        }
+        $notice = $target->getCurrentNotice();
+        if (!$notice) {
+            $channel->error($this->user, _('User has no last notice'));
+            return;
+        }
+        $notice_content = $notice->content;
+        
+        $channel->output($this->user, $target_nickname . ": " . $notice_content);
+    }
 }
 
-class SubCommand extends Command {
-       
-       var $other = NULL;
-       
-       function __construct($user, $other) {
-               parent::__construct($user);
-               $this->other = $other;
-       }
-       
-       function execute($channel) {
-               
-               if (!$this->other) {
-                       $channel->error($this->user, _('Specify the name of the user to subscribe to'));
-                       return;
-               }
-               
-               $result = subs_subscribe_user($this->user, $this->other);
-               
-               if ($result == 'true') {
-                       $channel->output($this->user, sprintf(_('Subscribed to %s'), $this->other));
-               } else {
-                       $channel->error($this->user, $result);
-               }
-       }
+class SubCommand extends Command
+{
+    
+    var $other = null;
+    
+    function __construct($user, $other)
+    {
+        parent::__construct($user);
+        $this->other = $other;
+    }
+    
+    function execute($channel)
+    {
+        
+        if (!$this->other) {
+            $channel->error($this->user, _('Specify the name of the user to subscribe to'));
+            return;
+        }
+        
+        $result = subs_subscribe_user($this->user, $this->other);
+        
+        if ($result == 'true') {
+            $channel->output($this->user, sprintf(_('Subscribed to %s'), $this->other));
+        } else {
+            $channel->error($this->user, $result);
+        }
+    }
 }
 
-class UnsubCommand extends Command {
+class UnsubCommand extends Command
+{
 
-       var $other = NULL;
-       
-       function __construct($user, $other) {
-               parent::__construct($user);
-               $this->other = $other;
-       }
+    var $other = null;
+    
+    function __construct($user, $other)
+    {
+        parent::__construct($user);
+        $this->other = $other;
+    }
 
-       function execute($channel) {
-               if(!$this->other) {
-                       $channel->error($this->user, _('Specify the name of the user to unsubscribe from'));
-                       return;
-               }
-               
-               $result=subs_unsubscribe_user($this->user, $this->other);
-               
-               if ($result) {
-                       $channel->output($this->user, sprintf(_('Unsubscribed from %s'), $this->other));
-               } else {
-                       $channel->error($this->user, $result);
-               }
-       }
+    function execute($channel)
+    {
+        if(!$this->other) {
+            $channel->error($this->user, _('Specify the name of the user to unsubscribe from'));
+            return;
+        }
+        
+        $result=subs_unsubscribe_user($this->user, $this->other);
+        
+        if ($result) {
+            $channel->output($this->user, sprintf(_('Unsubscribed from %s'), $this->other));
+        } else {
+            $channel->error($this->user, $result);
+        }
+    }
 }
 
-class OffCommand extends Command {
-       var $other = NULL;
-       function __construct($user, $other=NULL) {
-               parent::__construct($user);
-               $this->other = $other;
-       }
-       function execute($channel) {
-               if ($other) {
-                       $channel->error($this->user, _("Command not yet implemented."));
-               } else {
-                       if ($channel->off($this->user)) {
-                               $channel->output($this->user, _('Notification off.'));
-                       } else {
-                               $channel->error($this->user, _('Can\'t turn off notification.'));
-                       }
-               }
-       }
+class OffCommand extends Command
+{
+    var $other = null;
+    function __construct($user, $other=null)
+    {
+        parent::__construct($user);
+        $this->other = $other;
+    }
+    function execute($channel)
+    {
+        if ($other) {
+            $channel->error($this->user, _("Command not yet implemented."));
+        } else {
+            if ($channel->off($this->user)) {
+                $channel->output($this->user, _('Notification off.'));
+            } else {
+                $channel->error($this->user, _('Can\'t turn off notification.'));
+            }
+        }
+    }
 }
 
-class OnCommand extends Command {
-       var $other = NULL;
-       function __construct($user, $other=NULL) {
-               parent::__construct($user);
-               $this->other = $other;
-       }
-       
-       function execute($channel) {
-               if ($other) {
-                       $channel->error($this->user, _("Command not yet implemented."));
-               } else {
-                       if ($channel->on($this->user)) {
-                               $channel->output($this->user, _('Notification on.'));
-                       } else {
-                               $channel->error($this->user, _('Can\'t turn on notification.'));
-                       }
-               }
-       }
+class OnCommand extends Command
+{
+    var $other = null;
+    function __construct($user, $other=null)
+    {
+        parent::__construct($user);
+        $this->other = $other;
+    }
+    
+    function execute($channel)
+    {
+        if ($other) {
+            $channel->error($this->user, _("Command not yet implemented."));
+        } else {
+            if ($channel->on($this->user)) {
+                $channel->output($this->user, _('Notification on.'));
+            } else {
+                $channel->error($this->user, _('Can\'t turn on notification.'));
+            }
+        }
+    }
 }
 
-class HelpCommand extends Command {
-       function execute($channel) {
-               $channel->output($this->user,
-                                                _("Commands:\n".
-                                                  "on - turn on notifications\n".
-                                                  "off - turn off notifications\n".
-                                                  "help - show this help\n".
-                                                  "follow <nickname> - subscribe to user\n".
-                                                  "leave <nickname> - unsubscribe from user\n".
-                                                  "d <nickname> <text> - direct message to user\n".
-                                                  "get <nickname> - get last notice from user\n".
-                                                  "whois <nickname> - get profile info on user\n".
-                                                  "fav <nickname> - add user's last notice as a 'fave'\n".
-                                                  "stats - get your stats\n".
-                                                  "stop - same as 'off'\n".
-                                                  "quit - same as 'off'\n".
-                                                  "sub <nickname> - same as 'follow'\n".
-                                                  "unsub <nickname> - same as 'leave'\n".
-                                                  "last <nickname> - same as 'get'\n".
-                                                  "on <nickname> - not yet implemented.\n".
-                                                  "off <nickname> - not yet implemented.\n".                                              
-                                                  "nudge <nickname> - not yet implemented.\n".
-                                                  "invite <phone number> - not yet implemented.\n".
-                                                  "track <word> - not yet implemented.\n".
-                                                  "untrack <word> - not yet implemented.\n".
-                                                  "track off - not yet implemented.\n".
-                                                  "untrack all - not yet implemented.\n".
-                                                  "tracks - not yet implemented.\n".
-                                                  "tracking - not yet implemented.\n"));
-       }
+class HelpCommand extends Command
+{
+    function execute($channel)
+    {
+        $channel->output($this->user,
+                         _("Commands:\n".
+                           "on - turn on notifications\n".
+                           "off - turn off notifications\n".
+                           "help - show this help\n".
+                           "follow <nickname> - subscribe to user\n".
+                           "leave <nickname> - unsubscribe from user\n".
+                           "d <nickname> <text> - direct message to user\n".
+                           "get <nickname> - get last notice from user\n".
+                           "whois <nickname> - get profile info on user\n".
+                           "fav <nickname> - add user's last notice as a 'fave'\n".
+                           "stats - get your stats\n".
+                           "stop - same as 'off'\n".
+                           "quit - same as 'off'\n".
+                           "sub <nickname> - same as 'follow'\n".
+                           "unsub <nickname> - same as 'leave'\n".
+                           "last <nickname> - same as 'get'\n".
+                           "on <nickname> - not yet implemented.\n".
+                           "off <nickname> - not yet implemented.\n".                           
+                           "nudge <nickname> - not yet implemented.\n".
+                           "invite <phone number> - not yet implemented.\n".
+                           "track <word> - not yet implemented.\n".
+                           "untrack <word> - not yet implemented.\n".
+                           "track off - not yet implemented.\n".
+                           "untrack all - not yet implemented.\n".
+                           "tracks - not yet implemented.\n".
+                           "tracking - not yet implemented.\n"));
+    }
 }
index eae315cb6b9215af2963d198ff69ebaa8608ad18..0679f5462dd4c0b03f7cfdb5b0ddc57a105ffeec 100644 (file)
@@ -21,176 +21,178 @@ if (!defined('LACONICA')) { exit(1); }
 
 require_once(INSTALLDIR.'/classes/Command.php');
 
-class CommandInterpreter {
-       
-       function handle_command($user, $text) {
-               # XXX: localise
+class CommandInterpreter
+{
 
-               $text = preg_replace('/\s+/', ' ', trim($text));
-               list($cmd, $arg) = explode(' ', $text, 2);
+    function handle_command($user, $text)
+    {
+        # XXX: localise
 
-               # We try to support all the same commands as Twitter, see
-               # http://getsatisfaction.com/twitter/topics/what_are_the_twitter_commands
-               # There are a few compatibility commands from earlier versions of 
-               # Laconica
-               
-               switch(strtolower($cmd)) {
-                case 'help':
-                       if ($arg) {
-                               return NULL;
-                       }
-                       return new HelpCommand($user);
-                case 'on':
-                       if ($arg) {
-                               list($other, $extra) = explode(' ', $arg, 2);
-                               if ($extra) {
-                                       return NULL;
-                               } else {
-                                       return new OnCommand($user, $other);
-                               }
-                       } else {
-                               return new OnCommand($user);
-                       }
-                case 'off':
-                       if ($arg) {
-                               list($other, $extra) = explode(' ', $arg, 2);
-                               if ($extra) {
-                                       return NULL;
-                               } else {
-                                       return new OffCommand($user, $other);
-                               }
-                       } else {
-                               return new OffCommand($user);
-                       }
-                case 'stop':
-                case 'quit':
-                       if ($arg) {
-                               return NULL;
-                       } else {
-                               return new OffCommand($user);
-                       }
-                case 'follow':
-                case 'sub':
-                       if (!$arg) {
-                               return NULL;
-                       }
-                       list($other, $extra) = explode(' ', $arg, 2);
-                       if ($extra) {
-                               return NULL;
-                       } else {
-                               return new SubCommand($user, $other);
-                       }
-                case 'leave':
-                case 'unsub':
-                       if (!$arg) {
-                               return NULL;
-                       }
-                       list($other, $extra) = explode(' ', $arg, 2);
-                       if ($extra) {
-                               return NULL;
-                       } else {
-                               return new UnsubCommand($user, $other);
-                       }
-                case 'get':
-                case 'last':
-                       if (!$arg) {
-                               return NULL;
-                       }
-                       list($other, $extra) = explode(' ', $arg, 2);
-                       if ($extra) {
-                               return NULL;
-                       } else {
-                               return new GetCommand($user, $other);
-                       }
-                case 'd':
-                case 'dm':
-                       if (!$arg) {
-                               return NULL;
-                       }
-                       list($other, $extra) = explode(' ', $arg, 2);
-                       if (!$extra) {
-                               return NULL;
-                       } else {
-                               return new MessageCommand($user, $other, $extra);
-                       }
-                case 'whois':
-                       if (!$arg) {
-                               return NULL;
-                       }
-                       list($other, $extra) = explode(' ', $arg, 2);
-                       if ($extra) {
-                               return NULL;
-                       } else {
-                               return new WhoisCommand($user, $other);
-                       }
-                case 'fav':
-                       if (!$arg) {
-                               return NULL;
-                       }
-                       list($other, $extra) = explode(' ', $arg, 2);
-                       if ($extra) {
-                               return NULL;
-                       } else {
-                               return new FavCommand($user, $other);
-                       }
-                case 'nudge':
-                       if (!$arg) {
-                               return NULL;
-                       }
-                       list($other, $extra) = explode(' ', $arg, 2);
-                       if ($extra) {
-                               return NULL;
-                       } else {
-                               return new NudgeCommand($user, $other);
-                       }
-                case 'stats':
-                       if ($arg) {
-                               return NULL;
-                       }
-                       return new StatsCommand($user);
-                case 'invite':
-                       if (!$arg) {
-                               return NULL;
-                       }
-                       list($other, $extra) = explode(' ', $arg, 2);
-                       if ($extra) {
-                               return NULL;
-                       } else {
-                               return new InviteCommand($user, $other);
-                       }
-                case 'track':
-                       if (!$arg) {
-                               return NULL;
-                       }
-                       list($word, $extra) = explode(' ', $arg, 2);
-                       if ($extra) {
-                               return NULL;
-                       } else if ($word == 'off') {
-                               return new TrackOffCommand($user);
-                       } else {
-                               return new TrackCommand($user, $word);
-                       }
-                case 'untrack':
-                       if (!$arg) {
-                               return NULL;
-                       }
-                       list($word, $extra) = explode(' ', $arg, 2);
-                       if ($extra) {
-                               return NULL;
-                       } else if ($word == 'all') {
-                               return new TrackOffCommand($user);
-                       } else {
-                               return new UntrackCommand($user, $word);
-                       }
-                case 'tracks':
-                case 'tracking':
-                       if ($arg) {
-                               return NULL;
-                       }
-                       return new TrackingCommand($user);
-                default:
-                       return false;
-               }
-       }
+        $text = preg_replace('/\s+/', ' ', trim($text));
+        list($cmd, $arg) = explode(' ', $text, 2);
+
+        # We try to support all the same commands as Twitter, see
+        # http://getsatisfaction.com/twitter/topics/what_are_the_twitter_commands
+        # There are a few compatibility commands from earlier versions of
+        # Laconica
+
+        switch(strtolower($cmd)) {
+         case 'help':
+            if ($arg) {
+                return null;
+            }
+            return new HelpCommand($user);
+         case 'on':
+            if ($arg) {
+                list($other, $extra) = explode(' ', $arg, 2);
+                if ($extra) {
+                    return null;
+                } else {
+                    return new OnCommand($user, $other);
+                }
+            } else {
+                return new OnCommand($user);
+            }
+         case 'off':
+            if ($arg) {
+                list($other, $extra) = explode(' ', $arg, 2);
+                if ($extra) {
+                    return null;
+                } else {
+                    return new OffCommand($user, $other);
+                }
+            } else {
+                return new OffCommand($user);
+            }
+         case 'stop':
+         case 'quit':
+            if ($arg) {
+                return null;
+            } else {
+                return new OffCommand($user);
+            }
+         case 'follow':
+         case 'sub':
+            if (!$arg) {
+                return null;
+            }
+            list($other, $extra) = explode(' ', $arg, 2);
+            if ($extra) {
+                return null;
+            } else {
+                return new SubCommand($user, $other);
+            }
+         case 'leave':
+         case 'unsub':
+            if (!$arg) {
+                return null;
+            }
+            list($other, $extra) = explode(' ', $arg, 2);
+            if ($extra) {
+                return null;
+            } else {
+                return new UnsubCommand($user, $other);
+            }
+         case 'get':
+         case 'last':
+            if (!$arg) {
+                return null;
+            }
+            list($other, $extra) = explode(' ', $arg, 2);
+            if ($extra) {
+                return null;
+            } else {
+                return new GetCommand($user, $other);
+            }
+         case 'd':
+         case 'dm':
+            if (!$arg) {
+                return null;
+            }
+            list($other, $extra) = explode(' ', $arg, 2);
+            if (!$extra) {
+                return null;
+            } else {
+                return new MessageCommand($user, $other, $extra);
+            }
+         case 'whois':
+            if (!$arg) {
+                return null;
+            }
+            list($other, $extra) = explode(' ', $arg, 2);
+            if ($extra) {
+                return null;
+            } else {
+                return new WhoisCommand($user, $other);
+            }
+         case 'fav':
+            if (!$arg) {
+                return null;
+            }
+            list($other, $extra) = explode(' ', $arg, 2);
+            if ($extra) {
+                return null;
+            } else {
+                return new FavCommand($user, $other);
+            }
+         case 'nudge':
+            if (!$arg) {
+                return null;
+            }
+            list($other, $extra) = explode(' ', $arg, 2);
+            if ($extra) {
+                return null;
+            } else {
+                return new NudgeCommand($user, $other);
+            }
+         case 'stats':
+            if ($arg) {
+                return null;
+            }
+            return new StatsCommand($user);
+         case 'invite':
+            if (!$arg) {
+                return null;
+            }
+            list($other, $extra) = explode(' ', $arg, 2);
+            if ($extra) {
+                return null;
+            } else {
+                return new InviteCommand($user, $other);
+            }
+         case 'track':
+            if (!$arg) {
+                return null;
+            }
+            list($word, $extra) = explode(' ', $arg, 2);
+            if ($extra) {
+                return null;
+            } else if ($word == 'off') {
+                return new TrackOffCommand($user);
+            } else {
+                return new TrackCommand($user, $word);
+            }
+         case 'untrack':
+            if (!$arg) {
+                return null;
+            }
+            list($word, $extra) = explode(' ', $arg, 2);
+            if ($extra) {
+                return null;
+            } else if ($word == 'all') {
+                return new TrackOffCommand($user);
+            } else {
+                return new UntrackCommand($user, $word);
+            }
+         case 'tracks':
+         case 'tracking':
+            if ($arg) {
+                return null;
+            }
+            return new TrackingCommand($user);
+         default:
+            return false;
+        }
+    }
 }
 
index 10661ff5ce9ac9015b4e7b5dd20e6b35d4fafa8f..ed3875d223c0ff5935979861a4adc5951e919040 100644 (file)
@@ -20,10 +20,12 @@ class Confirm_address extends Memcached_DataObject
     public $modified;                        // timestamp()   not_null default_CURRENT_TIMESTAMP
 
     /* Static get */
-    function staticGet($k,$v=NULL) { return Memcached_DataObject::staticGet('Confirm_address',$k,$v); }
+    function staticGet($k,$v=null)
+    { return Memcached_DataObject::staticGet('Confirm_address',$k,$v); }
 
     /* the code above is auto generated do not remove the tag below */
     ###END_AUTOCODE
 
-    function sequenceKey() { return array(false, false); }
+    function sequenceKey()
+    { return array(false, false); }
 }
index d18e6feeb93f29aca4feea99e0d8527bd0e917ae..d5b7b7e33ad440f04a5b16886692c11874f48d94 100644 (file)
@@ -16,7 +16,8 @@ class Consumer extends Memcached_DataObject
     public $modified;                        // timestamp()   not_null default_CURRENT_TIMESTAMP
 
     /* Static get */
-    function staticGet($k,$v=NULL) { return Memcached_DataObject::staticGet('Consumer',$k,$v); }
+    function staticGet($k,$v=null)
+    { return Memcached_DataObject::staticGet('Consumer',$k,$v); }
 
     /* the code above is auto generated do not remove the tag below */
     ###END_AUTOCODE
index 7cc3f585e70899ddaac787ef1cfbc5b5008223cb..24df5938c23ef1fb4b95f31a353012b43018763d 100644 (file)
@@ -15,23 +15,25 @@ class Fave extends Memcached_DataObject
     public $modified;                        // timestamp()   not_null default_CURRENT_TIMESTAMP
 
     /* Static get */
-    function staticGet($k,$v=NULL) { return Memcached_DataObject::staticGet('Fave',$k,$v); }
+    function staticGet($k,$v=null)
+    { return Memcached_DataObject::staticGet('Fave',$k,$v); }
 
     /* the code above is auto generated do not remove the tag below */
     ###END_AUTOCODE
 
-       static function addNew($user, $notice) {
-               $fave = new Fave();
-               $fave->user_id = $user->id;
-               $fave->notice_id = $notice->id;
-               if (!$fave->insert()) {
-                       common_log_db_error($fave, 'INSERT', __FILE__);
-                       return false;
-               }
-               return $fave;
-       }
-       
-       function &pkeyGet($kv) {
-               return Memcached_DataObject::pkeyGet('Fave', $kv);
-       }
+    static function addNew($user, $notice) {
+        $fave = new Fave();
+        $fave->user_id = $user->id;
+        $fave->notice_id = $notice->id;
+        if (!$fave->insert()) {
+            common_log_db_error($fave, 'INSERT', __FILE__);
+            return false;
+        }
+        return $fave;
+    }
+    
+    function &pkeyGet($kv)
+    {
+        return Memcached_DataObject::pkeyGet('Fave', $kv);
+    }
 }
index 7a625a209295039210b3b8f1a84405b97b05d002..afc0e2180455644130c757e351303f23c6538e5e 100644 (file)
@@ -4,7 +4,7 @@
  */
 require_once INSTALLDIR.'/classes/Memcached_DataObject.php';
 
-class Foreign_link extends Memcached_DataObject 
+class Foreign_link extends Memcached_DataObject
 {
     ###START_AUTOCODE
     /* the code below is auto generated do not remove the above tag */
@@ -13,7 +13,7 @@ class Foreign_link extends Memcached_DataObject
     public $user_id;                         // int(4)  primary_key not_null
     public $foreign_id;                      // int(4)  primary_key not_null
     public $service;                         // int(4)  primary_key not_null
-    public $credentials;                     // varchar(255)  
+    public $credentials;                     // varchar(255)
     public $noticesync;                      // tinyint(1)   not_null default_1
     public $friendsync;                      // tinyint(1)   not_null default_2
     public $profilesync;                     // tinyint(1)   not_null default_1
@@ -21,56 +21,84 @@ class Foreign_link extends Memcached_DataObject
     public $modified;                        // timestamp()   not_null default_CURRENT_TIMESTAMP
 
     /* Static get */
-    function staticGet($k,$v=NULL) { return Memcached_DataObject::staticGet('Foreign_link',$k,$v); }
+    function staticGet($k,$v=null)
+    { return Memcached_DataObject::staticGet('Foreign_link',$k,$v); }
 
     /* the code above is auto generated do not remove the tag below */
     ###END_AUTOCODE
 
-       // XXX:  This only returns a 1->1 single obj mapping.  Change?  Or make
-       // a getForeignUsers() that returns more than one? --Zach
-       static function getByUserID($user_id, $service) {
-               $flink = new Foreign_link();
-               $flink->service = $service;
-               $flink->user_id = $user_id;
-               $flink->limit(1);
-
-               if ($flink->find(TRUE)) {
-                       return $flink;
-               }
-
-               return NULL;            
-       }
-       
-       static function getByForeignID($foreign_id, $service) {
-               $flink = new Foreign_link();
-               $flink->service = $service;
-               $flink->foreign_id = $foreign_id;
-               $flink->limit(1);
-
-               if ($flink->find(TRUE)) {
-                       return $flink;
-               }
-
-               return NULL;            
-       }
-               
-       # Convenience methods
-       function getForeignUser() {             
-               $fuser = new Foreign_user();
-               $fuser->service = $this->service;
-               $fuser->id = $this->foreign_id;
-               
-               $fuser->limit(1);
-               
-               if ($fuser->find(TRUE)) {
-                       return $fuser;
-               }
-               
-               return NULL;            
-       }
-       
-       function getUser() {
-               return User::staticGet($this->user_id);
-       }
-               
+    // XXX:  This only returns a 1->1 single obj mapping.  Change?  Or make
+    // a getForeignUsers() that returns more than one? --Zach
+    static function getByUserID($user_id, $service)
+    {
+        $flink = new Foreign_link();
+        $flink->service = $service;
+        $flink->user_id = $user_id;
+        $flink->limit(1);
+
+        if ($flink->find(true)) {
+            return $flink;
+        }
+
+        return null;
+    }
+
+    static function getByForeignID($foreign_id, $service)
+    {
+        $flink = new Foreign_link();
+        $flink->service = $service;
+        $flink->foreign_id = $foreign_id;
+        $flink->limit(1);
+
+        if ($flink->find(true)) {
+            return $flink;
+        }
+
+        return null;
+    }
+
+    function set_flags($noticesync, $replysync, $friendsync)
+    {
+        if ($noticesync) {
+            $this->noticesync |= FOREIGN_NOTICE_SEND;
+        } else {
+            $this->noticesync &= ~FOREIGN_NOTICE_SEND;
+        }
+
+        if ($replysync) {
+            $this->noticesync |= FOREIGN_NOTICE_SEND_REPLY;
+        } else {
+            $this->noticesync &= ~FOREIGN_NOTICE_SEND_REPLY;
+        }
+
+        if ($friendsync) {
+            $this->friendsync |= FOREIGN_FRIEND_RECV;
+        } else {
+            $this->friendsync &= ~FOREIGN_FRIEND_RECV;
+        }
+
+        $this->profilesync = 0;
+    }
+
+    # Convenience methods
+    function getForeignUser()
+    {
+        $fuser = new Foreign_user();
+        $fuser->service = $this->service;
+        $fuser->id = $this->foreign_id;
+
+        $fuser->limit(1);
+
+        if ($fuser->find(true)) {
+            return $fuser;
+        }
+
+        return null;
+    }
+
+    function getUser()
+    {
+        return User::staticGet($this->user_id);
+    }
+
 }
index 18ef83d6991f2b5453a93bf9d99aafad8eac64de..ef614dbd6e08a28fc20b2f8221a0ab2341bd1249 100644 (file)
@@ -17,7 +17,8 @@ class Foreign_service extends Memcached_DataObject
     public $modified;                        // timestamp()   not_null default_CURRENT_TIMESTAMP
 
     /* Static get */
-    function staticGet($k,$v=NULL) { return Memcached_DataObject::staticGet('Foreign_service',$k,$v); }
+    function staticGet($k,$v=null)
+    { return Memcached_DataObject::staticGet('Foreign_service',$k,$v); }
 
     /* the code above is auto generated do not remove the tag below */
     ###END_AUTOCODE
index 31506406724c7d4d1c41843e2c0a9b59bb52acef..d508606218f3946bda976c206dc265477aab85d6 100644 (file)
@@ -16,7 +16,8 @@ class Foreign_subscription extends Memcached_DataObject
     public $created;                         // datetime()   not_null
 
     /* Static get */
-    function staticGet($k,$v=NULL) { return Memcached_DataObject::staticGet('Foreign_subscription',$k,$v); }
+    function staticGet($k,$v=null)
+    { return Memcached_DataObject::staticGet('Foreign_subscription',$k,$v); }
 
     /* the code above is auto generated do not remove the tag below */
     ###END_AUTOCODE
index 027fae69d16e2839732468b2be6e6a28931700ef..61727abe5ed5924d6a8a7bb41eb721a2d672cefc 100644 (file)
@@ -18,53 +18,55 @@ class Foreign_user extends Memcached_DataObject
     public $modified;                        // timestamp()   not_null default_CURRENT_TIMESTAMP
 
     /* Static get */
-    function staticGet($k,$v=NULL) { return Memcached_DataObject::staticGet('Foreign_user',$k,$v); }
+    function staticGet($k,$v=null)
+    { return Memcached_DataObject::staticGet('Foreign_user',$k,$v); }
 
     /* the code above is auto generated do not remove the tag below */
     ###END_AUTOCODE
-       
-       // XXX:  This only returns a 1->1 single obj mapping.  Change?  Or make
-       // a getForeignUsers() that returns more than one? --Zach
-       static function getForeignUser($id, $service) {         
-               $fuser = new Foreign_user();
-               $fuser->whereAdd("service = $service");
-               $fuser->whereAdd("id = $id");
-               $fuser->limit(1);
-               
-               if ($fuser->find()) {
-                       $fuser->fetch();
-                       return $fuser;
-               }
-               
-               return NULL;            
-       }
-       
-       function updateKeys(&$orig) {
-               $parts = array();
-               foreach (array('id', 'service', 'uri', 'nickname') as $k) {
-                       if (strcmp($this->$k, $orig->$k) != 0) {
-                               $parts[] = $k . ' = ' . $this->_quote($this->$k);
-                       }
-               }
-               if (count($parts) == 0) {
-                       # No changes
-                       return true;
-               }
-               $toupdate = implode(', ', $parts);
+    
+    // XXX:  This only returns a 1->1 single obj mapping.  Change?  Or make
+    // a getForeignUsers() that returns more than one? --Zach
+    static function getForeignUser($id, $service) {        
+        $fuser = new Foreign_user();
+        $fuser->whereAdd("service = $service");
+        $fuser->whereAdd("id = $id");
+        $fuser->limit(1);
+        
+        if ($fuser->find()) {
+            $fuser->fetch();
+            return $fuser;
+        }
+        
+        return null;        
+    }
+    
+    function updateKeys(&$orig)
+    {
+        $parts = array();
+        foreach (array('id', 'service', 'uri', 'nickname') as $k) {
+            if (strcmp($this->$k, $orig->$k) != 0) {
+                $parts[] = $k . ' = ' . $this->_quote($this->$k);
+            }
+        }
+        if (count($parts) == 0) {
+            # No changes
+            return true;
+        }
+        $toupdate = implode(', ', $parts);
 
-               $table = $this->tableName();
-               if(common_config('db','quote_identifiers')) {
-                       $table = '"' . $table . '"';
-               }
-               $qry = 'UPDATE ' . $table . ' SET ' . $toupdate .
-                 ' WHERE id = ' . $this->id;
-               $orig->decache();
-               $result = $this->query($qry);
-               if ($result) {
-                       $this->encache();
-               }
-               return $result;
-       }
+        $table = $this->tableName();
+        if(common_config('db','quote_identifiers')) {
+            $table = '"' . $table . '"';
+        }
+        $qry = 'UPDATE ' . $table . ' SET ' . $toupdate .
+          ' WHERE id = ' . $this->id;
+        $orig->decache();
+        $result = $this->query($qry);
+        if ($result) {
+            $this->encache();
+        }
+        return $result;
+    }
 
-       
+    
 }
index 1477391b0ed115ce69b68c8151d0524f701b4fa4..8a36fd8df1678418760efe419461f938a07fa4ce 100644 (file)
@@ -17,7 +17,8 @@ class Invitation extends Memcached_DataObject
     public $created;                         // datetime()   not_null
 
     /* Static get */
-    function staticGet($k,$v=NULL) { return Memcached_DataObject::staticGet('Invitation',$k,$v); }
+    function staticGet($k,$v=null)
+    { return Memcached_DataObject::staticGet('Invitation',$k,$v); }
 
     /* the code above is auto generated do not remove the tag below */
     ###END_AUTOCODE
index 7a33e158dd1e2dffa9ee0f4300b11bf5704a7237..b9f599dbc8edc0a6d6b4664502f6abf1bfd6916e 100644 (file)
@@ -23,154 +23,164 @@ require_once INSTALLDIR.'/classes/Memcached_DataObject.php';
 
 class Memcached_DataObject extends DB_DataObject 
 {
-    function &staticGet($cls, $k, $v=NULL) {
-               if (is_null($v)) {
-                       $v = $k;
-                       # XXX: HACK!
-                       $i = new $cls;
-                       $keys = $i->keys();
-                       $k = $keys[0];
-                       unset($i);
-               }
-               $i = Memcached_DataObject::getcached($cls, $k, $v);
-               if ($i) {
-                       return $i;
-               } else {
-                       $i = DB_DataObject::staticGet($cls, $k, $v);
-                       if ($i) {
-                               $i->encache();
-                       }
-                       return $i;
-               }
-       }
+    function &staticGet($cls, $k, $v=null)
+    {
+        if (is_null($v)) {
+            $v = $k;
+            # XXX: HACK!
+            $i = new $cls;
+            $keys = $i->keys();
+            $k = $keys[0];
+            unset($i);
+        }
+        $i = Memcached_DataObject::getcached($cls, $k, $v);
+        if ($i) {
+            return $i;
+        } else {
+            $i = DB_DataObject::staticGet($cls, $k, $v);
+            if ($i) {
+                $i->encache();
+            }
+            return $i;
+        }
+    }
 
-       function &pkeyGet($cls, $kv) {
-               $i = Memcached_DataObject::multicache($cls, $kv);
-               if ($i) {
-                       return $i;
-               } else {
-                       $i = new $cls();
-                       foreach ($kv as $k => $v) {
-                               $i->$k = $v;
-                       }
-                       if ($i->find(true)) {
-                               $i->encache();
-                       } else {
-                               $i = NULL;
-                       }
+    function &pkeyGet($cls, $kv)
+    {
+        $i = Memcached_DataObject::multicache($cls, $kv);
+        if ($i) {
+            return $i;
+        } else {
+            $i = new $cls();
+            foreach ($kv as $k => $v) {
+                $i->$k = $v;
+            }
+            if ($i->find(true)) {
+                $i->encache();
+            } else {
+                $i = null;
+            }
             return $i;
-               }
-       }
+        }
+    }
 
-       function insert() {
-               $result = parent::insert();
-               return $result;
-       }
-       
-       function update($orig=NULL) {
-               if (is_object($orig) && $orig instanceof Memcached_DataObject) {
-                       $orig->decache(); # might be different keys
-               }
-               $result = parent::update($orig);
-               if ($result) {
-                       $this->encache();
-               }
-               return $result;
-       }
-       
-       function delete() {
-               $this->decache(); # while we still have the values!
-               return parent::delete();
-       }
-       
-       static function memcache() {
-               return common_memcache();
-       }
-       
-       static function cacheKey($cls, $k, $v) {
-               return common_cache_key(strtolower($cls).':'.$k.':'.$v);
-       }
-       
-       static function getcached($cls, $k, $v) {
-               $c = Memcached_DataObject::memcache();
-               if (!$c) {
-                       return false;
-               } else {
-                       return $c->get(Memcached_DataObject::cacheKey($cls, $k, $v));
-               }
-       }
+    function insert()
+    {
+        $result = parent::insert();
+        return $result;
+    }
+    
+    function update($orig=null)
+    {
+        if (is_object($orig) && $orig instanceof Memcached_DataObject) {
+            $orig->decache(); # might be different keys
+        }
+        $result = parent::update($orig);
+        if ($result) {
+            $this->encache();
+        }
+        return $result;
+    }
+    
+    function delete()
+    {
+        $this->decache(); # while we still have the values!
+        return parent::delete();
+    }
+    
+    static function memcache() {
+        return common_memcache();
+    }
+    
+    static function cacheKey($cls, $k, $v) {
+        return common_cache_key(strtolower($cls).':'.$k.':'.$v);
+    }
+    
+    static function getcached($cls, $k, $v) {
+        $c = Memcached_DataObject::memcache();
+        if (!$c) {
+            return false;
+        } else {
+            return $c->get(Memcached_DataObject::cacheKey($cls, $k, $v));
+        }
+    }
 
-       function keyTypes() {
-               global $_DB_DATAOBJECT;
+    function keyTypes()
+    {
+        global $_DB_DATAOBJECT;
         if (!isset($_DB_DATAOBJECT['INI'][$this->_database][$this->__table."__keys"])) {
-                       $this->databaseStructure();
+            $this->databaseStructure();
 
         }
-               return $_DB_DATAOBJECT['INI'][$this->_database][$this->__table."__keys"];
-       }
-       
-       function encache() {
-               $c = $this->memcache();
-               if (!$c) {
-                       return false;
-               } else {
-                       $pkey = array();
-                       $pval = array();                        
-                       $types = $this->keyTypes();
-                       ksort($types);
-                       foreach ($types as $key => $type) {
-                               if ($type == 'K') {
-                                       $pkey[] = $key;
-                                       $pval[] = $this->$key;
-                               } else {
-                                       $c->set($this->cacheKey($this->tableName(), $key, $this->$key), $this);
-                               }
-                       }
-                       # XXX: should work for both compound and scalar pkeys
-                       $pvals = implode(',', $pval);
-                       $pkeys = implode(',', $pkey);
-                       $c->set($this->cacheKey($this->tableName(), $pkeys, $pvals), $this);
-               }
-       }
-       
-       function decache() {
-               $c = $this->memcache();
-               if (!$c) {
-                       return false;
-               } else {
-                       $pkey = array();
-                       $pval = array();                        
-                       $types = $this->keyTypes();
-                       ksort($types);
-                       foreach ($types as $key => $type) {
-                               if ($type == 'K') {
-                                       $pkey[] = $key;
-                                       $pval[] = $this->$key;
-                               } else {
-                                       $c->delete($this->cacheKey($this->tableName(), $key, $this->$key));
-                               }
-                       }
-                       # should work for both compound and scalar pkeys
-                       # XXX: comma works for now but may not be safe separator for future keys
-                       $pvals = implode(',', $pval);
-                       $pkeys = implode(',', $pkey);
-                       $c->delete($this->cacheKey($this->tableName(), $pkeys, $pvals));
-               }
-       }
+        return $_DB_DATAOBJECT['INI'][$this->_database][$this->__table."__keys"];
+    }
+    
+    function encache()
+    {
+        $c = $this->memcache();
+        if (!$c) {
+            return false;
+        } else {
+            $pkey = array();
+            $pval = array();            
+            $types = $this->keyTypes();
+            ksort($types);
+            foreach ($types as $key => $type) {
+                if ($type == 'K') {
+                    $pkey[] = $key;
+                    $pval[] = $this->$key;
+                } else {
+                    $c->set($this->cacheKey($this->tableName(), $key, $this->$key), $this);
+                }
+            }
+            # XXX: should work for both compound and scalar pkeys
+            $pvals = implode(',', $pval);
+            $pkeys = implode(',', $pkey);
+            $c->set($this->cacheKey($this->tableName(), $pkeys, $pvals), $this);
+        }
+    }
+    
+    function decache()
+    {
+        $c = $this->memcache();
+        if (!$c) {
+            return false;
+        } else {
+            $pkey = array();
+            $pval = array();            
+            $types = $this->keyTypes();
+            ksort($types);
+            foreach ($types as $key => $type) {
+                if ($type == 'K') {
+                    $pkey[] = $key;
+                    $pval[] = $this->$key;
+                } else {
+                    $c->delete($this->cacheKey($this->tableName(), $key, $this->$key));
+                }
+            }
+            # should work for both compound and scalar pkeys
+            # XXX: comma works for now but may not be safe separator for future keys
+            $pvals = implode(',', $pval);
+            $pkeys = implode(',', $pkey);
+            $c->delete($this->cacheKey($this->tableName(), $pkeys, $pvals));
+        }
+    }
 
-       function multicache($cls, $kv) {
-               ksort($kv);
-               $c = Memcached_DataObject::memcache();
-               if (!$c) {
-                       return false;
-               } else {
-                       $pkeys = implode(',', array_keys($kv));
-                       $pvals = implode(',', array_values($kv));
-                       return $c->get(Memcached_DataObject::cacheKey($cls, $pkeys, $pvals));
-               }
-       }
+    function multicache($cls, $kv)
+    {
+        ksort($kv);
+        $c = Memcached_DataObject::memcache();
+        if (!$c) {
+            return false;
+        } else {
+            $pkeys = implode(',', array_keys($kv));
+            $pvals = implode(',', array_values($kv));
+            return $c->get(Memcached_DataObject::cacheKey($cls, $pkeys, $pvals));
+        }
+    }
 
-    function getSearchEngine($table) {
+    function getSearchEngine($table)
+    {
         require_once INSTALLDIR.'/lib/search_engines.php';
         static $search_engine;
         if (!isset($search_engine)) {
index ef4bd03161cf2978c866acd4ed45f4af8043fb4c..4806057b4ca1183fa6c752fde2e0ce03c4f20ee0 100644 (file)
@@ -22,47 +22,50 @@ class Message extends Memcached_DataObject
     public $source;                          // varchar(32)  
 
     /* Static get */
-    function staticGet($k,$v=NULL) { return Memcached_DataObject::staticGet('Message',$k,$v); }
+    function staticGet($k,$v=null)
+    { return Memcached_DataObject::staticGet('Message',$k,$v); }
 
     /* the code above is auto generated do not remove the tag below */
     ###END_AUTOCODE
-       
-       function getFrom() {
-               return Profile::staticGet('id', $this->from_profile);
-       }
-       
-       function getTo() {
-               return Profile::staticGet('id', $this->to_profile);
-       }
-       
-       static function saveNew($from, $to, $content, $source) {
-               
-               $msg = new Message();
-               
-               $msg->from_profile = $from;
-               $msg->to_profile = $to;
-               $msg->content = common_shorten_links($content);
-               $msg->rendered = common_render_text($content);
-               $msg->created = common_sql_now();
-               $msg->source = $source;
-               
-               $result = $msg->insert();
-               
-               if (!$result) {
-                       common_log_db_error($msg, 'INSERT', __FILE__);
-                       return _('Could not insert message.');
-               }
-               
-               $orig = clone($msg);
-               $msg->uri = common_local_url('showmessage', array('message' => $msg->id));
-               
-               $result = $msg->update($orig);
-               
-               if (!$result) {
-                       common_log_db_error($msg, 'UPDATE', __FILE__);
-                       return _('Could not update message with new URI.');
-               }
-               
-               return $msg;
-       }
+    
+    function getFrom()
+    {
+        return Profile::staticGet('id', $this->from_profile);
+    }
+    
+    function getTo()
+    {
+        return Profile::staticGet('id', $this->to_profile);
+    }
+    
+    static function saveNew($from, $to, $content, $source) {
+        
+        $msg = new Message();
+        
+        $msg->from_profile = $from;
+        $msg->to_profile = $to;
+        $msg->content = common_shorten_links($content);
+        $msg->rendered = common_render_text($content);
+        $msg->created = common_sql_now();
+        $msg->source = $source;
+        
+        $result = $msg->insert();
+        
+        if (!$result) {
+            common_log_db_error($msg, 'INSERT', __FILE__);
+            return _('Could not insert message.');
+        }
+        
+        $orig = clone($msg);
+        $msg->uri = common_local_url('showmessage', array('message' => $msg->id));
+        
+        $result = $msg->update($orig);
+        
+        if (!$result) {
+            common_log_db_error($msg, 'UPDATE', __FILE__);
+            return _('Could not update message with new URI.');
+        }
+        
+        return $msg;
+    }
 }
index 89d673c532f7ab747c6417f48f8b5a4377e2ba11..2c0edfa14d70561bb4c6341310a93ddd3c837ef0 100644 (file)
@@ -18,7 +18,8 @@ class Nonce extends Memcached_DataObject
     public $modified;                        // timestamp()   not_null default_CURRENT_TIMESTAMP
 
     /* Static get */
-    function staticGet($k,$v=NULL) { return Memcached_DataObject::staticGet('Nonce',$k,$v); }
+    function staticGet($k,$v=null)
+    { return Memcached_DataObject::staticGet('Nonce',$k,$v); }
 
     /* the code above is auto generated do not remove the tag below */
     ###END_AUTOCODE
index ca8283bcef35221d2a952dd6d284d565d43ca804..3eb6530669bdc2d56c958930f68cd9bf3ad30446 100644 (file)
  *
  * 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
+ * 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/>.
+ * along with this program.     If not, see <http://www.gnu.org/licenses/>.
  */
 
 if (!defined('LACONICA')) { exit(1); }
@@ -31,69 +31,73 @@ define('NOTICE_CACHE_WINDOW', 61);
 
 class Notice extends Memcached_DataObject
 {
-       ###START_AUTOCODE
-       /* the code below is auto generated do not remove the above tag */
-
-       public $__table = 'notice';                                                      // table name
-       public $id;                                                              // int(4)      primary_key not_null
-       public $profile_id;                                              // int(4)       not_null
-       public $uri;                                                     // varchar(255)  unique_key
-       public $content;                                                 // varchar(140)
-       public $rendered;                                                // text()
-       public $url;                                                     // varchar(255)
-       public $created;                                                 // datetime()   not_null
-       public $modified;                                                // timestamp()   not_null default_CURRENT_TIMESTAMP
-       public $reply_to;                                                // int(4)
-       public $is_local;                                                // tinyint(1)
-       public $source;                                                  // varchar(32)
-
-       /* Static get */
-       function staticGet($k,$v=NULL) { return Memcached_DataObject::staticGet('Notice',$k,$v); }
-
-       /* the code above is auto generated do not remove the tag below */
-       ###END_AUTOCODE
-
-       function getProfile() {
-               return Profile::staticGet('id', $this->profile_id);
-       }
-
-       function delete() {
-               $this->blowCaches(true);
-               $this->blowFavesCache(true);
-               $this->blowInboxes();
-               return parent::delete();
-       }
-
-       function saveTags() {
-               /* extract all #hastags */
-               $count = preg_match_all('/(?:^|\s)#([A-Za-z0-9_\-\.]{1,64})/', strtolower($this->content), $match);
-               if (!$count) {
-                       return true;
-               }
-
-               /* elide characters we don't want in the tag */
-               $match[1] = str_replace(array('-', '_', '.'), '', $match[1]);
-
-               /* Add them to the database */
-               foreach(array_unique($match[1]) as $hashtag) {
-                       $tag = DB_DataObject::factory('Notice_tag');
-                       $tag->notice_id = $this->id;
-                       $tag->tag = $hashtag;
-                       $tag->created = $this->created;
-                       $id = $tag->insert();
-                       if (!$id) {
-                               $last_error = PEAR::getStaticProperty('DB_DataObject','lastError');
-                               common_log(LOG_ERR, 'DB error inserting hashtag: ' . $last_error->message);
-                               common_server_error(sprintf(_('DB error inserting hashtag: %s'), $last_error->message));
-                               return;
-                       }
-               }
-               return true;
-       }
-
-       static function saveNew($profile_id, $content, $source=NULL, $is_local=1, $reply_to=NULL, $uri=NULL) {
-
-               $profile = Profile::staticGet($profile_id);
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'notice';                             // table name
+    public $id;                                 // int(4)    primary_key not_null
+    public $profile_id;                         // int(4)     not_null
+    public $uri;                             // varchar(255)  unique_key
+    public $content;                         // varchar(140)
+    public $rendered;                         // text()
+    public $url;                             // varchar(255)
+    public $created;                         // datetime()     not_null
+    public $modified;                         // timestamp()      not_null default_CURRENT_TIMESTAMP
+    public $reply_to;                         // int(4)
+    public $is_local;                         // tinyint(1)
+    public $source;                             // varchar(32)
+
+    /* Static get */
+    function staticGet($k,$v=null)
+    { return Memcached_DataObject::staticGet('Notice',$k,$v); }
+
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+
+    function getProfile()
+    {
+        return Profile::staticGet('id', $this->profile_id);
+    }
+
+    function delete()
+    {
+        $this->blowCaches(true);
+        $this->blowFavesCache(true);
+        $this->blowInboxes();
+        return parent::delete();
+    }
+
+    function saveTags()
+    {
+        /* extract all #hastags */
+        $count = preg_match_all('/(?:^|\s)#([A-Za-z0-9_\-\.]{1,64})/', strtolower($this->content), $match);
+        if (!$count) {
+            return true;
+        }
+
+        /* elide characters we don't want in the tag */
+        $match[1] = str_replace(array('-', '_', '.'), '', $match[1]);
+
+        /* Add them to the database */
+        foreach(array_unique($match[1]) as $hashtag) {
+            $tag = DB_DataObject::factory('Notice_tag');
+            $tag->notice_id = $this->id;
+            $tag->tag = $hashtag;
+            $tag->created = $this->created;
+            $id = $tag->insert();
+            if (!$id) {
+                $last_error = PEAR::getStaticProperty('DB_DataObject','lastError');
+                common_log(LOG_ERR, 'DB error inserting hashtag: ' . $last_error->message);
+                common_server_error(sprintf(_('DB error inserting hashtag: %s'), $last_error->message));
+                return;
+            }
+        }
+        return true;
+    }
+
+    static function saveNew($profile_id, $content, $source=null, $is_local=1, $reply_to=null, $uri=null) {
+
+        $profile = Profile::staticGet($profile_id);
 
         if (!$profile) {
             common_log(LOG_ERR, 'Problem saving notice. Unknown user.');
@@ -102,69 +106,69 @@ class Notice extends Memcached_DataObject
 
         if (common_config('throttle', 'enabled') && !Notice::checkEditThrottle($profile_id)) {
             common_log(LOG_WARNING, 'Excessive posting by profile #' . $profile_id . '; throttled.');
-                       return _('Too many notices too fast; take a breather and post again in a few minutes.');
+            return _('Too many notices too fast; take a breather and post again in a few minutes.');
         }
 
-               $banned = common_config('profile', 'banned');
+        $banned = common_config('profile', 'banned');
 
-               if ( in_array($profile_id, $banned) || in_array($profile->nickname, $banned)) {
-                       common_log(LOG_WARNING, "Attempted post from banned user: $profile->nickname (user id = $profile_id).");
+        if ( in_array($profile_id, $banned) || in_array($profile->nickname, $banned)) {
+            common_log(LOG_WARNING, "Attempted post from banned user: $profile->nickname (user id = $profile_id).");
             return _('You are banned from posting notices on this site.');
-               }
+        }
 
-               $notice = new Notice();
-               $notice->profile_id = $profile_id;
+        $notice = new Notice();
+        $notice->profile_id = $profile_id;
 
-               $blacklist = common_config('public', 'blacklist');
+        $blacklist = common_config('public', 'blacklist');
 
-               # Blacklisted are non-false, but not 1, either
+        # Blacklisted are non-false, but not 1, either
 
-               if ($blacklist && in_array($profile_id, $blacklist)) {
-                       $notice->is_local = -1;
-               } else {
-                       $notice->is_local = $is_local;
-               }
+        if ($blacklist && in_array($profile_id, $blacklist)) {
+            $notice->is_local = -1;
+        } else {
+            $notice->is_local = $is_local;
+        }
 
-               $notice->reply_to = $reply_to;
-               $notice->created = common_sql_now();
-               $notice->content = common_shorten_links($content);
-               $notice->rendered = common_render_content($notice->content, $notice);
-               $notice->source = $source;
-               $notice->uri = $uri;
+        $notice->reply_to = $reply_to;
+        $notice->created = common_sql_now();
+        $notice->content = common_shorten_links($content);
+        $notice->rendered = common_render_content($notice->content, $notice);
+        $notice->source = $source;
+        $notice->uri = $uri;
 
-               $id = $notice->insert();
+        $id = $notice->insert();
 
-               if (!$id) {
-                       common_log_db_error($notice, 'INSERT', __FILE__);
-                       return _('Problem saving notice.');
-               }
+        if (!$id) {
+            common_log_db_error($notice, 'INSERT', __FILE__);
+            return _('Problem saving notice.');
+        }
 
-               # Update the URI after the notice is in the database
-               if (!$uri) {
-                       $orig = clone($notice);
-                       $notice->uri = common_notice_uri($notice);
+        # Update the URI after the notice is in the database
+        if (!$uri) {
+            $orig = clone($notice);
+            $notice->uri = common_notice_uri($notice);
 
-                       if (!$notice->update($orig)) {
-                               common_log_db_error($notice, 'UPDATE', __FILE__);
-                               return _('Problem saving notice.');
-                       }
-               }
+            if (!$notice->update($orig)) {
+                common_log_db_error($notice, 'UPDATE', __FILE__);
+                return _('Problem saving notice.');
+            }
+        }
 
-               # XXX: do we need to change this for remote users?
+        # XXX: do we need to change this for remote users?
 
-               common_save_replies($notice);
-               $notice->saveTags();
+        common_save_replies($notice);
+        $notice->saveTags();
 
-               # Clear the cache for subscribed users, so they'll update at next request
-               # XXX: someone clever could prepend instead of clearing the cache
+        # Clear the cache for subscribed users, so they'll update at next request
+        # XXX: someone clever could prepend instead of clearing the cache
 
-               if (common_config('memcached', 'enabled')) {
-                       $notice->blowCaches();
-               }
+        if (common_config('memcached', 'enabled')) {
+            $notice->blowCaches();
+        }
 
-               $notice->addToInboxes();
-               return $notice;
-       }
+        $notice->addToInboxes();
+        return $notice;
+    }
 
     static function checkEditThrottle($profile_id) {
         $profile = Profile::staticGet($profile_id);
@@ -184,356 +188,366 @@ class Notice extends Memcached_DataObject
         return true;
     }
 
-       function blowCaches($blowLast=false) {
-               $this->blowSubsCache($blowLast);
-               $this->blowNoticeCache($blowLast);
-               $this->blowRepliesCache($blowLast);
-               $this->blowPublicCache($blowLast);
-               $this->blowTagCache($blowLast);
-       }
-
-       function blowTagCache($blowLast=false) {
-               $cache = common_memcache();
-               if ($cache) {
-                       $tag = new Notice_tag();
-                       $tag->notice_id = $this->id;
-                       if ($tag->find()) {
-                               while ($tag->fetch()) {
-                                       $cache->delete(common_cache_key('notice_tag:notice_stream:' . $tag->tag));
-                                       if ($blowLast) {
-                                               $cache->delete(common_cache_key('notice_tag:notice_stream:' . $tag->tag . ';last'));
-                                       }
-                               }
-                       }
-                       $tag->free();
-                       unset($tag);
-               }
-       }
-
-       function blowSubsCache($blowLast=false) {
-               $cache = common_memcache();
-               if ($cache) {
-                       $user = new User();
-
-                       $user->query('SELECT id ' .
-                                                'FROM user JOIN subscription ON user.id = subscription.subscriber ' .
-                                                'WHERE subscription.subscribed = ' . $this->profile_id);
-
-                       while ($user->fetch()) {
-                               $cache->delete(common_cache_key('user:notices_with_friends:' . $user->id));
-                               if ($blowLast) {
-                                       $cache->delete(common_cache_key('user:notices_with_friends:' . $user->id . ';last'));
-                               }
-                       }
-                       $user->free();
-                       unset($user);
-               }
-       }
-
-       function blowNoticeCache($blowLast=false) {
-               if ($this->is_local) {
-                       $cache = common_memcache();
-                       if ($cache) {
-                               $cache->delete(common_cache_key('profile:notices:'.$this->profile_id));
-                               if ($blowLast) {
-                                       $cache->delete(common_cache_key('profile:notices:'.$this->profile_id.';last'));
-                               }
-                       }
-               }
-       }
-
-       function blowRepliesCache($blowLast=false) {
-               $cache = common_memcache();
-               if ($cache) {
-                       $reply = new Reply();
-                       $reply->notice_id = $this->id;
-                       if ($reply->find()) {
-                               while ($reply->fetch()) {
-                                       $cache->delete(common_cache_key('user:replies:'.$reply->profile_id));
-                                       if ($blowLast) {
-                                               $cache->delete(common_cache_key('user:replies:'.$reply->profile_id.';last'));
-                                       }
-                               }
-                       }
-                       $reply->free();
-                       unset($reply);
-               }
-       }
-
-       function blowPublicCache($blowLast=false) {
-               if ($this->is_local == 1) {
-                       $cache = common_memcache();
-                       if ($cache) {
-                               $cache->delete(common_cache_key('public'));
-                               if ($blowLast) {
-                                       $cache->delete(common_cache_key('public').';last');
-                               }
-                       }
-               }
-       }
-
-       function blowFavesCache($blowLast=false) {
-               $cache = common_memcache();
-               if ($cache) {
-                       $fave = new Fave();
-                       $fave->notice_id = $this->id;
-                       if ($fave->find()) {
-                               while ($fave->fetch()) {
-                                       $cache->delete(common_cache_key('user:faves:'.$fave->user_id));
-                                       if ($blowLast) {
-                                               $cache->delete(common_cache_key('user:faves:'.$fave->user_id.';last'));
-                                       }
-                               }
-                       }
-                       $fave->free();
-                       unset($fave);
-               }
-       }
-
-       # XXX: too many args; we need to move to named params or even a separate
-       # class for notice streams
-
-       static function getStream($qry, $cachekey, $offset=0, $limit=20, $since_id=0, $before_id=0, $order=NULL, $since=NULL) {
-
-               if (common_config('memcached', 'enabled')) {
-
-                       # Skip the cache if this is a since, since_id or before_id qry
-                       if ($since_id > 0 || $before_id > 0 || $since) {
-                               return Notice::getStreamDirect($qry, $offset, $limit, $since_id, $before_id, $order, $since);
-                       } else {
-                               return Notice::getCachedStream($qry, $cachekey, $offset, $limit, $order);
-                       }
-               }
-
-               return Notice::getStreamDirect($qry, $offset, $limit, $since_id, $before_id, $order, $since);
-       }
-
-       static function getStreamDirect($qry, $offset, $limit, $since_id, $before_id, $order, $since) {
-
-               $needAnd = FALSE;
-               $needWhere = TRUE;
-
-               if (preg_match('/\bWHERE\b/i', $qry)) {
-                       $needWhere = FALSE;
-                       $needAnd = TRUE;
-               }
-
-               if ($since_id > 0) {
-
-                       if ($needWhere) {
-                               $qry .= ' WHERE ';
-                               $needWhere = FALSE;
-                       } else {
-                               $qry .= ' AND ';
-                       }
-
-                       $qry .= ' notice.id > ' . $since_id;
-               }
-
-               if ($before_id > 0) {
-
-                       if ($needWhere) {
-                               $qry .= ' WHERE ';
-                               $needWhere = FALSE;
-                       } else {
-                               $qry .= ' AND ';
-                       }
-
-                       $qry .= ' notice.id < ' . $before_id;
-               }
+    function blowCaches($blowLast=false)
+    {
+        $this->blowSubsCache($blowLast);
+        $this->blowNoticeCache($blowLast);
+        $this->blowRepliesCache($blowLast);
+        $this->blowPublicCache($blowLast);
+        $this->blowTagCache($blowLast);
+    }
+
+    function blowTagCache($blowLast=false)
+    {
+        $cache = common_memcache();
+        if ($cache) {
+            $tag = new Notice_tag();
+            $tag->notice_id = $this->id;
+            if ($tag->find()) {
+                while ($tag->fetch()) {
+                    $cache->delete(common_cache_key('notice_tag:notice_stream:' . $tag->tag));
+                    if ($blowLast) {
+                        $cache->delete(common_cache_key('notice_tag:notice_stream:' . $tag->tag . ';last'));
+                    }
+                }
+            }
+            $tag->free();
+            unset($tag);
+        }
+    }
+
+    function blowSubsCache($blowLast=false)
+    {
+        $cache = common_memcache();
+        if ($cache) {
+            $user = new User();
+
+            $user->query('SELECT id ' .
+                         'FROM user JOIN subscription ON user.id = subscription.subscriber ' .
+                         'WHERE subscription.subscribed = ' . $this->profile_id);
+
+            while ($user->fetch()) {
+                $cache->delete(common_cache_key('user:notices_with_friends:' . $user->id));
+                if ($blowLast) {
+                    $cache->delete(common_cache_key('user:notices_with_friends:' . $user->id . ';last'));
+                }
+            }
+            $user->free();
+            unset($user);
+        }
+    }
+
+    function blowNoticeCache($blowLast=false)
+    {
+        if ($this->is_local) {
+            $cache = common_memcache();
+            if ($cache) {
+                $cache->delete(common_cache_key('profile:notices:'.$this->profile_id));
+                if ($blowLast) {
+                    $cache->delete(common_cache_key('profile:notices:'.$this->profile_id.';last'));
+                }
+            }
+        }
+    }
+
+    function blowRepliesCache($blowLast=false)
+    {
+        $cache = common_memcache();
+        if ($cache) {
+            $reply = new Reply();
+            $reply->notice_id = $this->id;
+            if ($reply->find()) {
+                while ($reply->fetch()) {
+                    $cache->delete(common_cache_key('user:replies:'.$reply->profile_id));
+                    if ($blowLast) {
+                        $cache->delete(common_cache_key('user:replies:'.$reply->profile_id.';last'));
+                    }
+                }
+            }
+            $reply->free();
+            unset($reply);
+        }
+    }
+
+    function blowPublicCache($blowLast=false)
+    {
+        if ($this->is_local == 1) {
+            $cache = common_memcache();
+            if ($cache) {
+                $cache->delete(common_cache_key('public'));
+                if ($blowLast) {
+                    $cache->delete(common_cache_key('public').';last');
+                }
+            }
+        }
+    }
+
+    function blowFavesCache($blowLast=false)
+    {
+        $cache = common_memcache();
+        if ($cache) {
+            $fave = new Fave();
+            $fave->notice_id = $this->id;
+            if ($fave->find()) {
+                while ($fave->fetch()) {
+                    $cache->delete(common_cache_key('user:faves:'.$fave->user_id));
+                    if ($blowLast) {
+                        $cache->delete(common_cache_key('user:faves:'.$fave->user_id.';last'));
+                    }
+                }
+            }
+            $fave->free();
+            unset($fave);
+        }
+    }
+
+    # XXX: too many args; we need to move to named params or even a separate
+    # class for notice streams
+
+    static function getStream($qry, $cachekey, $offset=0, $limit=20, $since_id=0, $before_id=0, $order=null, $since=null) {
+
+        if (common_config('memcached', 'enabled')) {
+
+            # Skip the cache if this is a since, since_id or before_id qry
+            if ($since_id > 0 || $before_id > 0 || $since) {
+                return Notice::getStreamDirect($qry, $offset, $limit, $since_id, $before_id, $order, $since);
+            } else {
+                return Notice::getCachedStream($qry, $cachekey, $offset, $limit, $order);
+            }
+        }
+
+        return Notice::getStreamDirect($qry, $offset, $limit, $since_id, $before_id, $order, $since);
+    }
+
+    static function getStreamDirect($qry, $offset, $limit, $since_id, $before_id, $order, $since) {
+
+        $needAnd = false;
+        $needWhere = true;
+
+        if (preg_match('/\bWHERE\b/i', $qry)) {
+            $needWhere = false;
+            $needAnd = true;
+        }
+
+        if ($since_id > 0) {
+
+            if ($needWhere) {
+                $qry .= ' WHERE ';
+                $needWhere = false;
+            } else {
+                $qry .= ' AND ';
+            }
+
+            $qry .= ' notice.id > ' . $since_id;
+        }
+
+        if ($before_id > 0) {
+
+            if ($needWhere) {
+                $qry .= ' WHERE ';
+                $needWhere = false;
+            } else {
+                $qry .= ' AND ';
+            }
+
+            $qry .= ' notice.id < ' . $before_id;
+        }
 
-               if ($since) {
-
-                       if ($needWhere) {
-                               $qry .= ' WHERE ';
-                               $needWhere = FALSE;
-                       } else {
-                               $qry .= ' AND ';
-                       }
+        if ($since) {
 
-                       $qry .= ' notice.created > \'' . date('Y-m-d H:i:s', $since) . '\'';
-               }
+            if ($needWhere) {
+                $qry .= ' WHERE ';
+                $needWhere = false;
+            } else {
+                $qry .= ' AND ';
+            }
 
-               # Allow ORDER override
+            $qry .= ' notice.created > \'' . date('Y-m-d H:i:s', $since) . '\'';
+        }
 
-               if ($order) {
-                       $qry .= $order;
-               } else {
-                       $qry .= ' ORDER BY notice.created DESC, notice.id DESC ';
-               }
+        # Allow ORDER override
 
-               if (common_config('db','type') == 'pgsql') {
-                       $qry .= ' LIMIT ' . $limit . ' OFFSET ' . $offset;
-               } else {
-                       $qry .= ' LIMIT ' . $offset . ', ' . $limit;
-               }
+        if ($order) {
+            $qry .= $order;
+        } else {
+            $qry .= ' ORDER BY notice.created DESC, notice.id DESC ';
+        }
 
-               $notice = new Notice();
+        if (common_config('db','type') == 'pgsql') {
+            $qry .= ' LIMIT ' . $limit . ' OFFSET ' . $offset;
+        } else {
+            $qry .= ' LIMIT ' . $offset . ', ' . $limit;
+        }
 
-               $notice->query($qry);
+        $notice = new Notice();
 
-               return $notice;
-       }
+        $notice->query($qry);
 
-       # XXX: this is pretty long and should probably be broken up into
-       # some helper functions
+        return $notice;
+    }
 
-       static function getCachedStream($qry, $cachekey, $offset, $limit, $order) {
+    # XXX: this is pretty long and should probably be broken up into
+    # some helper functions
 
-               # If outside our cache window, just go to the DB
+    static function getCachedStream($qry, $cachekey, $offset, $limit, $order) {
 
-               if ($offset + $limit > NOTICE_CACHE_WINDOW) {
-                       return Notice::getStreamDirect($qry, $offset, $limit, NULL, NULL, $order, NULL);
-               }
+        # If outside our cache window, just go to the DB
 
-               # Get the cache; if we can't, just go to the DB
+        if ($offset + $limit > NOTICE_CACHE_WINDOW) {
+            return Notice::getStreamDirect($qry, $offset, $limit, null, null, $order, null);
+        }
 
-               $cache = common_memcache();
+        # Get the cache; if we can't, just go to the DB
 
-               if (!$cache) {
-                       return Notice::getStreamDirect($qry, $offset, $limit, NULL, NULL, $order, NULL);
-               }
+        $cache = common_memcache();
 
-               # Get the notices out of the cache
+        if (!$cache) {
+            return Notice::getStreamDirect($qry, $offset, $limit, null, null, $order, null);
+        }
 
-               $notices = $cache->get(common_cache_key($cachekey));
+        # Get the notices out of the cache
 
-               # On a cache hit, return a DB-object-like wrapper
+        $notices = $cache->get(common_cache_key($cachekey));
 
-               if ($notices !== FALSE) {
-                       $wrapper = new NoticeWrapper(array_slice($notices, $offset, $limit));
-                       return $wrapper;
-               }
+        # On a cache hit, return a DB-object-like wrapper
 
-               # If the cache was invalidated because of new data being
-               # added, we can try and just get the new stuff. We keep an additional
-               # copy of the data at the key + ';last'
+        if ($notices !== false) {
+            $wrapper = new NoticeWrapper(array_slice($notices, $offset, $limit));
+            return $wrapper;
+        }
 
-               # No cache hit. Try to get the *last* cached version
+        # If the cache was invalidated because of new data being
+        # added, we can try and just get the new stuff. We keep an additional
+        # copy of the data at the key + ';last'
 
-               $last_notices = $cache->get(common_cache_key($cachekey) . ';last');
+        # No cache hit. Try to get the *last* cached version
 
-               if ($last_notices) {
+        $last_notices = $cache->get(common_cache_key($cachekey) . ';last');
 
-                       # Reverse-chron order, so last ID is last.
+        if ($last_notices) {
 
-                       $last_id = $last_notices[0]->id;
+            # Reverse-chron order, so last ID is last.
 
-                       # XXX: this assumes monotonically increasing IDs; a fair
-                       # bet with our DB.
+            $last_id = $last_notices[0]->id;
 
-                       $new_notice = Notice::getStreamDirect($qry, 0, NOTICE_CACHE_WINDOW,
-                                                                                                 $last_id, NULL, $order, NULL);
+            # XXX: this assumes monotonically increasing IDs; a fair
+            # bet with our DB.
 
-                       if ($new_notice) {
-                               $new_notices = array();
-                               while ($new_notice->fetch()) {
-                                       $new_notices[] = clone($new_notice);
-                               }
-                               $new_notice->free();
-                               $notices = array_slice(array_merge($new_notices, $last_notices),
-                                                                          0, NOTICE_CACHE_WINDOW);
+            $new_notice = Notice::getStreamDirect($qry, 0, NOTICE_CACHE_WINDOW,
+                                                  $last_id, null, $order, null);
 
-                               # Store the array in the cache for next time
+            if ($new_notice) {
+                $new_notices = array();
+                while ($new_notice->fetch()) {
+                    $new_notices[] = clone($new_notice);
+                }
+                $new_notice->free();
+                $notices = array_slice(array_merge($new_notices, $last_notices),
+                                       0, NOTICE_CACHE_WINDOW);
 
-                               $result = $cache->set(common_cache_key($cachekey), $notices);
-                               $result = $cache->set(common_cache_key($cachekey) . ';last', $notices);
+                # Store the array in the cache for next time
 
-                               # return a wrapper of the array for use now
+                $result = $cache->set(common_cache_key($cachekey), $notices);
+                $result = $cache->set(common_cache_key($cachekey) . ';last', $notices);
 
-                               return new NoticeWrapper(array_slice($notices, $offset, $limit));
-                       }
-               }
+                # return a wrapper of the array for use now
 
-               # Otherwise, get the full cache window out of the DB
+                return new NoticeWrapper(array_slice($notices, $offset, $limit));
+            }
+        }
 
-               $notice = Notice::getStreamDirect($qry, 0, NOTICE_CACHE_WINDOW, NULL, NULL, $order, NULL);
+        # Otherwise, get the full cache window out of the DB
 
-               # If there are no hits, just return the value
+        $notice = Notice::getStreamDirect($qry, 0, NOTICE_CACHE_WINDOW, null, null, $order, null);
 
-               if (!$notice) {
-                       return $notice;
-               }
+        # If there are no hits, just return the value
 
-               # Pack results into an array
+        if (!$notice) {
+            return $notice;
+        }
 
-               $notices = array();
+        # Pack results into an array
 
-               while ($notice->fetch()) {
-                       $notices[] = clone($notice);
-               }
+        $notices = array();
 
-               $notice->free();
+        while ($notice->fetch()) {
+            $notices[] = clone($notice);
+        }
 
-               # Store the array in the cache for next time
+        $notice->free();
 
-               $result = $cache->set(common_cache_key($cachekey), $notices);
-               $result = $cache->set(common_cache_key($cachekey) . ';last', $notices);
+        # Store the array in the cache for next time
 
-               # return a wrapper of the array for use now
+        $result = $cache->set(common_cache_key($cachekey), $notices);
+        $result = $cache->set(common_cache_key($cachekey) . ';last', $notices);
 
-               $wrapper = new NoticeWrapper(array_slice($notices, $offset, $limit));
+        # return a wrapper of the array for use now
 
-               return $wrapper;
-       }
+        $wrapper = new NoticeWrapper(array_slice($notices, $offset, $limit));
 
-       function publicStream($offset=0, $limit=20, $since_id=0, $before_id=0, $since=NULL) {
+        return $wrapper;
+    }
 
-               $parts = array();
+    function publicStream($offset=0, $limit=20, $since_id=0, $before_id=0, $since=null)
+    {
 
-               $qry = 'SELECT * FROM notice ';
+        $parts = array();
 
-               if (common_config('public', 'localonly')) {
-                       $parts[] = 'is_local = 1';
-               } else {
-                       # -1 == blacklisted
-                       $parts[] = 'is_local != -1';
-               }
+        $qry = 'SELECT * FROM notice ';
 
-               if ($parts) {
-                       $qry .= ' WHERE ' . implode(' AND ', $parts);
-               }
+        if (common_config('public', 'localonly')) {
+            $parts[] = 'is_local = 1';
+        } else {
+            # -1 == blacklisted
+            $parts[] = 'is_local != -1';
+        }
 
-               return Notice::getStream($qry,
-                                                                'public',
-                                                                $offset, $limit, $since_id, $before_id, NULL, $since);
-       }
+        if ($parts) {
+            $qry .= ' WHERE ' . implode(' AND ', $parts);
+        }
 
-       function addToInboxes() {
-               $enabled = common_config('inboxes', 'enabled');
+        return Notice::getStream($qry,
+                                 'public',
+                                 $offset, $limit, $since_id, $before_id, null, $since);
+    }
 
-               if ($enabled === true || $enabled === 'transitional') {
-                       $inbox = new Notice_inbox();
-                       $qry = 'INSERT INTO notice_inbox (user_id, notice_id, created) ' .
-                         'SELECT user.id, ' . $this->id . ', "' . $this->created . '" ' .
-                         'FROM user JOIN subscription ON user.id = subscription.subscriber ' .
-                         'WHERE subscription.subscribed = ' . $this->profile_id . ' ' .
-                         'AND NOT EXISTS (SELECT user_id, notice_id ' .
-                         'FROM notice_inbox ' .
-                         'WHERE user_id = user.id ' .
-                         'AND notice_id = ' . $this->id . ' )';
-                       if ($enabled === 'transitional') {
-                               $qry .= ' AND user.inboxed = 1';
-                       }
-                       $inbox->query($qry);
-               }
-               return;
-       }
+    function addToInboxes()
+    {
+        $enabled = common_config('inboxes', 'enabled');
+
+        if ($enabled === true || $enabled === 'transitional') {
+            $inbox = new Notice_inbox();
+            $qry = 'INSERT INTO notice_inbox (user_id, notice_id, created) ' .
+              'SELECT user.id, ' . $this->id . ', "' . $this->created . '" ' .
+              'FROM user JOIN subscription ON user.id = subscription.subscriber ' .
+              'WHERE subscription.subscribed = ' . $this->profile_id . ' ' .
+              'AND NOT EXISTS (SELECT user_id, notice_id ' .
+              'FROM notice_inbox ' .
+              'WHERE user_id = user.id ' .
+              'AND notice_id = ' . $this->id . ' )';
+            if ($enabled === 'transitional') {
+                $qry .= ' AND user.inboxed = 1';
+            }
+            $inbox->query($qry);
+        }
+        return;
+    }
 
-       # Delete from inboxes if we're deleted.
+    # Delete from inboxes if we're deleted.
 
-       function blowInboxes() {
+    function blowInboxes()
+    {
 
-               $enabled = common_config('inboxes', 'enabled');
+        $enabled = common_config('inboxes', 'enabled');
 
-               if ($enabled === true || $enabled === 'transitional') {
-                       $inbox = new Notice_inbox();
-                       $inbox->notice_id = $this->id;
-                       $inbox->delete();
-               }
+        if ($enabled === true || $enabled === 'transitional') {
+            $inbox = new Notice_inbox();
+            $inbox->notice_id = $this->id;
+            $inbox->delete();
+        }
 
-               return;
-       }
+        return;
+    }
 
 }
 
index f8c0aa38199400ec926a4283fb7ab9b17d350536..233340ccd69e27b9019b3da49652b70819c1dc80 100644 (file)
@@ -21,7 +21,8 @@ if (!defined('LACONICA')) { exit(1); }
 
 require_once(INSTALLDIR.'/classes/Notice.php');
 
-class NoticeWrapper extends Notice {
+class NoticeWrapper extends Notice
+{
 
     public $id;                              // int(4)  primary_key not_null
     public $profile_id;                      // int(4)   not_null
@@ -35,25 +36,27 @@ class NoticeWrapper extends Notice {
     public $is_local;                        // tinyint(1)  
     public $source;                          // varchar(32)  
 
-       var $notices = NULL;
-       var $i = -1;
-       
-       function __construct($arr) {
-               $this->notices = $arr;
-       }
-       
-       function fetch() {
-               static $fields = array('id', 'profile_id', 'uri', 'content', 'rendered',
-                                                          'url', 'created', 'modified', 'reply_to', 'is_local', 'source');
-               $this->i++;
-               if ($this->i >= count($this->notices)) {
-                       return false;
-               } else {
-                       $n = $this->notices[$this->i];
-                       foreach ($fields as $f) {
-                               $this->$f = $n->$f;
-                       }
-                       return true;
-               }
-       }
+    var $notices = null;
+    var $i = -1;
+    
+    function __construct($arr)
+    {
+        $this->notices = $arr;
+    }
+    
+    function fetch()
+    {
+        static $fields = array('id', 'profile_id', 'uri', 'content', 'rendered',
+                               'url', 'created', 'modified', 'reply_to', 'is_local', 'source');
+        $this->i++;
+        if ($this->i >= count($this->notices)) {
+            return false;
+        } else {
+            $n = $this->notices[$this->i];
+            foreach ($fields as $f) {
+                $this->$f = $n->$f;
+            }
+            return true;
+        }
+    }
 }
\ No newline at end of file
index cc482bd194fc07fe052350f5d2a6568db2367b4f..81ddb453859a4721b1c1b7531d618fdc84de263a 100644 (file)
@@ -33,7 +33,8 @@ class Notice_inbox extends Memcached_DataObject
     public $source;                          // tinyint(1)   default_1
 
     /* Static get */
-    function staticGet($k,$v=NULL) { return Memcached_DataObject::staticGet('Notice_inbox',$k,$v); }
+    function staticGet($k,$v=null)
+    { return Memcached_DataObject::staticGet('Notice_inbox',$k,$v); }
 
     /* the code above is auto generated do not remove the tag below */
     ###END_AUTOCODE
index e0a41b927ca8ca10bc39013e1e278855e1e7794d..e7568bbca2a0be0f0b644d5cb0a3974c8e430a02 100644 (file)
@@ -17,7 +17,8 @@ class Notice_source extends Memcached_DataObject
     public $modified;                        // timestamp()   not_null default_CURRENT_TIMESTAMP
 
     /* Static get */
-    function staticGet($k,$v=NULL) { return Memcached_DataObject::staticGet('Notice_source',$k,$v); }
+    function staticGet($k,$v=null)
+    { return Memcached_DataObject::staticGet('Notice_source',$k,$v); }
 
     /* the code above is auto generated do not remove the tag below */
     ###END_AUTOCODE
index 5b75ff13feb05a22bf48596ac5d73fdaf69f1759..94f9296d602c92cc1c121cd498ad988ce4b6024d 100644 (file)
@@ -30,26 +30,28 @@ class Notice_tag extends Memcached_DataObject
     public $created;                         // datetime()   not_null
 
     /* Static get */
-    function staticGet($k,$v=NULL) { return Memcached_DataObject::staticGet('Notice_tag',$k,$v); }
+    function staticGet($k,$v=null)
+    { return Memcached_DataObject::staticGet('Notice_tag',$k,$v); }
 
     /* the code above is auto generated do not remove the tag below */
     ###END_AUTOCODE
-       
-       static function getStream($tag, $offset=0, $limit=20) {
-               $qry = 
-                 'SELECT notice.* ' .
-                 'FROM notice JOIN notice_tag ON notice.id = notice_tag.notice_id ' .
-                 'WHERE notice_tag.tag = "%s" ';
+    
+    static function getStream($tag, $offset=0, $limit=20) {
+        $qry = 
+          'SELECT notice.* ' .
+          'FROM notice JOIN notice_tag ON notice.id = notice_tag.notice_id ' .
+          'WHERE notice_tag.tag = "%s" ';
 
-               return Notice::getStream(sprintf($qry, $tag),
-                                                                'notice_tag:notice_stream:' . common_keyize($tag),
-                                                                $offset, $limit);
-       }
-       
-       function blowCache() {
-               $cache = common_memcache();
-               if ($cache) {
-                       $cache->delete(common_cache_key('notice_tag:notice_stream:' . $this->tag));
-               }
-       }
+        return Notice::getStream(sprintf($qry, $tag),
+                                 'notice_tag:notice_stream:' . common_keyize($tag),
+                                 $offset, $limit);
+    }
+    
+    function blowCache()
+    {
+        $cache = common_memcache();
+        if ($cache) {
+            $cache->delete(common_cache_key('notice_tag:notice_stream:' . $this->tag));
+        }
+    }
 }
index b57d7e38ddfd8913010415321df22ae5da584d98..31bdf71d59b9923abacbab890e692b8864f442bf 100644 (file)
@@ -41,119 +41,150 @@ class Profile extends Memcached_DataObject
     public $modified;                        // timestamp()   not_null default_CURRENT_TIMESTAMP
 
     /* Static get */
-    function staticGet($k,$v=NULL) { return Memcached_DataObject::staticGet('Profile',$k,$v); }
+    function staticGet($k,$v=null)
+    { return Memcached_DataObject::staticGet('Profile',$k,$v); }
 
     /* the code above is auto generated do not remove the tag below */
     ###END_AUTOCODE
 
-       function getAvatar($width, $height=NULL) {
-               if (is_null($height)) {
-                       $height = $width;
-               }
-               return Avatar::pkeyGet(array('profile_id' => $this->id,
-                                                                        'width' => $width,
-                                                                        'height' => $height));
-       }
-
-       function getOriginalAvatar() {
-               $avatar = DB_DataObject::factory('avatar');
-               $avatar->profile_id = $this->id;
-               $avatar->original = true;
-               if ($avatar->find(true)) {
-                       return $avatar;
-               } else {
-                       return NULL;
-               }
-       }
-
-       function setOriginal($source) {
-
-               $info = @getimagesize($source);
-
-               if (!$info) {
-                       return NULL;
-               }
-
-               $filename = common_avatar_filename($this->id,
-                                                                                  image_type_to_extension($info[2]),
-                                                                                  NULL, common_timestamp());
-               $filepath = common_avatar_path($filename);
-
-               copy($source, $filepath);
-
-               $avatar = new Avatar();
-
-               $avatar->profile_id = $this->id;
-               $avatar->width = $info[0];
-               $avatar->height = $info[1];
-               $avatar->mediatype = image_type_to_mime_type($info[2]);
-               $avatar->filename = $filename;
-               $avatar->original = true;
-               $avatar->url = common_avatar_url($filename);
-               $avatar->created = DB_DataObject_Cast::dateTime(); # current time
-
-               # XXX: start a transaction here
-
-               if (!$this->delete_avatars()) {
-                       @unlink($filepath);
-                       return NULL;
-               }
-
-               if (!$avatar->insert()) {
-                       @unlink($filepath);
-                       return NULL;
-               }
-
-               foreach (array(AVATAR_PROFILE_SIZE, AVATAR_STREAM_SIZE, AVATAR_MINI_SIZE) as $size) {
-                       # We don't do a scaled one if original is our scaled size
-                       if (!($avatar->width == $size && $avatar->height == $size)) {
-                               $s = $avatar->scale($size);
-                               if (!$s) {
-                                       return NULL;
-                               }
-                       }
-               }
-
-               return $avatar;
-       }
-
-       function delete_avatars() {
-               $avatar = new Avatar();
-               $avatar->profile_id = $this->id;
-               $avatar->find();
-               while ($avatar->fetch()) {
-                       $avatar->delete();
-               }
-               return true;
-       }
-
-       function getBestName() {
-               return ($this->fullname) ? $this->fullname : $this->nickname;
-       }
+    function getAvatar($width, $height=null)
+    {
+        if (is_null($height)) {
+            $height = $width;
+        }
+        return Avatar::pkeyGet(array('profile_id' => $this->id,
+                                     'width' => $width,
+                                     'height' => $height));
+    }
+
+    function getOriginalAvatar()
+    {
+        $avatar = DB_DataObject::factory('avatar');
+        $avatar->profile_id = $this->id;
+        $avatar->original = true;
+        if ($avatar->find(true)) {
+            return $avatar;
+        } else {
+            return null;
+        }
+    }
+
+    function setOriginal($source)
+    {
+
+        $info = @getimagesize($source);
+
+        if (!$info) {
+            return null;
+        }
+
+        $filename = common_avatar_filename($this->id,
+                                           image_type_to_extension($info[2]),
+                                           null, common_timestamp());
+        $filepath = common_avatar_path($filename);
+
+        copy($source, $filepath);
+
+        $avatar = new Avatar();
+
+        $avatar->profile_id = $this->id;
+        $avatar->width = $info[0];
+        $avatar->height = $info[1];
+        $avatar->mediatype = image_type_to_mime_type($info[2]);
+        $avatar->filename = $filename;
+        $avatar->original = true;
+        $avatar->url = common_avatar_url($filename);
+        $avatar->created = DB_DataObject_Cast::dateTime(); # current time
+
+        # XXX: start a transaction here
+
+        if (!$this->delete_avatars()) {
+            @unlink($filepath);
+            return null;
+        }
+
+        if (!$avatar->insert()) {
+            @unlink($filepath);
+            return null;
+        }
+
+        foreach (array(AVATAR_PROFILE_SIZE, AVATAR_STREAM_SIZE, AVATAR_MINI_SIZE) as $size) {
+            # We don't do a scaled one if original is our scaled size
+            if (!($avatar->width == $size && $avatar->height == $size)) {
+                $s = $avatar->scale($size);
+                if (!$s) {
+                    return null;
+                }
+            }
+        }
+
+        return $avatar;
+    }
+
+    function crop_avatars($x, $y, $w, $h) 
+    {
+
+        $avatar = $this->getOriginalAvatar();
+        $this->delete_avatars(false); # don't delete original
+
+        foreach (array(AVATAR_PROFILE_SIZE, AVATAR_STREAM_SIZE, AVATAR_MINI_SIZE) as $size) {
+            # We don't do a scaled one if original is our scaled size
+            if (!($avatar->width == $size && $avatar->height == $size)) {
+                $s = $avatar->scale_and_crop($size, $x, $y, $w, $h);
+                if (!$s) {
+                    return NULL;
+                }
+            }
+        }
+        return true;
+    }
+
+    function delete_avatars($original=true) 
+    {
+        $avatar = new Avatar();
+        $avatar->profile_id = $this->id;
+        $avatar->find();
+        while ($avatar->fetch()) {
+            if ($avatar->original) {
+                if ($original == false) {
+                    continue;
+                }
+            }
+            $avatar->delete();
+        }
+        return true;
+    }
+
+    function getBestName()
+    {
+        return ($this->fullname) ? $this->fullname : $this->nickname;
+    }
 
     # Get latest notice on or before date; default now
-       function getCurrentNotice($dt=NULL) {
-               $notice = new Notice();
-               $notice->profile_id = $this->id;
-               if ($dt) {
-                       $notice->whereAdd('created < "' . $dt . '"');
-               }
-               $notice->orderBy('created DESC, notice.id DESC');
-               $notice->limit(1);
-               if ($notice->find(true)) {
-                       return $notice;
-               }
-               return NULL;
-       }
-
-       function getNotices($offset=0, $limit=NOTICES_PER_PAGE, $since_id=0, $before_id=0) {
-               $qry =
-                 'SELECT * ' .
-                 'FROM notice ' .
-                 'WHERE profile_id = %d ';
-
-               return Notice::getStream(sprintf($qry, $this->id),
-                                                                'profile:notices:'.$this->id,
-                                                                $offset, $limit, $since_id, $before_id);
-       }
+    function getCurrentNotice($dt=null)
+    {
+        $notice = new Notice();
+        $notice->profile_id = $this->id;
+        if ($dt) {
+            $notice->whereAdd('created < "' . $dt . '"');
+        }
+        $notice->orderBy('created DESC, notice.id DESC');
+        $notice->limit(1);
+        if ($notice->find(true)) {
+            return $notice;
+        }
+        return null;
+    }
+
+    function getNotices($offset=0, $limit=NOTICES_PER_PAGE, $since_id=0, $before_id=0)
+    {
+        $qry =
+          'SELECT * ' .
+          'FROM notice ' .
+          'WHERE profile_id = %d ';
+
+        return Notice::getStream(sprintf($qry, $this->id),
+                                 'profile:notices:'.$this->id,
+                                 $offset, $limit, $since_id, $before_id);
+    }
 }
index 6ea26a3bc46718a8357f33820eac6941d4dd7149..551e690e24a57e55c8850fb526be1848e31f4dc8 100644 (file)
@@ -36,12 +36,14 @@ class Profile_block extends Memcached_DataObject
     public $modified;                        // timestamp()   not_null default_CURRENT_TIMESTAMP
 
     /* Static get */
-    function staticGet($k,$v=NULL) { return Memcached_DataObject::staticGet('Profile_block',$k,$v); }
+    function staticGet($k,$v=null)
+    { return Memcached_DataObject::staticGet('Profile_block',$k,$v); }
 
     /* the code above is auto generated do not remove the tag below */
     ###END_AUTOCODE
 
-    function get($blocker, $blocked) {
+    function get($blocker, $blocked)
+    {
         return Memcached_DataObject::pkeyGet('Profile_block',
                                              array('blocker' => $blocker,
                                                    'blocked' => $blocked));
index dde19aea250a5e1dc724202cd50cefc802d15ce1..cb60cbaec9ef4fc6421c8e12864822f6b22fc07c 100644 (file)
@@ -16,86 +16,87 @@ class Profile_tag extends Memcached_DataObject
     public $modified;                        // timestamp()   not_null default_CURRENT_TIMESTAMP
 
     /* Static get */
-    function staticGet($k,$v=NULL) { return Memcached_DataObject::staticGet('Profile_tag',$k,$v); }
+    function staticGet($k,$v=null)
+    { return Memcached_DataObject::staticGet('Profile_tag',$k,$v); }
 
     /* the code above is auto generated do not remove the tag below */
     ###END_AUTOCODE
 
-       static function getTags($tagger, $tagged) {
-               
-               $tags = array();
+    static function getTags($tagger, $tagged) {
+        
+        $tags = array();
 
-               # XXX: store this in memcached
-               
-               $profile_tag = new Profile_tag();
-               $profile_tag->tagger = $tagger;
-               $profile_tag->tagged = $tagged;
-               
-               $profile_tag->find();
-               
-               while ($profile_tag->fetch()) {
-                       $tags[] = $profile_tag->tag;
-               }
-               
-               $profile_tag->free();
-               
-               return $tags;
-       }
-       
-       static function setTags($tagger, $tagged, $newtags) {
-               
-               $oldtags = Profile_tag::getTags($tagger, $tagged);
-               
-               # Delete stuff that's old that not in new
-               
-               $to_delete = array_diff($oldtags, $newtags);
-               
-               # Insert stuff that's in new and not in old
-               
-               $to_insert = array_diff($newtags, $oldtags);
-               
-               $profile_tag = new Profile_tag();
-               
-               $profile_tag->tagger = $tagger;
-               $profile_tag->tagged = $tagged;
-               
-               $profile_tag->query('BEGIN');
-               
-               foreach ($to_delete as $deltag) {
-                       $profile_tag->tag = $deltag;
-                       $result = $profile_tag->delete();
-                       if (!$result) {
-                               common_log_db_error($profile_tag, 'DELETE', __FILE__);
-                               return false;
-                       }
-               }
-               
-               foreach ($to_insert as $instag) {
-                       $profile_tag->tag = $instag;
-                       $result = $profile_tag->insert();
-                       if (!$result) {
-                               common_log_db_error($profile_tag, 'INSERT', __FILE__);
-                               return false;
-                       }
-               }
-               
-               $profile_tag->query('COMMIT');
-               
-               return true;
-       }
-       
-       # Return profiles with a given tag
-       static function getTagged($tagger, $tag) {
-               $profile = new Profile();
-               $profile->query('SELECT profile.* ' .
-                                               'FROM profile JOIN profile_tag ' .
-                                               'ON profile.id = profile_tag.tagged ' .
-                                               'WHERE profile_tag.tagger = ' . $tagger . ' ' .
-                                               'AND profile_tag.tag = "' . $tag . '" ');
-               $tagged = array();
-               while ($profile->fetch()) {
-                       $tagged[] = clone($profile);
-               }
-               return $tagged;
-       }
+        # XXX: store this in memcached
+        
+        $profile_tag = new Profile_tag();
+        $profile_tag->tagger = $tagger;
+        $profile_tag->tagged = $tagged;
+        
+        $profile_tag->find();
+        
+        while ($profile_tag->fetch()) {
+            $tags[] = $profile_tag->tag;
+        }
+        
+        $profile_tag->free();
+        
+        return $tags;
+    }
+    
+    static function setTags($tagger, $tagged, $newtags) {
+        
+        $oldtags = Profile_tag::getTags($tagger, $tagged);
+        
+        # Delete stuff that's old that not in new
+        
+        $to_delete = array_diff($oldtags, $newtags);
+        
+        # Insert stuff that's in new and not in old
+        
+        $to_insert = array_diff($newtags, $oldtags);
+        
+        $profile_tag = new Profile_tag();
+        
+        $profile_tag->tagger = $tagger;
+        $profile_tag->tagged = $tagged;
+        
+        $profile_tag->query('BEGIN');
+        
+        foreach ($to_delete as $deltag) {
+            $profile_tag->tag = $deltag;
+            $result = $profile_tag->delete();
+            if (!$result) {
+                common_log_db_error($profile_tag, 'DELETE', __FILE__);
+                return false;
+            }
+        }
+        
+        foreach ($to_insert as $instag) {
+            $profile_tag->tag = $instag;
+            $result = $profile_tag->insert();
+            if (!$result) {
+                common_log_db_error($profile_tag, 'INSERT', __FILE__);
+                return false;
+            }
+        }
+        
+        $profile_tag->query('COMMIT');
+        
+        return true;
+    }
+    
+    # Return profiles with a given tag
+    static function getTagged($tagger, $tag) {
+        $profile = new Profile();
+        $profile->query('SELECT profile.* ' .
+                        'FROM profile JOIN profile_tag ' .
+                        'ON profile.id = profile_tag.tagged ' .
+                        'WHERE profile_tag.tagger = ' . $tagger . ' ' .
+                        'AND profile_tag.tag = "' . $tag . '" ');
+        $tagged = array();
+        while ($profile->fetch()) {
+            $tagged[] = clone($profile);
+        }
+        return $tagged;
+    }
 }
index 8ba3281de39cf30846b57eb61d4403f9099cb22b..9b909ec22ba8360ca1f39ee5f990cd47ed92f3e7 100644 (file)
@@ -16,40 +16,42 @@ class Queue_item extends Memcached_DataObject
     public $claimed;                         // datetime()  
 
     /* Static get */
-    function staticGet($k,$v=NULL) { return Memcached_DataObject::staticGet('Queue_item',$k,$v); }
+    function staticGet($k,$v=null)
+    { return Memcached_DataObject::staticGet('Queue_item',$k,$v); }
 
     /* the code above is auto generated do not remove the tag below */
     ###END_AUTOCODE
 
-    function sequenceKey() { return array(false, false); }
-       
-       static function top($transport) {
-
-               $qi = new Queue_item();
-               $qi->transport = $transport;
-               $qi->orderBy('created');
-               $qi->whereAdd('claimed is NULL');
-
-               $qi->limit(1);
-
-               $cnt = $qi->find(TRUE);
-
-               if ($cnt) {
-                       # XXX: potential race condition
-                       # can we force it to only update if claimed is still NULL
-                       # (or old)?
-                       common_log(LOG_INFO, 'claiming queue item = ' . $qi->notice_id . ' for transport ' . $transport);
-                       $orig = clone($qi);
-                       $qi->claimed = common_sql_now();
-                       $result = $qi->update($orig);
-                       if ($result) {
-                               common_log(LOG_INFO, 'claim succeeded.');
-                               return $qi;
-                       } else {
-                               common_log(LOG_INFO, 'claim failed.');
-                       }
-               }
-               $qi = NULL;
-               return NULL;
-       }
+    function sequenceKey()
+    { return array(false, false); }
+    
+    static function top($transport) {
+
+        $qi = new Queue_item();
+        $qi->transport = $transport;
+        $qi->orderBy('created');
+        $qi->whereAdd('claimed is null');
+
+        $qi->limit(1);
+
+        $cnt = $qi->find(true);
+
+        if ($cnt) {
+            # XXX: potential race condition
+            # can we force it to only update if claimed is still null
+            # (or old)?
+            common_log(LOG_INFO, 'claiming queue item = ' . $qi->notice_id . ' for transport ' . $transport);
+            $orig = clone($qi);
+            $qi->claimed = common_sql_now();
+            $result = $qi->update($orig);
+            if ($result) {
+                common_log(LOG_INFO, 'claim succeeded.');
+                return $qi;
+            } else {
+                common_log(LOG_INFO, 'claim failed.');
+            }
+        }
+        $qi = null;
+        return null;
+    }
 }
index 5bbd6cf174c6ef086b853d1c83f4797a96987a45..8dc29bfa39d6d2151d156c6d1a40e8a9c3f83ac0 100644 (file)
@@ -15,10 +15,12 @@ class Remember_me extends Memcached_DataObject
     public $modified;                        // timestamp()   not_null default_CURRENT_TIMESTAMP
 
     /* Static get */
-    function staticGet($k,$v=NULL) { return Memcached_DataObject::staticGet('Remember_me',$k,$v); }
+    function staticGet($k,$v=null)
+    { return Memcached_DataObject::staticGet('Remember_me',$k,$v); }
 
     /* the code above is auto generated do not remove the tag below */
     ###END_AUTOCODE
 
-    function sequenceKey() { return array(false, false); }
+    function sequenceKey()
+    { return array(false, false); }
 }
index c961dcca2e58f6611830be6ef56413a8f77bb193..5aa6d913e5949465ff3b1db84684b403f8324d33 100644 (file)
@@ -38,7 +38,8 @@ class Remote_profile extends Memcached_DataObject
     public $modified;                        // timestamp()   not_null default_CURRENT_TIMESTAMP
 
     /* Static get */
-    function staticGet($k,$v=NULL) { return Memcached_DataObject::staticGet('Remote_profile',$k,$v); }
+    function staticGet($k,$v=null)
+    { return Memcached_DataObject::staticGet('Remote_profile',$k,$v); }
 
     /* the code above is auto generated do not remove the tag below */
     ###END_AUTOCODE
index d71ce3afbcf758178462cfae65b123abb836641d..af86aaf878c0ea5392a9579c601c46565a4b884a 100644 (file)
@@ -16,7 +16,8 @@ class Reply extends Memcached_DataObject
     public $replied_id;                      // int(4)  
 
     /* Static get */
-    function staticGet($k,$v=NULL) { return Memcached_DataObject::staticGet('Reply',$k,$v); }
+    function staticGet($k,$v=null)
+    { return Memcached_DataObject::staticGet('Reply',$k,$v); }
 
     /* the code above is auto generated do not remove the tag below */
     ###END_AUTOCODE
index 6ecb5134684633e982eebcbe9c4493e56d6e88ca..ffa12de29e26b92fef0c83442ee690e7be74aade 100644 (file)
@@ -17,12 +17,14 @@ class Sms_carrier extends Memcached_DataObject
     public $modified;                        // timestamp()   not_null default_CURRENT_TIMESTAMP
 
     /* Static get */
-    function staticGet($k,$v=NULL) { return Memcached_DataObject::staticGet('Sms_carrier',$k,$v); }
+    function staticGet($k,$v=null)
+    { return Memcached_DataObject::staticGet('Sms_carrier',$k,$v); }
 
     /* the code above is auto generated do not remove the tag below */
     ###END_AUTOCODE
-       
-       function toEmailAddress($sms) {
-               return sprintf($this->email_pattern, $sms);
-       }
+    
+    function toEmailAddress($sms)
+    {
+        return sprintf($this->email_pattern, $sms);
+    }
 }
index cc174fccee3fce58e022825e893767f82ff8f3ed..3fe0d167f1c094da91866c57535764fd52307cbb 100644 (file)
@@ -40,12 +40,14 @@ class Subscription extends Memcached_DataObject
     public $modified;                        // timestamp()   not_null default_CURRENT_TIMESTAMP
 
     /* Static get */
-    function staticGet($k,$v=NULL) { return Memcached_DataObject::staticGet('Subscription',$k,$v); }
+    function staticGet($k,$v=null)
+    { return Memcached_DataObject::staticGet('Subscription',$k,$v); }
 
     /* the code above is auto generated do not remove the tag below */
     ###END_AUTOCODE
-       
-       function &pkeyGet($kv) {
-               return Memcached_DataObject::pkeyGet('Subscription', $kv);
-       }
+    
+    function &pkeyGet($kv)
+    {
+        return Memcached_DataObject::pkeyGet('Subscription', $kv);
+    }
 }
index d180ecebebac2430d8d1b96239a67a32ac09bc7c..1fabd72f13a70a1b89a2f62b8bd916f4d425403c 100644 (file)
@@ -19,7 +19,8 @@ class Token extends Memcached_DataObject
     public $modified;                        // timestamp()   not_null default_CURRENT_TIMESTAMP
 
     /* Static get */
-    function staticGet($k,$v=NULL) { return Memcached_DataObject::staticGet('Token',$k,$v); }
+    function staticGet($k,$v=null)
+    { return Memcached_DataObject::staticGet('Token',$k,$v); }
 
     /* the code above is auto generated do not remove the tag below */
     ###END_AUTOCODE
index 32d5bedde1b72b6430637c1311aa6c1d84aa485d..92ff8776b0d669cc3ceb24deef9b7970722c37b9 100644 (file)
@@ -62,89 +62,98 @@ class User extends Memcached_DataObject
     public $modified;                        // timestamp()   not_null default_CURRENT_TIMESTAMP
 
     /* Static get */
-    function staticGet($k,$v=NULL) { return Memcached_DataObject::staticGet('User',$k,$v); }
+    function staticGet($k,$v=null)
+    { return Memcached_DataObject::staticGet('User',$k,$v); }
 
     /* the code above is auto generated do not remove the tag below */
     ###END_AUTOCODE
 
-       function getProfile() {
-               return Profile::staticGet('id', $this->id);
-       }
-
-       function isSubscribed($other) {
-               assert(!is_null($other));
-               # XXX: cache results of this query
-               $sub = Subscription::pkeyGet(array('subscriber' => $this->id,
-                                                                                  'subscribed' => $other->id));
-               return (is_null($sub)) ? false : true;
-       }
-
-       # 'update' won't write key columns, so we have to do it ourselves.
-
-       function updateKeys(&$orig) {
-               $parts = array();
-               foreach (array('nickname', 'email', 'jabber', 'incomingemail', 'sms', 'carrier', 'smsemail', 'language', 'timezone') as $k) {
-                       if (strcmp($this->$k, $orig->$k) != 0) {
-                               $parts[] = $k . ' = ' . $this->_quote($this->$k);
-                       }
-               }
-               if (count($parts) == 0) {
-                       # No changes
-                       return true;
-               }
-               $toupdate = implode(', ', $parts);
-
-               $table = $this->tableName();
-               if(common_config('db','quote_identifiers')) {
-                       $table = '"' . $table . '"';
-               }
-               $qry = 'UPDATE ' . $table . ' SET ' . $toupdate .
-                 ' WHERE id = ' . $this->id;
-               $orig->decache();
-               $result = $this->query($qry);
-               if ($result) {
-                       $this->encache();
-               }
-               return $result;
-       }
-
-       function allowed_nickname($nickname) {
-               # XXX: should already be validated for size, content, etc.
-               static $blacklist = array('rss', 'xrds', 'doc', 'main',
-                                                                 'settings', 'notice', 'user',
-                                                                 'search', 'avatar', 'tag', 'tags',
-                                                                 'api', 'message');
-               $merged = array_merge($blacklist, common_config('nickname', 'blacklist'));
-               return !in_array($nickname, $merged);
-       }
-
-       function getCurrentNotice($dt=NULL) {
-               $profile = $this->getProfile();
-               if (!$profile) {
-                       return NULL;
-               }
-               return $profile->getCurrentNotice($dt);
-       }
-
-       function getCarrier() {
-               return Sms_carrier::staticGet('id', $this->carrier);
-       }
-
-       function subscribeTo($other) {
-               $sub = new Subscription();
-               $sub->subscriber = $this->id;
-               $sub->subscribed = $other->id;
-
-               $sub->created = common_sql_now(); # current time
-
-               if (!$sub->insert()) {
-                       return false;
-               }
-
-               return true;
-       }
-
-    function hasBlocked($other) {
+    function getProfile()
+    {
+        return Profile::staticGet('id', $this->id);
+    }
+
+    function isSubscribed($other)
+    {
+        assert(!is_null($other));
+        # XXX: cache results of this query
+        $sub = Subscription::pkeyGet(array('subscriber' => $this->id,
+                                           'subscribed' => $other->id));
+        return (is_null($sub)) ? false : true;
+    }
+
+    # 'update' won't write key columns, so we have to do it ourselves.
+
+    function updateKeys(&$orig)
+    {
+        $parts = array();
+        foreach (array('nickname', 'email', 'jabber', 'incomingemail', 'sms', 'carrier', 'smsemail', 'language', 'timezone') as $k) {
+            if (strcmp($this->$k, $orig->$k) != 0) {
+                $parts[] = $k . ' = ' . $this->_quote($this->$k);
+            }
+        }
+        if (count($parts) == 0) {
+            # No changes
+            return true;
+        }
+        $toupdate = implode(', ', $parts);
+
+        $table = $this->tableName();
+        if(common_config('db','quote_identifiers')) {
+            $table = '"' . $table . '"';
+        }
+        $qry = 'UPDATE ' . $table . ' SET ' . $toupdate .
+          ' WHERE id = ' . $this->id;
+        $orig->decache();
+        $result = $this->query($qry);
+        if ($result) {
+            $this->encache();
+        }
+        return $result;
+    }
+
+    function allowed_nickname($nickname)
+    {
+        # XXX: should already be validated for size, content, etc.
+        static $blacklist = array('rss', 'xrds', 'doc', 'main',
+                                  'settings', 'notice', 'user',
+                                  'search', 'avatar', 'tag', 'tags',
+                                  'api', 'message');
+        $merged = array_merge($blacklist, common_config('nickname', 'blacklist'));
+        return !in_array($nickname, $merged);
+    }
+
+    function getCurrentNotice($dt=null)
+    {
+        $profile = $this->getProfile();
+        if (!$profile) {
+            return null;
+        }
+        return $profile->getCurrentNotice($dt);
+    }
+
+    function getCarrier()
+    {
+        return Sms_carrier::staticGet('id', $this->carrier);
+    }
+
+    function subscribeTo($other)
+    {
+        $sub = new Subscription();
+        $sub->subscriber = $this->id;
+        $sub->subscribed = $other->id;
+
+        $sub->created = common_sql_now(); # current time
+
+        if (!$sub->insert()) {
+            return false;
+        }
+
+        return true;
+    }
+
+    function hasBlocked($other)
+    {
 
         $block = Profile_block::get($this->id, $other->id);
 
@@ -158,261 +167,273 @@ class User extends Memcached_DataObject
         return $result;
     }
 
-       static function register($fields) {
+    static function register($fields) {
+
+        # MAGICALLY put fields into current scope
+
+        extract($fields);
+
+        $profile = new Profile();
+
+        $profile->query('BEGIN');
+
+        $profile->nickname = $nickname;
+        $profile->profileurl = common_profile_url($nickname);
+
+        if ($fullname) {
+            $profile->fullname = $fullname;
+        }
+        if ($homepage) {
+            $profile->homepage = $homepage;
+        }
+        if ($bio) {
+            $profile->bio = $bio;
+        }
+        if ($location) {
+            $profile->location = $location;
+        }
+
+        $profile->created = common_sql_now();
 
-               # MAGICALLY put fields into current scope
+        $id = $profile->insert();
 
-               extract($fields);
+        if (!$id) {
+            common_log_db_error($profile, 'INSERT', __FILE__);
+            return false;
+        }
 
-               $profile = new Profile();
+        $user = new User();
 
-               $profile->query('BEGIN');
+        $user->id = $id;
+        $user->nickname = $nickname;
 
-               $profile->nickname = $nickname;
-               $profile->profileurl = common_profile_url($nickname);
+        if ($password) { # may not have a password for OpenID users
+            $user->password = common_munge_password($password, $id);
+        }
 
-               if ($fullname) {
-                       $profile->fullname = $fullname;
-               }
-               if ($homepage) {
-                       $profile->homepage = $homepage;
-               }
-               if ($bio) {
-                       $profile->bio = $bio;
-               }
-               if ($location) {
-                       $profile->location = $location;
-               }
+        # Users who respond to invite email have proven their ownership of that address
 
-               $profile->created = common_sql_now();
+        if ($code) {
+            $invite = Invitation::staticGet($code);
+            if ($invite && $invite->address && $invite->address_type == 'email' && $invite->address == $email) {
+                $user->email = $invite->address;
+            }
+        }
 
-               $id = $profile->insert();
+        $inboxes = common_config('inboxes', 'enabled');
 
-               if (!$id) {
-                       common_log_db_error($profile, 'INSERT', __FILE__);
-                   return FALSE;
-               }
+        if ($inboxes === true || $inboxes == 'transitional') {
+            $user->inboxed = 1;
+        }
+
+        $user->created = common_sql_now();
+        $user->uri = common_user_uri($user);
+
+        $result = $user->insert();
 
-               $user = new User();
+        if (!$result) {
+            common_log_db_error($user, 'INSERT', __FILE__);
+            return false;
+        }
 
-               $user->id = $id;
-               $user->nickname = $nickname;
+        # Everyone is subscribed to themself
 
-               if ($password) { # may not have a password for OpenID users
-                       $user->password = common_munge_password($password, $id);
-               }
+        $subscription = new Subscription();
+        $subscription->subscriber = $user->id;
+        $subscription->subscribed = $user->id;
+        $subscription->created = $user->created;
 
-               # Users who respond to invite email have proven their ownership of that address
+        $result = $subscription->insert();
 
-               if ($code) {
-                       $invite = Invitation::staticGet($code);
-                       if ($invite && $invite->address && $invite->address_type == 'email' && $invite->address == $email) {
-                               $user->email = $invite->address;
-                       }
-               }
-
-               $inboxes = common_config('inboxes', 'enabled');
-
-               if ($inboxes === true || $inboxes == 'transitional') {
-                       $user->inboxed = 1;
-               }
-
-               $user->created = common_sql_now();
-               $user->uri = common_user_uri($user);
-
-               $result = $user->insert();
-
-               if (!$result) {
-                       common_log_db_error($user, 'INSERT', __FILE__);
-                       return FALSE;
-               }
-
-               # Everyone is subscribed to themself
-
-               $subscription = new Subscription();
-               $subscription->subscriber = $user->id;
-               $subscription->subscribed = $user->id;
-               $subscription->created = $user->created;
-
-               $result = $subscription->insert();
-
-               if (!$result) {
-                       common_log_db_error($subscription, 'INSERT', __FILE__);
-                       return FALSE;
-               }
-
-               if ($email && !$user->email) {
-
-                       $confirm = new Confirm_address();
-                       $confirm->code = common_confirmation_code(128);
-                       $confirm->user_id = $user->id;
-                       $confirm->address = $email;
-                       $confirm->address_type = 'email';
-
-                       $result = $confirm->insert();
-                       if (!$result) {
-                               common_log_db_error($confirm, 'INSERT', __FILE__);
-                               return FALSE;
-                       }
-               }
-
-               if ($code && $user->email) {
-                       $user->emailChanged();
-               }
-
-               $profile->query('COMMIT');
-
-               if ($email && !$user->email) {
-                       mail_confirm_address($user, $confirm->code, $profile->nickname, $email);
-               }
-
-               return $user;
-       }
-
-       # Things we do when the email changes
-
-       function emailChanged() {
-
-               $invites = new Invitation();
-               $invites->address = $this->email;
-               $invites->address_type = 'email';
-
-               if ($invites->find()) {
-                       while ($invites->fetch()) {
-                               $other = User::staticGet($invites->user_id);
-                               subs_subscribe_to($other, $this);
-                       }
-               }
-       }
-
-       function hasFave($notice) {
-               $cache = common_memcache();
-
-               # XXX: Kind of a hack.
-               if ($cache) {
-                       # This is the stream of favorite notices, in rev chron
-                       # order. This forces it into cache.
-                       $faves = $this->favoriteNotices(0, NOTICE_CACHE_WINDOW);
-                       $cnt = 0;
-                       while ($faves->fetch()) {
-                               if ($faves->id < $notice->id) {
-                                       # If we passed it, it's not a fave
-                                       return false;
-                               } else if ($faves->id == $notice->id) {
-                                       # If it matches a cached notice, then it's a fave
-                                       return true;
-                               }
-                               $cnt++;
-                       }
-                       # If we're not past the end of the cache window,
-                       # then the cache has all available faves, so this one
-                       # is not a fave.
-                       if ($cnt < NOTICE_CACHE_WINDOW) {
-                               return false;
-                       }
-                       # Otherwise, cache doesn't have all faves;
-                       # fall through to the default
-               }
-               $fave = Fave::pkeyGet(array('user_id' => $this->id,
-                                                                       'notice_id' => $notice->id));
-               return ((is_null($fave)) ? false : true);
-       }
-       function mutuallySubscribed($other) {
-               return $this->isSubscribed($other) &&
-                 $other->isSubscribed($this);
-       }
-
-        function mutuallySubscribedUsers() {
-
-               # 3-way join; probably should get cached
-               $qry = 'SELECT user.* ' .
-                 'FROM subscription sub1 JOIN user ON sub1.subscribed = user.id ' .
-                 'JOIN subscription sub2 ON user.id = sub2.subscriber ' .
-                 'WHERE sub1.subscriber = %d and sub2.subscribed = %d ' .
-                 'ORDER BY user.nickname';
-               $user = new User();
-               $user->query(sprintf($qry, $this->id, $this->id));
-
-               return $user;
-       }
-
-       function getReplies($offset=0, $limit=NOTICES_PER_PAGE, $since_id=0, $before_id=0, $since=NULL) {
-               $qry =
-                 'SELECT notice.* ' .
-                 'FROM notice JOIN reply ON notice.id = reply.notice_id ' .
-                 'WHERE reply.profile_id = %d ';
-               return Notice::getStream(sprintf($qry, $this->id),
-                                                                'user:replies:'.$this->id,
-                                                                $offset, $limit, $since_id, $before_id, NULL, $since);
-       }
-
-        function getNotices($offset=0, $limit=NOTICES_PER_PAGE, $since_id=0, $before_id=0, $since=NULL) {
+        if (!$result) {
+            common_log_db_error($subscription, 'INSERT', __FILE__);
+            return false;
+        }
+
+        if ($email && !$user->email) {
+
+            $confirm = new Confirm_address();
+            $confirm->code = common_confirmation_code(128);
+            $confirm->user_id = $user->id;
+            $confirm->address = $email;
+            $confirm->address_type = 'email';
+
+            $result = $confirm->insert();
+            if (!$result) {
+                common_log_db_error($confirm, 'INSERT', __FILE__);
+                return false;
+            }
+        }
+
+        if ($code && $user->email) {
+            $user->emailChanged();
+        }
+
+        $profile->query('COMMIT');
+
+        if ($email && !$user->email) {
+            mail_confirm_address($user, $confirm->code, $profile->nickname, $email);
+        }
+
+        return $user;
+    }
+
+    # Things we do when the email changes
+
+    function emailChanged()
+    {
+
+        $invites = new Invitation();
+        $invites->address = $this->email;
+        $invites->address_type = 'email';
+
+        if ($invites->find()) {
+            while ($invites->fetch()) {
+                $other = User::staticGet($invites->user_id);
+                subs_subscribe_to($other, $this);
+            }
+        }
+    }
+
+    function hasFave($notice)
+    {
+        $cache = common_memcache();
+
+        # XXX: Kind of a hack.
+        if ($cache) {
+            # This is the stream of favorite notices, in rev chron
+            # order. This forces it into cache.
+            $faves = $this->favoriteNotices(0, NOTICE_CACHE_WINDOW);
+            $cnt = 0;
+            while ($faves->fetch()) {
+                if ($faves->id < $notice->id) {
+                    # If we passed it, it's not a fave
+                    return false;
+                } else if ($faves->id == $notice->id) {
+                    # If it matches a cached notice, then it's a fave
+                    return true;
+                }
+                $cnt++;
+            }
+            # If we're not past the end of the cache window,
+            # then the cache has all available faves, so this one
+            # is not a fave.
+            if ($cnt < NOTICE_CACHE_WINDOW) {
+                return false;
+            }
+            # Otherwise, cache doesn't have all faves;
+            # fall through to the default
+        }
+        $fave = Fave::pkeyGet(array('user_id' => $this->id,
+                                    'notice_id' => $notice->id));
+        return ((is_null($fave)) ? false : true);
+    }
+    function mutuallySubscribed($other)
+    {
+        return $this->isSubscribed($other) &&
+          $other->isSubscribed($this);
+    }
+
+        function mutuallySubscribedUsers()
+        {
+
+        # 3-way join; probably should get cached
+        $qry = 'SELECT user.* ' .
+          'FROM subscription sub1 JOIN user ON sub1.subscribed = user.id ' .
+          'JOIN subscription sub2 ON user.id = sub2.subscriber ' .
+          'WHERE sub1.subscriber = %d and sub2.subscribed = %d ' .
+          'ORDER BY user.nickname';
+        $user = new User();
+        $user->query(sprintf($qry, $this->id, $this->id));
+
+        return $user;
+    }
+
+    function getReplies($offset=0, $limit=NOTICES_PER_PAGE, $since_id=0, $before_id=0, $since=null)
+    {
+        $qry =
+          'SELECT notice.* ' .
+          'FROM notice JOIN reply ON notice.id = reply.notice_id ' .
+          'WHERE reply.profile_id = %d ';
+        return Notice::getStream(sprintf($qry, $this->id),
+                                 'user:replies:'.$this->id,
+                                 $offset, $limit, $since_id, $before_id, null, $since);
+    }
+
+        function getNotices($offset=0, $limit=NOTICES_PER_PAGE, $since_id=0, $before_id=0, $since=null)
+        {
         $profile = $this->getProfile();
         if (!$profile) {
-            return NULL;
+            return null;
         } else {
             return $profile->getNotices($offset, $limit, $since_id, $before_id);
         }
-       }
-
-      function favoriteNotices($offset=0, $limit=NOTICES_PER_PAGE) {
-               $qry =
-                 'SELECT notice.* ' .
-                 'FROM notice JOIN fave ON notice.id = fave.notice_id ' .
-                 'WHERE fave.user_id = %d ';
-               return Notice::getStream(sprintf($qry, $this->id),
-                                                                'user:faves:'.$this->id,
-                                                                $offset, $limit);
-       }
-
-        function noticesWithFriends($offset=0, $limit=NOTICES_PER_PAGE, $since_id=0, $before_id=0, $since=NULL) {
-               $enabled = common_config('inboxes', 'enabled');
-
-               # Complicated code, depending on whether we support inboxes yet
-               # XXX: make this go away when inboxes become mandatory
-
-               if ($enabled === false ||
-                       ($enabled == 'transitional' && $this->inboxed == 0)) {
-                       $qry =
-                         'SELECT notice.* ' .
-                         'FROM notice JOIN subscription ON notice.profile_id = subscription.subscribed ' .
-                         'WHERE subscription.subscriber = %d ';
-                       $order = NULL;
-               } else if ($enabled === true ||
-                          ($enabled == 'transitional' && $this->inboxed == 1)) {
-
-                       $qry =
-                         'SELECT notice.* ' .
-                         'FROM notice JOIN notice_inbox ON notice.id = notice_inbox.notice_id ' .
-                         'WHERE notice_inbox.user_id = %d ';
-                       # NOTE: we override ORDER
-                       $order = 'ORDER BY notice_inbox.created DESC, notice_inbox.notice_id DESC ';
-               }
-               return Notice::getStream(sprintf($qry, $this->id),
-                                                                'user:notices_with_friends:' . $this->id,
-                                                                $offset, $limit, $since_id, $before_id,
-                                                                $order, $since);
-       }
-
-        function blowFavesCache() {
-               $cache = common_memcache();
-               if ($cache) {
-                       # Faves don't happen chronologically, so we need to blow
-                       # ;last cache, too
-                       $cache->delete(common_cache_key('user:faves:'.$this->id));
-                       $cache->delete(common_cache_key('user:faves:'.$this->id).';last');
-               }
-       }
-
-        function getSelfTags() {
-               return Profile_tag::getTags($this->id, $this->id);
-       }
-
-        function setSelfTags($newtags) {
-               return Profile_tag::setTags($this->id, $this->id, $newtags);
-       }
-
-    function block($other) {
+    }
+
+      function favoriteNotices($offset=0, $limit=NOTICES_PER_PAGE)
+      {
+        $qry =
+          'SELECT notice.* ' .
+          'FROM notice JOIN fave ON notice.id = fave.notice_id ' .
+          'WHERE fave.user_id = %d ';
+        return Notice::getStream(sprintf($qry, $this->id),
+                                 'user:faves:'.$this->id,
+                                 $offset, $limit);
+    }
+
+        function noticesWithFriends($offset=0, $limit=NOTICES_PER_PAGE, $since_id=0, $before_id=0, $since=null)
+        {
+        $enabled = common_config('inboxes', 'enabled');
+
+        # Complicated code, depending on whether we support inboxes yet
+        # XXX: make this go away when inboxes become mandatory
+
+        if ($enabled === false ||
+            ($enabled == 'transitional' && $this->inboxed == 0)) {
+            $qry =
+              'SELECT notice.* ' .
+              'FROM notice JOIN subscription ON notice.profile_id = subscription.subscribed ' .
+              'WHERE subscription.subscriber = %d ';
+            $order = null;
+        } else if ($enabled === true ||
+               ($enabled == 'transitional' && $this->inboxed == 1)) {
+
+            $qry =
+              'SELECT notice.* ' .
+              'FROM notice JOIN notice_inbox ON notice.id = notice_inbox.notice_id ' .
+              'WHERE notice_inbox.user_id = %d ';
+            # NOTE: we override ORDER
+            $order = 'ORDER BY notice_inbox.created DESC, notice_inbox.notice_id DESC ';
+        }
+        return Notice::getStream(sprintf($qry, $this->id),
+                                 'user:notices_with_friends:' . $this->id,
+                                 $offset, $limit, $since_id, $before_id,
+                                 $order, $since);
+    }
+
+        function blowFavesCache()
+        {
+        $cache = common_memcache();
+        if ($cache) {
+            # Faves don't happen chronologically, so we need to blow
+            # ;last cache, too
+            $cache->delete(common_cache_key('user:faves:'.$this->id));
+            $cache->delete(common_cache_key('user:faves:'.$this->id).';last');
+        }
+    }
+
+        function getSelfTags()
+        {
+        return Profile_tag::getTags($this->id, $this->id);
+    }
+
+        function setSelfTags($newtags)
+        {
+        return Profile_tag::setTags($this->id, $this->id, $newtags);
+    }
+
+    function block($other)
+    {
 
         # Add a new block record
 
@@ -434,8 +455,8 @@ class User extends Memcached_DataObject
 
         # Cancel their subscription, if it exists
 
-               $sub = Subscription::pkeyGet(array('subscriber' => $other->id,
-                                                                                  'subscribed' => $this->id));
+        $sub = Subscription::pkeyGet(array('subscriber' => $other->id,
+                                           'subscribed' => $this->id));
 
         if ($sub) {
             $result = $sub->delete();
@@ -450,7 +471,8 @@ class User extends Memcached_DataObject
         return true;
     }
 
-    function unblock($other) {
+    function unblock($other)
+    {
 
         # Get the block record
 
index ad68f74024770dc7eaccf3f3c22dff9a163202db..f4fda1c72e48985e09cc0657994cf42a4377c446 100644 (file)
@@ -17,7 +17,8 @@ class User_openid extends Memcached_DataObject
     public $modified;                        // timestamp()   not_null default_CURRENT_TIMESTAMP
 
     /* Static get */
-    function staticGet($k,$v=NULL) { return Memcached_DataObject::staticGet('User_openid',$k,$v); }
+    function staticGet($k,$v=null)
+    { return Memcached_DataObject::staticGet('User_openid',$k,$v); }
 
     /* the code above is auto generated do not remove the tag below */
     ###END_AUTOCODE
diff --git a/file/.gitignore b/file/.gitignore
new file mode 100644 (file)
index 0000000..e69de29
index bd29d318f52fa1e22768ab321e7a4abf3bbdf074..e348635a86823d2ddeab8b9034e65b63fa580949 100644 (file)
@@ -143,6 +143,9 @@ RewriteRule ^api/notifications/leave/(.*)$ index.php?action=api&apiaction=notifi
 RewriteRule ^api/blocks/create/(.*)$ index.php?action=api&apiaction=blocks&method=create&argument=$1 [L,QSA]
 RewriteRule ^api/blocks/destroy/(.*)$ index.php?action=api&apiaction=blocks&method=destroy&argument=$1 [L,QSA]
 RewriteRule ^api/help/(.*)$ index.php?action=api&apiaction=help&method=$1 [L,QSA]
+RewriteRule ^api/laconica/version(.*)$ index.php?action=api&apiaction=laconica&method=version$1 [L,QSA]
+RewriteRule ^api/laconica/config(.*)$ index.php?action=api&apiaction=laconica&method=config$1 [L,QSA]
+RewriteRule ^api/laconica/wadl\.xml$ index.php?action=api&apiaction=laconica&method=wadl.xml [L,QSA]
 
 <FilesMatch "\.(ini)">
   Order allow,deny
index d387740fc230624fc99e660045877efc88125cb3..3cecb5c8b6c3825d5e2e116ba05a2574191231ba 100644 (file)
--- a/index.php
+++ b/index.php
@@ -1,5 +1,5 @@
 <?php
-/*
+/**
  * Laconica - a distributed open-source microblogging tool
  * Copyright (C) 2008, Controlez-Vous, Inc.
  *
 define('INSTALLDIR', dirname(__FILE__));
 define('LACONICA', true);
 
-require_once(INSTALLDIR . "/lib/common.php");
+require_once INSTALLDIR . '/lib/common.php';
 
-# get and cache current user
+// get and cache current user
 
 $user = common_current_user();
 
-# initialize language env
+// initialize language env
 
 common_init_language();
 
@@ -41,30 +41,34 @@ if (!$action || !preg_match('/^[a-zA-Z0-9_-]*$/', $action)) {
 
 if (!$user && common_config('site', 'private') &&
     !in_array($action, array('login', 'openidlogin', 'finishopenidlogin',
-                             'recoverpassword', 'api', 'doc', 'register')))
-{
+                             'recoverpassword', 'api', 'doc', 'register'))) {
     common_redirect(common_local_url('login'));
 }
 
 $actionfile = INSTALLDIR."/actions/$action.php";
 
 if (file_exists($actionfile)) {
-    require_once($actionfile);
-    $action_class = ucfirst($action)."Action";
+
+    include_once $actionfile;
+
+    $action_class = ucfirst($action).'Action';
+
     $action_obj = new $action_class();
-       if ($config['db']['mirror'] && $action_obj->is_readonly()) {
-               if (is_array($config['db']['mirror'])) {
-                       # "load balancing", ha ha
-                       $k = array_rand($config['db']['mirror']);
-                       $mirror = $config['db']['mirror'][$k];
-               } else {
-                       $mirror = $config['db']['mirror'];
-               }
-               $config['db']['database'] = $mirror;
-       }
+
+    if ($config['db']['mirror'] && $action_obj->is_readonly()) {
+        if (is_array($config['db']['mirror'])) {
+            // "load balancing", ha ha
+            $k = array_rand($config['db']['mirror']);
+
+            $mirror = $config['db']['mirror'][$k];
+        } else {
+            $mirror = $config['db']['mirror'];
+        }
+        $config['db']['database'] = $mirror;
+    }
     if (call_user_func(array($action_obj, 'prepare'), $_REQUEST)) {
-               call_user_func(array($action_obj, 'handle'), $_REQUEST);
-       }
+        call_user_func(array($action_obj, 'handle'), $_REQUEST);
+    }
 } else {
     common_user_error(_('Unknown action'));
 }
\ No newline at end of file
diff --git a/js/identica-badge.js b/js/identica-badge.js
new file mode 100644 (file)
index 0000000..5c586b5
--- /dev/null
@@ -0,0 +1,293 @@
+// identica badge -- updated to work with the native API, 12-4-2008
+// copyright Kent Brewster 2008
+// see http://kentbrewster.com/identica-badge for info
+( function() { 
+   var trueName = '';
+   for (var i = 0; i < 16; i++) { 
+      trueName += String.fromCharCode(Math.floor(Math.random() * 26) + 97); 
+   }
+   window[trueName] = {};
+   var $ = window[trueName];
+   $.f = function() {
+      return { 
+         runFunction : [],
+         init : function(target) {
+            var theScripts = document.getElementsByTagName('SCRIPT');
+            for (var i = 0; i < theScripts.length; i++) {
+               if (theScripts[i].src.match(target)) {
+                  $.a = {};
+                  if (theScripts[i].innerHTML) {
+                     $.a = $.f.parseJson(theScripts[i].innerHTML);
+                  }
+                  if ($.a.err) {
+                     alert('bad json!');
+                  }
+                  $.f.loadDefaults();
+                  $.f.buildStructure();
+                  $.f.buildPresentation();
+                  theScripts[i].parentNode.insertBefore($.s, theScripts[i]);
+                  theScripts[i].parentNode.removeChild(theScripts[i]);
+                  break;
+               }
+            }         
+         },
+         parseJson : function(json) {
+            this.parseJson.data = json;
+            if ( typeof json !== 'string') {
+               return {"err":"trying to parse a non-string JSON object"};
+            }
+            try {
+               var f = Function(['var document,top,self,window,parent,Number,Date,Object,Function,',
+                  'Array,String,Math,RegExp,Image,ActiveXObject;',
+                  'return (' , json.replace(/<\!--.+-->/gim,'').replace(/\bfunction\b/g,'function&shy;') , ');'].join(''));
+               return f();
+            } catch (e) {
+               return {"err":"trouble parsing JSON object"};
+            }
+         },
+         loadDefaults : function() {
+            $.d = { 
+               "user":"7000",
+               "headerText" : "",
+               "height" : 350,
+               "width" : 300,
+               "background" : "#193441",
+               "border" : "1px solid black",
+               "userFontSize" : "inherit",
+               "userColor" : "inherit",
+               "headerBackground" : "transparent", 
+               "headerColor" : "white",
+               "evenBackground" : "#fff",
+               "oddBackground" : "#eee",
+               "thumbnailBorder" : "1px solid black",
+               "thumbnailSize" : 24,
+               "padding" : 3,
+               "server" : "identi.ca"
+            };
+            for (var k in $.d) { if ($.a[k] === undefined) { $.a[k] = $.d[k]; } }
+         },
+          buildPresentation : function () {
+            var ns = document.createElement('style');
+            document.getElementsByTagName('head')[0].appendChild(ns);
+            if (!window.createPopup) {
+               ns.appendChild(document.createTextNode(''));
+               ns.setAttribute("type", "text/css");
+            }
+            var s = document.styleSheets[document.styleSheets.length - 1];
+            var rules = {
+               "" : "{zoom:1;margin:0;padding:0;width:" + $.a.width + "px;background:" + $.a.background + ";border:" + $.a.border + ";font:13px/1.2em tahoma, veranda, arial, helvetica, clean, sans-serif;*font-size:small;*font:x-small;}",
+               "a" : "{cursor:pointer;text-decoration:none;}",
+               "a:hover" : "{text-decoration:underline;}",
+               "cite" : "{font-weight:bold;margin:0 0 0 4px;padding:0;display:block;font-style:normal;line-height:" + ($.a.thumbnailSize/2) + "px;}",
+               "cite a" : "{color:#C15D42;}",
+               "date":"{font-size:87%;margin:0 0 0 4px;padding:0;display:block;font-style:normal;line-height:" + ($.a.thumbnailSize/2) + "px;}",
+               "date:after" : "{clear:both; content:\".\"; display:block; height:0; visibility:hidden; }",
+               "date a" : "{color:#676;}",
+               "h3" : "{margin:0;padding:" + $.a.padding + "px;font-weight:bold;background:" + $.a.headerBackground + " url('http://" + $.a.server + "/favicon.ico') " + $.a.padding + "px 50% no-repeat;text-indent:" + ($.a.padding + 16) + "px;}",
+               "h3.loading" : "{background-image:url('http://l.yimg.com/us.yimg.com/i/us/my/mw/anim_loading_sm.gif');}",
+               "h3 a" : "{font-size:92%; color:" + $.a.headerColor + ";}",
+               "h4" : "{font-weight:normal; background:" + $.a.headerBackground + ";text-align:right;margin:0;padding:" + $.a.padding + "px;}",
+               "h4 a" : "{font-size:92%; color:" + $.a.headerColor + ";}",
+               "img":"{float:left; height:" + $.a.thumbnailSize + "px;width:" + $.a.thumbnailSize + "px;border:" + $.a.thumbnailBorder + ";margin-right:" + $.a.padding + "px;}",
+               "p" : "{margin:0; padding:0;width:" + ($.a.width - 22) + "px;overflow:hidden;font-size:87%;}",
+               "p a" : "{color:#C15D42;}",
+               "ul":"{margin:0; padding:0; height:" + $.a.height + "px;width:" + $.a.width + "px;overflow:auto;}",
+               "ul li":"{background:" + $.a.evenBackground + ";margin:0;padding:" + $.a.padding + "px;list-style:none;width:" + ($.a.width - 22) + "px;overflow:hidden;border-bottom:1px solid #D8E2D7;}",
+               "ul li:hover":"{background:#f3f8ea;}"
+            };
+            var ieRules = "";
+            // brute-force each and every style rule here to !important
+            // sometimes you have to take off and nuke the site from orbit; it's the only way to be sure
+            for (var z in rules) {
+               var selector = '.' + trueName + ' ' + z;
+               var rule = rules[z];
+               if (typeof rule === 'string') {
+                  var important = rule.replace(/;/gi, '!important;');
+                  if (!window.createPopup) {
+                     var theRule = document.createTextNode(selector + important);
+                     ns.appendChild(theRule);
+                  } else {
+                     ieRules += selector + important;
+                  }
+               }
+            }
+            if (window.createPopup) { s.cssText = ieRules; }
+         },
+         buildStructure : function() {
+            $.s = document.createElement('DIV');
+            $.s.className = trueName;         
+            $.s.h = document.createElement('H3');
+            $.s.h.a = document.createElement('A');
+            $.s.h.a.target = '_laconica';
+            $.s.h.appendChild($.s.h.a);
+            $.s.appendChild($.s.h);
+            $.s.r = document.createElement('UL');
+            $.s.appendChild($.s.r);
+            $.s.f = document.createElement('H4');
+            var a = document.createElement('A');
+            a.innerHTML = 'get this';
+            a.target = '_blank';
+            a.href = 'http://kentbrewster.com/identica-badge';
+            $.s.f.appendChild(a);
+            $.s.appendChild($.s.f);
+            $.f.getUser();
+         },
+         getUser : function() {
+            if (!$.f.runFunction) { $.f.runFunction = []; }
+            var n = $.f.runFunction.length;
+            var id = trueName + '.f.runFunction[' + n + ']';
+            $.f.runFunction[n] = function(r) {
+               delete($.f.runFunction[n]);
+               var a = document.createElement('A');
+               a.rel = $.a.user;
+               a.rev = r.name; 
+               a.id = r.screen_name;
+               $.f.removeScript(id);
+               $.f.changeUserTo(a);
+            };
+            var url = 'http://' + $.a.server + '/api/users/show/' + $.a.user + '.json?callback=' + id;
+            $.f.runScript(url, id);
+         },
+         changeUserTo : function(el) {
+            $.a.user = el.rel;
+            $.s.h.a.innerHTML = el.rev + $.a.headerText;
+            $.s.h.a.href = 'http://' + $.a.server + '/' + el.id;
+            $.f.runSearch(); 
+         },
+         runSearch : function() {
+            $.s.h.className = 'loading';
+            $.s.r.innerHTML = '';
+            if (!$.f.runFunction) { $.f.runFunction = []; }
+            var n = $.f.runFunction.length;
+            var id = trueName + '.f.runFunction[' + n + ']';
+            $.f.runFunction[n] = function(r) {
+               delete($.f.runFunction[n]);
+               $.f.removeScript(id);
+               $.f.renderResult(r); 
+            };
+            var url = 'http://' + $.a.server + '/api/statuses/friends/' + $.a.user + '.json?callback=' + id;
+            $.f.runScript(url, id);
+         },
+         renderResult: function(r) { 
+            for (var i = 0; i < r.length; i++) {
+               if (!r[i].status) {
+                  r.splice(i, 1);
+               } else {
+                  r[i].status_id = parseInt(r[i].status.id);
+               }
+            }
+            r = $.f.sortArray(r, "status_id", true);
+            $.s.h.className = '';
+            for (var i = 0; i < r.length; i++) {
+               var li = document.createElement('LI');
+               var icon = document.createElement('A');
+               if (r[i] && r[i].url) {
+                  icon.href = r[i].url;
+                  icon.target = '_laconica'; 
+                  icon.title = 'Visit ' + r[i].screen_name + ' at ' + r[i].url;
+               } else {
+                  icon.href = 'http://' + $.a.server + '/' + r[i].screen_name;
+                  icon.target = '_laconica'; 
+                  icon.title = 'Visit ' + r[i].screen_name + ' at http://' + $.a.server + '/' + r[i].screen_name;
+               }
+
+               var img = document.createElement('IMG');
+               img.src = r[i].profile_image_url;
+               icon.appendChild(img);
+               li.appendChild(icon); 
+               
+               var user = document.createElement('CITE');
+               var a = document.createElement('A');
+               a.rel = r[i].id;
+               a.rev = r[i].name;
+               a.id = r[i].screen_name;
+               a.innerHTML = r[i].name; 
+               a.href = 'http://' + $.a.server + '/' + r[i].screen_name;
+               a.onclick = function() {
+                  $.f.changeUserTo(this);
+                  return false;
+               };
+               user.appendChild(a);
+               li.appendChild(user);
+               var updated = document.createElement('DATE');
+               if (r[i].status && r[i].status.created_at) {
+                  var date_link = document.createElement('A');
+                  date_link.innerHTML = r[i].status.created_at.split(/\+/)[0];
+                  date_link.href = 'http://' + $.a.server + '/notice/' + r[i].status.id;
+                  date_link.target = '_laconica';
+                  updated.appendChild(date_link);
+                  if (r[i].status.in_reply_to_status_id) {
+                     updated.appendChild(document.createTextNode(' in reply to '));
+                     var in_reply_to = document.createElement('A');
+                     in_reply_to.innerHTML = r[i].status.in_reply_to_status_id;
+                     in_reply_to.href = 'http://' + $.a.server + '/notice/' + r[i].status.in_reply_to_status_id;
+                     in_reply_to.target = '_laconica';
+                     updated.appendChild(in_reply_to);
+                  }
+               } else {
+                  updated.innerHTML = 'has not updated yet';
+               }
+               li.appendChild(updated);
+               var p = document.createElement('P');
+               if (r[i].status && r[i].status.text) {
+                  var raw = r[i].status.text;
+                  var cooked = raw;
+                  cooked = cooked.replace(/http:\/\/([^ ]+)/g, "<a href=\"http://$1\" target=\"_laconica\">http://$1</a>");
+                  cooked = cooked.replace(/@([\w*]+)/g, '@<a href="http://' + $.a.server + '/$1" target=\"_laconica\">$1</a>');
+                  cooked = cooked.replace(/#([\w*]+)/g, '#<a href="http://' + $.a.server + '/tag/$1" target="_laconica">$1</a>');
+                  p.innerHTML = cooked;
+               }
+               li.appendChild(p);
+               var a = p.getElementsByTagName('A');
+               for (var j = 0; j < a.length; j++) {
+                  if (a[j].className == 'changeUserTo') {
+                     a[j].className = '';
+                     a[j].href = 'http://' + $.a.server + '/' + a[j].innerHTML;
+                     a[j].rel = a[j].innerHTML;
+                     a[j].onclick = function() { 
+                        $.f.changeUserTo(this); 
+                        return false;
+                     } 
+                  }
+               }
+               $.s.r.appendChild(li);
+            }         
+         },
+         sortArray : function(r, k, x) {
+            if (window.createPopup) { 
+               return r; 
+            }
+            function s(a, b) {
+               if (x === true) {
+                   return b[k] - a[k];
+               } else {
+                   return a[k] - b[k];
+               }
+            }
+            r = r.sort(s);
+            return r;
+         },         
+         runScript : function(url, id) {
+            var s = document.createElement('script');
+            s.id = id;
+            s.type ='text/javascript';
+            s.src = url;
+            document.getElementsByTagName('body')[0].appendChild(s);
+         },
+         removeScript : function(id) {
+            if (document.getElementById(id)) {
+               var s = document.getElementById(id);
+               s.parentNode.removeChild(s);
+            }
+         }         
+      };
+   }();
+//   var thisScript = /^https?:\/\/[^\/]*r8ar.com\/identica-badge.js$/;
+   var thisScript = /identica-badge.js$/;
+   if(typeof window.addEventListener !== 'undefined') {
+      window.addEventListener('load', function() { $.f.init(thisScript); }, false);
+   } else if(typeof window.attachEvent !== 'undefined') {
+      window.attachEvent('onload', function() { $.f.init(thisScript); });
+   }
+} )();
+
diff --git a/js/jcrop/Jcrop.gif b/js/jcrop/Jcrop.gif
new file mode 100644 (file)
index 0000000..72ea7cc
Binary files /dev/null and b/js/jcrop/Jcrop.gif differ
diff --git a/js/jcrop/jquery.Jcrop.css b/js/jcrop/jquery.Jcrop.css
new file mode 100644 (file)
index 0000000..b95178a
--- /dev/null
@@ -0,0 +1,45 @@
+/* Fixes issue here http://code.google.com/p/jcrop/issues/detail?id=1 */
+.jcrop-holder
+{
+       text-align: left;
+}
+
+.jcrop-vline, .jcrop-hline
+{
+       font-size: 0;
+       position: absolute;
+       background: white url('Jcrop.gif') top left repeat;
+       /*
+       opacity: .5;
+       *filter:alpha(opacity=50);
+       */
+}
+.jcrop-vline { height: 100%; width: 1px !important; }
+.jcrop-hline { width: 100%; height: 1px !important; }
+.jcrop-handle {
+       font-size: 1px;
+       width: 7px !important;
+       height: 7px !important;
+       border: 1px #eee solid;
+       background-color: #333;
+       *width: 9px;
+       *height: 9px;
+}
+
+.jcrop-tracker {
+       *background-color: gray;
+       width: 100%; height: 100%;
+}
+
+.custom .jcrop-vline,
+.custom .jcrop-hline
+{
+       background: yellow;
+}
+.custom .jcrop-handle
+{
+       border-color: black;
+       background-color: #C7BB00;
+       -moz-border-radius: 3px;
+       -webkit-border-radius: 3px;
+}
diff --git a/js/jcrop/jquery.Jcrop.go.js b/js/jcrop/jquery.Jcrop.go.js
new file mode 100644 (file)
index 0000000..7c5b5e4
--- /dev/null
@@ -0,0 +1,41 @@
+               $(function(){
+                       jQuery("#avatar_original img.avatar").Jcrop({ onChange: showPreview,
+                                                                                                             setSelect: [ 0, 0, $("#avatar_original img.avatar").attr("width"), $("#avatar_original img.avatar").attr("height") ],
+                                                                                                                 onSelect: updateCoords,
+                                                                                                             aspectRatio: 1,
+                                                                                                                 boxWidth: 480,
+                                                                                                                 boxHeight: 480,
+                                                                                                                 bgColor: '#000',
+                                                                                                                 bgOpacity: .4
+                                                                                               });
+               });
+
+               function showPreview(coords) {
+                       var rx = 96 / coords.w;
+                       var ry = 96 / coords.h;
+
+                       var img_width = $("#avatar_original img.avatar").attr("width");
+                       var img_height = $("#avatar_original img.avatar").attr("height");
+
+
+                       $('#avatar_preview img.avatar').css({
+                               width: Math.round(rx *img_width) + 'px',
+                               height: Math.round(ry * img_height) + 'px',
+                               marginLeft: '-' + Math.round(rx * coords.x) + 'px',
+                               marginTop: '-' + Math.round(ry * coords.y) + 'px'
+                       });
+               };
+
+               function updateCoords(c) {
+                       $('#avatar_crop_x').val(c.x);
+                       $('#avatar_crop_y').val(c.y);
+                       $('#avatar_crop_w').val(c.w);
+                       $('#avatar_crop_h').val(c.h);
+               };
+
+               function checkCoords() {
+                       if (parseInt($('#avatar_crop_w').val())) return true;
+                       alert('Please select a crop region then press submit.');
+                       return false;
+               };
+
diff --git a/js/jcrop/jquery.Jcrop.pack.js b/js/jcrop/jquery.Jcrop.pack.js
new file mode 100644 (file)
index 0000000..aa82e8a
--- /dev/null
@@ -0,0 +1,8 @@
+/**
+ * Jcrop v.0.9.5 (packed)
+ * (c) 2008 Kelly Hallman and DeepLiquid.com
+ * More information: http://deepliquid.com/content/Jcrop.html
+ * Released under MIT License - this header must remain with code
+ */
+
+eval(function(p,a,c,k,e,d){e=function(c){return(c<a?'':e(parseInt(c/a)))+((c=c%a)>35?String.fromCharCode(c+29):c.toString(36))};if(!''.replace(/^/,String)){while(c--){d[e(c)]=k[c]||e(c)}k=[function(e){return d[e]}];e=function(){return'\\w+'};c=1};while(c--){if(k[c]){p=p.replace(new RegExp('\\b'+e(c)+'\\b','g'),k[c])}}return p}('$.1n=7(G,F){d G=G,F=F;g(1p(G)!==\'2d\')G=$(G)[0];g(1p(F)!==\'2d\')F={};g(!(\'2x\'1a F))F.2x=$.3d.3e?K:M;g(!(\'2c\'1a F))F.2c=$.3d.3e?K:M;d 4f={2x:K,3W:\'4C\',1f:4D,3T:\'4Y\',3x:.6,3O:.4,3P:.5,53:5,3N:9,3D:5,51:14,25:0,2c:M,3I:M,3B:M,30:M,3A:M,49:0,4p:0,4k:8,3V:20,3X:3,2f:K,3n:[0,0],2z:[0,0],2O:[0,0],2D:7(){},2G:7(){}};d j=4f;21(F);d $I=$(G).B({16:\'1b\'});47($I,j.49,j.4p);d S=$I.W(),L=$I.U(),$12=$(\'<12 />\').W(S).U(L).1f(1L(\'4F\')).B({16:\'4H\',4B:j.3T});g(j.1f)$12.1f(j.1f);$I.54($12);d $34=$(\'<I />\').3Y(\'2N\',$I.3Y(\'2N\')).B(\'16\',\'1b\').W(S).U(L);d $2C=$(\'<12 />\').W(1t(V)).U(1t(V)).B({1l:59,16:\'1b\',4o:\'4g\'}).1P($34);d $2g=$(\'<12 />\').W(1t(V)).U(1t(V)).B({1l:5b});d $28=$(\'<12 />\').B({16:\'1b\',1l:55}).3U($I).1P($2C,$2g);d 23=j.4k;d $1S=$(\'<12 />\').1f(1L(\'3v\')).W(S+(23*2)).U(L+(23*2)).B({16:\'1b\',R:D(-23),P:D(-23),1l:3R,1z:0}).3q(48);d 1I,1Q;d 2u=2Q(G),1q,1B,3i,58,3h,1O;g(\'36\'1a j){1I=j.36[0]/S;1Q=j.36[1]/L}d E=7(){d A=0,u=0,q=0,m=0,Z,Y;7 1A(z){d z=2T(z);q=A=z[0];m=u=z[1]};7 1y(z){d z=2T(z);Z=z[0]-q;Y=z[1]-m;q=z[0];m=z[1]};7 3f(){k[Z,Y]};7 2b(2y){d Z=2y[0],Y=2y[1];g(0>A+Z)Z-=Z+A;g(0>u+Y)Y-=Y+u;g(L<m+Y)Y+=L-(m+Y);g(S<q+Z)Z+=S-(q+Z);A+=Z;q+=Z;u+=Y;m+=Y};7 2K(T){d c=Q();1E(T){C\'1s\':k[c.q,c.y];C\'11\':k[c.x,c.y];C\'2e\':k[c.q,c.m];C\'1M\':k[c.x,c.m]}};7 Q(){g(!j.25&&!1B)k 3F();d 1k=j.25?j.25:1B,5c=j.2O,4u=j.2z,1V=q-A,1Z=m-u,3c=N.17(1V),3j=N.17(1Z),3M=3c/3j,15,13;g(3M<1k){13=m;w=3j*1k;15=1V<0?A-w:w+A;g(15<0){15=0;h=N.17((15-A)/1k);13=1Z<0?u-h:h+u}1g g(15>S){15=S;h=N.17((15-A)/1k);13=1Z<0?u-h:h+u}}1g{15=q;h=3c/1k;13=1Z<0?u-h:u+h;g(13<0){13=0;w=N.17((13-u)*1k);15=1V<0?A-w:w+A}1g g(13>L){13=L;w=N.17(13-u)*1k;15=1V<0?A-w:w+A}}k 4E=3g(1F(A,u,15,13))};7 2T(p){g(p[0]<0)p[0]=0;g(p[1]<0)p[1]=0;g(p[0]>S)p[0]=S;g(p[1]>L)p[1]=L;k[p[0],p[1]]};7 1F(A,u,q,m){d 2R=A,3r=q,3o=u,3l=m;g(q<A){2R=q;3r=A}g(m<u){3o=m;3l=u}k[N.1K(2R),N.1K(3o),N.1K(3r),N.1K(3l)]};7 3F(){d 1U=q-A;d 22=m-u;g(2q&&(N.17(1U)>2q))q=(1U>0)?(A+2q):(A-2q);g(2n&&(N.17(22)>2n))m=(22>0)?(u+2n):(u-2n);g(2i&&(N.17(22)<2i))m=(22>0)?(u+2i):(u-2i);g(2m&&(N.17(1U)<2m))q=(1U>0)?(A+2m):(A-2m);g(A<0){q-=A;A-=A}g(u<0){m-=u;u-=u}g(q<0){A-=q;q-=q}g(m<0){u-=m;m-=m}g(q>S){d X=q-S;A-=X;q-=X}g(m>L){d X=m-L;u-=X;m-=X}g(A>S){d X=A-L;m-=X;u-=X}g(u>L){d X=u-L;m-=X;u-=X}k 3g(1F(A,u,q,m))};7 3g(a){k{x:a[0],y:a[1],q:a[2],m:a[3],w:a[2]-a[0],h:a[3]-a[1]}};k{1F:1F,1A:1A,1y:1y,3f:3f,2b:2b,2K:2K,Q:Q}}();d J=7(){d 4v,4z,4y,1R,2U=4x;d 2F={};d H={};d 2E=K;d 1i=j.3D;g(j.30){2F={R:1Y(\'3C\').B(\'R\',$.3d.3e?D(-1):D(0)),3Q:1Y(\'3C\'),P:1Y(\'3z\'),3L:1Y(\'3z\')}}g(j.3A){H.t=1W(\'n\');H.b=1W(\'s\');H.r=1W(\'e\');H.l=1W(\'w\')}j.3B&&2Y([\'n\',\'s\',\'e\',\'w\']);j.3I&&2Y([\'1M\',\'11\',\'1s\',\'2e\']);7 1Y(1u){d 1J=$(\'<12 />\').B({16:\'1b\',1z:j.3O}).1f(1L(1u));$2C.1P(1J);k 1J};7 2W(T,3y){d 1J=$(\'<12 />\').3q(3b(T)).B({3p:T+\'-2A\',16:\'1b\',1l:3y});$2g.1P(1J);k 1J};7 3J(T){k 2W(T,2U++).B({R:D(-1i+1),P:D(-1i+1),1z:j.3P}).1f(1L(\'H\'))};7 1W(T){d s=j.3N,o=1i,h=s,w=s,t=o,l=o;1E(T){C\'n\':C\'s\':w=1t(V);O;C\'e\':C\'w\':h=1t(V);O}k 2W(T,2U++).W(w).U(h).B({R:D(-t+1),P:D(-l+1)})};7 2Y(2J){4U(i 1a 2J)H[2J[i]]=3J(2J[i])};7 31(c){d 3a=N.1K((c.h/2)-1i),35=N.1K((c.w/2)-1i),4V=4W=-1i+1,2a=c.w-1i,1X=c.h-1i,x,y;\'e\'1a H&&H.e.B({R:D(3a),P:D(2a)})&&H.w.B({R:D(3a)})&&H.s.B({R:D(1X),P:D(35)})&&H.n.B({P:D(35)});\'1s\'1a H&&H.1s.B({P:D(2a)})&&H.2e.B({R:D(1X),P:D(2a)})&&H.1M.B({R:D(1X)});\'b\'1a H&&H.b.B({R:D(1X)})&&H.r.B({P:D(2a)})};7 3K(x,y){$34.B({R:D(-y),P:D(-x)});$28.B({R:D(y),P:D(x)})};7 2A(w,h){$28.W(w).U(h)};7 3s(){d p=E.Q();E.1A([p.x,p.y]);E.1y([p.q,p.m])};7 2I(){g(1R)k 1e()};7 1e(){d c=E.Q();2A(c.w,c.h);3K(c.x,c.y);j.30&&2F[\'3L\'].B({P:D(c.w-1)})&&2F[\'3Q\'].B({R:D(c.h-1)});2E&&31(c);1R||1w();j.2D(2H(c))};7 1w(){$28.1w();$I.B(\'1z\',j.3x);1R=M};7 1r(){1o();$28.1v();$I.B(\'1z\',1);1R=K};7 1v(){1r();$I.B(\'1z\',1);1R=K};7 2t(){2E=M;31(E.Q());$2g.1w()};7 1o(){2E=K;$2g.1v()};7 2o(v){(3h=v)?1o():2t()};7 1h(){d c=E.Q();2o(K);3s()};1o();$2C.1P($(\'<12 />\').1f(1L(\'3v\')).3q(3b(\'1N\')).B({3p:\'1N\',16:\'1b\',1l:4M,1z:0}));k{2I:2I,1e:1e,1r:1r,1w:1w,1v:1v,2t:2t,1o:1o,2o:2o,1h:1h}}();d 1j=7(){d 2w=7(){},2v=7(){},2L=j.2x;g(!2L){$1S.3k(2B).2S(26).4N(26)}7 4j(){g(2L){$(3t).3k(2B).2S(26)}$1S.B({1l:4G})}7 4i(){g(2L){$(3t).3H(\'3k\',2B).3H(\'2S\',26)}$1S.B({1l:3R})}7 2B(e){2w(2r(e))};7 26(e){e.2j();e.2k();g(1q){1q=K;2v(2r(e));j.2G(2H(E.Q()));4i();2w=7(){};2v=7(){}}k K};7 1G(1N,1h){1q=M;2w=1N;2v=1h;4j();k K};7 1x(t){$1S.B(\'3p\',t)};$I.4s($1S);k{1G:1G,1x:1x}}();d 33=7(){d $24=$(\'<4w 1u="4L" />\').B({16:\'1b\',P:\'-4O\'}).57(43).56(2f).5a(41),$3S=$(\'<12 />\').B({16:\'1b\',4o:\'4g\'}).1P($24);7 2l(){g(j.2c){$24.1w();$24.4Z()}};7 41(e){$24.1v()};7 2f(e){g(!j.2f)k;d 42=1O,1C;1O=e.4Q?M:K;g(42!=1O){g(1O&&1q){1C=E.Q();1B=1C.w/1C.h}1g 1B=0;J.1e()}e.2k();e.2j();k K};7 29(e,x,y){E.2b([x,y]);J.2I();e.2j();e.2k()};7 43(e){g(e.4T)k M;2f(e);d 2h=1O?10:1;1E(e.5d){C 37:29(e,-2h,0);O;C 39:29(e,2h,0);O;C 38:29(e,0,-2h);O;C 40:29(e,0,2h);O;C 27:J.1r();O;C 9:k M}k K};g(j.2c)$3S.3U($I);k{2l:2l}}();7 D(n){k\'\'+1m(n)+\'D\'};7 1t(n){k\'\'+1m(n)+\'%\'};7 1L(44){k j.3W+\'-\'+44};7 2Q(G){d z=$(G).2y();k[z.P,z.R]};7 2r(e){k[(e.4q-2u[0]),(e.4r-2u[1])]};7 46(1u){g(1u!=3i){1j.1x(1u);3i=1u}};7 4a(19,z){2u=2Q(G);1j.1x(19==\'1N\'?19:19+\'-2A\');g(19==\'1N\')k 1j.1G(4e(z),2P);d 1C=E.Q();E.1A(E.2K(4b(19)));1j.1G(45(19,1C),2P)};7 45(19,f){k 7(z){g(!j.25&&!1B)1E(19){C\'e\':z[1]=f.m;O;C\'w\':z[1]=f.m;O;C\'n\':z[0]=f.q;O;C\'s\':z[0]=f.q;O}1g 1E(19){C\'e\':z[1]=f.y+1;O;C\'w\':z[1]=f.y+1;O;C\'n\':z[0]=f.x+1;O;C\'s\':z[0]=f.x+1;O}E.1y(z);J.1e()}};7 4e(z){d 2M=z;33.2l();k 7(z){E.2b([z[0]-2M[0],z[1]-2M[1]]);2M=z;J.1e()}};7 4b(T){1E(T){C\'n\':k\'1M\';C\'s\':k\'11\';C\'e\':k\'11\';C\'w\':k\'1s\';C\'1s\':k\'1M\';C\'11\':k\'2e\';C\'2e\':k\'11\';C\'1M\':k\'1s\'}};7 3b(T){k 7(e){1q=M;4a(T,2r(e));e.2k();e.2j();k K}};7 47($G,w,h){d 11=$G.W(),1H=$G.U();g((11>w)&&w>0){11=w;1H=(w/$G.W())*$G.U()}g((1H>h)&&h>0){1H=h;11=(h/$G.U())*$G.W()}1I=$G.W()/11;1Q=$G.U()/1H;$G.W(11).U(1H)};7 2H(c){k{x:1m(c.x*1I),y:1m(c.y*1Q),q:1m(c.q*1I),m:1m(c.m*1Q),w:1m(c.w*1I),h:1m(c.h*1Q)}};7 2P(z){d c=E.Q();g(c.w>j.3n[0]&&c.h>j.3n[1]){J.2t();J.1h()}1g{J.1r()}1j.1x(\'2X\')};7 48(e){1q=M;2u=2Q(G);J.1r();J.1o();46(\'2X\');E.1A(2r(e));1j.1G(4c,2P);33.2l();e.2k();e.2j();k K};7 4c(z){E.1y(z);J.1e()};7 2Z(a){d A=a[0],u=a[1],q=a[2],m=a[3];g(3h)k;d 2s=E.1F(A,u,q,m);d c=E.Q();d 18=2p=[c.x,c.y,c.q,c.m];d 3w=j.3V;d x=18[0];d y=18[1];d q=18[2];d m=18[3];d 3Z=2s[0]-2p[0];d 4m=2s[1]-2p[1];d 4n=2s[2]-2p[2];d 4l=2s[3]-2p[3];d 1c=0;d 4h=j.3X;J.2o(M);d 3u=7(){k 7(){1c+=(V-1c)/4h;18[0]=x+((1c/V)*3Z);18[1]=y+((1c/V)*4m);18[2]=q+((1c/V)*4n);18[3]=m+((1c/V)*4l);g(1c<V)32();1g J.1h();g(1c>=4K.8)1c=V;1d(18)}}();7 32(){4I.4t(3u,3w)};32()};7 1d(l){E.1A([l[0],l[1]]);E.1y([l[2],l[3]]);J.1e()};7 21(F){g(1p(F)!=\'2d\')F={};j=$.4X(j,F);g(1p(j.2D)!==\'7\')j.2D=7(){};g(1p(j.2G)!==\'7\')j.2G=7(){}};7 3m(){k 2H(E.Q())};7 2V(){k E.Q()};7 3E(F){21(F);g(\'1d\'1a F){1d(F.1d);J.1h()}};g(1p(F)!=\'2d\')F={};g(\'1d\'1a F){1d(F.1d);J.1h()}d 2q=j.2z[0]||0;d 2n=j.2z[1]||0;d 2m=j.2O[0]||0;d 2i=j.2O[1]||0;1j.1x(\'2X\');k{2Z:2Z,1d:1d,21:3E,3m:3m,2V:2V}};$.5e.1n=7(j){7 3G(1D){d 4d=j.4R||1D.2N;d I=4P 4S();d 1D=1D;I.50=7(){$(1D).1v().4A(I);1D.1n=$.1n(I,j)};I.2N=4d};g(1p(j)!==\'2d\')j={};1T.4J(7(){g(\'1n\'1a 1T){g(j==\'52\')k 1T.1n;1g 1T.1n.21(j)}1g 3G(1T)});k 1T};',62,325,'|||||||function||||||var|||if|||options|return||y2||||x2||||y1|||||pos|x1|css|case|px|Coords|opt|obj|handle|img|Selection|false|boundy|true|Math|break|left|getFixed|top|boundx|ord|height|100|width|delta|oy|ox||nw|div|yy||xx|position|abs|animat|mode|in|absolute|pcent|setSelect|update|addClass|else|done|hhs|Tracker|aspect|zIndex|parseInt|Jcrop|disableHandles|typeof|btndown|release|ne|pct|type|hide|show|setCursor|setCurrent|opacity|setPressed|aspectLock|fc|from|switch|flipCoords|activateHandlers|nh|xscale|jq|round|cssClass|sw|move|shift_down|append|yscale|awake|trk|this|xsize|rw|insertDragbar|south|insertBorder|rh||setOptions|ysize|bound|keymgr|aspectRatio|trackUp||sel|doNudge|east|moveOffset|keySupport|object|se|watchShift|hdl_holder|nudge|ymin|preventDefault|stopPropagation|watchKeys|xmin|ylimit|animMode|initcr|xlimit|mouseAbs|animto|enableHandles|docOffset|onDone|onMove|trackDocument|offset|maxSize|resize|trackMove|img_holder|onChange|seehandles|borders|onSelect|unscale|updateVisible|li|getCorner|trackDoc|lloc|src|minSize|doneSelect|getPos|xa|mouseup|rebound|hdep|tellScaled|dragDiv|crosshair|createHandles|animateTo|drawBorders|moveHandles|animateStart|KeyManager|img2|midhoriz|trueSize||||midvert|createDragger|rwa|browser|msie|getOffset|makeObj|animating|lastcurs|rha|mousemove|yb|tellSelect|minSelect|ya|cursor|mousedown|xb|refresh|document|animator|tracker|interv|bgOpacity|zi|vline|dragEdges|sideHandles|hline|handleOffset|setOptionsNew|getRect|attachWhenDone|unbind|cornerHandles|insertHandle|moveto|right|real_ratio|handleSize|borderOpacity|handleOpacity|bottom|290|keywrap|bgColor|insertBefore|animationDelay|baseClass|swingSpeed|attr|ix1||onBlur|init_shift|parseKey|cl|dragmodeHandler|myCursor|presize|newSelection|boxWidth|startDragMode|oppLockCorner|selectDrag|loadsrc|createMover|defaults|hidden|velocity|toBack|toFront|boundary|iy2|iy1|ix2|overflow|boxHeight|pageX|pageY|before|setTimeout|max|start|input|370|dragmode|end|after|backgroundColor|jcrop|null|last|holder|450|relative|window|each|99|radio|360|mouseout|30px|new|shiftKey|useImg|Image|ctrlKey|for|north|west|extend|black|focus|onload|edgeMargin|api|handlePad|wrap|300|keyup|keydown|dimmed|310|blur|320|min|keyCode|fn'.split('|'),0,{}))
index 7beae0ec6446577ba9dc10b04afefaa6b6264e6b..fe106cb8376a06b69ac5ba142329917b808a4427 100644 (file)
 
 if (!defined('LACONICA')) { exit(1); }
 
-class ShortUrlApi {
+class ShortUrlApi
+{
     protected $service_url;
 
-    function __construct($service_url) {
+    function __construct($service_url)
+    {
         $this->service_url = $service_url;
     }
 
-    function shorten($url) {
+    function shorten($url)
+    {
         if ($this->is_long($url)) return $this->shorten_imp($url);
         return $url;
     }
@@ -67,8 +70,10 @@ class ShortUrlApi {
     }
 }
 
-class LilUrl extends ShortUrlApi {
-    function __construct() {
+class LilUrl extends ShortUrlApi
+{
+    function __construct()
+    {
         parent::__construct('http://ur1.ca/');
     }
 
@@ -85,8 +90,10 @@ class LilUrl extends ShortUrlApi {
 }
 
 
-class PtitUrl extends ShortUrlApi {
-    function __construct() {
+class PtitUrl extends ShortUrlApi
+{
+    function __construct()
+    {
         parent::__construct('http://ptiturl.com/?creer=oui&action=Reduire&url=');
     }
 
@@ -102,8 +109,10 @@ class PtitUrl extends ShortUrlApi {
     }
 }
 
-class TightUrl extends ShortUrlApi {
-    function __construct() {
+class TightUrl extends ShortUrlApi
+{
+    function __construct()
+    {
         parent::__construct('http://2tu.us/?save=y&url=');
     }
 
index 7a2461bb5cf60640d2bc80d2e940f1eba1e44ff5..486b403878475c423d63711a755865ec12f4339e 100644 (file)
@@ -1,5 +1,5 @@
 <?php
-/*
+/**
  * Laconica - a distributed open-source microblogging tool
  * Copyright (C) 2008, Controlez-Vous, Inc.
  *
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 
-if (!defined('LACONICA')) { exit(1); }
-
-class Action { // lawsuit
-
-       var $args;
-
-       function Action() {
-       }
-
-       # For initializing members of the class
-
-       function prepare($argarray) {
-               $this->args =& common_copy_args($argarray);
-               return true;
-       }
-
-       # For comparison with If-Last-Modified
-       # If not applicable, return NULL
-
-       function last_modified() {
-               return NULL;
-       }
-
-       function etag() {
-               return NULL;
-       }
-
-       function is_readonly() {
-               return false;
-       }
-
-       function arg($key, $def=NULL) {
-               if (array_key_exists($key, $this->args)) {
-                       return $this->args[$key];
-               } else {
-                       return $def;
-               }
-       }
-
-       function trimmed($key, $def=NULL) {
-               $arg = $this->arg($key, $def);
-               return (is_string($arg)) ? trim($arg) : $arg;
-       }
-
-       # Note: argarray ignored, since it's now passed in in prepare()
-
-       function handle($argarray=NULL) {
-
-               $lm = $this->last_modified();
-               $etag = $this->etag();
-
-               if ($etag) {
-                       header('ETag: ' . $etag);
-               }
-
-               if ($lm) {
-                       header('Last-Modified: ' . date(DATE_RFC1123, $lm));
-                       $if_modified_since = $_SERVER['HTTP_IF_MODIFIED_SINCE'];
-                       if ($if_modified_since) {
-                               $ims = strtotime($if_modified_since);
-                               if ($lm <= $ims) {
-                                       if (!$etag || $this->_has_etag($etag, $_SERVER['HTTP_IF_NONE_MATCH'])) {
-                                               header('HTTP/1.1 304 Not Modified');
-                                               # Better way to do this?
-                                               exit(0);
-                                       }
-                               }
-                       }
-               }
-       }
-
-       function _has_etag($etag, $if_none_match) {
-               return ($if_none_match) && in_array($etag, explode(',', $if_none_match));
-       }
-
-       function boolean($key, $def=false) {
-               $arg = strtolower($this->trimmed($key));
-
-               if (is_null($arg)) {
-                       return $def;
-               } else if (in_array($arg, array('true', 'yes', '1'))) {
-                       return true;
-               } else if (in_array($arg, array('false', 'no', '0'))) {
-                       return false;
-               } else {
-                       return $def;
-               }
-       }
-
-       function server_error($msg, $code=500) {
-               $action = $this->trimmed('action');
-               common_debug("Server error '$code' on '$action': $msg", __FILE__);
-               common_server_error($msg, $code);
-       }
-
-       function client_error($msg, $code=400) {
-               $action = $this->trimmed('action');
-               common_debug("User error '$code' on '$action': $msg", __FILE__);
-               common_user_error($msg, $code);
-       }
-
-       function self_url() {
-               $action = $this->trimmed('action');
-               $args = $this->args;
-               unset($args['action']);
-               foreach (array_keys($_COOKIE) as $cookie) {
-                       unset($args[$cookie]);
-               }
-               return common_local_url($action, $args);
-       }
-
-       function nav_menu($menu) {
+if (!defined('LACONICA')) {
+    exit(1);
+}
+
+class Action // lawsuit
+{
+
+    var $args;
+
+    function Action()
+    {
+    }
+
+    // For initializing members of the class
+
+    function prepare($argarray)
+    {
+        $this->args =& common_copy_args($argarray);
+        return true;
+    }
+
+    // For comparison with If-Last-Modified
+    // If not applicable, return null
+
+    function last_modified()
+    {
+        return null;
+    }
+
+    function etag()
+    {
+        return null;
+    }
+
+    function is_readonly()
+    {
+        return false;
+    }
+
+    function arg($key, $def=null)
+    {
+        if (array_key_exists($key, $this->args)) {
+            return $this->args[$key];
+        } else {
+            return $def;
+        }
+    }
+
+    function trimmed($key, $def=null)
+    {
+        $arg = $this->arg($key, $def);
+        return (is_string($arg)) ? trim($arg) : $arg;
+    }
+
+    // Note: argarray ignored, since it's now passed in in prepare()
+
+    function handle($argarray=null)
+    {
+
+        $lm = $this->last_modified();
+        $etag = $this->etag();
+
+        if ($etag) {
+            header('ETag: ' . $etag);
+        }
+
+        if ($lm) {
+            header('Last-Modified: ' . date(DATE_RFC1123, $lm));
+            $if_modified_since = $_SERVER['HTTP_IF_MODIFIED_SINCE'];
+            if ($if_modified_since) {
+                $ims = strtotime($if_modified_since);
+                if ($lm <= $ims) {
+                    if (!$etag ||
+                        $this->_has_etag($etag, $_SERVER['HTTP_IF_NONE_MATCH'])) {
+                        header('HTTP/1.1 304 Not Modified');
+                        // Better way to do this?
+                        exit(0);
+                    }
+                }
+            }
+        }
+    }
+
+    function _has_etag($etag, $if_none_match)
+    {
+        return ($if_none_match) && in_array($etag, explode(',', $if_none_match));
+    }
+
+    function boolean($key, $def=false)
+    {
+        $arg = strtolower($this->trimmed($key));
+
+        if (is_null($arg)) {
+            return $def;
+        } else if (in_array($arg, array('true', 'yes', '1'))) {
+            return true;
+        } else if (in_array($arg, array('false', 'no', '0'))) {
+            return false;
+        } else {
+            return $def;
+        }
+    }
+
+    function server_error($msg, $code=500)
+    {
+        $action = $this->trimmed('action');
+        common_debug("Server error '$code' on '$action': $msg", __FILE__);
+        common_server_error($msg, $code);
+    }
+
+    function client_error($msg, $code=400)
+    {
+        $action = $this->trimmed('action');
+        common_debug("User error '$code' on '$action': $msg", __FILE__);
+        common_user_error($msg, $code);
+    }
+
+    function self_url()
+    {
+        $action = $this->trimmed('action');
+        $args = $this->args;
+        unset($args['action']);
+        foreach (array_keys($_COOKIE) as $cookie) {
+            unset($args[$cookie]);
+        }
+        return common_local_url($action, $args);
+    }
+
+    function nav_menu($menu)
+    {
         $action = $this->trimmed('action');
         common_element_start('ul', array('id' => 'nav_views'));
         foreach ($menu as $menuaction => $menudesc) {
-            common_menu_item(common_local_url($menuaction, isset($menudesc[2]) ? $menudesc[2] : NULL),
-                                                        $menudesc[0],
-                                                        $menudesc[1],
-                                                        $action == $menuaction);
+            common_menu_item(common_local_url($menuaction,
+                                              isset($menudesc[2]) ? $menudesc[2] : null),
+                             $menudesc[0],
+                             $menudesc[1],
+                             $action == $menuaction);
         }
         common_element_end('ul');
-       }
+    }
 }
index 5a28c309133a54648024a246b85cb2689b65f9ea..74c992f1c9af7c6fd0f080dba98b9d090a0a24bf 100644 (file)
@@ -54,100 +54,100 @@ require_once(INSTALLDIR.'/lib/language.php');
 
 $config =
   array('site' =>
-               array('name' => 'Just another Laconica microblog',
-                         'server' => 'localhost',
-                         'theme' => 'default',
-                         'path' => '/',
-                         'logfile' => NULL,
-                         'fancy' => false,
-                         'locale_path' => INSTALLDIR.'/locale',
-                         'language' => 'en_US',
-                         'languages' => get_all_languages(),
-                     'email' =>
-                     array_key_exists('SERVER_ADMIN', $_SERVER) ? $_SERVER['SERVER_ADMIN'] : NULL,
-                         'broughtby' => NULL,
-                         'timezone' => 'UTC',
-                         'broughtbyurl' => NULL,
-                         'closed' => false,
-                         'inviteonly' => false,
+        array('name' => 'Just another Laconica microblog',
+              'server' => 'localhost',
+              'theme' => 'default',
+              'path' => '/',
+              'logfile' => null,
+              'fancy' => false,
+              'locale_path' => INSTALLDIR.'/locale',
+              'language' => 'en_US',
+              'languages' => get_all_languages(),
+              'email' =>
+              array_key_exists('SERVER_ADMIN', $_SERVER) ? $_SERVER['SERVER_ADMIN'] : null,
+              'broughtby' => null,
+              'timezone' => 'UTC',
+              'broughtbyurl' => null,
+              'closed' => false,
+              'inviteonly' => false,
               'private' => false),
-               'syslog' =>
-               array('appname' => 'laconica', # for syslog
-                         'priority' => 'debug'), # XXX: currently ignored
-               'queue' =>
-               array('enabled' => false),
-               'license' =>
-               array('url' => 'http://creativecommons.org/licenses/by/3.0/',
-                         'title' => 'Creative Commons Attribution 3.0',
-                         'image' => 'http://i.creativecommons.org/l/by/3.0/88x31.png'),
-               'mail' =>
-               array('backend' => 'mail',
-                         'params' => NULL),
-               'nickname' =>
-               array('blacklist' => array(),
-                         'featured' => array()),
-               'profile' =>
-               array('banned' => array()),
-               'avatar' =>
-               array('server' => NULL),
-               'public' =>
-               array('localonly' => true,
-                         'blacklist' => array()),
-               'theme' =>
-               array('server' => NULL),
-               'throttle' =>
+        'syslog' =>
+        array('appname' => 'laconica', # for syslog
+              'priority' => 'debug'), # XXX: currently ignored
+        'queue' =>
+        array('enabled' => false),
+        'license' =>
+        array('url' => 'http://creativecommons.org/licenses/by/3.0/',
+              'title' => 'Creative Commons Attribution 3.0',
+              'image' => 'http://i.creativecommons.org/l/by/3.0/88x31.png'),
+        'mail' =>
+        array('backend' => 'mail',
+              'params' => null),
+        'nickname' =>
+        array('blacklist' => array(),
+              'featured' => array()),
+        'profile' =>
+        array('banned' => array()),
+        'avatar' =>
+        array('server' => null),
+        'public' =>
+        array('localonly' => true,
+              'blacklist' => array()),
+        'theme' =>
+        array('server' => null),
+        'throttle' =>
         array('enabled' => false, // whether to throttle edits; false by default
               'count' => 20, // number of allowed messages in timespan
               'timespan' => 600), // timespan for throttling
-               'xmpp' =>
-               array('enabled' => false,
-                         'server' => 'INVALID SERVER',
-                         'port' => 5222,
-                         'user' => 'update',
-                         'encryption' => true,
-                         'resource' => 'uniquename',
-                         'password' => 'blahblahblah',
-                         'host' => NULL, # only set if != server
-                         'debug' => false, # print extra debug info
-                         'public' => array()), # JIDs of users who want to receive the public stream
+        'xmpp' =>
+        array('enabled' => false,
+              'server' => 'INVALID SERVER',
+              'port' => 5222,
+              'user' => 'update',
+              'encryption' => true,
+              'resource' => 'uniquename',
+              'password' => 'blahblahblah',
+              'host' => null, # only set if != server
+              'debug' => false, # print extra debug info
+              'public' => array()), # JIDs of users who want to receive the public stream
         'sphinx' =>
         array('enabled' => false,
               'server' => 'localhost',
               'port' => 3312),
-               'tag' =>
-               array('dropoff' => 864000.0),
-               'popular' =>
-               array('dropoff' => 864000.0),
-               'daemon' =>
-               array('piddir' => '/var/run',
-                         'user' => false,
-                         'group' => false),
-               'integration' =>
-               array('source' => 'Laconica'), # source attribute for Twitter
-               'memcached' =>
-               array('enabled' => false,
-                         'server' => 'localhost',
-                         'port' => 11211),
-               'inboxes' =>
-               array('enabled' => true), # on by default for new sites
-               );
+        'tag' =>
+        array('dropoff' => 864000.0),
+        'popular' =>
+        array('dropoff' => 864000.0),
+        'daemon' =>
+        array('piddir' => '/var/run',
+              'user' => false,
+              'group' => false),
+        'integration' =>
+        array('source' => 'Laconica'), # source attribute for Twitter
+        'memcached' =>
+        array('enabled' => false,
+              'server' => 'localhost',
+              'port' => 11211),
+        'inboxes' =>
+        array('enabled' => true), # on by default for new sites
+        );
 
 $config['db'] = &PEAR::getStaticProperty('DB_DataObject','options');
 
 $config['db'] =
   array('database' => 'YOU HAVE TO SET THIS IN config.php',
-           'schema_location' => INSTALLDIR . '/classes',
-               'class_location' => INSTALLDIR . '/classes',
-               'require_prefix' => 'classes/',
-               'class_prefix' => '',
-               'mirror' => NULL,
+        'schema_location' => INSTALLDIR . '/classes',
+        'class_location' => INSTALLDIR . '/classes',
+        'require_prefix' => 'classes/',
+        'class_prefix' => '',
+        'mirror' => null,
         'db_driver' => 'DB', # XXX: JanRain libs only work with DB
-               'quote_identifiers' => false,
-               'type' => 'mysql' );
+        'quote_identifiers' => false,
+        'type' => 'mysql' );
 
 if (function_exists('date_default_timezone_set')) {
-       /* Work internally in UTC */
-       date_default_timezone_set('UTC');
+    /* Work internally in UTC */
+    date_default_timezone_set('UTC');
 }
 
 require_once(INSTALLDIR.'/config.php');
@@ -163,10 +163,11 @@ require_once(INSTALLDIR.'/lib/subs.php');
 require_once(INSTALLDIR.'/lib/Shorturl_api.php');
 require_once(INSTALLDIR.'/lib/twitter.php');
 
-function __autoload($class) {
-       if ($class == 'OAuthRequest') {
-               require_once('OAuth.php');
-       } else if (file_exists(INSTALLDIR.'/classes/' . $class . '.php')) {
+function __autoload($class)
+{
+    if ($class == 'OAuthRequest') {
+        require_once('OAuth.php');
+    } else if (file_exists(INSTALLDIR.'/classes/' . $class . '.php')) {
         require_once(INSTALLDIR.'/classes/' . $class . '.php');
     }
 }
index 359a4343b5efc2a7a2e7f0557715b53dc1fecbcb..9c1ae50a02c56e5be81534f905d352fd287e6944 100644 (file)
@@ -1,5 +1,5 @@
 <?php
-/*
+/**
  * Laconica - a distributed open-source microblogging tool
  * Copyright (C) 2008, Controlez-Vous, Inc.
  *
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 
-if (!defined('LACONICA')) { exit(1); }
-
-class Daemon {
-
-       function name() {
-               return NULL;
-       }
-       
-       function background() {
-               $pid = pcntl_fork();
-               if ($pid < 0) { # error
-                       common_log(LOG_ERR, "Could not fork.");
-                       return false;
-               } else if ($pid > 0) { # parent
-                       common_log(LOG_INFO, "Successfully forked.");
-                       exit(0);
-               } else { # child
-                       return true;
-               }
-       }
-
-       function alreadyRunning() {
-
-               $pidfilename = $this->pidFilename();
-
-               if (!$pidfilename) {
-                       return false;
-               }
-               
-               if (!file_exists($pidfilename)) {
-                       return false;
-               }
-               $contents = file_get_contents($pidfilename);
-               if (posix_kill(trim($contents),0)) {
-                       return true;
-               } else {
-                       return false;
-               }
-       }
-       
-       function writePidFile() {
-               $pidfilename = $this->pidFilename();
-               
-               if (!$pidfilename) {
-                       return false;
-               }
-               
-           return file_put_contents($pidfilename, posix_getpid() . "\n");
-       }
-
-       function clearPidFile() {
-               $pidfilename = $this->pidFilename();
-               if (!$pidfilename) {
-                   return false;
-               }
-               return unlink($pidfilename);
-       }
-       
-       function pidFilename() {
-               $piddir = common_config('daemon', 'piddir');
-               if (!$piddir) {
-                       return NULL;
-               }
-               $name = $this->name();
-               if (!$name) {
-                       return NULL;
-               }
-               return $piddir . '/' . $name . '.pid';
-       }
-
-       function changeUser() {
-
-               $username = common_config('daemon', 'user');
-               
-               if ($username) {
-                       $user_info = posix_getpwnam($username);
-                       if (!$user_info) {
-                               common_log(LOG_WARNING, 'Ignoring unknown user for daemon: ' . $username);
-                       } else {
-                               common_log(LOG_INFO, "Setting user to " . $username);
-                               posix_setuid($user_info['uid']);
-                       }
-               }
-
-               $groupname = common_config('daemon', 'group');
-               
-               if ($groupname) {
-                       $group_info = posix_getgrnam($groupname);
-                       if (!$group_info) {
-                               common_log(LOG_WARNING, 'Ignoring unknown group for daemon: ' . $groupname);
-                       } else {
-                               common_log(LOG_INFO, "Setting group to " . $groupname);
-                               posix_setgid($group_info['gid']);
-                       }
-               }
-       }
-       
-       function runOnce() {
-               if ($this->alreadyRunning()) {
-                       common_log(LOG_INFO, $this->name() . ' already running. Exiting.');
-                       exit(0);
-               }
-               if ($this->background()) {
-                       $this->writePidFile();
-                       $this->changeUser();
-                       $this->run();
-                       $this->clearPidFile();
-               }
-       }
-       
-       function run() {
-               return true;
-       }
+if (!defined('LACONICA')) {
+    exit(1);
+}
+
+class Daemon
+{
+    function name()
+    {
+        return null;
+    }
+
+    function background()
+    {
+        $pid = pcntl_fork();
+        if ($pid < 0) { // error
+            common_log(LOG_ERR, "Could not fork.");
+            return false;
+        } else if ($pid > 0) { // parent
+            common_log(LOG_INFO, "Successfully forked.");
+            exit(0);
+        } else { // child
+            return true;
+        }
+    }
+
+    function alreadyRunning()
+    {
+        $pidfilename = $this->pidFilename();
+
+        if (!$pidfilename) {
+            return false;
+        }
+
+        if (!file_exists($pidfilename)) {
+            return false;
+        }
+        $contents = file_get_contents($pidfilename);
+        if (posix_kill(trim($contents), 0)) {
+            return true;
+        } else {
+            return false;
+        }
+    }
+
+    function writePidFile()
+    {
+        $pidfilename = $this->pidFilename();
+
+        if (!$pidfilename) {
+            return false;
+        }
+
+        return file_put_contents($pidfilename, posix_getpid() . "\n");
+    }
+
+    function clearPidFile()
+    {
+        $pidfilename = $this->pidFilename();
+        if (!$pidfilename) {
+            return false;
+        }
+        return unlink($pidfilename);
+    }
+
+    function pidFilename()
+    {
+        $piddir = common_config('daemon', 'piddir');
+        if (!$piddir) {
+            return null;
+        }
+        $name = $this->name();
+        if (!$name) {
+            return null;
+        }
+        return $piddir . '/' . $name . '.pid';
+    }
+
+    function changeUser()
+    {
+        $username = common_config('daemon', 'user');
+
+        if ($username) {
+            $user_info = posix_getpwnam($username);
+            if (!$user_info) {
+                common_log(LOG_WARNING,
+                           'Ignoring unknown user for daemon: ' . $username);
+            } else {
+                common_log(LOG_INFO, "Setting user to " . $username);
+                posix_setuid($user_info['uid']);
+            }
+        }
+
+        $groupname = common_config('daemon', 'group');
+
+        if ($groupname) {
+            $group_info = posix_getgrnam($groupname);
+            if (!$group_info) {
+                common_log(LOG_WARNING,
+                           'Ignoring unknown group for daemon: ' . $groupname);
+            } else {
+                common_log(LOG_INFO, "Setting group to " . $groupname);
+                posix_setgid($group_info['gid']);
+            }
+        }
+    }
+
+    function runOnce()
+    {
+        if ($this->alreadyRunning()) {
+            common_log(LOG_INFO, $this->name() . ' already running. Exiting.');
+            exit(0);
+        }
+        if ($this->background()) {
+            $this->writePidFile();
+            $this->changeUser();
+            $this->run();
+            $this->clearPidFile();
+        }
+    }
+
+    function run()
+    {
+        return true;
+    }
 }
index 5ba0e7e44283d3705dac1dddae4e73df69a1fcfc..9e89c0a549c989de2f4ddbbb46c15c58072b8523 100644 (file)
 
 if (!defined('LACONICA')) { exit(1); }
 
-class DeleteAction extends Action {
-
-       function handle($args) {
-               parent::handle($args);
-               $user = common_current_user();
-               $notice_id = $this->trimmed('notice');
-               $notice = Notice::staticGet($notice_id);
-               if (!$notice) {
-                       common_user_error(_('No such notice.'));
-                       exit;
-               }
-
-               $profile = $notice->getProfile();
-               $user_profile = $user->getProfile();
-
-               if (!common_logged_in()) {
-                       common_user_error(_('Not logged in.'));
-                       exit;
-               } else if ($notice->profile_id != $user_profile->id) {
-                       common_user_error(_('Can\'t delete this notice.'));
-                       exit;
-               }
-       }
-
-       function show_top($arr=NULL) {
-               $instr = $this->get_instructions();
-               $output = common_markup_to_html($instr);
-               common_element_start('div', 'instructions');
-               common_raw($output);
-               common_element_end('div');
-       }
-
-       function get_title() {
-               return NULL;
-       }
-
-       function show_header() {
-               return;
-       }
+class DeleteAction extends Action
+{
+
+    function handle($args)
+    {
+        parent::handle($args);
+        $user = common_current_user();
+        $notice_id = $this->trimmed('notice');
+        $notice = Notice::staticGet($notice_id);
+        if (!$notice) {
+            common_user_error(_('No such notice.'));
+            exit;
+        }
+
+        $profile = $notice->getProfile();
+        $user_profile = $user->getProfile();
+
+        if (!common_logged_in()) {
+            common_user_error(_('Not logged in.'));
+            exit;
+        } else if ($notice->profile_id != $user_profile->id) {
+            common_user_error(_('Can\'t delete this notice.'));
+            exit;
+        }
+    }
+
+    function show_top($arr=null)
+    {
+        $instr = $this->get_instructions();
+        $output = common_markup_to_html($instr);
+        common_element_start('div', 'instructions');
+        common_raw($output);
+        common_element_end('div');
+    }
+
+    function get_title()
+    {
+        return null;
+    }
+
+    function show_header()
+    {
+        return;
+    }
 }
index 87a82ba01e59e9dba31db4dbcb6625a69bd5c548..9230bad59368c025d09ab1f0f99579dfca11819c 100644 (file)
  *
  * 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
+ * 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/>.
+ * along with this program.     If not, see <http://www.gnu.org/licenses/>.
  */
 
 if (!defined('LACONICA')) { exit(1); }
 
-require_once(INSTALLDIR.'/extlib/facebook/facebook.php');
-
-class FacebookAction extends Action {
-
-       function handle($args) {
-               parent::handle($args);
-       }
-
-       function get_facebook() {
-               $apikey = common_config('facebook', 'apikey');
-               $secret = common_config('facebook', 'secret');
-               return new Facebook($apikey, $secret);
-       }
-
-       function update_profile_box($facebook, $fbuid, $user) {
-
-               $notice = $user->getCurrentNotice();
-
-               # Need to include inline CSS for styling the Profile box
-
-               $style = '<style>
-               #notices {
-               clear: both;
-               margin: 0 auto;
-               padding: 0;
-               list-style-type: none;
-               width: 600px;
-               border-top: 1px solid #dec5b5;
-               }
-               #notices a:hover {
-               text-decoration: underline;
-               }
-               .notice_single {
-               clear: both;
-               display: block;
-               margin: 0;
-               padding: 5px 5px 5px 0;
-               min-height: 48px;
-               font-family: Georgia, "Times New Roman", Times, serif;
-               font-size: 13px;
-               line-height: 16px;
-               border-bottom: 1px solid #dec5b5;
-               background-color:#FCFFF5;
-               opacity:1;
-               }
-               .notice_single:hover {
-               background-color: #f7ebcc;
-               }
-               .notice_single p {
-               display: inline;
-               margin: 0;
-               padding: 0;
-               }
-               </style>';
-
-               $html = $this->render_notice($notice);
-
-               $fbml = "<fb:wide>$content $html</fb:wide>";
-               $fbml .= "<fb:narrow>$content $html</fb:narrow>";
-
-               $fbml_main = "<fb:narrow>$content $html</fb:narrow>";
-
-               $facebook->api_client->profile_setFBML(NULL, $fbuid, $fbml, NULL, NULL, $fbml_main);
-       }
-
-       # Display methods
-
-       function show_header($selected ='Home') {
-
-               # Add a timestamp to the CSS file so Facebook cache wont ignore our changes
-               $ts = filemtime(theme_file('facebookapp.css'));
-               $cssurl = theme_path('facebookapp.css') . "?ts=$ts";
-
-               $header = '<link rel="stylesheet" type="text/css" href="'. $cssurl . '" />';
-               # $header .='<script src="" ></script>';
-               $header .= '<fb:dashboard/>';
-
-               $header .=
-                       '<fb:tabs>'
-                       .'<fb:tab-item title="Home" href="index.php" selected="' . ($selected == 'Home') .'" />'
-                       .'<fb:tab-item title="Invite Friends"  href="invite.php" selected="' . ($selected == 'Invite') . '" />'
-                       .'<fb:tab-item title="Settings"  href="settings.php" selected="' . ($selected == 'Settings') . '" />'
-                       .'</fb:tabs>';
-               $header .= '<div id="main_body">';
-
-         echo $header;
-
-       }
-
-       function show_footer() {
-         $footer = '</div>';
-         echo $footer;
-       }
-
-       function show_login_form() {
-
-               $loginform =
-                       ' <h2>To add the Identi.ca application, you need to log into your Identi.ca account.</h2>'
-                       .'<a href="http://identi.ca/">'
-                       .'      <img src="http://theme.identi.ca/identica/logo.png" alt="Identi.ca" id="logo"/>'
-                       .'</a>'
-                       .'<h1 class="pagetitle">Login</h1>'
-                       .'<div class="instructions">'
-                       .'      <p>Login with your username and password. Don\'t have a username yet?'
-                       .'        <a href="http://identi.ca/main/register">Register</a> a new account.'
-                       .'      </p>'
-                       .'</div>'
-                       .'<div id="content">'
-                       .'      <form method="post" id="login">'
-                       .'        <p>'
-                       .'              <label for="nickname">Nickname</label>'
-                       .'              <input name="nickname" type="text" class="input_text" id="nickname"/>'
-                       .'        </p>'
-                       .'        <p>'
-                       .'                <label for="password">Password</label>'
-                       .'              <input name="password" type="password" class="password" id="password"/>'
-                       .'        </p>'
-                       .'        <p>'
-                       .'              <input type="submit" id="submit" name="submit" class="submit" value="Login"/>'
-                       .'        </p>'
-                       .'      </form>'
-                       .'      <p>'
-                       .'        <a href="http://identi.ca/main/recoverpassword">Lost or forgotten password?</a>'
-                       .'      </p>'
-                       .'</div';
-
-                       echo $loginform;
-       }
-
-       function render_notice($notice) {
-
-               global $config;
-
-               $profile = $notice->getProfile();
-               $avatar = $profile->getAvatar(AVATAR_STREAM_SIZE);
-
-               $noticeurl = common_local_url('shownotice', array('notice' => $notice->id));
-
-               # XXX: we need to figure this out better. Is this right?
-               if (strcmp($notice->uri, $noticeurl) != 0 && preg_match('/^http/', $notice->uri)) {
-                       $noticeurl = $notice->uri;
-               }
-
-               $html =
-               '<li class="notice_single" id="' . $notice->id . '">'
-               .'<a href="' . $profile->profileurl . '">'
-               .'<img src="';
-
-               if ($avatar) {
-                       $html .= common_avatar_display_url($avatar);
-               } else {
-                       $html .= common_default_avatar(AVATAR_STREAM_SIZE);
-               }
-
-               $html .=
-               '" class="avatar stream" width="'
-               . AVATAR_STREAM_SIZE . '" height="' . AVATAR_STREAM_SIZE .'"'
-               .' alt="';
-
-               if ($profile->fullname) {
-                       $html .= $profile->fullname;
-               } else {
-                       $html .= $profile->nickname;
-               }
-
-               $html .=
-               '"></a>'
-               .'<a href="' .  $profile->profileurl . '" class="nickname">' . $profile->nickname . '</a>'
-               .'<p class="content">' . $notice->rendered . '</p>'
-               .'<p class="time">'
-               .'<a class="permalink" href="' . $noticeurl . '" title="' . common_exact_date($notice->created) . '">' . common_date_string($notice->created) . '</a>';
-
-               if ($notice->source) {
-                       $html .= _(' from ');
-                       $html .= $this->source_link($notice->source);
-               }
-
-               if ($notice->reply_to) {
-                       $replyurl = common_local_url('shownotice', array('notice' => $notice->reply_to));
-                       $html .=
-                       ' (<a class="inreplyto" href="' . $replyurl . '">' . _('in reply to...') . ')';
-               }
-
-               $html .= '</p></li>';
-
-               return $html;
-       }
-
-       function source_link($source) {
-               $source_name = _($source);
-
-               $html = '<span class="noticesource">';
-
-               switch ($source) {
-                case 'web':
-                case 'xmpp':
-                case 'mail':
-                case 'omb':
-                case 'api':
-                       $html .= $source_name;
-                       break;
-                default:
-                       $ns = Notice_source::staticGet($source);
-                       if ($ns) {
-                               $html .= '<a href="' . $ns->url . '">' . $ns->name . '</a>';
-                       } else {
-                               $html .= $source_name;
-                       }
-                       break;
-               }
-
-               $html .= '</span>';
-
-               return $html;
-       }
-
-       function pagination($have_before, $have_after, $page, $fbaction, $args=NULL) {
-
-               $html = '';
-
-               if ($have_before || $have_after) {
-                       $html = '<div id="pagination">';
-                       $html .'<ul id="nav_pagination">';
-               }
-
-               if ($have_before) {
-                       $pargs = array('page' => $page-1);
-                       $newargs = ($args) ? array_merge($args,$pargs) : $pargs;
-                       $html .= '<li class="before">';
-                       $html .'<a href="' . $this->pagination_url($fbaction, $newargs) . '">' . _('« After') . '</a>';
-                       $html .'</li>';
-               }
-
-               if ($have_after) {
-                       $pargs = array('page' => $page+1);
-                       $newargs = ($args) ? array_merge($args,$pargs) : $pargs;
-                       $html .= '<li class="after">';
-                       $html .'<a href="' . $this->pagination_url($fbaction, $newargs) . '">' . _('Before Â»') . '</a>';
-                       $html .'</li>';
-               }
-
-               if ($have_before || $have_after) {
-                       $html .= '<ul>';
-                       $html .'<div>';
-               }
-       }
-
-       function pagination_url($fbaction, $args=NULL) {
-               global $config;
-
-               $extra = '';
-
-               if ($args) {
-                       foreach ($args as $key => $value) {
-                               $extra .= "&${key}=${value}";
-                       }
-               }
-
-               return "$fbaction?${extra}";
-       }
+require_once(INSTALLDIR.'/lib/facebookutil.php');
+
+
+class FacebookAction extends Action
+{
+
+    function handle($args)
+    {
+        parent::handle($args);
+    }
+
+    function update_profile_box($facebook, $fbuid, $user)
+    {
+
+        $notice = $user->getCurrentNotice();
+
+        # Need to include inline CSS for styling the Profile box
+
+         $style = '<style>
+         #notices {
+         clear: both;
+         margin: 0 auto;
+         padding: 0;
+         list-style-type: none;
+         width: 600px;
+         border-top: 1px solid #dec5b5;
+         }
+         #notices a:hover {
+         text-decoration: underline;
+         }
+         .notice_single {
+         clear: both;
+         display: block;
+         margin: 0;
+         padding: 5px 5px 5px 0;
+         min-height: 48px;
+         font-family: Georgia, "Times New Roman", Times, serif;
+         font-size: 13px;
+         line-height: 16px;
+         border-bottom: 1px solid #dec5b5;
+         background-color:#FCFFF5;
+         opacity:1;
+         }
+         .notice_single:hover {
+         background-color: #f7ebcc;
+         }
+         .notice_single p {
+         display: inline;
+         margin: 0;
+         padding: 0;
+         }
+         </style>';
+
+        $html = Facebookaction::render_notice($notice);
+
+        $fbml = "<fb:wide>$style $html</fb:wide>";
+        $fbml .= "<fb:narrow>$style $html</fb:narrow>";
+
+        $fbml_main = "<fb:narrow>$style $html</fb:narrow>";
+
+        $facebook->api_client->profile_setFBML(null, $fbuid, $fbml, null, null, $fbml_main);
+    }
+
+    # Display methods
+
+    function show_header($selected ='Home')
+    {
+
+        # Add a timestamp to the CSS file so Facebook cache wont ignore our changes
+        $ts = filemtime(theme_file('facebookapp.css'));
+        $cssurl = theme_path('facebookapp.css') . "?ts=$ts";
+
+         $header = '<link rel="stylesheet" type="text/css" href="'. $cssurl . '" />';
+         # $header .='<script src="" ></script>';
+          $header .= '<fb:dashboard/>';
+
+          $header .=
+            '<fb:tabs>'
+            .'<fb:tab-item title="Home" href="index.php" selected="' . ($selected == 'Home') .'" />'
+            .'<fb:tab-item title="Invite Friends"  href="invite.php" selected="' . ($selected == 'Invite') . '" />'
+            .'<fb:tab-item title="Settings"     href="settings.php" selected="' . ($selected == 'Settings') . '" />'
+            .'</fb:tabs>';
+          $header .= '<div id="main_body">';
+
+      echo $header;
+
+    }
+
+    function show_footer()
+    {
+      $footer = '</div>';
+      echo $footer;
+    }
+
+    function show_login_form()
+    {
+
+        $loginform =
+            ' <h2>To add the Identi.ca application, you need to log into your Identi.ca account.</h2>'
+            .'<a href="http://identi.ca/">'
+            .'    <img src="http://theme.identi.ca/identica/logo.png" alt="Identi.ca" id="logo"/>'
+            .'</a>'
+            .'<h1 class="pagetitle">Login</h1>'
+            .'<div class="instructions">'
+            .'    <p>Login with your username and password. Don\'t have a username yet?'
+            .'      <a href="http://identi.ca/main/register">Register</a> a new account.'
+            .'    </p>'
+            .'</div>'
+            .'<div id="content">'
+            .'    <form method="post" id="login">'
+            .'      <p>'
+            .'        <label for="nickname">Nickname</label>'
+            .'        <input name="nickname" type="text" class="input_text" id="nickname"/>'
+            .'      </p>'
+            .'      <p>'
+            .'          <label for="password">Password</label>'
+            .'        <input name="password" type="password" class="password" id="password"/>'
+            .'      </p>'
+            .'      <p>'
+            .'        <input type="submit" id="submit" name="submit" class="submit" value="Login"/>'
+            .'      </p>'
+            .'    </form>'
+            .'    <p>'
+            .'      <a href="http://identi.ca/main/recoverpassword">Lost or forgotten password?</a>'
+            .'    </p>'
+            .'</div';
+
+            echo $loginform;
+    }
+
+    function render_notice($notice)
+    {
+
+        global $config;
+
+        $profile = $notice->getProfile();
+        $avatar = $profile->getAvatar(AVATAR_STREAM_SIZE);
+
+        $noticeurl = common_local_url('shownotice', array('notice' => $notice->id));
+
+        # XXX: we need to figure this out better. Is this right?
+        if (strcmp($notice->uri, $noticeurl) != 0 && preg_match('/^http/', $notice->uri)) {
+            $noticeurl = $notice->uri;
+        }
+
+        $html =
+        '<li class="notice_single" id="' . $notice->id . '">'
+        .'<a href="' . $profile->profileurl . '">'
+        .'<img src="';
+
+        if ($avatar) {
+            $html .= common_avatar_display_url($avatar);
+        } else {
+            $html .= common_default_avatar(AVATAR_STREAM_SIZE);
+        }
+
+        $html .=
+        '" class="avatar stream" width="'
+        . AVATAR_STREAM_SIZE . '" height="' . AVATAR_STREAM_SIZE .'"'
+        .' alt="';
+
+        if ($profile->fullname) {
+            $html .= $profile->fullname;
+        } else {
+            $html .= $profile->nickname;
+        }
+
+        $html .=
+        '"></a>'
+        .'<a href="' .    $profile->profileurl . '" class="nickname">' . $profile->nickname . '</a>'
+        .'<p class="content">' . $notice->rendered . '</p>'
+        .'<p class="time">'
+        .'<a class="permalink" href="' . $noticeurl . '" title="' . common_exact_date($notice->created) . '">' . common_date_string($notice->created) . '</a>';
+
+        if ($notice->source) {
+            $html .= _(' from ');
+            $html .= $this->source_link($notice->source);
+        }
+
+        if ($notice->reply_to) {
+            $replyurl = common_local_url('shownotice', array('notice' => $notice->reply_to));
+            $html .=
+            ' (<a class="inreplyto" href="' . $replyurl . '">' . _('in reply to...') . ')';
+        }
+
+        $html .= '</p></li>';
+
+        return $html;
+    }
+
+    function source_link($source)
+    {
+        $source_name = _($source);
+
+        $html = '<span class="noticesource">';
+
+        switch ($source) {
+         case 'web':
+         case 'xmpp':
+         case 'mail':
+         case 'omb':
+         case 'api':
+            $html .= $source_name;
+            break;
+         default:
+            $ns = Notice_source::staticGet($source);
+            if ($ns) {
+                $html .= '<a href="' . $ns->url . '">' . $ns->name . '</a>';
+            } else {
+                $html .= $source_name;
+            }
+            break;
+        }
+
+        $html .= '</span>';
+
+        return $html;
+    }
+
+    function pagination($have_before, $have_after, $page, $fbaction, $args=null)
+    {
+
+        $html = '';
+
+        if ($have_before || $have_after) {
+            $html = '<div id="pagination">';
+            $html .'<ul id="nav_pagination">';
+        }
+
+        if ($have_before) {
+            $pargs = array('page' => $page-1);
+            $newargs = ($args) ? array_merge($args,$pargs) : $pargs;
+            $html .= '<li class="before">';
+            $html .'<a href="' . $this->pagination_url($fbaction, $newargs) . '">' . _('« After') . '</a>';
+            $html .'</li>';
+        }
+
+        if ($have_after) {
+            $pargs = array('page' => $page+1);
+            $newargs = ($args) ? array_merge($args,$pargs) : $pargs;
+            $html .= '<li class="after">';
+            $html .'<a href="' . $this->pagination_url($fbaction, $newargs) . '">' . _('Before Â»') . '</a>';
+            $html .'</li>';
+        }
+
+        if ($have_before || $have_after) {
+            $html .= '<ul>';
+            $html .'<div>';
+        }
+    }
+
+    function pagination_url($fbaction, $args=null)
+    {
+        global $config;
+
+        $extra = '';
+
+        if ($args) {
+            foreach ($args as $key => $value) {
+                $extra .= "&${key}=${value}";
+            }
+        }
+
+        return "$fbaction?${extra}";
+    }
 
 }
diff --git a/lib/facebookutil.php b/lib/facebookutil.php
new file mode 100644 (file)
index 0000000..fc0e41e
--- /dev/null
@@ -0,0 +1,40 @@
+<?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/>.
+ */
+
+require_once(INSTALLDIR.'/extlib/facebook/facebook.php');
+
+// Gets all the notices from users with a Facebook link since a given ID
+function get_facebook_notices($since)
+{
+    $qry = 'SELECT notice.* ' .
+        'FROM notice ' .
+        'JOIN foreign_link ' .
+        'WHERE notice.profile_id = foreign_link.user_id ' .
+        'AND foreign_link.service = 2';
+
+    // XXX: What should the limit be?
+    return Notice::getStreamDirect($qry, 0, 100, 0, 0, null, $since);
+}
+
+function get_facebook()
+{
+    $apikey = common_config('facebook', 'apikey');
+    $secret = common_config('facebook', 'secret');
+    return new Facebook($apikey, $secret);
+}
index 0dd351bab5b788d9f15e044ae506f4de04dc67a8..34b58518c63e1815cf9f8db6c79fadd0bd07c441 100644 (file)
@@ -1,6 +1,5 @@
 <?php
-
-/*
+/**
  * Laconica - a distributed open-source microblogging tool
  * Copyright (C) 2008, Controlez-Vous, Inc.
  *
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 
-if (!defined('LACONICA')) { exit(1); }
+if (!defined('LACONICA')) {
+    exit(1);
+}
 
-require_once(INSTALLDIR.'/lib/profilelist.php');
+require_once INSTALLDIR.'/lib/profilelist.php';
 
-# 10x8
+// 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));
+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) {
+    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);
+    }
 
-               $other = new Profile();
+    function show_gallery($profile, $page, $display='list', $tag=null)
+    {
+        $other = new Profile();
 
-               list($lst, $usr) = $this->fields();
+        list($lst, $usr) = $this->fields();
 
-               $per_page = ($display == 'list') ? PROFILES_PER_PAGE : AVATARS_PER_PAGE;
+        $per_page = ($display == 'list') ? PROFILES_PER_PAGE : AVATARS_PER_PAGE;
 
-               $offset = ($page-1)*$per_page;
-               $limit = $per_page + 1;
+        $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;
-               }
+        if (common_config('db', 'type') == 'pgsql') {
+            $lim = ' LIMIT ' . $limit . ' OFFSET ' . $offset;
+        } else {
+            $lim = ' LIMIT ' . $offset . ', ' . $limit;
+        }
 
-               # XXX: memcached results
-               # FIXME: SQL injection on $tag
+        // 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);
+        $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') {
+        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);
-               }
+            $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
+        // For building the pagination URLs
 
-               $args = array('nickname' => $profile->nickname);
+        $args = array('nickname' => $profile->nickname);
 
-               if ($display != 'list') {
-                       $args['display'] = $display;
-               }
+        if ($display != 'list') {
+            $args['display'] = $display;
+        }
 
-               common_pagination($page > 1,
-                                                 $cnt > $per_page,
-                                                 $page,
-                                                 $this->trimmed('action'),
-                                                 $args);
-       }
+        common_pagination($page > 1,
+                          $cnt > $per_page,
+                          $page,
+                          $this->trimmed('action'),
+                          $args);
+    }
 
-    function profile_list_class() {
+    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;
-       }
+    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
index ab0fd6af8663a6490e3df5dbc9c088e0894c1380..099ded9ebd53395b09765733539e07c86530b259 100644 (file)
@@ -1,9 +1,12 @@
 <?php
-/*
- * Laconica - a distributed open-source microblogging tool
- * Copyright (C) 2008, Controlez-Vous, Inc.
+/**
+ * Laconica, the distributed open-source microblogging tool
  *
- * This program is free software: you can redistribute it and/or modify
+ * utility functions for Jabber/GTalk/XMPP messages
+ *
+ * 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.
  *
  * 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  Network
+ * @package   Laconica
+ * @author    Evan Prodromou <evan@controlyourself.ca>
+ * @copyright 2008 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); }
+if (!defined('LACONICA')) {
+    exit(1);
+}
 
-require_once('XMPPHP/XMPP.php');
+require_once 'XMPPHP/XMPP.php';
 
-function jabber_valid_base_jid($jid) {
-       # Cheap but effective
-       return Validate::email($jid);
-}
+/**
+ * checks whether a string is a syntactically valid Jabber ID (JID)
+ *
+ * @param string $jid string to check
+ *
+ * @return     boolean whether the string is a valid JID
+ */
 
-function jabber_normalize_jid($jid) {
-       if (preg_match("/(?:([^\@]+)\@)?([^\/]+)(?:\/(.*))?$/", $jid, $matches)) {
-               $node = $matches[1];
-               $server = $matches[2];
-               return strtolower($node.'@'.$server);
-       } else {
-               return NULL;
-       }
+function jabber_valid_base_jid($jid)
+{
+    // Cheap but effective
+    return Validate::email($jid);
 }
 
-function jabber_daemon_address() {
-       return common_config('xmpp', 'user') . '@' . common_config('xmpp', 'server');
+/**
+ * normalizes a Jabber ID for comparison
+ *
+ * @param string $jid JID to check
+ *
+ * @return string an equivalent JID in normalized (lowercase) form
+ */
+
+function jabber_normalize_jid($jid)
+{
+    if (preg_match("/(?:([^\@]+)\@)?([^\/]+)(?:\/(.*))?$/", $jid, $matches)) {
+        $node   = $matches[1];
+        $server = $matches[2];
+        return strtolower($node.'@'.$server);
+    } else {
+        return null;
+    }
 }
 
-function jabber_connect($resource=NULL) {
-       static $conn = NULL;
-       if (!$conn) {
-               $conn = new XMPPHP_XMPP(common_config('xmpp', 'host') ?
-                                                               common_config('xmpp', 'host') :
-                                                               common_config('xmpp', 'server'),
-                                                               common_config('xmpp', 'port'),
-                                                               common_config('xmpp', 'user'),
-                                                               common_config('xmpp', 'password'),
-                                                               ($resource) ? $resource :
-                                                               common_config('xmpp', 'resource'),
-                                                               common_config('xmpp', 'server'),
-                                                               common_config('xmpp', 'debug') ?
-                                                               true : false,
-                                                               common_config('xmpp', 'debug') ?
-                                                               XMPPHP_Log::LEVEL_VERBOSE :  NULL
-                                                               );
-
-               if (!$conn) {
-                       return false;
-               }
-
-               $conn->autoSubscribe();
-               $conn->useEncryption(common_config('xmpp', 'encryption'));
-
-               try {
-                       $conn->connect(true); # true = persistent connection
-               } catch (XMPPHP_Exception $e) {
-                       common_log(LOG_ERROR, $e->getMessage());
-                       return false;
-               }
-
-       $conn->processUntil('session_start');
-       }
-       return $conn;
+/**
+ * the JID of the Jabber daemon for this Laconica instance
+ *
+ * @return string JID of the Jabber daemon
+ */
+
+function jabber_daemon_address()
+{
+    return common_config('xmpp', 'user') . '@' . common_config('xmpp', 'server');
 }
 
-function jabber_send_notice($to, $notice) {
-       $conn = jabber_connect();
-       if (!$conn) {
-               return false;
-       }
-       $profile = Profile::staticGet($notice->profile_id);
-       if (!$profile) {
-               common_log(LOG_WARNING, 'Refusing to send notice with ' .
-                          'unknown profile ' . common_log_objstring($notice),
-                          __FILE__);
-               return false;
-       }
-       $msg = jabber_format_notice($profile, $notice);
-       $entry = jabber_format_entry($profile, $notice);
-       $conn->message($to, $msg, 'chat', NULL, $entry);
-       $profile->free();
-       return true;
+/**
+ * connect the configured Jabber account to the configured server
+ *
+ * @param string $resource Resource to connect (defaults to configured resource)
+ *
+ * @return XMPPHP connection to the configured server
+ */
+
+function jabber_connect($resource=null)
+{
+    static $conn = null;
+    if (!$conn) {
+        $conn = new XMPPHP_XMPP(common_config('xmpp', 'host') ?
+                                common_config('xmpp', 'host') :
+                                common_config('xmpp', 'server'),
+                                common_config('xmpp', 'port'),
+                                common_config('xmpp', 'user'),
+                                common_config('xmpp', 'password'),
+                                ($resource) ? $resource :
+                                common_config('xmpp', 'resource'),
+                                common_config('xmpp', 'server'),
+                                common_config('xmpp', 'debug') ?
+                                true : false,
+                                common_config('xmpp', 'debug') ?
+                                XMPPHP_Log::LEVEL_VERBOSE :  null
+                                );
+
+        if (!$conn) {
+            return false;
+        }
+
+        $conn->autoSubscribe();
+        $conn->useEncryption(common_config('xmpp', 'encryption'));
+
+        try {
+            $conn->connect(true); // true = persistent connection
+        } catch (XMPPHP_Exception $e) {
+            common_log(LOG_ERROR, $e->getMessage());
+            return false;
+        }
+
+        $conn->processUntil('session_start');
+    }
+    return $conn;
 }
 
-# Extra stuff defined by Twitter, needed by twitter clients
-
-function jabber_format_entry($profile, $notice) {
-
-       # FIXME: notice url might be remote
-
-       $noticeurl = common_local_url('shownotice',
-                                                                 array('notice' => $notice->id));
-       $msg = jabber_format_notice($profile, $notice);
-       $entry = "\n<entry xmlns='http://www.w3.org/2005/Atom'>\n";
-       $entry .= "<source>\n";
-       $entry .= "<title>" . $profile->nickname . " - " . common_config('site', 'name') . "</title>\n";
-       $entry .= "<link href='" . htmlspecialchars($profile->profileurl) . "'/>\n";
-       $entry .= "<link rel='self' type='application/rss+xml' href='" . common_local_url('userrss', array('nickname' => $profile->nickname)) . "'/>\n";
-       $entry .= "<author><name>" . $profile->nickname . "</name></author>\n";
-       $entry .= "<icon>" . common_profile_avatar_url($profile, AVATAR_PROFILE_SIZE) . "</icon>\n";
-       $entry .= "</source>\n";
-       $entry .= "<title>" . htmlspecialchars($msg) . "</title>\n";
-       $entry .= "<summary>" . htmlspecialchars($msg) . "</summary>\n";
-       $entry .= "<link rel='alternate' href='" . $noticeurl . "' />\n";
-       $entry .= "<id>". $notice->uri . "</id>\n";
-       $entry .= "<published>".common_date_w3dtf($notice->created)."</published>\n";
-       $entry .= "<updated>".common_date_w3dtf($notice->modified)."</updated>\n";
-       $entry .= "</entry>\n";
-
-       $html = "\n<html xmlns='http://jabber.org/protocol/xhtml-im'>\n";
-       $html .= "<body xmlns='http://www.w3.org/1999/xhtml'>\n";
-       $html .= "<a href='".htmlspecialchars($profile->profileurl)."'>".$profile->nickname."</a>: ";
-       $html .= ($notice->rendered) ? $notice->rendered : common_render_content($notice->content, $notice);
-       $html .= "\n</body>\n";
-       $html .= "\n</html>\n";
-
-       $address = "<addresses xmlns='http://jabber.org/protocol/address'>\n";
-       $address .= "<address type='replyto' jid='" . jabber_daemon_address() . "' />\n";
-       $address .= "</addresses>\n";
-
-       # FIXME: include a pubsub event, too.
-
-       return $html . $entry . $address;
+/**
+ * send a single notice to a given Jabber address
+ *
+ * @param string $to     JID to send the notice to
+ * @param Notice $notice notice to send
+ *
+ * @return boolean success value
+ */
+
+function jabber_send_notice($to, $notice)
+{
+    $conn = jabber_connect();
+    if (!$conn) {
+        return false;
+    }
+    $profile = Profile::staticGet($notice->profile_id);
+    if (!$profile) {
+        common_log(LOG_WARNING, 'Refusing to send notice with ' .
+                   'unknown profile ' . common_log_objstring($notice),
+                   __FILE__);
+        return false;
+    }
+    $msg   = jabber_format_notice($profile, $notice);
+    $entry = jabber_format_entry($profile, $notice);
+    $conn->message($to, $msg, 'chat', null, $entry);
+    $profile->free();
+    return true;
 }
 
-function jabber_send_message($to, $body, $type='chat', $subject=NULL) {
-       $conn = jabber_connect();
-       if (!$conn) {
-               return false;
-       }
-       $conn->message($to, $body, $type, $subject);
-       return true;
+/**
+ * extra information for XMPP messages, as defined by Twitter
+ *
+ * @param Profile $profile Profile of the sending user
+ * @param Notice  $notice  Notice being sent
+ *
+ * @return string Extra information (Atom, HTML, addresses) in string format
+ */
+
+function jabber_format_entry($profile, $notice)
+{
+    // FIXME: notice url might be remote
+
+    $noticeurl = common_local_url('shownotice',
+                                  array('notice' => $notice->id));
+
+    $msg = jabber_format_notice($profile, $notice);
+
+    $self_url = common_local_url('userrss', array('nickname' => $profile->nickname));
+
+    $entry  = "\n<entry xmlns='http://www.w3.org/2005/Atom'>\n";
+    $entry .= "<source>\n";
+    $entry .= "<title>" . $profile->nickname . " - " . common_config('site', 'name') . "</title>\n";
+    $entry .= "<link href='" . htmlspecialchars($profile->profileurl) . "'/>\n";
+    $entry .= "<link rel='self' type='application/rss+xml' href='" . $self_url . "'/>\n";
+    $entry .= "<author><name>" . $profile->nickname . "</name></author>\n";
+    $entry .= "<icon>" . common_profile_avatar_url($profile, AVATAR_PROFILE_SIZE) . "</icon>\n";
+    $entry .= "</source>\n";
+    $entry .= "<title>" . htmlspecialchars($msg) . "</title>\n";
+    $entry .= "<summary>" . htmlspecialchars($msg) . "</summary>\n";
+    $entry .= "<link rel='alternate' href='" . $noticeurl . "' />\n";
+    $entry .= "<id>". $notice->uri . "</id>\n";
+    $entry .= "<published>".common_date_w3dtf($notice->created)."</published>\n";
+    $entry .= "<updated>".common_date_w3dtf($notice->modified)."</updated>\n";
+    $entry .= "</entry>\n";
+
+    $html  = "\n<html xmlns='http://jabber.org/protocol/xhtml-im'>\n";
+    $html .= "<body xmlns='http://www.w3.org/1999/xhtml'>\n";
+    $html .= "<a href='".htmlspecialchars($profile->profileurl)."'>".$profile->nickname."</a>: ";
+    $html .= ($notice->rendered) ? $notice->rendered : common_render_content($notice->content, $notice);
+    $html .= "\n</body>\n";
+    $html .= "\n</html>\n";
+
+    $address  = "<addresses xmlns='http://jabber.org/protocol/address'>\n";
+    $address .= "<address type='replyto' jid='" . jabber_daemon_address() . "' />\n";
+    $address .= "</addresses>\n";
+
+    // FIXME: include a pubsub event, too.
+
+    return $html . $entry . $address;
 }
 
-function jabber_send_presence($status, $show='available', $to=NULL,
-                                                         $type = 'available', $priority=NULL)
+/**
+ * sends a single text message to a given JID
+ *
+ * @param string $to      JID to send the message to
+ * @param string $body    body of the message
+ * @param string $type    type of the message
+ * @param string $subject subject of the message
+ *
+ * @return boolean success flag
+ */
+
+function jabber_send_message($to, $body, $type='chat', $subject=null)
 {
-       $conn = jabber_connect();
-       if (!$conn) {
-               return false;
-       }
-       $conn->presence($status, $show, $to, $type, $priority);
-       return true;
+    $conn = jabber_connect();
+    if (!$conn) {
+        return false;
+    }
+    $conn->message($to, $body, $type, $subject);
+    return true;
 }
 
-function jabber_confirm_address($code, $nickname, $address) {
-       $body = 'User "' . $nickname . '" on ' . common_config('site', 'name') . ' ' .
-                       'has said that your Jabber ID belongs to them. ' .
-           'If that\'s true, you can confirm by clicking on this URL: ' .
-               common_local_url('confirmaddress', array('code' => $code)) .
-               ' . (If you cannot click it, copy-and-paste it into the ' .
-               'address bar of your browser). If that user isn\'t you, ' .
-               'or if you didn\'t request this confirmation, just ignore this message.';
+/**
+ * sends a presence stanza on the Jabber network
+ *
+ * @param string $status   current status, free-form string
+ * @param string $show     structured status value
+ * @param string $to       recipient of presence, null for general
+ * @param string $type     type of status message, related to $show
+ * @param int    $priority priority of the presence
+ *
+ * @return boolean success value
+ */
 
-       return jabber_send_message($address, $body);
+function jabber_send_presence($status, $show='available', $to=null,
+                              $type = 'available', $priority=null)
+{
+    $conn = jabber_connect();
+    if (!$conn) {
+        return false;
+    }
+    $conn->presence($status, $show, $to, $type, $priority);
+    return true;
 }
 
-function jabber_special_presence($type, $to=NULL, $show=NULL, $status=NULL) {
-       $conn = jabber_connect();
-
-       $to = htmlspecialchars($to);
-       $status = htmlspecialchars($status);
-       $out = "<presence";
-       if($to) $out .= " to='$to'";
-       if($type) $out .= " type='$type'";
-       if($show == 'available' and !$status) {
-               $out .= "/>";
-       } else {
-               $out .= ">";
-               if($show && ($show != 'available')) $out .= "<show>$show</show>";
-               if($status) $out .= "<status>$status</status>";
-               $out .= "</presence>";
-       }
-       $conn->send($out);
+/**
+ * sends a confirmation request to a JID
+ *
+ * @param string $code     confirmation code for confirmation URL
+ * @param string $nickname nickname of confirming user
+ * @param string $address  JID to send confirmation to
+ *
+ * @return boolean success flag
+ */
+
+function jabber_confirm_address($code, $nickname, $address)
+{
+    $body = 'User "' . $nickname . '" on ' . common_config('site', 'name') . ' ' .
+      'has said that your Jabber ID belongs to them. ' .
+      'If that\'s true, you can confirm by clicking on this URL: ' .
+      common_local_url('confirmaddress', array('code' => $code)) .
+      ' . (If you cannot click it, copy-and-paste it into the ' .
+      'address bar of your browser). If that user isn\'t you, ' .
+      'or if you didn\'t request this confirmation, just ignore this message.';
+
+    return jabber_send_message($address, $body);
 }
 
-function jabber_broadcast_notice($notice) {
-
-       if (!common_config('xmpp', 'enabled')) {
-               return true;
-       }
-       $profile = Profile::staticGet($notice->profile_id);
-
-       if (!$profile) {
-               common_log(LOG_WARNING, 'Refusing to broadcast notice with ' .
-                          'unknown profile ' . common_log_objstring($notice),
-                          __FILE__);
-               return false;
-       }
-
-       $msg = jabber_format_notice($profile, $notice);
-       $entry = jabber_format_entry($profile, $notice);
-
-       $profile->free();
-       unset($profile);
-
-       $sent_to = array();
-       $conn = jabber_connect();
-
-       # First, get users to whom this is a direct reply
-       $user = new User();
-       $user->query('SELECT user.id, user.jabber ' .
-                                'FROM user JOIN reply ON user.id = reply.profile_id ' .
-                                'WHERE reply.notice_id = ' . $notice->id . ' ' .
-                                'AND user.jabber is not null ' .
-                                'AND user.jabbernotify = 1 ' .
-                                'AND user.jabberreplies = 1 ');
-
-       while ($user->fetch()) {
-               common_log(LOG_INFO,
-                                  'Sending reply notice ' . $notice->id . ' to ' . $user->jabber,
-                                  __FILE__);
-               $conn->message($user->jabber, $msg, 'chat', NULL, $entry);
-               $conn->processTime(0);
-               $sent_to[$user->id] = 1;
-       }
-
-       $user->free();
-
-    # Now, get users subscribed to this profile
-
-       $user = new User();
-       $user->query('SELECT user.id, user.jabber ' .
-                                'FROM user JOIN subscription ON user.id = subscription.subscriber ' .
-                                'WHERE subscription.subscribed = ' . $notice->profile_id . ' ' .
-                                'AND user.jabber is not null ' .
-                                'AND user.jabbernotify = 1 ' .
-                 'AND subscription.jabber = 1 ');
+/**
+ * sends a "special" presence stanza on the Jabber network
+ *
+ * @param string $type   Type of presence
+ * @param string $to     JID to send presence to
+ * @param string $show   show value for presence
+ * @param string $status status value for presence
+ *
+ * @return boolean success flag
+ *
+ * @see jabber_send_presence()
+ */
 
-       while ($user->fetch()) {
-               if (!array_key_exists($user->id, $sent_to)) {
-                       common_log(LOG_INFO,
-                                          'Sending notice ' . $notice->id . ' to ' . $user->jabber,
-                                          __FILE__);
-                       $conn->message($user->jabber, $msg, 'chat', NULL, $entry);
-                       # To keep the incoming queue from filling up, we service it after each send.
-                       $conn->processTime(0);
-               }
-       }
+function jabber_special_presence($type, $to=null, $show=null, $status=null)
+{
+    // FIXME: why use this instead of jabber_send_presence()?
+    $conn = jabber_connect();
+
+    $to     = htmlspecialchars($to);
+    $status = htmlspecialchars($status);
+
+    $out = "<presence";
+    if ($to) {
+        $out .= " to='$to'";
+    }
+    if ($type) {
+        $out .= " type='$type'";
+    }
+    if ($show == 'available' and !$status) {
+        $out .= "/>";
+    } else {
+        $out .= ">";
+        if ($show && ($show != 'available')) {
+            $out .= "<show>$show</show>";
+        }
+        if ($status) {
+            $out .= "<status>$status</status>";
+        }
+        $out .= "</presence>";
+    }
+    $conn->send($out);
+}
 
-       $user->free();
+/**
+ * broadcast a notice to all subscribers and reply recipients
+ *
+ * This function will send a notice to all subscribers on the local server
+ * who have Jabber addresses, and have Jabber notification enabled, and
+ * have this subscription enabled for Jabber. It also sends the notice to
+ * all recipients of @-replies who have Jabber addresses and Jabber notification
+ * enabled. This is really the heart of Jabber distribution in Laconica.
+ *
+ * @param Notice $notice The notice to broadcast
+ *
+ * @return boolean success flag
+ */
 
-       return true;
+function jabber_broadcast_notice($notice)
+{
+    if (!common_config('xmpp', 'enabled')) {
+        return true;
+    }
+    $profile = Profile::staticGet($notice->profile_id);
+
+    if (!$profile) {
+        common_log(LOG_WARNING, 'Refusing to broadcast notice with ' .
+                   'unknown profile ' . common_log_objstring($notice),
+                   __FILE__);
+        return false;
+    }
+
+    $msg   = jabber_format_notice($profile, $notice);
+    $entry = jabber_format_entry($profile, $notice);
+
+    $profile->free();
+    unset($profile);
+
+    $sent_to = array();
+
+    $conn = jabber_connect();
+
+    // First, get users to whom this is a direct reply
+    $user = new User();
+    $user->query('SELECT user.id, user.jabber ' .
+                 'FROM user JOIN reply ON user.id = reply.profile_id ' .
+                 'WHERE reply.notice_id = ' . $notice->id . ' ' .
+                 'AND user.jabber is not null ' .
+                 'AND user.jabbernotify = 1 ' .
+                 'AND user.jabberreplies = 1 ');
+
+    while ($user->fetch()) {
+        common_log(LOG_INFO,
+                   'Sending reply notice ' . $notice->id . ' to ' . $user->jabber,
+                   __FILE__);
+        $conn->message($user->jabber, $msg, 'chat', null, $entry);
+        $conn->processTime(0);
+        $sent_to[$user->id] = 1;
+    }
+
+    $user->free();
+
+    // Now, get users subscribed to this profile
+
+    $user = new User();
+    $user->query('SELECT user.id, user.jabber ' .
+                 'FROM user JOIN subscription ' .
+                 'ON user.id = subscription.subscriber ' .
+                 'WHERE subscription.subscribed = ' . $notice->profile_id . ' ' .
+                 'AND user.jabber is not null ' .
+                 'AND user.jabbernotify = 1 ' .
+                 'AND subscription.jabber = 1 ');
+
+    while ($user->fetch()) {
+        if (!array_key_exists($user->id, $sent_to)) {
+            common_log(LOG_INFO,
+                       'Sending notice ' . $notice->id . ' to ' . $user->jabber,
+                       __FILE__);
+            $conn->message($user->jabber, $msg, 'chat', null, $entry);
+            // To keep the incoming queue from filling up,
+            // we service it after each send.
+            $conn->processTime(0);
+        }
+    }
+
+    $user->free();
+
+    return true;
 }
 
-function jabber_public_notice($notice) {
+/**
+ * send a notice to all public listeners
+ *
+ * For notices that are generated on the local system (by users), we can optionally
+ * forward them to remote listeners by XMPP.
+ *
+ * @param Notice $notice notice to broadcast
+ *
+ * @return boolean success flag
+ */
 
-       # Now, users who want everything
+function jabber_public_notice($notice)
+{
+    // Now, users who want everything
 
-       $public = common_config('xmpp', 'public');
+    $public = common_config('xmpp', 'public');
 
-       # FIXME PRIV don't send out private messages here
-       # XXX: should we send out non-local messages if public,localonly
-       # = false? I think not
+    // FIXME PRIV don't send out private messages here
+    // XXX: should we send out non-local messages if public,localonly
+    // = false? I think not
 
-       if ($public && $notice->is_local) {
-               $profile = Profile::staticGet($notice->profile_id);
+    if ($public && $notice->is_local) {
+        $profile = Profile::staticGet($notice->profile_id);
 
-               if (!$profile) {
-                       common_log(LOG_WARNING, 'Refusing to broadcast notice with ' .
-                                          'unknown profile ' . common_log_objstring($notice),
-                                          __FILE__);
-                       return false;
-               }
+        if (!$profile) {
+            common_log(LOG_WARNING, 'Refusing to broadcast notice with ' .
+                       'unknown profile ' . common_log_objstring($notice),
+                       __FILE__);
+            return false;
+        }
 
-               $msg = jabber_format_notice($profile, $notice);
-               $entry = jabber_format_entry($profile, $notice);
+        $msg   = jabber_format_notice($profile, $notice);
+        $entry = jabber_format_entry($profile, $notice);
 
-               $conn = jabber_connect();
+        $conn = jabber_connect();
 
-               foreach ($public as $address) {
-                       common_log(LOG_INFO,
-                                          'Sending notice ' . $notice->id . ' to public listener ' . $address,
-                                          __FILE__);
-                       $conn->message($address, $msg, 'chat', NULL, $entry);
-                       $conn->processTime(0);
-               }
-               $profile->free();
-       }
+        foreach ($public as $address) {
+            common_log(LOG_INFO,
+                       'Sending notice ' . $notice->id .
+                       ' to public listener ' . $address,
+                       __FILE__);
+            $conn->message($address, $msg, 'chat', null, $entry);
+            $conn->processTime(0);
+        }
+        $profile->free();
+    }
 
-       return true;
+    return true;
 }
 
-function jabber_format_notice(&$profile, &$notice) {
-       return $profile->nickname . ': ' . $notice->content;
+/**
+ * makes a plain-text formatted version of a notice, suitable for Jabber distribution
+ *
+ * @param Profile &$profile profile of the sending user
+ * @param Notice  &$notice  notice being sent
+ *
+ * @return string plain-text version of the notice, with user nickname prefixed
+ */
+
+function jabber_format_notice(&$profile, &$notice)
+{
+    return $profile->nickname . ': ' . $notice->content;
 }
index 796e28870dddec7282ecb52d7a6f5bf98428aff3..1d00cc31e18f88d33c2743f3d35183d08fac6722 100644 (file)
@@ -1,9 +1,12 @@
 <?php
-/*
- * Laconica - a distributed open-source microblogging tool
- * Copyright (C) 2008, Controlez-Vous, Inc.
+/**
+ * Laconica, the distributed open-source microblogging tool
  *
- * This program is free software: you can redistribute it and/or modify
+ * utility functions for i18n
+ *
+ * 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.
  *
  * 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 I18n
+ * @package  Laconica
+ * @author   Matthew Gregg <matthew.gregg@gmail.com>
+ * @author   Ciaran Gultnieks <ciaran@ciarang.com>
+ * @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/
  */
 
-if (!defined('LACONICA')) { exit(1); }
+if (!defined('LACONICA')) {
+    exit(1);
+}
 
+/**
+ * Content negotiation for language codes
+ *
+ * @param string $httplang HTTP Accept-Language header
+ *
+ * @return string language code for best language match
+ */
 
+function client_prefered_language($httplang)
+{
+    $client_langs = array();
 
-function client_prefered_language($httplang) {
-        $client_langs = array();
-        $all_languages = common_config('site','languages');
+    $all_languages = common_config('site', 'languages');
 
-        preg_match_all('"(((\S\S)-?(\S\S)?)(;q=([0-9.]+))?)\s*(,\s*|$)"',strtolower($httplang),$httplang);
-        for ($i = 0; $i < count($httplang); $i++) {
-             if(!empty($httplang[2][$i])) {
-                    #if no q default to 1.0
-                    $client_langs[$httplang[2][$i]] = ($httplang[6][$i]? (float) $httplang[6][$i] : 1.0);
-                }
-                if(!empty($httplang[3][$i]) && empty($client_langs[$httplang[3][$i]])) {
-                    #if a catchall default 0.01 lower
-                    $client_langs[$httplang[3][$i]] = ($httplang[6][$i]? (float) $httplang[6][$i]-0.01 : 0.99);
-                }
-            }
-            #sort in decending q
-            arsort($client_langs);
+    preg_match_all('"(((\S\S)-?(\S\S)?)(;q=([0-9.]+))?)\s*(,\s*|$)"',
+                   strtolower($httplang), $httplang);
 
-            foreach ($client_langs as $lang => $q) {
-                if (isset($all_languages[$lang])) {
-                    return($all_languages[$lang]['lang']);
-                }
-            }
-            return FALSE;
-}
+    for ($i = 0; $i < count($httplang); $i++) {
+        if (!empty($httplang[2][$i])) {
+            // if no q default to 1.0
+            $client_langs[$httplang[2][$i]] =
+              ($httplang[6][$i]? (float) $httplang[6][$i] : 1.0);
+        }
+        if (!empty($httplang[3][$i]) && empty($client_langs[$httplang[3][$i]])) {
+            // if a catchall default 0.01 lower
+            $client_langs[$httplang[3][$i]] =
+              ($httplang[6][$i]? (float) $httplang[6][$i]-0.01 : 0.99);
+        }
+    }
+    // sort in decending q
+    arsort($client_langs);
 
-function get_nice_language_list() {
-        $nice_lang = array();
-        $all_languages = common_config('site','languages');
-        foreach ($all_languages as $lang) {
-                $nice_lang = $nice_lang + array($lang['lang'] => $lang['name']);
+    foreach ($client_langs as $lang => $q) {
+        if (isset($all_languages[$lang])) {
+            return($all_languages[$lang]['lang']);
         }
-        return $nice_lang;
+    }
+    return false;
 }
 
-// Get a list of all languages that are enabled in the default config. This
-// should ONLY be called when setting up the default config in common.php.
-// Any other attempt to get a list of lanugages should instead call
-// common_config('site','languages')
-function get_all_languages() {
-       return array(
-               'en-us' => array('q' => 1, 'lang' => 'en_US', 'name' => 'English (US)', 'direction' => 'ltr'),
-               'en-nz' => array('q' => 1, 'lang' => 'en_NZ', 'name' => 'English (NZ)', 'direction' => 'ltr'),
-               'en-gb' => array('q' => 1, 'lang' => 'en_GB', 'name' => 'English (British)', 'direction' => 'ltr'),
-               'en'    => array('q' => 1, 'lang' => 'en',    'name' => 'English', 'direction' => 'ltr'),
-               'da'    => array('q' => 0.1, 'lang' => 'da_DK', 'name' => 'Danish', 'direction' => 'ltr'),
-               'nl'    => array('q' => 1, 'lang' => 'nl_NL', 'name' => 'Dutch', 'direction' => 'ltr'),
-               'eo'    => array('q' => 0.1, 'lang' => 'eo',    'name' => 'Esperanto', 'direction' => 'ltr'),
-               'fr-fr' => array('q' => 0.9, 'lang' => 'fr_FR', 'name' => 'French', 'direction' => 'ltr'),
-               'de'    => array('q' => 1, 'lang' => 'de_DE', 'name' => 'German', 'direction' => 'ltr'),
-               'it'    => array('q' => 1, 'lang' => 'it_IT', 'name' => 'Italian', 'direction' => 'ltr'),
-               'ko'    => array('q' => 0.1, 'lang' => 'ko',    'name' => 'Korean', 'direction' => 'ltr'),
-               'nb'    => array('q' => 1, 'lang' => 'nb_NO', 'name' => 'Norwegian (bokmal)', 'direction' => 'ltr'),
-               'pt'    => array('q' => 0.2, 'lang' => 'pt',    'name' => 'Portuguese', 'direction' => 'ltr'),
-               'pt-br' => array('q' => 1, 'lang' => 'pt_BR', 'name' => 'Portuguese Brazil', 'direction' => 'ltr'),
-#              'ru'    => array('q' => 0.1, 'lang' => 'ru_RU', 'name' => 'Russian', 'direction' => 'ltr'),
-               'es'    => array('q' => 1, 'lang' => 'es',    'name' => 'Spanish', 'direction' => 'ltr'),
-               'tr'    => array('q' => 1, 'lang' => 'tr_TR', 'name' => 'Turkish', 'direction' => 'ltr'),
-               'uk'    => array('q' => 1, 'lang' => 'uk_UA', 'name' => 'Ukrainian', 'direction' => 'ltr'),
-#              'lt'    => array('q' => 0.1, 'lang' => 'lt_LT', 'name' => 'Lithuanian', 'direction' => 'ltr'),
-#              'sv'    => array('q' => 1, 'lang' => 'sv_SE', 'name' => 'Swedish', 'direction' => 'ltr'),
-               'pl'    => array('q' => 1, 'lang' => 'pl_PL', 'name' => 'Polish', 'direction' => 'ltr'),
-               'mk'    => array('q' => 1, 'lang' => 'mk_MK', 'name' => 'Macedonian', 'direction' => 'ltr'),
-               'jp'    => array('q' => 0.1, 'lang' => 'ja_JP', 'name' => 'Japanese', 'direction' => 'ltr'),
-               'cs'    => array('q' => 1, 'lang' => 'cs_CZ', 'name' => 'Czech', 'direction' => 'ltr'),
-               'ca'    => array('q' => 1, 'lang' => 'ca_ES', 'name' => 'Catalan', 'direction' => 'ltr'),
-#              'hr'    => array('q' => 0.1, 'lang' => 'he_IL', 'name' => 'Hebrew', 'direction' => 'ltr')
-       );
+/**
+ * returns a simple code -> name mapping for languages
+ *
+ * @return array map of available languages by code to language name.
+ */
+
+function get_nice_language_list()
+{
+    $nice_lang = array();
+
+    $all_languages = common_config('site', 'languages');
+
+    foreach ($all_languages as $lang) {
+        $nice_lang = $nice_lang + array($lang['lang'] => $lang['name']);
+    }
+    return $nice_lang;
+}
+
+/**
+ * Get a list of all languages that are enabled in the default config
+ *
+ * This should ONLY be called when setting up the default config in common.php.
+ * Any other attempt to get a list of lanugages should instead call
+ * common_config('site','languages')
+ *
+ * @return array mapping of language codes to language info
+ */
+
+function get_all_languages()
+{
+    return
+      array('en-us' => array('q' => 1, 'lang' => 'en_US',
+                             'name' => 'English (US)', 'direction' => 'ltr'),
+            'en-nz' => array('q' => 1, 'lang' => 'en_NZ',
+                             'name' => 'English (NZ)', 'direction' => 'ltr'),
+            'en-gb' => array('q' => 1, 'lang' => 'en_GB',
+                             'name' => 'English (British)', 'direction' => 'ltr'),
+            'en' => array('q' => 1, 'lang' => 'en',
+                          'name' => 'English', 'direction' => 'ltr'),
+            'da' => array('q' => 0.1, 'lang' => 'da_DK',
+                          'name' => 'Danish', 'direction' => 'ltr'),
+            'nl' => array('q' => 1, 'lang' => 'nl_NL',
+                          'name' => 'Dutch', 'direction' => 'ltr'),
+            'eo' => array('q' => 0.1, 'lang' => 'eo',
+                          'name' => 'Esperanto', 'direction' => 'ltr'),
+            'fr-fr' => array('q' => 0.9, 'lang' => 'fr_FR',
+                             'name' => 'French', 'direction' => 'ltr'),
+            'de' => array('q' => 1, 'lang' => 'de_DE',
+                          'name' => 'German', 'direction' => 'ltr'),
+            'it' => array('q' => 1, 'lang' => 'it_IT',
+                          'name' => 'Italian', 'direction' => 'ltr'),
+            'ko' => array('q' => 0.1, 'lang' => 'ko',
+                          'name' => 'Korean', 'direction' => 'ltr'),
+            'nb' => array('q' => 1, 'lang' => 'nb_NO',
+                          'name' => 'Norwegian (bokmal)', 'direction' => 'ltr'),
+            'pt' => array('q' => 0.2, 'lang' => 'pt',
+                          'name' => 'Portuguese', 'direction' => 'ltr'),
+            'pt-br' => array('q' => 1, 'lang' => 'pt_BR',
+                             'name' => 'Portuguese Brazil', 'direction' => 'ltr'),
+            'es' => array('q' => 1, 'lang' => 'es',
+                          'name' => 'Spanish', 'direction' => 'ltr'),
+            'tr' => array('q' => 1, 'lang' => 'tr_TR',
+                          'name' => 'Turkish', 'direction' => 'ltr'),
+            'uk' => array('q' => 1, 'lang' => 'uk_UA',
+                          'name' => 'Ukrainian', 'direction' => 'ltr'),
+            'pl' => array('q' => 1, 'lang' => 'pl_PL',
+                          'name' => 'Polish', 'direction' => 'ltr'),
+            'mk' => array('q' => 1, 'lang' => 'mk_MK',
+                          'name' => 'Macedonian', 'direction' => 'ltr'),
+            'jp' => array('q' => 0.1, 'lang' => 'ja_JP',
+                          'name' => 'Japanese', 'direction' => 'ltr'),
+            'cs' => array('q' => 1, 'lang' => 'cs_CZ',
+                          'name' => 'Czech', 'direction' => 'ltr'),
+            'ca' => array('q' => 1, 'lang' => 'ca_ES',
+                          'name' => 'Catalan', 'direction' => 'ltr'),
+            );
 }
 
index a7cbab8589665daa7343ce171d892e66d5947037..5638ae9bfb596e5f91344b008df83df3d329f36b 100644 (file)
@@ -1,9 +1,12 @@
 <?php
-/*
- * Laconica - a distributed open-source microblogging tool
- * Copyright (C) 2008, Controlez-Vous, Inc.
+/**
+ * Laconica, the distributed open-source microblogging tool
  *
- * This program is free software: you can redistribute it and/or modify
+ * utilities for sending email
+ *
+ * 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.
  *
  * 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  Mail
+ * @package   Laconica
+ * @author    Evan Prodromou <evan@controlyourself.ca>
+ * @author    Zach Copley <zach@controlyourself.ca>
+ * @author    Robin Millette <millette@controlyourself.ca>
+ * @author    Sarven Capadisli <csarven@controlyourself.ca>
+ * @copyright 2008 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); }
+if (!defined('LACONICA')) {
+    exit(1);
+}
 
-require_once('Mail.php');
+require_once 'Mail.php';
 
-function mail_backend() {
-       static $backend = NULL;
+/**
+ * return the configured mail backend
+ *
+ * Uses the $config array to make a mail backend. Cached so it is safe to call
+ * more than once.
+ *
+ * @return Mail backend
+ */
 
-       if (!$backend) {
-               global $config;
-               $backend = Mail::factory($config['mail']['backend'],
-                                                                ($config['mail']['params']) ? $config['mail']['params'] : array());
-               if (PEAR::isError($backend)) {
-                       common_server_error($backend->getMessage(), 500);
-               }
-       }
-       return $backend;
+function mail_backend()
+{
+    static $backend = null;
+
+    if (!$backend) {
+        global $config;
+        $backend = Mail::factory($config['mail']['backend'],
+                                 ($config['mail']['params']) ?
+                                 $config['mail']['params'] :
+                                 array());
+        if (PEAR::isError($backend)) {
+            common_server_error($backend->getMessage(), 500);
+        }
+    }
+    return $backend;
 }
 
-# XXX: use Mail_Queue... maybe
+/**
+ * send an email to one or more recipients
+ *
+ * @param array  $recipients array of strings with email addresses of recipients
+ * @param array  $headers    array mapping strings to strings for email headers
+ * @param string $body       body of the email
+ *
+ * @return boolean success flag
+ */
 
-function mail_send($recipients, $headers, $body) {
-       $backend = mail_backend();
+function mail_send($recipients, $headers, $body)
+{
+    // XXX: use Mail_Queue... maybe
+    $backend = mail_backend();
     if (!isset($headers['Content-Type'])) {
         $headers['Content-Type'] = 'text/plain; charset=UTF-8';
     }
-       assert($backend); # throws an error if it's bad
-       $sent = $backend->send($recipients, $headers, $body);
-       if (PEAR::isError($sent)) {
-               common_log(LOG_ERR, 'Email error: ' . $sent->getMessage());
-               return false;
-       }
-       return true;
+    assert($backend); // throws an error if it's bad
+    $sent = $backend->send($recipients, $headers, $body);
+    if (PEAR::isError($sent)) {
+        common_log(LOG_ERR, 'Email error: ' . $sent->getMessage());
+        return false;
+    }
+    return true;
 }
 
-function mail_domain() {
-       $maildomain = common_config('mail', 'domain');
-       if (!$maildomain) {
-               $maildomain = common_config('site', 'server');
-       }
-       return $maildomain;
-}
+/**
+ * returns the configured mail domain
+ *
+ * Defaults to the server name.
+ *
+ * @return string mail domain, suitable for making email addresses.
+ */
 
-function mail_notify_from() {
-       $notifyfrom = common_config('mail', 'notifyfrom');
-       if (!$notifyfrom) {
-               $domain = mail_domain();
-               $notifyfrom = common_config('site', 'name') .' <noreply@'.$domain.'>';
-       }
-       return $notifyfrom;
+function mail_domain()
+{
+    $maildomain = common_config('mail', 'domain');
+    if (!$maildomain) {
+        $maildomain = common_config('site', 'server');
+    }
+    return $maildomain;
 }
 
-function mail_to_user(&$user, $subject, $body, $address=NULL) {
-       if (!$address) {
-               $address = $user->email;
-       }
+/**
+ * returns a good address for sending email from this server
+ *
+ * Uses either the configured value or a faked-up value made
+ * from the mail domain.
+ *
+ * @return string notify from address
+ */
 
-       $recipients = $address;
-       $profile = $user->getProfile();
+function mail_notify_from()
+{
+    $notifyfrom = common_config('mail', 'notifyfrom');
 
-       $headers['From'] = mail_notify_from();
-       $headers['To'] = $profile->getBestName() . ' <' . $address . '>';
-       $headers['Subject'] = $subject;
+    if (!$notifyfrom) {
 
-       return mail_send($recipients, $headers, $body);
+        $domain = mail_domain();
+
+        $notifyfrom = common_config('site', 'name') .' <noreply@'.$domain.'>';
+    }
+
+    return $notifyfrom;
 }
 
-# For confirming a Jabber address
+/**
+ * sends email to a user
+ *
+ * @param User   &$user   user to send email to
+ * @param string $subject subject of the email
+ * @param string $body    body of the email
+ * @param string $address optional specification of email address
+ *
+ * @return boolean success flag
+ */
 
-function mail_confirm_address($user, $code, $nickname, $address) {
+function mail_to_user(&$user, $subject, $body, $address=null)
+{
+    if (!$address) {
+        $address = $user->email;
+    }
+
+    $recipients = $address;
+    $profile    = $user->getProfile();
 
-       $subject = _('Email address confirmation');
+    $headers['From']    = mail_notify_from();
+    $headers['To']      = $profile->getBestName() . ' <' . $address . '>';
+    $headers['Subject'] = $subject;
 
-    $body = sprintf(_("Hey, %s.\n\nSomeone just entered this email address on %s.\n\n" .
-        "If it was you, and you want to confirm your entry, use the URL below:\n\n\t%s\n\n" .
-        "If not, just ignore this message.\n\nThanks for your time, \n%s\n")
-        , $nickname, common_config('site', 'name')
-        , common_local_url('confirmaddress', array('code' => $code)), common_config('site', 'name'));
-     return mail_to_user($user, $subject, $body, $address);
+    return mail_send($recipients, $headers, $body);
 }
 
-function mail_subscribe_notify($listenee, $listener) {
-       $other = $listener->getProfile();
-       mail_subscribe_notify_profile($listenee, $other);
+/**
+ * Send an email to confirm a user's control of an email address
+ *
+ * @param User   $user     User claiming the email address
+ * @param string $code     Confirmation code
+ * @param string $nickname Nickname of user
+ * @param string $address  email address to confirm
+ *
+ * @see common_confirmation_code()
+ *
+ * @return success flag
+ */
+
+function mail_confirm_address($user, $code, $nickname, $address)
+{
+    $subject = _('Email address confirmation');
+
+    $body = sprintf(_("Hey, %s.\n\n".
+                      "Someone just entered this email address on %s.\n\n" .
+                      "If it was you, and you want to confirm your entry, ".
+                      "use the URL below:\n\n\t%s\n\n" .
+                      "If not, just ignore this message.\n\n".
+                      "Thanks for your time, \n%s\n"),
+                    $nickname, common_config('site', 'name'),
+                    common_local_url('confirmaddress', array('code' => $code)),
+                    common_config('site', 'name'));
+    return mail_to_user($user, $subject, $body, $address);
 }
 
-function mail_subscribe_notify_profile($listenee, $other) {
-       if ($listenee->email && $listenee->emailnotifysub) {
-        // use the recipients localization
+/**
+ * notify a user of subscription by another user
+ *
+ * This is just a wrapper around the profile-based version.
+ *
+ * @param User $listenee user who is being subscribed to
+ * @param User $listener user who is subscribing
+ *
+ * @see mail_subscribe_notify_profile()
+ *
+ * @return void
+ */
+
+function mail_subscribe_notify($listenee, $listener)
+{
+    $other = $listener->getProfile();
+    mail_subscribe_notify_profile($listenee, $other);
+}
+
+/**
+ * notify a user of subscription by a profile (remote or local)
+ *
+ * This function checks to see if the listenee has an email
+ * address and wants subscription notices.
+ *
+ * @param User    $listenee user who's being subscribed to
+ * @param Profile $other    profile of person who's listening
+ *
+ * @return void
+ */
+
+function mail_subscribe_notify_profile($listenee, $other)
+{
+    if ($listenee->email && $listenee->emailnotifysub) {
+
+        // use the recipient's localization
         common_init_locale($listenee->language);
-               $profile = $listenee->getProfile();
-               $name = $profile->getBestName();
-               $long_name = ($other->fullname) ? ($other->fullname . ' (' . $other->nickname . ')') : $other->nickname;
-               $recipients = $listenee->email;
-               $headers['From'] = mail_notify_from();
-               $headers['To'] = $name . ' <' . $listenee->email . '>';
-               $headers['Subject'] = sprintf(_('%1$s is now listening to your notices on %2$s.'), $other->getBestName(),
-                                                                         common_config('site', 'name'));
-               $body  = sprintf(_('%1$s is now listening to your notices on %2$s.'."\n\n".
-                                                  "\t".'%3$s'."\n\n".
-                                                  'Faithfully yours,'."\n".'%4$s.'."\n"),
-                                                $long_name,
-                                                common_config('site', 'name'),
-                                                $other->profileurl,
-                                                common_config('site', 'name'));
+
+        $profile = $listenee->getProfile();
+
+        $name = $profile->getBestName();
+
+        $long_name = ($other->fullname) ?
+          ($other->fullname . ' (' . $other->nickname . ')') : $other->nickname;
+
+        $recipients = $listenee->email;
+
+        $headers['From']    = mail_notify_from();
+        $headers['To']      = $name . ' <' . $listenee->email . '>';
+        $headers['Subject'] = sprintf(_('%1$s is now listening to '.
+                                        'your notices on %2$s.'),
+                                      $other->getBestName(),
+                                      common_config('site', 'name'));
+
+        $body = sprintf(_('%1$s is now listening to your notices on %2$s.'."\n\n".
+                          "\t".'%3$s'."\n\n".
+                          '%4$s'.
+                          '%5$s'.
+                          '%6$s'.
+                          "\n".'Faithfully yours,'."\n".'%7$s.'."\n\n".
+                          "----\n".
+                          "Change your email address or ".
+                          "notification options at %8$s\n"),
+                        $long_name,
+                        common_config('site', 'name'),
+                        $other->profileurl,
+                        ($other->location) ?
+                        sprintf(_("Location: %s\n"), $other->location) : '',
+                        ($other->homepage) ?
+                        sprintf(_("Homepage: %s\n"), $other->homepage) : '',
+                        ($other->bio) ?
+                        sprintf(_("Bio: %s\n\n"), $other->bio) : '',
+                        common_config('site', 'name'),
+                        common_local_url('emailsettings'));
 
         // reset localization
         common_init_locale();
-               mail_send($recipients, $headers, $body);
-       }
+        mail_send($recipients, $headers, $body);
+    }
 }
 
-function mail_new_incoming_notify($user) {
+/**
+ * notify a user of their new incoming email address
+ *
+ * User's email and incoming fields should already be updated.
+ *
+ * @param User $user user with the new address
+ *
+ * @return void
+ */
 
-       $profile = $user->getProfile();
-       $name = $profile->getBestName();
+function mail_new_incoming_notify($user)
+{
+    $profile = $user->getProfile();
 
-       $headers['From'] = $user->incomingemail;
-       $headers['To'] = $name . ' <' . $user->email . '>';
-       $headers['Subject'] = sprintf(_('New email address for posting to %s'),
-                                                                 common_config('site', 'name'));
+    $name = $profile->getBestName();
 
-       $body  = sprintf(_("You have a new posting address on %1\$s.\n\n".
-                                          "Send email to %2\$s to post new messages.\n\n".
-                                          "More email instructions at %3\$s.\n\n".
-                                          "Faithfully yours,\n%4\$s"),
-                                        common_config('site', 'name'),
-                                        $user->incomingemail,
-                                        common_local_url('doc', array('title' => 'email')),
-                                        common_config('site', 'name'));
+    $headers['From']    = $user->incomingemail;
+    $headers['To']      = $name . ' <' . $user->email . '>';
+    $headers['Subject'] = sprintf(_('New email address for posting to %s'),
+                                  common_config('site', 'name'));
 
-       mail_send($user->email, $headers, $body);
+    $body = sprintf(_("You have a new posting address on %1\$s.\n\n".
+                      "Send email to %2\$s to post new messages.\n\n".
+                      "More email instructions at %3\$s.\n\n".
+                      "Faithfully yours,\n%4\$s"),
+                    common_config('site', 'name'),
+                    $user->incomingemail,
+                    common_local_url('doc', array('title' => 'email')),
+                    common_config('site', 'name'));
+
+    mail_send($user->email, $headers, $body);
 }
 
-function mail_new_incoming_address() {
-       $prefix = common_confirmation_code(64);
-       $suffix = mail_domain();
-       return $prefix . '@' . $suffix;
+/**
+ * generate a new address for incoming messages
+ *
+ * @todo check the database for uniqueness
+ *
+ * @return string new email address for incoming messages
+ */
+
+function mail_new_incoming_address()
+{
+    $prefix = common_confirmation_code(64);
+    $suffix = mail_domain();
+    return $prefix . '@' . $suffix;
 }
 
-function mail_broadcast_notice_sms($notice) {
+/**
+ * broadcast a notice to all subscribers with SMS notification on
+ *
+ * This function sends SMS messages to all users who have sms addresses;
+ * have sms notification on; and have sms enabled for this particular
+ * subscription.
+ *
+ * @param Notice $notice The notice to broadcast
+ *
+ * @return success flag
+ */
 
-    # Now, get users subscribed to this profile
+function mail_broadcast_notice_sms($notice)
+{
+    // Now, get users subscribed to this profile
 
-       $user = new User();
+    $user = new User();
 
-       $user->query('SELECT nickname, smsemail, incomingemail ' .
-                                'FROM user JOIN subscription ' .
-                                'ON user.id = subscription.subscriber ' .
-                                'WHERE subscription.subscribed = ' . $notice->profile_id . ' ' .
-                                'AND user.smsemail IS NOT NULL ' .
-                                'AND user.smsnotify = 1 ' .
+    $user->query('SELECT nickname, smsemail, incomingemail ' .
+                 'FROM user JOIN subscription ' .
+                 'ON user.id = subscription.subscriber ' .
+                 'WHERE subscription.subscribed = ' . $notice->profile_id . ' ' .
+                 'AND user.smsemail IS NOT null ' .
+                 'AND user.smsnotify = 1 ' .
                  'AND subscription.sms = 1 ');
 
-       while ($user->fetch()) {
-               common_log(LOG_INFO,
-                                  'Sending notice ' . $notice->id . ' to ' . $user->smsemail,
-                                  __FILE__);
-               $success = mail_send_sms_notice_address($notice, $user->smsemail, $user->incomingemail);
-               if (!$success) {
-                       # XXX: Not sure, but I think that's the right thing to do
-                       common_log(LOG_WARNING,
-                                          'Sending notice ' . $notice->id . ' to ' . $user->smsemail . ' FAILED, cancelling.',
-                                          __FILE__);
-                       return false;
-               }
-       }
-
-       $user->free();
-       unset($user);
-
-       return true;
+    while ($user->fetch()) {
+        common_log(LOG_INFO,
+                   'Sending notice ' . $notice->id . ' to ' . $user->smsemail,
+                   __FILE__);
+        $success = mail_send_sms_notice_address($notice,
+                                                $user->smsemail,
+                                                $user->incomingemail);
+        if (!$success) {
+            // XXX: Not sure, but I think that's the right thing to do
+            common_log(LOG_WARNING,
+                       'Sending notice ' . $notice->id . ' to ' .
+                       $user->smsemail . ' FAILED, cancelling.',
+                       __FILE__);
+            return false;
+        }
+    }
+
+    $user->free();
+    unset($user);
+
+    return true;
 }
 
-function mail_send_sms_notice($notice, $user) {
-       return mail_send_sms_notice_address($notice, $user->smsemail, $user->incomingemail);
+/**
+ * send a notice to a user via SMS
+ *
+ * A convenience wrapper around mail_send_sms_notice_address()
+ *
+ * @param Notice $notice notice to send
+ * @param User   $user   user to receive notice
+ *
+ * @see mail_send_sms_notice_address()
+ *
+ * @return boolean success flag
+ */
+
+function mail_send_sms_notice($notice, $user)
+{
+    return mail_send_sms_notice_address($notice,
+                                        $user->smsemail,
+                                        $user->incomingemail);
 }
 
-function mail_send_sms_notice_address($notice, $smsemail, $incomingemail) {
+/**
+ * send a notice to an SMS email address from a given address
+ *
+ * We use the user's incoming email address as the "From" address to make
+ * replying to notices easier.
+ *
+ * @param Notice $notice        notice to send
+ * @param string $smsemail      email address to send to
+ * @param string $incomingemail email address to set as 'from'
+ *
+ * @return boolean success flag
+ */
+
+function mail_send_sms_notice_address($notice, $smsemail, $incomingemail)
+{
+    $to = $nickname . ' <' . $smsemail . '>';
 
-       $to = $nickname . ' <' . $smsemail . '>';
-       $other = $notice->getProfile();
+    $other = $notice->getProfile();
 
-       common_log(LOG_INFO, "Sending notice " . $notice->id . " to " . $smsemail, __FILE__);
+    common_log(LOG_INFO, 'Sending notice ' . $notice->id .
+               ' to ' . $smsemail, __FILE__);
 
-       $headers = array();
-       $headers['From'] = (isset($incomingemail)) ? $incomingemail : mail_notify_from();
-       $headers['To'] = $to;
-       $headers['Subject'] = sprintf(_('%s status'),
-                                                                 $other->getBestName());
-       $body = $notice->content;
+    $headers = array();
 
-       return mail_send($smsemail, $headers, $body);
+    $headers['From']    = ($incomingemail) ? $incomingemail : mail_notify_from();
+    $headers['To']      = $to;
+    $headers['Subject'] = sprintf(_('%s status'),
+                                  $other->getBestName());
+
+    $body = $notice->content;
+
+    return mail_send($smsemail, $headers, $body);
 }
 
-function mail_confirm_sms($code, $nickname, $address) {
+/**
+ * send a message to confirm a claim for an SMS number
+ *
+ * @param string $code     confirmation code
+ * @param string $nickname nickname of user claiming number
+ * @param string $address  email address to send the confirmation to
+ *
+ * @see common_confirmation_code()
+ *
+ * @return void
+ */
+
+function mail_confirm_sms($code, $nickname, $address)
+{
+    $recipients = $address;
 
-       $recipients = $address;
+    $headers['From']    = mail_notify_from();
+    $headers['To']      = $nickname . ' <' . $address . '>';
+    $headers['Subject'] = _('SMS confirmation');
 
-       $headers['From'] = mail_notify_from();
-       $headers['To'] = $nickname . ' <' . $address . '>';
-       $headers['Subject'] = _('SMS confirmation');
+    // FIXME: I18N
 
-       $body = "$nickname: confirm you own this phone number with this code:";
-       $body .= "\n\n";
-       $body .= $code;
-       $body .= "\n\n";
+    $body  = "$nickname: confirm you own this phone number with this code:";
+    $body .= "\n\n";
+    $body .= $code;
+    $body .= "\n\n";
 
-       mail_send($recipients, $headers, $body);
+    mail_send($recipients, $headers, $body);
 }
 
-function mail_notify_nudge($from, $to) {
+/**
+ * send a mail message to notify a user of a 'nudge'
+ *
+ * @param User $from user nudging
+ * @param User $to   user being nudged
+ *
+ * @return boolean success flag
+ */
+
+function mail_notify_nudge($from, $to)
+{
     common_init_locale($to->language);
-       $subject = sprintf(_('You\'ve been nudged by %s'), $from->nickname);
-
-       $from_profile = $from->getProfile();
-
-       $body = sprintf(_("%1\$s (%2\$s) is wondering what you are up to these days and is inviting you to post some news.\n\n".
-                                         "So let's hear from you :)\n\n".
-                                         "%3\$s\n\n".
-                                         "Don't reply to this email; it won't get to them.\n\n".
-                                         "With kind regards,\n".
-                                         "%4\$s\n"),
-                                       $from_profile->getBestName(),
-                                       $from->nickname,
-                                       common_local_url('all', array('nickname' => $to->nickname)),
-                                       common_config('site', 'name'));
+    $subject = sprintf(_('You\'ve been nudged by %s'), $from->nickname);
+
+    $from_profile = $from->getProfile();
+
+    $body = sprintf(_("%1\$s (%2\$s) is wondering what you are up to ".
+                      "these days and is inviting you to post some news.\n\n".
+                      "So let's hear from you :)\n\n".
+                      "%3\$s\n\n".
+                      "Don't reply to this email; it won't get to them.\n\n".
+                      "With kind regards,\n".
+                      "%4\$s\n"),
+                    $from_profile->getBestName(),
+                    $from->nickname,
+                    common_local_url('all', array('nickname' => $to->nickname)),
+                    common_config('site', 'name'));
     common_init_locale();
-       return mail_to_user($to, $subject, $body);
+    return mail_to_user($to, $subject, $body);
 }
 
-function mail_notify_message($message, $from=NULL, $to=NULL) {
+/**
+ * send a message to notify a user of a direct message (DM)
+ *
+ * This function checks to see if the recipient wants notification
+ * of DMs and has a configured email address.
+ *
+ * @param Message $message message to notify about
+ * @param User    $from    user sending message; default to sender
+ * @param User    $to      user receiving message; default to recipient
+ *
+ * @return boolean success code
+ */
 
-       if (is_null($from)) {
-               $from = User::staticGet('id', $message->from_profile);
-       }
+function mail_notify_message($message, $from=null, $to=null)
+{
+    if (is_null($from)) {
+        $from = User::staticGet('id', $message->from_profile);
+    }
 
-       if (is_null($to)) {
-               $to = User::staticGet('id', $message->to_profile);
-       }
+    if (is_null($to)) {
+        $to = User::staticGet('id', $message->to_profile);
+    }
 
-       if (is_null($to->email) || !$to->emailnotifymsg) {
-               return true;
-       }
+    if (is_null($to->email) || !$to->emailnotifymsg) {
+        return true;
+    }
 
     common_init_locale($to->language);
-       $subject = sprintf(_('New private message from %s'), $from->nickname);
-
-       $from_profile = $from->getProfile();
-
-       $body = sprintf(_("%1\$s (%2\$s) sent you a private message:\n\n".
-                                         "------------------------------------------------------\n".
-                                         "%3\$s\n".
-                                         "------------------------------------------------------\n\n".
-                                         "You can reply to their message here:\n\n".
-                                         "%4\$s\n\n".
-                                         "Don't reply to this email; it won't get to them.\n\n".
-                                         "With kind regards,\n".
-                                         "%5\$s\n"),
-                                       $from_profile->getBestName(),
-                                       $from->nickname,
-                                       $message->content,
-                                       common_local_url('newmessage', array('to' => $from->id)),
-                                       common_config('site', 'name'));
+    $subject = sprintf(_('New private message from %s'), $from->nickname);
+
+    $from_profile = $from->getProfile();
+
+    $body = sprintf(_("%1\$s (%2\$s) sent you a private message:\n\n".
+                      "------------------------------------------------------\n".
+                      "%3\$s\n".
+                      "------------------------------------------------------\n\n".
+                      "You can reply to their message here:\n\n".
+                      "%4\$s\n\n".
+                      "Don't reply to this email; it won't get to them.\n\n".
+                      "With kind regards,\n".
+                      "%5\$s\n"),
+                    $from_profile->getBestName(),
+                    $from->nickname,
+                    $message->content,
+                    common_local_url('newmessage', array('to' => $from->id)),
+                    common_config('site', 'name'));
 
     common_init_locale();
-       return mail_to_user($to, $subject, $body);
+    return mail_to_user($to, $subject, $body);
 }
 
-function mail_notify_fave($other, $user, $notice) {
+/**
+ * notify a user that one of their notices has been chosen as a 'fave'
+ *
+ * Doesn't check that the user has an email address nor if they
+ * want to receive notification of faves. Maybe this happens higher
+ * up the stack...?
+ *
+ * @param User   $other  The user whose notice was faved
+ * @param User   $user   The user who faved the notice
+ * @param Notice $notice The notice that was faved
+ *
+ * @return void
+ */
+
+function mail_notify_fave($other, $user, $notice)
+{
+    $profile = $user->getProfile();
+
+    $bestname = $profile->getBestName();
 
-       $profile = $user->getProfile();
-       $bestname = $profile->getBestName();
     common_init_locale($other->language);
-       $subject = sprintf(_('%s added your notice as a favorite'), $bestname);
-       $body = sprintf(_("%1\$s just added your notice from %2\$s as one of their favorites.\n\n" .
-                                         "In case you forgot, you can see the text of your notice here:\n\n" .
-                                         "%3\$s\n\n" .
-                                         "You can see the list of %1\$s's favorites here:\n\n" .
-                                         "%4\$s\n\n" .
-                                         "Faithfully yours,\n" .
-                                         "%5\$s\n"),
-                                       $bestname,
-                                       common_exact_date($notice->created),
-                                       common_local_url('shownotice', array('notice' => $notice->id)),
-                                       common_local_url('showfavorites', array('nickname' => $user->nickname)),
-                                       common_config('site', 'name'));
+
+    $subject = sprintf(_('%s added your notice as a favorite'), $bestname);
+
+    $body = sprintf(_("%1\$s just added your notice from %2\$s".
+                      " as one of their favorites.\n\n" .
+                      "In case you forgot, you can see the text".
+                      " of your notice here:\n\n" .
+                      "%3\$s\n\n" .
+                      "You can see the list of %1\$s's favorites here:\n\n" .
+                      "%4\$s\n\n" .
+                      "Faithfully yours,\n" .
+                      "%5\$s\n"),
+                    $bestname,
+                    common_exact_date($notice->created),
+                    common_local_url('shownotice',
+                                     array('notice' => $notice->id)),
+                    common_local_url('showfavorites',
+                                     array('nickname' => $user->nickname)),
+                    common_config('site', 'name'));
 
     common_init_locale();
-       mail_to_user($other, $subject, $body);
+    mail_to_user($other, $subject, $body);
 }
index 4ed8d17582a6d53d40f71f902a8676a09c88f853..bdc360a35325f485a5bc9f7117bb8607dfde2f67 100644 (file)
@@ -1,9 +1,12 @@
 <?php
-/*
- * Laconica - a distributed open-source microblogging tool
- * Copyright (C) 2008, Controlez-Vous, Inc.
+/**
+ * Laconica, the distributed open-source microblogging tool
  *
- * This program is free software: you can redistribute it and/or modify
+ * common superclass for direct messages inbox and outbox
+ *
+ * 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.
  *
  * 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  Message
+ * @package   Laconica
+ * @author    Evan Prodromou <evan@controlyourself.ca>
+ * @copyright 2008 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); }
+if (!defined('LACONICA')) {
+    exit(1);
+}
 
-require_once(INSTALLDIR.'/lib/personal.php');
+require_once INSTALLDIR.'/lib/personal.php';
 
 define('MESSAGES_PER_PAGE', 20);
 
-class MailboxAction extends PersonalAction {
-       
-       function handle($args) {
-
-               parent::handle($args);
-
-               $nickname = common_canonical_nickname($this->arg('nickname'));
-               $user = User::staticGet('nickname', $nickname);
-
-               if (!$user) {
-                       $this->client_error(_('No such user.'), 404);
-                       return;
-               }
-
-               $cur = common_current_user();
-               
-               if (!$cur || $cur->id != $user->id) {
-                       $this->client_error(_('Only the user can read their own mailboxes.'), 403);
-                       return;
-               }
-               
-               $profile = $user->getProfile();
-
-               if (!$profile) {
-                       $this->server_error(_('User has no profile.'));
-                       return;
-               }
-
-               $page = $this->trimmed('page');
-               
-               if (!$page) {
-                       $page = 1;
-               }
-               
-               $this->show_page($user, $page);
-       }
-
-       function get_title($user, $page) {
-               return '';
-       }
-
-       function get_instructions() {
-               return '';
-       }
-
-       function show_top() {
-
-               $cur = common_current_user();
-               
-               common_message_form(NULL, $cur, NULL);
-               
-               $this->views_menu();
-       }
-       
-       function show_page($user, $page) {
-
-               common_show_header($this->get_title($user, $page),
-                                                  NULL, NULL,
-                                                  array($this, 'show_top'));
-               
-               $this->show_box($user, $page);
-               
-               common_show_footer();
-       }
-       
-       function show_box($user, $page) {
-               
-               $message = $this->get_messages($user, $page);
-               
-               if ($message) {
-                       
-                       $cnt = 0;
-                       common_element_start('ul', array('id' => 'messages'));
-               
-                       while ($message->fetch() && $cnt <= MESSAGES_PER_PAGE) {
-                               $cnt++;
-                               
-                               if ($cnt > MESSAGES_PER_PAGE) {
-                                       break;
-                               }
-                               
-                               $this->show_message($message);
-                       }
-
-                       common_element_end('ul');
-                       
-                       common_pagination($page > 1, $cnt > MESSAGES_PER_PAGE,
-                                                         $page, $this->trimmed('action'),
-                                                         array('nickname' => $user->nickname));
-                       
-                       $message->free();
-                       unset($message);
-               }
-       }
-
-       # returns the profile we want to show with the message
-       
-       function get_message_profile($message) {
-               return NULL;
-       }
-       
-       function show_message($message) {
-
-               common_element_start('li', array('class' => 'message_single',
-                                                                                 'id' => 'message-' . $message->id));
-
-               $profile = $this->get_message_profile($message);
-               
-               $avatar = $profile->getAvatar(AVATAR_STREAM_SIZE);
-               common_element_start('a', array('href' => $profile->profileurl));
-               common_element('img', array('src' => ($avatar) ? common_avatar_display_url($avatar) : common_default_avatar(AVATAR_STREAM_SIZE),
-                                                                       'class' => 'avatar stream',
-                                                                       'width' => AVATAR_STREAM_SIZE,
-                                                                       'height' => AVATAR_STREAM_SIZE,
-                                                                       'alt' =>
-                                                                       ($profile->fullname) ? $profile->fullname :
-                                                                       $profile->nickname));
-               common_element_end('a');
-               common_element('a', array('href' => $profile->profileurl,
-                                                                 'class' => 'nickname'),
-                                          $profile->nickname);
-               # FIXME: URL, image, video, audio
-               common_element_start('p', array('class' => 'content'));
-               common_raw($message->rendered);
-               common_element_end('p');
-               
-               $messageurl = common_local_url('showmessage', array('message' => $message->id));
-               
-               # XXX: we need to figure this out better. Is this right?
-               if (strcmp($message->uri, $messageurl) != 0 && preg_match('/^http/', $message->uri)) {
-                       $messageurl = $message->uri;
-               }
-               common_element_start('p', 'time');
-               common_element('a', array('class' => 'permalink',
-                                                                 'href' => $messageurl,
-                                                                 'title' => common_exact_date($message->created)),
-                                          common_date_string($message->created));
-               if ($message->source) {
-                       common_text(_(' from '));
-                       $this->source_link($message->source);
-               }
-               
-               common_element_end('p');
-               
-               common_element_end('li');
-       }
+/**
+ * common superclass for direct messages inbox and outbox
+ *
+ * @category Message
+ * @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/
+ * @see      InboxAction
+ * @see      OutboxAction
+ */
+
+class MailboxAction extends PersonalAction
+{
+    /**
+     * output page based on arguments
+     *
+     * @param array $args HTTP arguments (from $_REQUEST)
+     *
+     * @return void
+     */
+
+    function handle($args)
+    {
+        parent::handle($args);
+
+        $nickname = common_canonical_nickname($this->arg('nickname'));
+
+        $user = User::staticGet('nickname', $nickname);
+
+        if (!$user) {
+            $this->client_error(_('No such user.'), 404);
+            return;
+        }
+
+        $cur = common_current_user();
+
+        if (!$cur || $cur->id != $user->id) {
+            $this->client_error(_('Only the user can read their own mailboxes.'),
+                                403);
+            return;
+        }
+
+        $profile = $user->getProfile();
+
+        if (!$profile) {
+            $this->server_error(_('User has no profile.'));
+            return;
+        }
+
+        $page = $this->trimmed('page');
+
+        if (!$page) {
+            $page = 1;
+        }
+
+        $this->showPage($user, $page);
+    }
+
+    /**
+     * returns the title of the page
+     *
+     * @param User $user current user
+     * @param int  $page current page
+     *
+     * @return string localised title of the page
+     */
+
+    function getTitle($user, $page)
+    {
+        return '';
+    }
+
+    /**
+     * instructions for using this page
+     *
+     * @return string localised instructions for using the page
+     */
+
+    function getInstructions()
+    {
+        return '';
+    }
+
+    /**
+     * do structured output for the "instructions" are of the page
+     *
+     * @return void
+     */
+
+    function showTop()
+    {
+        $cur = common_current_user();
+
+        common_message_form(null, $cur, null);
+
+        $this->views_menu();
+    }
+
+    /**
+     * show a full page of output
+     *
+     * @param User $user The current user
+     * @param int  $page The page the user is on
+     *
+     * @return void
+     */
+
+    function showPage($user, $page)
+    {
+        common_show_header($this->getTitle($user, $page),
+                           null, null,
+                           array($this, 'showTop'));
+
+        $this->showBox($user, $page);
+
+        common_show_footer();
+    }
+
+    /**
+     * retrieve the messages appropriate for this mailbox
+     *
+     * Does a query for the right messages
+     *
+     * @param User $user The current user
+     * @param int  $page The page the user is on
+     *
+     * @return Message data object with stream for messages
+     */
+
+    function getMessages($user, $page)
+    {
+        return null;
+    }
+
+    /**
+     * show the messages for a mailbox in list format
+     *
+     * Includes the pagination links (before, after).
+     *
+     * @param User $user The current user
+     * @param int  $page The page the user is on
+     *
+     * @return void
+     */
+
+    function showBox($user, $page)
+    {
+        $message = $this->getMessages($user, $page);
+
+        if ($message) {
+
+            $cnt = 0;
+            common_element_start('ul', array('id' => 'messages'));
+
+            while ($message->fetch() && $cnt <= MESSAGES_PER_PAGE) {
+                $cnt++;
+
+                if ($cnt > MESSAGES_PER_PAGE) {
+                    break;
+                }
+
+                $this->showMessage($message);
+            }
+
+            common_element_end('ul');
+
+            common_pagination($page > 1, $cnt > MESSAGES_PER_PAGE,
+                              $page, $this->trimmed('action'),
+                              array('nickname' => $user->nickname));
+
+            $message->free();
+            unset($message);
+        }
+    }
+
+    /**
+     * returns the profile we want to show with the message
+     *
+     * For inboxes, we show the sender; for outboxes, the recipient.
+     *
+     * @param Message $message The message to get the profile for
+     *
+     * @return Profile The profile that matches the message
+     */
+
+    function getMessageProfile($message)
+    {
+        return null;
+    }
+
+    /**
+     * show a single message in the list format
+     *
+     * @param Message $message the message to show
+     *
+     * @return void
+     */
+
+    function showMessage($message)
+    {
+        common_element_start('li', array('class' => 'message_single',
+                                         'id' => 'message-' . $message->id));
+
+        $profile = $this->getMessageProfile($message);
+
+        $avatar = $profile->getAvatar(AVATAR_STREAM_SIZE);
+        common_element_start('a', array('href' => $profile->profileurl));
+        common_element('img', array('src' => ($avatar) ?
+                                    common_avatar_display_url($avatar) :
+                                    common_default_avatar(AVATAR_STREAM_SIZE),
+                                    'class' => 'avatar stream',
+                                    'width' => AVATAR_STREAM_SIZE,
+                                    'height' => AVATAR_STREAM_SIZE,
+                                    'alt' =>
+                                    ($profile->fullname) ? $profile->fullname :
+                                    $profile->nickname));
+        common_element_end('a');
+        common_element('a', array('href' => $profile->profileurl,
+                                  'class' => 'nickname'),
+                       $profile->nickname);
+        // FIXME: URL, image, video, audio
+        common_element_start('p', array('class' => 'content'));
+        common_raw($message->rendered);
+        common_element_end('p');
+
+        $messageurl = common_local_url('showmessage',
+                                       array('message' => $message->id));
+
+        // XXX: we need to figure this out better. Is this right?
+        if (strcmp($message->uri, $messageurl) != 0 &&
+            preg_match('/^http/', $message->uri)) {
+            $messageurl = $message->uri;
+        }
+        common_element_start('p', 'time');
+        common_element('a', array('class' => 'permalink',
+                                  'href' => $messageurl,
+                                  'title' => common_exact_date($message->created)),
+                       common_date_string($message->created));
+        if ($message->source) {
+            common_text(_(' from '));
+            $this->source_link($message->source);
+        }
+
+        common_element_end('p');
+
+        common_element_end('li');
+    }
 }
index 415c062e4675e3d11bd78ba72887df61b7c78598..71db067d08e0e7cf842180f23aa7f885b5ca92d2 100644 (file)
 <?php
-/*
- * Laconica - a distributed open-source microblogging tool
- * Copyright (C) 2008, Controlez-Vous, Inc.
+/**
+ * Laconica, the distributed open-source microblogging tool
  *
- * This program is free software: you can redistribute it and/or modify
+ * widget for displaying a list 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
+ * 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/>.
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * @category  UI
+ * @package   Laconica
+ * @author    Evan Prodromou <evan@controlyourself.ca>
+ * @copyright 2008 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); }
+if (!defined('LACONICA')) {
+    exit(1);
+}
+
+/**
+ * widget for displaying a list of notices
+ *
+ * There are a number of actions that display a list of notices, in
+ * reverse chronological order. This widget abstracts out most of the
+ * code for UI for notice lists. It's overridden to hide some
+ * data for e.g. the profile page.
+ *
+ * @category UI
+ * @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/
+ * @see      Notice
+ * @see      StreamAction
+ * @see      NoticeListItem
+ * @see      ProfileNoticeList
+ */
 
-class NoticeList {
+class NoticeList
+{
+    /** the current stream of notices being displayed. */
 
-    var $notice = NULL;
+    var $notice = null;
 
-    function __construct($notice) {
+    /**
+     * constructor
+     *
+     * @param Notice $notice stream of notices from DB_DataObject
+     */
+
+    function __construct($notice)
+    {
         $this->notice = $notice;
     }
 
-    function show() {
+    /**
+     * show the list of notices
+     *
+     * "Uses up" the stream by looping through it. So, probably can't
+     * be called twice on the same list.
+     *
+     * @return int count of notices listed.
+     */
 
-               common_element_start('ul', array('id' => 'notices'));
+    function show()
+    {
+        common_element_start('ul', array('id' => 'notices'));
 
-               $cnt = 0;
+        $cnt = 0;
 
-               while ($this->notice->fetch() && $cnt <= NOTICES_PER_PAGE) {
-                       $cnt++;
+        while ($this->notice->fetch() && $cnt <= NOTICES_PER_PAGE) {
+            $cnt++;
 
-                       if ($cnt > NOTICES_PER_PAGE) {
-                               break;
-                       }
+            if ($cnt > NOTICES_PER_PAGE) {
+                break;
+            }
 
-            $item = $this->new_list_item($this->notice);
+            $item = $this->newListItem($this->notice);
             $item->show();
-               }
+        }
 
-               common_element_end('ul');
+        common_element_end('ul');
 
         return $cnt;
-       }
+    }
 
-    function new_list_item($notice) {
+    /**
+     * returns a new list item for the current notice
+     *
+     * Recipe (factory?) method; overridden by sub-classes to give
+     * a different list item class.
+     *
+     * @param Notice $notice the current notice
+     *
+     * @return NoticeListItem a list item for displaying the notice
+     */
+
+    function newListItem($notice)
+    {
         return new NoticeListItem($notice);
     }
 }
 
-class NoticeListItem {
+/**
+ * widget for displaying a single notice
+ *
+ * This widget has the core smarts for showing a single notice: what to display,
+ * where, and under which circumstances. Its key method is show(); this is a recipe
+ * that calls all the other show*() methods to build up a single notice. The
+ * ProfileNoticeListItem subclass, for example, overrides showAuthor() to skip
+ * author info (since that's implicit by the data in the page).
+ *
+ * @category UI
+ * @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/
+ * @see      NoticeList
+ * @see      ProfileNoticeListItem
+ */
+
+class NoticeListItem
+{
+    /** The notice this item will show. */
 
-    var $notice = NULL;
-    var $profile = NULL;
+    var $notice = null;
 
-    function __construct($notice) {
-        $this->notice = $notice;
-               $this->profile = $notice->getProfile();
-    }
-
-       function show() {
-        $this->show_start();
-        $this->show_fave_form();
-        $this->show_author();
-        $this->show_content();
-        $this->show_start_time_section();
-        $this->show_notice_link();
-        $this->show_notice_source();
-        $this->show_reply_to();
-        $this->show_reply_link();
-        $this->show_delete_link();
-        $this->show_end_time_section();
-        $this->show_end();
-       }
-
-    function show_start() {
-               # XXX: RDFa
-               common_element_start('li', array('class' => 'notice_single hentry',
-                                                                                 'id' => 'notice-' . $this->notice->id));
-    }
-
-    function show_fave_form() {
+    /** The profile of the author of the notice, extracted once for convenience. */
+
+    var $profile = null;
+
+    /**
+     * constructor
+     *
+     * Also initializes the profile attribute.
+     *
+     * @param Notice $notice The notice we'll display
+     */
+
+    function __construct($notice)
+    {
+        $this->notice  = $notice;
+        $this->profile = $notice->getProfile();
+    }
+
+    /**
+     * recipe function for displaying a single notice.
+     *
+     * This uses all the other methods to correctly display a notice. Override
+     * it or one of the others to fine-tune the output.
+     *
+     * @return void
+     */
+
+    function show()
+    {
+        $this->showStart();
+        $this->showFaveForm();
+        $this->showAuthor();
+        $this->showContent();
+        $this->startTimeSection();
+        $this->showNoticeLink();
+        $this->showNoticeSource();
+        $this->showReplyTo();
+        $this->showReplyLink();
+        $this->showDeleteLink();
+        $this->endTimeSection();
+        $this->showEnd();
+    }
+
+    /**
+     * start a single notice.
+     *
+     * @return void
+     */
+
+    function showStart()
+    {
+        // XXX: RDFa
+        common_element_start('li', array('class' => 'notice_single hentry',
+                                         'id' => 'notice-' . $this->notice->id));
+    }
+
+    /**
+     * show the "favorite" form
+     *
+     * @return void
+     */
+
+    function showFaveForm()
+    {
         $user = common_current_user();
-               if ($user) {
-                       if ($user->hasFave($this->notice)) {
-                               common_disfavor_form($this->notice);
-                       } else {
-                               common_favor_form($this->notice);
-                       }
-               }
-    }
-
-    function show_author() {
-               common_element_start('span', 'vcard author');
-        $this->show_avatar();
-        $this->show_nickname();
-               common_element_end('span');
-    }
-
-    function show_avatar() {
-               $avatar = $this->profile->getAvatar(AVATAR_STREAM_SIZE);
-               common_element_start('a', array('href' => $this->profile->profileurl));
-               common_element('img', array('src' => ($avatar) ? common_avatar_display_url($avatar) : common_default_avatar(AVATAR_STREAM_SIZE),
-                                                                       'class' => 'avatar stream photo',
-                                                                       'width' => AVATAR_STREAM_SIZE,
-                                                                       'height' => AVATAR_STREAM_SIZE,
-                                                                       'alt' =>
-                                                                       ($this->profile->fullname) ? $this->profile->fullname :
-                                                                       $this->profile->nickname));
-               common_element_end('a');
-    }
-
-    function show_nickname() {
-               common_element('a', array('href' => $this->profile->profileurl,
-                                                                 'class' => 'nickname fn url'),
-                                          $this->profile->nickname);
-    }
-
-    function show_content() {
-               # FIXME: URL, image, video, audio
-               common_element_start('p', array('class' => 'content entry-title'));
-               if ($this->notice->rendered) {
-                       common_raw($this->notice->rendered);
-               } else {
-                       # XXX: may be some uncooked notices in the DB,
-                       # we cook them right now. This should probably disappear in future
-                       # versions (>> 0.4.x)
-                       common_raw(common_render_content($this->notice->content, $this->notice));
-               }
-               common_element_end('p');
-    }
-
-    function show_start_time_section() {
-               common_element_start('p', 'time');
-    }
-
-    function show_notice_link() {
-               $noticeurl = common_local_url('shownotice', array('notice' => $this->notice->id));
-               # XXX: we need to figure this out better. Is this right?
-               if (strcmp($this->notice->uri, $noticeurl) != 0 && preg_match('/^http/', $this->notice->uri)) {
-                       $noticeurl = $this->notice->uri;
-               }
-               common_element_start('a', array('class' => 'permalink',
-                                                                 'rel' => 'bookmark',
-                                                                 'href' => $noticeurl));
-               common_element('abbr', array('class' => 'published',
-                                                                        'title' => common_date_iso8601($this->notice->created)),
-                                               common_date_string($this->notice->created));
-               common_element_end('a');
-    }
-
-    function show_notice_source() {
-               if ($this->notice->source) {
-                       common_element('span', null, _(' from '));
+        if ($user) {
+            if ($user->hasFave($this->notice)) {
+                common_disfavor_form($this->notice);
+            } else {
+                common_favor_form($this->notice);
+            }
+        }
+    }
+
+    /**
+     * show the author of a notice
+     *
+     * By default, this shows the avatar and (linked) nickname of the author.
+     *
+     * @return void
+     */
+
+    function showAuthor()
+    {
+        common_element_start('span', 'vcard author');
+        $this->showAvatar();
+        $this->showNickname();
+        common_element_end('span');
+    }
+
+    /**
+     * show the avatar of the notice's author
+     *
+     * This will use the default avatar if no avatar is assigned for the author.
+     * It makes a link to the author's profile.
+     *
+     * @return void
+     */
+
+    function showAvatar()
+    {
+        $avatar = $this->profile->getAvatar(AVATAR_STREAM_SIZE);
+        common_element_start('a', array('href' => $this->profile->profileurl));
+        common_element('img', array('src' => ($avatar) ?
+                                    common_avatar_display_url($avatar) :
+                                    common_default_avatar(AVATAR_STREAM_SIZE),
+                                    'class' => 'avatar stream photo',
+                                    'width' => AVATAR_STREAM_SIZE,
+                                    'height' => AVATAR_STREAM_SIZE,
+                                    'alt' =>
+                                    ($this->profile->fullname) ?
+                                    $this->profile->fullname :
+                                    $this->profile->nickname));
+        common_element_end('a');
+    }
+
+    /**
+     * show the nickname of the author
+     *
+     * Links to the author's profile page
+     *
+     * @return void
+     */
+
+    function showNickname()
+    {
+        common_element('a', array('href' => $this->profile->profileurl,
+                                  'class' => 'nickname fn url'),
+                       $this->profile->nickname);
+    }
+
+    /**
+     * show the content of the notice
+     *
+     * Shows the content of the notice. This is pre-rendered for efficiency
+     * at save time. Some very old notices might not be pre-rendered, so
+     * they're rendered on the spot.
+     *
+     * @return void
+     */
+
+    function showContent()
+    {
+        // FIXME: URL, image, video, audio
+        common_element_start('p', array('class' => 'content entry-title'));
+        if ($this->notice->rendered) {
+            common_raw($this->notice->rendered);
+        } else {
+            // XXX: may be some uncooked notices in the DB,
+            // we cook them right now. This should probably disappear in future
+            // versions (>> 0.4.x)
+            common_raw(common_render_content($this->notice->content, $this->notice));
+        }
+        common_element_end('p');
+    }
+
+    /**
+     * show the "time" section of a notice
+     *
+     * This is the greyed-out section that appears beneath the content, including
+     * links to delete or reply to the notice. Probably should be called something
+     * else.
+     *
+     * @return void
+     */
+
+    function startTimeSection()
+    {
+        common_element_start('p', 'time');
+    }
+
+    /**
+     * show the link to the main page for the notice
+     *
+     * Displays a link to the page for a notice, with "relative" time. Tries to
+     * get remote notice URLs correct, but doesn't always succeed.
+     *
+     * @return void
+     */
+
+    function showNoticeLink()
+    {
+        $noticeurl = common_local_url('shownotice',
+                                      array('notice' => $this->notice->id));
+        // XXX: we need to figure this out better. Is this right?
+        if (strcmp($this->notice->uri, $noticeurl) != 0 &&
+            preg_match('/^http/', $this->notice->uri)) {
+            $noticeurl = $this->notice->uri;
+        }
+        common_element_start('a', array('class' => 'permalink',
+                                        'rel' => 'bookmark',
+                                        'href' => $noticeurl));
+        $dt = common_date_iso8601($this->notice->created);
+        common_element('abbr', array('class' => 'published',
+                                     'title' => $dt),
+                       common_date_string($this->notice->created));
+        common_element_end('a');
+    }
+
+    /**
+     * Show the source of the notice
+     *
+     * Either the name (and link) of the API client that posted the notice,
+     * or one of other other channels.
+     *
+     * @return void
+     */
+
+    function showNoticeSource()
+    {
+        if ($this->notice->source) {
+            common_element('span', null, _(' from '));
             $source_name = _($this->notice->source);
             switch ($this->notice->source) {
-             case 'web':
-             case 'xmpp':
-             case 'mail':
-             case 'omb':
-             case 'api':
+            case 'web':
+            case 'xmpp':
+            case 'mail':
+            case 'omb':
+            case 'api':
                 common_element('span', 'noticesource', $source_name);
                 break;
-             default:
+            default:
                 $ns = Notice_source::staticGet($this->notice->source);
                 if ($ns) {
                     common_element('a', array('href' => $ns->url),
@@ -177,48 +370,98 @@ class NoticeListItem {
                 }
                 break;
             }
-               }
+        }
     }
 
-    function show_reply_to() {
-               if ($this->notice->reply_to) {
-                       $replyurl = common_local_url('shownotice', array('notice' => $this->notice->reply_to));
-                       common_text(' (');
-                       common_element('a', array('class' => 'inreplyto',
-                                                                         'href' => $replyurl),
-                                                  _('in reply to...'));
-                       common_text(')');
-               }
+    /**
+     * show link to notice this notice is a reply to
+     *
+     * If this notice is a reply, show a link to the notice it is replying to. The
+     * heavy lifting for figuring out replies happens at save time.
+     *
+     * @return void
+     */
+
+    function showReplyTo()
+    {
+        if ($this->notice->reply_to) {
+            $replyurl = common_local_url('shownotice',
+                                         array('notice' => $this->notice->reply_to));
+            common_text(' (');
+            common_element('a', array('class' => 'inreplyto',
+                                      'href' => $replyurl),
+                           _('in reply to...'));
+            common_text(')');
+        }
     }
 
-    function show_reply_link() {
-               common_element_start('a',
-                                                        array('href' => common_local_url('newnotice',
-                                                                                                                         array('replyto' => $this->profile->nickname)),
-                                                                  'onclick' => 'return doreply("'.$this->profile->nickname.'", '.$this->notice->id.');',
-                                                                  'title' => _('reply'),
-                                                                  'class' => 'replybutton'));
-               common_raw(' &#8594;');
-               common_element_end('a');
+    /**
+     * show a link to reply to the current notice
+     *
+     * Should either do the reply in the current notice form (if available), or
+     * link out to the notice-posting form. A little flakey, doesn't always work.
+     *
+     * @return void
+     */
+
+    function showReplyLink()
+    {
+        $reply_url = common_local_url('newnotice',
+                                      array('replyto' => $this->profile->nickname));
+
+        $reply_js =
+          'return doreply("'.$this->profile->nickname.'",'.$this->notice->id.');';
+
+        common_element_start('a',
+                             array('href' => $reply_url,
+                                   'onclick' => $reply_js,
+                                   'title' => _('reply'),
+                                   'class' => 'replybutton'));
+        common_raw(' &#8594;');
+        common_element_end('a');
     }
 
-    function show_delete_link() {
+    /**
+     * if the user is the author, let them delete the notice
+     *
+     * @return void
+     */
+
+    function showDeleteLink()
+    {
         $user = common_current_user();
-               if ($user && $this->notice->profile_id == $user->id) {
-                       $deleteurl = common_local_url('deletenotice', array('notice' => $this->notice->id));
-                       common_element_start('a', array('class' => 'deletenotice',
-                                                                                       'href' => $deleteurl,
-                                                                                       'title' => _('delete')));
-                       common_raw(' &#215;');
-                       common_element_end('a');
-               }
+        if ($user && $this->notice->profile_id == $user->id) {
+            $deleteurl = common_local_url('deletenotice',
+                                          array('notice' => $this->notice->id));
+            common_element_start('a', array('class' => 'deletenotice',
+                                            'href' => $deleteurl,
+                                            'title' => _('delete')));
+            common_raw(' &#215;');
+            common_element_end('a');
+        }
     }
 
-    function show_end_time_section() {
-               common_element_end('p');
+    /**
+     * end the time section
+     *
+     * @return void
+     */
+
+    function endTimeSection()
+    {
+        common_element_end('p');
     }
 
-    function show_end() {
-               common_element_end('li');
+    /**
+     * finish the notice
+     *
+     * Close the last elements in the notice list item
+     *
+     * @return void
+     */
+
+    function showEnd()
+    {
+        common_element_end('li');
     }
 }
index d7f9c9ff1b91b9959aafa8365612ce09fb15e022..7ad3be20e2ac318517b5b150e974de7a32633546 100644 (file)
@@ -21,124 +21,132 @@ if (!defined('LACONICA')) { exit(1); }
 
 require_once(INSTALLDIR.'/lib/omb.php');
 
-class LaconicaOAuthDataStore extends OAuthDataStore {
+class LaconicaOAuthDataStore extends OAuthDataStore
+{
 
-       # We keep a record of who's contacted us
+    // We keep a record of who's contacted us
 
-       function lookup_consumer($consumer_key) {
-               $con = Consumer::staticGet('consumer_key', $consumer_key);
-               if (!$con) {
-                       $con = new Consumer();
-                       $con->consumer_key = $consumer_key;
-                       $con->seed = common_good_rand(16);
-                       $con->created = DB_DataObject_Cast::dateTime();
-                       if (!$con->insert()) {
-                               return NULL;
-                       }
-               }
-               return new OAuthConsumer($con->consumer_key, '');
-       }
+    function lookup_consumer($consumer_key)
+    {
+        $con = Consumer::staticGet('consumer_key', $consumer_key);
+        if (!$con) {
+            $con = new Consumer();
+            $con->consumer_key = $consumer_key;
+            $con->seed = common_good_rand(16);
+            $con->created = DB_DataObject_Cast::dateTime();
+            if (!$con->insert()) {
+                return null;
+            }
+        }
+        return new OAuthConsumer($con->consumer_key, '');
+    }
 
-       function lookup_token($consumer, $token_type, $token_key) {
-               $t = new Token();
-               $t->consumer_key = $consumer->key;
-               $t->tok = $token_key;
-               $t->type = ($token_type == 'access') ? 1 : 0;
-               if ($t->find(true)) {
-                       return new OAuthToken($t->tok, $t->secret);
-               } else {
-                       return NULL;
-               }
-       }
+    function lookup_token($consumer, $token_type, $token_key)
+    {
+        $t = new Token();
+        $t->consumer_key = $consumer->key;
+        $t->tok = $token_key;
+        $t->type = ($token_type == 'access') ? 1 : 0;
+        if ($t->find(true)) {
+            return new OAuthToken($t->tok, $t->secret);
+        } else {
+            return null;
+        }
+    }
 
-       function lookup_nonce($consumer, $token, $nonce, $timestamp) {
-               $n = new Nonce();
-               $n->consumer_key = $consumer->key;
-               $n->tok = $token->key;
-               $n->nonce = $nonce;
-               if ($n->find(TRUE)) {
-                       return TRUE;
-               } else {
-                       $n->timestamp = $timestamp;
-                       $n->created = DB_DataObject_Cast::dateTime();
-                       $n->insert();
-                       return FALSE;
-               }
-       }
+    function lookup_nonce($consumer, $token, $nonce, $timestamp)
+    {
+        $n = new Nonce();
+        $n->consumer_key = $consumer->key;
+        $n->tok = $token->key;
+        $n->nonce = $nonce;
+        if ($n->find(true)) {
+            return true;
+        } else {
+            $n->timestamp = $timestamp;
+            $n->created = DB_DataObject_Cast::dateTime();
+            $n->insert();
+            return false;
+        }
+    }
 
-       function new_request_token($consumer) {
-               $t = new Token();
-               $t->consumer_key = $consumer->key;
-               $t->tok = common_good_rand(16);
-               $t->secret = common_good_rand(16);
-               $t->type = 0; # request
-               $t->state = 0; # unauthorized
-               $t->created = DB_DataObject_Cast::dateTime();
-               if (!$t->insert()) {
-                       return NULL;
-               } else {
-                       return new OAuthToken($t->tok, $t->secret);
-               }
-       }
+    function new_request_token($consumer)
+    {
+        $t = new Token();
+        $t->consumer_key = $consumer->key;
+        $t->tok = common_good_rand(16);
+        $t->secret = common_good_rand(16);
+        $t->type = 0; // request
+        $t->state = 0; // unauthorized
+        $t->created = DB_DataObject_Cast::dateTime();
+        if (!$t->insert()) {
+            return null;
+        } else {
+            return new OAuthToken($t->tok, $t->secret);
+        }
+    }
 
-       # defined in OAuthDataStore, but not implemented anywhere
+    // defined in OAuthDataStore, but not implemented anywhere
 
-       function fetch_request_token($consumer) {
-               return $this->new_request_token($consumer);
-       }
+    function fetch_request_token($consumer)
+    {
+        return $this->new_request_token($consumer);
+    }
 
-       function new_access_token($token, $consumer) {
-               common_debug('new_access_token("'.$token->key.'","'.$consumer->key.'")', __FILE__);
-               $rt = new Token();
-               $rt->consumer_key = $consumer->key;
-               $rt->tok = $token->key;
-               $rt->type = 0; # request
-               if ($rt->find(TRUE) && $rt->state == 1) { # authorized
-                       common_debug('request token found.', __FILE__);
-                       $at = new Token();
-                       $at->consumer_key = $consumer->key;
-                       $at->tok = common_good_rand(16);
-                       $at->secret = common_good_rand(16);
-                       $at->type = 1; # access
-                       $at->created = DB_DataObject_Cast::dateTime();
-                       if (!$at->insert()) {
-                               $e = $at->_lastError;
-                               common_debug('access token "'.$at->tok.'" not inserted: "'.$e->message.'"', __FILE__);
-                               return NULL;
-                       } else {
-                               common_debug('access token "'.$at->tok.'" inserted', __FILE__);
-                               # burn the old one
-                               $orig_rt = clone($rt);
-                               $rt->state = 2; # used
-                               if (!$rt->update($orig_rt)) {
-                                       return NULL;
-                               }
-                               common_debug('request token "'.$rt->tok.'" updated', __FILE__);
-                               # Update subscription
-                               # XXX: mixing levels here
-                               $sub = Subscription::staticGet('token', $rt->tok);
-                               if (!$sub) {
-                                       return NULL;
-                               }
-                               common_debug('subscription for request token found', __FILE__);
-                               $orig_sub = clone($sub);
-                               $sub->token = $at->tok;
-                               $sub->secret = $at->secret;
-                               if (!$sub->update($orig_sub)) {
-                                       return NULL;
-                               } else {
-                                       common_debug('subscription updated to use access token', __FILE__);
-                                       return new OAuthToken($at->tok, $at->secret);
-                               }
-                       }
-               } else {
-                       return NULL;
-               }
-       }
+    function new_access_token($token, $consumer)
+    {
+        common_debug('new_access_token("'.$token->key.'","'.$consumer->key.'")', __FILE__);
+        $rt = new Token();
+        $rt->consumer_key = $consumer->key;
+        $rt->tok = $token->key;
+        $rt->type = 0; // request
+        if ($rt->find(true) && $rt->state == 1) { // authorized
+            common_debug('request token found.', __FILE__);
+            $at = new Token();
+            $at->consumer_key = $consumer->key;
+            $at->tok = common_good_rand(16);
+            $at->secret = common_good_rand(16);
+            $at->type = 1; // access
+            $at->created = DB_DataObject_Cast::dateTime();
+            if (!$at->insert()) {
+                $e = $at->_lastError;
+                common_debug('access token "'.$at->tok.'" not inserted: "'.$e->message.'"', __FILE__);
+                return null;
+            } else {
+                common_debug('access token "'.$at->tok.'" inserted', __FILE__);
+                // burn the old one
+                $orig_rt = clone($rt);
+                $rt->state = 2; // used
+                if (!$rt->update($orig_rt)) {
+                    return null;
+                }
+                common_debug('request token "'.$rt->tok.'" updated', __FILE__);
+                // Update subscription
+                // XXX: mixing levels here
+                $sub = Subscription::staticGet('token', $rt->tok);
+                if (!$sub) {
+                    return null;
+                }
+                common_debug('subscription for request token found', __FILE__);
+                $orig_sub = clone($sub);
+                $sub->token = $at->tok;
+                $sub->secret = $at->secret;
+                if (!$sub->update($orig_sub)) {
+                    return null;
+                } else {
+                    common_debug('subscription updated to use access token', __FILE__);
+                    return new OAuthToken($at->tok, $at->secret);
+                }
+            }
+        } else {
+            return null;
+        }
+    }
 
-       # defined in OAuthDataStore, but not implemented anywhere
+    // defined in OAuthDataStore, but not implemented anywhere
 
-       function fetch_access_token($consumer) {
-               return $this->new_access_token($consumer);
-       }
+    function fetch_access_token($consumer)
+    {
+        return $this->new_access_token($consumer);
+    }
 }
index 96736b4d47918bd11a25a3092cabfac838695864..f2dbef5ba945f97ed10c172cd5e3a5367c844035 100644 (file)
@@ -43,257 +43,271 @@ define('OAUTH_AUTH_HEADER', OAUTH_NAMESPACE.'parameters/auth-header');
 define('OAUTH_POST_BODY', OAUTH_NAMESPACE.'parameters/post-body');
 define('OAUTH_HMAC_SHA1', OAUTH_NAMESPACE.'signature/HMAC-SHA1');
 
-function omb_oauth_consumer() {
-       static $con = NULL;
-       if (!$con) {
-               $con = new OAuthConsumer(common_root_url(), '');
-       }
-       return $con;
+function omb_oauth_consumer()
+{
+    static $con = null;
+    if (!$con) {
+        $con = new OAuthConsumer(common_root_url(), '');
+    }
+    return $con;
 }
 
-function omb_oauth_server() {
-       static $server = null;
-       if (!$server) {
-               $server = new OAuthServer(omb_oauth_datastore());
-               $server->add_signature_method(omb_hmac_sha1());
-       }
-       return $server;
+function omb_oauth_server()
+{
+    static $server = null;
+    if (!$server) {
+        $server = new OAuthServer(omb_oauth_datastore());
+        $server->add_signature_method(omb_hmac_sha1());
+    }
+    return $server;
 }
 
-function omb_oauth_datastore() {
-       static $store = NULL;
-       if (!$store) {
-               $store = new LaconicaOAuthDataStore();
-       }
-       return $store;
+function omb_oauth_datastore()
+{
+    static $store = null;
+    if (!$store) {
+        $store = new LaconicaOAuthDataStore();
+    }
+    return $store;
 }
 
-function omb_hmac_sha1() {
-       static $hmac_method = NULL;
-       if (!$hmac_method) {
-               $hmac_method = new OAuthSignatureMethod_HMAC_SHA1();
-       }
-       return $hmac_method;
+function omb_hmac_sha1()
+{
+    static $hmac_method = null;
+    if (!$hmac_method) {
+        $hmac_method = new OAuthSignatureMethod_HMAC_SHA1();
+    }
+    return $hmac_method;
 }
 
-function omb_get_services($xrd, $type) {
-       return $xrd->services(array(omb_service_filter($type)));
+function omb_get_services($xrd, $type)
+{
+    return $xrd->services(array(omb_service_filter($type)));
 }
 
-function omb_service_filter($type) {
-       return create_function('$s',
-                                                  'return omb_match_service($s, \''.$type.'\');');
+function omb_service_filter($type)
+{
+    return create_function('$s',
+                           'return omb_match_service($s, \''.$type.'\');');
 }
 
-function omb_match_service($service, $type) {
-       return in_array($type, $service->getTypes());
+function omb_match_service($service, $type)
+{
+    return in_array($type, $service->getTypes());
 }
 
-function omb_service_uri($service) {
-       if (!$service) {
-               return NULL;
-       }
-       $uris = $service->getURIs();
-       if (!$uris) {
-               return NULL;
-       }
-       return $uris[0];
+function omb_service_uri($service)
+{
+    if (!$service) {
+        return null;
+    }
+    $uris = $service->getURIs();
+    if (!$uris) {
+        return null;
+    }
+    return $uris[0];
 }
 
-function omb_local_id($service) {
-       if (!$service) {
-               return NULL;
-       }
-       $els = $service->getElements('xrd:LocalID');
-       if (!$els) {
-               return NULL;
-       }
-       $el = $els[0];
-       return $service->parser->content($el);
+function omb_local_id($service)
+{
+    if (!$service) {
+        return null;
+    }
+    $els = $service->getElements('xrd:LocalID');
+    if (!$els) {
+        return null;
+    }
+    $el = $els[0];
+    return $service->parser->content($el);
 }
 
-function omb_broadcast_remote_subscribers($notice) {
+function omb_broadcast_remote_subscribers($notice)
+{
 
-       # First, get remote users subscribed to this profile
-       $rp = new Remote_profile();
+    # First, get remote users subscribed to this profile
+    $rp = new Remote_profile();
 
-       $rp->query('SELECT postnoticeurl, token, secret ' .
-                          'FROM subscription JOIN remote_profile ' .
-                          'ON subscription.subscriber = remote_profile.id ' .
-                          'WHERE subscription.subscribed = ' . $notice->profile_id . ' ');
+    $rp->query('SELECT postnoticeurl, token, secret ' .
+               'FROM subscription JOIN remote_profile ' .
+               'ON subscription.subscriber = remote_profile.id ' .
+               'WHERE subscription.subscribed = ' . $notice->profile_id . ' ');
 
-       $posted = array();
+    $posted = array();
 
-       while ($rp->fetch()) {
-               if (!$posted[$rp->postnoticeurl]) {
-                       common_log(LOG_DEBUG, 'Posting to ' . $rp->postnoticeurl);
-                       if (omb_post_notice_keys($notice, $rp->postnoticeurl, $rp->token, $rp->secret)) {
-                               common_log(LOG_DEBUG, 'Finished to ' . $rp->postnoticeurl);
-                               $posted[$rp->postnoticeurl] = TRUE;
-                       } else {
-                               common_log(LOG_DEBUG, 'Failed posting to ' . $rp->postnoticeurl);
-                       }
-               }
-       }
+    while ($rp->fetch()) {
+        if (!$posted[$rp->postnoticeurl]) {
+            common_log(LOG_DEBUG, 'Posting to ' . $rp->postnoticeurl);
+            if (omb_post_notice_keys($notice, $rp->postnoticeurl, $rp->token, $rp->secret)) {
+                common_log(LOG_DEBUG, 'Finished to ' . $rp->postnoticeurl);
+                $posted[$rp->postnoticeurl] = true;
+            } else {
+                common_log(LOG_DEBUG, 'Failed posting to ' . $rp->postnoticeurl);
+            }
+        }
+    }
 
-       $rp->free();
-       unset($rp);
+    $rp->free();
+    unset($rp);
 
-       return true;
+    return true;
 }
 
-function omb_post_notice($notice, $remote_profile, $subscription) {
-       return omb_post_notice_keys($notice, $remote_profile->postnoticeurl, $subscription->token, $subscription->secret);
+function omb_post_notice($notice, $remote_profile, $subscription)
+{
+    return omb_post_notice_keys($notice, $remote_profile->postnoticeurl, $subscription->token, $subscription->secret);
 }
 
-function omb_post_notice_keys($notice, $postnoticeurl, $tk, $secret) {
+function omb_post_notice_keys($notice, $postnoticeurl, $tk, $secret)
+{
 
-       common_debug('Posting notice ' . $notice->id . ' to ' . $postnoticeurl, __FILE__);
+    common_debug('Posting notice ' . $notice->id . ' to ' . $postnoticeurl, __FILE__);
 
-       $user = User::staticGet('id', $notice->profile_id);
+    $user = User::staticGet('id', $notice->profile_id);
 
-       if (!$user) {
-               common_debug('Failed to get user for notice ' . $notice->id . ', profile = ' . $notice->profile_id, __FILE__);
-               return false;
-       }
+    if (!$user) {
+        common_debug('Failed to get user for notice ' . $notice->id . ', profile = ' . $notice->profile_id, __FILE__);
+        return false;
+    }
 
-       $con = omb_oauth_consumer();
+    $con = omb_oauth_consumer();
 
-       $token = new OAuthToken($tk, $secret);
+    $token = new OAuthToken($tk, $secret);
 
-       $url = $postnoticeurl;
-       $parsed = parse_url($url);
-       $params = array();
-       parse_str($parsed['query'], $params);
+    $url = $postnoticeurl;
+    $parsed = parse_url($url);
+    $params = array();
+    parse_str($parsed['query'], $params);
 
-       $req = OAuthRequest::from_consumer_and_token($con, $token,
-                                                                                                'POST', $url, $params);
+    $req = OAuthRequest::from_consumer_and_token($con, $token,
+                                                 'POST', $url, $params);
 
-       $req->set_parameter('omb_version', OMB_VERSION_01);
-       $req->set_parameter('omb_listenee', $user->uri);
-       $req->set_parameter('omb_notice', $notice->uri);
-       $req->set_parameter('omb_notice_content', $notice->content);
-       $req->set_parameter('omb_notice_url', common_local_url('shownotice',
-                                                                                                                  array('notice' =>
-                                                                                                                                $notice->id)));
-       $req->set_parameter('omb_notice_license', common_config('license', 'url'));
+    $req->set_parameter('omb_version', OMB_VERSION_01);
+    $req->set_parameter('omb_listenee', $user->uri);
+    $req->set_parameter('omb_notice', $notice->uri);
+    $req->set_parameter('omb_notice_content', $notice->content);
+    $req->set_parameter('omb_notice_url', common_local_url('shownotice',
+                                                           array('notice' =>
+                                                                 $notice->id)));
+    $req->set_parameter('omb_notice_license', common_config('license', 'url'));
 
-       $user->free();
-       unset($user);
+    $user->free();
+    unset($user);
 
-       $req->sign_request(omb_hmac_sha1(), $con, $token);
+    $req->sign_request(omb_hmac_sha1(), $con, $token);
 
-       # We re-use this tool's fetcher, since it's pretty good
+    # We re-use this tool's fetcher, since it's pretty good
 
-       $fetcher = Auth_Yadis_Yadis::getHTTPFetcher();
+    $fetcher = Auth_Yadis_Yadis::getHTTPFetcher();
 
-       if (!$fetcher) {
-               common_log(LOG_WARNING, 'Failed to initialize Yadis fetcher.', __FILE__);
-               return false;
-       }
+    if (!$fetcher) {
+        common_log(LOG_WARNING, 'Failed to initialize Yadis fetcher.', __FILE__);
+        return false;
+    }
 
-       $result = $fetcher->post($req->get_normalized_http_url(),
-                                                        $req->to_postdata(),
+    $result = $fetcher->post($req->get_normalized_http_url(),
+                             $req->to_postdata(),
                              array('User-Agent' => 'Laconica/' . LACONICA_VERSION));
 
-       common_debug('Got HTTP result "'.print_r($result,TRUE).'"', __FILE__);
-
-       if ($result->status == 403) { # not authorized, don't send again
-               common_debug('403 result, deleting subscription', __FILE__);
-               # FIXME: figure out how to delete this
-               # $subscription->delete();
-               return false;
-       } else if ($result->status != 200) {
-               common_debug('Error status '.$result->status, __FILE__);
-               return false;
-       } else { # success!
-               parse_str($result->body, $return);
-               if ($return['omb_version'] == OMB_VERSION_01) {
-                       return true;
-               } else {
-                       return false;
-               }
-       }
+    common_debug('Got HTTP result "'.print_r($result,true).'"', __FILE__);
+
+    if ($result->status == 403) { # not authorized, don't send again
+        common_debug('403 result, deleting subscription', __FILE__);
+        # FIXME: figure out how to delete this
+        # $subscription->delete();
+        return false;
+    } else if ($result->status != 200) {
+        common_debug('Error status '.$result->status, __FILE__);
+        return false;
+    } else { # success!
+        parse_str($result->body, $return);
+        if ($return['omb_version'] == OMB_VERSION_01) {
+            return true;
+        } else {
+            return false;
+        }
+    }
 }
 
-function omb_broadcast_profile($profile) {
-       # First, get remote users subscribed to this profile
-       # XXX: use a join here rather than looping through results
-       $sub = new Subscription();
-       $sub->subscribed = $profile->id;
-       if ($sub->find()) {
-               $updated = array();
-               while ($sub->fetch()) {
-                       $rp = Remote_profile::staticGet('id', $sub->subscriber);
-                       if ($rp) {
-                               if (!$updated[$rp->updateprofileurl]) {
-                                       if (omb_update_profile($profile, $rp, $sub)) {
-                                               $updated[$rp->updateprofileurl] = TRUE;
-                                       }
-                               }
-                       }
-               }
-       }
+function omb_broadcast_profile($profile)
+{
+    # First, get remote users subscribed to this profile
+    # XXX: use a join here rather than looping through results
+    $sub = new Subscription();
+    $sub->subscribed = $profile->id;
+    if ($sub->find()) {
+        $updated = array();
+        while ($sub->fetch()) {
+            $rp = Remote_profile::staticGet('id', $sub->subscriber);
+            if ($rp) {
+                if (!$updated[$rp->updateprofileurl]) {
+                    if (omb_update_profile($profile, $rp, $sub)) {
+                        $updated[$rp->updateprofileurl] = true;
+                    }
+                }
+            }
+        }
+    }
 }
 
-function omb_update_profile($profile, $remote_profile, $subscription) {
-       global $config; # for license URL
-       $user = User::staticGet($profile->id);
-       $con = omb_oauth_consumer();
-       $token = new OAuthToken($subscription->token, $subscription->secret);
-       $url = $remote_profile->updateprofileurl;
-       $parsed = parse_url($url);
-       $params = array();
-       parse_str($parsed['query'], $params);
-       $req = OAuthRequest::from_consumer_and_token($con, $token,
-                                                                                                "POST", $url, $params);
-       $req->set_parameter('omb_version', OMB_VERSION_01);
-       $req->set_parameter('omb_listenee', $user->uri);
-       $req->set_parameter('omb_listenee_profile', common_profile_url($profile->nickname));
-       $req->set_parameter('omb_listenee_nickname', $profile->nickname);
-
-       # We use blanks to force emptying any existing values in these optional fields
-
-       $req->set_parameter('omb_listenee_fullname',
-                                               ($profile->fullname) ? $profile->fullname : '');
-       $req->set_parameter('omb_listenee_homepage',
-                                               ($profile->homepage) ? $profile->homepage : '');
-       $req->set_parameter('omb_listenee_bio',
-                                               ($profile->bio) ? $profile->bio : '');
-       $req->set_parameter('omb_listenee_location',
-                                               ($profile->location) ? $profile->location : '');
-
-       $avatar = $profile->getAvatar(AVATAR_PROFILE_SIZE);
-       $req->set_parameter('omb_listenee_avatar',
-                                               ($avatar) ? $avatar->url : '');
-
-       $req->sign_request(omb_hmac_sha1(), $con, $token);
-
-       # We re-use this tool's fetcher, since it's pretty good
-
-       $fetcher = Auth_Yadis_Yadis::getHTTPFetcher();
-
-       common_debug('request URL = '.$req->get_normalized_http_url(), __FILE__);
-       common_debug('postdata = '.$req->to_postdata(), __FILE__);
-       $result = $fetcher->post($req->get_normalized_http_url(),
-                                                        $req->to_postdata(),
+function omb_update_profile($profile, $remote_profile, $subscription)
+{
+    global $config; # for license URL
+    $user = User::staticGet($profile->id);
+    $con = omb_oauth_consumer();
+    $token = new OAuthToken($subscription->token, $subscription->secret);
+    $url = $remote_profile->updateprofileurl;
+    $parsed = parse_url($url);
+    $params = array();
+    parse_str($parsed['query'], $params);
+    $req = OAuthRequest::from_consumer_and_token($con, $token,
+                                                 "POST", $url, $params);
+    $req->set_parameter('omb_version', OMB_VERSION_01);
+    $req->set_parameter('omb_listenee', $user->uri);
+    $req->set_parameter('omb_listenee_profile', common_profile_url($profile->nickname));
+    $req->set_parameter('omb_listenee_nickname', $profile->nickname);
+
+    # We use blanks to force emptying any existing values in these optional fields
+
+    $req->set_parameter('omb_listenee_fullname',
+                        ($profile->fullname) ? $profile->fullname : '');
+    $req->set_parameter('omb_listenee_homepage',
+                        ($profile->homepage) ? $profile->homepage : '');
+    $req->set_parameter('omb_listenee_bio',
+                        ($profile->bio) ? $profile->bio : '');
+    $req->set_parameter('omb_listenee_location',
+                        ($profile->location) ? $profile->location : '');
+
+    $avatar = $profile->getAvatar(AVATAR_PROFILE_SIZE);
+    $req->set_parameter('omb_listenee_avatar',
+                        ($avatar) ? $avatar->url : '');
+
+    $req->sign_request(omb_hmac_sha1(), $con, $token);
+
+    # We re-use this tool's fetcher, since it's pretty good
+
+    $fetcher = Auth_Yadis_Yadis::getHTTPFetcher();
+
+    common_debug('request URL = '.$req->get_normalized_http_url(), __FILE__);
+    common_debug('postdata = '.$req->to_postdata(), __FILE__);
+    $result = $fetcher->post($req->get_normalized_http_url(),
+                             $req->to_postdata(),
                              array('User-Agent' => 'Laconica/' . LACONICA_VERSION));
 
-       common_debug('Got HTTP result "'.print_r($result,TRUE).'"', __FILE__);
-
-       if ($result->status == 403) { # not authorized, don't send again
-               common_debug('403 result, deleting subscription', __FILE__);
-               $subscription->delete();
-               return false;
-       } else if ($result->status != 200) {
-               common_debug('Error status '.$result->status, __FILE__);
-               return false;
-       } else { # success!
-               parse_str($result->body, $return);
-               if ($return['omb_version'] == OMB_VERSION_01) {
-                       return true;
-               } else {
-                       return false;
-               }
-       }
+    common_debug('Got HTTP result "'.print_r($result,true).'"', __FILE__);
+
+    if ($result->status == 403) { # not authorized, don't send again
+        common_debug('403 result, deleting subscription', __FILE__);
+        $subscription->delete();
+        return false;
+    } else if ($result->status != 200) {
+        common_debug('Error status '.$result->status, __FILE__);
+        return false;
+    } else { # success!
+        parse_str($result->body, $return);
+        if ($return['omb_version'] == OMB_VERSION_01) {
+            return true;
+        } else {
+            return false;
+        }
+    }
 }
index 6e501c2b10727211cf64d4ee8a7eabb07c55772c..1e7f318fb5dc833c3b7096eb5831dd86c65576d9 100644 (file)
@@ -31,212 +31,223 @@ require_once('Auth/OpenID/MySQLStore.php');
 define('OPENID_COOKIE_EXPIRY', round(365.25 * 24 * 60 * 60));
 define('OPENID_COOKIE_KEY', 'lastusedopenid');
 
-function oid_store() {
-    static $store = NULL;
-       if (!$store) {
-               # Can't be called statically
-               $user = new User();
-               $conn = $user->getDatabaseConnection();
-               $store = new Auth_OpenID_MySQLStore($conn);
-       }
-       return $store;
+function oid_store()
+{
+    static $store = null;
+    if (!$store) {
+        # Can't be called statically
+        $user = new User();
+        $conn = $user->getDatabaseConnection();
+        $store = new Auth_OpenID_MySQLStore($conn);
+    }
+    return $store;
 }
 
-function oid_consumer() {
-       $store = oid_store();
-       $consumer = new Auth_OpenID_Consumer($store);
-       return $consumer;
+function oid_consumer()
+{
+    $store = oid_store();
+    $consumer = new Auth_OpenID_Consumer($store);
+    return $consumer;
 }
 
-function oid_clear_last() {
-       oid_set_last('');
+function oid_clear_last()
+{
+    oid_set_last('');
 }
 
-function oid_set_last($openid_url) {
-       common_set_cookie(OPENID_COOKIE_KEY,
-                                $openid_url,
-                                time() + OPENID_COOKIE_EXPIRY);
+function oid_set_last($openid_url)
+{
+    common_set_cookie(OPENID_COOKIE_KEY,
+                     $openid_url,
+                     time() + OPENID_COOKIE_EXPIRY);
 }
 
-function oid_get_last() {
-       $openid_url = $_COOKIE[OPENID_COOKIE_KEY];
-       if ($openid_url && strlen($openid_url) > 0) {
-               return $openid_url;
-       } else {
-               return NULL;
-       }
+function oid_get_last()
+{
+    $openid_url = $_COOKIE[OPENID_COOKIE_KEY];
+    if ($openid_url && strlen($openid_url) > 0) {
+        return $openid_url;
+    } else {
+        return null;
+    }
 }
 
-function oid_link_user($id, $canonical, $display) {
+function oid_link_user($id, $canonical, $display)
+{
 
-       $oid = new User_openid();
-       $oid->user_id = $id;
-       $oid->canonical = $canonical;
-       $oid->display = $display;
-       $oid->created = DB_DataObject_Cast::dateTime();
+    $oid = new User_openid();
+    $oid->user_id = $id;
+    $oid->canonical = $canonical;
+    $oid->display = $display;
+    $oid->created = DB_DataObject_Cast::dateTime();
 
-       if (!$oid->insert()) {
-               $err = PEAR::getStaticProperty('DB_DataObject','lastError');
-               common_debug('DB error ' . $err->code . ': ' . $err->message, __FILE__);
-               return false;
-       }
+    if (!$oid->insert()) {
+        $err = PEAR::getStaticProperty('DB_DataObject','lastError');
+        common_debug('DB error ' . $err->code . ': ' . $err->message, __FILE__);
+        return false;
+    }
 
-       return true;
+    return true;
 }
 
-function oid_get_user($openid_url) {
-       $user = NULL;
-       $oid = User_openid::staticGet('canonical', $openid_url);
-       if ($oid) {
-               $user = User::staticGet('id', $oid->user_id);
-       }
-       return $user;
+function oid_get_user($openid_url)
+{
+    $user = null;
+    $oid = User_openid::staticGet('canonical', $openid_url);
+    if ($oid) {
+        $user = User::staticGet('id', $oid->user_id);
+    }
+    return $user;
 }
 
-function oid_check_immediate($openid_url, $backto=NULL) {
-       if (!$backto) {
-               $action = $_REQUEST['action'];
-               $args = common_copy_args($_GET);
-               unset($args['action']);
-               $backto = common_local_url($action, $args);
-       }
-       common_debug('going back to "' . $backto . '"', __FILE__);
-
-       common_ensure_session();
-
-       $_SESSION['openid_immediate_backto'] = $backto;
-       common_debug('passed-in variable is "' . $backto . '"', __FILE__);
-       common_debug('session variable is "' . $_SESSION['openid_immediate_backto'] . '"', __FILE__);
-
-       oid_authenticate($openid_url,
-                                        'finishimmediate',
-                                        true);
+function oid_check_immediate($openid_url, $backto=null)
+{
+    if (!$backto) {
+        $action = $_REQUEST['action'];
+        $args = common_copy_args($_GET);
+        unset($args['action']);
+        $backto = common_local_url($action, $args);
+    }
+    common_debug('going back to "' . $backto . '"', __FILE__);
+
+    common_ensure_session();
+
+    $_SESSION['openid_immediate_backto'] = $backto;
+    common_debug('passed-in variable is "' . $backto . '"', __FILE__);
+    common_debug('session variable is "' . $_SESSION['openid_immediate_backto'] . '"', __FILE__);
+
+    oid_authenticate($openid_url,
+                     'finishimmediate',
+                     true);
 }
 
-function oid_authenticate($openid_url, $returnto, $immediate=false) {
-
-       $consumer = oid_consumer();
-
-       if (!$consumer) {
-               common_server_error(_('Cannot instantiate OpenID consumer object.'));
-               return false;
-       }
-
-       common_ensure_session();
-
-       $auth_request = $consumer->begin($openid_url);
-
-       // Handle failure status return values.
-       if (!$auth_request) {
-               return _('Not a valid OpenID.');
-       } else if (Auth_OpenID::isFailure($auth_request)) {
-               return sprintf(_('OpenID failure: %s'), $auth_request->message);
-       }
-
-       $sreg_request = Auth_OpenID_SRegRequest::build(// Required
-                                                                                                  array(),
-                                                                                                  // Optional
-                                                                                                  array('nickname',
-                                                                                                                'email',
-                                                                                                                'fullname',
-                                                                                                                'language',
-                                                                                                                'timezone',
-                                                                                                                'postcode',
-                                                                                                                'country'));
-
-       if ($sreg_request) {
-               $auth_request->addExtension($sreg_request);
-       }
-
-       $trust_root = common_local_url('public');
-       $process_url = common_local_url($returnto);
-
-       if ($auth_request->shouldSendRedirect()) {
-               $redirect_url = $auth_request->redirectURL($trust_root,
-                                                                                                  $process_url,
-                                                                                                  $immediate);
-               if (!$redirect_url) {
-               } else if (Auth_OpenID::isFailure($redirect_url)) {
-                       return sprintf(_('Could not redirect to server: %s'), $redirect_url->message);
-               } else {
-                       common_redirect($redirect_url);
-               }
-       } else {
-               // Generate form markup and render it.
-               $form_id = 'openid_message';
-               $form_html = $auth_request->formMarkup($trust_root, $process_url,
-                                                                                          $immediate, array('id' => $form_id));
-
-               # XXX: This is cheap, but things choke if we don't escape ampersands
-               # in the HTML attributes
-
-               $form_html = preg_replace('/&/', '&amp;', $form_html);
-
-               // Display an error if the form markup couldn't be generated;
-               // otherwise, render the HTML.
-               if (Auth_OpenID::isFailure($form_html)) {
-                       $this->show_form(sprintf(_('Could not create OpenID form: %s'), $form_html->message));
-               } else {
-                       common_show_header(_('OpenID Auto-Submit'), NULL, NULL, '_oid_print_instructions');
-                       common_raw($form_html);
-                       common_element('script', NULL,
-                                                  '$(document).ready(function() { ' .
-                                                  '    $("#'. $form_id .'").submit(); '.
-                                                  '});');
-                       common_show_footer();
-               }
-       }
+function oid_authenticate($openid_url, $returnto, $immediate=false)
+{
+
+    $consumer = oid_consumer();
+
+    if (!$consumer) {
+        common_server_error(_('Cannot instantiate OpenID consumer object.'));
+        return false;
+    }
+
+    common_ensure_session();
+
+    $auth_request = $consumer->begin($openid_url);
+
+    // Handle failure status return values.
+    if (!$auth_request) {
+        return _('Not a valid OpenID.');
+    } else if (Auth_OpenID::isFailure($auth_request)) {
+        return sprintf(_('OpenID failure: %s'), $auth_request->message);
+    }
+
+    $sreg_request = Auth_OpenID_SRegRequest::build(// Required
+                                                   array(),
+                                                   // Optional
+                                                   array('nickname',
+                                                         'email',
+                                                         'fullname',
+                                                         'language',
+                                                         'timezone',
+                                                         'postcode',
+                                                         'country'));
+
+    if ($sreg_request) {
+        $auth_request->addExtension($sreg_request);
+    }
+
+    $trust_root = common_local_url('public');
+    $process_url = common_local_url($returnto);
+
+    if ($auth_request->shouldSendRedirect()) {
+        $redirect_url = $auth_request->redirectURL($trust_root,
+                                                   $process_url,
+                                                   $immediate);
+        if (!$redirect_url) {
+        } else if (Auth_OpenID::isFailure($redirect_url)) {
+            return sprintf(_('Could not redirect to server: %s'), $redirect_url->message);
+        } else {
+            common_redirect($redirect_url);
+        }
+    } else {
+        // Generate form markup and render it.
+        $form_id = 'openid_message';
+        $form_html = $auth_request->formMarkup($trust_root, $process_url,
+                                               $immediate, array('id' => $form_id));
+
+        # XXX: This is cheap, but things choke if we don't escape ampersands
+        # in the HTML attributes
+
+        $form_html = preg_replace('/&/', '&amp;', $form_html);
+
+        // Display an error if the form markup couldn't be generated;
+        // otherwise, render the HTML.
+        if (Auth_OpenID::isFailure($form_html)) {
+            $this->show_form(sprintf(_('Could not create OpenID form: %s'), $form_html->message));
+        } else {
+            common_show_header(_('OpenID Auto-Submit'), null, null, '_oid_print_instructions');
+            common_raw($form_html);
+            common_element('script', null,
+                           '$(document).ready(function() { ' .
+                           '    $("#'. $form_id .'").submit(); '.
+                           '});');
+            common_show_footer();
+        }
+    }
 }
 
 # Half-assed attempt at a module-private function
 
-function _oid_print_instructions() {
-       common_element('div', 'instructions',
-                                  _('This form should automatically submit itself. '.
-                                         'If not, click the submit button to go to your '.
-                                         'OpenID provider.'));
+function _oid_print_instructions()
+{
+    common_element('div', 'instructions',
+                   _('This form should automatically submit itself. '.
+                      'If not, click the submit button to go to your '.
+                      'OpenID provider.'));
 }
 
 # update a user from sreg parameters
 
-function oid_update_user(&$user, &$sreg) {
+function oid_update_user(&$user, &$sreg)
+{
 
-       $profile = $user->getProfile();
+    $profile = $user->getProfile();
 
-       $orig_profile = clone($profile);
+    $orig_profile = clone($profile);
 
-       if ($sreg['fullname'] && strlen($sreg['fullname']) <= 255) {
-               $profile->fullname = $sreg['fullname'];
-       }
+    if ($sreg['fullname'] && strlen($sreg['fullname']) <= 255) {
+        $profile->fullname = $sreg['fullname'];
+    }
 
-       if ($sreg['country']) {
-               if ($sreg['postcode']) {
-                       # XXX: use postcode to get city and region
-                       # XXX: also, store postcode somewhere -- it's valuable!
-                       $profile->location = $sreg['postcode'] . ', ' . $sreg['country'];
-               } else {
-                       $profile->location = $sreg['country'];
-               }
-       }
+    if ($sreg['country']) {
+        if ($sreg['postcode']) {
+            # XXX: use postcode to get city and region
+            # XXX: also, store postcode somewhere -- it's valuable!
+            $profile->location = $sreg['postcode'] . ', ' . $sreg['country'];
+        } else {
+            $profile->location = $sreg['country'];
+        }
+    }
 
-       # XXX save language if it's passed
-       # XXX save timezone if it's passed
+    # XXX save language if it's passed
+    # XXX save timezone if it's passed
 
-       if (!$profile->update($orig_profile)) {
-               common_server_error(_('Error saving the profile.'));
-               return false;
-       }
+    if (!$profile->update($orig_profile)) {
+        common_server_error(_('Error saving the profile.'));
+        return false;
+    }
 
-       $orig_user = clone($user);
+    $orig_user = clone($user);
 
-       if ($sreg['email'] && Validate::email($sreg['email'], true)) {
-               $user->email = $sreg['email'];
-       }
+    if ($sreg['email'] && Validate::email($sreg['email'], true)) {
+        $user->email = $sreg['email'];
+    }
 
-       if (!$user->update($orig_user)) {
-               common_server_error(_('Error saving the user.'));
-               return false;
-       }
+    if (!$user->update($orig_user)) {
+        common_server_error(_('Error saving the user.'));
+        return false;
+    }
 
-       return true;
+    return true;
 }
index 86433b4867fea94ea4e77f539ea7d81fb2d034ec..02b01fece448213c199834457d801297d79acef2 100644 (file)
 
 if (!defined('LACONICA')) { exit(1); }
 
-class PersonalAction extends Action {
-       
-       function is_readonly() {
-               return true;
-       }
-       
-       function handle($args) {
-               parent::handle($args);
-           common_set_returnto($this->self_url());
-       }
-
-       function views_menu() {
-
-               $user = NULL;
-               $action = $this->trimmed('action');
-               $nickname = $this->trimmed('nickname');
-
-               if ($nickname) {
-                       $user = User::staticGet('nickname', $nickname);
-                       $user_profile = $user->getProfile();
-               } else {
-                       $user_profile = false;
-               }
-
-               common_element_start('ul', array('id' => 'nav_views'));
-
-               common_menu_item(common_local_url('all', array('nickname' =>
-                                                                                                          $nickname)),
-                                                _('Personal'),
-                                                sprintf(_('%s and friends'), (($user_profile && $user_profile->fullname) ? $user_profile->fullname : $nickname)),
-                                                $action == 'all');
-               common_menu_item(common_local_url('replies', array('nickname' =>
-                                                                                                                         $nickname)),
-                                                _('Replies'),
-                                                sprintf(_('Replies to %s'), (($user_profile && $user_profile->fullname) ? $user_profile->fullname : $nickname)),
-                                                $action == 'replies');
-               common_menu_item(common_local_url('showstream', array('nickname' =>
-                                                                                                                         $nickname)),
-                                                _('Profile'),
-                                                ($user_profile && $user_profile->fullname) ? $user_profile->fullname : $nickname,
-                                                $action == 'showstream');
-               common_menu_item(common_local_url('showfavorites', array('nickname' =>
-                                                                                                                         $nickname)),
-                                                _('Favorites'),
-                                                sprintf(_('%s\'s favorite notices'), ($user_profile) ? $user_profile->getBestName() : _('User')),
-                                                $action == 'showfavorites');
-               
-               $cur = common_current_user();
-               
-               if ($cur && $cur->id == $user->id) {
-                       
-                       common_menu_item(common_local_url('inbox', array('nickname' =>
-                                                                                                                                        $nickname)),
-                                                        _('Inbox'),
-                                                        _('Your incoming messages'),
-                                                        $action == 'inbox');
-                       common_menu_item(common_local_url('outbox', array('nickname' =>
-                                                                                                                                        $nickname)),
-                                                        _('Outbox'),
-                                                        _('Your sent messages'),
-                                                        $action == 'outbox');
-               }
-               
-               common_element_end('ul');
-       }
-
-       function show_feeds_list($feeds) {
-               common_element_start('div', array('class' => 'feeds'));
-               common_element('p', null, 'Feeds:');
-               common_element_start('ul', array('class' => 'xoxo'));
-
-               foreach ($feeds as $key => $value) {
-                       $this->common_feed_item($feeds[$key]);
-               }
-               common_element_end('ul');
-               common_element_end('div');
-       }
-
-       function common_feed_item($feed) {
-               $nickname = $this->trimmed('nickname');
-
-               switch($feed['item']) {
-                       case 'notices': default:
-                               $feed_classname = $feed['type'];
-                               $feed_mimetype = "application/".$feed['type']."+xml";
-                               $feed_title = "$nickname's ".$feed['version']." notice feed";
-                               $feed['textContent'] = "RSS";
-                               break;
-
-                       case 'allrss':
-                               $feed_classname = $feed['type'];
-                               $feed_mimetype = "application/".$feed['type']."+xml";
-                               $feed_title = $feed['version']." feed for $nickname and friends";
-                               $feed['textContent'] = "RSS";
-                               break;
-
-                       case 'repliesrss':
-                               $feed_classname = $feed['type'];
-                               $feed_mimetype = "application/".$feed['type']."+xml";
-                               $feed_title = $feed['version']." feed for replies to $nickname";
-                               $feed['textContent'] = "RSS";
-                               break;
-
-                       case 'publicrss':
-                               $feed_classname = $feed['type'];
-                               $feed_mimetype = "application/".$feed['type']."+xml";
-                               $feed_title = "Public timeline ".$feed['version']." feed";
-                               $feed['textContent'] = "RSS";
-                               break;
-
-                       case 'publicatom':
-                               $feed_classname = "atom";
-                               $feed_mimetype = "application/".$feed['type']."+xml";
-                               $feed_title = "Public timeline ".$feed['version']." feed";
-                               $feed['textContent'] = "Atom";
-                               break;
-
-                       case 'tagrss':
-                               $feed_classname = $feed['type'];
-                               $feed_mimetype = "application/".$feed['type']."+xml";
-                               $feed_title = $feed['version']." feed for this tag";
-                               $feed['textContent'] = "RSS";
-                               break;
-
-                       case 'favoritedrss':
-                               $feed_classname = $feed['type'];
-                               $feed_mimetype = "application/".$feed['type']."+xml";
-                               $feed_title = "Favorited ".$feed['version']." feed";
-                               $feed['textContent'] = "RSS";
-                               break;
-
-                       case 'foaf':
-                               $feed_classname = "foaf";
-                               $feed_mimetype = "application/".$feed['type']."+xml";
-                               $feed_title = "$nickname's FOAF file";
-                               $feed['textContent'] = "FOAF";
-                               break;
-
-                       case 'favoritesrss':
-                               $feed_classname = "favorites";
-                               $feed_mimetype = "application/".$feed['type']."+xml";
-                               $feed_title = "Feed for favorites of $nickname";
-                               $feed['textContent'] = "RSS";
-                               break;
-
-                       case 'usertimeline':
-                               $feed_classname = "atom";
-                               $feed_mimetype = "application/".$feed['type']."+xml";
-                               $feed_title = "$nickname's ".$feed['version']." notice feed";
-                               $feed['textContent'] = "Atom";
-                               break;
-               }
-               common_element_start('li');
-               common_element('a', array('href' => $feed['href'],
-                                                                 'class' => $feed_classname,
-                                                                 'type' => $feed_mimetype,
-                                                                 'title' => $feed_title),
-                                                       $feed['textContent']);
-               common_element_end('li');
-       }
-
-       
-       function source_link($source) {
-               $source_name = _($source);
-               switch ($source) {
-                case 'web':
-                case 'xmpp':
-                case 'mail':
-                case 'omb':
-                case 'api':
-                       common_element('span', 'noticesource', $source_name);
-                       break;
-                default:
-                       $ns = Notice_source::staticGet($source);
-                       if ($ns) {
-                               common_element('a', array('href' => $ns->url),
-                                                          $ns->name);
-                       } else {
-                               common_element('span', 'noticesource', $source_name);
-                       }
-                       break;
-               }
-               return;
-       }
+class PersonalAction extends Action
+{
+    
+    function is_readonly()
+    {
+        return true;
+    }
+    
+    function handle($args)
+    {
+        parent::handle($args);
+        common_set_returnto($this->self_url());
+    }
+
+    function views_menu()
+    {
+
+        $user = null;
+        $action = $this->trimmed('action');
+        $nickname = $this->trimmed('nickname');
+
+        if ($nickname) {
+            $user = User::staticGet('nickname', $nickname);
+            $user_profile = $user->getProfile();
+        } else {
+            $user_profile = false;
+        }
+
+        common_element_start('ul', array('id' => 'nav_views'));
+
+        common_menu_item(common_local_url('all', array('nickname' =>
+                                                       $nickname)),
+                         _('Personal'),
+                         sprintf(_('%s and friends'), (($user_profile && $user_profile->fullname) ? $user_profile->fullname : $nickname)),
+                         $action == 'all');
+        common_menu_item(common_local_url('replies', array('nickname' =>
+                                                              $nickname)),
+                         _('Replies'),
+                         sprintf(_('Replies to %s'), (($user_profile && $user_profile->fullname) ? $user_profile->fullname : $nickname)),
+                         $action == 'replies');
+        common_menu_item(common_local_url('showstream', array('nickname' =>
+                                                              $nickname)),
+                         _('Profile'),
+                         ($user_profile && $user_profile->fullname) ? $user_profile->fullname : $nickname,
+                         $action == 'showstream');
+        common_menu_item(common_local_url('showfavorites', array('nickname' =>
+                                                              $nickname)),
+                         _('Favorites'),
+                         sprintf(_('%s\'s favorite notices'), ($user_profile) ? $user_profile->getBestName() : _('User')),
+                         $action == 'showfavorites');
+        
+        $cur = common_current_user();
+        
+        if ($cur && $cur->id == $user->id) {
+            
+            common_menu_item(common_local_url('inbox', array('nickname' =>
+                                                                     $nickname)),
+                             _('Inbox'),
+                             _('Your incoming messages'),
+                             $action == 'inbox');
+            common_menu_item(common_local_url('outbox', array('nickname' =>
+                                                                     $nickname)),
+                             _('Outbox'),
+                             _('Your sent messages'),
+                             $action == 'outbox');
+        }
+        
+        common_element_end('ul');
+    }
+
+    function show_feeds_list($feeds)
+    {
+        common_element_start('div', array('class' => 'feeds'));
+        common_element('p', null, 'Feeds:');
+        common_element_start('ul', array('class' => 'xoxo'));
+
+        foreach ($feeds as $key => $value) {
+            $this->common_feed_item($feeds[$key]);
+        }
+        common_element_end('ul');
+        common_element_end('div');
+    }
+
+    function common_feed_item($feed)
+    {
+        $nickname = $this->trimmed('nickname');
+
+        switch($feed['item']) {
+            case 'notices': default:
+                $feed_classname = $feed['type'];
+                $feed_mimetype = "application/".$feed['type']."+xml";
+                $feed_title = "$nickname's ".$feed['version']." notice feed";
+                $feed['textContent'] = "RSS";
+                break;
+
+            case 'allrss':
+                $feed_classname = $feed['type'];
+                $feed_mimetype = "application/".$feed['type']."+xml";
+                $feed_title = $feed['version']." feed for $nickname and friends";
+                $feed['textContent'] = "RSS";
+                break;
+
+            case 'repliesrss':
+                $feed_classname = $feed['type'];
+                $feed_mimetype = "application/".$feed['type']."+xml";
+                $feed_title = $feed['version']." feed for replies to $nickname";
+                $feed['textContent'] = "RSS";
+                break;
+
+            case 'publicrss':
+                $feed_classname = $feed['type'];
+                $feed_mimetype = "application/".$feed['type']."+xml";
+                $feed_title = "Public timeline ".$feed['version']." feed";
+                $feed['textContent'] = "RSS";
+                break;
+
+            case 'publicatom':
+                $feed_classname = "atom";
+                $feed_mimetype = "application/".$feed['type']."+xml";
+                $feed_title = "Public timeline ".$feed['version']." feed";
+                $feed['textContent'] = "Atom";
+                break;
+
+            case 'tagrss':
+                $feed_classname = $feed['type'];
+                $feed_mimetype = "application/".$feed['type']."+xml";
+                $feed_title = $feed['version']." feed for this tag";
+                $feed['textContent'] = "RSS";
+                break;
+
+            case 'favoritedrss':
+                $feed_classname = $feed['type'];
+                $feed_mimetype = "application/".$feed['type']."+xml";
+                $feed_title = "Favorited ".$feed['version']." feed";
+                $feed['textContent'] = "RSS";
+                break;
+
+            case 'foaf':
+                $feed_classname = "foaf";
+                $feed_mimetype = "application/".$feed['type']."+xml";
+                $feed_title = "$nickname's FOAF file";
+                $feed['textContent'] = "FOAF";
+                break;
+
+            case 'favoritesrss':
+                $feed_classname = "favorites";
+                $feed_mimetype = "application/".$feed['type']."+xml";
+                $feed_title = "Feed for favorites of $nickname";
+                $feed['textContent'] = "RSS";
+                break;
+
+            case 'usertimeline':
+                $feed_classname = "atom";
+                $feed_mimetype = "application/".$feed['type']."+xml";
+                $feed_title = "$nickname's ".$feed['version']." notice feed";
+                $feed['textContent'] = "Atom";
+                break;
+        }
+        common_element_start('li');
+        common_element('a', array('href' => $feed['href'],
+                                  'class' => $feed_classname,
+                                  'type' => $feed_mimetype,
+                                  'title' => $feed_title),
+                            $feed['textContent']);
+        common_element_end('li');
+    }
+
+    
+    function source_link($source)
+    {
+        $source_name = _($source);
+        switch ($source) {
+         case 'web':
+         case 'xmpp':
+         case 'mail':
+         case 'omb':
+         case 'api':
+            common_element('span', 'noticesource', $source_name);
+            break;
+         default:
+            $ns = Notice_source::staticGet($source);
+            if ($ns) {
+                common_element('a', array('href' => $ns->url),
+                               $ns->name);
+            } else {
+                common_element('span', 'noticesource', $source_name);
+            }
+            break;
+        }
+        return;
+    }
 }
index 9079ea9d7c64c162d3794c3720b09c884e8c1939..bda05daf3bbf5fb12165840d85c223659c39f565 100644 (file)
@@ -22,148 +22,154 @@ if (!defined('LACONICA')) { exit(1); }
 
 define('PROFILES_PER_PAGE', 20);
 
-class ProfileList {
-
-       var $profile = NULL;
-       var $owner = NULL;
-       var $action = NULL;
-
-       function __construct($profile, $owner=NULL, $action=NULL) {
-               $this->profile = $profile;
-               $this->owner = $owner;
-               $this->action = $action;
-       }
-
-       function show_list() {
-
-               common_element_start('ul', array('id' => 'profiles', 'class' => 'profile_list'));
-
-               $cnt = 0;
-
-               while ($this->profile->fetch()) {
-                       $cnt++;
-                       if($cnt > PROFILES_PER_PAGE) {
-                               break;
-                       }
-                       $this->show();
-               }
-
-               common_element_end('ul');
-
-               return $cnt;
-       }
-
-       function show() {
-
-               common_element_start('li', array('class' => 'profile_single',
-                                                                                'id' => 'profile-' . $this->profile->id));
-
-               $user = common_current_user();
-
-               if ($user && $user->id != $this->profile->id) {
-                       # XXX: special-case for user looking at own
-                       # subscriptions page
-                       if ($user->isSubscribed($this->profile)) {
-                               common_unsubscribe_form($this->profile);
-                       } else {
-                               common_subscribe_form($this->profile);
-                       }
-               }
-
-               $avatar = $this->profile->getAvatar(AVATAR_STREAM_SIZE);
-               common_element_start('a', array('href' => $this->profile->profileurl));
-               common_element('img', array('src' => ($avatar) ? common_avatar_display_url($avatar) : common_default_avatar(AVATAR_STREAM_SIZE),
-                                                                       'class' => 'avatar stream',
-                                                                       'width' => AVATAR_STREAM_SIZE,
-                                                                       'height' => AVATAR_STREAM_SIZE,
-                                                                       'alt' =>
-                                                                       ($this->profile->fullname) ? $this->profile->fullname :
-                                                                       $this->profile->nickname));
-               common_element_end('a');
-               common_element_start('p');
-               common_element_start('a', array('href' => $this->profile->profileurl,
-                                                                               'class' => 'nickname'));
-               common_raw($this->highlight($this->profile->nickname));
-               common_element_end('a');
-               if ($this->profile->fullname) {
-                       common_text(' | ');
-                       common_element_start('span', 'fullname');
-                       common_raw($this->highlight($this->profile->fullname));
-                       common_element_end('span');
-               }
-               if ($this->profile->location) {
-                       common_text(' | ');
-                       common_element_start('span', 'location');
-                       common_raw($this->highlight($this->profile->location));
-                       common_element_end('span');
-               }
-               common_element_end('p');
-               if ($this->profile->homepage) {
-                       common_element_start('p', 'website');
-                       common_element_start('a', array('href' => $this->profile->homepage));
-                       common_raw($this->highlight($this->profile->homepage));
-                       common_element_end('a');
-                       common_element_end('p');
-               }
-               if ($this->profile->bio) {
-                       common_element_start('p', 'bio');
-                       common_raw($this->highlight($this->profile->bio));
-                       common_element_end('p');
-               }
-
-               # 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);
-
-                       common_element_start('div', 'tags_user');
-                       common_element_start('dl');
-                       common_element_start('dt');
-                       if ($user->id == $this->owner->id) {
-                               common_element('a', array('href' => common_local_url('tagother',
-                                                                                                                                        array('id' => $this->profile->id))),
-                                                          _('Tags'));
-                       } else {
-                               common_text(_('Tags'));
-                       }
-                       common_text(":");
-                       common_element_end('dt');
-                       common_element_start('dd');
-                       if ($tags) {
-                               common_element_start('ul', 'tags xoxo');
-                               foreach ($tags as $tag) {
-                                       common_element_start('li');
-                                       common_element('a', array('rel' => 'tag',
-                                                                                         'href' => common_local_url($this->action,
-                                                                                                                                                array('nickname' => $this->owner->nickname,
-                                                                                                                                                          'tag' => $tag))),
-                                                                  $tag);
-                                       common_element_end('li');
-                               }
-                               common_element_end('ul');
-                       } else {
-                               common_text(_('(none)'));
-                       }
-                       common_element_end('dd');
-                       common_element_end('dl');
-                       common_element_end('div');
-               }
+class ProfileList
+{
+
+    var $profile = null;
+    var $owner = null;
+    var $action = null;
+
+    function __construct($profile, $owner=null, $action=null)
+    {
+        $this->profile = $profile;
+        $this->owner = $owner;
+        $this->action = $action;
+    }
+
+    function show_list()
+    {
+
+        common_element_start('ul', array('id' => 'profiles', 'class' => 'profile_list'));
+
+        $cnt = 0;
+
+        while ($this->profile->fetch()) {
+            $cnt++;
+            if($cnt > PROFILES_PER_PAGE) {
+                break;
+            }
+            $this->show();
+        }
+
+        common_element_end('ul');
+
+        return $cnt;
+    }
+
+    function show()
+    {
+
+        common_element_start('li', array('class' => 'profile_single',
+                                         'id' => 'profile-' . $this->profile->id));
+
+        $user = common_current_user();
+
+        if ($user && $user->id != $this->profile->id) {
+            # XXX: special-case for user looking at own
+            # subscriptions page
+            if ($user->isSubscribed($this->profile)) {
+                common_unsubscribe_form($this->profile);
+            } else {
+                common_subscribe_form($this->profile);
+            }
+        }
+
+        $avatar = $this->profile->getAvatar(AVATAR_STREAM_SIZE);
+        common_element_start('a', array('href' => $this->profile->profileurl));
+        common_element('img', array('src' => ($avatar) ? common_avatar_display_url($avatar) : common_default_avatar(AVATAR_STREAM_SIZE),
+                                    'class' => 'avatar stream',
+                                    'width' => AVATAR_STREAM_SIZE,
+                                    'height' => AVATAR_STREAM_SIZE,
+                                    'alt' =>
+                                    ($this->profile->fullname) ? $this->profile->fullname :
+                                    $this->profile->nickname));
+        common_element_end('a');
+        common_element_start('p');
+        common_element_start('a', array('href' => $this->profile->profileurl,
+                                        'class' => 'nickname'));
+        common_raw($this->highlight($this->profile->nickname));
+        common_element_end('a');
+        if ($this->profile->fullname) {
+            common_text(' | ');
+            common_element_start('span', 'fullname');
+            common_raw($this->highlight($this->profile->fullname));
+            common_element_end('span');
+        }
+        if ($this->profile->location) {
+            common_text(' | ');
+            common_element_start('span', 'location');
+            common_raw($this->highlight($this->profile->location));
+            common_element_end('span');
+        }
+        common_element_end('p');
+        if ($this->profile->homepage) {
+            common_element_start('p', 'website');
+            common_element_start('a', array('href' => $this->profile->homepage));
+            common_raw($this->highlight($this->profile->homepage));
+            common_element_end('a');
+            common_element_end('p');
+        }
+        if ($this->profile->bio) {
+            common_element_start('p', 'bio');
+            common_raw($this->highlight($this->profile->bio));
+            common_element_end('p');
+        }
+
+        # 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);
+
+            common_element_start('div', 'tags_user');
+            common_element_start('dl');
+            common_element_start('dt');
+            if ($user->id == $this->owner->id) {
+                common_element('a', array('href' => common_local_url('tagother',
+                                                                     array('id' => $this->profile->id))),
+                               _('Tags'));
+            } else {
+                common_text(_('Tags'));
+            }
+            common_text(":");
+            common_element_end('dt');
+            common_element_start('dd');
+            if ($tags) {
+                common_element_start('ul', 'tags xoxo');
+                foreach ($tags as $tag) {
+                    common_element_start('li');
+                    common_element('a', array('rel' => 'tag',
+                                              'href' => common_local_url($this->action,
+                                                                         array('nickname' => $this->owner->nickname,
+                                                                               'tag' => $tag))),
+                                   $tag);
+                    common_element_end('li');
+                }
+                common_element_end('ul');
+            } else {
+                common_text(_('(none)'));
+            }
+            common_element_end('dd');
+            common_element_end('dl');
+            common_element_end('div');
+        }
 
         if ($user && $user->id == $this->owner->id) {
             $this->show_owner_controls($this->profile);
         }
 
-               common_element_end('li');
-       }
+        common_element_end('li');
+    }
 
     /* Override this in subclasses. */
 
-    function show_owner_controls($profile) {
+    function show_owner_controls($profile)
+    {
         return;
     }
 
-       function highlight($text) {
-               return htmlspecialchars($text);
-       }
+    function highlight($text)
+    {
+        return htmlspecialchars($text);
+    }
 }
\ No newline at end of file
index 23f295c45296fb480e233e4add9e7bb3fcc15782..9ce9e32b3b718f1d60375607aefbf194cdbcb156 100644 (file)
@@ -25,108 +25,122 @@ require_once(INSTALLDIR.'/lib/daemon.php');
 require_once(INSTALLDIR.'/classes/Queue_item.php');
 require_once(INSTALLDIR.'/classes/Notice.php');
 
-class QueueHandler extends Daemon {
+class QueueHandler extends Daemon
+{
 
-       var $_id = 'generic';
+    var $_id = 'generic';
 
-       function QueueHandler($id=NULL) {
-               if ($id) {
-                       $this->set_id($id);
-               }
-       }
-       
-       function class_name() {
-               return ucfirst($this->transport()) . 'Handler';
-       }
+    function QueueHandler($id=null)
+    {
+        if ($id) {
+            $this->set_id($id);
+        }
+    }
+    
+    function class_name()
+    {
+        return ucfirst($this->transport()) . 'Handler';
+    }
 
-       function name() {
-               return strtolower($this->class_name().'.'.$this->get_id());
-       }
-       
-       function get_id() {
-               return $this->_id;
-       }
+    function name()
+    {
+        return strtolower($this->class_name().'.'.$this->get_id());
+    }
+    
+    function get_id()
+    {
+        return $this->_id;
+    }
 
-       function set_id($id) {
-               $this->_id = $id;
-       }
-       
-       function transport() {
-               return NULL;
-       }
-       
-       function start() {
-       }
-       
-       function finish() {
-       }
+    function set_id($id)
+    {
+        $this->_id = $id;
+    }
+    
+    function transport()
+    {
+        return null;
+    }
+    
+    function start()
+    {
+    }
+    
+    function finish()
+    {
+    }
 
-       function handle_notice($notice) {
-               return true;
-       }
-       
-       function run() {
-               if (!$this->start()) {
-                       return false;
-               }
-               $this->log(LOG_INFO, 'checking for queued notices');
-               $transport = $this->transport();
-               do {
-                       $qi = Queue_item::top($transport);
-                       if ($qi) {
-                               $this->log(LOG_INFO, 'Got item enqueued '.common_exact_date($qi->created));
-                               $notice = Notice::staticGet($qi->notice_id);
-                               if ($notice) {
-                                       $this->log(LOG_INFO, 'broadcasting notice ID = ' . $notice->id);
-                                       # XXX: what to do if broadcast fails?
-                                       $result = $this->handle_notice($notice);
-                                       if (!$result) {
-                                               $this->log(LOG_WARNING, 'Failed broadcast for notice ID = ' . $notice->id);
-                                               $orig = $qi;
-                                               $qi->claimed = NULL;
-                                               $qi->update($orig);
-                                               $this->log(LOG_WARNING, 'Abandoned claim for notice ID = ' . $notice->id);
-                                               continue;
-                                       }
-                                       $this->log(LOG_INFO, 'finished broadcasting notice ID = ' . $notice->id);
-                                       $notice->free();
-                                       unset($notice);
-                                       $notice = NULL;
-                               } else {
-                                       $this->log(LOG_WARNING, 'queue item for notice that does not exist');
-                               }
-                               $qi->delete();
-                               $qi->free();
-                               unset($qi);
-                               $this->idle(0);
-                       } else {
-                               $this->clear_old_claims();
-                               $this->idle(5);
-                       }       
-               } while (true);
-               if (!$this->finish()) {
-                       return false;
-               }
-               return true;
-       }
+    function handle_notice($notice)
+    {
+        return true;
+    }
+    
+    function run()
+    {
+        if (!$this->start()) {
+            return false;
+        }
+        $this->log(LOG_INFO, 'checking for queued notices');
+        $transport = $this->transport();
+        do {
+            $qi = Queue_item::top($transport);
+            if ($qi) {
+                $this->log(LOG_INFO, 'Got item enqueued '.common_exact_date($qi->created));
+                $notice = Notice::staticGet($qi->notice_id);
+                if ($notice) {
+                    $this->log(LOG_INFO, 'broadcasting notice ID = ' . $notice->id);
+                    # XXX: what to do if broadcast fails?
+                    $result = $this->handle_notice($notice);
+                    if (!$result) {
+                        $this->log(LOG_WARNING, 'Failed broadcast for notice ID = ' . $notice->id);
+                        $orig = $qi;
+                        $qi->claimed = null;
+                        $qi->update($orig);
+                        $this->log(LOG_WARNING, 'Abandoned claim for notice ID = ' . $notice->id);
+                        continue;
+                    }
+                    $this->log(LOG_INFO, 'finished broadcasting notice ID = ' . $notice->id);
+                    $notice->free();
+                    unset($notice);
+                    $notice = null;
+                } else {
+                    $this->log(LOG_WARNING, 'queue item for notice that does not exist');
+                }
+                $qi->delete();
+                $qi->free();
+                unset($qi);
+                $this->idle(0);
+            } else {
+                $this->clear_old_claims();
+                $this->idle(5);
+            }    
+        } while (true);
+        if (!$this->finish()) {
+            return false;
+        }
+        return true;
+    }
 
-       function idle($timeout=0) {
-               if ($timeout>0) {
-                       sleep($timeout);
-               }
-       }
-       
-       function clear_old_claims() {
-               $qi = new Queue_item();
-               $qi->transport = $this->transport();
-               $qi->whereAdd('now() - claimed > '.CLAIM_TIMEOUT);
-               $qi->update(DB_DATAOBJECT_WHEREADD_ONLY);
-               $qi->free();
-               unset($qi);
-       }
-       
-       function log($level, $msg) {
-               common_log($level, $this->class_name() . ' ('. $this->get_id() .'): '.$msg);
-       }
+    function idle($timeout=0)
+    {
+        if ($timeout>0) {
+            sleep($timeout);
+        }
+    }
+    
+    function clear_old_claims()
+    {
+        $qi = new Queue_item();
+        $qi->transport = $this->transport();
+        $qi->whereAdd('now() - claimed > '.CLAIM_TIMEOUT);
+        $qi->update(DB_DATAOBJECT_WHEREADD_ONLY);
+        $qi->free();
+        unset($qi);
+    }
+    
+    function log($level, $msg)
+    {
+        common_log($level, $this->class_name() . ' ('. $this->get_id() .'): '.$msg);
+    }
 }
-       
\ No newline at end of file
+    
\ No newline at end of file
index 777511506dff0bf8b710a77bcc7029e3344cab5e..9564cfb4605ad198eacaa048f58c3fb98782e11a 100644 (file)
@@ -21,169 +21,183 @@ if (!defined('LACONICA')) { exit(1); }
 
 define('DEFAULT_RSS_LIMIT', 48);
 
-class Rss10Action extends Action {
-
-       # This will contain the details of each feed item's author and be used to generate SIOC data.
-       var $creators = array();
-
-       function is_readonly() {
-               return true;
-       }
-
-       function handle($args) {
-               parent::handle($args);
-               $limit = (int) $this->trimmed('limit');
-               if ($limit == 0) {
-                       $limit = DEFAULT_RSS_LIMIT;
-               }
-               $this->show_rss($limit);
-       }
-
-       function init() {
-               return true;
-       }
-
-       function get_notices() {
-               return array();
-       }
-
-       function get_channel() {
-               return array('url' => '',
-                                        'title' => '',
-                                        'link' => '',
-                                        'description' => '');
-       }
-
-       function get_image() {
-               return NULL;
-       }
-
-       function show_rss($limit=0) {
-
-               if (!$this->init()) {
-                       return;
-               }
-
-               $notices = $this->get_notices($limit);
-
-               $this->init_rss();
-               $this->show_channel($notices);
-               $this->show_image();
-
-               foreach ($notices as $n) {
-                       $this->show_item($n);
-               }
-
-               $this->show_creators();
-               $this->end_rss();
-       }
-
-       function show_channel($notices) {
-
-               $channel = $this->get_channel();
-               $image = $this->get_image();
-
-               common_element_start('channel', array('rdf:about' => $channel['url']));
-               common_element('title', NULL, $channel['title']);
-               common_element('link', NULL, $channel['link']);
-               common_element('description', NULL, $channel['description']);
-               common_element('cc:licence', array('rdf:resource' => common_config('license','url')));
-
-               if ($image) {
-                       common_element('image', array('rdf:resource' => $image));
-               }
-
-               common_element_start('items');
-               common_element_start('rdf:Seq');
-
-               foreach ($notices as $notice) {
-                       common_element('sioct:MicroblogPost', array('rdf:resource' => $notice->uri));
-               }
-
-               common_element_end('rdf:Seq');
-               common_element_end('items');
-
-               common_element_end('channel');
-       }
-
-       function show_image() {
-               $image = $this->get_image();
-               if ($image) {
-                       $channel = $this->get_channel();
-                       common_element_start('image', array('rdf:about' => $image));
-                       common_element('title', NULL, $channel['title']);
-                       common_element('link', NULL, $channel['link']);
-                       common_element('url', NULL, $image);
-                       common_element_end('image');
-               }
-       }
-
-       function show_item($notice) {
-               $profile = Profile::staticGet($notice->profile_id);
-               $nurl = common_local_url('shownotice', array('notice' => $notice->id));
-               $creator_uri = common_profile_uri($profile);
-               common_element_start('item', array('rdf:about' => $notice->uri));
-               $title = $profile->nickname . ': ' . common_xml_safe_str(trim($notice->content));
-               common_element('title', NULL, $title);
-               common_element('link', NULL, $nurl);
-               common_element('description', NULL, $profile->nickname."'s status on ".common_exact_date($notice->created));
-               common_element('dc:date', NULL, common_date_w3dtf($notice->created));
-               common_element('dc:creator', NULL, ($profile->fullname) ? $profile->fullname : $profile->nickname);
-               common_element('sioc:has_creator', array('rdf:resource' => $creator_uri));
-               common_element('laconica:postIcon', array('rdf:resource' => common_profile_avatar_url($profile)));
-               common_element('cc:licence', array('rdf:resource' => common_config('license', 'url')));
-               common_element_end('item');
-               $this->creators[$creator_uri] = $profile;
-       }
-
-       function show_creators() {
-               foreach ($this->creators as $uri => $profile) {
-                       $id = $profile->id;
-                       $nickname = $profile->nickname;
-                       common_element_start('sioc:User', array('rdf:about' => $uri));
-                       common_element('foaf:nick', NULL, $nickname);
-                       if ($profile->fullname) {
-                               common_element('foaf:name', NULL, $profile->fullname);
-                       }
-                       common_element('sioc:id', NULL, $id);
-                       $avatar = common_profile_avatar_url($profile);
-                       common_element('sioc:avatar', array('rdf:resource' => $avatar));
-                       common_element_end('sioc:User');
-               }
-       }
-
-       function init_rss() {
-               $channel = $this->get_channel();
-               header('Content-Type: application/rdf+xml');
-
-               common_start_xml();
-               common_element_start('rdf:RDF', array('xmlns:rdf' =>
-                                                                                         'http://www.w3.org/1999/02/22-rdf-syntax-ns#',
-                                                                                         'xmlns:dc' =>
-                                                                                         'http://purl.org/dc/elements/1.1/',
-                                                                                         'xmlns:cc' =>
-                                                                                         'http://web.resource.org/cc/',
+class Rss10Action extends Action
+{
+
+    # This will contain the details of each feed item's author and be used to generate SIOC data.
+    var $creators = array();
+
+    function is_readonly()
+    {
+        return true;
+    }
+
+    function handle($args)
+    {
+        parent::handle($args);
+        $limit = (int) $this->trimmed('limit');
+        if ($limit == 0) {
+            $limit = DEFAULT_RSS_LIMIT;
+        }
+        $this->show_rss($limit);
+    }
+
+    function init()
+    {
+        return true;
+    }
+
+    function get_notices()
+    {
+        return array();
+    }
+
+    function get_channel()
+    {
+        return array('url' => '',
+                     'title' => '',
+                     'link' => '',
+                     'description' => '');
+    }
+
+    function get_image()
+    {
+        return null;
+    }
+
+    function show_rss($limit=0)
+    {
+
+        if (!$this->init()) {
+            return;
+        }
+
+        $notices = $this->get_notices($limit);
+
+        $this->init_rss();
+        $this->show_channel($notices);
+        $this->show_image();
+
+        foreach ($notices as $n) {
+            $this->show_item($n);
+        }
+
+        $this->show_creators();
+        $this->end_rss();
+    }
+
+    function show_channel($notices)
+    {
+
+        $channel = $this->get_channel();
+        $image = $this->get_image();
+
+        common_element_start('channel', array('rdf:about' => $channel['url']));
+        common_element('title', null, $channel['title']);
+        common_element('link', null, $channel['link']);
+        common_element('description', null, $channel['description']);
+        common_element('cc:licence', array('rdf:resource' => common_config('license','url')));
+
+        if ($image) {
+            common_element('image', array('rdf:resource' => $image));
+        }
+
+        common_element_start('items');
+        common_element_start('rdf:Seq');
+
+        foreach ($notices as $notice) {
+            common_element('sioct:MicroblogPost', array('rdf:resource' => $notice->uri));
+        }
+
+        common_element_end('rdf:Seq');
+        common_element_end('items');
+
+        common_element_end('channel');
+    }
+
+    function show_image()
+    {
+        $image = $this->get_image();
+        if ($image) {
+            $channel = $this->get_channel();
+            common_element_start('image', array('rdf:about' => $image));
+            common_element('title', null, $channel['title']);
+            common_element('link', null, $channel['link']);
+            common_element('url', null, $image);
+            common_element_end('image');
+        }
+    }
+
+    function show_item($notice)
+    {
+        $profile = Profile::staticGet($notice->profile_id);
+        $nurl = common_local_url('shownotice', array('notice' => $notice->id));
+        $creator_uri = common_profile_uri($profile);
+        common_element_start('item', array('rdf:about' => $notice->uri));
+        $title = $profile->nickname . ': ' . common_xml_safe_str(trim($notice->content));
+        common_element('title', null, $title);
+        common_element('link', null, $nurl);
+        common_element('description', null, $profile->nickname."'s status on ".common_exact_date($notice->created));
+        common_element('dc:date', null, common_date_w3dtf($notice->created));
+        common_element('dc:creator', null, ($profile->fullname) ? $profile->fullname : $profile->nickname);
+        common_element('sioc:has_creator', array('rdf:resource' => $creator_uri));
+        common_element('laconica:postIcon', array('rdf:resource' => common_profile_avatar_url($profile)));
+        common_element('cc:licence', array('rdf:resource' => common_config('license', 'url')));
+        common_element_end('item');
+        $this->creators[$creator_uri] = $profile;
+    }
+
+    function show_creators()
+    {
+        foreach ($this->creators as $uri => $profile) {
+            $id = $profile->id;
+            $nickname = $profile->nickname;
+            common_element_start('sioc:User', array('rdf:about' => $uri));
+            common_element('foaf:nick', null, $nickname);
+            if ($profile->fullname) {
+                common_element('foaf:name', null, $profile->fullname);
+            }
+            common_element('sioc:id', null, $id);
+            $avatar = common_profile_avatar_url($profile);
+            common_element('sioc:avatar', array('rdf:resource' => $avatar));
+            common_element_end('sioc:User');
+        }
+    }
+
+    function init_rss()
+    {
+        $channel = $this->get_channel();
+        header('Content-Type: application/rdf+xml');
+
+        common_start_xml();
+        common_element_start('rdf:RDF', array('xmlns:rdf' =>
+                                              'http://www.w3.org/1999/02/22-rdf-syntax-ns#',
+                                              'xmlns:dc' =>
+                                              'http://purl.org/dc/elements/1.1/',
+                                              'xmlns:cc' =>
+                                              'http://web.resource.org/cc/',
                                               'xmlns:content' =>
                                               'http://purl.org/rss/1.0/modules/content/',
-                                                                                         'xmlns:foaf' =>
-                                                                                         'http://xmlns.com/foaf/0.1/',
-                                                                                         'xmlns:sioc' =>
-                                                                                         'http://rdfs.org/sioc/ns#',
-                                                     'xmlns:sioct' =>
-                                                     'http://rdfs.org/sioc/types#',
-                                                     'xmlns:laconica' =>
-                                                     'http://laconi.ca/ont/',
-                                                                                         'xmlns' => 'http://purl.org/rss/1.0/'));
-               common_element_start('sioc:Site', array('rdf:about' => common_root_url()));
-               common_element('sioc:name', NULL, common_config('site', 'name'));
-               common_element_start('sioc:container_of');
-               common_element('sioc:Container', array('rdf:about' =>
-                                                      $channel['url']));
-               common_element_end('sioc:container_of');
-               common_element_end('sioc:Site');
-       }
-
-       function end_rss() {
-               common_element_end('rdf:RDF');
-       }
+                                              'xmlns:foaf' =>
+                                              'http://xmlns.com/foaf/0.1/',
+                                              'xmlns:sioc' =>
+                                              'http://rdfs.org/sioc/ns#',
+                                              'xmlns:sioct' =>
+                                              'http://rdfs.org/sioc/types#',
+                                              'xmlns:laconica' =>
+                                              'http://laconi.ca/ont/',
+                                              'xmlns' => 'http://purl.org/rss/1.0/'));
+        common_element_start('sioc:Site', array('rdf:about' => common_root_url()));
+        common_element('sioc:name', null, common_config('site', 'name'));
+        common_element_start('sioc:container_of');
+        common_element('sioc:Container', array('rdf:about' =>
+                                               $channel['url']));
+        common_element_end('sioc:container_of');
+        common_element_end('sioc:Site');
+    }
+
+    function end_rss()
+    {
+        common_element_end('rdf:RDF');
+    }
 }
index 7fcc1ffcb027d375e120ea58271bbc379292b1d1..559107910cef885bccb87a4687b8ab0b2dcae707 100644 (file)
 
 if (!defined('LACONICA')) { exit(1); }
 
-class SearchEngine {
+class SearchEngine
+{
     protected $target;
     protected $table;
 
-    function __construct($target, $table) {
+    function __construct($target, $table)
+    {
         $this->target = $target;
         $this->table = $table;
     }
 
-    function query($q) {
+    function query($q)
+    {
     }
 
-    function limit($offset, $count, $rss = false) {
+    function limit($offset, $count, $rss = false)
+    {
         return $this->target->limit($offset, $count);
     }
 
-    function set_sort_mode($mode) {
+    function set_sort_mode($mode)
+    {
         if ('chron' === $mode)
             return $this->target->orderBy('created desc');
     }
 }
 
-class SphinxSearch extends SearchEngine {
+class SphinxSearch extends SearchEngine
+{
     private $sphinx;
     private $connected;
 
-    function __construct($target, $table) {
+    function __construct($target, $table)
+    {
         $fp = @fsockopen(common_config('sphinx', 'server'), common_config('sphinx', 'port'));
         if (!$fp) {
             $this->connected = false;
@@ -58,11 +65,13 @@ class SphinxSearch extends SearchEngine {
         $this->connected = true;
     }
 
-    function is_connected() {
+    function is_connected()
+    {
         return $this->connected;
     }
 
-    function limit($offset, $count, $rss = false) {
+    function limit($offset, $count, $rss = false)
+    {
         //FIXME without LARGEST_POSSIBLE, the most recent results aren't returned
         //      this probably has a large impact on performance
         $LARGEST_POSSIBLE = 1e6; 
@@ -78,7 +87,8 @@ class SphinxSearch extends SearchEngine {
         return $this->target->limit(0, $count);
     }
 
-    function query($q) {
+    function query($q)
+    {
         $result = $this->sphinx->query($q, $this->table);
         if (!isset($result['matches'])) return false;
         $id_set = join(', ', array_keys($result['matches']));
@@ -86,7 +96,8 @@ class SphinxSearch extends SearchEngine {
         return true;
      }
 
-    function set_sort_mode($mode) {
+    function set_sort_mode($mode)
+    {
         if ('chron' === $mode) {
             $this->sphinx->SetSortMode(SPH_SORT_ATTR_DESC, 'created_ts');
             return $this->target->orderBy('created desc');
@@ -94,19 +105,23 @@ class SphinxSearch extends SearchEngine {
     }
 }
 
-class MySQLSearch extends SearchEngine {
-    function query($q) {
+class MySQLSearch extends SearchEngine
+{
+    function query($q)
+    {
         if ('identica_people' === $this->table)
             return $this->target->whereAdd('MATCH(nickname, fullname, location, bio, homepage) ' .
-                                                  'against (\''.addslashes($q).'\')');
+                           'against (\''.addslashes($q).'\')');
         if ('identica_notices' === $this->table)
             return $this->target->whereAdd('MATCH(content) ' .
-                                                  'against (\''.addslashes($q).'\')');
+                           'against (\''.addslashes($q).'\')');
     }
 }
 
-class PGSearch extends SearchEngine {
-    function query($q) {
+class PGSearch extends SearchEngine
+{
+    function query($q)
+    {
         if ('identica_people' === $this->table)
             return $this->target->whereAdd('textsearch @@ plainto_tsquery(\''.addslashes($q).'\')');
         if ('identica_notices' === $this->table)
index f99883b251ec7ca2eed5044f555155c5f1ed5166..bc90fac1aac5530be8d31476630e011e127256f0 100644 (file)
 
 if (!defined('LACONICA')) { exit(1); }
 
-class SearchAction extends Action {
+class SearchAction extends Action
+{
 
-       function is_readonly() {
-               return true;
-       }
+    function is_readonly()
+    {
+        return true;
+    }
 
-       function handle($args) {
-               parent::handle($args);
-               $this->show_form();
-       }
+    function handle($args)
+    {
+        parent::handle($args);
+        $this->show_form();
+    }
 
-       function show_top($arr=NULL) {
-               if ($arr) {
-                       $error = $arr[1];
-               }
-               if ($error) {
-                       common_element('p', 'error', $error);
-               } else {
-                       $instr = $this->get_instructions();
-                       $output = common_markup_to_html($instr);
-                       common_element_start('div', 'instructions');
-                       common_raw($output);
-                       common_element_end('div');
-               }
-               $this->search_menu();
-       }
+    function show_top($arr=null)
+    {
+        if ($arr) {
+            $error = $arr[1];
+        }
+        if ($error) {
+            common_element('p', 'error', $error);
+        } else {
+            $instr = $this->get_instructions();
+            $output = common_markup_to_html($instr);
+            common_element_start('div', 'instructions');
+            common_raw($output);
+            common_element_end('div');
+        }
+        $this->search_menu();
+    }
 
-       function get_title() {
-               return NULL;
-       }
+    function get_title()
+    {
+        return null;
+    }
 
-       function show_header($arr) {
-               return;
-       }
+    function show_header($arr)
+    {
+        return;
+    }
 
-       function show_form($error=NULL) {
-               global $config;
+    function show_form($error=null)
+    {
+        global $config;
 
-               $q = $this->trimmed('q');
-               $page = $this->trimmed('page', 1);
+        $q = $this->trimmed('q');
+        $page = $this->trimmed('page', 1);
 
-               common_show_header($this->get_title(), array($this, 'show_header'), array($q, $error),
-                                                  array($this, 'show_top'));
-               common_element_start('form', array('method' => 'get',
-                                                                                  'id' => 'login',
-                                                                                  'action' => common_local_url($this->trimmed('action'))));
-               common_element_start('p');
-               if (!isset($config['site']['fancy']) || !$config['site']['fancy']) {
-                       common_element('input', array('name' => 'action',
-                                                                                 'type' => 'hidden',
-                                                                                 'value' => $this->trimmed('action')));
-               }
-               common_element('input', array('name' => 'q',
-                                                                         'id' => 'q',
-                                                                         'type' => 'text',
-                                                                         'class' => 'input_text',
-                                                                         'value' => ($q) ? $q : ''));
-               common_text(' ');
-               common_element('input', array('type' => 'submit',
-                                                                         'id' => 'search',
-                                                                         'name' => 'search',
-                                                                         'class' => 'submit',
-                                                                         'value' => _('Search')));
+        common_show_header($this->get_title(), array($this, 'show_header'), array($q, $error),
+                           array($this, 'show_top'));
+        common_element_start('form', array('method' => 'get',
+                                           'id' => 'login',
+                                           'action' => common_local_url($this->trimmed('action'))));
+        common_element_start('p');
+        if (!isset($config['site']['fancy']) || !$config['site']['fancy']) {
+            common_element('input', array('name' => 'action',
+                                          'type' => 'hidden',
+                                          'value' => $this->trimmed('action')));
+        }
+        common_element('input', array('name' => 'q',
+                                      'id' => 'q',
+                                      'type' => 'text',
+                                      'class' => 'input_text',
+                                      'value' => ($q) ? $q : ''));
+        common_text(' ');
+        common_element('input', array('type' => 'submit',
+                                      'id' => 'search',
+                                      'name' => 'search',
+                                      'class' => 'submit',
+                                      'value' => _('Search')));
 
-               common_element_end('p');
-               common_element_end('form');
-               if ($q) {
-                       $this->show_results($q, $page);
-               }
-               common_show_footer();
-       }
+        common_element_end('p');
+        common_element_end('form');
+        if ($q) {
+            $this->show_results($q, $page);
+        }
+        common_show_footer();
+    }
 
-       function search_menu() {
-               # action => array('prompt', 'title', $args)
-               $action = $this->trimmed('action');
-               $menu =
-                 array('peoplesearch' =>
-                               array(
-                                         _('People'),
-                                         _('Find people on this site'),
-                                         ($action != 'peoplesearch' && $this->trimmed('q')) ? array('q' => $this->trimmed('q')) : NULL),
-                               'noticesearch' =>
-                               array( _('Text'),
-                                          _('Find content of notices'),
-                                          ($action != 'noticesearch' && $this->trimmed('q')) ? array('q' => $this->trimmed('q')) : NULL)
-                               );
-               $this->nav_menu($menu);
-       }
+    function search_menu()
+    {
+        # action => array('prompt', 'title', $args)
+        $action = $this->trimmed('action');
+        $menu =
+          array('peoplesearch' =>
+                array(
+                      _('People'),
+                      _('Find people on this site'),
+                      ($action != 'peoplesearch' && $this->trimmed('q')) ? array('q' => $this->trimmed('q')) : null),
+                'noticesearch' =>
+                array( _('Text'),
+                       _('Find content of notices'),
+                       ($action != 'noticesearch' && $this->trimmed('q')) ? array('q' => $this->trimmed('q')) : null)
+                );
+        $this->nav_menu($menu);
+    }
 }
index 9e783431f23586073429c867546e3cddbc7b3a89..03bac3a93b0173f9ffcf1a6dc5fbc78162bd809a 100644 (file)
 
 if (!defined('LACONICA')) { exit(1); }
 
-class SettingsAction extends Action {
+class SettingsAction extends Action
+{
 
-    function handle($args) {
+    function handle($args)
+    {
         parent::handle($args);
         if (!common_logged_in()) {
             common_user_error(_('Not logged in.'));
             return;
         } else if (!common_is_real_login()) {
-               # Cookie theft means that automatic logins can't
-               # change important settings or see private info, and
-               # _all_ our settings are important
+            # Cookie theft means that automatic logins can't
+            # change important settings or see private info, and
+            # _all_ our settings are important
             common_set_returnto($this->self_url());
             common_redirect(common_local_url('login'));
         } else if ($_SERVER['REQUEST_METHOD'] == 'POST') {
@@ -40,75 +42,93 @@ class SettingsAction extends Action {
     }
 
     # override!
-    function handle_post() {
+    function handle_post()
+    {
         return false;
     }
 
-    function show_form($msg=NULL, $success=false) {
+    function show_form($msg=null, $success=false)
+    {
         return false;
     }
 
-    function message($msg, $success) {
+    function message($msg, $success)
+    {
         if ($msg) {
             common_element('div', ($success) ? 'success' : 'error',
                            $msg);
         }
     }
 
-       function form_header($title, $msg=NULL, $success=false) {
-               common_show_header($title,
-                                  NULL,
-                                  array($msg, $success),
-                                                  array($this, 'show_top'));
-       }
+    function form_header($title, $msg=NULL, $success=false) 
+    {
+        common_show_header($title,
+                           array($this, 'show_header'),
+                           array($msg, $success),
+                           array($this, 'show_top'));
+    }
+
+    function show_header() 
+    {
+        common_element('link', array('rel' => 'stylesheet',
+                                     'type' => 'text/css',
+                                     'href' => common_path('js/jcrop/jquery.Jcrop.css?version='.LACONICA_VERSION),
+                                     'media' => 'screen, projection, tv'));
+        common_element('script', array('type' => 'text/javascript',
+                                       'src' => common_path('js/jcrop/jquery.Jcrop.pack.js')));
+        common_element('script', array('type' => 'text/javascript',
+                                       'src' => common_path('js/jcrop/jquery.Jcrop.go.js')));
+    }
 
-       function show_top($arr) {
-               $msg = $arr[0];
-               $success = $arr[1];
-               if ($msg) {
-                       $this->message($msg, $success);
-               } else {
-                       $inst = $this->get_instructions();
-                       $output = common_markup_to_html($inst);
-                       common_element_start('div', 'instructions');
-                       common_raw($output);
-                       common_element_end('div');
-               }
-               $this->settings_menu();
-       }
+    function show_top($arr)
+    {
+        $msg = $arr[0];
+        $success = $arr[1];
+        if ($msg) {
+            $this->message($msg, $success);
+        } else {
+            $inst = $this->get_instructions();
+            $output = common_markup_to_html($inst);
+            common_element_start('div', 'instructions');
+            common_raw($output);
+            common_element_end('div');
+        }
+        $this->settings_menu();
+    }
 
-    function settings_menu() {
+    function settings_menu()
+    {
         # action => array('prompt', 'title')
-               $menu =
-                 array('profilesettings' =>
-                               array(_('Profile'),
-                                         _('Change your profile settings')),
-                               'emailsettings' =>
-                               array(_('Email'),
-                                         _('Change email handling')),
-                               'openidsettings' =>
-                               array(_('OpenID'),
-                                         _('Add or remove OpenIDs')),
-                               'smssettings' =>
-                               array(_('SMS'),
-                                         _('Updates by SMS')),
-                               'imsettings' =>
-                               array(_('IM'),
-                                         _('Updates by instant messenger (IM)')),
-                               'twittersettings' =>
-                               array(_('Twitter'),
-                                         _('Twitter integration options')),
-                               'othersettings' =>
-                               array(_('Other'),
-                                         _('Other options')));
-               
+        $menu =
+          array('profilesettings' =>
+                array(_('Profile'),
+                      _('Change your profile settings')),
+                'emailsettings' =>
+                array(_('Email'),
+                      _('Change email handling')),
+                'openidsettings' =>
+                array(_('OpenID'),
+                      _('Add or remove OpenIDs')),
+                'smssettings' =>
+                array(_('SMS'),
+                      _('Updates by SMS')),
+                'imsettings' =>
+                array(_('IM'),
+                      _('Updates by instant messenger (IM)')),
+                'twittersettings' =>
+                array(_('Twitter'),
+                      _('Twitter integration options')),
+                'othersettings' =>
+                array(_('Other'),
+                      _('Other options')));
+        
         $action = $this->trimmed('action');
         common_element_start('ul', array('id' => 'nav_views'));
         foreach ($menu as $menuaction => $menudesc) {
-                       if ($menuaction == 'imsettings' &&
-                               !common_config('xmpp', 'enabled')) {
-                               continue;
-                       }
+            if ($menuaction == 'imsettings' &&
+                !common_config('xmpp', 'enabled')) {
+                continue;
+            }
             common_menu_item(common_local_url($menuaction),
                     $menudesc[0],
                     $menudesc[1],
index 27ab78137f430f7f6ba1205897d6e938815500c3..73758adee637a7b9e58b25f00b3ad189851aaed9 100644 (file)
  *
  * 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
+ * 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/>.
+ * along with this program.     If not, see <http://www.gnu.org/licenses/>.
  */
 
 if (!defined('LACONICA')) { exit(1); }
@@ -22,33 +22,36 @@ if (!defined('LACONICA')) { exit(1); }
 require_once(INSTALLDIR.'/lib/personal.php');
 require_once(INSTALLDIR.'/lib/noticelist.php');
 
-class StreamAction extends PersonalAction {
+class StreamAction extends PersonalAction
+{
 
-       function public_views_menu() {
+    function public_views_menu()
+    {
 
-               $action = $this->trimmed('action');
+        $action = $this->trimmed('action');
 
-               common_element_start('ul', array('id' => 'nav_views'));
+        common_element_start('ul', array('id' => 'nav_views'));
 
-               common_menu_item(common_local_url('public'), _('Public'),
-                       _('Public timeline'), $action == 'public');
+        common_menu_item(common_local_url('public'), _('Public'),
+            _('Public timeline'), $action == 'public');
 
-               common_menu_item(common_local_url('tag'), _('Recent tags'),
-                       _('Recent tags'), $action == 'tag');
+        common_menu_item(common_local_url('tag'), _('Recent tags'),
+            _('Recent tags'), $action == 'tag');
 
-               if (count(common_config('nickname', 'featured')) > 0) {
-                       common_menu_item(common_local_url('featured'), _('Featured'),
-                               _('Featured users'), $action == 'featured');
-               }
+        if (count(common_config('nickname', 'featured')) > 0) {
+            common_menu_item(common_local_url('featured'), _('Featured'),
+                _('Featured users'), $action == 'featured');
+        }
 
-               common_menu_item(common_local_url('favorited'), _('Popular'),
-                       _("Popular notices"), $action == 'favorited');
+        common_menu_item(common_local_url('favorited'), _('Popular'),
+            _("Popular notices"), $action == 'favorited');
 
-               common_element_end('ul');
+        common_element_end('ul');
 
-       }
+    }
 
-    function show_notice_list($notice) {
+    function show_notice_list($notice)
+    {
         $nl = new NoticeList($notice);
         return $nl->show();
     }
index 91fc8445d7c34bc4a130819c5986f9ffd49a3350..6fa1dcad3bbba5e07ce01e0a4595c5d11ea4a20e 100644 (file)
@@ -25,15 +25,16 @@ require_once('XMPPHP/XMPP.php');
   Returns true or an error message.
 */
 
-function subs_subscribe_user($user, $other_nickname) {
+function subs_subscribe_user($user, $other_nickname)
+{
 
-       $other = User::staticGet('nickname', $other_nickname);
+    $other = User::staticGet('nickname', $other_nickname);
 
-       if (!$other) {
-               return _('No such user.');
-       }
+    if (!$other) {
+        return _('No such user.');
+    }
 
-       return subs_subscribe_to($user, $other);
+    return subs_subscribe_to($user, $other);
 }
 
 /* Subscribe user $user to other user $other.
@@ -41,100 +42,105 @@ function subs_subscribe_user($user, $other_nickname) {
  * Because the other way is quite a bit more complicated.
  */
 
-function subs_subscribe_to($user, $other) {
+function subs_subscribe_to($user, $other)
+{
 
-       if ($user->isSubscribed($other)) {
-               return _('Already subscribed!.');
-       }
+    if ($user->isSubscribed($other)) {
+        return _('Already subscribed!.');
+    }
 
     if ($other->hasBlocked($user)) {
-               return _('User has blocked you.');
+        return _('User has blocked you.');
     }
 
-       if (!$user->subscribeTo($other)) {
-               return _('Could not subscribe.');
-               return;
-       }
+    if (!$user->subscribeTo($other)) {
+        return _('Could not subscribe.');
+        return;
+    }
 
     subs_notify($other, $user);
 
-       if (common_config('memcached', 'enabled')) {
-               $cache = new Memcache();
-               if ($cache->connect(common_config('memcached', 'server'), common_config('memcached', 'port'))) {
-                       $cache->delete(common_cache_key('user:notices_with_friends:' . $user->id));
-               }
-       }
-
-       if ($other->autosubscribe && !$other->isSubscribed($user) && !$user->hasBlocked($other)) {
-               if (!$other->subscribeTo($user)) {
-                       return _('Could not subscribe other to you.');
-               }
-               if (common_config('memcached', 'enabled')) {
-                       $cache = new Memcache();
-                       if ($cache->connect(common_config('memcached', 'server'), common_config('memcached', 'port'))) {
-                               $cache->delete(common_cache_key('user:notices_with_friends:' . $other->id));
-                       }
-               }
-
-               subs_notify($user, $other);
-       }
-
-       return true;
+    if (common_config('memcached', 'enabled')) {
+        $cache = new Memcache();
+        if ($cache->connect(common_config('memcached', 'server'), common_config('memcached', 'port'))) {
+            $cache->delete(common_cache_key('user:notices_with_friends:' . $user->id));
+        }
+    }
+
+    if ($other->autosubscribe && !$other->isSubscribed($user) && !$user->hasBlocked($other)) {
+        if (!$other->subscribeTo($user)) {
+            return _('Could not subscribe other to you.');
+        }
+        if (common_config('memcached', 'enabled')) {
+            $cache = new Memcache();
+            if ($cache->connect(common_config('memcached', 'server'), common_config('memcached', 'port'))) {
+                $cache->delete(common_cache_key('user:notices_with_friends:' . $other->id));
+            }
+        }
+
+        subs_notify($user, $other);
+    }
+
+    return true;
 }
 
-function subs_notify($listenee, $listener) {
-       # XXX: add other notifications (Jabber, SMS) here
-       # XXX: queue this and handle it offline
-       # XXX: Whatever happens, do it in Twitter-like API, too
-       subs_notify_email($listenee, $listener);
+function subs_notify($listenee, $listener)
+{
+    # XXX: add other notifications (Jabber, SMS) here
+    # XXX: queue this and handle it offline
+    # XXX: Whatever happens, do it in Twitter-like API, too
+    subs_notify_email($listenee, $listener);
 }
 
-function subs_notify_email($listenee, $listener) {
-       mail_subscribe_notify($listenee, $listener);
+function subs_notify_email($listenee, $listener)
+{
+    mail_subscribe_notify($listenee, $listener);
 }
 
 /* Unsubscribe $user from nickname $other_nickname
   Returns true or an error message.
 */
 
-function subs_unsubscribe_user($user, $other_nickname) {
+function subs_unsubscribe_user($user, $other_nickname)
+{
 
-       $other = User::staticGet('nickname', $other_nickname);
+    $other = User::staticGet('nickname', $other_nickname);
 
-       if (!$other) {
-               return _('No such user.');
-       }
+    if (!$other) {
+        return _('No such user.');
+    }
 
-       return subs_unsubscribe_to($user, $other->getProfile());
+    return subs_unsubscribe_to($user, $other->getProfile());
 }
 
 /* Unsubscribe user $user from profile $other
  * NB: other can be a remote user. */
 
-function subs_unsubscribe_to($user, $other) {
+function subs_unsubscribe_to($user, $other)
+{
 
-       if (!$user->isSubscribed($other))
-               return _('Not subscribed!.');
+    if (!$user->isSubscribed($other))
+        return _('Not subscribed!.');
 
-       $sub = DB_DataObject::factory('subscription');
+    $sub = DB_DataObject::factory('subscription');
 
-       $sub->subscriber = $user->id;
-       $sub->subscribed = $other->id;
+    $sub->subscriber = $user->id;
+    $sub->subscribed = $other->id;
 
-       $sub->find(true);
+    $sub->find(true);
 
-       // note we checked for existence above
+    // note we checked for existence above
 
-       if (!$sub->delete())
-               return _('Couldn\'t delete subscription.');
+    if (!$sub->delete())
+        return _('Couldn\'t delete subscription.');
 
-       if (common_config('memcached', 'enabled')) {
-               $cache = new Memcache();
-               if ($cache->connect(common_config('memcached', 'server'), common_config('memcached', 'port'))) {
-                       $cache->delete(common_cache_key('user:notices_with_friends:' . $user->id));
-               }
-       }
+    if (common_config('memcached', 'enabled')) {
+        $cache = new Memcache();
+        if ($cache->connect(common_config('memcached', 'server'), common_config('memcached', 'port'))) {
+            $cache->delete(common_cache_key('user:notices_with_friends:' . $user->id));
+        }
+    }
 
-       return true;
+    return true;
 }
 
index 80982aa82b0d59f7742fd2d128dceccbbb60881b..6f365bd9925c2db0d06dd0e987bf14c6214d7d35 100644 (file)
 
 if (!defined('LACONICA')) { exit(1); }
 
-function theme_file($relative) {
-       $theme = common_config('site', 'theme');
-       return INSTALLDIR.'/theme/'.$theme.'/'.$relative;
+function theme_file($relative)
+{
+    $theme = common_config('site', 'theme');
+    return INSTALLDIR.'/theme/'.$theme.'/'.$relative;
 }
 
-function theme_path($relative) {
-       $theme = common_config('site', 'theme');
-       $server = common_config('theme', 'server');
-       if ($server) {
-               return 'http://'.$server.'/'.$theme.'/'.$relative;
-       } else {
-               return common_path('theme/'.$theme.'/'.$relative);
-       }
+function theme_path($relative)
+{
+    $theme = common_config('site', 'theme');
+    $server = common_config('theme', 'server');
+    if ($server) {
+        return 'http://'.$server.'/'.$theme.'/'.$relative;
+    } else {
+        return common_path('theme/'.$theme.'/'.$relative);
+    }
 }
\ No newline at end of file
index 7f75a1afd87d00050c9f17997363ae4e827fddfa..5eb15005a6dcfdb50c774c26cf556d1a035886f8 100644 (file)
 
 if (!defined('LACONICA')) { exit(1); }
 
-function get_twitter_data($uri, $screen_name, $password) {
-
-       $options = array(
-                       CURLOPT_USERPWD => sprintf("%s:%s", $screen_name, $password),
-                       CURLOPT_RETURNTRANSFER  => true,
-                       CURLOPT_FAILONERROR             => true,
-                       CURLOPT_HEADER                  => false,
-                       CURLOPT_FOLLOWLOCATION  => true,
-                       // CURLOPT_USERAGENT            => "identi.ca",
-                       CURLOPT_CONNECTTIMEOUT  => 120,
+function get_twitter_data($uri, $screen_name, $password)
+{
+
+    $options = array(
+            CURLOPT_USERPWD => sprintf("%s:%s", $screen_name, $password),
+            CURLOPT_RETURNTRANSFER    => true,
+            CURLOPT_FAILONERROR        => true,
+            CURLOPT_HEADER            => false,
+            CURLOPT_FOLLOWLOCATION    => true,
+            # CURLOPT_USERAGENT        => "identi.ca",
+            CURLOPT_CONNECTTIMEOUT    => 120,
             CURLOPT_TIMEOUT            => 120,
-            
             # Twitter is strict about accepting invalid "Expect" headers
             CURLOPT_HTTPHEADER => array('Expect:')
-       );
+    );
 
 
-       $ch = curl_init($uri);
+    $ch = curl_init($uri);
     curl_setopt_array($ch, $options);
     $data = curl_exec($ch);
     $errmsg = curl_error($ch);
 
-       if ($errmsg) {
-               common_debug("Twitter bridge - cURL error: $errmsg - trying to load: $uri with user $twit_user.",
-                       __FILE__);
-       }
+    if ($errmsg) {
+        common_debug("Twitter bridge - cURL error: $errmsg - trying to load: $uri with user $twit_user.",
+            __FILE__);
+    }
 
-       curl_close($ch);
+    curl_close($ch);
 
-       return $data;
+    return $data;
 }
 
-function twitter_user_info($screen_name, $password) {
+function twitter_user_info($screen_name, $password)
+{
 
-       $uri = "http://twitter.com/users/show/$screen_name.json";
-       $data = get_twitter_data($uri, $screen_name, $password);
+    $uri = "http://twitter.com/users/show/$screen_name.json";
+    $data = get_twitter_data($uri, $screen_name, $password);
 
-       if (!$data) {
-               return false;
-       }
+    if (!$data) {
+        return false;
+    }
 
-       $twit_user = json_decode($data);
+    $twit_user = json_decode($data);
 
-       if (!$twit_user) {
-               return false;
-       }
+    if (!$twit_user) {
+        return false;
+    }
 
-       return $twit_user;
+    return $twit_user;
 }
 
-function update_twitter_user($fuser, $twitter_id, $screen_name) {
+function update_twitter_user($fuser, $twitter_id, $screen_name)
+{
 
-       $original = clone($fuser);
-       $fuser->nickname = $screen_name;
-       $fuser->uri = 'http://twitter.com/' . $screen_name;
-       $result = $fuser->updateKeys($original);
+    $original = clone($fuser);
+    $fuser->nickname = $screen_name;
+    $fuser->uri = 'http://twitter.com/' . $screen_name;
+    $result = $fuser->updateKeys($original);
 
-       if (!$result) {
-               common_log_db_error($fuser, 'UPDATE', __FILE__);
-               return false;
-       }
+    if (!$result) {
+        common_log_db_error($fuser, 'UPDATE', __FILE__);
+        return false;
+    }
 
-       return true;
+    return true;
 }
 
-function add_twitter_user($twitter_id, $screen_name) {
+function add_twitter_user($twitter_id, $screen_name)
+{
 
-       // Otherwise, create a new Twitter user
-       $fuser = DB_DataObject::factory('foreign_user');
+    // Otherwise, create a new Twitter user
+    $fuser = DB_DataObject::factory('foreign_user');
 
-       $fuser->nickname = $screen_name;
-       $fuser->uri = 'http://twitter.com/' . $screen_name;
-       $fuser->id = $twitter_id;
-       $fuser->service = 1; // Twitter
-       $fuser->created = common_sql_now();
-       $result = $fuser->insert();
+    $fuser->nickname = $screen_name;
+    $fuser->uri = 'http://twitter.com/' . $screen_name;
+    $fuser->id = $twitter_id;
+    $fuser->service = 1; // Twitter
+    $fuser->created = common_sql_now();
+    $result = $fuser->insert();
 
-       if (!$result) {
-               common_debug("Twitter bridge - failed to add new Twitter user: $twitter_id - $screen_name.");
-               common_log_db_error($fuser, 'INSERT', __FILE__);
-               return false;
-       }
+    if (!$result) {
+        common_debug("Twitter bridge - failed to add new Twitter user: $twitter_id - $screen_name.");
+        common_log_db_error($fuser, 'INSERT', __FILE__);
+        return false;
+    }
 
-       common_debug("Twitter bridge - Added new Twitter user: $screen_name ($twitter_id).");
+    common_debug("Twitter bridge - Added new Twitter user: $screen_name ($twitter_id).");
 
-       return true;
+    return true;
 }
 
 // Creates or Updates a Twitter user
-function save_twitter_user($twitter_id, $screen_name) {
+function save_twitter_user($twitter_id, $screen_name)
+{
 
-       // Check to see whether the Twitter user is already in the system,
-       // and update its screen name and uri if so.
-       $fuser = Foreign_user::getForeignUser($twitter_id, 1);
+    // Check to see whether the Twitter user is already in the system,
+    // and update its screen name and uri if so.
+    $fuser = Foreign_user::getForeignUser($twitter_id, 1);
 
-       if ($fuser) {
+    if ($fuser) {
 
-               // Only update if Twitter screen name has changed
-               if ($fuser->nickname != $screen_name) {
+        // Only update if Twitter screen name has changed
+        if ($fuser->nickname != $screen_name) {
 
-                       common_debug('Twitter bridge - Updated nickname (and URI) for Twitter user ' .
-                               "$fuser->id to $screen_name, was $fuser->nickname");
+            common_debug('Twitter bridge - Updated nickname (and URI) for Twitter user ' .
+                "$fuser->id to $screen_name, was $fuser->nickname");
 
-                       return update_twitter_user($fuser, $twitter_id, $screen_name);
-               }
+            return update_twitter_user($fuser, $twitter_id, $screen_name);
+        }
 
-       } else {
-               return add_twitter_user($twitter_id, $screen_name);
-       }
+    } else {
+        return add_twitter_user($twitter_id, $screen_name);
+    }
 
-       return true;
+    return true;
 }
 
-function retreive_twitter_friends($twitter_id, $screen_name, $password) {
+function retreive_twitter_friends($twitter_id, $screen_name, $password)
+{
 
-       $uri = "http://twitter.com/statuses/friends/$twitter_id.json?page=";
-       $twitter_user = twitter_user_info($screen_name, $password);
+    $uri = "http://twitter.com/statuses/friends/$twitter_id.json?page=";
+    $twitter_user = twitter_user_info($screen_name, $password);
 
-       // Calculate how many pages to get...
-       $pages = ceil($twitter_user->friends_count / 100);
+    // Calculate how many pages to get...
+    $pages = ceil($twitter_user->friends_count / 100);
 
-       if ($pages == 0) {
-               common_debug("Twitter bridge - Twitter user $screen_name has no friends! Lame.");
-       }
+    if ($pages == 0) {
+        common_debug("Twitter bridge - Twitter user $screen_name has no friends! Lame.");
+    }
 
-       $friends = array();
+    $friends = array();
 
-       for ($i = 1; $i <= $pages; $i++) {
+    for ($i = 1; $i <= $pages; $i++) {
 
-               $data = get_twitter_data($uri . $i, $screen_name, $password);
+        $data = get_twitter_data($uri . $i, $screen_name, $password);
 
-               if (!$data) {
-                       return NULL;
-               }
+        if (!$data) {
+            return null;
+        }
 
-               $more_friends = json_decode($data);
+        $more_friends = json_decode($data);
 
-               if (!$more_friends) {
-                       return NULL;
-               }
+        if (!$more_friends) {
+            return null;
+        }
 
-               $friends = array_merge($friends, $more_friends);
-       }
+         $friends = array_merge($friends, $more_friends);
+    }
 
-       return $friends;
+    return $friends;
 }
 
-function save_twitter_friends($user, $twitter_id, $screen_name, $password) {
+function save_twitter_friends($user, $twitter_id, $screen_name, $password)
+{
 
-       $friends = retreive_twitter_friends($twitter_id, $screen_name, $password);
+    $friends = retreive_twitter_friends($twitter_id, $screen_name, $password);
 
-       if (is_null($friends)) {
-               common_debug("Twitter bridge - Couldn't get friends data from Twitter.");
-               return false;
-       }
+    if (is_null($friends)) {
+        common_debug("Twitter bridge - Couldn't get friends data from Twitter.");
+        return false;
+    }
 
     foreach ($friends as $friend) {
 
-               $friend_name = $friend->screen_name;
-               $friend_id = $friend->id;
+        $friend_name = $friend->screen_name;
+        $friend_id = $friend->id;
 
-               // Update or create the Foreign_user record
-               if (!save_twitter_user($friend_id, $friend_name)) {
-                       return false;
-               }
+        // Update or create the Foreign_user record
+        if (!save_twitter_user($friend_id, $friend_name)) {
+            return false;
+        }
 
-               // Check to see if there's a related local user
-               $flink = Foreign_link::getByForeignID($friend_id, 1);
+        // Check to see if there's a related local user
+        $flink = Foreign_link::getByForeignID($friend_id, 1);
 
-               if ($flink) {
+        if ($flink) {
 
-                       // Get associated user and subscribe her
-                       $friend_user = User::staticGet('id', $flink->user_id);
-                       subs_subscribe_to($user, $friend_user);
-                       common_debug("Twitter bridge - subscribed $friend_user->nickname to $user->nickname.");
-               }
-       }
+            // Get associated user and subscribe her
+            $friend_user = User::staticGet('id', $flink->user_id);
+            subs_subscribe_to($user, $friend_user);
+            common_debug("Twitter bridge - subscribed $friend_user->nickname to $user->nickname.");
+        }
+    }
 
-       return true;
+    return true;
 }
 
index 2eb127525c5c0bb1b819e85345ecce506c72e7d1..50bcb06fe9388cdb2fe11eb8789a68849f80c794 100644 (file)
 
 if (!defined('LACONICA')) { exit(1); }
 
-class TwitterapiAction extends Action {
+class TwitterapiAction extends Action
+{
 
-       var $auth_user;
+    var $auth_user;
 
-       function handle($args) {
-               parent::handle($args);
-       }
+    function handle($args)
+    {
+        parent::handle($args);
+    }
 
-       function twitter_user_array($profile, $get_notice=false) {
+    function twitter_user_array($profile, $get_notice=false)
+    {
 
-               $twitter_user = array();
+        $twitter_user = array();
 
-               $twitter_user['name'] = $profile->getBestName();
-               $twitter_user['followers_count'] = $this->count_subscriptions($profile);
-               $twitter_user['screen_name'] = $profile->nickname;
-               $twitter_user['description'] = ($profile->bio) ? $profile->bio : NULL;
-               $twitter_user['location'] = ($profile->location) ? $profile->location : NULL;
-               $twitter_user['id'] = intval($profile->id);
+        $twitter_user['name'] = $profile->getBestName();
+        $twitter_user['followers_count'] = $this->count_subscriptions($profile);
+        $twitter_user['screen_name'] = $profile->nickname;
+        $twitter_user['description'] = ($profile->bio) ? $profile->bio : null;
+        $twitter_user['location'] = ($profile->location) ? $profile->location : null;
+        $twitter_user['id'] = intval($profile->id);
 
-               $avatar = $profile->getAvatar(AVATAR_STREAM_SIZE);
+        $avatar = $profile->getAvatar(AVATAR_STREAM_SIZE);
 
-               $twitter_user['profile_image_url'] = ($avatar) ? common_avatar_display_url($avatar) : common_default_avatar(AVATAR_STREAM_SIZE);
-               $twitter_user['protected'] = 'false'; # not supported by Laconica yet
-               $twitter_user['url'] = ($profile->homepage) ? $profile->homepage : NULL;
+        $twitter_user['profile_image_url'] = ($avatar) ? common_avatar_display_url($avatar) : common_default_avatar(AVATAR_STREAM_SIZE);
+        $twitter_user['protected'] = 'false'; # not supported by Laconica yet
+        $twitter_user['url'] = ($profile->homepage) ? $profile->homepage : null;
 
-               if ($get_notice) {
-                       $notice = $profile->getCurrentNotice();
-                       if ($notice) {
-                               # don't get user!
-                               $twitter_user['status'] = $this->twitter_status_array($notice, false);
-                       }
-               }
+        if ($get_notice) {
+            $notice = $profile->getCurrentNotice();
+            if ($notice) {
+                # don't get user!
+                $twitter_user['status'] = $this->twitter_status_array($notice, false);
+            }
+        }
 
-               return $twitter_user;
-       }
+        return $twitter_user;
+    }
 
-       function twitter_status_array($notice, $include_user=true) {
+    function twitter_status_array($notice, $include_user=true)
+    {
 
-               $profile = $notice->getProfile();
+        $profile = $notice->getProfile();
 
-               $twitter_status = array();
-               $twitter_status['text'] = $notice->content;
-               $twitter_status['truncated'] = 'false'; # Not possible on Laconica
-               $twitter_status['created_at'] = $this->date_twitter($notice->created);
-               $twitter_status['in_reply_to_status_id'] = ($notice->reply_to) ? intval($notice->reply_to) : NULL;
-               $twitter_status['source'] = $this->source_link($notice->source);
-               $twitter_status['id'] = intval($notice->id);
-               $twitter_status['in_reply_to_user_id'] = ($notice->reply_to) ? $this->replier_by_reply(intval($notice->reply_to)) : NULL;
+        $twitter_status = array();
+        $twitter_status['text'] = $notice->content;
+        $twitter_status['truncated'] = 'false'; # Not possible on Laconica
+        $twitter_status['created_at'] = $this->date_twitter($notice->created);
+        $twitter_status['in_reply_to_status_id'] = ($notice->reply_to) ? intval($notice->reply_to) : null;
+        $twitter_status['source'] = $this->source_link($notice->source);
+        $twitter_status['id'] = intval($notice->id);
+        $twitter_status['in_reply_to_user_id'] = ($notice->reply_to) ? $this->replier_by_reply(intval($notice->reply_to)) : null;
 
-               if (isset($this->auth_user)) {
-                       $twitter_status['favorited'] = ($this->auth_user->hasFave($notice)) ? 'true' : 'false';
-               } else {
-                       $twitter_status['favorited'] = 'false';
-               }
+        if (isset($this->auth_user)) {
+            $twitter_status['favorited'] = ($this->auth_user->hasFave($notice)) ? 'true' : 'false';
+        } else {
+            $twitter_status['favorited'] = 'false';
+        }
 
-               if ($include_user) {
-                       # Don't get notice (recursive!)
-                       $twitter_user = $this->twitter_user_array($profile, false);
-                       $twitter_status['user'] = $twitter_user;
-               }
+        if ($include_user) {
+            # Don't get notice (recursive!)
+            $twitter_user = $this->twitter_user_array($profile, false);
+            $twitter_status['user'] = $twitter_user;
+        }
 
-               return $twitter_status;
-       }
+        return $twitter_status;
+    }
 
-       function twitter_rss_entry_array($notice) {
+    function twitter_rss_entry_array($notice)
+    {
 
-               $profile = $notice->getProfile();
+        $profile = $notice->getProfile();
 
-               $server = common_config('site', 'server');
-               $entry = array();
+        $server = common_config('site', 'server');
+        $entry = array();
 
         # We trim() to avoid extraneous whitespace in the output
 
-               $entry['content'] = common_xml_safe_str(trim($notice->rendered));
-               $entry['title'] = $profile->nickname . ': ' . common_xml_safe_str(trim($notice->content));
-               $entry['link'] = common_local_url('shownotice', array('notice' => $notice->id));
-               $entry['published'] = common_date_iso8601($notice->created);
-               $entry['id'] = "tag:$server,2008:$entry[link]";
-               $entry['updated'] = $entry['published'];
-
-               # RSS Item specific
-               $entry['description'] = $entry['content'];
-               $entry['pubDate'] = common_date_rfc2822($notice->created);
-               $entry['guid'] = $entry['link'];
-
-               return $entry;
-       }
-
-       function twitter_rss_dmsg_array($message) {
-
-               $server = common_config('site', 'server');
-               $entry = array();
-
-               $entry['title'] = sprintf('Message from %s to %s',
-                       $message->getFrom()->nickname, $message->getTo()->nickname);
-
-               $entry['content'] = common_xml_safe_str(trim($message->content));
-               $entry['link'] = common_local_url('showmessage', array('message' => $message->id));
-               $entry['published'] = common_date_iso8601($message->created);
-               $entry['id'] = "tag:$server,2008:$entry[link]";
-               $entry['updated'] = $entry['published'];
-
-               # RSS Item specific
-               $entry['description'] = $entry['content'];
-               $entry['pubDate'] = common_date_rfc2822($message->created);
-               $entry['guid'] = $entry['link'];
-
-               return $entry;
-       }
-
-       function twitter_dmsg_array($message) {
-
-               $twitter_dm = array();
-
-               $from_profile = $message->getFrom();
-               $to_profile = $message->getTo();
-
-               $twitter_dm['id'] = $message->id;
-               $twitter_dm['sender_id'] = $message->from_profile;
-               $twitter_dm['text'] = trim($message->content);
-               $twitter_dm['recipient_id'] = $message->to_profile;
-               $twitter_dm['created_at'] = $this->date_twitter($message->created);
-               $twitter_dm['sender_screen_name'] = $from_profile->nickname;
-               $twitter_dm['recipient_screen_name'] = $to_profile->nickname;
-               $twitter_dm['sender'] = $this->twitter_user_array($from_profile, false);
-               $twitter_dm['recipient'] = $this->twitter_user_array($to_profile, false);
-
-               return $twitter_dm;
-       }
-
-       function show_twitter_xml_status($twitter_status) {
-               common_element_start('status');
-               foreach($twitter_status as $element => $value) {
-                       switch ($element) {
-                       case 'user':
-                               $this->show_twitter_xml_user($twitter_status['user']);
-                               break;
-                       case 'text':
-                               common_element($element, NULL, common_xml_safe_str($value));
-                               break;
-                       default:
-                               common_element($element, NULL, $value);
-                       }
-               }
-               common_element_end('status');
-       }
-
-       function show_twitter_xml_user($twitter_user, $role='user') {
-               common_element_start($role);
-               foreach($twitter_user as $element => $value) {
-                       if ($element == 'status') {
-                               $this->show_twitter_xml_status($twitter_user['status']);
-                       } else {
-                               common_element($element, NULL, $value);
-                       }
-               }
-               common_element_end($role);
-       }
-
-       function show_twitter_rss_item($entry) {
-               common_element_start('item');
-               common_element('title', NULL, $entry['title']);
-               common_element('description', NULL, $entry['description']);
-               common_element('pubDate', NULL, $entry['pubDate']);
-               common_element('guid', NULL, $entry['guid']);
-               common_element('link', NULL, $entry['link']);
-               common_element_end('item');
-       }
-
-       function show_twitter_atom_entry($entry) {
-           common_element_start('entry');
-               common_element('title', NULL, $entry['title']);
-               common_element('content', array('type' => 'html'), $entry['content']);
-               common_element('id', NULL, $entry['id']);
-               common_element('published', NULL, $entry['published']);
-               common_element('updated', NULL, $entry['updated']);
-               common_element('link', array('href' => $entry['link'], 'rel' => 'alternate', 'type' => 'text/html'), NULL);
-               common_element_end('entry');
-       }
-
-       function show_json_objects($objects) {
-               print(json_encode($objects));
-       }
-
-       function show_single_xml_status($notice) {
-               $this->init_document('xml');
-               $twitter_status = $this->twitter_status_array($notice);
-               $this->show_twitter_xml_status($twitter_status);
-               $this->end_document('xml');
-       }
-
-       function show_single_json_status($notice) {
-               $this->init_document('json');
-               $status = $this->twitter_status_array($notice);
-               $this->show_json_objects($status);
-               $this->end_document('json');
-       }
-
-       function show_single_xml_dmsg($message) {
-               $this->init_document('xml');
-               $dmsg = $this->twitter_dmsg_array($message);
-               $this->show_twitter_xml_dmsg($dmsg);
-               $this->end_document('xml');
-       }
-
-       function show_single_json_dmsg($message) {
-               $this->init_document('json');
-               $dmsg = $this->twitter_dmsg_array($message);
-               $this->show_json_objects($dmsg);
-               $this->end_document('json');
-       }
-
-       function show_twitter_xml_dmsg($twitter_dm) {
-               common_element_start('direct_message');
-               foreach($twitter_dm as $element => $value) {
-                       switch ($element) {
-                       case 'sender':
-                       case 'recipient':
-                               $this->show_twitter_xml_user($value, $element);
-                               break;
-                       case 'text':
-                               common_element($element, NULL, common_xml_safe_str($value));
-                               break;
-                       default:
-                               common_element($element, NULL, $value);
-                       }
-               }
-               common_element_end('direct_message');
-       }
-
-       function show_xml_timeline($notice) {
-
-               $this->init_document('xml');
-               common_element_start('statuses', array('type' => 'array'));
-
-               if (is_array($notice)) {
-                       foreach ($notice as $n) {
-                               $twitter_status = $this->twitter_status_array($n);
-                               $this->show_twitter_xml_status($twitter_status);
-                       }
-               } else {
-                       while ($notice->fetch()) {
-                               $twitter_status = $this->twitter_status_array($notice);
-                               $this->show_twitter_xml_status($twitter_status);
-                       }
-               }
-
-               common_element_end('statuses');
-               $this->end_document('xml');
-       }
-
-       function show_rss_timeline($notice, $title, $link, $subtitle, $suplink=NULL) {
-
-               $this->init_document('rss');
-
-               common_element_start('channel');
-               common_element('title', NULL, $title);
-               common_element('link', NULL, $link);
-               if (!is_null($suplink)) {
-                       # For FriendFeed's SUP protocol
-                       common_element('link', array('xmlns' => 'http://www.w3.org/2005/Atom',
-                                                                                'rel' => 'http://api.friendfeed.com/2008/03#sup',
-                                                                                'href' => $suplink,
-                                                                                'type' => 'application/json'));
-               }
-               common_element('description', NULL, $subtitle);
-               common_element('language', NULL, 'en-us');
-               common_element('ttl', NULL, '40');
-
-               if (is_array($notice)) {
-                       foreach ($notice as $n) {
-                               $entry = $this->twitter_rss_entry_array($n);
-                               $this->show_twitter_rss_item($entry);
-                       }
-               } else {
-                       while ($notice->fetch()) {
-                               $entry = $this->twitter_rss_entry_array($notice);
-                               $this->show_twitter_rss_item($entry);
-                       }
-               }
-
-               common_element_end('channel');
-               $this->end_twitter_rss();
-       }
-
-       function show_atom_timeline($notice, $title, $id, $link, $subtitle=NULL, $suplink=NULL) {
-
-               $this->init_document('atom');
-
-               common_element('title', NULL, $title);
-               common_element('id', NULL, $id);
-               common_element('link', array('href' => $link, 'rel' => 'alternate', 'type' => 'text/html'), NULL);
-               if (!is_null($suplink)) {
-                       # For FriendFeed's SUP protocol
-                       common_element('link', array('rel' => 'http://api.friendfeed.com/2008/03#sup',
-                                                                                'href' => $suplink,
-                                                                                'type' => 'application/json'));
-               }
-               common_element('subtitle', NULL, $subtitle);
-
-               if (is_array($notice)) {
-                       foreach ($notice as $n) {
-                               $entry = $this->twitter_rss_entry_array($n);
-                               $this->show_twitter_atom_entry($entry);
-                       }
-               } else {
-                       while ($notice->fetch()) {
-                               $entry = $this->twitter_rss_entry_array($notice);
-                               $this->show_twitter_atom_entry($entry);
-                       }
-               }
-
-               $this->end_document('atom');
-
-       }
-
-       function show_json_timeline($notice) {
-
-               $this->init_document('json');
-
-               $statuses = array();
-
-               if (is_array($notice)) {
-                       foreach ($notice as $n) {
-                               $twitter_status = $this->twitter_status_array($n);
-                               array_push($statuses, $twitter_status);
-                       }
-               } else {
-                       while ($notice->fetch()) {
-                               $twitter_status = $this->twitter_status_array($notice);
-                               array_push($statuses, $twitter_status);
-                       }
-               }
-
-               $this->show_json_objects($statuses);
-
-               $this->end_document('json');
-       }
-
-       // Anyone know what date format this is?
-       // Twitter's dates look like this: "Mon Jul 14 23:52:38 +0000 2008" -- Zach
-       function date_twitter($dt) {
-               $t = strtotime($dt);
-               return date("D M d G:i:s O Y", $t);
-       }
-
-       function replier_by_reply($reply_id) {
-               $notice = Notice::staticGet($reply_id);
-               if ($notice) {
-                       $profile = $notice->getProfile();
-                       if ($profile) {
-                               return intval($profile->id);
-                       } else {
-                               common_debug('Can\'t find a profile for notice: ' . $notice->id, __FILE__);
-                       }
-               } else {
-                       common_debug("Can't get notice: $reply_id", __FILE__);
-               }
-               return NULL;
-       }
-
-       // XXX: Candidate for a general utility method somewhere?
-       function count_subscriptions($profile) {
-
-               $count = 0;
-               $sub = new Subscription();
-               $sub->subscribed = $profile->id;
-
-               $count = $sub->find();
-
-               if ($count > 0) {
-                       return $count - 1;
-               } else {
-                       return 0;
-               }
-       }
-
-       function init_document($type='xml') {
-               switch ($type) {
-                case 'xml':
-                       header('Content-Type: application/xml; charset=utf-8');
-                       common_start_xml();
-                       break;
-                case 'json':
-                       header('Content-Type: application/json; charset=utf-8');
-
-                       // Check for JSONP callback
-                       $callback = $this->arg('callback');
-                       if ($callback) {
-                               print $callback . '(';
-                       }
-                       break;
-                case 'rss':
-                       header("Content-Type: application/rss+xml; charset=utf-8");
-                       $this->init_twitter_rss();
-                       break;
-                case 'atom':
-                       header('Content-Type: application/atom+xml; charset=utf-8');
-                       $this->init_twitter_atom();
-                       break;
-                default:
-                       $this->client_error(_('Not a supported data format.'));
-                       break;
-               }
-
-               return;
-       }
-
-       function end_document($type='xml') {
-               switch ($type) {
-                case 'xml':
-                       common_end_xml();
-                       break;
-                case 'json':
-
-                       // Check for JSONP callback
-                       $callback = $this->arg('callback');
-                       if ($callback) {
-                               print ')';
-                       }
-                       break;
-                case 'rss':
-                       $this->end_twitter_rss();
-                       break;
-                case 'atom':
-                       $this->end_twitter_rss();
-                       break;
-                default:
-                       $this->client_error(_('Not a supported data format.'));
-                       break;
-               }
-               return;
-       }
-
-       function client_error($msg, $code = 400, $content_type = 'json') {
-
-               static $status = array(400 => 'Bad Request',
-                                                          401 => 'Unauthorized',
-                                                          402 => 'Payment Required',
-                                                          403 => 'Forbidden',
-                                                          404 => 'Not Found',
-                                                          405 => 'Method Not Allowed',
-                                                          406 => 'Not Acceptable',
-                                                          407 => 'Proxy Authentication Required',
-                                                          408 => 'Request Timeout',
-                                                          409 => 'Conflict',
-                                                          410 => 'Gone',
-                                                          411 => 'Length Required',
-                                                          412 => 'Precondition Failed',
-                                                          413 => 'Request Entity Too Large',
-                                                          414 => 'Request-URI Too Long',
-                                                          415 => 'Unsupported Media Type',
-                                                          416 => 'Requested Range Not Satisfiable',
-                                                          417 => 'Expectation Failed');
-
-               $action = $this->trimmed('action');
-
-               common_debug("User error '$code' on '$action': $msg", __FILE__);
-
-               if (!array_key_exists($code, $status)) {
-                       $code = 400;
-               }
-
-               $status_string = $status[$code];
-               header('HTTP/1.1 '.$code.' '.$status_string);
-
-               if ($content_type == 'xml') {
-                       $this->init_document('xml');
-                       common_element_start('hash');
-                       common_element('error', NULL, $msg);
-                       common_element('request', NULL, $_SERVER['REQUEST_URI']);
-                       common_element_end('hash');
-                       $this->end_document('xml');
-               } else {
-                       $this->init_document('json');
-                       $error_array = array('error' => $msg, 'request' => $_SERVER['REQUEST_URI']);
-                       print(json_encode($error_array));
-                       $this->end_document('json');
-               }
-
-       }
-
-       function init_twitter_rss() {
-               common_start_xml();
-               common_element_start('rss', array('version' => '2.0'));
-       }
-
-       function end_twitter_rss() {
-               common_element_end('rss');
-               common_end_xml();
-       }
-
-       function init_twitter_atom() {
-               common_start_xml();
-               common_element_start('feed', array('xmlns' => 'http://www.w3.org/2005/Atom', 'xml:lang' => 'en-US'));
-       }
-
-       function end_twitter_atom() {
-               common_end_xml();
-               common_element_end('feed');
-       }
-
-       function show_profile($profile, $content_type='xml', $notice=NULL) {
-               $profile_array = $this->twitter_user_array($profile, true);
-               switch ($content_type) {
-                case 'xml':
-                       $this->show_twitter_xml_user($profile_array);
-                       break;
-                case 'json':
-                       $this->show_json_objects($profile_array);
-                       break;
-                default:
-                       $this->client_error(_('Not a supported data format.'));
-                       return;
-               }
-               return;
-       }
-
-       function get_user($id, $apidata=NULL) {
-               if (!$id) {
-                       return $apidata['user'];
-               } else if (is_numeric($id)) {
-                       return User::staticGet($id);
-               } else {
-                       $nickname = common_canonical_nickname($id);
-                       return User::staticGet('nickname', $nickname);
-               }
-       }
-
-       function get_profile($id) {
-               if (is_numeric($id)) {
-                       return Profile::staticGet($id);
-               } else {
-                       $user = User::staticGet('nickname', $id);
-                       if ($user) {
-                               return $user->getProfile();
-                       } else {
-                               return NULL;
-                       }
-               }
-       }
-
-       function source_link($source) {
-               $source_name = _($source);
-               switch ($source) {
-                case 'web':
-                case 'xmpp':
-                case 'mail':
-                case 'omb':
-                case 'api':
-                       break;
-                default:
-                       $ns = Notice_source::staticGet($source);
-                       if ($ns) {
-                               $source_name = '<a href="' . $ns->url . '">' . $ns->name . '</a>';
-                       }
-                       break;
-               }
-               return $source_name;
-       }
-
-       function show_extended_profile($user, $apidata) {
-
-               $this->auth_user = $apidata['user'];
-
-               $profile = $user->getProfile();
-
-               if (!$profile) {
-                       common_server_error(_('User has no profile.'));
-                       return;
-               }
-
-               $twitter_user = $this->twitter_user_array($profile, true);
-
-               // Add in extended user fields offered up by this method
-               $twitter_user['created_at'] = $this->date_twitter($profile->created);
-
-               $subbed = DB_DataObject::factory('subscription');
-               $subbed->subscriber = $profile->id;
-               $subbed_count = (int) $subbed->count() - 1;
-
-               $notices = DB_DataObject::factory('notice');
-               $notices->profile_id = $profile->id;
-               $notice_count = (int) $notices->count();
-
-               $twitter_user['friends_count'] = (is_int($subbed_count)) ? $subbed_count : 0;
-               $twitter_user['statuses_count'] = (is_int($notice_count)) ? $notice_count : 0;
-
-               // Other fields Twitter sends...
-               $twitter_user['profile_background_color'] = '';
-               $twitter_user['profile_text_color'] = '';
-               $twitter_user['profile_link_color'] = '';
-               $twitter_user['profile_sidebar_fill_color'] = '';
-
-               $faves = DB_DataObject::factory('fave');
-               $faves->user_id = $user->id;
-               $faves_count = (int) $faves->count();
-               $twitter_user['favourites_count'] = $faves_count;
-
-               $timezone = 'UTC';
-
-               if ($user->timezone) {
-                       $timezone = $user->timezone;
-               }
-
-               $t = new DateTime;
-               $t->setTimezone(new DateTimeZone($timezone));
-               $twitter_user['utc_offset'] = $t->format('Z');
-               $twitter_user['time_zone'] = $timezone;
-
-               $following = 'false';
-
-               if (isset($this->auth_user)) {
-                       if ($this->auth_user->isSubscribed($profile)) {
-                               $following = 'true';
-                       }
-
-                       // Not implemented yet
-                       $twitter_user['notifications'] = 'false';
-               }
-
-               $twitter_user['following'] = $following;
-
-               if ($apidata['content-type'] == 'xml') {
-                       $this->init_document('xml');
-                       $this->show_twitter_xml_user($twitter_user);
-                       $this->end_document('xml');
-               } elseif ($apidata['content-type'] == 'json') {
-                       $this->init_document('json');
-                       $this->show_json_objects($twitter_user);
-                       $this->end_document('json');
-               }
-
-       }
+        $entry['content'] = common_xml_safe_str(trim($notice->rendered));
+        $entry['title'] = $profile->nickname . ': ' . common_xml_safe_str(trim($notice->content));
+        $entry['link'] = common_local_url('shownotice', array('notice' => $notice->id));
+        $entry['published'] = common_date_iso8601($notice->created);
+        $entry['id'] = "tag:$server,2008:$entry[link]";
+        $entry['updated'] = $entry['published'];
+
+        # RSS Item specific
+        $entry['description'] = $entry['content'];
+        $entry['pubDate'] = common_date_rfc2822($notice->created);
+        $entry['guid'] = $entry['link'];
+
+        return $entry;
+    }
+
+    function twitter_rss_dmsg_array($message)
+    {
+
+        $server = common_config('site', 'server');
+        $entry = array();
+
+        $entry['title'] = sprintf('Message from %s to %s',
+            $message->getFrom()->nickname, $message->getTo()->nickname);
+
+        $entry['content'] = common_xml_safe_str(trim($message->content));
+        $entry['link'] = common_local_url('showmessage', array('message' => $message->id));
+        $entry['published'] = common_date_iso8601($message->created);
+        $entry['id'] = "tag:$server,2008:$entry[link]";
+        $entry['updated'] = $entry['published'];
+
+        # RSS Item specific
+        $entry['description'] = $entry['content'];
+        $entry['pubDate'] = common_date_rfc2822($message->created);
+        $entry['guid'] = $entry['link'];
+
+        return $entry;
+    }
+
+    function twitter_dmsg_array($message)
+    {
+
+        $twitter_dm = array();
+
+        $from_profile = $message->getFrom();
+        $to_profile = $message->getTo();
+
+        $twitter_dm['id'] = $message->id;
+        $twitter_dm['sender_id'] = $message->from_profile;
+        $twitter_dm['text'] = trim($message->content);
+        $twitter_dm['recipient_id'] = $message->to_profile;
+        $twitter_dm['created_at'] = $this->date_twitter($message->created);
+        $twitter_dm['sender_screen_name'] = $from_profile->nickname;
+        $twitter_dm['recipient_screen_name'] = $to_profile->nickname;
+        $twitter_dm['sender'] = $this->twitter_user_array($from_profile, false);
+        $twitter_dm['recipient'] = $this->twitter_user_array($to_profile, false);
+
+        return $twitter_dm;
+    }
+
+    function show_twitter_xml_status($twitter_status)
+    {
+        common_element_start('status');
+        foreach($twitter_status as $element => $value) {
+            switch ($element) {
+            case 'user':
+                $this->show_twitter_xml_user($twitter_status['user']);
+                break;
+            case 'text':
+                common_element($element, null, common_xml_safe_str($value));
+                break;
+            default:
+                common_element($element, null, $value);
+            }
+        }
+        common_element_end('status');
+    }
+
+    function show_twitter_xml_user($twitter_user, $role='user')
+    {
+        common_element_start($role);
+        foreach($twitter_user as $element => $value) {
+            if ($element == 'status') {
+                $this->show_twitter_xml_status($twitter_user['status']);
+            } else {
+                common_element($element, null, $value);
+            }
+        }
+        common_element_end($role);
+    }
+
+    function show_twitter_rss_item($entry)
+    {
+        common_element_start('item');
+        common_element('title', null, $entry['title']);
+        common_element('description', null, $entry['description']);
+        common_element('pubDate', null, $entry['pubDate']);
+        common_element('guid', null, $entry['guid']);
+        common_element('link', null, $entry['link']);
+        common_element_end('item');
+    }
+
+    function show_twitter_atom_entry($entry)
+    {
+        common_element_start('entry');
+        common_element('title', null, $entry['title']);
+        common_element('content', array('type' => 'html'), $entry['content']);
+        common_element('id', null, $entry['id']);
+        common_element('published', null, $entry['published']);
+        common_element('updated', null, $entry['updated']);
+        common_element('link', array('href' => $entry['link'], 'rel' => 'alternate', 'type' => 'text/html'), null);
+        common_element_end('entry');
+    }
+
+    function show_json_objects($objects)
+    {
+        print(json_encode($objects));
+    }
+
+    function show_single_xml_status($notice)
+    {
+        $this->init_document('xml');
+        $twitter_status = $this->twitter_status_array($notice);
+        $this->show_twitter_xml_status($twitter_status);
+        $this->end_document('xml');
+    }
+
+    function show_single_json_status($notice)
+    {
+        $this->init_document('json');
+        $status = $this->twitter_status_array($notice);
+        $this->show_json_objects($status);
+        $this->end_document('json');
+    }
+
+    function show_single_xml_dmsg($message)
+    {
+        $this->init_document('xml');
+        $dmsg = $this->twitter_dmsg_array($message);
+        $this->show_twitter_xml_dmsg($dmsg);
+        $this->end_document('xml');
+    }
+
+    function show_single_json_dmsg($message)
+    {
+        $this->init_document('json');
+        $dmsg = $this->twitter_dmsg_array($message);
+        $this->show_json_objects($dmsg);
+        $this->end_document('json');
+    }
+
+    function show_twitter_xml_dmsg($twitter_dm)
+    {
+        common_element_start('direct_message');
+        foreach($twitter_dm as $element => $value) {
+            switch ($element) {
+            case 'sender':
+            case 'recipient':
+                $this->show_twitter_xml_user($value, $element);
+                break;
+            case 'text':
+                common_element($element, null, common_xml_safe_str($value));
+                break;
+            default:
+                common_element($element, null, $value);
+            }
+        }
+        common_element_end('direct_message');
+    }
+
+    function show_xml_timeline($notice)
+    {
+
+        $this->init_document('xml');
+        common_element_start('statuses', array('type' => 'array'));
+
+        if (is_array($notice)) {
+            foreach ($notice as $n) {
+                $twitter_status = $this->twitter_status_array($n);
+                $this->show_twitter_xml_status($twitter_status);
+            }
+        } else {
+            while ($notice->fetch()) {
+                $twitter_status = $this->twitter_status_array($notice);
+                $this->show_twitter_xml_status($twitter_status);
+            }
+        }
+
+        common_element_end('statuses');
+        $this->end_document('xml');
+    }
+
+    function show_rss_timeline($notice, $title, $link, $subtitle, $suplink=null)
+    {
+
+        $this->init_document('rss');
+
+        common_element_start('channel');
+        common_element('title', null, $title);
+        common_element('link', null, $link);
+        if (!is_null($suplink)) {
+            # For FriendFeed's SUP protocol
+            common_element('link', array('xmlns' => 'http://www.w3.org/2005/Atom',
+                                         'rel' => 'http://api.friendfeed.com/2008/03#sup',
+                                         'href' => $suplink,
+                                         'type' => 'application/json'));
+        }
+        common_element('description', null, $subtitle);
+        common_element('language', null, 'en-us');
+        common_element('ttl', null, '40');
+
+        if (is_array($notice)) {
+            foreach ($notice as $n) {
+                $entry = $this->twitter_rss_entry_array($n);
+                $this->show_twitter_rss_item($entry);
+            }
+        } else {
+            while ($notice->fetch()) {
+                $entry = $this->twitter_rss_entry_array($notice);
+                $this->show_twitter_rss_item($entry);
+            }
+        }
+
+        common_element_end('channel');
+        $this->end_twitter_rss();
+    }
+
+    function show_atom_timeline($notice, $title, $id, $link, $subtitle=null, $suplink=null)
+    {
+
+        $this->init_document('atom');
+
+        common_element('title', null, $title);
+        common_element('id', null, $id);
+        common_element('link', array('href' => $link, 'rel' => 'alternate', 'type' => 'text/html'), null);
+        if (!is_null($suplink)) {
+            # For FriendFeed's SUP protocol
+            common_element('link', array('rel' => 'http://api.friendfeed.com/2008/03#sup',
+                                         'href' => $suplink,
+                                         'type' => 'application/json'));
+        }
+        common_element('subtitle', null, $subtitle);
+
+        if (is_array($notice)) {
+            foreach ($notice as $n) {
+                $entry = $this->twitter_rss_entry_array($n);
+                $this->show_twitter_atom_entry($entry);
+            }
+        } else {
+            while ($notice->fetch()) {
+                $entry = $this->twitter_rss_entry_array($notice);
+                $this->show_twitter_atom_entry($entry);
+            }
+        }
+
+        $this->end_document('atom');
+
+    }
+
+    function show_json_timeline($notice)
+    {
+
+        $this->init_document('json');
+
+        $statuses = array();
+
+        if (is_array($notice)) {
+            foreach ($notice as $n) {
+                $twitter_status = $this->twitter_status_array($n);
+                array_push($statuses, $twitter_status);
+            }
+        } else {
+            while ($notice->fetch()) {
+                $twitter_status = $this->twitter_status_array($notice);
+                array_push($statuses, $twitter_status);
+            }
+        }
+
+        $this->show_json_objects($statuses);
+
+        $this->end_document('json');
+    }
+
+    // Anyone know what date format this is?
+    // Twitter's dates look like this: "Mon Jul 14 23:52:38 +0000 2008" -- Zach
+    function date_twitter($dt)
+    {
+        $t = strtotime($dt);
+        return date("D M d G:i:s O Y", $t);
+    }
+
+    function replier_by_reply($reply_id)
+    {
+        $notice = Notice::staticGet($reply_id);
+        if ($notice) {
+            $profile = $notice->getProfile();
+            if ($profile) {
+                return intval($profile->id);
+            } else {
+                common_debug('Can\'t find a profile for notice: ' . $notice->id, __FILE__);
+            }
+        } else {
+            common_debug("Can't get notice: $reply_id", __FILE__);
+        }
+        return null;
+    }
+
+    // XXX: Candidate for a general utility method somewhere?
+    function count_subscriptions($profile)
+    {
+
+        $count = 0;
+        $sub = new Subscription();
+        $sub->subscribed = $profile->id;
+
+        $count = $sub->find();
+
+        if ($count > 0) {
+            return $count - 1;
+        } else {
+            return 0;
+        }
+    }
+
+    function init_document($type='xml')
+    {
+        switch ($type) {
+         case 'xml':
+            header('Content-Type: application/xml; charset=utf-8');
+            common_start_xml();
+            break;
+         case 'json':
+            header('Content-Type: application/json; charset=utf-8');
+
+            // Check for JSONP callback
+            $callback = $this->arg('callback');
+            if ($callback) {
+                print $callback . '(';
+            }
+            break;
+         case 'rss':
+            header("Content-Type: application/rss+xml; charset=utf-8");
+            $this->init_twitter_rss();
+            break;
+         case 'atom':
+            header('Content-Type: application/atom+xml; charset=utf-8');
+            $this->init_twitter_atom();
+            break;
+         default:
+            $this->client_error(_('Not a supported data format.'));
+            break;
+        }
+
+        return;
+    }
+
+    function end_document($type='xml')
+    {
+        switch ($type) {
+         case 'xml':
+            common_end_xml();
+            break;
+         case 'json':
+
+            // Check for JSONP callback
+            $callback = $this->arg('callback');
+            if ($callback) {
+                print ')';
+            }
+            break;
+         case 'rss':
+            $this->end_twitter_rss();
+            break;
+         case 'atom':
+            $this->end_twitter_rss();
+            break;
+         default:
+            $this->client_error(_('Not a supported data format.'));
+            break;
+        }
+        return;
+    }
+
+    function client_error($msg, $code = 400, $content_type = 'json')
+    {
+
+        static $status = array(400 => 'Bad Request',
+                               401 => 'Unauthorized',
+                               402 => 'Payment Required',
+                               403 => 'Forbidden',
+                               404 => 'Not Found',
+                               405 => 'Method Not Allowed',
+                               406 => 'Not Acceptable',
+                               407 => 'Proxy Authentication Required',
+                               408 => 'Request Timeout',
+                               409 => 'Conflict',
+                               410 => 'Gone',
+                               411 => 'Length Required',
+                               412 => 'Precondition Failed',
+                               413 => 'Request Entity Too Large',
+                               414 => 'Request-URI Too Long',
+                               415 => 'Unsupported Media Type',
+                               416 => 'Requested Range Not Satisfiable',
+                               417 => 'Expectation Failed');
+
+        $action = $this->trimmed('action');
+
+        common_debug("User error '$code' on '$action': $msg", __FILE__);
+
+        if (!array_key_exists($code, $status)) {
+            $code = 400;
+        }
+
+        $status_string = $status[$code];
+        header('HTTP/1.1 '.$code.' '.$status_string);
+
+        if ($content_type == 'xml') {
+            $this->init_document('xml');
+            common_element_start('hash');
+            common_element('error', null, $msg);
+            common_element('request', null, $_SERVER['REQUEST_URI']);
+            common_element_end('hash');
+            $this->end_document('xml');
+        } else {
+            $this->init_document('json');
+            $error_array = array('error' => $msg, 'request' => $_SERVER['REQUEST_URI']);
+            print(json_encode($error_array));
+            $this->end_document('json');
+        }
+
+    }
+
+    function init_twitter_rss()
+    {
+        common_start_xml();
+        common_element_start('rss', array('version' => '2.0'));
+    }
+
+    function end_twitter_rss()
+    {
+        common_element_end('rss');
+        common_end_xml();
+    }
+
+    function init_twitter_atom()
+    {
+        common_start_xml();
+        common_element_start('feed', array('xmlns' => 'http://www.w3.org/2005/Atom', 'xml:lang' => 'en-US'));
+    }
+
+    function end_twitter_atom()
+    {
+        common_end_xml();
+        common_element_end('feed');
+    }
+
+    function show_profile($profile, $content_type='xml', $notice=null)
+    {
+        $profile_array = $this->twitter_user_array($profile, true);
+        switch ($content_type) {
+         case 'xml':
+            $this->show_twitter_xml_user($profile_array);
+            break;
+         case 'json':
+            $this->show_json_objects($profile_array);
+            break;
+         default:
+            $this->client_error(_('Not a supported data format.'));
+            return;
+        }
+        return;
+    }
+
+    function get_user($id, $apidata=null)
+    {
+        if (!$id) {
+            return $apidata['user'];
+        } else if (is_numeric($id)) {
+            return User::staticGet($id);
+        } else {
+            $nickname = common_canonical_nickname($id);
+            return User::staticGet('nickname', $nickname);
+        }
+    }
+
+    function get_profile($id)
+    {
+        if (is_numeric($id)) {
+            return Profile::staticGet($id);
+        } else {
+            $user = User::staticGet('nickname', $id);
+            if ($user) {
+                return $user->getProfile();
+            } else {
+                return null;
+            }
+        }
+    }
+
+    function source_link($source)
+    {
+        $source_name = _($source);
+        switch ($source) {
+         case 'web':
+         case 'xmpp':
+         case 'mail':
+         case 'omb':
+         case 'api':
+            break;
+         default:
+            $ns = Notice_source::staticGet($source);
+            if ($ns) {
+                $source_name = '<a href="' . $ns->url . '">' . $ns->name . '</a>';
+            }
+            break;
+        }
+        return $source_name;
+    }
+
+    function show_extended_profile($user, $apidata)
+    {
+
+        $this->auth_user = $apidata['user'];
+
+        $profile = $user->getProfile();
+
+        if (!$profile) {
+            common_server_error(_('User has no profile.'));
+            return;
+        }
+
+        $twitter_user = $this->twitter_user_array($profile, true);
+
+        // Add in extended user fields offered up by this method
+        $twitter_user['created_at'] = $this->date_twitter($profile->created);
+
+        $subbed = DB_DataObject::factory('subscription');
+        $subbed->subscriber = $profile->id;
+        $subbed_count = (int) $subbed->count() - 1;
+
+        $notices = DB_DataObject::factory('notice');
+        $notices->profile_id = $profile->id;
+        $notice_count = (int) $notices->count();
+
+        $twitter_user['friends_count'] = (is_int($subbed_count)) ? $subbed_count : 0;
+        $twitter_user['statuses_count'] = (is_int($notice_count)) ? $notice_count : 0;
+
+        // Other fields Twitter sends...
+        $twitter_user['profile_background_color'] = '';
+        $twitter_user['profile_text_color'] = '';
+        $twitter_user['profile_link_color'] = '';
+        $twitter_user['profile_sidebar_fill_color'] = '';
+
+        $faves = DB_DataObject::factory('fave');
+        $faves->user_id = $user->id;
+        $faves_count = (int) $faves->count();
+        $twitter_user['favourites_count'] = $faves_count;
+
+        $timezone = 'UTC';
+
+        if ($user->timezone) {
+            $timezone = $user->timezone;
+        }
+
+        $t = new DateTime;
+        $t->setTimezone(new DateTimeZone($timezone));
+        $twitter_user['utc_offset'] = $t->format('Z');
+        $twitter_user['time_zone'] = $timezone;
+
+        $following = 'false';
+
+        if (isset($this->auth_user)) {
+            if ($this->auth_user->isSubscribed($profile)) {
+                $following = 'true';
+            }
+
+            // Not implemented yet
+            $twitter_user['notifications'] = 'false';
+        }
+
+        $twitter_user['following'] = $following;
+
+        if ($apidata['content-type'] == 'xml') {
+            $this->init_document('xml');
+            $this->show_twitter_xml_user($twitter_user);
+            $this->end_document('xml');
+        } elseif ($apidata['content-type'] == 'json') {
+            $this->init_document('json');
+            $this->show_json_objects($twitter_user);
+            $this->end_document('json');
+        }
+
+    }
 
 }
\ No newline at end of file
index 7518fbf5595edc5636e0a45764564a18e2f21627..fbe04c6c4aebb2b0b33781685138c08ffc858272 100644 (file)
 
 /* XXX: break up into separate modules (HTTP, HTML, user, files) */
 
-# Show a server error
-
-function common_server_error($msg, $code=500) {
-       static $status = array(500 => 'Internal Server Error',
-                                                  501 => 'Not Implemented',
-                                                  502 => 'Bad Gateway',
-                                                  503 => 'Service Unavailable',
-                                                  504 => 'Gateway Timeout',
-                                                  505 => 'HTTP Version Not Supported');
-
-       if (!array_key_exists($code, $status)) {
-               $code = 500;
-       }
-
-       $status_string = $status[$code];
-
-       header('HTTP/1.1 '.$code.' '.$status_string);
-       header('Content-type: text/plain');
-
-       print $msg;
-       print "\n";
-       exit();
-}
-
-# Show a user error
-function common_user_error($msg, $code=400) {
-       static $status = array(400 => 'Bad Request',
-                                                  401 => 'Unauthorized',
-                                                  402 => 'Payment Required',
-                                                  403 => 'Forbidden',
-                                                  404 => 'Not Found',
-                                                  405 => 'Method Not Allowed',
-                                                  406 => 'Not Acceptable',
-                                                  407 => 'Proxy Authentication Required',
-                                                  408 => 'Request Timeout',
-                                                  409 => 'Conflict',
-                                                  410 => 'Gone',
-                                                  411 => 'Length Required',
-                                                  412 => 'Precondition Failed',
-                                                  413 => 'Request Entity Too Large',
-                                                  414 => 'Request-URI Too Long',
-                                                  415 => 'Unsupported Media Type',
-                                                  416 => 'Requested Range Not Satisfiable',
-                                                  417 => 'Expectation Failed');
-
-       if (!array_key_exists($code, $status)) {
-               $code = 400;
-       }
-
-       $status_string = $status[$code];
-
-       header('HTTP/1.1 '.$code.' '.$status_string);
-
-       common_show_header('Error');
-       common_element('div', array('class' => 'error'), $msg);
-       common_show_footer();
+// Show a server error
+
+function common_server_error($msg, $code=500)
+{
+    static $status = array(500 => 'Internal Server Error',
+                           501 => 'Not Implemented',
+                           502 => 'Bad Gateway',
+                           503 => 'Service Unavailable',
+                           504 => 'Gateway Timeout',
+                           505 => 'HTTP Version Not Supported');
+
+    if (!array_key_exists($code, $status)) {
+        $code = 500;
+    }
+
+    $status_string = $status[$code];
+
+    header('HTTP/1.1 '.$code.' '.$status_string);
+    header('Content-type: text/plain');
+
+    print $msg;
+    print "\n";
+    exit();
+}
+
+// Show a user error
+function common_user_error($msg, $code=400)
+{
+    static $status = array(400 => 'Bad Request',
+                           401 => 'Unauthorized',
+                           402 => 'Payment Required',
+                           403 => 'Forbidden',
+                           404 => 'Not Found',
+                           405 => 'Method Not Allowed',
+                           406 => 'Not Acceptable',
+                           407 => 'Proxy Authentication Required',
+                           408 => 'Request Timeout',
+                           409 => 'Conflict',
+                           410 => 'Gone',
+                           411 => 'Length Required',
+                           412 => 'Precondition Failed',
+                           413 => 'Request Entity Too Large',
+                           414 => 'Request-URI Too Long',
+                           415 => 'Unsupported Media Type',
+                           416 => 'Requested Range Not Satisfiable',
+                           417 => 'Expectation Failed');
+
+    if (!array_key_exists($code, $status)) {
+        $code = 400;
+    }
+
+    $status_string = $status[$code];
+
+    header('HTTP/1.1 '.$code.' '.$status_string);
+
+    common_show_header('Error');
+    common_element('div', array('class' => 'error'), $msg);
+    common_show_footer();
 }
 
 $xw = null;
 
-# Start an HTML element
-function common_element_start($tag, $attrs=NULL) {
-       global $xw;
-       $xw->startElement($tag);
-       if (is_array($attrs)) {
-               foreach ($attrs as $name => $value) {
-                       $xw->writeAttribute($name, $value);
-               }
-       } else if (is_string($attrs)) {
-               $xw->writeAttribute('class', $attrs);
-       }
-}
-
-function common_element_end($tag) {
-       static $empty_tag = array('base', 'meta', 'link', 'hr',
-                                                         'br', 'param', 'img', 'area',
-                                                         'input', 'col');
-       global $xw;
-       # XXX: check namespace
-       if (in_array($tag, $empty_tag)) {
-               $xw->endElement();
-       } else {
-               $xw->fullEndElement();
-       }
-}
-
-function common_element($tag, $attrs=NULL, $content=NULL) {
-       common_element_start($tag, $attrs);
-       global $xw;
-       if (!is_null($content)) {
-               $xw->text($content);
-       }
-       common_element_end($tag);
-}
-
-function common_start_xml($doc=NULL, $public=NULL, $system=NULL, $indent=true) {
-       global $xw;
-       $xw = new XMLWriter();
-       $xw->openURI('php://output');
-       $xw->setIndent($indent);
-       $xw->startDocument('1.0', 'UTF-8');
-       if ($doc) {
-               $xw->writeDTD($doc, $public, $system);
-       }
-}
-
-function common_end_xml() {
-       global $xw;
-       $xw->endDocument();
-       $xw->flush();
-}
-
-function common_init_locale($language=null) {
+// Start an HTML element
+function common_element_start($tag, $attrs=null)
+{
+    global $xw;
+    $xw->startElement($tag);
+    if (is_array($attrs)) {
+        foreach ($attrs as $name => $value) {
+            $xw->writeAttribute($name, $value);
+        }
+    } else if (is_string($attrs)) {
+        $xw->writeAttribute('class', $attrs);
+    }
+}
+
+function common_element_end($tag)
+{
+    static $empty_tag = array('base', 'meta', 'link', 'hr',
+                              'br', 'param', 'img', 'area',
+                              'input', 'col');
+    global $xw;
+    // XXX: check namespace
+    if (in_array($tag, $empty_tag)) {
+        $xw->endElement();
+    } else {
+        $xw->fullEndElement();
+    }
+}
+
+function common_element($tag, $attrs=null, $content=null)
+{
+    common_element_start($tag, $attrs);
+    global $xw;
+    if (!is_null($content)) {
+        $xw->text($content);
+    }
+    common_element_end($tag);
+}
+
+function common_start_xml($doc=null, $public=null, $system=null, $indent=true)
+{
+    global $xw;
+    $xw = new XMLWriter();
+    $xw->openURI('php://output');
+    $xw->setIndent($indent);
+    $xw->startDocument('1.0', 'UTF-8');
+    if ($doc) {
+        $xw->writeDTD($doc, $public, $system);
+    }
+}
+
+function common_end_xml()
+{
+    global $xw;
+    $xw->endDocument();
+    $xw->flush();
+}
+
+function common_init_locale($language=null)
+{
     if(!$language) {
         $language = common_language();
     }
     putenv('LANGUAGE='.$language);
     putenv('LANG='.$language);
     return setlocale(LC_ALL, $language . ".utf8",
-            $language . ".UTF8",
-            $language . ".utf-8",
-            $language . ".UTF-8",
-            $language);
-}
-
-function common_init_language() {
-       mb_internal_encoding('UTF-8');
-       $language = common_language();
-       # So we don't have to make people install the gettext locales
-       $locale_set = common_init_locale($language);
-       bindtextdomain("laconica", common_config('site','locale_path'));
-       bind_textdomain_codeset("laconica", "UTF-8");
-       textdomain("laconica");
-       setlocale(LC_CTYPE, 'C');
-       if(!$locale_set) {
-               common_log(LOG_INFO,'Language requested:'.$language.' - locale could not be set:',__FILE__);
-       }
+                     $language . ".UTF8",
+                     $language . ".utf-8",
+                     $language . ".UTF-8",
+                     $language);
+}
+
+function common_init_language()
+{
+    mb_internal_encoding('UTF-8');
+    $language = common_language();
+    // So we don't have to make people install the gettext locales
+    $locale_set = common_init_locale($language);
+    bindtextdomain("laconica", common_config('site','locale_path'));
+    bind_textdomain_codeset("laconica", "UTF-8");
+    textdomain("laconica");
+    setlocale(LC_CTYPE, 'C');
+    if(!$locale_set) {
+        common_log(LOG_INFO,'Language requested:'.$language.' - locale could not be set:',__FILE__);
+    }
 }
 
 define('PAGE_TYPE_PREFS', 'text/html,application/xhtml+xml,application/xml;q=0.3,text/xml;q=0.2');
 
-function common_show_header($pagetitle, $callable=NULL, $data=NULL, $headercall=NULL) {
+function common_show_header($pagetitle, $callable=null, $data=null, $headercall=null)
+{
 
-       global $config, $xw;
+    global $config, $xw;
     global $action; /* XXX: kind of cheating here. */
 
-       common_start_html();
-
-       common_element_start('head');
-       common_element('title', NULL,
-                                  $pagetitle . " - " . $config['site']['name']);
-       common_element('link', array('rel' => 'stylesheet',
-                                                                'type' => 'text/css',
-                                                                'href' => theme_path('display.css') . '?version=' . LACONICA_VERSION,
-                                                                'media' => 'screen, projection, tv'));
-       foreach (array(6,7) as $ver) {
-               if (file_exists(theme_file('ie'.$ver.'.css'))) {
-                       # Yes, IE people should be put in jail.
-                       $xw->writeComment('[if lte IE '.$ver.']><link rel="stylesheet" type="text/css" '.
-                                                         'href="'.theme_path('ie'.$ver.'.css').'?version='.LACONICA_VERSION.'" /><![endif]');
-               }
-       }
-
-       common_element('script', array('type' => 'text/javascript',
-                                                                  'src' => common_path('js/jquery.min.js')),
-                                  ' ');
-       common_element('script', array('type' => 'text/javascript',
-                                                                  'src' => common_path('js/jquery.form.js')),
-                                  ' ');
-       common_element('script', array('type' => 'text/javascript',
-                                                                  'src' => common_path('js/xbImportNode.js')),
-                                  ' ');
-       common_element('script', array('type' => 'text/javascript',
-                                                                  'src' => common_path('js/util.js?version='.LACONICA_VERSION)),
-                                  ' ');
-       common_element('link', array('rel' => 'search', 'type' => 'application/opensearchdescription+xml',
-                                        'href' =>  common_local_url('opensearch', array('type' => 'people')),
-                                        'title' => common_config('site', 'name').' People Search'));
-
-       common_element('link', array('rel' => 'search', 'type' => 'application/opensearchdescription+xml',
-                                        'href' =>  common_local_url('opensearch', array('type' => 'notice')),
-                                        'title' => common_config('site', 'name').' Notice Search'));
-
-       if ($callable) {
-               if ($data) {
-                       call_user_func($callable, $data);
-               } else {
-                       call_user_func($callable);
-               }
-       }
-       common_element_end('head');
-       common_element_start('body', $action);
-       common_element_start('div', array('id' => 'wrap'));
-       common_element_start('div', array('id' => 'header'));
-       common_nav_menu();
-       if ((isset($config['site']['logo']) && is_string($config['site']['logo']) && (strlen($config['site']['logo']) > 0))
-               || file_exists(theme_file('logo.png')))
-       {
-               common_element_start('a', array('href' => common_local_url('public')));
-               common_element('img', array('src' => isset($config['site']['logo']) ?
-                                                                       ($config['site']['logo']) : theme_path('logo.png'),
-                                                                       'alt' => $config['site']['name'],
-                                                                       'id' => 'logo'));
-               common_element_end('a');
-       } else {
-               common_element_start('p', array('id' => 'branding'));
-               common_element('a', array('href' => common_local_url('public')),
-                                          $config['site']['name']);
-               common_element_end('p');
-       }
-
-       common_element('h1', 'pagetitle', $pagetitle);
-
-       if ($headercall) {
-               if ($data) {
-                       call_user_func($headercall, $data);
-               } else {
-                       call_user_func($headercall);
-               }
-       }
-       common_element_end('div');
-       common_element_start('div', array('id' => 'content'));
-}
-
-function common_start_html($type=NULL, $indent=true) {
-
-       if (!$type) {
-               $httpaccept = isset($_SERVER['HTTP_ACCEPT']) ? $_SERVER['HTTP_ACCEPT'] : NULL;
-
-               # XXX: allow content negotiation for RDF, RSS, or XRDS
-
-               $type = common_negotiate_type(common_accept_to_prefs($httpaccept),
-                                                                         common_accept_to_prefs(PAGE_TYPE_PREFS));
-
-               if (!$type) {
-                       common_user_error(_('This page is not available in a media type you accept'), 406);
-                       exit(0);
-               }
-       }
-
-       header('Content-Type: '.$type);
-
-       common_start_xml('html',
-                                        '-//W3C//DTD XHTML 1.0 Strict//EN',
-                                        'http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd', $indent);
-
-       # FIXME: correct language for interface
-
-       $language = common_language();
-
-       common_element_start('html', array('xmlns' => 'http://www.w3.org/1999/xhtml',
-                                                                          'xml:lang' => $language,
-                                                                          'lang' => $language));
-}
-
-function common_show_footer() {
-       global $xw, $config;
-       common_element_end('div'); # content div
-       common_foot_menu();
-       common_element_start('div', array('id' => 'footer'));
-       common_element_start('div', 'laconica');
-       if (common_config('site', 'broughtby')) {
-               $instr = _('**%%site.name%%** is a microblogging service brought to you by [%%site.broughtby%%](%%site.broughtbyurl%%). ');
-       } else {
-               $instr = _('**%%site.name%%** is a microblogging service. ');
-       }
-       $instr .= sprintf(_('It runs the [Laconica](http://laconi.ca/) microblogging software, version %s, available under the [GNU Affero General Public License](http://www.fsf.org/licensing/licenses/agpl-3.0.html).'), LACONICA_VERSION);
+    common_start_html();
+
+    common_element_start('head');
+    common_element('title', null,
+                   $pagetitle . " - " . $config['site']['name']);
+    common_element('link', array('rel' => 'stylesheet',
+                                 'type' => 'text/css',
+                                 'href' => theme_path('display.css') . '?version=' . LACONICA_VERSION,
+                                 'media' => 'screen, projection, tv'));
+    foreach (array(6,7) as $ver) {
+        if (file_exists(theme_file('ie'.$ver.'.css'))) {
+            // Yes, IE people should be put in jail.
+            $xw->writeComment('[if lte IE '.$ver.']><link rel="stylesheet" type="text/css" '.
+                              'href="'.theme_path('ie'.$ver.'.css').'?version='.LACONICA_VERSION.'" /><![endif]');
+        }
+    }
+
+    common_element('script', array('type' => 'text/javascript',
+                                   'src' => common_path('js/jquery.min.js')),
+                   ' ');
+    common_element('script', array('type' => 'text/javascript',
+                                   'src' => common_path('js/jquery.form.js')),
+                   ' ');
+    common_element('script', array('type' => 'text/javascript',
+                                   'src' => common_path('js/xbImportNode.js')),
+                   ' ');
+    common_element('script', array('type' => 'text/javascript',
+                                   'src' => common_path('js/util.js?version='.LACONICA_VERSION)),
+                   ' ');
+    common_element('link', array('rel' => 'search', 'type' => 'application/opensearchdescription+xml',
+                                 'href' =>  common_local_url('opensearch', array('type' => 'people')),
+                                 'title' => common_config('site', 'name').' People Search'));
+
+    common_element('link', array('rel' => 'search', 'type' => 'application/opensearchdescription+xml',
+                                 'href' =>  common_local_url('opensearch', array('type' => 'notice')),
+                                 'title' => common_config('site', 'name').' Notice Search'));
+
+    if ($callable) {
+        if ($data) {
+            call_user_func($callable, $data);
+        } else {
+            call_user_func($callable);
+        }
+    }
+    common_element_end('head');
+    common_element_start('body', $action);
+    common_element_start('div', array('id' => 'wrap'));
+    common_element_start('div', array('id' => 'header'));
+    common_nav_menu();
+    if ((isset($config['site']['logo']) && is_string($config['site']['logo']) && (strlen($config['site']['logo']) > 0))
+        || file_exists(theme_file('logo.png')))
+    {
+        common_element_start('a', array('href' => common_local_url('public')));
+        common_element('img', array('src' => isset($config['site']['logo']) ?
+                                    ($config['site']['logo']) : theme_path('logo.png'),
+                                    'alt' => $config['site']['name'],
+                                    'id' => 'logo'));
+        common_element_end('a');
+    } else {
+        common_element_start('p', array('id' => 'branding'));
+        common_element('a', array('href' => common_local_url('public')),
+                       $config['site']['name']);
+        common_element_end('p');
+    }
+
+    common_element('h1', 'pagetitle', $pagetitle);
+
+    if ($headercall) {
+        if ($data) {
+            call_user_func($headercall, $data);
+        } else {
+            call_user_func($headercall);
+        }
+    }
+    common_element_end('div');
+    common_element_start('div', array('id' => 'content'));
+}
+
+function common_start_html($type=null, $indent=true)
+{
+
+    if (!$type) {
+        $httpaccept = isset($_SERVER['HTTP_ACCEPT']) ? $_SERVER['HTTP_ACCEPT'] : null;
+
+        // XXX: allow content negotiation for RDF, RSS, or XRDS
+
+        $type = common_negotiate_type(common_accept_to_prefs($httpaccept),
+                                      common_accept_to_prefs(PAGE_TYPE_PREFS));
+
+        if (!$type) {
+            common_user_error(_('This page is not available in a media type you accept'), 406);
+            exit(0);
+        }
+    }
+
+    header('Content-Type: '.$type);
+
+    common_start_xml('html',
+                     '-//W3C//DTD XHTML 1.0 Strict//EN',
+                     'http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd', $indent);
+
+    // FIXME: correct language for interface
+
+    $language = common_language();
+
+    common_element_start('html', array('xmlns' => 'http://www.w3.org/1999/xhtml',
+                                       'xml:lang' => $language,
+                                       'lang' => $language));
+}
+
+function common_show_footer()
+{
+    global $xw, $config;
+    common_element_end('div'); // content div
+    common_foot_menu();
+    common_element_start('div', array('id' => 'footer'));
+    common_element_start('div', 'laconica');
+    if (common_config('site', 'broughtby')) {
+        $instr = _('**%%site.name%%** is a microblogging service brought to you by [%%site.broughtby%%](%%site.broughtbyurl%%). ');
+    } else {
+        $instr = _('**%%site.name%%** is a microblogging service. ');
+    }
+    $instr .= sprintf(_('It runs the [Laconica](http://laconi.ca/) microblogging software, version %s, available under the [GNU Affero General Public License](http://www.fsf.org/licensing/licenses/agpl-3.0.html).'), LACONICA_VERSION);
     $output = common_markup_to_html($instr);
     common_raw($output);
-       common_element_end('div');
-       common_element('img', array('id' => 'cc',
-                                                               'src' => $config['license']['image'],
-                                                               'alt' => $config['license']['title']));
-       common_element_start('p');
-       common_text(_('Unless otherwise specified, contents of this site are copyright by the contributors and available under the '));
-       common_element('a', array('class' => 'license',
-                                                         'rel' => 'license',
-                                                         'href' => $config['license']['url']),
-                                  $config['license']['title']);
-       common_text(_('. Contributors should be attributed by full name or nickname.'));
-       common_element_end('p');
-       common_element_end('div');
-       common_element_end('div');
-       common_element_end('body');
-       common_element_end('html');
-       common_end_xml();
-}
-
-function common_text($txt) {
-       global $xw;
-       $xw->text($txt);
-}
-
-function common_raw($xml) {
-       global $xw;
-       $xw->writeRaw($xml);
-}
-
-function common_nav_menu() {
-       $user = common_current_user();
-       common_element_start('ul', array('id' => 'nav'));
-       if ($user) {
-               common_menu_item(common_local_url('all', array('nickname' => $user->nickname)),
-                                                _('Home'));
-       }
-       common_menu_item(common_local_url('peoplesearch'), _('Search'));
-       if ($user) {
-               common_menu_item(common_local_url('profilesettings'),
-                                                _('Settings'));
-               common_menu_item(common_local_url('invite'),
-                                                _('Invite'));
-               common_menu_item(common_local_url('logout'),
-                                                _('Logout'));
-       } else {
-               common_menu_item(common_local_url('login'), _('Login'));
-               if (!common_config('site', 'closed')) {
-                       common_menu_item(common_local_url('register'), _('Register'));
-               }
-               common_menu_item(common_local_url('openidlogin'), _('OpenID'));
-       }
-       common_menu_item(common_local_url('doc', array('title' => 'help')),
-                                        _('Help'));
-       common_element_end('ul');
-}
-
-function common_foot_menu() {
-       common_element_start('ul', array('id' => 'nav_sub'));
-       common_menu_item(common_local_url('doc', array('title' => 'help')),
-                                        _('Help'));
-       common_menu_item(common_local_url('doc', array('title' => 'about')),
-                                        _('About'));
-       common_menu_item(common_local_url('doc', array('title' => 'faq')),
-                                        _('FAQ'));
-       common_menu_item(common_local_url('doc', array('title' => 'privacy')),
-                                        _('Privacy'));
-       common_menu_item(common_local_url('doc', array('title' => 'source')),
-                                        _('Source'));
-       common_menu_item(common_local_url('doc', array('title' => 'contact')),
-                                        _('Contact'));
-       common_element_end('ul');
-}
-
-function common_menu_item($url, $text, $title=NULL, $is_selected=false) {
-       $lattrs = array();
-       if ($is_selected) {
-               $lattrs['class'] = 'current';
-       }
-       common_element_start('li', $lattrs);
-       $attrs['href'] = $url;
-       if ($title) {
-               $attrs['title'] = $title;
-       }
-       common_element('a', $attrs, $text);
-       common_element_end('li');
-}
-
-function common_input($id, $label, $value=NULL,$instructions=NULL) {
-       common_element_start('p');
-       common_element('label', array('for' => $id), $label);
-       $attrs = array('name' => $id,
-                                  'type' => 'text',
-                                  'class' => 'input_text',
-                                  'id' => $id);
-       if ($value) {
-               $attrs['value'] = htmlspecialchars($value);
-       }
-       common_element('input', $attrs);
-       if ($instructions) {
-               common_element('span', 'input_instructions', $instructions);
-       }
-       common_element_end('p');
-}
-
-function common_checkbox($id, $label, $checked=false, $instructions=NULL, $value='true', $disabled=false)
-{
-       common_element_start('p');
-       $attrs = array('name' => $id,
-                                  'type' => 'checkbox',
-                                  'class' => 'checkbox',
-                                  'id' => $id);
-       if ($value) {
-               $attrs['value'] = htmlspecialchars($value);
-       }
-       if ($checked) {
-               $attrs['checked'] = 'checked';
-       }
-       if ($disabled) {
-               $attrs['disabled'] = 'true';
-       }
-       common_element('input', $attrs);
-       common_text(' ');
-       common_element('label', array('class' => 'checkbox_label', 'for' => $id), $label);
-       common_text(' ');
-       if ($instructions) {
-               common_element('span', 'input_instructions', $instructions);
-       }
-       common_element_end('p');
-}
-
-function common_dropdown($id, $label, $content, $instructions=NULL, $blank_select=FALSE, $selected=NULL) {
-       common_element_start('p');
-       common_element('label', array('for' => $id), $label);
-       common_element_start('select', array('id' => $id, 'name' => $id));
-       if ($blank_select) {
-               common_element('option', array('value' => ''));
-       }
-       foreach ($content as $value => $option) {
-               if ($value == $selected) {
-                       common_element('option', array('value' => $value, 'selected' => $value), $option);
-               } else {
-                       common_element('option', array('value' => $value), $option);
-               }
-       }
-       common_element_end('select');
-       if ($instructions) {
-               common_element('span', 'input_instructions', $instructions);
-       }
-       common_element_end('p');
-}
-function common_hidden($id, $value) {
-       common_element('input', array('name' => $id,
-                                                                 'type' => 'hidden',
-                                                                 'id' => $id,
-                                                                 'value' => $value));
-}
-
-function common_password($id, $label, $instructions=NULL) {
-       common_element_start('p');
-       common_element('label', array('for' => $id), $label);
-       $attrs = array('name' => $id,
-                                  'type' => 'password',
-                                  'class' => 'password',
-                                  'id' => $id);
-       common_element('input', $attrs);
-       if ($instructions) {
-               common_element('span', 'input_instructions', $instructions);
-       }
-       common_element_end('p');
-}
-
-function common_submit($id, $label, $cls='submit') {
-       global $xw;
-       common_element_start('p');
-       common_element('input', array('type' => 'submit',
-                                                                 'id' => $id,
-                                                                 'name' => $id,
-                                                                 'class' => $cls,
-                                                                 'value' => $label));
-       common_element_end('p');
-}
-
-function common_textarea($id, $label, $content=NULL, $instructions=NULL) {
-       common_element_start('p');
-       common_element('label', array('for' => $id), $label);
-       common_element('textarea', array('rows' => 3,
-                                                                        'cols' => 40,
-                                                                        'name' => $id,
-                                                                        'id' => $id),
-                                  ($content) ? $content : '');
-       if ($instructions) {
-               common_element('span', 'input_instructions', $instructions);
-       }
-       common_element_end('p');
-}
-
-function common_timezone() {
-       if (common_logged_in()) {
-               $user = common_current_user();
-               if ($user->timezone) {
-                       return $user->timezone;
-               }
-       }
-
-       global $config;
-       return $config['site']['timezone'];
-}
-
-function common_language() {
-
-       // If there is a user logged in and they've set a language preference
-       // then return that one...
-        if (common_logged_in()) {
-                $user = common_current_user();
-                $user_language = $user->language;
-               if ($user_language)
-                       return $user_language;
+    common_element_end('div');
+    common_element('img', array('id' => 'cc',
+                                'src' => $config['license']['image'],
+                                'alt' => $config['license']['title']));
+    common_element_start('p');
+    common_text(_('Unless otherwise specified, contents of this site are copyright by the contributors and available under the '));
+    common_element('a', array('class' => 'license',
+                              'rel' => 'license',
+                              'href' => $config['license']['url']),
+                   $config['license']['title']);
+    common_text(_('. Contributors should be attributed by full name or nickname.'));
+    common_element_end('p');
+    common_element_end('div');
+    common_element_end('div');
+    common_element_end('body');
+    common_element_end('html');
+    common_end_xml();
+}
+
+function common_text($txt)
+{
+    global $xw;
+    $xw->text($txt);
+}
+
+function common_raw($xml)
+{
+    global $xw;
+    $xw->writeRaw($xml);
+}
+
+function common_nav_menu()
+{
+    $user = common_current_user();
+    common_element_start('ul', array('id' => 'nav'));
+    if ($user) {
+        common_menu_item(common_local_url('all', array('nickname' => $user->nickname)),
+                         _('Home'));
+    }
+    common_menu_item(common_local_url('peoplesearch'), _('Search'));
+    if ($user) {
+        common_menu_item(common_local_url('profilesettings'),
+                         _('Settings'));
+        common_menu_item(common_local_url('invite'),
+                         _('Invite'));
+        common_menu_item(common_local_url('logout'),
+                         _('Logout'));
+    } else {
+        common_menu_item(common_local_url('login'), _('Login'));
+        if (!common_config('site', 'closed')) {
+            common_menu_item(common_local_url('register'), _('Register'));
+        }
+        common_menu_item(common_local_url('openidlogin'), _('OpenID'));
+    }
+    common_menu_item(common_local_url('doc', array('title' => 'help')),
+                     _('Help'));
+    common_element_end('ul');
+}
+
+function common_foot_menu()
+{
+    common_element_start('ul', array('id' => 'nav_sub'));
+    common_menu_item(common_local_url('doc', array('title' => 'help')),
+                     _('Help'));
+    common_menu_item(common_local_url('doc', array('title' => 'about')),
+                     _('About'));
+    common_menu_item(common_local_url('doc', array('title' => 'faq')),
+                     _('FAQ'));
+    common_menu_item(common_local_url('doc', array('title' => 'privacy')),
+                     _('Privacy'));
+    common_menu_item(common_local_url('doc', array('title' => 'source')),
+                     _('Source'));
+    common_menu_item(common_local_url('doc', array('title' => 'contact')),
+                     _('Contact'));
+    common_element_end('ul');
+}
+
+function common_menu_item($url, $text, $title=null, $is_selected=false)
+{
+    $lattrs = array();
+    if ($is_selected) {
+        $lattrs['class'] = 'current';
+    }
+    common_element_start('li', $lattrs);
+    $attrs['href'] = $url;
+    if ($title) {
+        $attrs['title'] = $title;
+    }
+    common_element('a', $attrs, $text);
+    common_element_end('li');
+}
+
+function common_input($id, $label, $value=null,$instructions=null)
+{
+    common_element_start('p');
+    common_element('label', array('for' => $id), $label);
+    $attrs = array('name' => $id,
+                   'type' => 'text',
+                   'class' => 'input_text',
+                   'id' => $id);
+    if ($value) {
+        $attrs['value'] = htmlspecialchars($value);
+    }
+    common_element('input', $attrs);
+    if ($instructions) {
+        common_element('span', 'input_instructions', $instructions);
+    }
+    common_element_end('p');
+}
+
+function common_checkbox($id, $label, $checked=false, $instructions=null, $value='true', $disabled=false)
+{
+    common_element_start('p');
+    $attrs = array('name' => $id,
+                   'type' => 'checkbox',
+                   'class' => 'checkbox',
+                   'id' => $id);
+    if ($value) {
+        $attrs['value'] = htmlspecialchars($value);
+    }
+    if ($checked) {
+        $attrs['checked'] = 'checked';
+    }
+    if ($disabled) {
+        $attrs['disabled'] = 'true';
+    }
+    common_element('input', $attrs);
+    common_text(' ');
+    common_element('label', array('class' => 'checkbox_label', 'for' => $id), $label);
+    common_text(' ');
+    if ($instructions) {
+        common_element('span', 'input_instructions', $instructions);
+    }
+    common_element_end('p');
+}
+
+function common_dropdown($id, $label, $content, $instructions=null, $blank_select=false, $selected=null)
+{
+    common_element_start('p');
+    common_element('label', array('for' => $id), $label);
+    common_element_start('select', array('id' => $id, 'name' => $id));
+    if ($blank_select) {
+        common_element('option', array('value' => ''));
+    }
+    foreach ($content as $value => $option) {
+        if ($value == $selected) {
+            common_element('option', array('value' => $value, 'selected' => $value), $option);
+        } else {
+            common_element('option', array('value' => $value), $option);
+        }
+    }
+    common_element_end('select');
+    if ($instructions) {
+        common_element('span', 'input_instructions', $instructions);
+    }
+    common_element_end('p');
+}
+function common_hidden($id, $value)
+{
+    common_element('input', array('name' => $id,
+                                  'type' => 'hidden',
+                                  'id' => $id,
+                                  'value' => $value));
+}
+
+function common_password($id, $label, $instructions=null)
+{
+    common_element_start('p');
+    common_element('label', array('for' => $id), $label);
+    $attrs = array('name' => $id,
+                   'type' => 'password',
+                   'class' => 'password',
+                   'id' => $id);
+    common_element('input', $attrs);
+    if ($instructions) {
+        common_element('span', 'input_instructions', $instructions);
+    }
+    common_element_end('p');
+}
+
+function common_submit($id, $label, $cls='submit')
+{
+    global $xw;
+    common_element_start('p');
+    common_element('input', array('type' => 'submit',
+                                  'id' => $id,
+                                  'name' => $id,
+                                  'class' => $cls,
+                                  'value' => $label));
+    common_element_end('p');
+}
+
+function common_textarea($id, $label, $content=null, $instructions=null)
+{
+    common_element_start('p');
+    common_element('label', array('for' => $id), $label);
+    common_element('textarea', array('rows' => 3,
+                                     'cols' => 40,
+                                     'name' => $id,
+                                     'id' => $id),
+                   ($content) ? $content : '');
+    if ($instructions) {
+        common_element('span', 'input_instructions', $instructions);
+    }
+    common_element_end('p');
+}
+
+function common_timezone()
+{
+    if (common_logged_in()) {
+        $user = common_current_user();
+        if ($user->timezone) {
+            return $user->timezone;
         }
+    }
+
+    global $config;
+    return $config['site']['timezone'];
+}
+
+function common_language()
+{
+
+    // If there is a user logged in and they've set a language preference
+    // then return that one...
+    if (common_logged_in()) {
+        $user = common_current_user();
+        $user_language = $user->language;
+        if ($user_language)
+          return $user_language;
+    }
 
-       // Otherwise, find the best match for the languages requested by the
-       // user's browser...
-       $httplang = isset($_SERVER['HTTP_ACCEPT_LANGUAGE']) ? $_SERVER['HTTP_ACCEPT_LANGUAGE'] : NULL;
-       if (!empty($httplang)) {
-               $language = client_prefered_language($httplang);
-               if ($language)
-                       return $language;
-       }
+    // Otherwise, find the best match for the languages requested by the
+    // user's browser...
+    $httplang = isset($_SERVER['HTTP_ACCEPT_LANGUAGE']) ? $_SERVER['HTTP_ACCEPT_LANGUAGE'] : null;
+    if (!empty($httplang)) {
+        $language = client_prefered_language($httplang);
+        if ($language)
+          return $language;
+    }
 
-       // Finally, if none of the above worked, use the site's default...
-       return common_config('site', 'language');
+    // Finally, if none of the above worked, use the site's default...
+    return common_config('site', 'language');
 }
-# salted, hashed passwords are stored in the DB
+// salted, hashed passwords are stored in the DB
 
-function common_munge_password($password, $id) {
-       return md5($password . $id);
+function common_munge_password($password, $id)
+{
+    return md5($password . $id);
 }
 
-# check if a username exists and has matching password
-function common_check_user($nickname, $password) {
-       # NEVER allow blank passwords, even if they match the DB
-       if (mb_strlen($password) == 0) {
-               return false;
-       }
-       $user = User::staticGet('nickname', $nickname);
-       if (is_null($user)) {
-               return false;
-       } else {
-               if (0 == strcmp(common_munge_password($password, $user->id),
-                                               $user->password)) {
-                       return $user;
-               } else {
-                       return false;
-               }
-       }
+// check if a username exists and has matching password
+function common_check_user($nickname, $password)
+{
+    // NEVER allow blank passwords, even if they match the DB
+    if (mb_strlen($password) == 0) {
+        return false;
+    }
+    $user = User::staticGet('nickname', $nickname);
+    if (is_null($user)) {
+        return false;
+    } else {
+        if (0 == strcmp(common_munge_password($password, $user->id),
+                        $user->password)) {
+            return $user;
+        } else {
+            return false;
+        }
+    }
 }
 
-# is the current user logged in?
-function common_logged_in() {
-       return (!is_null(common_current_user()));
+// is the current user logged in?
+function common_logged_in()
+{
+    return (!is_null(common_current_user()));
 }
 
-function common_have_session() {
-       return (0 != strcmp(session_id(), ''));
+function common_have_session()
+{
+    return (0 != strcmp(session_id(), ''));
 }
 
-function common_ensure_session() {
-       if (!common_have_session()) {
-               @session_start();
-       }
+function common_ensure_session()
+{
+    if (!common_have_session()) {
+        @session_start();
+    }
 }
 
-# Three kinds of arguments:
-# 1) a user object
-# 2) a nickname
-# 3) NULL to clear
+// Three kinds of arguments:
+// 1) a user object
+// 2) a nickname
+// 3) null to clear
 
-# Initialize to false; set to NULL if none found
+// Initialize to false; set to null if none found
 
 $_cur = false;
 
-function common_set_user($user) {
+function common_set_user($user)
+{
 
     global $_cur;
 
-       if (is_null($user) && common_have_session()) {
-        $_cur = NULL;
-               unset($_SESSION['userid']);
-               return true;
-       } else if (is_string($user)) {
-               $nickname = $user;
-               $user = User::staticGet('nickname', $nickname);
-       } else if (!($user instanceof User)) {
-               return false;
-       }
-
-       if ($user) {
-               common_ensure_session();
-               $_SESSION['userid'] = $user->id;
+    if (is_null($user) && common_have_session()) {
+        $_cur = null;
+        unset($_SESSION['userid']);
+        return true;
+    } else if (is_string($user)) {
+        $nickname = $user;
+        $user = User::staticGet('nickname', $nickname);
+    } else if (!($user instanceof User)) {
+        return false;
+    }
+
+    if ($user) {
+        common_ensure_session();
+        $_SESSION['userid'] = $user->id;
         $_cur = $user;
-               return $_cur;
-       }
-       return false;
+        return $_cur;
+    }
+    return false;
 }
 
-function common_set_cookie($key, $value, $expiration=0) {
-       $path = common_config('site', 'path');
-       $server = common_config('site', 'server');
+function common_set_cookie($key, $value, $expiration=0)
+{
+    $path = common_config('site', 'path');
+    $server = common_config('site', 'server');
 
-       if ($path && ($path != '/')) {
-               $cookiepath = '/' . $path . '/';
-       } else {
-               $cookiepath = '/';
-       }
-       return setcookie($key,
-                        $value,
-                                $expiration,
-                                        $cookiepath,
-                                    $server);
+    if ($path && ($path != '/')) {
+        $cookiepath = '/' . $path . '/';
+    } else {
+        $cookiepath = '/';
+    }
+    return setcookie($key,
+                     $value,
+                     $expiration,
+                     $cookiepath,
+                     $server);
 }
 
 define('REMEMBERME', 'rememberme');
-define('REMEMBERME_EXPIRY', 30 * 24 * 60 * 60); # 30 days
+define('REMEMBERME_EXPIRY', 30 * 24 * 60 * 60); // 30 days
 
-function common_rememberme($user=NULL) {
-       if (!$user) {
-               $user = common_current_user();
-               if (!$user) {
-                       common_debug('No current user to remember', __FILE__);
-                       return false;
-               }
-       }
+function common_rememberme($user=null)
+{
+    if (!$user) {
+        $user = common_current_user();
+        if (!$user) {
+            common_debug('No current user to remember', __FILE__);
+            return false;
+        }
+    }
 
-       $rm = new Remember_me();
+    $rm = new Remember_me();
 
-       $rm->code = common_good_rand(16);
-       $rm->user_id = $user->id;
+    $rm->code = common_good_rand(16);
+    $rm->user_id = $user->id;
 
-    # Wrap the insert in some good ol' fashioned transaction code
+    // Wrap the insert in some good ol' fashioned transaction code
 
     $rm->query('BEGIN');
 
-       $result = $rm->insert();
+    $result = $rm->insert();
 
-       if (!$result) {
-               common_log_db_error($rm, 'INSERT', __FILE__);
-               common_debug('Error adding rememberme record for ' . $user->nickname, __FILE__);
-               return false;
+    if (!$result) {
+        common_log_db_error($rm, 'INSERT', __FILE__);
+        common_debug('Error adding rememberme record for ' . $user->nickname, __FILE__);
+        return false;
     }
 
     $rm->query('COMMIT');
 
-       common_debug('Inserted rememberme record (' . $rm->code . ', ' . $rm->user_id . '); result = ' . $result . '.', __FILE__);
+    common_debug('Inserted rememberme record (' . $rm->code . ', ' . $rm->user_id . '); result = ' . $result . '.', __FILE__);
 
     $cookieval = $rm->user_id . ':' . $rm->code;
 
-       common_log(LOG_INFO, 'adding rememberme cookie "' . $cookieval . '" for ' . $user->nickname);
+    common_log(LOG_INFO, 'adding rememberme cookie "' . $cookieval . '" for ' . $user->nickname);
 
-       common_set_cookie(REMEMBERME, $cookieval, time() + REMEMBERME_EXPIRY);
+    common_set_cookie(REMEMBERME, $cookieval, time() + REMEMBERME_EXPIRY);
 
-       return true;
+    return true;
 }
 
-function common_remembered_user() {
+function common_remembered_user()
+{
 
-       $user = NULL;
+    $user = null;
 
-       $packed = isset($_COOKIE[REMEMBERME]) ? $_COOKIE[REMEMBERME] : NULL;
+    $packed = isset($_COOKIE[REMEMBERME]) ? $_COOKIE[REMEMBERME] : null;
 
-       if (!$packed) {
-        return NULL;
+    if (!$packed) {
+        return null;
     }
 
     list($id, $code) = explode(':', $packed);
@@ -665,7 +699,7 @@ function common_remembered_user() {
     if (!$id || !$code) {
         common_log(LOG_WARNING, 'Malformed rememberme cookie: ' . $packed);
         common_forgetme();
-        return NULL;
+        return null;
     }
 
     $rm = Remember_me::staticGet($code);
@@ -673,13 +707,13 @@ function common_remembered_user() {
     if (!$rm) {
         common_log(LOG_WARNING, 'No such remember code: ' . $code);
         common_forgetme();
-        return NULL;
+        return null;
     }
 
     if ($rm->user_id != $id) {
         common_log(LOG_WARNING, 'Rememberme code for wrong user: ' . $rm->user_id . ' != ' . $id);
         common_forgetme();
-        return NULL;
+        return null;
     }
 
     $user = User::staticGet($rm->user_id);
@@ -687,17 +721,17 @@ function common_remembered_user() {
     if (!$user) {
         common_log(LOG_WARNING, 'No such user for rememberme: ' . $rm->user_id);
         common_forgetme();
-        return NULL;
+        return null;
     }
 
-       # successful!
+    // successful!
     $result = $rm->delete();
 
     if (!$result) {
         common_log_db_error($rm, 'DELETE', __FILE__);
         common_log(LOG_WARNING, 'Could not delete rememberme: ' . $code);
         common_forgetme();
-        return NULL;
+        return null;
     }
 
     common_log(LOG_INFO, 'logging in ' . $user->nickname . ' using rememberme code ' . $rm->code);
@@ -705,22 +739,24 @@ function common_remembered_user() {
     common_set_user($user);
     common_real_login(false);
 
-    # We issue a new cookie, so they can log in
-    # automatically again after this session
+    // We issue a new cookie, so they can log in
+    // automatically again after this session
 
     common_rememberme($user);
 
-       return $user;
+    return $user;
 }
 
-# must be called with a valid user!
+// must be called with a valid user!
 
-function common_forgetme() {
-       common_set_cookie(REMEMBERME, '', 0);
+function common_forgetme()
+{
+    common_set_cookie(REMEMBERME, '', 0);
 }
 
-# who is the current user?
-function common_current_user() {
+// who is the current user?
+function common_current_user()
+{
     global $_cur;
 
     if ($_cur === false) {
@@ -734,1471 +770,1559 @@ function common_current_user() {
             }
         }
 
-        # that didn't work; try to remember; will init $_cur to NULL on failure
+        // that didn't work; try to remember; will init $_cur to null on failure
         $_cur = common_remembered_user();
 
         if ($_cur) {
             common_debug("Got User " . $_cur->nickname);
             common_debug("Faking session on remembered user");
-            # XXX: Is this necessary?
+            // XXX: Is this necessary?
             $_SESSION['userid'] = $_cur->id;
         }
     }
 
-       return $_cur;
+    return $_cur;
 }
 
-# Logins that are 'remembered' aren't 'real' -- they're subject to
-# cookie-stealing. So, we don't let them do certain things. New reg,
-# OpenID, and password logins _are_ real.
+// Logins that are 'remembered' aren't 'real' -- they're subject to
+// cookie-stealing. So, we don't let them do certain things. New reg,
+// OpenID, and password logins _are_ real.
 
-function common_real_login($real=true) {
-       common_ensure_session();
-       $_SESSION['real_login'] = $real;
+function common_real_login($real=true)
+{
+    common_ensure_session();
+    $_SESSION['real_login'] = $real;
 }
 
-function common_is_real_login() {
-       return common_logged_in() && $_SESSION['real_login'];
+function common_is_real_login()
+{
+    return common_logged_in() && $_SESSION['real_login'];
 }
 
-# get canonical version of nickname for comparison
-function common_canonical_nickname($nickname) {
-       # XXX: UTF-8 canonicalization (like combining chars)
-       return strtolower($nickname);
+// get canonical version of nickname for comparison
+function common_canonical_nickname($nickname)
+{
+    // XXX: UTF-8 canonicalization (like combining chars)
+    return strtolower($nickname);
 }
 
-# get canonical version of email for comparison
-function common_canonical_email($email) {
-       # XXX: canonicalize UTF-8
-       # XXX: lcase the domain part
-       return $email;
+// get canonical version of email for comparison
+function common_canonical_email($email)
+{
+    // XXX: canonicalize UTF-8
+    // XXX: lcase the domain part
+    return $email;
 }
 
 define('URL_REGEX', '^|[ \t\r\n])((ftp|http|https|gopher|mailto|news|nntp|telnet|wais|file|prospero|aim|webcal):(([A-Za-z0-9$_.+!*(),;/?:@&~=-])|%[A-Fa-f0-9]{2}){2,}(#([a-zA-Z0-9][a-zA-Z0-9$_.+!*(),;/?:@&~=%-]*))?([A-Za-z0-9$_+!*();/?:~-]))');
 
-function common_render_content($text, $notice) {
-       $r = common_render_text($text);
-       $id = $notice->profile_id;
-       $r = preg_replace('/(^|\s+)@([A-Za-z0-9]{1,64})/e', "'\\1@'.common_at_link($id, '\\2')", $r);
-       $r = preg_replace('/^T ([A-Z0-9]{1,64}) /e', "'T '.common_at_link($id, '\\1').' '", $r);
-       $r = preg_replace('/(^|\s+)@#([A-Za-z0-9]{1,64})/e', "'\\1@#'.common_at_hash_link($id, '\\2')", $r);
-       return $r;
-}
-
-function common_render_text($text) {
-       $r = htmlspecialchars($text);
-
-       $r = preg_replace('/[\x{0}-\x{8}\x{b}-\x{c}\x{e}-\x{19}]/', '', $r);
-       $r = preg_replace_callback('@https?://[^\]>\s]+@', 'common_render_uri_thingy', $r);
-       $r = preg_replace('/(^|\s+)#([A-Za-z0-9_\-\.]{1,64})/e', "'\\1#'.common_tag_link('\\2')", $r);
-       # XXX: machine tags
-       return $r;
-}
-
-function common_render_uri_thingy($matches) {
-       $uri = $matches[0];
-       $trailer = '';
-
-       # Some heuristics for extracting URIs from surrounding punctuation
-       # Strip from trailing text...
-       if (preg_match('/^(.*)([,.:"\']+)$/', $uri, $matches)) {
-               $uri = $matches[1];
-               $trailer = $matches[2];
-       }
-
-       $pairs = array(
-               ']' => '[', # technically disallowed in URIs, but used in Java docs
-               ')' => '(', # far too frequent in Wikipedia and MSDN
-       );
-       $final = substr($uri, -1, 1);
-       if (isset($pairs[$final])) {
-               $openers = substr_count($uri, $pairs[$final]);
-               $closers = substr_count($uri, $final);
-               if ($closers > $openers) {
-                       // Assume the paren was opened outside the URI
-                       $uri = substr($uri, 0, -1);
-                       $trailer = $final . $trailer;
-               }
-       }
-       if ($longurl = common_longurl($uri)) {
-               $longurl = htmlentities($longurl, ENT_QUOTES, 'UTF-8');
-               $title = " title='$longurl'";
-       }
-       else $title = '';
-
-       return '<a href="' . $uri . '"' . $title . ' class="extlink">' . $uri . '</a>' . $trailer;
-}
-
-function common_longurl($short_url)  {
+function common_render_content($text, $notice)
+{
+    $r = common_render_text($text);
+    $id = $notice->profile_id;
+    $r = preg_replace('/(^|\s+)@([A-Za-z0-9]{1,64})/e', "'\\1@'.common_at_link($id, '\\2')", $r);
+    $r = preg_replace('/^T ([A-Z0-9]{1,64}) /e', "'T '.common_at_link($id, '\\1').' '", $r);
+    $r = preg_replace('/(^|\s+)@#([A-Za-z0-9]{1,64})/e', "'\\1@#'.common_at_hash_link($id, '\\2')", $r);
+    return $r;
+}
+
+function common_render_text($text)
+{
+    $r = htmlspecialchars($text);
+
+    $r = preg_replace('/[\x{0}-\x{8}\x{b}-\x{c}\x{e}-\x{19}]/', '', $r);
+    $r = preg_replace_callback('@https?://[^\]>\s]+@', 'common_render_uri_thingy', $r);
+    $r = preg_replace('/(^|\s+)#([A-Za-z0-9_\-\.]{1,64})/e', "'\\1#'.common_tag_link('\\2')", $r);
+    // XXX: machine tags
+    return $r;
+}
+
+function common_render_uri_thingy($matches)
+{
+    $uri = $matches[0];
+    $trailer = '';
+
+    // Some heuristics for extracting URIs from surrounding punctuation
+    // Strip from trailing text...
+    if (preg_match('/^(.*)([,.:"\']+)$/', $uri, $matches)) {
+        $uri = $matches[1];
+        $trailer = $matches[2];
+    }
+
+    $pairs = array(
+                   ']' => '[', // technically disallowed in URIs, but used in Java docs
+                   ')' => '(', // far too frequent in Wikipedia and MSDN
+                   );
+    $final = substr($uri, -1, 1);
+    if (isset($pairs[$final])) {
+        $openers = substr_count($uri, $pairs[$final]);
+        $closers = substr_count($uri, $final);
+        if ($closers > $openers) {
+            // Assume the paren was opened outside the URI
+            $uri = substr($uri, 0, -1);
+            $trailer = $final . $trailer;
+        }
+    }
+    if ($longurl = common_longurl($uri)) {
+        $longurl = htmlentities($longurl, ENT_QUOTES, 'UTF-8');
+        $title = " title='$longurl'";
+    }
+    else $title = '';
+
+    return '<a href="' . $uri . '"' . $title . ' class="extlink">' . $uri . '</a>' . $trailer;
+}
+
+function common_longurl($short_url)
+{
     $long_url = common_shorten_link($short_url, true);
     if ($long_url === $short_url) return false;
     return $long_url;
 }
 
-function common_longurl2($uri)  {
-       $uri_e = urlencode($uri);
-       $longurl = unserialize(file_get_contents("http://api.longurl.org/v1/expand?format=php&url=$uri_e"));
-       if (empty($longurl['long_url']) || $uri === $longurl['long_url']) return false;
-       return stripslashes($longurl['long_url']);
+function common_longurl2($uri)
+{
+    $uri_e = urlencode($uri);
+    $longurl = unserialize(file_get_contents("http://api.longurl.org/v1/expand?format=php&url=$uri_e"));
+    if (empty($longurl['long_url']) || $uri === $longurl['long_url']) return false;
+    return stripslashes($longurl['long_url']);
 }
 
-function common_shorten_links($text) {
+function common_shorten_links($text)
+{
     if (mb_strlen($text) <= 140) return $text;
     static $cache = array();
     if (isset($cache[$text])) return $cache[$text];
     // \s = not a horizontal whitespace character (since PHP 5.2.4)
-       return $cache[$text] = preg_replace('@https?://[^)\]>\s]+@e', "common_shorten_link('\\0')", $text);
+    return $cache[$text] = preg_replace('@https?://[^)\]>\s]+@e', "common_shorten_link('\\0')", $text);
 }
 
-function common_shorten_link($url, $reverse = false) {
-       static $url_cache = array();
+function common_shorten_link($url, $reverse = false)
+{
+    static $url_cache = array();
     if ($reverse) return isset($url_cache[$url]) ? $url_cache[$url] : $url;
 
-       $user = common_current_user();
-
-       $curlh = curl_init();
-       curl_setopt($curlh, CURLOPT_CONNECTTIMEOUT, 20); // # seconds to wait
-       curl_setopt($curlh, CURLOPT_USERAGENT, 'Laconica');
-       curl_setopt($curlh, CURLOPT_RETURNTRANSFER, true);
-
-       switch($user->urlshorteningservice) {
-        case 'ur1.ca':
-            $short_url_service = new LilUrl;
-            $short_url = $short_url_service->shorten($url);
-            break;
-
-        case '2tu.us':
-            $short_url_service = new TightUrl;
-            $short_url = $short_url_service->shorten($url);
-            break;
-
-        case 'ptiturl.com':
-            $short_url_service = new PtitUrl;
-            $short_url = $short_url_service->shorten($url);
-            break;
-
-        case 'bit.ly':
-                       curl_setopt($curlh, CURLOPT_URL, 'http://bit.ly/api?method=shorten&long_url='.urlencode($url));
-                       $short_url = current(json_decode(curl_exec($curlh))->results)->hashUrl;
-            break;
-
-               case 'is.gd':
-                       curl_setopt($curlh, CURLOPT_URL, 'http://is.gd/api.php?longurl='.urlencode($url));
-                       $short_url = curl_exec($curlh);
-                       break;
-               case 'snipr.com':
-                       curl_setopt($curlh, CURLOPT_URL, 'http://snipr.com/site/snip?r=simple&link='.urlencode($url));
-                       $short_url = curl_exec($curlh);
-                       break;
-               case 'metamark.net':
-                       curl_setopt($curlh, CURLOPT_URL, 'http://metamark.net/api/rest/simple?long_url='.urlencode($url));
-                       $short_url = curl_exec($curlh);
-                       break;
-               case 'tinyurl.com':
-                       curl_setopt($curlh, CURLOPT_URL, 'http://tinyurl.com/api-create.php?url='.urlencode($url));
-                       $short_url = curl_exec($curlh);
-                       break;
-               default:
-                       $short_url = false;
-       }
-
-       curl_close($curlh);
-
-       if ($short_url) {
-        $url_cache[(string)$short_url] = $url;
-               return (string)$short_url;
-       }
-       return $url;
-}
-
-function common_xml_safe_str($str) {
-       $xmlStr = htmlentities(iconv('UTF-8', 'UTF-8//IGNORE', $str), ENT_NOQUOTES, 'UTF-8');
-
-       // Replace control, formatting, and surrogate characters with '*', ala Twitter
-       return preg_replace('/[\p{Cc}\p{Cf}\p{Cs}]/u', '*', $str);
-}
-
-function common_tag_link($tag) {
-       $canonical = common_canonical_tag($tag);
-       $url = common_local_url('tag', array('tag' => $canonical));
-       return '<a href="' . htmlspecialchars($url) . '" rel="tag" class="hashlink">' . htmlspecialchars($tag) . '</a>';
-}
-
-function common_canonical_tag($tag) {
-       return strtolower(str_replace(array('-', '_', '.'), '', $tag));
-}
-
-function common_valid_profile_tag($str) {
-       return preg_match('/^[A-Za-z0-9_\-\.]{1,64}$/', $str);
-}
-
-function common_at_link($sender_id, $nickname) {
-       $sender = Profile::staticGet($sender_id);
-       $recipient = common_relative_profile($sender, common_canonical_nickname($nickname));
-       if ($recipient) {
-               return '<a href="'.htmlspecialchars($recipient->profileurl).'" class="atlink">'.$nickname.'</a>';
-       } else {
-               return $nickname;
-       }
-}
-
-function common_at_hash_link($sender_id, $tag) {
-       $user = User::staticGet($sender_id);
-       if (!$user) {
-               return $tag;
-       }
-       $tagged = Profile_tag::getTagged($user->id, common_canonical_tag($tag));
-       if ($tagged) {
-               $url = common_local_url('subscriptions',
-                                                               array('nickname' => $user->nickname,
-                                                                         'tag' => $tag));
-               return '<a href="'.htmlspecialchars($url).'" class="atlink">'.$tag.'</a>';
-       } else {
-               return $tag;
-       }
-}
-
-function common_relative_profile($sender, $nickname, $dt=NULL) {
-       # Try to find profiles this profile is subscribed to that have this nickname
-       $recipient = new Profile();
-       # XXX: use a join instead of a subquery
-       $recipient->whereAdd('EXISTS (SELECT subscribed from subscription where subscriber = '.$sender->id.' and subscribed = id)', 'AND');
-       $recipient->whereAdd('nickname = "' . trim($nickname) . '"', 'AND');
-       if ($recipient->find(TRUE)) {
-               # XXX: should probably differentiate between profiles with
-               # the same name by date of most recent update
-               return $recipient;
-       }
-       # Try to find profiles that listen to this profile and that have this nickname
-       $recipient = new Profile();
-       # XXX: use a join instead of a subquery
-       $recipient->whereAdd('EXISTS (SELECT subscriber from subscription where subscribed = '.$sender->id.' and subscriber = id)', 'AND');
-       $recipient->whereAdd('nickname = "' . trim($nickname) . '"', 'AND');
-       if ($recipient->find(TRUE)) {
-               # XXX: should probably differentiate between profiles with
-               # the same name by date of most recent update
-               return $recipient;
-       }
-       # If this is a local user, try to find a local user with that nickname.
-       $sender = User::staticGet($sender->id);
-       if ($sender) {
-               $recipient_user = User::staticGet('nickname', $nickname);
-               if ($recipient_user) {
-                       return $recipient_user->getProfile();
-               }
-       }
-       # Otherwise, no links. @messages from local users to remote users,
-       # or from remote users to other remote users, are just
-       # outside our ability to make intelligent guesses about
-       return NULL;
-}
-
-// where should the avatar go for this user?
+    $user = common_current_user();
+
+    $curlh = curl_init();
+    curl_setopt($curlh, CURLOPT_CONNECTTIMEOUT, 20); // # seconds to wait
+    curl_setopt($curlh, CURLOPT_USERAGENT, 'Laconica');
+    curl_setopt($curlh, CURLOPT_RETURNTRANSFER, true);
+
+    switch($user->urlshorteningservice) {
+     case 'ur1.ca':
+        $short_url_service = new LilUrl;
+        $short_url = $short_url_service->shorten($url);
+        break;
+
+     case '2tu.us':
+        $short_url_service = new TightUrl;
+        $short_url = $short_url_service->shorten($url);
+        break;
+
+     case 'ptiturl.com':
+        $short_url_service = new PtitUrl;
+        $short_url = $short_url_service->shorten($url);
+        break;
+
+     case 'bit.ly':
+        curl_setopt($curlh, CURLOPT_URL, 'http://bit.ly/api?method=shorten&long_url='.urlencode($url));
+        $short_url = current(json_decode(curl_exec($curlh))->results)->hashUrl;
+        break;
+
+     case 'is.gd':
+        curl_setopt($curlh, CURLOPT_URL, 'http://is.gd/api.php?longurl='.urlencode($url));
+        $short_url = curl_exec($curlh);
+        break;
+     case 'snipr.com':
+        curl_setopt($curlh, CURLOPT_URL, 'http://snipr.com/site/snip?r=simple&link='.urlencode($url));
+        $short_url = curl_exec($curlh);
+        break;
+     case 'metamark.net':
+        curl_setopt($curlh, CURLOPT_URL, 'http://metamark.net/api/rest/simple?long_url='.urlencode($url));
+        $short_url = curl_exec($curlh);
+        break;
+     case 'tinyurl.com':
+        curl_setopt($curlh, CURLOPT_URL, 'http://tinyurl.com/api-create.php?url='.urlencode($url));
+        $short_url = curl_exec($curlh);
+        break;
+     default:
+        $short_url = false;
+    }
 
-function common_avatar_filename($id, $extension, $size=NULL, $extra=NULL) {
-       global $config;
-
-       if ($size) {
-               return $id . '-' . $size . (($extra) ? ('-' . $extra) : '') . $extension;
-       } else {
-               return $id . '-original' . (($extra) ? ('-' . $extra) : '') . $extension;
-       }
-}
-
-function common_avatar_path($filename) {
-       global $config;
-       return INSTALLDIR . '/avatar/' . $filename;
-}
-
-function common_avatar_url($filename) {
-       return common_path('avatar/'.$filename);
-}
-
-function common_avatar_display_url($avatar) {
-       $server = common_config('avatar', 'server');
-       if ($server) {
-               return 'http://'.$server.'/'.$avatar->filename;
-       } else {
-               return $avatar->url;
-       }
-}
-
-function common_default_avatar($size) {
-       static $sizenames = array(AVATAR_PROFILE_SIZE => 'profile',
-                                                         AVATAR_STREAM_SIZE => 'stream',
-                                                         AVATAR_MINI_SIZE => 'mini');
-       return theme_path('default-avatar-'.$sizenames[$size].'.png');
-}
-
-function common_local_url($action, $args=NULL, $fragment=NULL) {
-       $url = NULL;
-       if (common_config('site','fancy')) {
-               $url = common_fancy_url($action, $args);
-       } else {
-               $url = common_simple_url($action, $args);
-       }
-       if (!is_null($fragment)) {
-               $url .= '#'.$fragment;
-       }
-       return $url;
-}
-
-function common_fancy_url($action, $args=NULL) {
-       switch (strtolower($action)) {
-        case 'public':
-               if ($args && isset($args['page'])) {
-                       return common_path('?page=' . $args['page']);
-               } else {
-                       return common_path('');
-               }
-        case 'featured':
-               if ($args && isset($args['page'])) {
-                       return common_path('featured?page=' . $args['page']);
-               } else {
-                       return common_path('featured');
-               }
-        case 'favorited':
-               if ($args && isset($args['page'])) {
-                       return common_path('favorited?page=' . $args['page']);
-               } else {
-                       return common_path('favorited');
-               }
-        case 'publicrss':
-               return common_path('rss');
-        case 'publicatom':
-               return common_path("api/statuses/public_timeline.atom");
-        case 'publicxrds':
-               return common_path('xrds');
-        case 'featuredrss':
-               return common_path('featuredrss');
-        case 'favoritedrss':
-               return common_path('favoritedrss');
-        case 'opensearch':
-                if ($args && $args['type']) {
-                        return common_path('opensearch/'.$args['type']);
-                } else {
-                        return common_path('opensearch/people');
-                }
-        case 'doc':
-               return common_path('doc/'.$args['title']);
-     case 'block':
-        case 'login':
-        case 'logout':
-        case 'subscribe':
-        case 'unsubscribe':
-        case 'invite':
-               return common_path('main/'.$action);
-        case 'tagother':
-               return common_path('main/tagother?id='.$args['id']);
-        case 'register':
-               if ($args && $args['code']) {
-                       return common_path('main/register/'.$args['code']);
-               } else {
-                       return common_path('main/register');
-               }
-        case 'remotesubscribe':
-               if ($args && $args['nickname']) {
-                       return common_path('main/remote?nickname=' . $args['nickname']);
-               } else {
-                       return common_path('main/remote');
-               }
-        case 'nudge':
-               return common_path($args['nickname'].'/nudge');
-        case 'openidlogin':
-               return common_path('main/openid');
-        case 'profilesettings':
-               return common_path('settings/profile');
-        case 'emailsettings':
-               return common_path('settings/email');
-        case 'openidsettings':
-               return common_path('settings/openid');
-        case 'smssettings':
-               return common_path('settings/sms');
-        case 'twittersettings':
-               return common_path('settings/twitter');
-        case 'othersettings':
-               return common_path('settings/other');
-     case 'deleteprofile':
-        return common_path('settings/delete');
-        case 'newnotice':
-               if ($args && $args['replyto']) {
-                       return common_path('notice/new?replyto='.$args['replyto']);
-               } else {
-                       return common_path('notice/new');
-               }
-        case 'shownotice':
-               return common_path('notice/'.$args['notice']);
-        case 'deletenotice':
-                if ($args && $args['notice']) {
-                        return common_path('notice/delete/'.$args['notice']);
-                } else {
-                        return common_path('notice/delete');
-                }
-        case 'microsummary':
-        case 'xrds':
-        case 'foaf':
-               return common_path($args['nickname'].'/'.$action);
-        case 'all':
-        case 'replies':
-        case 'inbox':
-        case 'outbox':
-               if ($args && isset($args['page'])) {
-                       return common_path($args['nickname'].'/'.$action.'?page=' . $args['page']);
-               } else {
-                       return common_path($args['nickname'].'/'.$action);
-               }
-        case 'subscriptions':
-        case 'subscribers':
-               $nickname = $args['nickname'];
-               unset($args['nickname']);
-               if (isset($args['tag'])) {
-                       $tag = $args['tag'];
-                       unset($args['tag']);
-               }
-               $params = http_build_query($args);
-               if ($params) {
-                       return common_path($nickname.'/'.$action . (($tag) ? '/' . $tag : '') . '?' . $params);
-               } else {
-                       return common_path($nickname.'/'.$action . (($tag) ? '/' . $tag : ''));
-               }
-        case 'allrss':
-               return common_path($args['nickname'].'/all/rss');
-        case 'repliesrss':
-               return common_path($args['nickname'].'/replies/rss');
-        case 'userrss':
-        if (isset($args['limit']))
-                   return common_path($args['nickname'].'/rss?limit=' . $args['limit']);
-               return common_path($args['nickname'].'/rss');
-        case 'showstream':
-               if ($args && isset($args['page'])) {
-                       return common_path($args['nickname'].'?page=' . $args['page']);
-               } else {
-                       return common_path($args['nickname']);
-               }
-
-        case 'usertimeline':
-               return common_path("api/statuses/user_timeline/".$args['nickname'].".atom");
-        case 'confirmaddress':
-               return common_path('main/confirmaddress/'.$args['code']);
-        case 'userbyid':
-               return common_path('user/'.$args['id']);
-        case 'recoverpassword':
-           $path = 'main/recoverpassword';
-           if ($args['code']) {
-               $path .= '/' . $args['code'];
-               }
-           return common_path($path);
-        case 'imsettings':
-               return common_path('settings/im');
-        case 'peoplesearch':
-               return common_path('search/people' . (($args) ? ('?' . http_build_query($args)) : ''));
-        case 'noticesearch':
-               return common_path('search/notice' . (($args) ? ('?' . http_build_query($args)) : ''));
-        case 'noticesearchrss':
-               return common_path('search/notice/rss' . (($args) ? ('?' . http_build_query($args)) : ''));
-        case 'avatarbynickname':
-               return common_path($args['nickname'].'/avatar/'.$args['size']);
-        case 'tag':
-           if (isset($args['tag']) && $args['tag']) {
-                       $path = 'tag/' . $args['tag'];
-                       unset($args['tag']);
-               } else {
-                       $path = 'tags';
-               }
-               return common_path($path . (($args) ? ('?' . http_build_query($args)) : ''));
-        case 'peopletag':
-               $path = 'peopletag/' . $args['tag'];
-               unset($args['tag']);
-               return common_path($path . (($args) ? ('?' . http_build_query($args)) : ''));
-        case 'tags':
-               return common_path('tags' . (($args) ? ('?' . http_build_query($args)) : ''));
-        case 'favor':
-               return common_path('main/favor');
-        case 'disfavor':
-               return common_path('main/disfavor');
-        case 'showfavorites':
-               if ($args && isset($args['page'])) {
-                       return common_path($args['nickname'].'/favorites?page=' . $args['page']);
-               } else {
-                       return common_path($args['nickname'].'/favorites');
-               }
-        case 'favoritesrss':
-               return common_path($args['nickname'].'/favorites/rss');
-        case 'showmessage':
-               return common_path('message/' . $args['message']);
-        case 'newmessage':
-               return common_path('message/new' . (($args) ? ('?' . http_build_query($args)) : ''));
-        case 'api':
-               # XXX: do fancy URLs for all the API methods
-               switch (strtolower($args['apiaction'])) {
-                case 'statuses':
-                       switch (strtolower($args['method'])) {
-                        case 'user_timeline.rss':
-                               return common_path('api/statuses/user_timeline/'.$args['argument'].'.rss');
-                        case 'user_timeline.atom':
-                               return common_path('api/statuses/user_timeline/'.$args['argument'].'.atom');
-                        case 'user_timeline.json':
-                               return common_path('api/statuses/user_timeline/'.$args['argument'].'.json');
-                        case 'user_timeline.xml':
-                               return common_path('api/statuses/user_timeline/'.$args['argument'].'.xml');
-                        default: return common_simple_url($action, $args);
-                       }
-                default: return common_simple_url($action, $args);
-               }
-        case 'sup':
-               if ($args && isset($args['seconds'])) {
-                       return common_path('main/sup?seconds='.$args['seconds']);
-               } else {
-                       return common_path('main/sup');
-               }
-        default:
-               return common_simple_url($action, $args);
-       }
-}
-
-function common_simple_url($action, $args=NULL) {
-       global $config;
-       /* XXX: pretty URLs */
-       $extra = '';
-       if ($args) {
-               foreach ($args as $key => $value) {
-                       $extra .= "&${key}=${value}";
-               }
-       }
-       return common_path("index.php?action=${action}${extra}");
-}
-
-function common_path($relative) {
-       global $config;
-       $pathpart = ($config['site']['path']) ? $config['site']['path']."/" : '';
-       return "http://".$config['site']['server'].'/'.$pathpart.$relative;
-}
-
-function common_date_string($dt) {
-       // XXX: do some sexy date formatting
-       // return date(DATE_RFC822, $dt);
-       $t = strtotime($dt);
-       $now = time();
-       $diff = $now - $t;
-
-       if ($now < $t) { # that shouldn't happen!
-               return common_exact_date($dt);
-       } else if ($diff < 60) {
-               return _('a few seconds ago');
-       } else if ($diff < 92) {
-               return _('about a minute ago');
-       } else if ($diff < 3300) {
-               return sprintf(_('about %d minutes ago'), round($diff/60));
-       } else if ($diff < 5400) {
-               return _('about an hour ago');
-       } else if ($diff < 22 * 3600) {
-               return sprintf(_('about %d hours ago'), round($diff/3600));
-       } else if ($diff < 37 * 3600) {
-               return _('about a day ago');
-       } else if ($diff < 24 * 24 * 3600) {
-               return sprintf(_('about %d days ago'), round($diff/(24*3600)));
-       } else if ($diff < 46 * 24 * 3600) {
-               return _('about a month ago');
-       } else if ($diff < 330 * 24 * 3600) {
-               return sprintf(_('about %d months ago'), round($diff/(30*24*3600)));
-       } else if ($diff < 480 * 24 * 3600) {
-               return _('about a year ago');
-       } else {
-               return common_exact_date($dt);
-       }
-}
-
-function common_exact_date($dt) {
-    static $_utc;
-    static $_siteTz;
+    curl_close($curlh);
 
-    if (!$_utc) {
-        $_utc = new DateTimeZone('UTC');
-        $_siteTz = new DateTimeZone(common_timezone());
+    if ($short_url) {
+        $url_cache[(string)$short_url] = $url;
+        return (string)$short_url;
     }
-
-       $dateStr = date('d F Y H:i:s', strtotime($dt));
-       $d = new DateTime($dateStr, $_utc);
-       $d->setTimezone($_siteTz);
-       return $d->format(DATE_RFC850);
+    return $url;
 }
 
-function common_date_w3dtf($dt) {
-       $dateStr = date('d F Y H:i:s', strtotime($dt));
-       $d = new DateTime($dateStr, new DateTimeZone('UTC'));
-       $d->setTimezone(new DateTimeZone(common_timezone()));
-       return $d->format(DATE_W3C);
+function common_xml_safe_str($str)
+{
+    $xmlStr = htmlentities(iconv('UTF-8', 'UTF-8//IGNORE', $str), ENT_NOQUOTES, 'UTF-8');
+
+    // Replace control, formatting, and surrogate characters with '*', ala Twitter
+    return preg_replace('/[\p{Cc}\p{Cf}\p{Cs}]/u', '*', $str);
 }
 
-function common_date_rfc2822($dt) {
-       $dateStr = date('d F Y H:i:s', strtotime($dt));
-       $d = new DateTime($dateStr, new DateTimeZone('UTC'));
-       $d->setTimezone(new DateTimeZone(common_timezone()));
-       return $d->format('r');
+function common_tag_link($tag)
+{
+    $canonical = common_canonical_tag($tag);
+    $url = common_local_url('tag', array('tag' => $canonical));
+    return '<a href="' . htmlspecialchars($url) . '" rel="tag" class="hashlink">' . htmlspecialchars($tag) . '</a>';
 }
 
-function common_date_iso8601($dt) {
-       $dateStr = date('d F Y H:i:s', strtotime($dt));
-       $d = new DateTime($dateStr, new DateTimeZone('UTC'));
-       $d->setTimezone(new DateTimeZone(common_timezone()));
-       return $d->format('c');
+function common_canonical_tag($tag)
+{
+    return strtolower(str_replace(array('-', '_', '.'), '', $tag));
 }
 
-function common_sql_now() {
-       return strftime('%Y-%m-%d %H:%M:%S', time());
+function common_valid_profile_tag($str)
+{
+    return preg_match('/^[A-Za-z0-9_\-\.]{1,64}$/', $str);
 }
 
-function common_redirect($url, $code=307) {
-       static $status = array(301 => "Moved Permanently",
-                                                  302 => "Found",
-                                                  303 => "See Other",
-                                                  307 => "Temporary Redirect");
-       header("Status: ${code} $status[$code]");
-       header("Location: $url");
+function common_at_link($sender_id, $nickname)
+{
+    $sender = Profile::staticGet($sender_id);
+    $recipient = common_relative_profile($sender, common_canonical_nickname($nickname));
+    if ($recipient) {
+        return '<a href="'.htmlspecialchars($recipient->profileurl).'" class="atlink">'.$nickname.'</a>';
+    } else {
+        return $nickname;
+    }
+}
 
-       common_start_xml('a',
-                                        '-//W3C//DTD XHTML 1.0 Strict//EN',
-                                        'http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd');
-       common_element('a', array('href' => $url), $url);
-       common_end_xml();
-    exit;
+function common_at_hash_link($sender_id, $tag)
+{
+    $user = User::staticGet($sender_id);
+    if (!$user) {
+        return $tag;
+    }
+    $tagged = Profile_tag::getTagged($user->id, common_canonical_tag($tag));
+    if ($tagged) {
+        $url = common_local_url('subscriptions',
+                                array('nickname' => $user->nickname,
+                                      'tag' => $tag));
+        return '<a href="'.htmlspecialchars($url).'" class="atlink">'.$tag.'</a>';
+    } else {
+        return $tag;
+    }
 }
 
-function common_save_replies($notice) {
-       # Alternative reply format
-       $tname = false;
-       if (preg_match('/^T ([A-Z0-9]{1,64}) /', $notice->content, $match)) {
-               $tname = $match[1];
-       }
-       # extract all @messages
-       $cnt = preg_match_all('/(?:^|\s)@([a-z0-9]{1,64})/', $notice->content, $match);
-
-       $names = array();
-
-       if ($cnt || $tname) {
-               # XXX: is there another way to make an array copy?
-               $names = ($tname) ? array_unique(array_merge(array(strtolower($tname)), $match[1])) : array_unique($match[1]);
-       }
-
-       $sender = Profile::staticGet($notice->profile_id);
-
-       $replied = array();
-
-       # store replied only for first @ (what user/notice what the reply directed,
-       # we assume first @ is it)
-
-       for ($i=0; $i<count($names); $i++) {
-               $nickname = $names[$i];
-               $recipient = common_relative_profile($sender, $nickname, $notice->created);
-               if (!$recipient) {
-                       continue;
-               }
-               if ($i == 0 && ($recipient->id != $sender->id) && !$notice->reply_to) { # Don't save reply to self
-                       $reply_for = $recipient;
-                       $recipient_notice = $reply_for->getCurrentNotice();
-                       if ($recipient_notice) {
-                               $orig = clone($notice);
-                               $notice->reply_to = $recipient_notice->id;
-                               $notice->update($orig);
-                       }
-               }
-        # Don't save replies from blocked profile to local user
-        $recipient_user = User::staticGet('id', $recipient->id);
-        if ($recipient_user && $recipient_user->hasBlocked($sender)) {
-            continue;
+function common_relative_profile($sender, $nickname, $dt=null)
+{
+    // Try to find profiles this profile is subscribed to that have this nickname
+    $recipient = new Profile();
+    // XXX: use a join instead of a subquery
+    $recipient->whereAdd('EXISTS (SELECT subscribed from subscription where subscriber = '.$sender->id.' and subscribed = id)', 'AND');
+    $recipient->whereAdd('nickname = "' . trim($nickname) . '"', 'AND');
+    if ($recipient->find(true)) {
+        // XXX: should probably differentiate between profiles with
+        // the same name by date of most recent update
+        return $recipient;
+    }
+    // Try to find profiles that listen to this profile and that have this nickname
+    $recipient = new Profile();
+    // XXX: use a join instead of a subquery
+    $recipient->whereAdd('EXISTS (SELECT subscriber from subscription where subscribed = '.$sender->id.' and subscriber = id)', 'AND');
+    $recipient->whereAdd('nickname = "' . trim($nickname) . '"', 'AND');
+    if ($recipient->find(true)) {
+        // XXX: should probably differentiate between profiles with
+        // the same name by date of most recent update
+        return $recipient;
+    }
+    // If this is a local user, try to find a local user with that nickname.
+    $sender = User::staticGet($sender->id);
+    if ($sender) {
+        $recipient_user = User::staticGet('nickname', $nickname);
+        if ($recipient_user) {
+            return $recipient_user->getProfile();
         }
-               $reply = new Reply();
-               $reply->notice_id = $notice->id;
-               $reply->profile_id = $recipient->id;
-               $id = $reply->insert();
-               if (!$id) {
-                       $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;
-               } else {
-                       $replied[$recipient->id] = 1;
-               }
-       }
-
-       # Hash format replies, too
-       $cnt = preg_match_all('/(?:^|\s)@#([a-z0-9]{1,64})/', $notice->content, $match);
-       if ($cnt) {
-               foreach ($match[1] as $tag) {
-                       $tagged = Profile_tag::getTagged($sender->id, $tag);
-                       foreach ($tagged as $t) {
-                               if (!$replied[$t->id]) {
-                    # Don't save replies from blocked profile to local user
-                    $t_user = User::staticGet('id', $t->id);
-                    if ($t_user && $t_user->hasBlocked($sender)) {
-                        continue;
-                    }
-                                       $reply = new Reply();
-                                       $reply->notice_id = $notice->id;
-                                       $reply->profile_id = $t->id;
-                                       $id = $reply->insert();
-                                       if (!$id) {
-                                               common_log_db_error($reply, 'INSERT', __FILE__);
-                                               return;
-                                       }
-                               }
-                       }
-               }
-       }
-}
-
-function common_broadcast_notice($notice, $remote=false) {
-
-       // Check to see if notice should go to Twitter
-       $flink = Foreign_link::getByUserID($notice->profile_id, 1); // 1 == Twitter
-       if (($flink->noticesync & FOREIGN_NOTICE_SEND) == FOREIGN_NOTICE_SEND) {
-
-               // If it's not a Twitter-style reply, or if the user WANTS to send replies...
-
-               if (!preg_match('/^@[a-zA-Z0-9_]{1,15}\b/u', $notice->content) ||
-                       (($flink->noticesync & FOREIGN_NOTICE_SEND_REPLY) == FOREIGN_NOTICE_SEND_REPLY)) {
-
-                       $result = common_twitter_broadcast($notice, $flink);
-
-                       if (!$result) {
-                               common_debug('Unable to send notice: ' . $notice->id . ' to Twitter.', __FILE__);
-                       }
-               }
-       }
-
-       if (common_config('queue', 'enabled')) {
-               # Do it later!
-               return common_enqueue_notice($notice);
-       } else {
-               return common_real_broadcast($notice, $remote);
-       }
-}
-
-function common_twitter_broadcast($notice, $flink) {
-       global $config;
-       $success = true;
-       $fuser = $flink->getForeignUser();
-       $twitter_user = $fuser->nickname;
-       $twitter_password = $flink->credentials;
-       $uri = 'http://www.twitter.com/statuses/update.json';
-
-       // XXX: Hack to get around PHP cURL's use of @ being a a meta character
-       $statustxt = preg_replace('/^@/', ' @', $notice->content);
-
-       $options = array(
-               CURLOPT_USERPWD                 => "$twitter_user:$twitter_password",
-               CURLOPT_POST                    => true,
-               CURLOPT_POSTFIELDS              => array(
-                                                                       'status'        => $statustxt,
-                                                                       'source'        => $config['integration']['source']
-                                                                       ),
-               CURLOPT_RETURNTRANSFER  => true,
-               CURLOPT_FAILONERROR             => true,
-               CURLOPT_HEADER                  => false,
-               CURLOPT_FOLLOWLOCATION  => true,
-               CURLOPT_USERAGENT               => "Laconica",
-               CURLOPT_CONNECTTIMEOUT  => 120,  // XXX: Scary!!!! How long should this be?
-        CURLOPT_TIMEOUT            => 120,
-        
-        # Twitter is strict about accepting invalid "Expect" headers
-        CURLOPT_HTTPHEADER => array('Expect:')
-       );
-
-       $ch = curl_init($uri);
-    curl_setopt_array($ch, $options);
-    $data = curl_exec($ch);
-    $errmsg = curl_error($ch);
-
-       if ($errmsg) {
-               common_debug("cURL error: $errmsg - trying to send notice for $twitter_user.",
-                       __FILE__);
-               $success = false;
-       }
-
-       curl_close($ch);
-
-       if (!$data) {
-               common_debug("No data returned by Twitter's API trying to send update for $twitter_user",
-                       __FILE__);
-               $success = false;
-       }
+    }
+    // Otherwise, no links. @messages from local users to remote users,
+    // or from remote users to other remote users, are just
+    // outside our ability to make intelligent guesses about
+    return null;
+}
 
-       // Twitter should return a status
-       $status = json_decode($data);
+// where should the avatar go for this user?
 
-       if (!$status->id) {
-               common_debug("Unexpected data returned by Twitter API trying to send update for $twitter_user",
-                       __FILE__);
-               $success = false;
-       }
+function common_avatar_filename($id, $extension, $size=null, $extra=null)
+{
+    global $config;
 
-       return $success;
+    if ($size) {
+        return $id . '-' . $size . (($extra) ? ('-' . $extra) : '') . $extension;
+    } else {
+        return $id . '-original' . (($extra) ? ('-' . $extra) : '') . $extension;
+    }
 }
 
-# Stick the notice on the queue
-
-function common_enqueue_notice($notice) {
-       foreach (array('jabber', 'omb', 'sms', 'public') as $transport) {
-               $qi = new Queue_item();
-               $qi->notice_id = $notice->id;
-               $qi->transport = $transport;
-               $qi->created = $notice->created;
-        $result = $qi->insert();
-               if (!$result) {
-                       $last_error = &PEAR::getStaticProperty('DB_DataObject','lastError');
-                       common_log(LOG_ERR, 'DB error inserting queue item: ' . $last_error->message);
-                       return false;
-               }
-               common_log(LOG_DEBUG, 'complete queueing notice ID = ' . $notice->id . ' for ' . $transport);
-       }
-       return $result;
-}
-
-function common_dequeue_notice($notice) {
-        $qi = Queue_item::staticGet($notice->id);
-        if ($qi) {
-                $result = $qi->delete();
-               if (!$result) {
-                   $last_error = &PEAR::getStaticProperty('DB_DataObject','lastError');
-                    common_log(LOG_ERR, 'DB error deleting queue item: ' . $last_error->message);
-                    return false;
-                }
-                common_log(LOG_DEBUG, 'complete dequeueing notice ID = ' . $notice->id);
-                return $result;
-        } else {
-            return false;
-        }
+function common_avatar_path($filename)
+{
+    global $config;
+    return INSTALLDIR . '/avatar/' . $filename;
 }
 
-function common_real_broadcast($notice, $remote=false) {
-       $success = true;
-       if (!$remote) {
-               # Make sure we have the OMB stuff
-               require_once(INSTALLDIR.'/lib/omb.php');
-               $success = omb_broadcast_remote_subscribers($notice);
-               if (!$success) {
-                       common_log(LOG_ERR, 'Error in OMB broadcast for notice ' . $notice->id);
-               }
-       }
-       if ($success) {
-               require_once(INSTALLDIR.'/lib/jabber.php');
-               $success = jabber_broadcast_notice($notice);
-               if (!$success) {
-                       common_log(LOG_ERR, 'Error in jabber broadcast for notice ' . $notice->id);
-               }
-       }
-       if ($success) {
-               require_once(INSTALLDIR.'/lib/mail.php');
-               $success = mail_broadcast_notice_sms($notice);
-               if (!$success) {
-                       common_log(LOG_ERR, 'Error in sms broadcast for notice ' . $notice->id);
-               }
-       }
-       if ($success) {
-               $success = jabber_public_notice($notice);
-               if (!$success) {
-                       common_log(LOG_ERR, 'Error in public broadcast for notice ' . $notice->id);
-               }
-       }
-       // XXX: broadcast notices to other IM
-       return $success;
-}
-
-function common_broadcast_profile($profile) {
-       // XXX: optionally use a queue system like http://code.google.com/p/microapps/wiki/NQDQ
-       require_once(INSTALLDIR.'/lib/omb.php');
-       omb_broadcast_profile($profile);
-       // XXX: Other broadcasts...?
-       return true;
-}
-
-function common_profile_url($nickname) {
-       return common_local_url('showstream', array('nickname' => $nickname));
-}
-
-# Don't call if nobody's logged in
-
-function common_notice_form($action=NULL, $content=NULL) {
-       $user = common_current_user();
-       assert(!is_null($user));
-       common_element_start('form', array('id' => 'status_form',
-                                                                          'method' => 'post',
-                                                                          'action' => common_local_url('newnotice')));
-       common_element_start('p');
-       common_element('label', array('for' => 'status_textarea',
-                                                                 'id' => 'status_label'),
-                                  sprintf(_('What\'s up, %s?'), $user->nickname));
-    common_element('span', array('id' => 'counter', 'class' => 'counter'), '140');
-       common_element('textarea', array('id' => 'status_textarea',
-                                                                        'cols' => 60,
-                                                                        'rows' => 3,
-                                                                        'name' => 'status_textarea'),
-                                  ($content) ? $content : '');
-       common_hidden('token', common_session_token());
-       if ($action) {
-               common_hidden('returnto', $action);
-       }
-       # set by JavaScript
-       common_hidden('inreplyto', 'false');
-       common_element('input', array('id' => 'status_submit',
-                                                                 'name' => 'status_submit',
-                                                                 'type' => 'submit',
-                                                                 'value' => _('Send')));
-       common_element_end('p');
-       common_element_end('form');
-}
-
-# Should make up a reasonable root URL
-
-function common_root_url() {
-       return common_path('');
-}
-
-# returns $bytes bytes of random data as a hexadecimal string
-# "good" here is a goal and not a guarantee
-
-function common_good_rand($bytes) {
-       # XXX: use random.org...?
-       if (file_exists('/dev/urandom')) {
-               return common_urandom($bytes);
-       } else { # FIXME: this is probably not good enough
-               return common_mtrand($bytes);
-       }
-}
-
-function common_urandom($bytes) {
-       $h = fopen('/dev/urandom', 'rb');
-       # should not block
-       $src = fread($h, $bytes);
-       fclose($h);
-       $enc = '';
-       for ($i = 0; $i < $bytes; $i++) {
-               $enc .= sprintf("%02x", (ord($src[$i])));
-       }
-       return $enc;
-}
-
-function common_mtrand($bytes) {
-       $enc = '';
-       for ($i = 0; $i < $bytes; $i++) {
-               $enc .= sprintf("%02x", mt_rand(0, 255));
-       }
-       return $enc;
-}
-
-function common_set_returnto($url) {
-       common_ensure_session();
-       $_SESSION['returnto'] = $url;
-}
-
-function common_get_returnto() {
-       common_ensure_session();
-       return $_SESSION['returnto'];
-}
-
-function common_timestamp() {
-       return date('YmdHis');
-}
-
-function common_ensure_syslog() {
-       static $initialized = false;
-       if (!$initialized) {
-               global $config;
-               openlog($config['syslog']['appname'], 0, LOG_USER);
-               $initialized = true;
-       }
-}
-
-function common_log($priority, $msg, $filename=NULL) {
-       $logfile = common_config('site', 'logfile');
-       if ($logfile) {
-               $log = fopen($logfile, "a");
-               if ($log) {
-                       static $syslog_priorities = array('LOG_EMERG', 'LOG_ALERT', 'LOG_CRIT', 'LOG_ERR',
-                                                                                         'LOG_WARNING', 'LOG_NOTICE', 'LOG_INFO', 'LOG_DEBUG');
-                       $output = date('Y-m-d H:i:s') . ' ' . $syslog_priorities[$priority] . ': ' . $msg . "\n";
-                       fwrite($log, $output);
-                       fclose($log);
-               }
-       } else {
-               common_ensure_syslog();
-               syslog($priority, $msg);
-       }
-}
-
-function common_debug($msg, $filename=NULL) {
-       if ($filename) {
-               common_log(LOG_DEBUG, basename($filename).' - '.$msg);
-       } else {
-               common_log(LOG_DEBUG, $msg);
-       }
-}
-
-function common_log_db_error(&$object, $verb, $filename=NULL) {
-       $objstr = common_log_objstring($object);
-       $last_error = &PEAR::getStaticProperty('DB_DataObject','lastError');
-       common_log(LOG_ERR, $last_error->message . '(' . $verb . ' on ' . $objstr . ')', $filename);
+function common_avatar_url($filename)
+{
+    return common_path('avatar/'.$filename);
 }
 
-function common_log_objstring(&$object) {
-       if (is_null($object)) {
-               return "NULL";
-       }
-       $arr = $object->toArray();
-       $fields = array();
-       foreach ($arr as $k => $v) {
-               $fields[] = "$k='$v'";
-       }
-       $objstring = $object->tableName() . '[' . implode(',', $fields) . ']';
-       return $objstring;
+function common_avatar_display_url($avatar)
+{
+    $server = common_config('avatar', 'server');
+    if ($server) {
+        return 'http://'.$server.'/'.$avatar->filename;
+    } else {
+        return $avatar->url;
+    }
 }
 
-function common_valid_http_url($url) {
-       return Validate::uri($url, array('allowed_schemes' => array('http', 'https')));
-}
-
-function common_valid_tag($tag) {
-       if (preg_match('/^tag:(.*?),(\d{4}(-\d{2}(-\d{2})?)?):(.*)$/', $tag, $matches)) {
-               return (Validate::email($matches[1]) ||
-                               preg_match('/^([\w-\.]+)$/', $matches[1]));
-       }
-       return false;
+function common_default_avatar($size)
+{
+    static $sizenames = array(AVATAR_PROFILE_SIZE => 'profile',
+                              AVATAR_STREAM_SIZE => 'stream',
+                              AVATAR_MINI_SIZE => 'mini');
+    return theme_path('default-avatar-'.$sizenames[$size].'.png');
 }
 
-# Does a little before-after block for next/prev page
-
-function common_pagination($have_before, $have_after, $page, $action, $args=NULL) {
-
-       if ($have_before || $have_after) {
-               common_element_start('div', array('id' => 'pagination'));
-               common_element_start('ul', array('id' => 'nav_pagination'));
-       }
-
-       if ($have_before) {
-               $pargs = array('page' => $page-1);
-               $newargs = ($args) ? array_merge($args,$pargs) : $pargs;
-
-               common_element_start('li', 'before');
-               common_element('a', array('href' => common_local_url($action, $newargs), 'rel' => 'prev'),
-                                          _('« After'));
-               common_element_end('li');
-       }
-
-       if ($have_after) {
-               $pargs = array('page' => $page+1);
-               $newargs = ($args) ? array_merge($args,$pargs) : $pargs;
-               common_element_start('li', 'after');
-               common_element('a', array('href' => common_local_url($action, $newargs), 'rel' => 'next'),
-                                                  _('Before Â»'));
-               common_element_end('li');
-       }
-
-       if ($have_before || $have_after) {
-               common_element_end('ul');
-               common_element_end('div');
-       }
+function common_local_url($action, $args=null, $fragment=null)
+{
+    $url = null;
+    if (common_config('site','fancy')) {
+        $url = common_fancy_url($action, $args);
+    } else {
+        $url = common_simple_url($action, $args);
+    }
+    if (!is_null($fragment)) {
+        $url .= '#'.$fragment;
+    }
+    return $url;
+}
+
+function common_fancy_url($action, $args=null)
+{
+    switch (strtolower($action)) {
+     case 'public':
+        if ($args && isset($args['page'])) {
+            return common_path('?page=' . $args['page']);
+        } else {
+            return common_path('');
+        }
+     case 'featured':
+        if ($args && isset($args['page'])) {
+            return common_path('featured?page=' . $args['page']);
+        } else {
+            return common_path('featured');
+        }
+     case 'favorited':
+        if ($args && isset($args['page'])) {
+            return common_path('favorited?page=' . $args['page']);
+        } else {
+            return common_path('favorited');
+        }
+     case 'publicrss':
+        return common_path('rss');
+     case 'publicatom':
+        return common_path("api/statuses/public_timeline.atom");
+     case 'publicxrds':
+        return common_path('xrds');
+     case 'featuredrss':
+        return common_path('featuredrss');
+     case 'favoritedrss':
+        return common_path('favoritedrss');
+     case 'opensearch':
+        if ($args && $args['type']) {
+            return common_path('opensearch/'.$args['type']);
+        } else {
+            return common_path('opensearch/people');
+        }
+     case 'doc':
+        return common_path('doc/'.$args['title']);
+     case 'block':
+     case 'login':
+     case 'logout':
+     case 'subscribe':
+     case 'unsubscribe':
+     case 'invite':
+        return common_path('main/'.$action);
+     case 'tagother':
+        return common_path('main/tagother?id='.$args['id']);
+     case 'register':
+        if ($args && $args['code']) {
+            return common_path('main/register/'.$args['code']);
+        } else {
+            return common_path('main/register');
+        }
+     case 'remotesubscribe':
+        if ($args && $args['nickname']) {
+            return common_path('main/remote?nickname=' . $args['nickname']);
+        } else {
+            return common_path('main/remote');
+        }
+     case 'nudge':
+        return common_path($args['nickname'].'/nudge');
+     case 'openidlogin':
+        return common_path('main/openid');
+     case 'profilesettings':
+        return common_path('settings/profile');
+     case 'emailsettings':
+        return common_path('settings/email');
+     case 'openidsettings':
+        return common_path('settings/openid');
+     case 'smssettings':
+        return common_path('settings/sms');
+     case 'twittersettings':
+        return common_path('settings/twitter');
+     case 'othersettings':
+        return common_path('settings/other');
+     case 'deleteprofile':
+        return common_path('settings/delete');
+     case 'newnotice':
+        if ($args && $args['replyto']) {
+            return common_path('notice/new?replyto='.$args['replyto']);
+        } else {
+            return common_path('notice/new');
+        }
+     case 'shownotice':
+        return common_path('notice/'.$args['notice']);
+     case 'deletenotice':
+        if ($args && $args['notice']) {
+            return common_path('notice/delete/'.$args['notice']);
+        } else {
+            return common_path('notice/delete');
+        }
+     case 'microsummary':
+     case 'xrds':
+     case 'foaf':
+        return common_path($args['nickname'].'/'.$action);
+     case 'all':
+     case 'replies':
+     case 'inbox':
+     case 'outbox':
+        if ($args && isset($args['page'])) {
+            return common_path($args['nickname'].'/'.$action.'?page=' . $args['page']);
+        } else {
+            return common_path($args['nickname'].'/'.$action);
+        }
+     case 'subscriptions':
+     case 'subscribers':
+        $nickname = $args['nickname'];
+        unset($args['nickname']);
+        if (isset($args['tag'])) {
+            $tag = $args['tag'];
+            unset($args['tag']);
+        }
+        $params = http_build_query($args);
+        if ($params) {
+            return common_path($nickname.'/'.$action . (($tag) ? '/' . $tag : '') . '?' . $params);
+        } else {
+            return common_path($nickname.'/'.$action . (($tag) ? '/' . $tag : ''));
+        }
+     case 'allrss':
+        return common_path($args['nickname'].'/all/rss');
+     case 'repliesrss':
+        return common_path($args['nickname'].'/replies/rss');
+     case 'userrss':
+        if (isset($args['limit']))
+          return common_path($args['nickname'].'/rss?limit=' . $args['limit']);
+        return common_path($args['nickname'].'/rss');
+     case 'showstream':
+        if ($args && isset($args['page'])) {
+            return common_path($args['nickname'].'?page=' . $args['page']);
+        } else {
+            return common_path($args['nickname']);
+        }
+
+     case 'usertimeline':
+        return common_path("api/statuses/user_timeline/".$args['nickname'].".atom");
+     case 'confirmaddress':
+        return common_path('main/confirmaddress/'.$args['code']);
+     case 'userbyid':
+        return common_path('user/'.$args['id']);
+     case 'recoverpassword':
+        $path = 'main/recoverpassword';
+        if ($args['code']) {
+            $path .= '/' . $args['code'];
+        }
+        return common_path($path);
+     case 'imsettings':
+        return common_path('settings/im');
+     case 'peoplesearch':
+        return common_path('search/people' . (($args) ? ('?' . http_build_query($args)) : ''));
+     case 'noticesearch':
+        return common_path('search/notice' . (($args) ? ('?' . http_build_query($args)) : ''));
+     case 'noticesearchrss':
+        return common_path('search/notice/rss' . (($args) ? ('?' . http_build_query($args)) : ''));
+     case 'avatarbynickname':
+        return common_path($args['nickname'].'/avatar/'.$args['size']);
+     case 'tag':
+        if (isset($args['tag']) && $args['tag']) {
+            $path = 'tag/' . $args['tag'];
+            unset($args['tag']);
+        } else {
+            $path = 'tags';
+        }
+        return common_path($path . (($args) ? ('?' . http_build_query($args)) : ''));
+     case 'peopletag':
+        $path = 'peopletag/' . $args['tag'];
+        unset($args['tag']);
+        return common_path($path . (($args) ? ('?' . http_build_query($args)) : ''));
+     case 'tags':
+        return common_path('tags' . (($args) ? ('?' . http_build_query($args)) : ''));
+     case 'favor':
+        return common_path('main/favor');
+     case 'disfavor':
+        return common_path('main/disfavor');
+     case 'showfavorites':
+        if ($args && isset($args['page'])) {
+            return common_path($args['nickname'].'/favorites?page=' . $args['page']);
+        } else {
+            return common_path($args['nickname'].'/favorites');
+        }
+     case 'favoritesrss':
+        return common_path($args['nickname'].'/favorites/rss');
+     case 'showmessage':
+        return common_path('message/' . $args['message']);
+     case 'newmessage':
+        return common_path('message/new' . (($args) ? ('?' . http_build_query($args)) : ''));
+     case 'api':
+        // XXX: do fancy URLs for all the API methods
+        switch (strtolower($args['apiaction'])) {
+         case 'statuses':
+            switch (strtolower($args['method'])) {
+             case 'user_timeline.rss':
+                return common_path('api/statuses/user_timeline/'.$args['argument'].'.rss');
+             case 'user_timeline.atom':
+                return common_path('api/statuses/user_timeline/'.$args['argument'].'.atom');
+             case 'user_timeline.json':
+                return common_path('api/statuses/user_timeline/'.$args['argument'].'.json');
+             case 'user_timeline.xml':
+                return common_path('api/statuses/user_timeline/'.$args['argument'].'.xml');
+             default: return common_simple_url($action, $args);
+            }
+         default: return common_simple_url($action, $args);
+        }
+     case 'sup':
+        if ($args && isset($args['seconds'])) {
+            return common_path('main/sup?seconds='.$args['seconds']);
+        } else {
+            return common_path('main/sup');
+        }
+     default:
+        return common_simple_url($action, $args);
+    }
+}
+
+function common_simple_url($action, $args=null)
+{
+    global $config;
+    /* XXX: pretty URLs */
+    $extra = '';
+    if ($args) {
+        foreach ($args as $key => $value) {
+            $extra .= "&${key}=${value}";
+        }
+    }
+    return common_path("index.php?action=${action}${extra}");
+}
+
+function common_path($relative)
+{
+    global $config;
+    $pathpart = ($config['site']['path']) ? $config['site']['path']."/" : '';
+    return "http://".$config['site']['server'].'/'.$pathpart.$relative;
+}
+
+function common_date_string($dt)
+{
+    // XXX: do some sexy date formatting
+    // return date(DATE_RFC822, $dt);
+    $t = strtotime($dt);
+    $now = time();
+    $diff = $now - $t;
+
+    if ($now < $t) { // that shouldn't happen!
+        return common_exact_date($dt);
+    } else if ($diff < 60) {
+        return _('a few seconds ago');
+    } else if ($diff < 92) {
+        return _('about a minute ago');
+    } else if ($diff < 3300) {
+        return sprintf(_('about %d minutes ago'), round($diff/60));
+    } else if ($diff < 5400) {
+        return _('about an hour ago');
+    } else if ($diff < 22 * 3600) {
+        return sprintf(_('about %d hours ago'), round($diff/3600));
+    } else if ($diff < 37 * 3600) {
+        return _('about a day ago');
+    } else if ($diff < 24 * 24 * 3600) {
+        return sprintf(_('about %d days ago'), round($diff/(24*3600)));
+    } else if ($diff < 46 * 24 * 3600) {
+        return _('about a month ago');
+    } else if ($diff < 330 * 24 * 3600) {
+        return sprintf(_('about %d months ago'), round($diff/(30*24*3600)));
+    } else if ($diff < 480 * 24 * 3600) {
+        return _('about a year ago');
+    } else {
+        return common_exact_date($dt);
+    }
+}
+
+function common_exact_date($dt)
+{
+    static $_utc;
+    static $_siteTz;
+
+    if (!$_utc) {
+        $_utc = new DateTimeZone('UTC');
+        $_siteTz = new DateTimeZone(common_timezone());
+    }
+
+    $dateStr = date('d F Y H:i:s', strtotime($dt));
+    $d = new DateTime($dateStr, $_utc);
+    $d->setTimezone($_siteTz);
+    return $d->format(DATE_RFC850);
+}
+
+function common_date_w3dtf($dt)
+{
+    $dateStr = date('d F Y H:i:s', strtotime($dt));
+    $d = new DateTime($dateStr, new DateTimeZone('UTC'));
+    $d->setTimezone(new DateTimeZone(common_timezone()));
+    return $d->format(DATE_W3C);
+}
+
+function common_date_rfc2822($dt)
+{
+    $dateStr = date('d F Y H:i:s', strtotime($dt));
+    $d = new DateTime($dateStr, new DateTimeZone('UTC'));
+    $d->setTimezone(new DateTimeZone(common_timezone()));
+    return $d->format('r');
+}
+
+function common_date_iso8601($dt)
+{
+    $dateStr = date('d F Y H:i:s', strtotime($dt));
+    $d = new DateTime($dateStr, new DateTimeZone('UTC'));
+    $d->setTimezone(new DateTimeZone(common_timezone()));
+    return $d->format('c');
+}
+
+function common_sql_now()
+{
+    return strftime('%Y-%m-%d %H:%M:%S', time());
+}
+
+function common_redirect($url, $code=307)
+{
+    static $status = array(301 => "Moved Permanently",
+                           302 => "Found",
+                           303 => "See Other",
+                           307 => "Temporary Redirect");
+    header("Status: ${code} $status[$code]");
+    header("Location: $url");
+
+    common_start_xml('a',
+                     '-//W3C//DTD XHTML 1.0 Strict//EN',
+                     'http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd');
+    common_element('a', array('href' => $url), $url);
+    common_end_xml();
+    exit;
+}
+
+function common_save_replies($notice)
+{
+    // Alternative reply format
+    $tname = false;
+    if (preg_match('/^T ([A-Z0-9]{1,64}) /', $notice->content, $match)) {
+        $tname = $match[1];
+    }
+    // extract all @messages
+    $cnt = preg_match_all('/(?:^|\s)@([a-z0-9]{1,64})/', $notice->content, $match);
+
+    $names = array();
+
+    if ($cnt || $tname) {
+        // XXX: is there another way to make an array copy?
+        $names = ($tname) ? array_unique(array_merge(array(strtolower($tname)), $match[1])) : array_unique($match[1]);
+    }
+
+    $sender = Profile::staticGet($notice->profile_id);
+
+    $replied = array();
+
+    // store replied only for first @ (what user/notice what the reply directed,
+    // we assume first @ is it)
+
+    for ($i=0; $i<count($names); $i++) {
+        $nickname = $names[$i];
+        $recipient = common_relative_profile($sender, $nickname, $notice->created);
+        if (!$recipient) {
+            continue;
+        }
+        if ($i == 0 && ($recipient->id != $sender->id) && !$notice->reply_to) { // Don't save reply to self
+            $reply_for = $recipient;
+            $recipient_notice = $reply_for->getCurrentNotice();
+            if ($recipient_notice) {
+                $orig = clone($notice);
+                $notice->reply_to = $recipient_notice->id;
+                $notice->update($orig);
+            }
+        }
+        // Don't save replies from blocked profile to local user
+        $recipient_user = User::staticGet('id', $recipient->id);
+        if ($recipient_user && $recipient_user->hasBlocked($sender)) {
+            continue;
+        }
+        $reply = new Reply();
+        $reply->notice_id = $notice->id;
+        $reply->profile_id = $recipient->id;
+        $id = $reply->insert();
+        if (!$id) {
+            $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;
+        } else {
+            $replied[$recipient->id] = 1;
+        }
+    }
+
+    // Hash format replies, too
+    $cnt = preg_match_all('/(?:^|\s)@#([a-z0-9]{1,64})/', $notice->content, $match);
+    if ($cnt) {
+        foreach ($match[1] as $tag) {
+            $tagged = Profile_tag::getTagged($sender->id, $tag);
+            foreach ($tagged as $t) {
+                if (!$replied[$t->id]) {
+                    // Don't save replies from blocked profile to local user
+                    $t_user = User::staticGet('id', $t->id);
+                    if ($t_user && $t_user->hasBlocked($sender)) {
+                        continue;
+                    }
+                    $reply = new Reply();
+                    $reply->notice_id = $notice->id;
+                    $reply->profile_id = $t->id;
+                    $id = $reply->insert();
+                    if (!$id) {
+                        common_log_db_error($reply, 'INSERT', __FILE__);
+                        return;
+                    }
+                }
+            }
+        }
+    }
+}
+
+function common_broadcast_notice($notice, $remote=false)
+{
+
+    // Check to see if notice should go to Twitter
+    $flink = Foreign_link::getByUserID($notice->profile_id, 1); // 1 == Twitter
+    if (($flink->noticesync & FOREIGN_NOTICE_SEND) == FOREIGN_NOTICE_SEND) {
+
+        // If it's not a Twitter-style reply, or if the user WANTS to send replies...
+
+        if (!preg_match('/^@[a-zA-Z0-9_]{1,15}\b/u', $notice->content) ||
+            (($flink->noticesync & FOREIGN_NOTICE_SEND_REPLY) == FOREIGN_NOTICE_SEND_REPLY)) {
+
+            $result = common_twitter_broadcast($notice, $flink);
+
+            if (!$result) {
+                common_debug('Unable to send notice: ' . $notice->id . ' to Twitter.', __FILE__);
+            }
+        }
+    }
+
+    if (common_config('queue', 'enabled')) {
+        // Do it later!
+        return common_enqueue_notice($notice);
+    } else {
+        return common_real_broadcast($notice, $remote);
+    }
+}
+
+function common_twitter_broadcast($notice, $flink)
+{
+    global $config;
+    $success = true;
+    $fuser = $flink->getForeignUser();
+    $twitter_user = $fuser->nickname;
+    $twitter_password = $flink->credentials;
+    $uri = 'http://www.twitter.com/statuses/update.json';
+
+    // XXX: Hack to get around PHP cURL's use of @ being a a meta character
+    $statustxt = preg_replace('/^@/', ' @', $notice->content);
+
+    $options = array(
+                     CURLOPT_USERPWD         => "$twitter_user:$twitter_password",
+                     CURLOPT_POST            => true,
+                     CURLOPT_POSTFIELDS        => array(
+                                                        'status'    => $statustxt,
+                                                        'source'    => $config['integration']['source']
+                                                        ),
+                     CURLOPT_RETURNTRANSFER    => true,
+                     CURLOPT_FAILONERROR        => true,
+                     CURLOPT_HEADER            => false,
+                     CURLOPT_FOLLOWLOCATION    => true,
+                     CURLOPT_USERAGENT        => "Laconica",
+                     CURLOPT_CONNECTTIMEOUT    => 120,  // XXX: Scary!!!! How long should this be?
+                     CURLOPT_TIMEOUT            => 120,
+
+                     # Twitter is strict about accepting invalid "Expect" headers
+                     CURLOPT_HTTPHEADER => array('Expect:')
+                     );
+
+    $ch = curl_init($uri);
+    curl_setopt_array($ch, $options);
+    $data = curl_exec($ch);
+    $errmsg = curl_error($ch);
+
+    if ($errmsg) {
+        common_debug("cURL error: $errmsg - trying to send notice for $twitter_user.",
+                     __FILE__);
+        $success = false;
+    }
+
+    curl_close($ch);
+
+    if (!$data) {
+        common_debug("No data returned by Twitter's API trying to send update for $twitter_user",
+                     __FILE__);
+        $success = false;
+    }
+
+    // Twitter should return a status
+    $status = json_decode($data);
+
+    if (!$status->id) {
+        common_debug("Unexpected data returned by Twitter API trying to send update for $twitter_user",
+                     __FILE__);
+        $success = false;
+    }
+
+    return $success;
+}
+
+// Stick the notice on the queue
+
+function common_enqueue_notice($notice)
+{
+    foreach (array('jabber', 'omb', 'sms', 'public') as $transport) {
+        $qi = new Queue_item();
+        $qi->notice_id = $notice->id;
+        $qi->transport = $transport;
+        $qi->created = $notice->created;
+        $result = $qi->insert();
+        if (!$result) {
+            $last_error = &PEAR::getStaticProperty('DB_DataObject','lastError');
+            common_log(LOG_ERR, 'DB error inserting queue item: ' . $last_error->message);
+            return false;
+        }
+        common_log(LOG_DEBUG, 'complete queueing notice ID = ' . $notice->id . ' for ' . $transport);
+    }
+    return $result;
+}
+
+function common_dequeue_notice($notice)
+{
+    $qi = Queue_item::staticGet($notice->id);
+    if ($qi) {
+        $result = $qi->delete();
+        if (!$result) {
+            $last_error = &PEAR::getStaticProperty('DB_DataObject','lastError');
+            common_log(LOG_ERR, 'DB error deleting queue item: ' . $last_error->message);
+            return false;
+        }
+        common_log(LOG_DEBUG, 'complete dequeueing notice ID = ' . $notice->id);
+        return $result;
+    } else {
+        return false;
+    }
+}
+
+function common_real_broadcast($notice, $remote=false)
+{
+    $success = true;
+    if (!$remote) {
+        // Make sure we have the OMB stuff
+        require_once(INSTALLDIR.'/lib/omb.php');
+        $success = omb_broadcast_remote_subscribers($notice);
+        if (!$success) {
+            common_log(LOG_ERR, 'Error in OMB broadcast for notice ' . $notice->id);
+        }
+    }
+    if ($success) {
+        require_once(INSTALLDIR.'/lib/jabber.php');
+        $success = jabber_broadcast_notice($notice);
+        if (!$success) {
+            common_log(LOG_ERR, 'Error in jabber broadcast for notice ' . $notice->id);
+        }
+    }
+    if ($success) {
+        require_once(INSTALLDIR.'/lib/mail.php');
+        $success = mail_broadcast_notice_sms($notice);
+        if (!$success) {
+            common_log(LOG_ERR, 'Error in sms broadcast for notice ' . $notice->id);
+        }
+    }
+    if ($success) {
+        $success = jabber_public_notice($notice);
+        if (!$success) {
+            common_log(LOG_ERR, 'Error in public broadcast for notice ' . $notice->id);
+        }
+    }
+    // XXX: broadcast notices to other IM
+    return $success;
+}
+
+function common_broadcast_profile($profile)
+{
+    // XXX: optionally use a queue system like http://code.google.com/p/microapps/wiki/NQDQ
+    require_once(INSTALLDIR.'/lib/omb.php');
+    omb_broadcast_profile($profile);
+    // XXX: Other broadcasts...?
+    return true;
+}
+
+function common_profile_url($nickname)
+{
+    return common_local_url('showstream', array('nickname' => $nickname));
+}
+
+// Don't call if nobody's logged in
+
+function common_notice_form($action=null, $content=null)
+{
+    $user = common_current_user();
+    assert(!is_null($user));
+    common_element_start('form', array('id' => 'status_form',
+                                       'method' => 'post',
+                                       'action' => common_local_url('newnotice')));
+    common_element_start('p');
+    common_element('label', array('for' => 'status_textarea',
+                                  'id' => 'status_label'),
+                   sprintf(_('What\'s up, %s?'), $user->nickname));
+    common_element('span', array('id' => 'counter', 'class' => 'counter'), '140');
+    common_element('textarea', array('id' => 'status_textarea',
+                                     'cols' => 60,
+                                     'rows' => 3,
+                                     'name' => 'status_textarea'),
+                   ($content) ? $content : '');
+    common_hidden('token', common_session_token());
+    if ($action) {
+        common_hidden('returnto', $action);
+    }
+    // set by JavaScript
+    common_hidden('inreplyto', 'false');
+    common_element('input', array('id' => 'status_submit',
+                                  'name' => 'status_submit',
+                                  'type' => 'submit',
+                                  'value' => _('Send')));
+    common_element_end('p');
+    common_element_end('form');
+}
+
+// Should make up a reasonable root URL
+
+function common_root_url()
+{
+    return common_path('');
+}
+
+// returns $bytes bytes of random data as a hexadecimal string
+// "good" here is a goal and not a guarantee
+
+function common_good_rand($bytes)
+{
+    // XXX: use random.org...?
+    if (file_exists('/dev/urandom')) {
+        return common_urandom($bytes);
+    } else { // FIXME: this is probably not good enough
+        return common_mtrand($bytes);
+    }
+}
+
+function common_urandom($bytes)
+{
+    $h = fopen('/dev/urandom', 'rb');
+    // should not block
+    $src = fread($h, $bytes);
+    fclose($h);
+    $enc = '';
+    for ($i = 0; $i < $bytes; $i++) {
+        $enc .= sprintf("%02x", (ord($src[$i])));
+    }
+    return $enc;
+}
+
+function common_mtrand($bytes)
+{
+    $enc = '';
+    for ($i = 0; $i < $bytes; $i++) {
+        $enc .= sprintf("%02x", mt_rand(0, 255));
+    }
+    return $enc;
+}
+
+function common_set_returnto($url)
+{
+    common_ensure_session();
+    $_SESSION['returnto'] = $url;
+}
+
+function common_get_returnto()
+{
+    common_ensure_session();
+    return $_SESSION['returnto'];
+}
+
+function common_timestamp()
+{
+    return date('YmdHis');
+}
+
+function common_ensure_syslog()
+{
+    static $initialized = false;
+    if (!$initialized) {
+        global $config;
+        openlog($config['syslog']['appname'], 0, LOG_USER);
+        $initialized = true;
+    }
+}
+
+function common_log($priority, $msg, $filename=null)
+{
+    $logfile = common_config('site', 'logfile');
+    if ($logfile) {
+        $log = fopen($logfile, "a");
+        if ($log) {
+            static $syslog_priorities = array('LOG_EMERG', 'LOG_ALERT', 'LOG_CRIT', 'LOG_ERR',
+                                              'LOG_WARNING', 'LOG_NOTICE', 'LOG_INFO', 'LOG_DEBUG');
+            $output = date('Y-m-d H:i:s') . ' ' . $syslog_priorities[$priority] . ': ' . $msg . "\n";
+            fwrite($log, $output);
+            fclose($log);
+        }
+    } else {
+        common_ensure_syslog();
+        syslog($priority, $msg);
+    }
+}
+
+function common_debug($msg, $filename=null)
+{
+    if ($filename) {
+        common_log(LOG_DEBUG, basename($filename).' - '.$msg);
+    } else {
+        common_log(LOG_DEBUG, $msg);
+    }
+}
+
+function common_log_db_error(&$object, $verb, $filename=null)
+{
+    $objstr = common_log_objstring($object);
+    $last_error = &PEAR::getStaticProperty('DB_DataObject','lastError');
+    common_log(LOG_ERR, $last_error->message . '(' . $verb . ' on ' . $objstr . ')', $filename);
+}
+
+function common_log_objstring(&$object)
+{
+    if (is_null($object)) {
+        return "null";
+    }
+    $arr = $object->toArray();
+    $fields = array();
+    foreach ($arr as $k => $v) {
+        $fields[] = "$k='$v'";
+    }
+    $objstring = $object->tableName() . '[' . implode(',', $fields) . ']';
+    return $objstring;
+}
+
+function common_valid_http_url($url)
+{
+    return Validate::uri($url, array('allowed_schemes' => array('http', 'https')));
+}
+
+function common_valid_tag($tag)
+{
+    if (preg_match('/^tag:(.*?),(\d{4}(-\d{2}(-\d{2})?)?):(.*)$/', $tag, $matches)) {
+        return (Validate::email($matches[1]) ||
+                preg_match('/^([\w-\.]+)$/', $matches[1]));
+    }
+    return false;
+}
+
+// Does a little before-after block for next/prev page
+
+function common_pagination($have_before, $have_after, $page, $action, $args=null)
+{
+
+    if ($have_before || $have_after) {
+        common_element_start('div', array('id' => 'pagination'));
+        common_element_start('ul', array('id' => 'nav_pagination'));
+    }
+
+    if ($have_before) {
+        $pargs = array('page' => $page-1);
+        $newargs = ($args) ? array_merge($args,$pargs) : $pargs;
+
+        common_element_start('li', 'before');
+        common_element('a', array('href' => common_local_url($action, $newargs), 'rel' => 'prev'),
+                       _('« After'));
+        common_element_end('li');
+    }
+
+    if ($have_after) {
+        $pargs = array('page' => $page+1);
+        $newargs = ($args) ? array_merge($args,$pargs) : $pargs;
+        common_element_start('li', 'after');
+        common_element('a', array('href' => common_local_url($action, $newargs), 'rel' => 'next'),
+                       _('Before Â»'));
+        common_element_end('li');
+    }
+
+    if ($have_before || $have_after) {
+        common_element_end('ul');
+        common_element_end('div');
+    }
 }
 
 /* Following functions are copied from MediaWiki GlobalFunctions.php
  * and written by Evan Prodromou. */
 
-function common_accept_to_prefs($accept, $def = '*/*') {
-       # No arg means accept anything (per HTTP spec)
-       if(!$accept) {
-               return array($def => 1);
-       }
-
-       $prefs = array();
-
-       $parts = explode(',', $accept);
-
-       foreach($parts as $part) {
-               # FIXME: doesn't deal with params like 'text/html; level=1'
-               @list($value, $qpart) = explode(';', $part);
-               $match = array();
-               if(!isset($qpart)) {
-                       $prefs[$value] = 1;
-               } elseif(preg_match('/q\s*=\s*(\d*\.\d+)/', $qpart, $match)) {
-                       $prefs[$value] = $match[1];
-               }
-       }
-
-       return $prefs;
-}
-
-function common_mime_type_match($type, $avail) {
-       if(array_key_exists($type, $avail)) {
-               return $type;
-       } else {
-               $parts = explode('/', $type);
-               if(array_key_exists($parts[0] . '/*', $avail)) {
-                       return $parts[0] . '/*';
-               } elseif(array_key_exists('*/*', $avail)) {
-                       return '*/*';
-               } else {
-                       return NULL;
-               }
-       }
-}
-
-function common_negotiate_type($cprefs, $sprefs) {
-       $combine = array();
-
-       foreach(array_keys($sprefs) as $type) {
-               $parts = explode('/', $type);
-               if($parts[1] != '*') {
-                       $ckey = common_mime_type_match($type, $cprefs);
-                       if($ckey) {
-                               $combine[$type] = $sprefs[$type] * $cprefs[$ckey];
-                       }
-               }
-       }
-
-       foreach(array_keys($cprefs) as $type) {
-               $parts = explode('/', $type);
-               if($parts[1] != '*' && !array_key_exists($type, $sprefs)) {
-                       $skey = common_mime_type_match($type, $sprefs);
-                       if($skey) {
-                               $combine[$type] = $sprefs[$skey] * $cprefs[$type];
-                       }
-               }
-       }
-
-       $bestq = 0;
-       $besttype = "text/html";
-
-       foreach(array_keys($combine) as $type) {
-               if($combine[$type] > $bestq) {
-                       $besttype = $type;
-                       $bestq = $combine[$type];
-               }
-       }
-
-       return $besttype;
-}
-
-function common_config($main, $sub) {
-       global $config;
-       return isset($config[$main][$sub]) ? $config[$main][$sub] : false;
-}
-
-function common_copy_args($from) {
-       $to = array();
-       $strip = get_magic_quotes_gpc();
-       foreach ($from as $k => $v) {
-               $to[$k] = ($strip) ? stripslashes($v) : $v;
-       }
-       return $to;
+function common_accept_to_prefs($accept, $def = '*/*')
+{
+    // No arg means accept anything (per HTTP spec)
+    if(!$accept) {
+        return array($def => 1);
+    }
+
+    $prefs = array();
+
+    $parts = explode(',', $accept);
+
+    foreach($parts as $part) {
+        // FIXME: doesn't deal with params like 'text/html; level=1'
+        @list($value, $qpart) = explode(';', $part);
+        $match = array();
+        if(!isset($qpart)) {
+            $prefs[$value] = 1;
+        } elseif(preg_match('/q\s*=\s*(\d*\.\d+)/', $qpart, $match)) {
+            $prefs[$value] = $match[1];
+        }
+    }
+
+    return $prefs;
+}
+
+function common_mime_type_match($type, $avail)
+{
+    if(array_key_exists($type, $avail)) {
+        return $type;
+    } else {
+        $parts = explode('/', $type);
+        if(array_key_exists($parts[0] . '/*', $avail)) {
+            return $parts[0] . '/*';
+        } elseif(array_key_exists('*/*', $avail)) {
+            return '*/*';
+        } else {
+            return null;
+        }
+    }
+}
+
+function common_negotiate_type($cprefs, $sprefs)
+{
+    $combine = array();
+
+    foreach(array_keys($sprefs) as $type) {
+        $parts = explode('/', $type);
+        if($parts[1] != '*') {
+            $ckey = common_mime_type_match($type, $cprefs);
+            if($ckey) {
+                $combine[$type] = $sprefs[$type] * $cprefs[$ckey];
+            }
+        }
+    }
+
+    foreach(array_keys($cprefs) as $type) {
+        $parts = explode('/', $type);
+        if($parts[1] != '*' && !array_key_exists($type, $sprefs)) {
+            $skey = common_mime_type_match($type, $sprefs);
+            if($skey) {
+                $combine[$type] = $sprefs[$skey] * $cprefs[$type];
+            }
+        }
+    }
+
+    $bestq = 0;
+    $besttype = "text/html";
+
+    foreach(array_keys($combine) as $type) {
+        if($combine[$type] > $bestq) {
+            $besttype = $type;
+            $bestq = $combine[$type];
+        }
+    }
+
+    return $besttype;
+}
+
+function common_config($main, $sub)
+{
+    global $config;
+    return isset($config[$main][$sub]) ? $config[$main][$sub] : false;
+}
+
+function common_copy_args($from)
+{
+    $to = array();
+    $strip = get_magic_quotes_gpc();
+    foreach ($from as $k => $v) {
+        $to[$k] = ($strip) ? stripslashes($v) : $v;
+    }
+    return $to;
 }
 
 // Neutralise the evil effects of magic_quotes_gpc in the current request.
 // This is used before handing a request off to OAuthRequest::from_request.
-function common_remove_magic_from_request() {
-       if(get_magic_quotes_gpc()) {
-               $_POST=array_map('stripslashes',$_POST);
-               $_GET=array_map('stripslashes',$_GET);
-       }
+function common_remove_magic_from_request()
+{
+    if(get_magic_quotes_gpc()) {
+        $_POST=array_map('stripslashes',$_POST);
+        $_GET=array_map('stripslashes',$_GET);
+    }
 }
 
-function common_user_uri(&$user) {
-       return common_local_url('userbyid', array('id' => $user->id));
+function common_user_uri(&$user)
+{
+    return common_local_url('userbyid', array('id' => $user->id));
 }
 
-function common_notice_uri(&$notice) {
-       return common_local_url('shownotice',
-               array('notice' => $notice->id));
+function common_notice_uri(&$notice)
+{
+    return common_local_url('shownotice',
+                            array('notice' => $notice->id));
 }
 
-# 36 alphanums - lookalikes (0, O, 1, I) = 32 chars = 5 bits
+// 36 alphanums - lookalikes (0, O, 1, I) = 32 chars = 5 bits
 
-function common_confirmation_code($bits) {
-       # 36 alphanums - lookalikes (0, O, 1, I) = 32 chars = 5 bits
-       static $codechars = '23456789ABCDEFGHJKLMNPQRSTUVWXYZ';
-       $chars = ceil($bits/5);
-       $code = '';
-       for ($i = 0; $i < $chars; $i++) {
-               # XXX: convert to string and back
-               $num = hexdec(common_good_rand(1));
-               # XXX: randomness is too precious to throw away almost
-               # 40% of the bits we get!
-               $code .= $codechars[$num%32];
-       }
-       return $code;
+function common_confirmation_code($bits)
+{
+    // 36 alphanums - lookalikes (0, O, 1, I) = 32 chars = 5 bits
+    static $codechars = '23456789ABCDEFGHJKLMNPQRSTUVWXYZ';
+    $chars = ceil($bits/5);
+    $code = '';
+    for ($i = 0; $i < $chars; $i++) {
+        // XXX: convert to string and back
+        $num = hexdec(common_good_rand(1));
+        // XXX: randomness is too precious to throw away almost
+        // 40% of the bits we get!
+        $code .= $codechars[$num%32];
+    }
+    return $code;
 }
 
-# convert markup to HTML
+// convert markup to HTML
 
-function common_markup_to_html($c) {
-       $c = preg_replace('/%%action.(\w+)%%/e', "common_local_url('\\1')", $c);
-       $c = preg_replace('/%%doc.(\w+)%%/e', "common_local_url('doc', array('title'=>'\\1'))", $c);
-       $c = preg_replace('/%%(\w+).(\w+)%%/e', 'common_config(\'\\1\', \'\\2\')', $c);
-       return Markdown($c);
+function common_markup_to_html($c)
+{
+    $c = preg_replace('/%%action.(\w+)%%/e', "common_local_url('\\1')", $c);
+    $c = preg_replace('/%%doc.(\w+)%%/e', "common_local_url('doc', array('title'=>'\\1'))", $c);
+    $c = preg_replace('/%%(\w+).(\w+)%%/e', 'common_config(\'\\1\', \'\\2\')', $c);
+    return Markdown($c);
 }
 
-function common_profile_avatar_url($profile, $size=AVATAR_PROFILE_SIZE) {
-       $avatar = $profile->getAvatar($size);
-       if ($avatar) {
-               return common_avatar_display_url($avatar);
-       } else {
-               return common_default_avatar($size);
-       }
+function common_profile_avatar_url($profile, $size=AVATAR_PROFILE_SIZE)
+{
+    $avatar = $profile->getAvatar($size);
+    if ($avatar) {
+        return common_avatar_display_url($avatar);
+    } else {
+        return common_default_avatar($size);
+    }
 }
 
-function common_profile_uri($profile) {
-       if (!$profile) {
-               return NULL;
-       }
-       $user = User::staticGet($profile->id);
-       if ($user) {
-               return $user->uri;
-       }
+function common_profile_uri($profile)
+{
+    if (!$profile) {
+        return null;
+    }
+    $user = User::staticGet($profile->id);
+    if ($user) {
+        return $user->uri;
+    }
 
-       $remote = Remote_profile::staticGet($profile->id);
-       if ($remote) {
-               return $remote->uri;
-       }
-       # XXX: this is a very bad profile!
-       return NULL;
+    $remote = Remote_profile::staticGet($profile->id);
+    if ($remote) {
+        return $remote->uri;
+    }
+    // XXX: this is a very bad profile!
+    return null;
 }
 
-function common_canonical_sms($sms) {
-       # strip non-digits
-       preg_replace('/\D/', '', $sms);
-       return $sms;
+function common_canonical_sms($sms)
+{
+    // strip non-digits
+    preg_replace('/\D/', '', $sms);
+    return $sms;
 }
 
-function common_error_handler($errno, $errstr, $errfile, $errline, $errcontext) {
+function common_error_handler($errno, $errstr, $errfile, $errline, $errcontext)
+{
     switch ($errno) {
      case E_USER_ERROR:
-               common_log(LOG_ERR, "[$errno] $errstr ($errfile:$errline)");
-               exit(1);
-               break;
+        common_log(LOG_ERR, "[$errno] $errstr ($errfile:$errline)");
+        exit(1);
+        break;
 
-        case E_USER_WARNING:
-               common_log(LOG_WARNING, "[$errno] $errstr ($errfile:$errline)");
-               break;
+     case E_USER_WARNING:
+        common_log(LOG_WARNING, "[$errno] $errstr ($errfile:$errline)");
+        break;
 
      case E_USER_NOTICE:
-               common_log(LOG_NOTICE, "[$errno] $errstr ($errfile:$errline)");
-               break;
+        common_log(LOG_NOTICE, "[$errno] $errstr ($errfile:$errline)");
+        break;
     }
 
-       # FIXME: show error page if we're on the Web
+    // FIXME: show error page if we're on the Web
     /* Don't execute PHP internal error handler */
     return true;
 }
 
-function common_session_token() {
-       common_ensure_session();
-       if (!array_key_exists('token', $_SESSION)) {
-               $_SESSION['token'] = common_good_rand(64);
-       }
-       return $_SESSION['token'];
-}
-
-function common_disfavor_form($notice) {
-       common_element_start('form', array('id' => 'disfavor-' . $notice->id,
-                                                                          'method' => 'post',
-                                                                          'class' => 'disfavor',
-                                                                          'action' => common_local_url('disfavor')));
-
-       common_element('input', array('type' => 'hidden',
-                                                                 'name' => 'token-'. $notice->id,
-                                                                 'id' => 'token-'. $notice->id,
-                                                                 'class' => 'token',
-                                                                 'value' => common_session_token()));
-
-       common_element('input', array('type' => 'hidden',
-                                                                 'name' => 'notice',
-                                                                 'id' => 'notice-n'. $notice->id,
-                                                                 'class' => 'notice',
-                                                                 'value' => $notice->id));
-
-       common_element('input', array('type' => 'submit',
-                                                                 'id' => 'disfavor-submit-' . $notice->id,
-                                                                 'name' => 'disfavor-submit-' . $notice->id,
-                                                                 'class' => 'disfavor',
-                                                                 'value' => 'Disfavor favorite',
-                                                                 'title' => 'Remove this message from favorites'));
-       common_element_end('form');
-}
-
-function common_favor_form($notice) {
-       common_element_start('form', array('id' => 'favor-' . $notice->id,
-                                                                          'method' => 'post',
-                                                                          'class' => 'favor',
-                                                                          'action' => common_local_url('favor')));
-
-       common_element('input', array('type' => 'hidden',
-                                                                 'name' => 'token-'. $notice->id,
-                                                                 'id' => 'token-'. $notice->id,
-                                                                 'class' => 'token',
-                                                                 'value' => common_session_token()));
-
-       common_element('input', array('type' => 'hidden',
-                                                                 'name' => 'notice',
-                                                                 'id' => 'notice-n'. $notice->id,
-                                                                 'class' => 'notice',
-                                                                 'value' => $notice->id));
-
-       common_element('input', array('type' => 'submit',
-                                                                 'id' => 'favor-submit-' . $notice->id,
-                                                                 'name' => 'favor-submit-' . $notice->id,
-                                                                 'class' => 'favor',
-                                                                 'value' => 'Add to favorites',
-                                                                 'title' => 'Add this message to favorites'));
-       common_element_end('form');
-}
-
-function common_nudge_form($profile) {
-       common_element_start('form', array('id' => 'nudge', 'method' => 'post',
-                                                                          'action' => common_local_url('nudge', array('nickname' => $profile->nickname))));
-       common_hidden('token', common_session_token());
-       common_element('input', array('type' => 'submit',
-                                                                 'class' => 'submit',
-                                                                 'value' => _('Send a nudge')));
-       common_element_end('form');
-}
-function common_nudge_response() {
-       common_element('p', array('id' => 'nudge_response'), _('Nudge sent!'));
-}
-
-function common_subscribe_form($profile) {
-       common_element_start('form', array('id' => 'subscribe-' . $profile->id,
-                                                                          'method' => 'post',
-                                                                          'class' => 'subscribe',
-                                                                          'action' => common_local_url('subscribe')));
-       common_hidden('token', common_session_token());
-       common_element('input', array('id' => 'subscribeto-' . $profile->id,
-                                                                 'name' => 'subscribeto',
-                                                                 'type' => 'hidden',
-                                                                 'value' => $profile->id));
-       common_element('input', array('type' => 'submit',
-                                                                 'class' => 'submit',
-                                                                 'value' => _('Subscribe')));
-       common_element_end('form');
-}
-
-function common_unsubscribe_form($profile) {
-       common_element_start('form', array('id' => 'unsubscribe-' . $profile->id,
-                                                                          'method' => 'post',
-                                                                          'class' => 'unsubscribe',
-                                                                          'action' => common_local_url('unsubscribe')));
-       common_hidden('token', common_session_token());
-       common_element('input', array('id' => 'unsubscribeto-' . $profile->id,
-                                                                 'name' => 'unsubscribeto',
-                                                                 'type' => 'hidden',
-                                                                 'value' => $profile->id));
-       common_element('input', array('type' => 'submit',
-                                                                 'class' => 'submit',
-                                                                 'value' => _('Unsubscribe')));
-       common_element_end('form');
+function common_session_token()
+{
+    common_ensure_session();
+    if (!array_key_exists('token', $_SESSION)) {
+        $_SESSION['token'] = common_good_rand(64);
+    }
+    return $_SESSION['token'];
+}
+
+function common_disfavor_form($notice)
+{
+    common_element_start('form', array('id' => 'disfavor-' . $notice->id,
+                                       'method' => 'post',
+                                       'class' => 'disfavor',
+                                       'action' => common_local_url('disfavor')));
+
+    common_element('input', array('type' => 'hidden',
+                                  'name' => 'token-'. $notice->id,
+                                  'id' => 'token-'. $notice->id,
+                                  'class' => 'token',
+                                  'value' => common_session_token()));
+
+    common_element('input', array('type' => 'hidden',
+                                  'name' => 'notice',
+                                  'id' => 'notice-n'. $notice->id,
+                                  'class' => 'notice',
+                                  'value' => $notice->id));
+
+    common_element('input', array('type' => 'submit',
+                                  'id' => 'disfavor-submit-' . $notice->id,
+                                  'name' => 'disfavor-submit-' . $notice->id,
+                                  'class' => 'disfavor',
+                                  'value' => 'Disfavor favorite',
+                                  'title' => 'Remove this message from favorites'));
+    common_element_end('form');
+}
+
+function common_favor_form($notice)
+{
+    common_element_start('form', array('id' => 'favor-' . $notice->id,
+                                       'method' => 'post',
+                                       'class' => 'favor',
+                                       'action' => common_local_url('favor')));
+
+    common_element('input', array('type' => 'hidden',
+                                  'name' => 'token-'. $notice->id,
+                                  'id' => 'token-'. $notice->id,
+                                  'class' => 'token',
+                                  'value' => common_session_token()));
+
+    common_element('input', array('type' => 'hidden',
+                                  'name' => 'notice',
+                                  'id' => 'notice-n'. $notice->id,
+                                  'class' => 'notice',
+                                  'value' => $notice->id));
+
+    common_element('input', array('type' => 'submit',
+                                  'id' => 'favor-submit-' . $notice->id,
+                                  'name' => 'favor-submit-' . $notice->id,
+                                  'class' => 'favor',
+                                  'value' => 'Add to favorites',
+                                  'title' => 'Add this message to favorites'));
+    common_element_end('form');
+}
+
+function common_nudge_form($profile)
+{
+    common_element_start('form', array('id' => 'nudge', 'method' => 'post',
+                                       'action' => common_local_url('nudge', array('nickname' => $profile->nickname))));
+    common_hidden('token', common_session_token());
+    common_element('input', array('type' => 'submit',
+                                  'class' => 'submit',
+                                  'value' => _('Send a nudge')));
+    common_element_end('form');
+}
+function common_nudge_response()
+{
+    common_element('p', array('id' => 'nudge_response'), _('Nudge sent!'));
+}
+
+function common_subscribe_form($profile)
+{
+    common_element_start('form', array('id' => 'subscribe-' . $profile->id,
+                                       'method' => 'post',
+                                       'class' => 'subscribe',
+                                       'action' => common_local_url('subscribe')));
+    common_hidden('token', common_session_token());
+    common_element('input', array('id' => 'subscribeto-' . $profile->id,
+                                  'name' => 'subscribeto',
+                                  'type' => 'hidden',
+                                  'value' => $profile->id));
+    common_element('input', array('type' => 'submit',
+                                  'class' => 'submit',
+                                  'value' => _('Subscribe')));
+    common_element_end('form');
+}
+
+function common_unsubscribe_form($profile)
+{
+    common_element_start('form', array('id' => 'unsubscribe-' . $profile->id,
+                                       'method' => 'post',
+                                       'class' => 'unsubscribe',
+                                       'action' => common_local_url('unsubscribe')));
+    common_hidden('token', common_session_token());
+    common_element('input', array('id' => 'unsubscribeto-' . $profile->id,
+                                  'name' => 'unsubscribeto',
+                                  'type' => 'hidden',
+                                  'value' => $profile->id));
+    common_element('input', array('type' => 'submit',
+                                  'class' => 'submit',
+                                  'value' => _('Unsubscribe')));
+    common_element_end('form');
 }
 
 // XXX: Refactor this code
-function common_profile_new_message_nudge ($cur, $profile) {
-       $user = User::staticGet('id', $profile->id);
+function common_profile_new_message_nudge ($cur, $profile)
+{
+    $user = User::staticGet('id', $profile->id);
 
-       if ($cur && $cur->id != $user->id && $cur->mutuallySubscribed($user)) {
+    if ($cur && $cur->id != $user->id && $cur->mutuallySubscribed($user)) {
         common_element_start('li', array('id' => 'profile_send_a_new_message'));
-               common_element('a', array('href' => common_local_url('newmessage', array('to' => $user->id))),
-                                          _('Send a message'));
+        common_element('a', array('href' => common_local_url('newmessage', array('to' => $user->id))),
+                       _('Send a message'));
         common_element_end('li');
 
-           if ($user->email && $user->emailnotifynudge) {
+        if ($user->email && $user->emailnotifynudge) {
             common_element_start('li', array('id' => 'profile_nudge'));
             common_nudge_form($user);
             common_element_end('li');
         }
-       }
+    }
 }
 
-function common_cache_key($extra) {
-       return 'laconica:' . common_keyize(common_config('site', 'name')) . ':' . $extra;
+function common_cache_key($extra)
+{
+    return 'laconica:' . common_keyize(common_config('site', 'name')) . ':' . $extra;
 }
 
-function common_keyize($str) {
-       $str = strtolower($str);
-       $str = preg_replace('/\s/', '_', $str);
-       return $str;
+function common_keyize($str)
+{
+    $str = strtolower($str);
+    $str = preg_replace('/\s/', '_', $str);
+    return $str;
 }
 
-function common_message_form($content, $user, $to) {
+function common_message_form($content, $user, $to)
+{
 
-       common_element_start('form', array('id' => 'message_form',
-                                                                          'method' => 'post',
-                                                                          'action' => common_local_url('newmessage')));
+    common_element_start('form', array('id' => 'message_form',
+                                       'method' => 'post',
+                                       'action' => common_local_url('newmessage')));
 
-       $mutual_users = $user->mutuallySubscribedUsers();
+    $mutual_users = $user->mutuallySubscribedUsers();
 
-       $mutual = array();
+    $mutual = array();
 
-       while ($mutual_users->fetch()) {
-               if ($mutual_users->id != $user->id) {
-                       $mutual[$mutual_users->id] = $mutual_users->nickname;
-               }
-       }
+    while ($mutual_users->fetch()) {
+        if ($mutual_users->id != $user->id) {
+            $mutual[$mutual_users->id] = $mutual_users->nickname;
+        }
+    }
 
-       $mutual_users->free();
-       unset($mutual_users);
+    $mutual_users->free();
+    unset($mutual_users);
 
-       common_dropdown('to', _('To'), $mutual, NULL, FALSE, $to->id);
+    common_dropdown('to', _('To'), $mutual, null, false, $to->id);
 
-       common_element_start('p');
+    common_element_start('p');
 
-       common_element('textarea', array('id' => 'message_content',
-                                                                        'cols' => 60,
-                                                                        'rows' => 3,
-                                                                        'name' => 'content'),
-                                  ($content) ? $content : '');
+    common_element('textarea', array('id' => 'message_content',
+                                     'cols' => 60,
+                                     'rows' => 3,
+                                     'name' => 'content'),
+                   ($content) ? $content : '');
 
-       common_element('input', array('id' => 'message_send',
-                                                                 'name' => 'message_send',
-                                                                 'type' => 'submit',
-                                                                 'value' => _('Send')));
+    common_element('input', array('id' => 'message_send',
+                                  'name' => 'message_send',
+                                  'type' => 'submit',
+                                  'value' => _('Send')));
 
-       common_hidden('token', common_session_token());
+    common_hidden('token', common_session_token());
 
-       common_element_end('p');
-       common_element_end('form');
+    common_element_end('p');
+    common_element_end('form');
 }
 
-function common_memcache() {
-       static $cache = NULL;
-       if (!common_config('memcached', 'enabled')) {
-               return NULL;
-       } else {
-               if (!$cache) {
-                       $cache = new Memcache();
-                       $servers = common_config('memcached', 'server');
-                       if (is_array($servers)) {
-                               foreach($servers as $server) {
-                                       $cache->addServer($server);
-                               }
-                       } else {
-                               $cache->addServer($servers);
-                       }
-               }
-               return $cache;
-       }
+function common_memcache()
+{
+    static $cache = null;
+    if (!common_config('memcached', 'enabled')) {
+        return null;
+    } else {
+        if (!$cache) {
+            $cache = new Memcache();
+            $servers = common_config('memcached', 'server');
+            if (is_array($servers)) {
+                foreach($servers as $server) {
+                    $cache->addServer($server);
+                }
+            } else {
+                $cache->addServer($servers);
+            }
+        }
+        return $cache;
+    }
 }
 
-function common_compatible_license($from, $to) {
-       # XXX: better compatibility check needed here!
-       return ($from == $to);
+function common_compatible_license($from, $to)
+{
+    // XXX: better compatibility check needed here!
+    return ($from == $to);
 }
 
 /* These are almost identical, so we use a helper function */
 
-function common_block_form($profile, $args=NULL) {
+function common_block_form($profile, $args=null)
+{
     common_blocking_form('block', _('Block'), $profile, $args);
 }
 
-function common_unblock_form($profile, $args=NULL) {
+function common_unblock_form($profile, $args=null)
+{
     common_blocking_form('unblock', _('Unblock'), $profile, $args);
 }
 
-function common_blocking_form($type, $label, $profile, $args=NULL) {
+function common_blocking_form($type, $label, $profile, $args=null)
+{
     common_element_start('form', array('id' => $type . '-' . $profile->id,
                                        'method' => 'post',
                                        'class' => $type,
@@ -2220,4 +2344,3 @@ function common_blocking_form($type, $label, $profile, $args=NULL) {
     common_element_end('form');
     return;
 }
-
index cfc9642e4c159a602a00dda22edfdaab2fa7befd..91015fd4503f4875d489807a8b7bdf5642c561ee 100644 (file)
@@ -28,64 +28,71 @@ require_once(INSTALLDIR.'/lib/queuehandler.php');
  * superclass.
  */
 
-class XmppQueueHandler extends QueueHandler {
-       
-       function start() {
-               # Low priority; we don't want to receive messages
-               $this->log(LOG_INFO, "INITIALIZE");
-               $this->conn = jabber_connect($this->_id);
-               if ($this->conn) {
-                       $this->conn->addEventHandler('message', 'forward_message', $this);
-                       $this->conn->addEventHandler('reconnect', 'handle_reconnect', $this);
-                       $this->conn->setReconnectTimeout(600);
-                       jabber_send_presence("Send me a message to post a notice", 'available', NULL, 'available', -1);
-               }
-               return !is_null($this->conn);
-       }
-       
-       function handle_reconnect(&$pl) {
-               $this->conn->processUntil('session_start');
-               $this->conn->presence(NULL, 'available', NULL, 'available', -1);
-       }
+class XmppQueueHandler extends QueueHandler
+{
+    
+    function start()
+    {
+        # Low priority; we don't want to receive messages
+        $this->log(LOG_INFO, "INITIALIZE");
+        $this->conn = jabber_connect($this->_id);
+        if ($this->conn) {
+            $this->conn->addEventHandler('message', 'forward_message', $this);
+            $this->conn->addEventHandler('reconnect', 'handle_reconnect', $this);
+            $this->conn->setReconnectTimeout(600);
+            jabber_send_presence("Send me a message to post a notice", 'available', null, 'available', -1);
+        }
+        return !is_null($this->conn);
+    }
+    
+    function handle_reconnect(&$pl)
+    {
+        $this->conn->processUntil('session_start');
+        $this->conn->presence(null, 'available', null, 'available', -1);
+    }
 
-       function idle($timeout=0) {
-               # Process the queue for as long as needed
-               try {
-                       if ($this->conn) {
-                               $this->conn->processTime($timeout);
-                       }
-               } catch (XMPPHP_Exception $e) {
-                       $this->log(LOG_ERR, "Got an XMPPHP_Exception: " . $e->getMessage());
-                       die($e->getMessage());
-               }
-       }
-       
-       function forward_message(&$pl) {
-               if ($pl['type'] != 'chat') {
-                   $this->log(LOG_DEBUG, 'Ignoring message of type ' . $pl['type'] . ' from ' . $pl['from']);
-                       return;
-               }
-               $listener = $this->listener();
-               if (strtolower($listener) == strtolower($pl['from'])) {
-                       $this->log(LOG_WARNING, 'Ignoring loop message.');
-                       return;
-               }
-               $this->log(LOG_INFO, 'Forwarding message from ' . $pl['from'] . ' to ' . $listener);
-               $this->conn->message($this->listener(), $pl['body'], 'chat', NULL, $this->ofrom($pl['from']));
-       }
+    function idle($timeout=0)
+    {
+        # Process the queue for as long as needed
+        try {
+            if ($this->conn) {
+                $this->conn->processTime($timeout);
+            }
+        } catch (XMPPHP_Exception $e) {
+            $this->log(LOG_ERR, "Got an XMPPHP_Exception: " . $e->getMessage());
+            die($e->getMessage());
+        }
+    }
+    
+    function forward_message(&$pl)
+    {
+        if ($pl['type'] != 'chat') {
+            $this->log(LOG_DEBUG, 'Ignoring message of type ' . $pl['type'] . ' from ' . $pl['from']);
+            return;
+        }
+        $listener = $this->listener();
+        if (strtolower($listener) == strtolower($pl['from'])) {
+            $this->log(LOG_WARNING, 'Ignoring loop message.');
+            return;
+        }
+        $this->log(LOG_INFO, 'Forwarding message from ' . $pl['from'] . ' to ' . $listener);
+        $this->conn->message($this->listener(), $pl['body'], 'chat', null, $this->ofrom($pl['from']));
+    }
 
-       function ofrom($from) {
-               $address = "<addresses xmlns='http://jabber.org/protocol/address'>\n";
-               $address .= "<address type='ofrom' jid='$from' />\n";
-               $address .= "</addresses>\n";
-               return $address;
-       }
+    function ofrom($from)
+    {
+        $address = "<addresses xmlns='http://jabber.org/protocol/address'>\n";
+        $address .= "<address type='ofrom' jid='$from' />\n";
+        $address .= "</addresses>\n";
+        return $address;
+    }
 
-       function listener() {
-               if (common_config('xmpp', 'listener')) {
-                       return common_config('xmpp', 'listener');
-               } else {
-                       return jabber_daemon_address() . '/' . common_config('xmpp','resource') . '-listener';
-               }
-       }
+    function listener()
+    {
+        if (common_config('xmpp', 'listener')) {
+            return common_config('xmpp', 'listener');
+        } else {
+            return jabber_daemon_address() . '/' . common_config('xmpp','resource') . '-listener';
+        }
+    }
 }
index 8538ae09a2c561aaac2cfb80751c96dc1b5521b7..3a4f8315d338ff7a79f7576e9b3b7302e1284b19 100755 (executable)
@@ -20,8 +20,8 @@
 
 # Abort if called from a web server
 if (isset($_SERVER) && array_key_exists('REQUEST_METHOD', $_SERVER)) {
-       print "This script must be run from the command line\n";
-       exit();
+    print "This script must be run from the command line\n";
+    exit();
 }
 
 define('INSTALLDIR', realpath(dirname(__FILE__) . '/..'));
@@ -33,21 +33,25 @@ require_once(INSTALLDIR . '/lib/queuehandler.php');
 
 set_error_handler('common_error_handler');
 
-class EnjitQueueHandler extends QueueHandler {
-       
-       function transport() {
-               return 'enjit';
-       }
+class EnjitQueueHandler extends QueueHandler
+{
+    
+    function transport()
+    {
+        return 'enjit';
+    }
 
-       function start() {
+    function start()
+    {
                 $this->log(LOG_INFO, "Starting EnjitQueueHandler");
                 $this->log(LOG_INFO, "Broadcasting to ".common_config('enjit', 'apiurl'));
-               return true;
-       }
+        return true;
+    }
 
-       function handle_notice($notice) {
+    function handle_notice($notice)
+    {
 
-               $profile = Profile::staticGet($notice->profile_id);
+        $profile = Profile::staticGet($notice->profile_id);
 
                 $this->log(LOG_INFO, "Posting Notice ".$notice->id." from ".$profile->nickname);
 
@@ -60,25 +64,25 @@ class EnjitQueueHandler extends QueueHandler {
                 #
                 # Build an Atom message from the notice
                 #
-               $noticeurl = common_local_url('shownotice', array('notice' => $notice->id));
-               $msg = $profile->nickname . ': ' . $notice->content;
-
-               $atom  = "<entry xmlns='http://www.w3.org/2005/Atom'>\n";
-               $atom .= "<apisource>".common_config('enjit','source')."</apisource>\n";
-               $atom .= "<source>\n";
-               $atom .= "<title>" . $profile->nickname . " - " . common_config('site', 'name') . "</title>\n";
-               $atom .= "<link href='" . $profile->profileurl . "'/>\n";
-               $atom .= "<link rel='self' type='application/rss+xml' href='" . common_local_url('userrss', array('nickname' => $profile->nickname)) . "'/>\n";
-               $atom .= "<author><name>" . $profile->nickname . "</name></author>\n";
-               $atom .= "<icon>" . common_profile_avatar_url($profile, AVATAR_PROFILE_SIZE) . "</icon>\n";
-               $atom .= "</source>\n";
-               $atom .= "<title>" . htmlspecialchars($msg) . "</title>\n";
-               $atom .= "<summary>" . htmlspecialchars($msg) . "</summary>\n";
-               $atom .= "<link rel='alternate' href='" . $noticeurl . "' />\n";
-               $atom .= "<id>". $notice->uri . "</id>\n";
-               $atom .= "<published>".common_date_w3dtf($notice->created)."</published>\n";
-               $atom .= "<updated>".common_date_w3dtf($notice->modified)."</updated>\n";
-               $atom .= "</entry>\n";
+        $noticeurl = common_local_url('shownotice', array('notice' => $notice->id));
+        $msg = $profile->nickname . ': ' . $notice->content;
+
+        $atom  = "<entry xmlns='http://www.w3.org/2005/Atom'>\n";
+        $atom .= "<apisource>".common_config('enjit','source')."</apisource>\n";
+        $atom .= "<source>\n";
+        $atom .= "<title>" . $profile->nickname . " - " . common_config('site', 'name') . "</title>\n";
+        $atom .= "<link href='" . $profile->profileurl . "'/>\n";
+        $atom .= "<link rel='self' type='application/rss+xml' href='" . common_local_url('userrss', array('nickname' => $profile->nickname)) . "'/>\n";
+        $atom .= "<author><name>" . $profile->nickname . "</name></author>\n";
+        $atom .= "<icon>" . common_profile_avatar_url($profile, AVATAR_PROFILE_SIZE) . "</icon>\n";
+        $atom .= "</source>\n";
+        $atom .= "<title>" . htmlspecialchars($msg) . "</title>\n";
+        $atom .= "<summary>" . htmlspecialchars($msg) . "</summary>\n";
+        $atom .= "<link rel='alternate' href='" . $noticeurl . "' />\n";
+        $atom .= "<id>". $notice->uri . "</id>\n";
+        $atom .= "<published>".common_date_w3dtf($notice->created)."</published>\n";
+        $atom .= "<updated>".common_date_w3dtf($notice->modified)."</updated>\n";
+        $atom .= "</entry>\n";
 
                 $url  = common_config('enjit', 'apiurl') . "/submit/". common_config('enjit','apikey');
                 $data = "msg=$atom";
@@ -86,43 +90,43 @@ class EnjitQueueHandler extends QueueHandler {
                 #
                 # POST the message to $config['enjit']['apiurl']
                 #
-               $ch   = curl_init();
+        $ch   = curl_init();
 
-               curl_setopt($ch, CURLOPT_URL, $url);
+        curl_setopt($ch, CURLOPT_URL, $url);
  
                 curl_setopt($ch, CURLOPT_HEADER, 1); 
-               curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
-               curl_setopt($ch, CURLOPT_POST, 1) ;
-               curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
+        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
+        curl_setopt($ch, CURLOPT_POST, 1) ;
+        curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
 
                 # SSL and Debugging options
                 #
-               # curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
-               # curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
+        # curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
+        # curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
                 # curl_setopt($ch, CURLOPT_VERBOSE, 1); 
 
-               $result = curl_exec($ch);
+        $result = curl_exec($ch);
 
-               $code = curl_getinfo($ch, CURLINFO_HTTP_CODE );
+        $code = curl_getinfo($ch, CURLINFO_HTTP_CODE );
 
                 $this->log(LOG_INFO, "Response Code: $code");
 
-               curl_close($ch);
+        curl_close($ch);
 
                 return $code;
-       }
-       
+    }
+    
 
 }
 
 mb_internal_encoding('UTF-8');
 
-$id = ($argc > 1) ? $argv[1] : NULL;
+$id = ($argc > 1) ? $argv[1] : null;
 
 $handler = new EnjitQueueHandler($id);
 
 if ($handler->start()) {
-       $handler->handle_queue();
+    $handler->handle_queue();
 }
 
 $handler->finish();
index 88f385798d0496c930e9f6e1a4346153ad532590..6f65c78a1fe8f8971c3ed5ad0d90b04cd5f2ed63 100755 (executable)
@@ -37,10 +37,10 @@ $cnt = $notice->find();
 while ($notice->fetch()) {
     common_log(LOG_INFO, 'Getting tags for notice #' . $notice->id);
     $notice->saveTags();
-       $original = clone($notice);
-       $notice->rendered = common_render_content($notice->content, $notice);
-       $result = $notice->update($original);
-       if (!$result) {
-               common_log_db_error($notice, 'UPDATE', __FILE__);
-       }
+    $original = clone($notice);
+    $notice->rendered = common_render_content($notice->content, $notice);
+    $result = $notice->update($original);
+    if (!$result) {
+        common_log_db_error($notice, 'UPDATE', __FILE__);
+    }
 }
index 1715b0bc1ba22d13b3461121672f385772b02684..a5c8a0a5acb5e0dcf9afacb932aacd4d8151c5a1 100755 (executable)
@@ -34,14 +34,14 @@ define('LACONICA', true);
 
 require_once(INSTALLDIR . '/lib/common.php');
 
-$start_at = ($argc > 1) ? $argv[1] : NULL;
+$start_at = ($argc > 1) ? $argv[1] : null;
 
 common_log(LOG_INFO, 'Updating user inboxes.');
 
 $user = new User();
 
 if ($start_at) {
-       $user->whereAdd('id >= ' . $start_at);
+    $user->whereAdd('id >= ' . $start_at);
 }
 
 $cnt = $user->find();
@@ -49,32 +49,32 @@ $cache = common_memcache();
 
 while ($user->fetch()) {
     common_log(LOG_INFO, 'Updating inbox for user ' . $user->id);
-       $user->query('BEGIN');
-       $inbox = new Notice_inbox();
-       $result = $inbox->query('INSERT LOW_PRIORITY INTO notice_inbox (user_id, notice_id, created) ' .
-                                                       'SELECT ' . $user->id . ', notice.id, notice.created ' .
-                                                       'FROM subscription JOIN notice ON subscription.subscribed = notice.profile_id ' .
-                                                       'WHERE subscription.subscriber = ' . $user->id . ' ' .
-                                                       'AND notice.created >= subscription.created ' . 
-                                                       'AND NOT EXISTS (SELECT user_id, notice_id ' .
-                                                       'FROM notice_inbox ' .
-                                                       'WHERE user_id = ' . $user->id . ' ' . 
-                                                       'AND notice_id = notice.id)');
-       if (is_null($result) || $result === false) {
-               common_log_db_error($inbox, 'INSERT', __FILE__);
-               continue;
-       }
-       $orig = clone($user);
-       $user->inboxed = 1;
-       $result = $user->update($orig);
-       if (!$result) {
-               common_log_db_error($user, 'UPDATE', __FILE__);
-               continue;
-       }
-       $user->query('COMMIT');
-       $inbox->free();
-       unset($inbox);
-       if ($cache) {
-               $cache->delete(common_cache_key('user:notices_with_friends:' . $user->id));
-       }
+    $user->query('BEGIN');
+    $inbox = new Notice_inbox();
+    $result = $inbox->query('INSERT LOW_PRIORITY INTO notice_inbox (user_id, notice_id, created) ' .
+                            'SELECT ' . $user->id . ', notice.id, notice.created ' .
+                            'FROM subscription JOIN notice ON subscription.subscribed = notice.profile_id ' .
+                            'WHERE subscription.subscriber = ' . $user->id . ' ' .
+                            'AND notice.created >= subscription.created ' . 
+                            'AND NOT EXISTS (SELECT user_id, notice_id ' .
+                            'FROM notice_inbox ' .
+                            'WHERE user_id = ' . $user->id . ' ' . 
+                            'AND notice_id = notice.id)');
+    if (is_null($result) || $result === false) {
+        common_log_db_error($inbox, 'INSERT', __FILE__);
+        continue;
+    }
+    $orig = clone($user);
+    $user->inboxed = 1;
+    $result = $user->update($orig);
+    if (!$result) {
+        common_log_db_error($user, 'UPDATE', __FILE__);
+        continue;
+    }
+    $user->query('COMMIT');
+    $inbox->free();
+    unset($inbox);
+    if ($cache) {
+        $cache->delete(common_cache_key('user:notices_with_friends:' . $user->id));
+    }
 }
index c6c925729eca884dc446a3450185561a73edd30d..c27185546e7004c150f0290274621dcbf48311d1 100755 (executable)
@@ -20,8 +20,8 @@
 
 # Abort if called from a web server
 if (isset($_SERVER) && array_key_exists('REQUEST_METHOD', $_SERVER)) {
-       print "This script must be run from the command line\n";
-       exit();
+    print "This script must be run from the command line\n";
+    exit();
 }
 
 define('INSTALLDIR', realpath(dirname(__FILE__) . '/..'));
@@ -31,20 +31,20 @@ require_once(INSTALLDIR . '/lib/common.php');
 
 common_log(LOG_INFO, 'Starting to render old notices.');
 
-$start_at = ($argc > 1) ? $argv[1] : NULL;
+$start_at = ($argc > 1) ? $argv[1] : null;
 
 $notice = new Notice();
 if ($start_at) {
-       $notice->whereAdd('id >= ' . $start_at);
+    $notice->whereAdd('id >= ' . $start_at);
 }
 $cnt = $notice->find();
 
 while ($notice->fetch()) {
-       common_log(LOG_INFO, 'Pre-rendering notice #' . $notice->id);
-       $original = clone($notice);
-       $notice->rendered = common_render_content($notice->content, $notice);
-       $result = $notice->update($original);
-       if (!$result) {
-               common_log_db_error($notice, 'UPDATE', __FILE__);
-       }
+    common_log(LOG_INFO, 'Pre-rendering notice #' . $notice->id);
+    $original = clone($notice);
+    $notice->rendered = common_render_content($notice->content, $notice);
+    $result = $notice->update($original);
+    if (!$result) {
+        common_log_db_error($notice, 'UPDATE', __FILE__);
+    }
 }
index b4dda2254cef080d3bccf150d6e2c836ccaf23aa..4f5704249319b018beee7be4dcdc613fe0997621 100755 (executable)
@@ -20,8 +20,8 @@
 
 # Abort if called from a web server
 if (isset($_SERVER) && array_key_exists('REQUEST_METHOD', $_SERVER)) {
-       print "This script must be run from the command line\n";
-       exit();
+    print "This script must be run from the command line\n";
+    exit();
 }
 
 define('INSTALLDIR', realpath(dirname(__FILE__) . '/..'));
index 0543abb2a33bb46e045699ed78faa711192a2167..f907e158416099b87df2da8d0b66d9fcd26927ff 100755 (executable)
@@ -42,68 +42,68 @@ common_log(LOG_INFO, 'Updating user inboxes.');
 $ids = file($id_file);
 
 foreach ($ids as $id) {
-       
-       $user = User::staticGet('id', $id);
+    
+    $user = User::staticGet('id', $id);
 
-       if (!$user) {
-               common_log(LOG_WARNING, 'No such user: ' . $id);
-               continue;
-       }
-       
-       if ($user->inboxed) {
-               common_log(LOG_WARNING, 'Already inboxed: ' . $id);
-               continue;
-       }
-       
+    if (!$user) {
+        common_log(LOG_WARNING, 'No such user: ' . $id);
+        continue;
+    }
+    
+    if ($user->inboxed) {
+        common_log(LOG_WARNING, 'Already inboxed: ' . $id);
+        continue;
+    }
+    
     common_log(LOG_INFO, 'Updating inbox for user ' . $user->id);
-       
-       $user->query('BEGIN');
-       
-       $old_inbox = new Notice_inbox();
-       $old_inbox->user_id = $user->id;
-       
-       $result = $old_inbox->delete();
-       
-       if (is_null($result) || $result === false) {
-               common_log_db_error($old_inbox, 'DELETE', __FILE__);
-               continue;
-       }
+    
+    $user->query('BEGIN');
+    
+    $old_inbox = new Notice_inbox();
+    $old_inbox->user_id = $user->id;
+    
+    $result = $old_inbox->delete();
+    
+    if (is_null($result) || $result === false) {
+        common_log_db_error($old_inbox, 'DELETE', __FILE__);
+        continue;
+    }
 
-       $old_inbox->free();
-       
-       $inbox = new Notice_inbox();
-       
-       $result = $inbox->query('INSERT INTO notice_inbox (user_id, notice_id, created) ' .
-                                                       'SELECT ' . $user->id . ', notice.id, notice.created ' .
-                                                       'FROM subscription JOIN notice ON subscription.subscribed = notice.profile_id ' .
-                                                       'WHERE subscription.subscriber = ' . $user->id . ' ' .
-                                                       'AND notice.created >= subscription.created ' .
-                                                       'AND now() - notice.created < ' . (7 * 24 * 3600) . ' ' .
-                                                       'AND NOT EXISTS (SELECT user_id, notice_id ' .
-                                                       'FROM notice_inbox ' .
-                                                       'WHERE user_id = ' . $user->id . ' ' . 
-                                                       'AND notice_id = notice.id)');
-       
-       if (is_null($result) || $result === false) {
-               common_log_db_error($inbox, 'INSERT', __FILE__);
-               continue;
-       }
-       
-       $orig = clone($user);
-       $user->inboxed = 1;
-       $result = $user->update($orig);
-       
-       if (!$result) {
-               common_log_db_error($user, 'UPDATE', __FILE__);
-               continue;
-       }
-       
-       $user->query('COMMIT');
-       
-       $inbox->free();
-       unset($inbox);
-       
-       if ($cache) {
-               $cache->delete(common_cache_key('user:notices_with_friends:' . $user->id));
-       }
+    $old_inbox->free();
+    
+    $inbox = new Notice_inbox();
+    
+    $result = $inbox->query('INSERT INTO notice_inbox (user_id, notice_id, created) ' .
+                            'SELECT ' . $user->id . ', notice.id, notice.created ' .
+                            'FROM subscription JOIN notice ON subscription.subscribed = notice.profile_id ' .
+                            'WHERE subscription.subscriber = ' . $user->id . ' ' .
+                            'AND notice.created >= subscription.created ' .
+                            'AND now() - notice.created < ' . (7 * 24 * 3600) . ' ' .
+                            'AND NOT EXISTS (SELECT user_id, notice_id ' .
+                            'FROM notice_inbox ' .
+                            'WHERE user_id = ' . $user->id . ' ' . 
+                            'AND notice_id = notice.id)');
+    
+    if (is_null($result) || $result === false) {
+        common_log_db_error($inbox, 'INSERT', __FILE__);
+        continue;
+    }
+    
+    $orig = clone($user);
+    $user->inboxed = 1;
+    $result = $user->update($orig);
+    
+    if (!$result) {
+        common_log_db_error($user, 'UPDATE', __FILE__);
+        continue;
+    }
+    
+    $user->query('COMMIT');
+    
+    $inbox->free();
+    unset($inbox);
+    
+    if ($cache) {
+        $cache->delete(common_cache_key('user:notices_with_friends:' . $user->id));
+    }
 }
index 59cdb94ad72e28dd0e0b6dd861f72ddf51fcbb01..924fc45453ecc2ef08d5b570962c38d27ab6d839 100755 (executable)
@@ -20,8 +20,8 @@
 
 # Abort if called from a web server
 if (isset($_SERVER) && array_key_exists('REQUEST_METHOD', $_SERVER)) {
-       print "This script must be run from the command line\n";
-       exit();
+    print "This script must be run from the command line\n";
+    exit();
 }
 
 define('INSTALLDIR', realpath(dirname(__FILE__) . '/..'));
@@ -33,22 +33,25 @@ require_once(INSTALLDIR . '/lib/xmppqueuehandler.php');
 
 set_error_handler('common_error_handler');
 
-class JabberQueueHandler extends XmppQueueHandler {
+class JabberQueueHandler extends XmppQueueHandler
+{
 
-       var $conn = NULL;
+    var $conn = null;
 
-       function transport() {
-               return 'jabber';
-       }
+    function transport()
+    {
+        return 'jabber';
+    }
 
-       function handle_notice($notice) {
-               try {
-                       return jabber_broadcast_notice($notice);
-               } catch (XMPPHP_Exception $e) {
-                       $this->log(LOG_ERR, "Got an XMPPHP_Exception: " . $e->getMessage());
-                       exit(1);
-               }
-       }
+    function handle_notice($notice)
+    {
+        try {
+            return jabber_broadcast_notice($notice);
+        } catch (XMPPHP_Exception $e) {
+            $this->log(LOG_ERR, "Got an XMPPHP_Exception: " . $e->getMessage());
+            exit(1);
+        }
+    }
 }
 
 ini_set("max_execution_time", "0");
index 8b809f646eb88c97d2020857bf40e6988aa0e804..b9facec1a56f2cd38a673c5134ca585c9dfc27b3 100755 (executable)
@@ -20,8 +20,8 @@
 
 # Abort if called from a web server
 if (isset($_SERVER) && array_key_exists('REQUEST_METHOD', $_SERVER)) {
-       print "This script must be run from the command line\n";
-       exit();
+    print "This script must be run from the command line\n";
+    exit();
 }
 
 define('INSTALLDIR', realpath(dirname(__FILE__) . '/..'));
@@ -34,181 +34,194 @@ require_once('Mail/mimeDecode.php');
 # FIXME: we use both Mail_mimeDecode and mailparse
 # Need to move everything to mailparse
 
-class MailerDaemon {
-
-       function __construct() {
-       }
-
-       function handle_message($fname='php://stdin') {
-               list($from, $to, $msg) = $this->parse_message($fname);
-               if (!$from || !$to || !$msg) {
-                       $this->error(NULL, _('Could not parse message.'));
-               }
-               common_log(LOG_INFO, "Mail from $from to $to: " .substr($msg, 0, 20));
-               $user = $this->user_from($from);
-               if (!$user) {
-                       $this->error($from, _('Not a registered user.'));
-                       return false;
-               }
-               if (!$this->user_match_to($user, $to)) {
-                       $this->error($from, _('Sorry, that is not your incoming email address.'));
-                       return false;
-               }
-               if (!$user->emailpost) {
-                       $this->error($from, _('Sorry, no incoming email allowed.'));
-                       return false;
-               }
-               $response = $this->handle_command($user, $from, $msg);
-               if ($response) {
-                       return true;
-               }
-               $msg = $this->cleanup_msg($msg);
-               $this->add_notice($user, $msg);
-       }
-
-       function error($from, $msg) {
-               file_put_contents("php://stderr", $msg . "\n");
-               exit(1);
-       }
-
-       function user_from($from_hdr) {
-               $froms = mailparse_rfc822_parse_addresses($from_hdr);
-               if (!$froms) {
-                       return NULL;
-               }
-               $from = $froms[0];
-               $addr = common_canonical_email($from['address']);
-               $user = User::staticGet('email', $addr);
-               if (!$user) {
-                       $user = User::staticGet('smsemail', $addr);
-               }
-               return $user;
-       }
-
-       function user_match_to($user, $to_hdr) {
-               $incoming = $user->incomingemail;
-               $tos = mailparse_rfc822_parse_addresses($to_hdr);
-               foreach ($tos as $to) {
-                       if (strcasecmp($incoming, $to['address']) == 0) {
-                               return true;
-                       }
-               }
-               return false;
-       }
-
-       function handle_command($user, $from, $msg) {
-               $inter = new CommandInterpreter();
-               $cmd = $inter->handle_command($user, $msg);
-               if ($cmd) {
-                       $cmd->execute(new MailChannel($from));
-                       return true;
-               }
-               return false;
-       }
-
-       function respond($from, $to, $response) {
-
-               $headers['From'] = $to;
-               $headers['To'] = $from;
-               $headers['Subject'] = "Command complete";
-
-               return mail_send(array($from), $headers, $response);
-       }
-
-       function log($level, $msg) {
-               common_log($level, 'MailDaemon: '.$msg);
-       }
-
-       function add_notice($user, $msg) {
+class MailerDaemon
+{
+
+    function __construct()
+    {
+    }
+
+    function handle_message($fname='php://stdin')
+    {
+        list($from, $to, $msg) = $this->parse_message($fname);
+        if (!$from || !$to || !$msg) {
+            $this->error(null, _('Could not parse message.'));
+        }
+        common_log(LOG_INFO, "Mail from $from to $to: " .substr($msg, 0, 20));
+        $user = $this->user_from($from);
+        if (!$user) {
+            $this->error($from, _('Not a registered user.'));
+            return false;
+        }
+        if (!$this->user_match_to($user, $to)) {
+            $this->error($from, _('Sorry, that is not your incoming email address.'));
+            return false;
+        }
+        if (!$user->emailpost) {
+            $this->error($from, _('Sorry, no incoming email allowed.'));
+            return false;
+        }
+        $response = $this->handle_command($user, $from, $msg);
+        if ($response) {
+            return true;
+        }
+        $msg = $this->cleanup_msg($msg);
+        $this->add_notice($user, $msg);
+    }
+
+    function error($from, $msg)
+    {
+        file_put_contents("php://stderr", $msg . "\n");
+        exit(1);
+    }
+
+    function user_from($from_hdr)
+    {
+        $froms = mailparse_rfc822_parse_addresses($from_hdr);
+        if (!$froms) {
+            return null;
+        }
+        $from = $froms[0];
+        $addr = common_canonical_email($from['address']);
+        $user = User::staticGet('email', $addr);
+        if (!$user) {
+            $user = User::staticGet('smsemail', $addr);
+        }
+        return $user;
+    }
+
+    function user_match_to($user, $to_hdr)
+    {
+        $incoming = $user->incomingemail;
+        $tos = mailparse_rfc822_parse_addresses($to_hdr);
+        foreach ($tos as $to) {
+            if (strcasecmp($incoming, $to['address']) == 0) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    function handle_command($user, $from, $msg)
+    {
+        $inter = new CommandInterpreter();
+        $cmd = $inter->handle_command($user, $msg);
+        if ($cmd) {
+            $cmd->execute(new MailChannel($from));
+            return true;
+        }
+        return false;
+    }
+
+    function respond($from, $to, $response)
+    {
+
+        $headers['From'] = $to;
+        $headers['To'] = $from;
+        $headers['Subject'] = "Command complete";
+
+        return mail_send(array($from), $headers, $response);
+    }
+
+    function log($level, $msg)
+    {
+        common_log($level, 'MailDaemon: '.$msg);
+    }
+
+    function add_notice($user, $msg)
+    {
         // should test
         // $msg_shortened = common_shorten_links($msg);
         // if (mb_strlen($msg_shortened) > 140) ERROR and STOP
-               $notice = Notice::saveNew($user->id, $msg, 'mail');
-               if (is_string($notice)) {
-                       $this->log(LOG_ERR, $notice);
-                       return;
-               }
-               common_broadcast_notice($notice);
-               $this->log(LOG_INFO,
-                                  'Added notice ' . $notice->id . ' from user ' . $user->nickname);
-       }
-
-       function parse_message($fname) {
-               $contents = file_get_contents($fname);
-               $parsed = Mail_mimeDecode::decode(array('input' => $contents,
-                                                                                               'include_bodies' => true,
-                                                                                               'decode_headers' => true,
-                                                                                               'decode_bodies' => true));
-               if (!$parsed) {
-                       return NULL;
-               }
-
-               $from = $parsed->headers['from'];
-
-               $to = $parsed->headers['to'];
-
-               $type = $parsed->ctype_primary . '/' . $parsed->ctype_secondary;
-
-               if ($parsed->ctype_primary == 'multipart') {
-                       foreach ($parsed->parts as $part) {
-                               if ($part->ctype_primary == 'text' &&
-                                       $part->ctype_secondary == 'plain') {
-                                       $msg = $part->body;
-                                       break;
-                               }
-                       }
-               } else if ($type == 'text/plain') {
-                       $msg = $parsed->body;
-               } else {
-                       $this->unsupported_type($type);
-               }
-
-               return array($from, $to, $msg);
-       }
-
-       function unsupported_type($type) {
-               $this->error(NULL, "Unsupported message type: " . $type);
-       }
-
-       function cleanup_msg($msg) {
-               $lines = explode("\n", $msg);
-
-               $output = '';
-
-               foreach ($lines as $line) {
-                       // skip quotes
-                       if (preg_match('/^\s*>.*$/', $line)) {
-                               continue;
-                       }
-                       // skip start of quote
-                       if (preg_match('/^\s*On.*wrote:\s*$/', $line)) {
-                               continue;
-                       }
-                       // probably interesting to someone, not us
-                       if (preg_match('/^\s*Sent via/', $line)) {
-                               continue;
-                       }
-                       // skip everything after a sig
-                       if (preg_match('/^\s*--+\s*$/', $line) ||
-                               preg_match('/^\s*__+\s*$/', $line))
-                       {
-                               break;
-                       }
-                       // skip everything after Outlook quote
-                       if (preg_match('/^\s*-+\s*Original Message\s*-+\s*$/', $line)) {
-                               break;
-                       }
-                       // skip everything after weird forward
-                       if (preg_match('/^\s*Begin\s+forward/', $line)) {
-                               break;
-                       }
-
-                       $output .= ' ' . $line;
-               }
-
-               preg_replace('/\s+/', ' ', $output);
-               return trim($output);
-       }
+        $notice = Notice::saveNew($user->id, $msg, 'mail');
+        if (is_string($notice)) {
+            $this->log(LOG_ERR, $notice);
+            return;
+        }
+        common_broadcast_notice($notice);
+        $this->log(LOG_INFO,
+                   'Added notice ' . $notice->id . ' from user ' . $user->nickname);
+    }
+
+    function parse_message($fname)
+    {
+        $contents = file_get_contents($fname);
+        $parsed = Mail_mimeDecode::decode(array('input' => $contents,
+                                                'include_bodies' => true,
+                                                'decode_headers' => true,
+                                                'decode_bodies' => true));
+        if (!$parsed) {
+            return null;
+        }
+
+        $from = $parsed->headers['from'];
+
+        $to = $parsed->headers['to'];
+
+        $type = $parsed->ctype_primary . '/' . $parsed->ctype_secondary;
+
+        if ($parsed->ctype_primary == 'multipart') {
+            foreach ($parsed->parts as $part) {
+                if ($part->ctype_primary == 'text' &&
+                    $part->ctype_secondary == 'plain') {
+                    $msg = $part->body;
+                    break;
+                }
+            }
+        } else if ($type == 'text/plain') {
+            $msg = $parsed->body;
+        } else {
+            $this->unsupported_type($type);
+        }
+
+        return array($from, $to, $msg);
+    }
+
+    function unsupported_type($type)
+    {
+        $this->error(null, "Unsupported message type: " . $type);
+    }
+
+    function cleanup_msg($msg)
+    {
+        $lines = explode("\n", $msg);
+
+        $output = '';
+
+        foreach ($lines as $line) {
+            // skip quotes
+            if (preg_match('/^\s*>.*$/', $line)) {
+                continue;
+            }
+            // skip start of quote
+            if (preg_match('/^\s*On.*wrote:\s*$/', $line)) {
+                continue;
+            }
+            // probably interesting to someone, not us
+            if (preg_match('/^\s*Sent via/', $line)) {
+                continue;
+            }
+            // skip everything after a sig
+            if (preg_match('/^\s*--+\s*$/', $line) ||
+                preg_match('/^\s*__+\s*$/', $line))
+            {
+                break;
+            }
+            // skip everything after Outlook quote
+            if (preg_match('/^\s*-+\s*Original Message\s*-+\s*$/', $line)) {
+                break;
+            }
+            // skip everything after weird forward
+            if (preg_match('/^\s*Begin\s+forward/', $line)) {
+                break;
+            }
+
+            $output .= ' ' . $line;
+        }
+
+        preg_replace('/\s+/', ' ', $output);
+        return trim($output);
+    }
 }
 
 $md = new MailerDaemon();
index 1df816d1403e2b49566313a8b57a048623a9ce1f..cdcea51dc737d1e6eaa9ab884aaa2779e9c50ae6 100755 (executable)
@@ -20,8 +20,8 @@
 
 # Abort if called from a web server
 if (isset($_SERVER) && array_key_exists('REQUEST_METHOD', $_SERVER)) {
-       print "This script must be run from the command line\n";
-       exit();
+    print "This script must be run from the command line\n";
+    exit();
 }
 
 define('INSTALLDIR', realpath(dirname(__FILE__) . '/..'));
@@ -33,33 +33,39 @@ require_once(INSTALLDIR . '/lib/queuehandler.php');
 
 set_error_handler('common_error_handler');
 
-class OmbQueueHandler extends QueueHandler {
-       
-       function transport() {
-               return 'omb';
-       }
-       
-       function start() {
-               $this->log(LOG_INFO, "INITIALIZE");
-               return true;
-       }
+class OmbQueueHandler extends QueueHandler
+{
+    
+    function transport()
+    {
+        return 'omb';
+    }
+    
+    function start()
+    {
+        $this->log(LOG_INFO, "INITIALIZE");
+        return true;
+    }
 
-       function handle_notice($notice) {
-               if ($this->is_remote($notice)) {
-                       $this->log(LOG_DEBUG, 'Ignoring remote notice ' . $notice->id);
-                       return true;
-               } else {
-                       return omb_broadcast_remote_subscribers($notice);
-               }
-       }
-       
-       function finish() {
-       }
+    function handle_notice($notice)
+    {
+        if ($this->is_remote($notice)) {
+            $this->log(LOG_DEBUG, 'Ignoring remote notice ' . $notice->id);
+            return true;
+        } else {
+            return omb_broadcast_remote_subscribers($notice);
+        }
+    }
+    
+    function finish()
+    {
+    }
 
-       function is_remote($notice) {
-               $user = User::staticGet($notice->profile_id);
-               return is_null($user);
-       }
+    function is_remote($notice)
+    {
+        $user = User::staticGet($notice->profile_id);
+        return is_null($user);
+    }
 }
 
 ini_set("max_execution_time", "0");
@@ -67,7 +73,7 @@ ini_set("max_input_time", "0");
 set_time_limit(0);
 mb_internal_encoding('UTF-8');
 
-$id = ($argc > 1) ? $argv[1] : NULL;
+$id = ($argc > 1) ? $argv[1] : null;
 
 $handler = new OmbQueueHandler($id);
 
index b1ae1d581dbcdda2ec57039183a264d4bbd3d5ac..5075c12df578aeeec4f45ce8db0bc430902dfe6f 100755 (executable)
@@ -20,8 +20,8 @@
 
 # Abort if called from a web server
 if (isset($_SERVER) && array_key_exists('REQUEST_METHOD', $_SERVER)) {
-       print "This script must be run from the command line\n";
-       exit();
+    print "This script must be run from the command line\n";
+    exit();
 }
 
 define('INSTALLDIR', realpath(dirname(__FILE__) . '/..'));
@@ -33,20 +33,23 @@ require_once(INSTALLDIR . '/lib/xmppqueuehandler.php');
 
 set_error_handler('common_error_handler');
 
-class PublicQueueHandler extends XmppQueueHandler {
-       
-       function transport() {
-               return 'public';
-       }
-       
-       function handle_notice($notice) {
-               try {
-                       return jabber_public_notice($notice);
-               } catch (XMPPHP_Exception $e) {
-                       $this->log(LOG_ERR, "Got an XMPPHP_Exception: " . $e->getMessage());
-                       die($e->getMessage());
-               }
-       }
+class PublicQueueHandler extends XmppQueueHandler
+{
+    
+    function transport()
+    {
+        return 'public';
+    }
+    
+    function handle_notice($notice)
+    {
+        try {
+            return jabber_public_notice($notice);
+        } catch (XMPPHP_Exception $e) {
+            $this->log(LOG_ERR, "Got an XMPPHP_Exception: " . $e->getMessage());
+            die($e->getMessage());
+        }
+    }
 }
 
 ini_set("max_execution_time", "0");
index 6b845beae1d50b91db49c06c42d1cd782bb0cc05..51a9bbd7573629d74803b446611783880b6f1ca0 100644 (file)
@@ -18,189 +18,193 @@ index_map();
 # ------------------------------------------------------------------------------
 
 # Generate index sitemap of all other sitemaps.
-function index_map() {
-       global $output_paths;
-       $output_dir = $output_paths['output_dir'];
-       $output_url = $output_paths['output_url'];
-
-       foreach (glob("$output_dir*.xml") as $file_name) {
-
-               # Just the file name please.
-               $file_name = preg_replace("|$output_dir|", '', $file_name);
-
-               $index_urls .= sitemap(
-                                                  array(
-                                                                'url' => $output_url . $file_name,
-                                                                'changefreq' => 'daily'
-                                                                )
-                                                  );
-       }
-
-       write_file($output_paths['index_file'], sitemapindex($index_urls));
+function index_map()
+{
+    global $output_paths;
+    $output_dir = $output_paths['output_dir'];
+    $output_url = $output_paths['output_url'];
+
+    foreach (glob("$output_dir*.xml") as $file_name) {
+
+        # Just the file name please.
+        $file_name = preg_replace("|$output_dir|", '', $file_name);
+
+        $index_urls .= sitemap(
+                           array(
+                                 'url' => $output_url . $file_name,
+                                 'changefreq' => 'daily'
+                                 )
+                           );
+    }
+
+    write_file($output_paths['index_file'], sitemapindex($index_urls));
 }
 
 # Generate sitemap of standard site elements.
-function standard_map() {
-       global $output_paths;
-
-       $standard_map_urls .= url(
-                                                         array(
-                                                                       'url' => common_local_url('public'),
-                                                                       'changefreq' => 'daily',
-                                                                       'priority' => '1',
-                                                                       )
-                                                         );
-
-       $standard_map_urls .= url(
-                                                         array(
-                                                                       'url' => common_local_url('publicrss'),
-                                                                       'changefreq' => 'daily',
-                                                                       'priority' => '0.3',
-                                                                       )
-                                                         );
-
-       $docs = array('about', 'faq', 'contact', 'im', 'openid', 'openmublog', 'privacy', 'source');
-
-       foreach($docs as $title) {
-               $standard_map_urls .= url(
-                                                                 array(
-                                                                               'url' => common_local_url('doc', array('title' => $title)),
-                                                                               'changefreq' => 'monthly',
-                                                                               'priority'   => '0.2',
-                                                                               )
-                                                                 );
-       }
-
-       $urlset_path = $output_paths['output_dir'] . 'standard.xml';
-
-       write_file($urlset_path, urlset($standard_map_urls));
+function standard_map()
+{
+    global $output_paths;
+
+    $standard_map_urls .= url(
+                              array(
+                                    'url' => common_local_url('public'),
+                                    'changefreq' => 'daily',
+                                    'priority' => '1',
+                                    )
+                              );
+
+    $standard_map_urls .= url(
+                              array(
+                                    'url' => common_local_url('publicrss'),
+                                    'changefreq' => 'daily',
+                                    'priority' => '0.3',
+                                    )
+                              );
+
+    $docs = array('about', 'faq', 'contact', 'im', 'openid', 'openmublog', 'privacy', 'source');
+
+    foreach($docs as $title) {
+        $standard_map_urls .= url(
+                                  array(
+                                        'url' => common_local_url('doc', array('title' => $title)),
+                                        'changefreq' => 'monthly',
+                                        'priority'   => '0.2',
+                                        )
+                                  );
+    }
+
+    $urlset_path = $output_paths['output_dir'] . 'standard.xml';
+
+    write_file($urlset_path, urlset($standard_map_urls));
 }
 
 # Generate sitemaps of all notices.
-function notices_map() {
-       global $output_paths;
-
-       $notices = DB_DataObject::factory('notice');
-
-       $notices->query('SELECT id, uri, url, modified FROM notice where is_local = 1');
-
-       $notice_count = 0;
-       $map_count = 1;
-
-       while ($notices->fetch()) {
-
-               # Maximum 50,000 URLs per sitemap file.
-               if ($notice_count == 50000) {
-                       $notice_count = 0;
-                       $map_count++;
-               }
-
-               # remote notices have an URL
-               
-               if (!$notices->url && $notices->uri) {
-                       $notice = array(
-                                               'url'        => ($notices->uri) ? $notices->uri : common_local_url('shownotice', array('notice' => $notices->id)),
-                                               'lastmod'    => common_date_w3dtf($notices->modified),
-                                               'changefreq' => 'never',
-                                               'priority'   => '1',
-                                               );
-
-                       $notice_list[$map_count] .= url($notice);
-                       $notice_count++;
-               }
-       }
-
-       # Make full sitemaps from the lists and save them.
-       array_to_map($notice_list, 'notice');
+function notices_map()
+{
+    global $output_paths;
+
+    $notices = DB_DataObject::factory('notice');
+
+    $notices->query('SELECT id, uri, url, modified FROM notice where is_local = 1');
+
+    $notice_count = 0;
+    $map_count = 1;
+
+    while ($notices->fetch()) {
+
+        # Maximum 50,000 URLs per sitemap file.
+        if ($notice_count == 50000) {
+            $notice_count = 0;
+            $map_count++;
+        }
+
+        # remote notices have an URL
+        
+        if (!$notices->url && $notices->uri) {
+            $notice = array(
+                        'url'        => ($notices->uri) ? $notices->uri : common_local_url('shownotice', array('notice' => $notices->id)),
+                        'lastmod'    => common_date_w3dtf($notices->modified),
+                        'changefreq' => 'never',
+                        'priority'   => '1',
+                        );
+
+            $notice_list[$map_count] .= url($notice);
+            $notice_count++;
+        }
+    }
+
+    # Make full sitemaps from the lists and save them.
+    array_to_map($notice_list, 'notice');
 }
 
 # Generate sitemaps of all users.
-function user_map() {
-       global $output_paths;
-
-       $users = DB_DataObject::factory('user');
-
-       $users->query('SELECT id, nickname FROM user');
-
-       $user_count = 0;
-       $map_count = 1;
-
-       while ($users->fetch()) {
-
-               # Maximum 50,000 URLs per sitemap file.
-               if ($user_count == 50000) {
-                       $user_count = 0;
-                       $map_count++;
-               }
-
-               $user_args = array('nickname' => $users->nickname);
-
-               # Define parameters for generating <url></url> elements.
-               $user = array(
-                                         'url'        => common_local_url('showstream', $user_args),
-                                         'changefreq' => 'daily',
-                                         'priority'   => '1',
-                                         );
-
-               $user_rss = array(
-                                                 'url'        => common_local_url('userrss', $user_args),
-                                                 'changefreq' => 'daily',
-                                                 'priority'   => '0.3',
-                                                 );
-
-               $all = array(
-                                        'url'        => common_local_url('all', $user_args),
-                                        'changefreq' => 'daily',
-                                        'priority'   => '1',
-                                        );
-
-               $all_rss = array(
-                                                'url'        => common_local_url('allrss', $user_args),
-                                                'changefreq' => 'daily',
-                                                'priority'   => '0.3',
-                                                );
-
-               $replies = array(
-                                                'url'        => common_local_url('replies', $user_args),
-                                                'changefreq' => 'daily',
-                                                'priority'   => '1',
-                                                );
-
-               $replies_rss = array(
-                                                        'url'        => common_local_url('repliesrss', $user_args),
-                                                        'changefreq' => 'daily',
-                                                        'priority'   => '0.3',
-                                                        );
-
-               $foaf = array(
-                                         'url'        => common_local_url('foaf', $user_args),
-                                         'changefreq' => 'weekly',
-                                         'priority'   => '0.5',
-                                         );
-
-               # Construct a <url></url> element for each user facet and add it
-               # to our existing list of those.
-               $user_list[$map_count]        .= url($user);
-               $user_rss_list[$map_count]    .= url($user_rss);
-               $all_list[$map_count]         .= url($all);
-               $all_rss_list[$map_count]     .= url($all_rss);
-               $replies_list[$map_count]     .= url($replies);
-               $replies_rss_list[$map_count] .= url($replies_rss);
-               $foaf_list[$map_count]        .= url($foaf);
-
-               $user_count++;
-       }
-
-       # Make full sitemaps from the lists and save them.
-       # Possible factoring: put all the lists into a master array, thus allowing
-       # calling with single argument (i.e., array_to_map('user')).
-       array_to_map($user_list, 'user');
-       array_to_map($user_rss_list, 'user_rss');
-       array_to_map($all_list, 'all');
-       array_to_map($all_rss_list, 'all_rss');
-       array_to_map($replies_list, 'replies');
-       array_to_map($replies_rss_list, 'replies_rss');
-       array_to_map($foaf_list, 'foaf');
+function user_map()
+{
+    global $output_paths;
+
+    $users = DB_DataObject::factory('user');
+
+    $users->query('SELECT id, nickname FROM user');
+
+    $user_count = 0;
+    $map_count = 1;
+
+    while ($users->fetch()) {
+
+        # Maximum 50,000 URLs per sitemap file.
+        if ($user_count == 50000) {
+            $user_count = 0;
+            $map_count++;
+        }
+
+        $user_args = array('nickname' => $users->nickname);
+
+        # Define parameters for generating <url></url> elements.
+        $user = array(
+                      'url'        => common_local_url('showstream', $user_args),
+                      'changefreq' => 'daily',
+                      'priority'   => '1',
+                      );
+
+        $user_rss = array(
+                          'url'        => common_local_url('userrss', $user_args),
+                          'changefreq' => 'daily',
+                          'priority'   => '0.3',
+                          );
+
+        $all = array(
+                     'url'        => common_local_url('all', $user_args),
+                     'changefreq' => 'daily',
+                     'priority'   => '1',
+                     );
+
+        $all_rss = array(
+                         'url'        => common_local_url('allrss', $user_args),
+                         'changefreq' => 'daily',
+                         'priority'   => '0.3',
+                         );
+
+        $replies = array(
+                         'url'        => common_local_url('replies', $user_args),
+                         'changefreq' => 'daily',
+                         'priority'   => '1',
+                         );
+
+        $replies_rss = array(
+                             'url'        => common_local_url('repliesrss', $user_args),
+                             'changefreq' => 'daily',
+                             'priority'   => '0.3',
+                             );
+
+        $foaf = array(
+                      'url'        => common_local_url('foaf', $user_args),
+                      'changefreq' => 'weekly',
+                      'priority'   => '0.5',
+                      );
+
+        # Construct a <url></url> element for each user facet and add it
+        # to our existing list of those.
+        $user_list[$map_count]        .= url($user);
+        $user_rss_list[$map_count]    .= url($user_rss);
+        $all_list[$map_count]         .= url($all);
+        $all_rss_list[$map_count]     .= url($all_rss);
+        $replies_list[$map_count]     .= url($replies);
+        $replies_rss_list[$map_count] .= url($replies_rss);
+        $foaf_list[$map_count]        .= url($foaf);
+
+        $user_count++;
+    }
+
+    # Make full sitemaps from the lists and save them.
+    # Possible factoring: put all the lists into a master array, thus allowing
+    # calling with single argument (i.e., array_to_map('user')).
+    array_to_map($user_list, 'user');
+    array_to_map($user_rss_list, 'user_rss');
+    array_to_map($all_list, 'all');
+    array_to_map($all_rss_list, 'all_rss');
+    array_to_map($replies_list, 'replies');
+    array_to_map($replies_rss_list, 'replies_rss');
+    array_to_map($foaf_list, 'foaf');
 }
 
 # ------------------------------------------------------------------------------
@@ -208,88 +212,93 @@ function user_map() {
 # ------------------------------------------------------------------------------
 
 # Generate a <url></url> element.
-function url($url_args) {
-       $url        = preg_replace('/&/', '&amp;', $url_args['url']); # escape ampersands for XML
-       $lastmod    = $url_args['lastmod'];
-       $changefreq = $url_args['changefreq'];
-       $priority   = $url_args['priority'];
+function url($url_args)
+{
+    $url        = preg_replace('/&/', '&amp;', $url_args['url']); # escape ampersands for XML
+    $lastmod    = $url_args['lastmod'];
+    $changefreq = $url_args['changefreq'];
+    $priority   = $url_args['priority'];
 
-       if (is_null($url)) {
-               error("url() arguments require 'url' value.");
-       }
+    if (is_null($url)) {
+        error("url() arguments require 'url' value.");
+    }
 
-       $url_out = "\t<url>\n";
-       $url_out .= "\t\t<loc>$url</loc>\n";
+    $url_out = "\t<url>\n";
+    $url_out .= "\t\t<loc>$url</loc>\n";
 
-       if ($changefreq) {
-               $url_out .= "\t\t<changefreq>$changefreq</changefreq>\n";
-       }
+    if ($changefreq) {
+        $url_out .= "\t\t<changefreq>$changefreq</changefreq>\n";
+    }
 
-       if ($lastmod) {
-               $url_out .= "\t\t<lastmod>$lastmod</lastmod>\n";
-       }
+    if ($lastmod) {
+        $url_out .= "\t\t<lastmod>$lastmod</lastmod>\n";
+    }
 
-       if ($priority) {
-               $url_out .= "\t\t<priority>$priority</priority>\n";
-       }
+    if ($priority) {
+        $url_out .= "\t\t<priority>$priority</priority>\n";
+    }
 
-       $url_out .= "\t</url>\n";
+    $url_out .= "\t</url>\n";
 
-       return $url_out;
+    return $url_out;
 }
 
-function sitemap($sitemap_args) {
-       $url        = preg_replace('/&/', '&amp;', $sitemap_args['url']); # escape ampersands for XML
-       $lastmod    = $sitemap_args['lastmod'];
+function sitemap($sitemap_args)
+{
+    $url        = preg_replace('/&/', '&amp;', $sitemap_args['url']); # escape ampersands for XML
+    $lastmod    = $sitemap_args['lastmod'];
 
-       if (is_null($url)) {
-               error("url() arguments require 'url' value.");
-       }
+    if (is_null($url)) {
+        error("url() arguments require 'url' value.");
+    }
 
-       $sitemap_out = "\t<sitemap>\n";
-       $sitemap_out .= "\t\t<loc>$url</loc>\n";
+    $sitemap_out = "\t<sitemap>\n";
+    $sitemap_out .= "\t\t<loc>$url</loc>\n";
 
-       if ($lastmod) {
-               $sitemap_out .= "\t\t<lastmod>$lastmod</lastmod>\n";
-       }
+    if ($lastmod) {
+        $sitemap_out .= "\t\t<lastmod>$lastmod</lastmod>\n";
+    }
 
-       $sitemap_out .= "\t</sitemap>\n";
+    $sitemap_out .= "\t</sitemap>\n";
 
-       return $sitemap_out;
+    return $sitemap_out;
 }
 
 # Generate a <urlset></urlset> element.
-function urlset($urlset_text) {
-       $urlset = '<?xml version="1.0" encoding="UTF-8"?>' . "\n" .
-         '<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">' . "\n" .
-         $urlset_text .
-         '</urlset>';
-
-       return $urlset;
+function urlset($urlset_text)
+{
+    $urlset = '<?xml version="1.0" encoding="UTF-8"?>' . "\n" .
+      '<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">' . "\n" .
+      $urlset_text .
+      '</urlset>';
+
+    return $urlset;
 }
 
 # Generate a <urlset></urlset> element.
-function sitemapindex($sitemapindex_text) {
-       $sitemapindex = '<?xml version="1.0" encoding="UTF-8"?>' . "\n" .
-         '<sitemapindex xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">' . "\n" .
-         $sitemapindex_text .
-         '</sitemapindex>';
-
-       return $sitemapindex;
+function sitemapindex($sitemapindex_text)
+{
+    $sitemapindex = '<?xml version="1.0" encoding="UTF-8"?>' . "\n" .
+      '<sitemapindex xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">' . "\n" .
+      $sitemapindex_text .
+      '</sitemapindex>';
+
+    return $sitemapindex;
 }
 
 # Generate a sitemap from an array containing <url></url> elements and write it to a file.
-function array_to_map($url_list, $filename_prefix) {
-       global $output_paths;
-
-       if ($url_list) {
-               # $map_urls is a long string containing concatenated <url></url> elements.
-               while (list($map_idx, $map_urls) = each($url_list)) {
-                       $urlset_path = $output_paths['output_dir'] . "$filename_prefix-$map_idx.xml";
-                       
-                       write_file($urlset_path, urlset($map_urls));
-               }
-       }
+function array_to_map($url_list, $filename_prefix)
+{
+    global $output_paths;
+
+    if ($url_list) {
+        # $map_urls is a long string containing concatenated <url></url> elements.
+        while (list($map_idx, $map_urls) = each($url_list)) {
+            $urlset_path = $output_paths['output_dir'] . "$filename_prefix-$map_idx.xml";
+            
+            write_file($urlset_path, urlset($map_urls));
+        }
+    }
 }
 
 # ------------------------------------------------------------------------------
@@ -297,80 +306,84 @@ function array_to_map($url_list, $filename_prefix) {
 # ------------------------------------------------------------------------------
 
 # Parse command line arguments.
-function parse_args() {
-       $args = getopt('f:d:u:');
-
-       if (is_null($args[f]) && is_null($args[d]) && is_null($args[u])) {
-               error('Mandatory arguments: -f <index file path> -d <output directory path> -u <URL of sitemaps directory>');
-       }
-
-       if (is_null($args[f])) {
-               error('You must specify an index file name with the -f option.');
-       }
-
-       if (is_null($args[d])) {
-               error('You must specify a directory for the output file with the -d option.');
-       }
-
-       if (is_null($args[u])) {
-               error('You must specify a URL for the directory where the sitemaps will be kept with the -u option.');
-       }
-
-       $index_file = $args[f];
-       $output_dir = $args[d];
-       $output_url = $args[u];
-
-       if (file_exists($output_dir)) {
-               if (is_writable($output_dir) === FALSE) {
-                       error("$output_dir is not writable.");
-               }
-       }        else {
-               error("output directory $output_dir does not exist.");
-       }
-
-       $paths = array(
-                                  'index_file' => $index_file,
-                                  'output_dir' => trailing_slash($output_dir),
-                                  'output_url' => trailing_slash($output_url),
-                                  );
-
-       return $paths;
+function parse_args()
+{
+    $args = getopt('f:d:u:');
+
+    if (is_null($args[f]) && is_null($args[d]) && is_null($args[u])) {
+        error('Mandatory arguments: -f <index file path> -d <output directory path> -u <URL of sitemaps directory>');
+    }
+
+    if (is_null($args[f])) {
+        error('You must specify an index file name with the -f option.');
+    }
+
+    if (is_null($args[d])) {
+        error('You must specify a directory for the output file with the -d option.');
+    }
+
+    if (is_null($args[u])) {
+        error('You must specify a URL for the directory where the sitemaps will be kept with the -u option.');
+    }
+
+    $index_file = $args[f];
+    $output_dir = $args[d];
+    $output_url = $args[u];
+
+    if (file_exists($output_dir)) {
+        if (is_writable($output_dir) === false) {
+            error("$output_dir is not writable.");
+        }
+    }     else {
+        error("output directory $output_dir does not exist.");
+    }
+
+    $paths = array(
+                   'index_file' => $index_file,
+                   'output_dir' => trailing_slash($output_dir),
+                   'output_url' => trailing_slash($output_url),
+                   );
+
+    return $paths;
 }
 
 # Ensure paths end with a "/".
-function trailing_slash($path) {
-       if (preg_match('/\/$/', $path) == 0) {
-               $path .= '/';
-       }
+function trailing_slash($path)
+{
+    if (preg_match('/\/$/', $path) == 0) {
+        $path .= '/';
+    }
 
-       return $path;
+    return $path;
 }
 
 # Write data to disk.
-function write_file($path, $data) {
-       if (is_null($path)) {
-               error('No path specified for writing to.');
-       }        elseif (is_null($data)) {
-               error('No data specified for writing.');
-       }
-
-       if (($fh_out = fopen($path,'w')) === FALSE) {
-               error("couldn't open $path for writing.");
-       }
-
-       if (fwrite($fh_out, $data) === FALSE) {
-               error("couldn't write to $path.");
-       }
+function write_file($path, $data)
+{
+    if (is_null($path)) {
+        error('No path specified for writing to.');
+    }     elseif (is_null($data)) {
+        error('No data specified for writing.');
+    }
+
+    if (($fh_out = fopen($path,'w')) === false) {
+        error("couldn't open $path for writing.");
+    }
+
+    if (fwrite($fh_out, $data) === false) {
+        error("couldn't write to $path.");
+    }
 }
 
 # Display an error message and exit.
-function error ($error_msg) {
-       if (is_null($error_msg)) {
-               $error_msg = 'error() was called without any explanation!';
-       }
-
-       echo "Error: $error_msg\n";
-       exit(1);
+function error ($error_msg)
+{
+    if (is_null($error_msg)) {
+        $error_msg = 'error() was called without any explanation!';
+    }
+
+    echo "Error: $error_msg\n";
+    exit(1);
 }
 
 ?>
\ No newline at end of file
index 8f0d02d9b67f76e35b17add1357de82e8e867f23..38f2f11febb4e6f812da9eb8f65d7a75348c481e 100755 (executable)
@@ -20,8 +20,8 @@
 
 # Abort if called from a web server
 if (isset($_SERVER) && array_key_exists('REQUEST_METHOD', $_SERVER)) {
-       print "This script must be run from the command line\n";
-       exit();
+    print "This script must be run from the command line\n";
+    exit();
 }
 
 define('INSTALLDIR', realpath(dirname(__FILE__) . '/..'));
@@ -33,23 +33,28 @@ require_once(INSTALLDIR . '/lib/queuehandler.php');
 
 set_error_handler('common_error_handler');
 
-class SmsQueueHandler extends QueueHandler {
-       
-       function transport() {
-               return 'sms';
-       }
+class SmsQueueHandler extends QueueHandler
+{
+    
+    function transport()
+    {
+        return 'sms';
+    }
 
-       function start() {
-               $this->log(LOG_INFO, "INITIALIZE");
-               return true;
-       }
+    function start()
+    {
+        $this->log(LOG_INFO, "INITIALIZE");
+        return true;
+    }
 
-       function handle_notice($notice) {
-               return mail_broadcast_notice_sms($notice);
-       }
-       
-       function finish() {
-       }
+    function handle_notice($notice)
+    {
+        return mail_broadcast_notice_sms($notice);
+    }
+    
+    function finish()
+    {
+    }
 }
 
 ini_set("max_execution_time", "0");
@@ -57,7 +62,7 @@ ini_set("max_input_time", "0");
 set_time_limit(0);
 mb_internal_encoding('UTF-8');
 
-$id = ($argc > 1) ? $argv[1] : NULL;
+$id = ($argc > 1) ? $argv[1] : null;
 
 $handler = new SmsQueueHandler($id);
 
index 070eb9bbb2f6bcc22b4ed4e3257277d90f87e948..0ce34c2ae44f943303dcdcfbeaa76244fa1787e5 100755 (executable)
  *
  * 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
+ * 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/>.
+ * along with this program.     If not, see <http://www.gnu.org/licenses/>.
  */
 
 # Abort if called from a web server
 if (isset($_SERVER) && array_key_exists('REQUEST_METHOD', $_SERVER)) {
-       print "This script must be run from the command line\n";
-       exit();
+    print "This script must be run from the command line\n";
+    exit();
 }
 
 define('INSTALLDIR', realpath(dirname(__FILE__) . '/..'));
@@ -35,21 +35,21 @@ $flink->find();
 
 while ($flink->fetch()) {
 
-       if (($flink->friendsync & FOREIGN_FRIEND_RECV) == FOREIGN_FRIEND_RECV) {
+    if (($flink->friendsync & FOREIGN_FRIEND_RECV) == FOREIGN_FRIEND_RECV) {
 
-               $user = User::staticGet($flink->user_id);
+        $user = User::staticGet($flink->user_id);
 
-               print "Updating Twitter friends for user $user->nickname ($user->id)\n";
+        print "Updating Twitter friends for user $user->nickname ($user->id)\n";
 
-               $fuser = $flink->getForeignUser();
+        $fuser = $flink->getForeignUser();
 
-               $result = save_twitter_friends($user, $fuser->id, $fuser->nickname, $flink->credentials);
+        $result = save_twitter_friends($user, $fuser->id, $fuser->nickname, $flink->credentials);
 
-               if ($result == false) {
-                       print "Problems updating Twitter friends! Check the log.\n";
-                       exit(1);
-               }
-       }
+        if ($result == false) {
+            print "Problems updating Twitter friends! Check the log.\n";
+            exit(1);
+        }
+    }
 
 }
 
diff --git a/scripts/update_facebook.php b/scripts/update_facebook.php
new file mode 100755 (executable)
index 0000000..15c0e49
--- /dev/null
@@ -0,0 +1,112 @@
+#!/usr/bin/env php
+<?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/>.
+ */
+
+# Abort if called from a web server
+if (isset($_SERVER) && array_key_exists('REQUEST_METHOD', $_SERVER)) {
+    print "This script must be run from the command line\n";
+    exit();
+}
+
+define('INSTALLDIR', realpath(dirname(__FILE__) . '/..'));
+define('LACONICA', true);
+
+require_once(INSTALLDIR . '/lib/common.php');
+require_once(INSTALLDIR . '/lib/facebookutil.php');
+
+// For storing the last run date-time
+$last_updated_file = "/home/zach/laconica/scripts/facebook_last_updated";
+
+// Lock file name
+$tmp_file = "/tmp/update_facebook.lock";
+
+// Make sure only one copy of the script is running at a time
+if (!($tmp_file = @fopen($tmp_file, "w")))
+{
+       die("Can't open lock file. Script already running?");
+}
+
+$facebook = get_facebook();
+
+$current_time = time();
+
+$notice = get_facebook_notices(get_last_updated());
+
+print date('r', $current_time) . " Looking for notices to send to Facebook...\n";
+
+$cnt = 0;
+
+while($notice->fetch()) {
+
+    $flink = Foreign_link::getByUserID($notice->profile_id, 2);
+    $fbuid = $flink->foreign_id;
+    $content = $notice->content;
+
+    if (($flink->noticesync & FOREIGN_NOTICE_SEND) == FOREIGN_NOTICE_SEND) {
+
+        // If it's not a reply, or if the user WANTS to send replies...
+        if (!preg_match('/@[a-zA-Z0-9_]{1,15}\b/u', $content) ||
+            (($flink->noticesync & FOREIGN_NOTICE_SEND_REPLY) == FOREIGN_NOTICE_SEND_REPLY)) {
+                update_status($fbuid, $content);
+                $cnt++;
+            }
+    }
+}
+
+update_last_updated($current_time);
+
+print "Sent $cnt notices to Facebook.\n";
+
+exit(0);
+
+
+
+function update_status($fbuid, $content) {
+    global $facebook;
+
+    try {
+        $result = $facebook->api_client->users_setStatus($content, $fbuid, false, true);
+    } catch(FacebookRestClientException $e){
+       print_r($e);
+    }
+}
+
+function get_last_updated(){
+       global $last_updated_file, $current_time;
+
+       $file = fopen($last_updated_file, 'r');
+
+       if ($file) {
+           $last = fgets($file);
+       } else {
+           print "Unable to read $last_updated_file. Using current time.\n";
+           return $current_time;
+       }
+
+       fclose($file);
+
+       return $last;
+}
+
+function update_last_updated($time){
+       global $last_updated_file;
+       $file = fopen($last_updated_file, 'w') or die("Can't open $last_updated_file for writing!");
+       fwrite($file, $time);
+       fclose($file);
+}
index 3eb7b34016ef7d5d6b5594e87e3082d47131f6a0..8ad07ccca9eb0a7b4f0c1da1bb0d646315e91a85 100644 (file)
@@ -5,62 +5,62 @@ chdir(dirname(__FILE__) . '/..');
 
 /* Languages to pull */
 $languages = array(
-       'da_DK' => 'http://laconi.ca/translate/download.php?file_id=23',
-       'nl_NL' => 'http://laconi.ca/translate/download.php?file_id=39',
-       'en_NZ' => 'http://laconi.ca/translate/download.php?file_id=15',
-       'eo'    => 'http://laconi.ca/translate/download.php?file_id=10',
-       'fr_FR' => 'http://laconi.ca/translate/download.php?file_id=19',
-       'de_DE' => 'http://laconi.ca/translate/download.php?file_id=18',
-       'it_IT' => 'http://laconi.ca/translate/download.php?file_id=21',
-       'ko'    => 'http://laconi.ca/translate/download.php?file_id=33',
-       'no_NB' => 'http://laconi.ca/translate/download.php?file_id=31',
-       'pt'    => 'http://laconi.ca/translate/download.php?file_id=8',
-       'pt_BR' => 'http://laconi.ca/translate/download.php?file_id=72',
-       'ru_RU' => 'http://laconi.ca/translate/download.php?file_id=26',
-       'es'    => 'http://laconi.ca/translate/download.php?file_id=9',
-       'tr_TR' => 'http://laconi.ca/translate/download.php?file_id=37',
-       'uk_UA' => 'http://laconi.ca/translate/download.php?file_id=44',
-       'he_IL' => 'http://laconi.ca/translate/download.php?file_id=71',
-       'mk_MK' => 'http://laconi.ca/translate/download.php?file_id=67',
-       'ja_JP' => 'http://laconi.ca/translate/download.php?file_id=43',
-       'cs_CZ' => 'http://laconi.ca/translate/download.php?file_id=63',
-       'ca_ES' => 'http://laconi.ca/translate/download.php?file_id=49',
-       'pl_PL' => 'http://laconi.ca/translate/download.php?file_id=51',
-       'sv_SE' => 'http://laconi.ca/translate/download.php?file_id=55'
+    'da_DK' => 'http://laconi.ca/translate/download.php?file_id=23',
+    'nl_NL' => 'http://laconi.ca/translate/download.php?file_id=39',
+    'en_NZ' => 'http://laconi.ca/translate/download.php?file_id=15',
+    'eo'    => 'http://laconi.ca/translate/download.php?file_id=10',
+    'fr_FR' => 'http://laconi.ca/translate/download.php?file_id=19',
+    'de_DE' => 'http://laconi.ca/translate/download.php?file_id=18',
+    'it_IT' => 'http://laconi.ca/translate/download.php?file_id=21',
+    'ko'    => 'http://laconi.ca/translate/download.php?file_id=33',
+    'no_NB' => 'http://laconi.ca/translate/download.php?file_id=31',
+    'pt'    => 'http://laconi.ca/translate/download.php?file_id=8',
+    'pt_BR' => 'http://laconi.ca/translate/download.php?file_id=72',
+    'ru_RU' => 'http://laconi.ca/translate/download.php?file_id=26',
+    'es'    => 'http://laconi.ca/translate/download.php?file_id=9',
+    'tr_TR' => 'http://laconi.ca/translate/download.php?file_id=37',
+    'uk_UA' => 'http://laconi.ca/translate/download.php?file_id=44',
+    'he_IL' => 'http://laconi.ca/translate/download.php?file_id=71',
+    'mk_MK' => 'http://laconi.ca/translate/download.php?file_id=67',
+    'ja_JP' => 'http://laconi.ca/translate/download.php?file_id=43',
+    'cs_CZ' => 'http://laconi.ca/translate/download.php?file_id=63',
+    'ca_ES' => 'http://laconi.ca/translate/download.php?file_id=49',
+    'pl_PL' => 'http://laconi.ca/translate/download.php?file_id=51',
+    'sv_SE' => 'http://laconi.ca/translate/download.php?file_id=55'
 );
 
 /* Update the languages */
 foreach ($languages as $code => $file) {
 
-       $lcdir='locale/'.$code;
-       $msgdir=$lcdir.'/LC_MESSAGES';
-       $pofile=$msgdir.'/laconica.po';
-       $mofile=$msgdir.'/laconica.mo';
+    $lcdir='locale/'.$code;
+    $msgdir=$lcdir.'/LC_MESSAGES';
+    $pofile=$msgdir.'/laconica.po';
+    $mofile=$msgdir.'/laconica.mo';
 
-       /* Check for an existing */
-       if (!is_dir($msgdir)) {
-               mkdir($lcdir);
-               mkdir($msgdir);
-               $existingSHA1 = '';
-       } else {
-               $existingSHA1 = file_exists($pofile) ? sha1_file($pofile) : '';
-       }
+    /* Check for an existing */
+    if (!is_dir($msgdir)) {
+        mkdir($lcdir);
+        mkdir($msgdir);
+        $existingSHA1 = '';
+    } else {
+        $existingSHA1 = file_exists($pofile) ? sha1_file($pofile) : '';
+    }
 
-       /* Get the remote one */
-       $newFile = file_get_contents($file);
+    /* Get the remote one */
+    $newFile = file_get_contents($file);
 
-       // Update if the local .po file is different to the one downloaded, or
-       // if the .mo file is not present.
-       if(sha1($newFile)!=$existingSHA1 || !file_exists($mofile)) {
-               echo "Updating ".$code."\n";
-               file_put_contents($pofile, $newFile);
-               $prevdir = getcwd();
-               chdir($msgdir);
-               system('msgmerge -U laconica.po ../../laconica.pot');
-               system('msgfmt -f -o laconica.mo laconica.po');
-               chdir($prevdir);
-       } else {
-               echo "Unchanged - ".$code."\n";
-       }
+    // Update if the local .po file is different to the one downloaded, or
+    // if the .mo file is not present.
+    if(sha1($newFile)!=$existingSHA1 || !file_exists($mofile)) {
+        echo "Updating ".$code."\n";
+        file_put_contents($pofile, $newFile);
+        $prevdir = getcwd();
+        chdir($msgdir);
+        system('msgmerge -U laconica.po ../../laconica.pot');
+        system('msgfmt -f -o laconica.mo laconica.po');
+        chdir($prevdir);
+    } else {
+        echo "Unchanged - ".$code."\n";
+    }
 }
 echo "Finished\n";
index 8961b0b6e38f6a54a62cdc3782b79ae9a93dadae..2b8b085ce8ec568ba2f1fad4cd000e3816ab2b3c 100755 (executable)
@@ -20,8 +20,8 @@
 
 # Abort if called from a web server
 if (isset($_SERVER) && array_key_exists('REQUEST_METHOD', $_SERVER)) {
-       print "This script must be run from the command line\n";
-       exit();
+    print "This script must be run from the command line\n";
+    exit();
 }
 
 define('INSTALLDIR', realpath(dirname(__FILE__) . '/..'));
@@ -35,104 +35,109 @@ set_error_handler('common_error_handler');
 
 define('CLAIM_TIMEOUT', 1200);
 
-class XmppConfirmHandler extends XmppQueueHandler {
+class XmppConfirmHandler extends XmppQueueHandler
+{
 
-       var $_id = 'confirm';
-       
-       function class_name() {
-               return 'XmppConfirmHandler';
-       }
-       
-       function run() {
-               if (!$this->start()) {
-                       return false;
-               }
-               $this->log(LOG_INFO, 'checking for queued confirmations');
-               do {
-                       $confirm = $this->next_confirm();
-                       if ($confirm) {
-                               $this->log(LOG_INFO, 'Sending confirmation for ' . $confirm->address);
-                               $user = User::staticGet($confirm->user_id);
-                               if (!$user) {
-                                       $this->log(LOG_WARNING, 'Confirmation for unknown user ' . $confirm->user_id);
-                                       continue;
-                               }
-                               $success = jabber_confirm_address($confirm->code,
-                                                                                                 $user->nickname,
-                                                                                                 $confirm->address);
-                               if (!$success) {
-                                       $this->log(LOG_ERR, 'Confirmation failed for ' . $confirm->address);
-                                       # Just let the claim age out; hopefully things work then
-                                       continue;
-                               } else {
-                                       $this->log(LOG_INFO, 'Confirmation sent for ' . $confirm->address);
-                                       # Mark confirmation sent; need a dupe so we don't have the WHERE clause
-                                       $dupe = Confirm_address::staticGet('code', $confirm->code);
-                                       if (!$dupe) {
-                                               common_log(LOG_WARNING, 'Could not refetch confirm', __FILE__);
-                                               continue;
-                                       }
-                                       $orig = clone($dupe);
-                                       $dupe->sent = $dupe->claimed;
-                                       $result = $dupe->update($orig);
-                                       if (!$result) {
-                                               common_log_db_error($dupe, 'UPDATE', __FILE__);
-                                               # Just let the claim age out; hopefully things work then
-                                               continue;
-                                       }
-                                       $dupe->free();
-                                       unset($dupe);
-                               }
-                               $user->free();
-                               unset($user);
-                               $confirm->free();
-                               unset($confirm);
-                               $this->idle(0);
-                       } else {
-#                              $this->clear_old_confirm_claims();
-                               $this->idle(10);
-                       }
-               } while (true);
-               if (!$this->finish()) {
-                       return false;
-               }
-               return true;
-       }
+    var $_id = 'confirm';
+    
+    function class_name()
+    {
+        return 'XmppConfirmHandler';
+    }
+    
+    function run()
+    {
+        if (!$this->start()) {
+            return false;
+        }
+        $this->log(LOG_INFO, 'checking for queued confirmations');
+        do {
+            $confirm = $this->next_confirm();
+            if ($confirm) {
+                $this->log(LOG_INFO, 'Sending confirmation for ' . $confirm->address);
+                $user = User::staticGet($confirm->user_id);
+                if (!$user) {
+                    $this->log(LOG_WARNING, 'Confirmation for unknown user ' . $confirm->user_id);
+                    continue;
+                }
+                $success = jabber_confirm_address($confirm->code,
+                                                  $user->nickname,
+                                                  $confirm->address);
+                if (!$success) {
+                    $this->log(LOG_ERR, 'Confirmation failed for ' . $confirm->address);
+                    # Just let the claim age out; hopefully things work then
+                    continue;
+                } else {
+                    $this->log(LOG_INFO, 'Confirmation sent for ' . $confirm->address);
+                    # Mark confirmation sent; need a dupe so we don't have the WHERE clause
+                    $dupe = Confirm_address::staticGet('code', $confirm->code);
+                    if (!$dupe) {
+                        common_log(LOG_WARNING, 'Could not refetch confirm', __FILE__);
+                        continue;
+                    }
+                    $orig = clone($dupe);
+                    $dupe->sent = $dupe->claimed;
+                    $result = $dupe->update($orig);
+                    if (!$result) {
+                        common_log_db_error($dupe, 'UPDATE', __FILE__);
+                        # Just let the claim age out; hopefully things work then
+                        continue;
+                    }
+                    $dupe->free();
+                    unset($dupe);
+                }
+                $user->free();
+                unset($user);
+                $confirm->free();
+                unset($confirm);
+                $this->idle(0);
+            } else {
+#                $this->clear_old_confirm_claims();
+                $this->idle(10);
+            }
+        } while (true);
+        if (!$this->finish()) {
+            return false;
+        }
+        return true;
+    }
 
-       function next_confirm() {
-               $confirm = new Confirm_address();
-               $confirm->whereAdd('claimed IS NULL');
-               $confirm->whereAdd('sent IS NULL');
-               # XXX: eventually we could do other confirmations in the queue, too
-               $confirm->address_type = 'jabber';
-               $confirm->orderBy('modified DESC');
-               $confirm->limit(1);
-               if ($confirm->find(TRUE)) {
-                       $this->log(LOG_INFO, 'Claiming confirmation for ' . $confirm->address);
-                       # working around some weird DB_DataObject behaviour
-                       $confirm->whereAdd(''); # clears where stuff
-                       $original = clone($confirm);
-                       $confirm->claimed = common_sql_now();
-                       $result = $confirm->update($original);
-                       if ($result) {
-                               $this->log(LOG_INFO, 'Succeeded in claim! '. $result);
-                               return $confirm;
-                       } else {
-                               $this->log(LOG_INFO, 'Failed in claim!');
-                               return false;
-                       }
-               }
-               return NULL;
-       }
+    function next_confirm()
+    {
+        $confirm = new Confirm_address();
+        $confirm->whereAdd('claimed IS null');
+        $confirm->whereAdd('sent IS null');
+        # XXX: eventually we could do other confirmations in the queue, too
+        $confirm->address_type = 'jabber';
+        $confirm->orderBy('modified DESC');
+        $confirm->limit(1);
+        if ($confirm->find(true)) {
+            $this->log(LOG_INFO, 'Claiming confirmation for ' . $confirm->address);
+                # working around some weird DB_DataObject behaviour
+            $confirm->whereAdd(''); # clears where stuff
+            $original = clone($confirm);
+            $confirm->claimed = common_sql_now();
+            $result = $confirm->update($original);
+            if ($result) {
+                $this->log(LOG_INFO, 'Succeeded in claim! '. $result);
+                return $confirm;
+            } else {
+                $this->log(LOG_INFO, 'Failed in claim!');
+                return false;
+            }
+        }
+        return null;
+    }
 
-       function clear_old_confirm_claims() {
-               $confirm = new Confirm();
-               $confirm->claimed = NULL;
-               $confirm->whereAdd('now() - claimed > '.CLAIM_TIMEOUT);
-               $confirm->update(DB_DATAOBJECT_WHEREADD_ONLY);
-               $confirm->free();
-               unset($confirm);
-       }
+    function clear_old_confirm_claims()
+    {
+        $confirm = new Confirm();
+        $confirm->claimed = null;
+        $confirm->whereAdd('now() - claimed > '.CLAIM_TIMEOUT);
+        $confirm->update(DB_DATAOBJECT_WHEREADD_ONLY);
+        $confirm->free();
+        unset($confirm);
+    }
 }
 
 ini_set("max_execution_time", "0");
index 9a60970a6e99414ec86b0f9cc594d2a67c35962a..01fe8914f1aae18bcc0874878b5507bc0d520864 100755 (executable)
@@ -20,8 +20,8 @@
 
 # Abort if called from a web server
 if (isset($_SERVER) && array_key_exists('REQUEST_METHOD', $_SERVER)) {
-       print "This script must be run from the command line\n";
-       exit();
+    print "This script must be run from the command line\n";
+    exit();
 }
 
 define('INSTALLDIR', realpath(dirname(__FILE__) . '/..'));
@@ -37,205 +37,221 @@ set_error_handler('common_error_handler');
 # in jabber.php, which create a new XMPP class. A more elegant (?) solution
 # might be to use make this a subclass of XMPP.
 
-class XMPPDaemon extends Daemon {
-
-       function XMPPDaemon($resource=NULL) {
-               static $attrs = array('server', 'port', 'user', 'password', 'host');
-
-               foreach ($attrs as $attr)
-               {
-                       $this->$attr = common_config('xmpp', $attr);
-               }
-
-               if ($resource) {
-                       $this->resource = $resource;
-               } else {
-                       $this->resource = common_config('xmpp', 'resource') . 'daemon';
-               }
-
-               $this->log(LOG_INFO, "INITIALIZE XMPPDaemon {$this->user}@{$this->server}/{$this->resource}");
-       }
-
-       function connect() {
-
-               $connect_to = ($this->host) ? $this->host : $this->server;
-
-               $this->log(LOG_INFO, "Connecting to $connect_to on port $this->port");
-
-               $this->conn = jabber_connect($this->resource);
-
-               if (!$this->conn) {
-                       return false;
-               }
-
-               $this->conn->setReconnectTimeout(600);
-
-               jabber_send_presence("Send me a message to post a notice", 'available',
-                                                        NULL, 'available', 100);
-               return !$this->conn->isDisconnected();
-       }
-
-       function name() {
-               return strtolower('xmppdaemon.'.$this->resource);
-       }
-
-       function run() {
-               if ($this->connect()) {
-
-                       $this->conn->addEventHandler('message', 'handle_message', $this);
-                       $this->conn->addEventHandler('presence', 'handle_presence', $this);
-                       $this->conn->addEventHandler('reconnect', 'handle_reconnect', $this);
-
-                       $this->conn->process();
-               }
-       }
-
-       function handle_reconnect(&$pl) {
-               $this->conn->processUntil('session_start');
-               $this->conn->presence('Send me a message to post a notice', 'available', NULL, 'available', 100);
-       }
-
-       function get_user($from) {
-               $user = User::staticGet('jabber', jabber_normalize_jid($from));
-               return $user;
-       }
-
-       function handle_message(&$pl) {
-               if ($pl['type'] != 'chat') {
-                       return;
-               }
-               if (mb_strlen($pl['body']) == 0) {
-                       return;
-               }
-
-               $from = jabber_normalize_jid($pl['from']);
-
-               # Forwarded from another daemon (probably a broadcaster) for
-               # us to handle
-
-               if ($this->is_self($from)) {
-                       $from = $this->get_ofrom($pl);
-                       if (is_null($from) || $this->is_self($from)) {
-                               return;
-                       }
-               }
-
-               $user = $this->get_user($from);
-
-               if (!$user) {
-                       $this->from_site($from, 'Unknown user; go to ' .
-                                                        common_local_url('imsettings') .
-                                                        ' to add your address to your account');
-                       $this->log(LOG_WARNING, 'Message from unknown user ' . $from);
-                       return;
-               }
-               if ($this->handle_command($user, $pl['body'])) {
-                       return;
-               } else if ($this->is_autoreply($pl['body'])) {
-                       $this->log(LOG_INFO, 'Ignoring auto reply from ' . $from);
-                       return;
-               } else if ($this->is_otr($pl['body'])) {
-                       $this->log(LOG_INFO, 'Ignoring OTR from ' . $from);
-                       return;
-               } else if ($this->is_direct($pl['body'])) {
-                       preg_match_all('/d[\ ]*([a-z0-9]{1,64})/', $pl['body'], $to);
-
-                       $to = preg_replace('/^d([\ ])*/', '', $to[0][0]);
-                       $body = preg_replace('/d[\ ]*('. $to .')[\ ]*/', '', $pl['body']);
-                       $this->add_direct($user, $body, $to, $from);
-               } else {
-                       $len = mb_strlen($pl['body']);
-                       if($len > 140) {
-                               $this->from_site($from, 'Message too long - maximum is 140 characters, you sent ' . $len);
-                               return;
-                       }
-                       $this->add_notice($user, $pl);
-               }
-
-               $user->free();
-               unset($user);
-       }
-
-       function is_self($from) {
-               return preg_match('/^'.strtolower(jabber_daemon_address()).'/', strtolower($from));
-       }
-
-       function get_ofrom($pl) {
-               $xml = $pl['xml'];
-               $addresses = $xml->sub('addresses');
-               if (!$addresses) {
-                       $this->log(LOG_WARNING, 'Forwarded message without addresses');
-                       return NULL;
-               }
-               $address = $addresses->sub('address');
-               if (!$address) {
-                       $this->log(LOG_WARNING, 'Forwarded message without address');
-                       return NULL;
-               }
-               if (!array_key_exists('type', $address->attrs)) {
-                       $this->log(LOG_WARNING, 'No type for forwarded message');
-                       return NULL;
-               }
-               $type = $address->attrs['type'];
-               if ($type != 'ofrom') {
-                       $this->log(LOG_WARNING, 'Type of forwarded message is not ofrom');
-                       return NULL;
-               }
-               if (!array_key_exists('jid', $address->attrs)) {
-                       $this->log(LOG_WARNING, 'No jid for forwarded message');
-                       return NULL;
-               }
-               $jid = $address->attrs['jid'];
-               if (!$jid) {
-                       $this->log(LOG_WARNING, 'Could not get jid from address');
-                       return NULL;
-               }
-               $this->log(LOG_DEBUG, 'Got message forwarded from jid ' . $jid);
-               return $jid;
-       }
-
-       function is_autoreply($txt) {
-               if (preg_match('/[\[\(]?[Aa]uto[-\s]?[Rr]e(ply|sponse)[\]\)]/', $txt)) {
-                       return true;
-               } else {
-                       return false;
-               }
-       }
-
-       function is_otr($txt) {
-               if (preg_match('/^\?OTR/', $txt)) {
-                       return true;
-               } else {
-                       return false;
-               }
-       }
-
-       function is_direct($txt) {
-               if (strtolower(substr($txt, 0, 2))=='d ') {
-                       return true;
-               } else {
-                       return false;
-               }
-       }
-
-       function from_site($address, $msg) {
-               $text = '['.common_config('site', 'name') . '] ' . $msg;
-               jabber_send_message($address, $text);
-       }
-
-       function handle_command($user, $body) {
-               $inter = new CommandInterpreter();
-               $cmd = $inter->handle_command($user, $body);
-               if ($cmd) {
-                       $chan = new XMPPChannel($this->conn);
-                       $cmd->execute($chan);
-                       return true;
-               } else {
-                       return false;
-               }
-       }
-
-       function add_notice(&$user, &$pl) {
+class XMPPDaemon extends Daemon
+{
+
+    function XMPPDaemon($resource=null)
+    {
+        static $attrs = array('server', 'port', 'user', 'password', 'host');
+
+        foreach ($attrs as $attr)
+        {
+            $this->$attr = common_config('xmpp', $attr);
+        }
+
+        if ($resource) {
+            $this->resource = $resource;
+        } else {
+            $this->resource = common_config('xmpp', 'resource') . 'daemon';
+        }
+
+        $this->log(LOG_INFO, "INITIALIZE XMPPDaemon {$this->user}@{$this->server}/{$this->resource}");
+    }
+
+    function connect()
+    {
+
+        $connect_to = ($this->host) ? $this->host : $this->server;
+
+        $this->log(LOG_INFO, "Connecting to $connect_to on port $this->port");
+
+        $this->conn = jabber_connect($this->resource);
+
+        if (!$this->conn) {
+            return false;
+        }
+
+        $this->conn->setReconnectTimeout(600);
+
+        jabber_send_presence("Send me a message to post a notice", 'available',
+                             null, 'available', 100);
+        return !$this->conn->isDisconnected();
+    }
+
+    function name()
+    {
+        return strtolower('xmppdaemon.'.$this->resource);
+    }
+
+    function run()
+    {
+        if ($this->connect()) {
+
+            $this->conn->addEventHandler('message', 'handle_message', $this);
+            $this->conn->addEventHandler('presence', 'handle_presence', $this);
+            $this->conn->addEventHandler('reconnect', 'handle_reconnect', $this);
+
+            $this->conn->process();
+        }
+    }
+
+    function handle_reconnect(&$pl)
+    {
+        $this->conn->processUntil('session_start');
+        $this->conn->presence('Send me a message to post a notice', 'available', null, 'available', 100);
+    }
+
+    function get_user($from)
+    {
+        $user = User::staticGet('jabber', jabber_normalize_jid($from));
+        return $user;
+    }
+
+    function handle_message(&$pl)
+    {
+        if ($pl['type'] != 'chat') {
+            return;
+        }
+        if (mb_strlen($pl['body']) == 0) {
+            return;
+        }
+
+        $from = jabber_normalize_jid($pl['from']);
+
+        # Forwarded from another daemon (probably a broadcaster) for
+        # us to handle
+
+        if ($this->is_self($from)) {
+            $from = $this->get_ofrom($pl);
+            if (is_null($from) || $this->is_self($from)) {
+                return;
+            }
+        }
+
+        $user = $this->get_user($from);
+
+        if (!$user) {
+            $this->from_site($from, 'Unknown user; go to ' .
+                             common_local_url('imsettings') .
+                             ' to add your address to your account');
+            $this->log(LOG_WARNING, 'Message from unknown user ' . $from);
+            return;
+        }
+        if ($this->handle_command($user, $pl['body'])) {
+            return;
+        } else if ($this->is_autoreply($pl['body'])) {
+            $this->log(LOG_INFO, 'Ignoring auto reply from ' . $from);
+            return;
+        } else if ($this->is_otr($pl['body'])) {
+            $this->log(LOG_INFO, 'Ignoring OTR from ' . $from);
+            return;
+        } else if ($this->is_direct($pl['body'])) {
+            preg_match_all('/d[\ ]*([a-z0-9]{1,64})/', $pl['body'], $to);
+
+            $to = preg_replace('/^d([\ ])*/', '', $to[0][0]);
+            $body = preg_replace('/d[\ ]*('. $to .')[\ ]*/', '', $pl['body']);
+            $this->add_direct($user, $body, $to, $from);
+        } else {
+            $len = mb_strlen($pl['body']);
+            if($len > 140) {
+                $this->from_site($from, 'Message too long - maximum is 140 characters, you sent ' . $len);
+                return;
+            }
+            $this->add_notice($user, $pl);
+        }
+
+        $user->free();
+        unset($user);
+    }
+
+    function is_self($from)
+    {
+        return preg_match('/^'.strtolower(jabber_daemon_address()).'/', strtolower($from));
+    }
+
+    function get_ofrom($pl)
+    {
+        $xml = $pl['xml'];
+        $addresses = $xml->sub('addresses');
+        if (!$addresses) {
+            $this->log(LOG_WARNING, 'Forwarded message without addresses');
+            return null;
+        }
+        $address = $addresses->sub('address');
+        if (!$address) {
+            $this->log(LOG_WARNING, 'Forwarded message without address');
+            return null;
+        }
+        if (!array_key_exists('type', $address->attrs)) {
+            $this->log(LOG_WARNING, 'No type for forwarded message');
+            return null;
+        }
+        $type = $address->attrs['type'];
+        if ($type != 'ofrom') {
+            $this->log(LOG_WARNING, 'Type of forwarded message is not ofrom');
+            return null;
+        }
+        if (!array_key_exists('jid', $address->attrs)) {
+            $this->log(LOG_WARNING, 'No jid for forwarded message');
+            return null;
+        }
+        $jid = $address->attrs['jid'];
+        if (!$jid) {
+            $this->log(LOG_WARNING, 'Could not get jid from address');
+            return null;
+        }
+        $this->log(LOG_DEBUG, 'Got message forwarded from jid ' . $jid);
+        return $jid;
+    }
+
+    function is_autoreply($txt)
+    {
+        if (preg_match('/[\[\(]?[Aa]uto[-\s]?[Rr]e(ply|sponse)[\]\)]/', $txt)) {
+            return true;
+        } else {
+            return false;
+        }
+    }
+
+    function is_otr($txt)
+    {
+        if (preg_match('/^\?OTR/', $txt)) {
+            return true;
+        } else {
+            return false;
+        }
+    }
+
+    function is_direct($txt)
+    {
+        if (strtolower(substr($txt, 0, 2))=='d ') {
+            return true;
+        } else {
+            return false;
+        }
+    }
+
+    function from_site($address, $msg)
+    {
+        $text = '['.common_config('site', 'name') . '] ' . $msg;
+        jabber_send_message($address, $text);
+    }
+
+    function handle_command($user, $body)
+    {
+        $inter = new CommandInterpreter();
+        $cmd = $inter->handle_command($user, $body);
+        if ($cmd) {
+            $chan = new XMPPChannel($this->conn);
+            $cmd->execute($chan);
+            return true;
+        } else {
+            return false;
+        }
+    }
+
+    function add_notice(&$user, &$pl)
+    {
         $body = trim($pl['body']);
         $content_shortened = common_shorten_link($body);
         if (mb_strlen($content_shortened) > 140) {
@@ -245,59 +261,62 @@ class XMPPDaemon extends Daemon {
         else {
             $content = $body;
         }
-               $notice = Notice::saveNew($user->id, $content, 'xmpp');
-               if (is_string($notice)) {
-                       $this->log(LOG_ERR, $notice);
-                       return;
-               }
-               common_broadcast_notice($notice);
-               $this->log(LOG_INFO,
-                                  'Added notice ' . $notice->id . ' from user ' . $user->nickname);
-               $notice->free();
-               unset($notice);
-       }
-
-       function handle_presence(&$pl) {
-               $from = jabber_normalize_jid($pl['from']);
-               switch ($pl['type']) {
-                case 'subscribe':
-                       # We let anyone subscribe
-                       $this->subscribed($from);
-                       $this->log(LOG_INFO,
-                                          'Accepted subscription from ' . $from);
-                       break;
-                case 'subscribed':
-                case 'unsubscribed':
-                case 'unsubscribe':
-                       $this->log(LOG_INFO,
-                                          'Ignoring  "' . $pl['type'] . '" from ' . $from);
-                       break;
-                default:
-                       if (!$pl['type']) {
-                               $user = User::staticGet('jabber', $from);
-                               if (!$user) {
-                                       $this->log(LOG_WARNING, 'Presence from unknown user ' . $from);
-                                       return;
-                               }
-                               if ($user->updatefrompresence) {
-                                       $this->log(LOG_INFO, 'Updating ' . $user->nickname .
-                                                          ' status from presence.');
-                                       $this->add_notice($user, $pl);
-                               }
-                               $user->free();
-                               unset($user);
-                       }
-                       break;
-               }
-       }
-
-       function log($level, $msg) {
-               common_log($level, 'XMPPDaemon('.$this->resource.'): '.$msg);
-       }
-
-       function subscribed($to) {
-               jabber_special_presence('subscribed', $to);
-       }
+        $notice = Notice::saveNew($user->id, $content, 'xmpp');
+        if (is_string($notice)) {
+            $this->log(LOG_ERR, $notice);
+            return;
+        }
+        common_broadcast_notice($notice);
+        $this->log(LOG_INFO,
+                   'Added notice ' . $notice->id . ' from user ' . $user->nickname);
+        $notice->free();
+        unset($notice);
+    }
+
+    function handle_presence(&$pl)
+    {
+        $from = jabber_normalize_jid($pl['from']);
+        switch ($pl['type']) {
+         case 'subscribe':
+            # We let anyone subscribe
+            $this->subscribed($from);
+            $this->log(LOG_INFO,
+                       'Accepted subscription from ' . $from);
+            break;
+         case 'subscribed':
+         case 'unsubscribed':
+         case 'unsubscribe':
+            $this->log(LOG_INFO,
+                       'Ignoring  "' . $pl['type'] . '" from ' . $from);
+            break;
+         default:
+            if (!$pl['type']) {
+                $user = User::staticGet('jabber', $from);
+                if (!$user) {
+                    $this->log(LOG_WARNING, 'Presence from unknown user ' . $from);
+                    return;
+                }
+                if ($user->updatefrompresence) {
+                    $this->log(LOG_INFO, 'Updating ' . $user->nickname .
+                               ' status from presence.');
+                    $this->add_notice($user, $pl);
+                }
+                $user->free();
+                unset($user);
+            }
+            break;
+        }
+    }
+
+    function log($level, $msg)
+    {
+        common_log($level, 'XMPPDaemon('.$this->resource.'): '.$msg);
+    }
+
+    function subscribed($to)
+    {
+        jabber_special_presence('subscribed', $to);
+    }
 }
 
 ini_set("max_execution_time", "0");
index 0b894550c15ad375adee62d241aca23812be0de6..f22f9aa69b1706ef94ffd782fc454a2a9b821e9e 100644 (file)
@@ -440,6 +440,32 @@ p.time a {
        float: left;
        margin: 0 10px 18px 0;
        }
+
+#profilesettings {
+       margin-bottom:2em;
+}
+
+
+.avatar_view {
+       float:left;
+       margin-bottom:1em;
+       margin-right:1em;
+}
+
+#avatar_preview_view {
+       overflow:hidden;
+       width:96px;
+       height:96px;
+}
+#avatar_crop {
+       margin-bottom:2em;
+}
+
+#avatar_crop,
+#avatarfile {
+       clear:both;
+}
+
 a.nickname {
        font-family: Verdana, Arial, Helvetica, sans-serif;
        font-weight: bold;