]> git.mxchange.org Git - quix0rs-gnu-social.git/commitdiff
Merge branch 'nightly'
authorMikael Nordfeldth <mmn@hethane.se>
Sat, 5 Sep 2015 23:54:00 +0000 (01:54 +0200)
committerMikael Nordfeldth <mmn@hethane.se>
Sat, 5 Sep 2015 23:54:00 +0000 (01:54 +0200)
217 files changed:
CONFIGURE
EVENTS.txt
INSTALL
actions/all.php
actions/allrss.php
actions/apiaccountupdateprofile.php
actions/apitimelinetag.php
actions/avatarsettings.php
actions/deletenotice.php
actions/emailsettings.php
actions/foaf.php
actions/groupbyid.php
actions/grouprss.php
actions/imsettings.php
actions/logout.php
actions/newapplication.php
actions/noticesearchrss.php
actions/oauthappssettings.php
actions/oauthconnectionssettings.php
actions/oldschoolsettings.php
actions/passwordsettings.php
actions/profilesettings.php
actions/publicrss.php
actions/recoverpassword.php
actions/redirecturl.php
actions/replies.php
actions/repliesrss.php
actions/robotstxt.php
actions/shownotice.php
actions/showstream.php
actions/smssettings.php
actions/startpage.php [deleted file]
actions/subscriptions.php
actions/tagrss.php
actions/top.php
actions/urlsettings.php
actions/usergroups.php
actions/userrss.php
avatar/.gitignore [deleted file]
background/.gitignore [deleted file]
classes/Conversation.php
classes/File_redirection.php
classes/Foreign_link.php
classes/Foreign_user.php
classes/Local_group.php
classes/Memcached_DataObject.php
classes/Notice.php
classes/Notice_location.php [new file with mode: 0644]
classes/Profile.php
classes/Profile_tag.php
classes/Queue_item.php
classes/Reply.php
classes/Subscription_queue.php
classes/User.php
classes/User_im_prefs.php
db/core.php
extlib/Mail/mimeDecode.php
extlib/Mf2/Parser.php
extlib/get_temp_dir.php [deleted file]
file/.gitignore [deleted file]
js/util.js
lib/action.php
lib/activityutils.php
lib/apiaction.php
lib/apignusocialoauthdatastore.php
lib/applicationlist.php
lib/atomnoticefeed.php
lib/authenticationplugin.php
lib/connectedappslist.php [new file with mode: 0644]
lib/dbqueuemanager.php
lib/default.php
lib/deletenoticeform.php [new file with mode: 0644]
lib/deluserqueuehandler.php
lib/formaction.php
lib/framework.php
lib/galleryaction.php
lib/imagefile.php
lib/implugin.php
lib/installer.php
lib/mail.php
lib/microid.php [deleted file]
lib/noticelistitem.php
lib/noticestreamaction.php
lib/personaltagcloudsection.php
lib/profileaction.php
lib/profilelistitem.php
lib/queuemanager.php
lib/router.php
lib/rss10action.php [new file with mode: 0644]
lib/rssaction.php [deleted file]
lib/settingsaction.php
lib/siteprofile.php
lib/tagcloudsection.php
lib/targetedrss10action.php [new file with mode: 0644]
lib/threadednoticelist.php
lib/util.php
lib/xmloutputter.php
nginx.conf.sample [new file with mode: 0644]
plugins/Activity/ActivityPlugin.php
plugins/AuthCrypt/AuthCryptPlugin.php
plugins/Bookmark/actions/bookmarksrss.php
plugins/ChooseTheme/ChooseThemePlugin.php [new file with mode: 0644]
plugins/ChooseTheme/README.md [new file with mode: 0644]
plugins/ChooseTheme/actions/choosethemesettings.php [new file with mode: 0644]
plugins/ChooseTheme/locale/ChooseTheme.pot [new file with mode: 0644]
plugins/ChooseTheme/locale/nb/LC_MESSAGES/ChooseTheme.po [new file with mode: 0644]
plugins/DirectMessage/actions/apidirectmessage.php
plugins/DirectMessage/actions/apidirectmessagenew.php
plugins/Directory/css/directory.css
plugins/Directory/lib/sortablegrouplist.php
plugins/Directory/lib/sortablesubscriptionlist.php
plugins/ExtendedProfile/actions/profiledetail.php
plugins/ExtendedProfile/actions/profiledetailsettings.php
plugins/ExtendedProfile/lib/extendedprofile.php
plugins/FacebookBridge/actions/facebookfinishlogin.php
plugins/FacebookBridge/actions/facebooksettings.php
plugins/FacebookBridge/lib/facebookclient.php
plugins/Favorite/actions/favoritesrss.php
plugins/Favorite/actions/showfavorites.php
plugins/GeoURL/GeoURLPlugin.php
plugins/Gravatar/GravatarPlugin.php [deleted file]
plugins/Gravatar/README [deleted file]
plugins/Gravatar/locale/Gravatar.pot [deleted file]
plugins/Gravatar/locale/af/LC_MESSAGES/Gravatar.po [deleted file]
plugins/Gravatar/locale/ar/LC_MESSAGES/Gravatar.po [deleted file]
plugins/Gravatar/locale/arz/LC_MESSAGES/Gravatar.po [deleted file]
plugins/Gravatar/locale/ast/LC_MESSAGES/Gravatar.po [deleted file]
plugins/Gravatar/locale/be-tarask/LC_MESSAGES/Gravatar.po [deleted file]
plugins/Gravatar/locale/bg/LC_MESSAGES/Gravatar.po [deleted file]
plugins/Gravatar/locale/br/LC_MESSAGES/Gravatar.po [deleted file]
plugins/Gravatar/locale/ca/LC_MESSAGES/Gravatar.po [deleted file]
plugins/Gravatar/locale/cs/LC_MESSAGES/Gravatar.po [deleted file]
plugins/Gravatar/locale/da/LC_MESSAGES/Gravatar.po [deleted file]
plugins/Gravatar/locale/de/LC_MESSAGES/Gravatar.po [deleted file]
plugins/Gravatar/locale/el/LC_MESSAGES/Gravatar.po [deleted file]
plugins/Gravatar/locale/en_GB/LC_MESSAGES/Gravatar.po [deleted file]
plugins/Gravatar/locale/eo/LC_MESSAGES/Gravatar.po [deleted file]
plugins/Gravatar/locale/es/LC_MESSAGES/Gravatar.po [deleted file]
plugins/Gravatar/locale/eu/LC_MESSAGES/Gravatar.po [deleted file]
plugins/Gravatar/locale/fa/LC_MESSAGES/Gravatar.po [deleted file]
plugins/Gravatar/locale/fi/LC_MESSAGES/Gravatar.po [deleted file]
plugins/Gravatar/locale/fr/LC_MESSAGES/Gravatar.po [deleted file]
plugins/Gravatar/locale/fur/LC_MESSAGES/Gravatar.po [deleted file]
plugins/Gravatar/locale/gl/LC_MESSAGES/Gravatar.po [deleted file]
plugins/Gravatar/locale/he/LC_MESSAGES/Gravatar.po [deleted file]
plugins/Gravatar/locale/hsb/LC_MESSAGES/Gravatar.po [deleted file]
plugins/Gravatar/locale/hu/LC_MESSAGES/Gravatar.po [deleted file]
plugins/Gravatar/locale/ia/LC_MESSAGES/Gravatar.po [deleted file]
plugins/Gravatar/locale/id/LC_MESSAGES/Gravatar.po [deleted file]
plugins/Gravatar/locale/is/LC_MESSAGES/Gravatar.po [deleted file]
plugins/Gravatar/locale/it/LC_MESSAGES/Gravatar.po [deleted file]
plugins/Gravatar/locale/ja/LC_MESSAGES/Gravatar.po [deleted file]
plugins/Gravatar/locale/ka/LC_MESSAGES/Gravatar.po [deleted file]
plugins/Gravatar/locale/ko/LC_MESSAGES/Gravatar.po [deleted file]
plugins/Gravatar/locale/ksh/LC_MESSAGES/Gravatar.po [deleted file]
plugins/Gravatar/locale/lb/LC_MESSAGES/Gravatar.po [deleted file]
plugins/Gravatar/locale/lt/LC_MESSAGES/Gravatar.po [deleted file]
plugins/Gravatar/locale/lv/LC_MESSAGES/Gravatar.po [deleted file]
plugins/Gravatar/locale/mg/LC_MESSAGES/Gravatar.po [deleted file]
plugins/Gravatar/locale/mk/LC_MESSAGES/Gravatar.po [deleted file]
plugins/Gravatar/locale/ml/LC_MESSAGES/Gravatar.po [deleted file]
plugins/Gravatar/locale/ms/LC_MESSAGES/Gravatar.po [deleted file]
plugins/Gravatar/locale/my/LC_MESSAGES/Gravatar.po [deleted file]
plugins/Gravatar/locale/nb/LC_MESSAGES/Gravatar.po [deleted file]
plugins/Gravatar/locale/ne/LC_MESSAGES/Gravatar.po [deleted file]
plugins/Gravatar/locale/nl/LC_MESSAGES/Gravatar.po [deleted file]
plugins/Gravatar/locale/nn/LC_MESSAGES/Gravatar.po [deleted file]
plugins/Gravatar/locale/pl/LC_MESSAGES/Gravatar.po [deleted file]
plugins/Gravatar/locale/pt/LC_MESSAGES/Gravatar.po [deleted file]
plugins/Gravatar/locale/pt_BR/LC_MESSAGES/Gravatar.po [deleted file]
plugins/Gravatar/locale/ru/LC_MESSAGES/Gravatar.po [deleted file]
plugins/Gravatar/locale/sr-ec/LC_MESSAGES/Gravatar.po [deleted file]
plugins/Gravatar/locale/sv/LC_MESSAGES/Gravatar.po [deleted file]
plugins/Gravatar/locale/ta/LC_MESSAGES/Gravatar.po [deleted file]
plugins/Gravatar/locale/te/LC_MESSAGES/Gravatar.po [deleted file]
plugins/Gravatar/locale/tl/LC_MESSAGES/Gravatar.po [deleted file]
plugins/Gravatar/locale/tr/LC_MESSAGES/Gravatar.po [deleted file]
plugins/Gravatar/locale/uk/LC_MESSAGES/Gravatar.po [deleted file]
plugins/Gravatar/locale/ur_PK/LC_MESSAGES/Gravatar.po [deleted file]
plugins/Gravatar/locale/vi/LC_MESSAGES/Gravatar.po [deleted file]
plugins/Gravatar/locale/zh_CN/LC_MESSAGES/Gravatar.po [deleted file]
plugins/Gravatar/locale/zh_TW/LC_MESSAGES/Gravatar.po [deleted file]
plugins/Mapstraction/actions/map.php
plugins/ModLog/ModLogPlugin.php
plugins/OStatus/OStatusPlugin.php
plugins/OStatus/classes/Ostatus_profile.php
plugins/OStatus/lib/magicenvelope.php
plugins/OStatus/lib/salmonaction.php
plugins/OpenID/OpenIDPlugin.php
plugins/OpenID/actions/openidsettings.php
plugins/OpenID/openid.php
plugins/OpportunisticQM/lib/opportunisticqueuemanager.php
plugins/Poll/actions/pollsettings.php
plugins/Poll/forms/pollprefs.php [new file with mode: 0644]
plugins/RequireValidatedEmail/actions/confirmfirstemail.php
plugins/SearchSub/actions/searchsubs.php
plugins/SearchSub/lib/searchsubmenu.php
plugins/SubMirror/actions/mirrorsettings.php
plugins/TagSub/actions/tagsubs.php
plugins/TwitterBridge/TwitterBridgePlugin.php
plugins/TwitterBridge/actions/twitterauthorization.php
plugins/TwitterBridge/actions/twitterlogin.php
plugins/TwitterBridge/actions/twittersettings.php
plugins/TwitterBridge/daemons/synctwitterfriends.php
plugins/TwitterBridge/daemons/twitterstatusfetcher.php
plugins/TwitterBridge/lib/tweetinqueuehandler.php
plugins/TwitterBridge/lib/twitterimport.php
plugins/TwitterBridge/lib/twitteroauthclient.php
plugins/TwitterBridge/scripts/fakestream.php
plugins/TwitterBridge/scripts/streamtest.php
plugins/TwitterBridge/twitter.php
plugins/WebFinger/WebFingerPlugin.php
plugins/Xmpp/XmppPlugin.php
scripts/delete_notice.php [new file with mode: 0755]
theme/base/css/display.css
theme/neo-gnu/css/display.css
theme/neo/css/display.css

index 217b32cc7c98d250b53f46502238016ba96e136e..120db976df82862ae1ee327ca0fa8e638f2f4d4e 100644 (file)
--- a/CONFIGURE
+++ b/CONFIGURE
@@ -563,6 +563,11 @@ sslserver: if specified, this server will be used when creating HTTPS
 sslpath: if this and the sslserver are specified, this path will be used
     when creating HTTPS URLs. Otherwise, the attachments|path value
     will be used.
+show_thumbs: show thumbnails in notice lists for uploaded images, and photos
+    and videos linked remotely that provide oEmbed info. Defaults to true.
+show_html: show (filtered) text/html attachments (and oEmbed HTML etc.).
+    Doesn't affect AJAX calls. Defaults to false.
+filename_base: for new files, choose one: 'upload', 'hash'. Defaults to hash.
 
 group
 -----
index cfba97403b20e1918193cb34483aabc5063d6750..2f91a305f0cce8eaec4ac19c21f4f898a855af4c 100644 (file)
@@ -615,12 +615,12 @@ EndCheckPassword: After checking a username/password pair
 - $authenticatedUser: User object if credentials match a user, else null.
 
 StartChangePassword: Before changing a password
-- $user: user
+- Profile $target: The profile of the User that is changing password
 - $oldpassword: the user's old password
 - $newpassword: the desired new password
 
 EndChangePassword: After changing a password
-- $user: user
+- Profile $target: The profile of the User that just changed its password
 
 StartHashPassword: Generate a hashed version of the password (like a salted crypt)
 - &$hashed: Hashed version of the password, later put in the database
diff --git a/INSTALL b/INSTALL
index 90fa84923bb92bda257863687ef5d71455e4b51d..64f30139bf92eea2c673bdc4bccbabe9567d45e6 100644 (file)
--- a/INSTALL
+++ b/INSTALL
@@ -196,7 +196,9 @@ your server (like lighttpd or nginx).
         file is well commented. 
     * For lighttpd, inspect the lighttpd.conf.example file and apply the
         appropriate changes in your virtualhost configuration for lighttpd.
-    * For nginx and other webservers, we gladly accept contributions of
+    * For nginx, inspect the nginx.conf.sample file and apply the appropriate
+        changes.
+    * For other webservers, we gladly accept contributions of
         server configuration examples.
 
 2. Assuming your webserver is properly configured and have its settings
index 39041064f9225f5be34c18c1b0415549a6c751fa..19413076b57f89231ba72f8ca333da6d06e5b065 100644 (file)
@@ -39,8 +39,6 @@ if (!defined('GNUSOCIAL')) { exit(1); }
 
 class AllAction extends ShowstreamAction
 {
-    var $notice;
-
     public function getStream()
     {
         if ($this->scoped instanceof Profile && $this->scoped->isLocal() && $this->scoped->getUser()->streamModeOnly()) {
@@ -54,7 +52,7 @@ class AllAction extends ShowstreamAction
 
     function title()
     {
-        if (!empty($this->scoped) && $this->scoped->id == $this->target->id) {
+        if (!empty($this->scoped) && $this->scoped->sameAs($this->target)) {
             // TRANS: Title of a user's own start page.
             return _('Home timeline');
         } else {
@@ -71,44 +69,44 @@ class AllAction extends ShowstreamAction
                 common_local_url(
                     'ApiTimelineFriends', array(
                         'format' => 'as',
-                        'id' => $this->target->nickname
+                        'id' => $this->target->getNickname()
                     )
                 ),
                 // TRANS: %s is user nickname.
-                sprintf(_('Feed for friends of %s (Activity Streams JSON)'), $this->target->nickname)),
+                sprintf(_('Feed for friends of %s (Activity Streams JSON)'), $this->target->getNickname())),
             new Feed(Feed::RSS1,
                 common_local_url(
                     'allrss', array(
                         'nickname' =>
-                        $this->target->nickname)
+                        $this->target->getNickname())
                 ),
                 // TRANS: %s is user nickname.
-                sprintf(_('Feed for friends of %s (RSS 1.0)'), $this->target->nickname)),
+                sprintf(_('Feed for friends of %s (RSS 1.0)'), $this->target->getNickname())),
             new Feed(Feed::RSS2,
                 common_local_url(
                     'ApiTimelineFriends', array(
                         'format' => 'rss',
-                        'id' => $this->target->nickname
+                        'id' => $this->target->getNickname()
                     )
                 ),
                 // TRANS: %s is user nickname.
-                sprintf(_('Feed for friends of %s (RSS 2.0)'), $this->target->nickname)),
+                sprintf(_('Feed for friends of %s (RSS 2.0)'), $this->target->getNickname())),
             new Feed(Feed::ATOM,
                 common_local_url(
                     'ApiTimelineFriends', array(
                         'format' => 'atom',
-                        'id' => $this->target->nickname
+                        'id' => $this->target->getNickname()
                     )
                 ),
                 // TRANS: %s is user nickname.
-                sprintf(_('Feed for friends of %s (Atom)'), $this->target->nickname))
+                sprintf(_('Feed for friends of %s (Atom)'), $this->target->getNickname()))
         );
     }
 
     function showEmptyListMessage()
     {
         // TRANS: Empty list message. %s is a user nickname.
-        $message = sprintf(_('This is the timeline for %s and friends but no one has posted anything yet.'), $this->target->nickname) . ' ';
+        $message = sprintf(_('This is the timeline for %s and friends but no one has posted anything yet.'), $this->target->getNickname()) . ' ';
 
         if (common_logged_in()) {
             if ($this->target->id === $this->scoped->id) {
@@ -118,12 +116,12 @@ class AllAction extends ShowstreamAction
             } else {
                 // TRANS: %1$s is user nickname, %2$s is user nickname, %2$s is user nickname prefixed with "@".
                 // TRANS: This message contains Markdown links. Keep "](" together.
-                $message .= sprintf(_('You can try to [nudge %1$s](../%2$s) from their profile or [post something to them](%%%%action.newnotice%%%%?status_textarea=%3$s).'), $this->target->nickname, $this->target->nickname, '@' . $this->target->nickname);
+                $message .= sprintf(_('You can try to [nudge %1$s](../%2$s) from their profile or [post something to them](%%%%action.newnotice%%%%?status_textarea=%3$s).'), $this->target->getNickname(), $this->target->getNickname(), '@' . $this->target->getNickname());
             }
         } else {
             // TRANS: Encouragement displayed on empty timeline user pages for anonymous users.
             // TRANS: %s is a user nickname. This message contains Markdown links. Keep "](" together.
-            $message .= sprintf(_('Why not [register an account](%%%%action.register%%%%) and then nudge %s or post a notice to them.'), $this->target->nickname);
+            $message .= sprintf(_('Why not [register an account](%%%%action.register%%%%) and then nudge %s or post a notice to them.'), $this->target->getNickname());
         }
 
         $this->elementStart('div', 'guide');
@@ -134,19 +132,10 @@ class AllAction extends ShowstreamAction
     function showContent()
     {
         if (Event::handle('StartShowAllContent', array($this))) {
-
-            $profile = null;
-
-            $current_user = common_current_user();
-
-            if (!empty($current_user)) {
-                $profile = $current_user->getProfile();
-            }
-
-            if (!empty($current_user) && $current_user->streamModeOnly()) {
+            if ($this->scoped instanceof Profile && $this->scoped->isLocal() && $this->scoped->getUser()->streamModeOnly()) {
                 $nl = new PrimaryNoticeList($this->notice, $this, array('show_n'=>NOTICES_PER_PAGE));
             } else {
-                $nl = new ThreadedNoticeList($this->notice, $this, $profile);
+                $nl = new ThreadedNoticeList($this->notice, $this, $this->scoped);
             }
 
             $cnt = $nl->show();
@@ -157,7 +146,7 @@ class AllAction extends ShowstreamAction
 
             $this->pagination(
                 $this->page > 1, $cnt > NOTICES_PER_PAGE,
-                $this->page, 'all', array('nickname' => $this->target->nickname)
+                $this->page, 'all', array('nickname' => $this->target->getNickname())
             );
 
             Event::handle('EndShowAllContent', array($this));
index fee52c79ab3c7301f307865c6504b12ec39d6d5e..4b6df25048645286e97f6c12cb319d9f3e317dfe 100644 (file)
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 
-if (!defined('STATUSNET') && !defined('LACONICA')) {
-    exit(1);
-}
-
-require_once INSTALLDIR.'/lib/rssaction.php';
+if (!defined('GNUSOCIAL')) { exit(1); }
 
 /**
  * RSS feed for user and friends timeline.
@@ -46,52 +42,12 @@ require_once INSTALLDIR.'/lib/rssaction.php';
  * @license  http://www.fsf.org/licensing/licenses/agpl.html AGPLv3
  * @link     http://status.net/
  */
-class AllrssAction extends Rss10Action
+class AllrssAction extends TargetedRss10Action
 {
-    var $user = null;
-
-    /**
-     * Initialization.
-     *
-     * @param array $args Web and URL arguments
-     *
-     * @return boolean false if user doesn't exist
-     *
-     */
-    function prepare($args)
-    {
-        parent::prepare($args);
-        $nickname   = $this->trimmed('nickname');
-        $this->user = User::getKV('nickname', $nickname);
-
-        if (!$this->user) {
-            // TRANS: Client error when user not found for an rss related action.
-            $this->clientError(_('No such user.'));
-        } else {
-            $this->notices = $this->getNotices($this->limit);
-            return true;
-        }
-    }
-
-    /**
-     * Get notices
-     *
-     * @param integer $limit max number of notices to return
-     *
-     * @return array notices
-     */
-    function getNotices($limit=0)
+    protected function getNotices()
     {
-        $stream = new InboxNoticeStream($this->user->getProfile());
-        $notice = $stream->getNotices(0, $limit, null, null);
-
-        $notices = array();
-
-        while ($notice->fetch()) {
-            $notices[] = clone($notice);
-        }
-
-        return $notices;
+        $stream = new InboxNoticeStream($this->target);
+        return $stream->getNotices(0, $this->limit)->fetchAll();
     }
 
      /**
@@ -101,33 +57,17 @@ class AllrssAction extends Rss10Action
      */
     function getChannel()
     {
-        $user = $this->user;
         $c    = array('url' => common_local_url('allrss',
                                              array('nickname' =>
-                                                   $user->nickname)),
+                                                   $this->target->getNickname())),
                    // TRANS: Message is used as link title. %s is a user nickname.
-                   'title' => sprintf(_('%s and friends'), $user->nickname),
+                   'title' => sprintf(_('%s and friends'), $this->target->getNickname()),
                    'link' => common_local_url('all',
                                              array('nickname' =>
-                                                   $user->nickname)),
+                                                   $this->target->getNickname())),
                    // TRANS: Message is used as link description. %1$s is a username, %2$s is a site name.
                    'description' => sprintf(_('Updates from %1$s and friends on %2$s!'),
-                                            $user->nickname, common_config('site', 'name')));
+                                            $this->target->getNickname(), common_config('site', 'name')));
         return $c;
     }
-
-    /**
-     * Get image.
-     *
-     * @return string user avatar URL or null
-     */
-    function getImage()
-    {
-        $user    = $this->user;
-        $profile = $user->getProfile();
-        if (!$profile) {
-            return null;
-        }
-        return $profile->avatarUrl(AVATAR_PROFILE_SIZE);
-    }
 }
index a9842ec5d8f33d80dba29e353e4597be3150623c..8767dabf8528a6ef23c597bb7b4a8de47903ba8a 100644 (file)
@@ -96,21 +96,12 @@ class ApiAccountUpdateProfileAction extends ApiAuthAction
 
         $original = clone($profile);
 
-        if (!empty($this->name)) {
-            $profile->fullname = $this->name;
-        }
-
-        if (!empty($this->url)) {
-            $profile->homepage = $this->url;
-        }
-
-        if (!empty($this->description)) {
-            $profile->bio = $this->description;
-        }
+        $profile->fullname = $this->name;
+        $profile->homepage = $this->url;
+        $profile->bio = $this->description;
+        $profile->location = $this->location;
 
         if (!empty($this->location)) {
-            $profile->location = $this->location;
-
             $loc = Location::fromName($this->location);
 
             if (!empty($loc)) {
@@ -119,6 +110,12 @@ class ApiAccountUpdateProfileAction extends ApiAuthAction
                 $profile->location_id = $loc->location_id;
                 $profile->location_ns = $loc->location_ns;
             }
+        } else {
+            // location is empty so reset the extrapolated information too
+            $profile->lat = '';
+            $profile->lon = '';
+            $profile->location_id = '';
+            $profile->location_ns = '';
         }
 
         $result = $profile->update($original);
index 04a4727a9d8bfe7ddc0cb3a4dfe8d134509953df..1184440c7ddd9742f8388ad84130e61b8e53d9e5 100644 (file)
@@ -51,10 +51,14 @@ class ApiTimelineTagAction extends ApiPrivateAuthAction
 {
     var $notices = null;
 
-    protected function doPreparation()
+    protected function prepare(array $args=array())
     {
+        parent::prepare($args);
+
         $this->tag     = $this->arg('tag');
         $this->notices = $this->getNotices();
+
+        return true;
     }
 
     /**
index 1f31cbdafedc9975b80f0feb1b537d6206b33b64..4b618eb9bef850d2f23c5c2d52fb5bb64012afe8 100644 (file)
@@ -76,11 +76,11 @@ class AvatarsettingsAction extends SettingsAction
     /**
      * Content area of the page
      *
-     * Shows a form for uploading an avatar.
+     * Shows a form for uploading an avatar. Currently overrides FormAction's showContent
+     * since we haven't made classes out of AvatarCropForm and AvatarUploadForm.
      *
      * @return void
      */
-
     function showContent()
     {
         if ($this->mode == 'crop') {
@@ -243,52 +243,19 @@ class AvatarsettingsAction extends SettingsAction
         $this->elementEnd('form');
     }
 
-    /**
-     * Handle a post
-     *
-     * We mux on the button name to figure out what the user actually wanted.
-     *
-     * @return void
-     */
-    function handlePost()
+    protected function doPost()
     {
-        // Workaround for PHP returning empty $_POST and $_FILES when POST
-        // length > post_max_size in php.ini
-
-        if (empty($_FILES)
-            && empty($_POST)
-            && ($_SERVER['CONTENT_LENGTH'] > 0)
-        ) {
-            // TRANS: Client error displayed when the number of bytes in a POST request exceeds a limit.
-            // TRANS: %s is the number of bytes of the CONTENT_LENGTH.
-            $msg = _m('The server was unable to handle that much POST data (%s byte) due to its current configuration.',
-                      'The server was unable to handle that much POST data (%s bytes) due to its current configuration.',
-                      intval($_SERVER['CONTENT_LENGTH']));
-            $this->showForm(sprintf($msg, $_SERVER['CONTENT_LENGTH']));
-            return;
-        }
-
-        // CSRF protection
-
-        $token = $this->trimmed('token');
-        if (!$token || $token != common_session_token()) {
-            // TRANS: Client error displayed when the session token does not match or is not given.
-            $this->showForm(_('There was a problem with your session token. '.
-                               'Try again, please.'));
-            return;
-        }
-
         if (Event::handle('StartAvatarSaveForm', array($this))) {
-            if ($this->arg('upload')) {
-                $this->uploadAvatar();
-                } else if ($this->arg('crop')) {
-                    $this->cropAvatar();
-                } else if ($this->arg('delete')) {
-                    $this->deleteAvatar();
-                } else {
-                    // TRANS: Unexpected validation error on avatar upload form.
-                    $this->showForm(_('Unexpected form submission.'));
-                }
+            if ($this->trimmed('upload')) {
+                return $this->uploadAvatar();
+            } else if ($this->trimmed('crop')) {
+                return $this->cropAvatar();
+            } else if ($this->trimmed('delete')) {
+                return $this->deleteAvatar();
+            } else {
+                // TRANS: Unexpected validation error on avatar upload form.
+                throw new ClientException(_('Unexpected form submission.'));
+            }
             Event::handle('EndAvatarSaveForm', array($this));
         }
     }
@@ -303,21 +270,12 @@ class AvatarsettingsAction extends SettingsAction
      */
     function uploadAvatar()
     {
-        try {
-            $imagefile = ImageFile::fromUpload('avatarfile');
-        } catch (Exception $e) {
-            $this->showForm($e->getMessage());
-            return;
-        }
-        if ($imagefile === null) {
-            // TRANS: Validation error on avatar upload form when no file was uploaded.
-            $this->showForm(_('No file uploaded.'));
-            return;
-        }
+        // ImageFile throws exception if something goes wrong, which we'll
+        // pick up and show as an error message above the form.
+        $imagefile = ImageFile::fromUpload('avatarfile');
 
-        $cur = common_current_user();
         $type = $imagefile->preferredType();
-        $filename = Avatar::filename($cur->id,
+        $filename = Avatar::filename($this->scoped->getID(),
                                      image_type_to_extension($type),
                                      null,
                                      'tmp'.common_timestamp());
@@ -338,8 +296,7 @@ class AvatarsettingsAction extends SettingsAction
         $this->mode = 'crop';
 
         // TRANS: Avatar upload form instruction after uploading a file.
-        $this->showForm(_('Pick a square area of the image to be your avatar.'),
-                        true);
+        return _('Pick a square area of the image to be your avatar.');
     }
 
     /**
@@ -351,13 +308,12 @@ class AvatarsettingsAction extends SettingsAction
     {
         $filedata = $_SESSION['FILEDATA'];
 
-        if (!$filedata) {
+        if (empty($filedata)) {
             // TRANS: Server error displayed if an avatar upload went wrong somehow server side.
-            $this->serverError(_('Lost our file data.'));
+            throw new ServerException(_('Lost our file data.'));
         }
 
-        $file_d = ($filedata['width'] > $filedata['height'])
-                     ? $filedata['height'] : $filedata['width'];
+        $file_d = min($filedata['width'],  $filedata['height']);
 
         $dest_x = $this->arg('avatar_crop_x') ? $this->arg('avatar_crop_x'):0;
         $dest_y = $this->arg('avatar_crop_y') ? $this->arg('avatar_crop_y'):0;
@@ -369,11 +325,8 @@ class AvatarsettingsAction extends SettingsAction
                      'x' => $dest_x,   'y' => $dest_y,
                      'w' => $dest_w,   'h' => $dest_h);
 
-        $user = common_current_user();
-        $profile = $user->getProfile();
-
         $imagefile = new ImageFile(null, $filedata['filepath']);
-        $filename = Avatar::filename($profile->getID(), image_type_to_extension($imagefile->preferredType()),
+        $filename = Avatar::filename($this->scoped->getID(), image_type_to_extension($imagefile->preferredType()),
                                      $size, common_timestamp());
         try {
             $imagefile->resizeTo(Avatar::path($filename), $box);
@@ -385,16 +338,16 @@ class AvatarsettingsAction extends SettingsAction
             }
         }
 
-        if ($profile->setOriginal($filename)) {
+        if ($this->scoped->setOriginal($filename)) {
             @unlink($filedata['filepath']);
             unset($_SESSION['FILEDATA']);
             $this->mode = 'upload';
             // TRANS: Success message for having updated a user avatar.
-            $this->showForm(_('Avatar updated.'), true);
-        } else {
-            // TRANS: Error displayed on the avatar upload page if the avatar could not be updated for an unknown reason.
-            $this->showForm(_('Failed updating avatar.'));
+            return _('Avatar updated.');
         }
+
+        // TRANS: Error displayed on the avatar upload page if the avatar could not be updated for an unknown reason.
+        throw new ServerException(_('Failed updating avatar.'));
     }
 
     /**
@@ -404,13 +357,10 @@ class AvatarsettingsAction extends SettingsAction
      */
     function deleteAvatar()
     {
-        $user = common_current_user();
-        $profile = $user->getProfile();
-
-        Avatar::deleteFromProfile($profile);
+        Avatar::deleteFromProfile($this->scoped);
 
         // TRANS: Success message for deleting a user avatar.
-        $this->showForm(_('Avatar deleted.'), true);
+        return _('Avatar deleted.');
     }
 
     /**
index eb84b4f3ae5d877281e4d205bf4ebc5fa42359b9..40b276a34895e664c2801fc4b741a876ae378360 100644 (file)
  * @link      http://status.net/
  */
 
-if (!defined('STATUSNET') && !defined('LACONICA')) {
-    exit(1);
-}
+if (!defined('GNUSOCIAL')) { exit(1); }
 
 // @todo FIXME: documentation needed.
-class DeletenoticeAction extends Action
+class DeletenoticeAction extends FormAction
 {
-    var $error        = null;
-    var $user         = null;
-    var $notice       = null;
-    var $profile      = null;
-    var $user_profile = null;
+    protected $notice = null;
 
-    function prepare($args)
+    protected function doPreparation()
     {
-        parent::prepare($args);
-
-        $this->user   = common_current_user();
-
-        if (!$this->user) {
-            // TRANS: Error message displayed when trying to perform an action that requires a logged in user.
-            common_user_error(_('Not logged in.'));
-            exit;
-        }
-
-        $notice_id    = $this->trimmed('notice');
-        $this->notice = Notice::getKV($notice_id);
-
-        if (!$this->notice) {
-            // TRANS: Error message displayed trying to delete a non-existing notice.
-            common_user_error(_('No such notice.'));
-            exit;
-        }
-
-        $this->profile      = $this->notice->getProfile();
-        $this->user_profile = $this->user->getProfile();
+        $this->notice = Notice::getByID($this->trimmed('notice'));
 
-        return true;
-    }
-
-    function handle($args)
-    {
-        parent::handle($args);
-
-        if ($this->notice->profile_id != $this->user_profile->id &&
-                   !$this->user->hasRight(Right::DELETEOTHERSNOTICE)) {
+        if (!$this->scoped->sameAs($this->notice->getProfile()) &&
+                   !$this->scoped->hasRight(Right::DELETEOTHERSNOTICE)) {
             // TRANS: Error message displayed trying to delete a notice that was not made by the current user.
-            common_user_error(_('Cannot delete this notice.'));
-            exit;
+            $this->clientError(_('Cannot delete this notice.'));
         }
-        // XXX: Ajax!
 
-        if ($_SERVER['REQUEST_METHOD'] == 'POST') {
-            $this->deleteNotice();
-        } else if ($_SERVER['REQUEST_METHOD'] == 'GET') {
-            $this->showForm();
-        }
-    }
-
-    /**
-     * Show the page notice
-     *
-     * Shows instructions for the page
-     *
-     * @return void
-     */
-    function showPageNotice()
-    {
-        $instr  = $this->getInstructions();
-        $output = common_markup_to_html($instr);
-
-        $this->elementStart('div', 'instructions');
-        $this->raw($output);
-        $this->elementEnd('div');
+        $this->formOpts['notice'] = $this->notice;
     }
 
     function getInstructions()
@@ -117,84 +61,17 @@ class DeletenoticeAction extends Action
         return _('Delete notice');
     }
 
-    /**
-     * Wrapper for showing a page
-     *
-     * Stores an error and shows the page
-     *
-     * @param string $error Error, if any
-     *
-     * @return void
-     */
-    function showForm($error = null)
-    {
-        $this->error = $error;
-        $this->showPage();
-    }
-
-    /**
-     * Insert delete notice form into the content
-     *
-     * @return void
-     */
-    function showContent()
-    {
-        $this->elementStart('form', array('id' => 'form_notice_delete',
-                                          'class' => 'form_settings',
-                                          'method' => 'post',
-                                          'action' => common_local_url('deletenotice')));
-        $this->elementStart('fieldset');
-        // TRANS: Fieldset legend for the delete notice form.
-        $this->element('legend', null, _('Delete notice'));
-        $this->hidden('token', common_session_token());
-        $this->hidden('notice', $this->trimmed('notice'));
-        // TRANS: Message for the delete notice form.
-        $this->element('p', null, _('Are you sure you want to delete this notice?'));
-        $this->submit('form_action-no',
-                      // TRANS: Button label on the delete notice form.
-                      _m('BUTTON','No'),
-                      'submit form_action-primary',
-                      'no',
-                      // TRANS: Submit button title for 'No' when deleting a notice.
-                      _('Do not delete this notice.'));
-        $this->submit('form_action-yes',
-                      // TRANS: Button label on the delete notice form.
-                      _m('BUTTON','Yes'),
-                      'submit form_action-secondary',
-                      'yes',
-                      // TRANS: Submit button title for 'Yes' when deleting a notice.
-                      _('Delete this notice.'));
-        $this->elementEnd('fieldset');
-        $this->elementEnd('form');
-    }
-
-    function deleteNotice()
+    protected function doPost()
     {
-        // CSRF protection
-        $token = $this->trimmed('token');
-
-        if (!$token || $token != common_session_token()) {
-            // TRANS: Client error displayed when the session token does not match or is not given.
-            $this->showForm(_('There was a problem with your session token. ' .
-                              'Try again, please.'));
-            return;
-        }
-
         if ($this->arg('yes')) {
-            if (Event::handle('StartDeleteOwnNotice', array($this->user, $this->notice))) {
+            if (Event::handle('StartDeleteOwnNotice', array($this->scoped->getUser(), $this->notice))) {
                 $this->notice->delete();
-                Event::handle('EndDeleteOwnNotice', array($this->user, $this->notice));
+                Event::handle('EndDeleteOwnNotice', array($this->scoped->getUser(), $this->notice));
             }
-        }
-
-        $url = common_get_returnto();
-
-        if ($url) {
-            common_set_returnto(null);
         } else {
-            $url = common_local_url('public');
+            common_redirect(common_get_returnto(), 303);
         }
 
-        common_redirect($url, 303);
+        common_redirect(common_local_url('top'), 303);
     }
 }
index a0f111c0d5ab6bc0a6b698b6d96fed60dda6f36d..c02f1cdfad27b861739e5c47737097c115e9ad5a 100644 (file)
  * @link      http://status.net/
  */
 
-if (!defined('STATUSNET') && !defined('LACONICA')) {
-    exit(1);
-}
-
-
+if (!defined('GNUSOCIAL')) { exit(1); }
 
 /**
  * Settings for email
@@ -112,8 +108,8 @@ class EmailsettingsAction extends SettingsAction
             // TRANS: Button label to remove a confirmed e-mail address.
             $this->submit('remove', _m('BUTTON','Remove'));
         } else {
-            $confirm = $this->getConfirmation();
-            if ($confirm) {
+            try {
+                $confirm = $this->getConfirmation();
                 $this->element('p', array('id' => 'form_unconfirmed'), $confirm->address);
                 $this->element('p', array('class' => 'form_note'),
                                         // TRANS: Form note in e-mail settings form.
@@ -123,12 +119,12 @@ class EmailsettingsAction extends SettingsAction
                 $this->hidden('email', $confirm->address);
                 // TRANS: Button label to cancel an e-mail address confirmation procedure.
                 $this->submit('cancel', _m('BUTTON','Cancel'));
-            } else {
+            } catch (NoResultException $e) {
                 $this->elementStart('ul', 'form_data');
                 $this->elementStart('li');
                 // TRANS: Field label for e-mail address input in e-mail settings form.
                 $this->input('email', _('Email address'),
-                             ($this->arg('email')) ? $this->arg('email') : null,
+                             $this->trimmed('email') ?: null,
                              // TRANS: Instructions for e-mail address input form. Do not translate
                              // TRANS: "example.org". It is one of the domain names reserved for
                              // TRANS: use in examples by http://www.rfc-editor.org/rfc/rfc2606.txt.
@@ -231,12 +227,6 @@ class EmailsettingsAction extends SettingsAction
                             _('Allow friends to nudge me and send me an email.'),
                             $user->emailnotifynudge);
             $this->elementEnd('li');
-            $this->elementStart('li');
-            $this->checkbox('emailmicroid',
-                            // TRANS: Checkbox label in e-mail preferences form.
-                            _('Publish a MicroID for my email address.'),
-                            $user->emailmicroid);
-            $this->elementEnd('li');
             Event::handle('EndEmailFormData', array($this, $this->scoped));
         }
         $this->elementEnd('ul');
@@ -254,56 +244,36 @@ class EmailsettingsAction extends SettingsAction
      */
     function getConfirmation()
     {
-        $user = common_current_user();
-
         $confirm = new Confirm_address();
 
-        $confirm->user_id      = $user->id;
+        $confirm->user_id      = $this->scoped->getID();
         $confirm->address_type = 'email';
 
         if ($confirm->find(true)) {
             return $confirm;
-        } else {
-            return null;
         }
+
+        throw new NoResultException($confirm);
     }
 
-    /**
-     * Handle posts
-     *
-     * Since there are a lot of different options on the page, we
-     * figure out what we're supposed to do based on which button was
-     * pushed
-     *
-     * @return void
-     */
-    function handlePost()
+    protected function doPost()
     {
-        // CSRF protection
-        $token = $this->trimmed('token');
-        if (!$token || $token != common_session_token()) {
-            // TRANS: Client error displayed when the session token does not match or is not given.
-            $this->show_form(_('There was a problem with your session token. '.
-                               'Try again, please.'));
-            return;
-        }
-
         if ($this->arg('save')) {
-            $this->savePreferences();
+            return $this->savePreferences();
         } else if ($this->arg('add')) {
-            $this->addAddress();
+            return $this->addAddress();
         } else if ($this->arg('cancel')) {
-            $this->cancelConfirmation();
+            return $this->cancelConfirmation();
         } else if ($this->arg('remove')) {
-            $this->removeAddress();
+            return $this->removeAddress();
         } else if ($this->arg('removeincoming')) {
-            $this->removeIncoming();
+            return $this->removeIncoming();
         } else if ($this->arg('newincoming')) {
-            $this->newIncoming();
-        } else {
-            // TRANS: Message given submitting a form with an unknown action in e-mail settings.
-            $this->showForm(_('Unexpected form submission.'));
+            return $this->newIncoming();
         }
+
+        // TRANS: Message given submitting a form with an unknown action in e-mail settings.
+        throw new ClientException(_('Unexpected form submission.'));
     }
 
     /**
@@ -313,25 +283,21 @@ class EmailsettingsAction extends SettingsAction
      */
     function savePreferences()
     {
-        $user = $this->scoped->getUser();
-
         if (Event::handle('StartEmailSaveForm', array($this, $this->scoped))) {
             $emailnotifysub   = $this->booleanintstring('emailnotifysub');
             $emailnotifymsg   = $this->booleanintstring('emailnotifymsg');
             $emailnotifynudge = $this->booleanintstring('emailnotifynudge');
             $emailnotifyattn  = $this->booleanintstring('emailnotifyattn');
-            $emailmicroid     = $this->booleanintstring('emailmicroid');
             $emailpost        = $this->booleanintstring('emailpost');
 
+            $user = $this->scoped->getUser();
             $user->query('BEGIN');
-
             $original = clone($user);
 
             $user->emailnotifysub   = $emailnotifysub;
             $user->emailnotifymsg   = $emailnotifymsg;
             $user->emailnotifynudge = $emailnotifynudge;
             $user->emailnotifyattn  = $emailnotifyattn;
-            $user->emailmicroid     = $emailmicroid;
             $user->emailpost        = $emailpost;
 
             $result = $user->update($original);
@@ -340,16 +306,15 @@ class EmailsettingsAction extends SettingsAction
                 common_log_db_error($user, 'UPDATE', __FILE__);
                 $user->query('ROLLBACK');
                 // TRANS: Server error thrown on database error updating e-mail preferences.
-                $this->serverError(_('Could not update user.'));
+                throw new ServerException(_('Could not update user.'));
             }
 
             $user->query('COMMIT');
 
             Event::handle('EndEmailSaveForm', array($this, $this->scoped));
-
-            // TRANS: Confirmation message for successful e-mail preferences save.
-            $this->showForm(_('Email preferences saved.'), true);
         }
+        // TRANS: Confirmation message for successful e-mail preferences save.
+        return _('Email preferences saved.');
     }
 
     /**
@@ -359,38 +324,32 @@ class EmailsettingsAction extends SettingsAction
      */
     function addAddress()
     {
-        $user = common_current_user();
+        $user = $this->scoped->getUser();
 
         $email = $this->trimmed('email');
 
         // Some validation
 
-        if (!$email) {
+        if (empty($email)) {
             // TRANS: Message given saving e-mail address without having provided one.
-            $this->showForm(_('No email address.'));
-            return;
+            throw new ClientException(_('No email address.'));
         }
 
         $email = common_canonical_email($email);
 
-        if (!$email) {
+        if (empty($email)) {
             // TRANS: Message given saving e-mail address that cannot be normalised.
-            $this->showForm(_('Cannot normalize that email address.'));
-            return;
+            throw new ClientException(_('Cannot normalize that email address.'));
         }
         if (!Validate::email($email, common_config('email', 'check_domain'))) {
             // TRANS: Message given saving e-mail address that not valid.
-            $this->showForm(_('Not a valid email address.'));
-            return;
+            throw new ClientException(_('Not a valid email address.'));
         } else if ($user->email == $email) {
             // TRANS: Message given saving e-mail address that is already set.
-            $this->showForm(_('That is already your email address.'));
-            return;
+            throw new ClientException(_('That is already your email address.'));
         } else if ($this->emailExists($email)) {
             // TRANS: Message given saving e-mail address that is already set for another user.
-            $this->showForm(_('That email address already belongs '.
-                              'to another user.'));
-            return;
+            throw new ClientException(_('That email address already belongs to another user.'));
         }
 
         if (Event::handle('StartAddEmailAddress', array($user, $email))) {
@@ -399,7 +358,7 @@ class EmailsettingsAction extends SettingsAction
 
             $confirm->address      = $email;
             $confirm->address_type = 'email';
-            $confirm->user_id      = $user->id;
+            $confirm->user_id      = $user->getID();
             $confirm->code         = common_confirmation_code(64);
 
             $result = $confirm->insert();
@@ -407,21 +366,19 @@ class EmailsettingsAction extends SettingsAction
             if ($result === false) {
                 common_log_db_error($confirm, 'INSERT', __FILE__);
                 // TRANS: Server error thrown on database error adding e-mail confirmation code.
-                $this->serverError(_('Could not insert confirmation code.'));
+                throw new ServerException(_('Could not insert confirmation code.'));
             }
 
-            common_debug('Sending confirmation address for user '.$user->id.' to email '.$email);
-            mail_confirm_address($user, $confirm->code, $user->nickname, $email);
+            common_debug('Sending confirmation address for user '.$user->getID().' to email '.$email);
+            mail_confirm_address($user, $confirm->code, $user->getNickname(), $email);
 
             Event::handle('EndAddEmailAddress', array($user, $email));
         }
 
         // TRANS: Message given saving valid e-mail address that is to be confirmed.
-        $msg = _('A confirmation code was sent to the email address you added. '.
+        return _('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->showForm($msg, true);
     }
 
     /**
@@ -431,31 +388,29 @@ class EmailsettingsAction extends SettingsAction
      */
     function cancelConfirmation()
     {
-        $email = $this->arg('email');
-
-        $confirm = $this->getConfirmation();
+        $email = $this->trimmed('email');
 
-        if (!$confirm) {
+        try {
+            $confirm = $this->getConfirmation();
+            if ($confirm->address !== $email) {
+                // TRANS: Message given canceling e-mail address confirmation for the wrong e-mail address.
+                throw new ClientException(_('That is the wrong email address.'));
+            }
+        } catch (NoResultException $e) {
             // TRANS: Message given canceling e-mail address confirmation that is not pending.
-            $this->showForm(_('No pending confirmation to cancel.'));
-            return;
-        }
-        if ($confirm->address != $email) {
-            // TRANS: Message given canceling e-mail address confirmation for the wrong e-mail address.
-            $this->showForm(_('That is the wrong email address.'));
-            return;
+            throw new AlreadyFulfilledException(_('No pending confirmation to cancel.'));
         }
 
         $result = $confirm->delete();
 
-        if (!$result) {
+        if ($result === false) {
             common_log_db_error($confirm, 'DELETE', __FILE__);
             // TRANS: Server error thrown on database error canceling e-mail address confirmation.
-            $this->serverError(_('Could not delete email confirmation.'));
+            throw new ServerException(_('Could not delete email confirmation.'));
         }
 
         // TRANS: Message given after successfully canceling e-mail address confirmation.
-        $this->showForm(_('Email confirmation cancelled.'), true);
+        return _('Email confirmation cancelled.');
     }
 
     /**
@@ -467,26 +422,22 @@ class EmailsettingsAction extends SettingsAction
     {
         $user = common_current_user();
 
-        $email = $this->arg('email');
+        $email = $this->trimmed('email');
 
         // Maybe an old tab open...?
-
-        if ($user->email != $email) {
+        if ($user->email !== $email) {
             // TRANS: Message given trying to remove an e-mail address that is not
             // TRANS: registered for the active user.
-            $this->showForm(_('That is not your email address.'));
-            return;
+            throw new ClientException(_('That is not your email address.'));
         }
 
         $original = clone($user);
-
         $user->email = null;
-
         // Throws exception on failure. Also performs it within a transaction.
         $user->updateWithKeys($original);
 
         // TRANS: Message given after successfully removing a registered e-mail address.
-        $this->showForm(_('The email address was removed.'), true);
+        return _('The email address was removed.');
     }
 
     /**
@@ -498,22 +449,19 @@ class EmailsettingsAction extends SettingsAction
     {
         $user = common_current_user();
 
-        if (!$user->incomingemail) {
+        if (empty($user->incomingemail)) {
             // TRANS: Form validation error displayed when trying to remove an incoming e-mail address while no address has been set.
-            $this->showForm(_('No incoming email address.'));
-            return;
+            throw new AlreadyFulfilledException(_('No incoming email address.'));
         }
 
         $orig = clone($user);
-
         $user->incomingemail = null;
         $user->emailpost = 0;
-
         // Throws exception on failure. Also performs it within a transaction.
         $user->updateWithKeys($orig);
 
         // TRANS: Message given after successfully removing an incoming e-mail address.
-        $this->showForm(_('Incoming email address removed.'), true);
+        return _('Incoming email address removed.');
     }
 
     /**
@@ -524,17 +472,14 @@ class EmailsettingsAction extends SettingsAction
     function newIncoming()
     {
         $user = common_current_user();
-
         $orig = clone($user);
-
         $user->incomingemail = mail_new_incoming_address();
         $user->emailpost = 1;
-
         // Throws exception on failure. Also performs it within a transaction.
         $user->updateWithKeys($orig);
 
         // TRANS: Message given after successfully adding an incoming e-mail address.
-        $this->showForm(_('New incoming email address added.'), true);
+        return _('New incoming email address added.');
     }
 
     /**
@@ -553,10 +498,10 @@ class EmailsettingsAction extends SettingsAction
 
         $other = User::getKV('email', $email);
 
-        if (!$other) {
+        if (!$other instanceof User) {
             return false;
-        } else {
-            return $other->id != $user->id;
         }
+
+        return $other->id != $user->id;
     }
 }
index bcdc86d886c97348ce42d74c5280552a389654a9..260388ba447b72819ea0f908e4da35e9ade80391 100644 (file)
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 
-if (!defined('STATUSNET') && !defined('LACONICA')) { exit(1); }
+if (!defined('GNUSOCIAL')) { exit(1); }
 
 define('LISTENER', 1);
 define('LISTENEE', -1);
 define('BOTH', 0);
 
 // @todo XXX: Documentation missing.
-class FoafAction extends Action
+class FoafAction extends ManagedAction
 {
     function isReadOnly($args)
     {
         return true;
     }
 
-    function prepare($args)
+    protected function doPreparation()
     {
-        parent::prepare($args);
-
         $nickname_arg = $this->arg('nickname');
 
         if (empty($nickname_arg)) {
@@ -69,10 +67,8 @@ class FoafAction extends Action
         return true;
     }
 
-    function handle($args)
+    public function showPage()
     {
-        parent::handle($args);
-
         header('Content-Type: application/rdf+xml');
 
         $this->startXML();
index b82a861e97319931b3f322cd1024e59e241969bf..de87ec5c672e20da7632ef8f29e99c9411e4a91a 100644 (file)
  * @link      http://status.net/
  */
 
-if (!defined('STATUSNET') && !defined('LACONICA')) {
-    exit(1);
-}
-
-require_once INSTALLDIR.'/lib/noticelist.php';
-require_once INSTALLDIR.'/lib/feedlist.php';
+if (!defined('GNUSOCIAL')) { exit(1); }
 
 /**
  * Permalink for a group
@@ -47,53 +42,22 @@ require_once INSTALLDIR.'/lib/feedlist.php';
  * @license  http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
  * @link     http://status.net/
  */
-class GroupbyidAction extends Action
+class GroupbyidAction extends ManagedAction
 {
     /** group we're viewing. */
-    var $group = null;
+    protected $group = null;
 
-    /**
-     * Is this page read-only?
-     *
-     * @return boolean true
-     */
     function isReadOnly($args)
     {
         return true;
     }
 
-    function prepare($args)
+    protected function doPreparation()
     {
-        parent::prepare($args);
-
-        $id = $this->arg('id');
-
-        if (!$id) {
-            // TRANS: Client error displayed referring to a group's permalink without providing a group ID.
-            $this->clientError(_('No ID.'));
-        }
-
-        common_debug("Got ID $id");
-
-        $this->group = User_group::getKV('id', $id);
-
-        if (!$this->group) {
-            // TRANS: Client error displayed referring to a group's permalink for a non-existing group ID.
-            $this->clientError(_('No such group.'), 404);
-        }
-
-        return true;
+        $this->group = User_group::getByID($this->arg('id'));
     }
 
-    /**
-     * Handle the request
-     *
-     * Shows a profile for the group, some controls, and a list of
-     * group notices.
-     *
-     * @return void
-     */
-    function handle($args)
+    public function showPage()
     {
         common_redirect($this->group->homeUrl(), 303);
     }
index 87e34d73f80eccb6eb9020bd5ac005a606dea475..14d85d89cd9e5c06a8ceed43e85011289a11620e 100644 (file)
  * @link      http://status.net/
  */
 
-if (!defined('STATUSNET') && !defined('LACONICA')) {
-    exit(1);
-}
-
-require_once INSTALLDIR.'/lib/rssaction.php';
+if (!defined('GNUSOCIAL')) { exit(1); }
 
 define('MEMBERS_PER_SECTION', 27);
 
@@ -45,10 +41,10 @@ define('MEMBERS_PER_SECTION', 27);
  * @license  http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
  * @link     http://status.net/
  */
-class groupRssAction extends Rss10Action
+class GroupRssAction extends TargetedRss10Action
 {
     /** group we're viewing. */
-    var $group = null;
+    protected $group = null;
 
     /**
      * Is this page read-only?
@@ -60,18 +56,8 @@ class groupRssAction extends Rss10Action
         return true;
     }
 
-    /**
-     * Prepare the action
-     *
-     * Reads and validates arguments and instantiates the attributes.
-     *
-     * @param array $args $_REQUEST args
-     *
-     * @return boolean success flag
-     */
-    function prepare($args)
+    protected function doStreamPreparation()
     {
-        parent::prepare($args);
 
         $nickname_arg = $this->arg('nickname');
         $nickname = common_canonical_nickname($nickname_arg);
@@ -90,52 +76,32 @@ class groupRssAction extends Rss10Action
 
         $local = Local_group::getKV('nickname', $nickname);
 
-        if (!$local) {
+        if (!$local instanceof Local_group) {
             // TRANS: Client error displayed when requesting a group RSS feed for group that does not exist.
             $this->clientError(_('No such group.'), 404);
         }
 
-        $this->group = User_group::getKV('id', $local->group_id);
-
-        if (!$this->group) {
-            // TRANS: Client error displayed when requesting a group RSS feed for an object that is not a group.
-            $this->clientError(_('No such group.'), 404);
-        }
-
-        $this->notices = $this->getNotices($this->limit);
-        return true;
+        $this->group = $local->getGroup();
+        $this->target = $this->group->getProfile();
     }
 
-    function getNotices($limit=0)
+    protected function getNotices()
     {
-        $group = $this->group;
-
-        if (is_null($group)) {
-            return null;
-        }
-
-        $notices = array();
-        $notice = $group->getNotices(0, ($limit == 0) ? NOTICES_PER_PAGE : $limit);
-
-        while ($notice->fetch()) {
-            $notices[] = clone($notice);
-        }
-
-        return $notices;
+        $stream = $this->group->getNotices(0, $this->limit);
+        return $stream->fetchAll();
     }
 
     function getChannel()
     {
-        $group = $this->group;
         $c = array('url' => common_local_url('grouprss',
                                              array('nickname' =>
-                                                   $group->nickname)),
+                                                   $this->target->getNickname())),
                    // TRANS: Message is used as link title. %s is a user nickname.
-                   'title' => sprintf(_('%s timeline'), $group->nickname),
-                   'link' => common_local_url('showgroup', array('nickname' => $group->nickname)),
+                   'title' => sprintf(_('%s timeline'), $this->target->getNickname()),
+                   'link' => common_local_url('showgroup', array('nickname' => $this->target->getNickname())),
                    // TRANS: Message is used as link description. %1$s is a group name, %2$s is a site name.
                    'description' => sprintf(_('Updates from members of %1$s on %2$s!'),
-                                            $group->nickname, common_config('site', 'name')));
+                                            $this->target->getNickname(), common_config('site', 'name')));
         return $c;
     }
 
index 92fff45a7db6d27f506be1f50520afb717b685af..40bea10e68b462fa3dc5dffe2709dbfb587e85c3 100644 (file)
@@ -27,9 +27,7 @@
  * @link      http://status.net/
  */
 
-if (!defined('STATUSNET') && !defined('LACONICA')) {
-    exit(1);
-}
+if (!defined('GNUSOCIAL')) { exit(1); }
 
 /**
  * Settings for Jabber/XMPP integration
@@ -118,8 +116,8 @@ class ImsettingsAction extends SettingsAction
                 // TRANS: Button label to remove a confirmed IM address.
                 $this->submit('remove', _m('BUTTON','Remove'));
             } else {
-                $confirm = $this->getConfirmation($transport);
-                if ($confirm) {
+                try {
+                    $confirm = $this->getConfirmation($transport);
                     $this->element('p', 'form_unconfirmed', $confirm->address);
                     // TRANS: Form note in IM settings form.
                     $this->element('p', 'form_note',
@@ -134,7 +132,7 @@ class ImsettingsAction extends SettingsAction
                     $this->hidden('screenname', $confirm->address);
                     // TRANS: Button label to cancel an IM address confirmation procedure.
                     $this->submit('cancel', _m('BUTTON','Cancel'));
-                } else {
+                } catch (NoResultException $e) {
                     $this->elementStart('ul', 'form_data');
                     $this->elementStart('li');
                     // TRANS: Field label for IM address.
@@ -179,8 +177,6 @@ class ImsettingsAction extends SettingsAction
                 // TRANS: Checkbox label in IM preferences form.
                 array('name'=>'replies', 'description'=>_('Send me replies '.
                               'from people I\'m not subscribed to.')),
-                // TRANS: Checkbox label in IM preferences form.
-                array('name'=>'microid', 'description'=>_('Publish a MicroID'))
             );
             foreach($preferences as $preference)
             {
@@ -211,57 +207,35 @@ class ImsettingsAction extends SettingsAction
      */
     function getConfirmation($transport)
     {
-        $user = common_current_user();
-
         $confirm = new Confirm_address();
 
-        $confirm->user_id      = $user->id;
+        $confirm->user_id      = $this->scoped->getID();
         $confirm->address_type = $transport;
 
         if ($confirm->find(true)) {
             return $confirm;
-        } else {
-            return null;
         }
+
+        throw new NoResultException($confirm);
     }
 
-    /**
-     * Handle posts to this form
-     *
-     * Based on the button that was pressed, muxes out to other functions
-     * to do the actual task requested.
-     *
-     * All sub-functions reload the form with a message -- success or failure.
-     *
-     * @return void
-     */
-    function handlePost()
+    protected function doPost()
     {
-        // CSRF protection
-        $token = $this->trimmed('token');
-        if (!$token || $token != common_session_token()) {
-            // TRANS: Client error displayed when the session token does not match or is not given.
-            $this->showForm(_('There was a problem with your session token. '.
-                              'Try again, please.'));
-            return;
-        }
-
         if ($this->arg('save')) {
-            $this->savePreferences();
+            return $this->savePreferences();
         } else if ($this->arg('add')) {
-            $this->addAddress();
+            return $this->addAddress();
         } else if ($this->arg('cancel')) {
-            $this->cancelConfirmation();
+            return $this->cancelConfirmation();
         } else if ($this->arg('remove')) {
-            $this->removeAddress();
-        } else {
-            // TRANS: Message given submitting a form with an unknown action in Instant Messaging settings.
-            $this->showForm(_('Unexpected form submission.'));
+            return $this->removeAddress();
         }
+        // TRANS: Message given submitting a form with an unknown action in Instant Messaging settings.
+        throw new ClientException(_('Unexpected form submission.'));
     }
 
     /**
-     * Save user's Jabber preferences
+     * Save user's XMPP preferences
      *
      * These are the checkboxes at the bottom of the page. They're used to
      * set different settings
@@ -270,14 +244,12 @@ class ImsettingsAction extends SettingsAction
      */
     function savePreferences()
     {
-        $user = common_current_user();
-
         $user_im_prefs = new User_im_prefs();
         $user_im_prefs->query('BEGIN');
-        $user_im_prefs->user_id = $user->id;
+        $user_im_prefs->user_id = $this->scoped->getID();
         if($user_im_prefs->find() && $user_im_prefs->fetch())
         {
-            $preferences = array('notify', 'updatefrompresence', 'replies', 'microid');
+            $preferences = array('notify', 'updatefrompresence', 'replies');
             do
             {
                 $original = clone($user_im_prefs);
@@ -289,15 +261,15 @@ class ImsettingsAction extends SettingsAction
                 $result = $new->update($original);
 
                 if ($result === false) {
-                    common_log_db_error($user, 'UPDATE', __FILE__);
+                    common_log_db_error($user_im_prefs, 'UPDATE', __FILE__);
                     // TRANS: Server error thrown on database error updating IM preferences.
-                    $this->serverError(_('Could not update IM preferences.'));
+                    throw new ServerException(_('Could not update IM preferences.'));
                 }
             }while($user_im_prefs->fetch());
         }
         $user_im_prefs->query('COMMIT');
         // TRANS: Confirmation message for successful IM preferences save.
-        $this->showForm(_('Preferences saved.'), true);
+        return _('Preferences saved.');
     }
 
     /**
@@ -310,49 +282,42 @@ class ImsettingsAction extends SettingsAction
      */
     function addAddress()
     {
-        $user = common_current_user();
-
         $screenname = $this->trimmed('screenname');
         $transport = $this->trimmed('transport');
 
         // Some validation
 
-        if (!$screenname) {
+        if (empty($screenname)) {
             // TRANS: Message given saving IM address without having provided one.
-            $this->showForm(_('No screenname.'));
-            return;
+            throw new ClientException(_('No screenname.'));
         }
 
-        if (!$transport) {
+        if (empty($transport)) {
             // TRANS: Form validation error when no transport is available setting an IM address.
-            $this->showForm(_('No transport.'));
-            return;
+            throw new ClientException(_('No transport.'));
         }
 
         Event::handle('NormalizeImScreenname', array($transport, &$screenname));
 
-        if (!$screenname) {
+        if (empty($screenname)) {
             // TRANS: Message given saving IM address that cannot be normalised.
-            $this->showForm(_('Cannot normalize that screenname.'));
-            return;
+            throw new ClientException(_('Cannot normalize that screenname.'));
         }
         $valid = false;
         Event::handle('ValidateImScreenname', array($transport, $screenname, &$valid));
         if (!$valid) {
             // TRANS: Message given saving IM address that not valid.
-            $this->showForm(_('Not a valid screenname.'));
-            return;
+            throw new ClientException(_('Not a valid screenname.'));
         } else if ($this->screennameExists($transport, $screenname)) {
             // TRANS: Message given saving IM address that is already set for another user.
-            $this->showForm(_('Screenname already belongs to another user.'));
-            return;
+            throw new ClientException(_('Screenname already belongs to another user.'));
         }
 
         $confirm = new Confirm_address();
 
         $confirm->address      = $screenname;
         $confirm->address_type = $transport;
-        $confirm->user_id      = $user->id;
+        $confirm->user_id      = $this->scoped->getID();
         $confirm->code         = common_confirmation_code(64);
         $confirm->sent         = common_sql_now();
         $confirm->claimed      = common_sql_now();
@@ -365,13 +330,10 @@ class ImsettingsAction extends SettingsAction
             $this->serverError(_('Could not insert confirmation code.'));
         }
 
-        Event::handle('SendImConfirmationCode', array($transport, $screenname, $confirm->code, $user));
+        Event::handle('SendImConfirmationCode', array($transport, $screenname, $confirm->code, $this->scoped));
 
         // TRANS: Message given saving valid IM address that is to be confirmed.
-        $msg = _('A confirmation code was sent '.
-                         'to the IM address you added.');
-
-        $this->showForm($msg, true);
+        return _('A confirmation code was sent to the IM address you added.');
     }
 
     /**
@@ -386,29 +348,27 @@ class ImsettingsAction extends SettingsAction
         $screenname = $this->trimmed('screenname');
         $transport = $this->trimmed('transport');
 
-        $confirm = $this->getConfirmation($transport);
-
-        if (!$confirm) {
+        try {
+            $confirm = $this->getConfirmation($transport);
+            if ($confirm->address != $screenname) {
+                // TRANS: Message given canceling IM address confirmation for the wrong IM address.
+                throw new ClientException(_('That is the wrong IM address.'));
+            }
+        } catch (NoResultException $e) {
             // TRANS: Message given canceling Instant Messaging address confirmation that is not pending.
-            $this->showForm(_('No pending confirmation to cancel.'));
-            return;
-        }
-        if ($confirm->address != $screenname) {
-            // TRANS: Message given canceling IM address confirmation for the wrong IM address.
-            $this->showForm(_('That is the wrong IM address.'));
-            return;
+            throw new AlreadyFulfilledException(_('No pending confirmation to cancel.'));
         }
 
         $result = $confirm->delete();
 
-        if (!$result) {
+        if ($result === false) {
             common_log_db_error($confirm, 'DELETE', __FILE__);
             // TRANS: Server error thrown on database error canceling IM address confirmation.
-            $this->serverError(_('Could not delete confirmation.'));
+            throw new ServerException(_('Could not delete confirmation.'));
         }
 
         // TRANS: Message given after successfully canceling IM address confirmation.
-        $this->showForm(_('IM confirmation cancelled.'), true);
+        return _('IM confirmation cancelled.');
     }
 
     /**
@@ -420,34 +380,32 @@ class ImsettingsAction extends SettingsAction
      */
     function removeAddress()
     {
-        $user = common_current_user();
-
         $screenname = $this->trimmed('screenname');
         $transport = $this->trimmed('transport');
 
         // Maybe an old tab open...?
 
         $user_im_prefs = new User_im_prefs();
-        $user_im_prefs->user_id = $user->id;
-        if(! ($user_im_prefs->find() && $user_im_prefs->fetch())) {
+        $user_im_prefs->user_id = $this->scoped->getID();
+        $user_im_prefs->transport = $transport;
+        if (!$user_im_prefs->find(true)) {
             // TRANS: Message given trying to remove an IM address that is not
             // TRANS: registered for the active user.
-            $this->showForm(_('That is not your screenname.'));
-            return;
+            throw new AlreadyFulfilledException(_('There were no preferences stored for this transport.'));
         }
 
         $result = $user_im_prefs->delete();
 
-        if (!$result) {
-            common_log_db_error($user, 'UPDATE', __FILE__);
+        if ($result === false) {
+            common_log_db_error($user_im_prefs, 'UPDATE', __FILE__);
             // TRANS: Server error thrown on database error removing a registered IM address.
-            $this->serverError(_('Could not update user IM preferences.'));
+            throw new ServerException(_('Could not update user IM preferences.'));
         }
 
         // XXX: unsubscribe to the old address
 
         // TRANS: Message given after successfully removing a registered Instant Messaging address.
-        $this->showForm(_('The IM address was removed.'), true);
+        return _('The IM address was removed.');
     }
 
     /**
@@ -463,15 +421,9 @@ class ImsettingsAction extends SettingsAction
 
     function screennameExists($transport, $screenname)
     {
-        $user = common_current_user();
-
         $user_im_prefs = new User_im_prefs();
         $user_im_prefs->transport = $transport;
         $user_im_prefs->screenname = $screenname;
-        if($user_im_prefs->find() && $user_im_prefs->fetch()){
-            return true;
-        }else{
-            return false;
-        }
+        return $user_im_prefs->find(true) ? true : false;
     }
 }
index 60aec3c83a48d37a21bf435fff4d0da2aa513424..5394a38c9fb573684ae8e28ff3ad95c0210f666a 100644 (file)
@@ -63,7 +63,7 @@ class LogoutAction extends ManagedAction
         }
         Event::handle('EndLogout', array($this));
 
-        common_redirect(common_local_url('startpage'));
+        common_redirect(common_local_url('top'));
     }
 
     // Accessed through the action on events
index 37bede0d72f3c547a3a4e3eb15bde6253c831d00..5032bb74951a8f05a8096ec9115999a33b2f8b33 100644 (file)
@@ -41,7 +41,7 @@ if (!defined('GNUSOCIAL')) { exit(1); }
  * @license  http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
  * @link     http://status.net/
  */
-class NewApplicationAction extends FormAction
+class NewApplicationAction extends SettingsAction
 {
     function title()
     {
@@ -54,6 +54,7 @@ class NewApplicationAction extends FormAction
         if ($this->arg('cancel')) {
             common_redirect(common_local_url('oauthappssettings'), 303);
         } elseif ($this->arg('save')) {
+            //trySave will never return, just throw exception or redirect
             $this->trySave();
         }
 
@@ -72,7 +73,7 @@ class NewApplicationAction extends FormAction
         return _('Use this form to register a new application.');
     }
 
-    private function trySave()
+    protected function trySave()
     {
         $name         = $this->trimmed('name');
         $description  = $this->trimmed('description');
@@ -137,7 +138,7 @@ class NewApplicationAction extends FormAction
         $app->query('BEGIN');
 
         $app->name         = $name;
-        $app->owner        = $this->scoped->id;
+        $app->owner        = $this->scoped->getID();
         $app->description  = $description;
         $app->source_url   = $source_url;
         $app->organization = $organization;
index 14c280f62cfd3f973f5c64703ce0734b16949c6c..2a5187b885dba53f440a1553fb1fc2eb3a261fb0 100644 (file)
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 
-if (!defined('STATUSNET') && !defined('LACONICA')) {
-    exit(1);
-}
-
-require_once INSTALLDIR.'/lib/rssaction.php';
+if (!defined('GNUSOCIAL')) { exit(1); }
 
 /**
  * RSS feed for notice search action class.
@@ -48,19 +44,7 @@ require_once INSTALLDIR.'/lib/rssaction.php';
  */
 class NoticesearchrssAction extends Rss10Action
 {
-    function init()
-    {
-        return true;
-    }
-
-    function prepare($args)
-    {
-        parent::prepare($args);
-        $this->notices = $this->getNotices();
-        return true;
-    }
-
-    function getNotices($limit=0)
+    protected function getNotices()
     {
         $q = $this->trimmed('q');
         $notices = array();
@@ -70,8 +54,7 @@ class NoticesearchrssAction extends Rss10Action
         $search_engine = $notice->getSearchEngine('notice');
         $search_engine->set_sort_mode('chron');
 
-        if (!$limit) $limit = 20;
-        $search_engine->limit(0, $limit, true);
+        $search_engine->limit(0, $this->limit, true);
         if (false === $search_engine->query($q)) {
             $cnt = 0;
         } else {
index 29e6d5607333e9e3d17fd2ab21316df45c927339..43e9b33663ac62c6da1ee94e5694fb71d19221af 100644 (file)
  * @link      http://status.net/
  */
 
-if (!defined('STATUSNET') && !defined('LACONICA')) {
-    exit(1);
-}
-
-require_once INSTALLDIR . '/lib/applicationlist.php';
+if (!defined('GNUSOCIAL')) { exit(1); }
 
 /**
  * Show a user's registered OAuth applications
@@ -47,19 +43,11 @@ require_once INSTALLDIR . '/lib/applicationlist.php';
 
 class OauthappssettingsAction extends SettingsAction
 {
-    var $page = 0;
+    protected $page = null;
 
-    function prepare($args)
+    protected function doPreparation()
     {
-        parent::prepare($args);
-        $this->page = ($this->arg('page')) ? ($this->arg('page') + 0) : 1;
-
-        if (!common_logged_in()) {
-            // TRANS: Message displayed to an anonymous user trying to view OAuth application list.
-            $this->clientError(_('You must be logged in to list your applications.'));
-        }
-
-        return true;
+        $this->page = $this->int('page') ?: 1;
     }
 
     /**
@@ -86,21 +74,13 @@ class OauthappssettingsAction extends SettingsAction
         return _('Applications you have registered');
     }
 
-    /**
-     * Content area of the page
-     *
-     * @return void
-     */
-
     function showContent()
     {
-        $user = common_current_user();
-
         $offset = ($this->page - 1) * APPS_PER_PAGE;
         $limit  =  APPS_PER_PAGE + 1;
 
         $application = new Oauth_application();
-        $application->owner = $user->id;
+        $application->owner = $this->scoped->getID();
         $application->whereAdd("name != 'anonymous'");
         $application->limit($offset, $limit);
         $application->orderBy('created DESC');
@@ -109,7 +89,7 @@ class OauthappssettingsAction extends SettingsAction
         $cnt = 0;
 
         if ($application) {
-            $al = new ApplicationList($application, $user, $this);
+            $al = new ApplicationList($application, $this->scoped, $this);
             $cnt = $al->show();
             if (0 == $cnt) {
                 $this->showEmptyListMessage();
@@ -135,34 +115,11 @@ class OauthappssettingsAction extends SettingsAction
 
     function showEmptyListMessage()
     {
-        // TRANS: Empty list message on page with OAuth applications.
+        // TRANS: Empty list message on page with OAuth applications. Markup allowed
         $message = sprintf(_('You have not registered any applications yet.'));
 
         $this->elementStart('div', 'guide');
         $this->raw(common_markup_to_html($message));
         $this->elementEnd('div');
     }
-
-    /**
-     * Handle posts to this form
-     *
-     * Based on the button that was pressed, muxes out to other functions
-     * to do the actual task requested.
-     *
-     * All sub-functions reload the form with a message -- success or failure.
-     *
-     * @return void
-     */
-
-    function handlePost()
-    {
-        // CSRF protection
-
-        $token = $this->trimmed('token');
-        if (!$token || $token != common_session_token()) {
-            $this->showForm(_('There was a problem with your session token. '.
-                              'Try again, please.'));
-            return;
-        }
-    }
 }
index 9aa3ad434f452b7a3335d4e51e4b08911e17bdaf..0c5a14344370e609df043fb67262683df6501a96 100644 (file)
  * @link      http://status.net/
  */
 
-if (!defined('STATUSNET') && !defined('LACONICA')) {
-    exit(1);
-}
-
-require_once INSTALLDIR . '/lib/applicationlist.php';
+if (!defined('GNUSOCIAL')) { exit(1); }
 
 /**
  * Show connected OAuth applications
@@ -46,15 +42,14 @@ require_once INSTALLDIR . '/lib/applicationlist.php';
  */
 class OauthconnectionssettingsAction extends SettingsAction
 {
-    var $page        = null;
-    var $oauth_token = null;
+    var $page = null;
 
-    function prepare($args)
+    protected $oauth_token = null;
+
+    protected function doPreparation()
     {
-        parent::prepare($args);
         $this->oauth_token = $this->arg('oauth_token');
-        $this->page = ($this->arg('page')) ? ($this->arg('page') + 0) : 1;
-        return true;
+        $this->page = $this->int('page') ?: 1;
     }
 
     /**
@@ -87,18 +82,15 @@ class OauthconnectionssettingsAction extends SettingsAction
 
     function showContent()
     {
-        $user    = common_current_user();
-        $profile = $user->getProfile();
-
         $offset = ($this->page - 1) * APPS_PER_PAGE;
         $limit  =  APPS_PER_PAGE + 1;
 
-        $connection = $user->getConnectedApps($offset, $limit);
+        $connection = $this->scoped->getConnectedApps($offset, $limit);
 
         $cnt = 0;
 
         if (!empty($connection)) {
-            $cal = new ConnectedAppsList($connection, $user, $this);
+            $cal = new ConnectedAppsList($connection, $this->scoped, $this);
             $cnt = $cal->show();
         }
 
@@ -111,7 +103,7 @@ class OauthconnectionssettingsAction extends SettingsAction
             $cnt > APPS_PER_PAGE,
             $this->page,
             'connectionssettings',
-            array('nickname' => $user->nickname)
+            array('nickname' => $this->scoped->getNickname())
         );
     }
 
@@ -125,24 +117,14 @@ class OauthconnectionssettingsAction extends SettingsAction
      *
      * @return void
      */
-    function handlePost()
+    protected function doPost()
     {
-        // CSRF protection
-
-        $token = $this->trimmed('token');
-        if (!$token || $token != common_session_token()) {
-            // TRANS: Client error displayed when the session token does not match or is not given.
-            $this->showForm(_('There was a problem with your session token. '.
-                              'Try again, please.'));
-            return;
-        }
-
         if ($this->arg('revoke')) {
-            $this->revokeAccess($this->oauth_token);
-        } else {
-            // TRANS: Client error when submitting a form with unexpected information.
-            $this->clientError(_('Unexpected form submission.'), 401);
+            return $this->revokeAccess($this->oauth_token);
         }
+
+        // TRANS: Client error when submitting a form with unexpected information.
+        throw new ClientException(_('Unexpected form submission.'), 401);
     }
 
     /**
index 25ec13e4816426b3f95fb91c6a1634a1b4591308..5c071954788e8690ad669a944838b6e8ec77bb67 100644 (file)
  * @link      http://status.net/
  */
 
-if (!defined('STATUSNET')) {
-    // This check helps protect against security problems;
-    // your code file can't be executed directly from the web.
-    exit(1);
-}
+if (!defined('GNUSOCIAL')) { exit(1); }
 
 /**
  * Old-school settings
@@ -77,35 +73,23 @@ class OldschoolsettingsAction extends SettingsAction
      * @return boolean true
      */
 
-    function prepare($argarray)
+    protected function doPreparation()
     {
         if (!common_config('oldschool', 'enabled')) {
             throw new ClientException("Old-school settings not enabled.");
         }
-        parent::prepare($argarray);
-        return true;
     }
 
-    /**
-     * Handler method
-     *
-     * @param array $argarray is ignored since it's now passed in in prepare()
-     *
-     * @return void
-     */
-
-    function handlePost()
+    function doPost()
     {
-        $user = common_current_user();
-
-        $osp = Old_school_prefs::getKV('user_id', $user->id);
+        $osp = Old_school_prefs::getKV('user_id', $this->scoped->getID());
         $orig = null;
 
         if (!empty($osp)) {
             $orig = clone($osp);
         } else {
             $osp = new Old_school_prefs();
-            $osp->user_id = $user->id;
+            $osp->user_id = $this->scoped->getID();
             $osp->created = common_sql_now();
         }
 
@@ -113,34 +97,25 @@ class OldschoolsettingsAction extends SettingsAction
         $osp->stream_nicknames  = $this->boolean('stream_nicknames');
         $osp->modified          = common_sql_now();
 
-        if (!empty($orig)) {
+        if ($orig instanceof Old_school_prefs) {
             $osp->update($orig);
         } else {
             $osp->insert();
         }
 
         // TRANS: Confirmation shown when user profile settings are saved.
-        $this->showForm(_('Settings saved.'), true);
-
-        return;
-    }
-
-    function showContent()
-    {
-        $user = common_current_user();
-        $form = new OldSchoolForm($this, $user);
-        $form->show();
+        return _('Settings saved.');
     }
 }
 
-class OldSchoolForm extends Form
+class OldSchoolSettingsForm extends Form
 {
     var $user;
 
-    function __construct($out, $user)
+    function __construct(Action $out)
     {
         parent::__construct($out);
-        $this->user = $user;
+        $this->user = $out->getScoped()->getUser();
     }
 
     /**
index db36b612a29becfa806733c885e57ff955504f48..cfdb6c78176e221fcef24a1cd3e7d04feb48584b 100644 (file)
  * @link      http://status.net/
  */
 
-if (!defined('STATUSNET') && !defined('LACONICA')) {
-    exit(1);
-}
-
-
+if (!defined('STATUSNET')) { exit(1); }
 
 /**
  * Change password
@@ -77,18 +73,8 @@ class PasswordsettingsAction extends SettingsAction
         $this->autofocus('oldpassword');
     }
 
-    /**
-     * Content area of the page
-     *
-     * Shows a form for changing the password
-     *
-     * @return void
-     */
-
     function showContent()
     {
-        $user = common_current_user();
-
         $this->elementStart('form', array('method' => 'POST',
                                           'id' => 'form_password',
                                           'class' => 'form_settings',
@@ -102,7 +88,7 @@ class PasswordsettingsAction extends SettingsAction
 
         $this->elementStart('ul', 'form_data');
         // Users who logged in with OpenID won't have a pwd
-        if ($user->password) {
+        if ($this->scoped->hasPassword()) {
             $this->elementStart('li');
             // TRANS: Field label on page where to change password.
             $this->password('oldpassword', _('Old password'));
@@ -129,29 +115,8 @@ class PasswordsettingsAction extends SettingsAction
         $this->elementEnd('form');
     }
 
-    /**
-     * Handle a post
-     *
-     * Validate input and save changes. Reload the form with a success
-     * or error message.
-     *
-     * @return void
-     */
-    function handlePost()
+    protected function doPost()
     {
-        // CSRF protection
-
-        $token = $this->trimmed('token');
-        if (!$token || $token != common_session_token()) {
-            // TRANS: Client error displayed when the session token does not match or is not given.
-            $this->showForm(_('There was a problem with your session token. '.
-                               'Try again, please.'));
-            return;
-        }
-
-        $user = common_current_user();
-        assert(!is_null($user)); // should already be checked
-
         // FIXME: scrub input
 
         $newpassword = $this->arg('newpassword');
@@ -161,49 +126,44 @@ class PasswordsettingsAction extends SettingsAction
 
         if (strlen($newpassword) < 6) {
             // TRANS: Form validation error on page where to change password.
-            $this->showForm(_('Password must be 6 or more characters.'));
-            return;
+            throw new ClientException(_('Password must be 6 or more characters.'));
         } else if (0 != strcmp($newpassword, $confirm)) {
             // TRANS: Form validation error on password change when password confirmation does not match.
-            $this->showForm(_('Passwords do not match.'));
-            return;
+            throw new ClientException(_('Passwords do not match.'));
         }
 
-        if ($user->password) {
+        $oldpassword = null;
+        if ($this->scoped->hasPassword()) {
             $oldpassword = $this->arg('oldpassword');
 
-            if (!common_check_user($user->nickname, $oldpassword)) {
+            if (!common_check_user($this->scoped->getNickname(), $oldpassword)) {
                 // TRANS: Form validation error on page where to change password.
-                $this->showForm(_('Incorrect old password.'));
-                return;
+                throw new ClientException(_('Incorrect old password.'));
             }
-        }else{
-            $oldpassword = null;
         }
 
-        $success = false;
-        if(Event::handle('StartChangePassword', array($user, $oldpassword, $newpassword))){
+        if (Event::handle('StartChangePassword', array($this->scoped, $oldpassword, $newpassword))) {
             //no handler changed the password, so change the password internally
+            $user = $this->scoped->getUser();
             $original = clone($user);
 
-            $user->password = common_munge_password($newpassword, $user->id);
+            $user->password = common_munge_password($newpassword, $this->scoped);
 
             $val = $user->validate();
             if ($val !== true) {
                 // TRANS: Form validation error on page where to change password.
-                $this->showForm(_('Error saving user; invalid.'));
-                return;
+                throw new ServerException(_('Error saving user; invalid.'));
             }
 
             if (!$user->update($original)) {
                 // TRANS: Server error displayed on page where to change password when password change
                 // TRANS: could not be made because of a server error.
-                $this->serverError(_('Cannot save new password.'));
+                throw new ServerException(_('Cannot save new password.'));
             }
-            Event::handle('EndChangePassword', array($user));
+            Event::handle('EndChangePassword', array($this->scoped));
         }
 
         // TRANS: Form validation notice on page where to change password.
-        $this->showForm(_('Password saved.'), true);
+        return _('Password saved.');
     }
 }
index 7d3143d4b186507483af83288750c910a220d45e..5804f21ca59d817d37642a3ccea537d5b6bdd607 100644 (file)
@@ -82,7 +82,6 @@ class ProfilesettingsAction extends SettingsAction
      */
     function showContent()
     {
-        $profile = $this->scoped;
         $user = $this->scoped->getUser();
 
         $this->elementStart('form', array('method' => 'post',
@@ -100,7 +99,7 @@ class ProfilesettingsAction extends SettingsAction
             $this->elementStart('li');
             // TRANS: Field label in form for profile settings.
             $this->input('nickname', _('Nickname'),
-                         $this->arg('nickname') ?: $profile->nickname,
+                         $this->trimmed('nickname') ?: $this->scoped->getNickname(),
                          // TRANS: Tooltip for field label in form for profile settings.
                          _('1-64 lowercase letters or numbers, no punctuation or spaces.'),
                          null, false,   // "name" (will be set to id), then "required"
@@ -111,12 +110,12 @@ class ProfilesettingsAction extends SettingsAction
             $this->elementStart('li');
             // TRANS: Field label in form for profile settings.
             $this->input('fullname', _('Full name'),
-                         ($this->arg('fullname')) ? $this->arg('fullname') : $profile->fullname);
+                         $this->trimmed('fullname') ?: $this->scoped->getFullname());
             $this->elementEnd('li');
             $this->elementStart('li');
             // TRANS: Field label in form for profile settings.
             $this->input('homepage', _('Homepage'),
-                         ($this->arg('homepage')) ? $this->arg('homepage') : $profile->homepage,
+                         $this->trimmed('homepage') ?: $this->scoped->getHomepage(),
                          // TRANS: Tooltip for field label in form for profile settings.
                          _('URL of your homepage, blog, or profile on another site.'));
             $this->elementEnd('li');
@@ -137,13 +136,13 @@ class ProfilesettingsAction extends SettingsAction
             // TRANS: Text area label in form for profile settings where users can provide
             // TRANS: their biography.
             $this->textarea('bio', _('Bio'),
-                            ($this->arg('bio')) ? $this->arg('bio') : $profile->bio,
+                            $this->trimmed('bio') ?: $this->scoped->getDescription(),
                             $bioInstr);
             $this->elementEnd('li');
             $this->elementStart('li');
             // TRANS: Field label in form for profile settings.
             $this->input('location', _('Location'),
-                         ($this->arg('location')) ? $this->arg('location') : $profile->location,
+                         $this->trimmed('location') ?: $this->scoped->location,
                          // TRANS: Tooltip for field label in form for profile settings.
                          _('Where you are, like "City, State (or Region), Country".'));
             $this->elementEnd('li');
@@ -152,14 +151,14 @@ class ProfilesettingsAction extends SettingsAction
                 // TRANS: Checkbox label in form for profile settings.
                 $this->checkbox('sharelocation', _('Share my current location when posting notices'),
                                 ($this->arg('sharelocation')) ?
-                                $this->arg('sharelocation') : $this->scoped->shareLocation());
+                                $this->boolean('sharelocation') : $this->scoped->shareLocation());
                 $this->elementEnd('li');
             }
             Event::handle('EndProfileFormData', array($this));
             $this->elementStart('li');
             // TRANS: Field label in form for profile settings.
             $this->input('tags', _('Tags'),
-                         ($this->arg('tags')) ? $this->arg('tags') : implode(' ', $user->getSelfTags()),
+                         $this->trimmed('tags') ?: implode(' ', Profile_tag::getSelfTagsArray($this->scoped)),
                          // TRANS: Tooltip for field label in form for profile settings.
                          _('Tags for yourself (letters, numbers, -, ., and _), comma- or space- separated.'));
             $this->elementEnd('li');
@@ -228,17 +227,8 @@ class ProfilesettingsAction extends SettingsAction
      *
      * @return void
      */
-    function handlePost()
+    protected function doPost()
     {
-        // CSRF protection
-        $token = $this->trimmed('token');
-        if (!$token || $token != common_session_token()) {
-            // TRANS: Form validation error.
-            $this->showForm(_('There was a problem with your session token. '.
-                              'Try again, please.'));
-            return;
-        }
-
         if (Event::handle('StartProfileSaveForm', array($this))) {
 
             // $nickname will only be set if this changenick value is true.
@@ -246,15 +236,13 @@ class ProfilesettingsAction extends SettingsAction
                 try {
                     $nickname = Nickname::normalize($this->trimmed('nickname'), true);
                 } catch (NicknameTakenException $e) {
-                    // Abort only if the nickname is occupied by another local profile
-                    if ($e->profile->id != $this->scoped->id) {
-                        $this->showForm($e->getMessage());
-                        return;
+                    // Abort only if the nickname is occupied by _another_ local user profile
+                    if (!$this->scoped->sameAs($e->profile)) {
+                        throw $e;
                     }
-                    $nickname = Nickname::normalize($this->trimmed('nickname')); // without in-use check this time
-                } catch (NicknameException $e) {
-                    $this->showForm($e->getMessage());
-                    return;
+                    // Since the variable wasn't set before the exception was thrown, let's run
+                    // the normalize sequence again, but without in-use check this time.
+                    $nickname = Nickname::normalize($this->trimmed('nickname'));
                 }
             }
 
@@ -273,33 +261,27 @@ class ProfilesettingsAction extends SettingsAction
             if (!is_null($homepage) && (strlen($homepage) > 0) &&
                        !common_valid_http_url($homepage)) {
                 // TRANS: Validation error in form for profile settings.
-                $this->showForm(_('Homepage is not a valid URL.'));
-                return;
-            } else if (!is_null($fullname) && mb_strlen($fullname) > 255) {
+                throw new ClientException(_('Homepage is not a valid URL.'));
+            } else if (!is_null($fullname) && mb_strlen($fullname) > 191) {
                 // TRANS: Validation error in form for profile settings.
-                $this->showForm(_('Full name is too long (maximum 255 characters).'));
-                return;
+                throw new ClientException(_('Full name is too long (maximum 191 characters).'));
             } else if (Profile::bioTooLong($bio)) {
                 // TRANS: Validation error in form for profile settings.
                 // TRANS: Plural form is used based on the maximum number of allowed
                 // TRANS: characters for the biography (%d).
-                $this->showForm(sprintf(_m('Bio is too long (maximum %d character).',
+                throw new ClientException(sprintf(_m('Bio is too long (maximum %d character).',
                                            'Bio is too long (maximum %d characters).',
                                            Profile::maxBio()),
                                         Profile::maxBio()));
-                return;
-            } else if (!is_null($location) && mb_strlen($location) > 255) {
+            } else if (!is_null($location) && mb_strlen($location) > 191) {
                 // TRANS: Validation error in form for profile settings.
-                $this->showForm(_('Location is too long (maximum 255 characters).'));
-                return;
+                throw new ClientException(_('Location is too long (maximum 191 characters).'));
             }  else if (is_null($timezone) || !in_array($timezone, DateTimeZone::listIdentifiers())) {
                 // TRANS: Validation error in form for profile settings.
-                $this->showForm(_('Timezone not selected.'));
-                return;
+                throw new ClientException(_('Timezone not selected.'));
             } else if (!is_null($language) && strlen($language) > 50) {
                 // TRANS: Validation error in form for profile settings.
-                $this->showForm(_('Language is too long (maximum 50 characters).'));
-                return;
+                throw new ClientException(_('Language is too long (maximum 50 characters).'));
             }
 
             $tags = array();
@@ -315,15 +297,14 @@ class ProfilesettingsAction extends SettingsAction
                     if (!common_valid_profile_tag($tag)) {
                         // TRANS: Validation error in form for profile settings.
                         // TRANS: %s is an invalid tag.
-                        $this->showForm(sprintf(_('Invalid tag: "%s".'), $tag));
-                        return;
+                        throw new ClientException(sprintf(_('Invalid tag: "%s".'), $tag));
                     }
 
                     $tag_priv[$tag] = $private;
                 }
             }
 
-            $user = common_current_user();
+            $user = $this->scoped->getUser();
             $user->query('BEGIN');
 
             // $user->nickname is updated through Profile->update();
@@ -346,54 +327,53 @@ class ProfilesettingsAction extends SettingsAction
                 $result = $user->update($original);
                 if ($result === false) {
                     common_log_db_error($user, 'UPDATE', __FILE__);
+                    $user->query('ROLLBACK');
                     // TRANS: Server error thrown when user profile settings could not be updated to
                     // TRANS: automatically subscribe to any subscriber.
-                    $this->serverError(_('Could not update user for autosubscribe or subscribe_policy.'));
+                    throw new ServerException(_('Could not update user for autosubscribe or subscribe_policy.'));
                 }
 
                 // Re-initialize language environment if it changed
                 common_init_language();
             }
 
-            $profile = $user->getProfile();
-
-            $orig_profile = clone($profile);
+            $original = clone($this->scoped);
 
-            if (common_config('profile', 'changenick') == true && $profile->nickname !== $nickname) {
+            if (common_config('profile', 'changenick') == true && $this->scoped->getNickname() !== $nickname) {
                 assert(Nickname::normalize($nickname)===$nickname);
-                common_debug("Changing user nickname from '{$profile->nickname}' to '{$nickname}'.");
-                $profile->nickname = $nickname;
-                $profile->profileurl = common_profile_url($profile->nickname);
+                common_debug("Changing user nickname from '{$this->scoped->getNickname()}' to '{$nickname}'.");
+                $this->scoped->nickname = $nickname;
+                $this->scoped->profileurl = common_profile_url($this->scoped->getNickname());
             }
-            $profile->fullname = $fullname;
-            $profile->homepage = $homepage;
-            $profile->bio = $bio;
-            $profile->location = $location;
+            $this->scoped->fullname = $fullname;
+            $this->scoped->homepage = $homepage;
+            $this->scoped->bio = $bio;
+            $this->scoped->location = $location;
 
             $loc = Location::fromName($location);
 
             if (empty($loc)) {
-                $profile->lat         = null;
-                $profile->lon         = null;
-                $profile->location_id = null;
-                $profile->location_ns = null;
+                $this->scoped->lat         = null;
+                $this->scoped->lon         = null;
+                $this->scoped->location_id = null;
+                $this->scoped->location_ns = null;
             } else {
-                $profile->lat         = $loc->lat;
-                $profile->lon         = $loc->lon;
-                $profile->location_id = $loc->location_id;
-                $profile->location_ns = $loc->location_ns;
+                $this->scoped->lat         = $loc->lat;
+                $this->scoped->lon         = $loc->lon;
+                $this->scoped->location_id = $loc->location_id;
+                $this->scoped->location_ns = $loc->location_ns;
             }
 
             if (common_config('location', 'share') == 'user') {
 
                 $exists = false;
 
-                $prefs = User_location_prefs::getKV('user_id', $user->id);
+                $prefs = User_location_prefs::getKV('user_id', $this->scoped->getID());
 
                 if (empty($prefs)) {
                     $prefs = new User_location_prefs();
 
-                    $prefs->user_id = $user->id;
+                    $prefs->user_id = $this->scoped->getID();
                     $prefs->created = common_sql_now();
                 } else {
                     $exists = true;
@@ -410,42 +390,37 @@ class ProfilesettingsAction extends SettingsAction
 
                 if ($result === false) {
                     common_log_db_error($prefs, ($exists) ? 'UPDATE' : 'INSERT', __FILE__);
+                    $user->query('ROLLBACK');
                     // TRANS: Server error thrown when user profile location preference settings could not be updated.
-                    $this->serverError(_('Could not save location prefs.'));
+                    throw new ServerException(_('Could not save location prefs.'));
                 }
             }
 
-            common_debug('Old profile: ' . common_log_objstring($orig_profile), __FILE__);
-            common_debug('New profile: ' . common_log_objstring($profile), __FILE__);
+            common_debug('Old profile: ' . common_log_objstring($original), __FILE__);
+            common_debug('New profile: ' . common_log_objstring($this->scoped), __FILE__);
 
-            $result = $profile->update($orig_profile);
+            $result = $this->scoped->update($original);
 
             if ($result === false) {
-                common_log_db_error($profile, 'UPDATE', __FILE__);
+                common_log_db_error($this->scoped, 'UPDATE', __FILE__);
+                $user->query('ROLLBACK');
                 // TRANS: Server error thrown when user profile settings could not be saved.
-                $this->serverError(_('Could not save profile.'));
+                throw new ServerException(_('Could not save profile.'));
             }
 
             // Set the user tags
-            $result = $user->setSelfTags($tags, $tag_priv);
-
-            if (!$result) {
-                // TRANS: Server error thrown when user profile settings tags could not be saved.
-                $this->serverError(_('Could not save tags.'));
-            }
+            $result = Profile_tag::setSelfTags($this->scoped, $tags, $tag_priv);
 
             $user->query('COMMIT');
             Event::handle('EndProfileSaveForm', array($this));
 
             // TRANS: Confirmation shown when user profile settings are saved.
-            $this->showForm(_('Settings saved.'), true);
+            return _('Settings saved.');
 
         }
     }
 
     function showAside() {
-        $user = common_current_user();
-
         $this->elementStart('div', array('id' => 'aside_primary',
                                          'class' => 'aside'));
 
@@ -453,7 +428,7 @@ class ProfilesettingsAction extends SettingsAction
                                          'class' => 'section'));
         $this->elementStart('ul');
         if (Event::handle('StartProfileSettingsActions', array($this))) {
-            if ($user->hasRight(Right::BACKUPACCOUNT)) {
+            if ($this->scoped->hasRight(Right::BACKUPACCOUNT)) {
                 $this->elementStart('li');
                 $this->element('a',
                                array('href' => common_local_url('backupaccount')),
@@ -461,7 +436,7 @@ class ProfilesettingsAction extends SettingsAction
                                _('Backup account'));
                 $this->elementEnd('li');
             }
-            if ($user->hasRight(Right::DELETEACCOUNT)) {
+            if ($this->scoped->hasRight(Right::DELETEACCOUNT)) {
                 $this->elementStart('li');
                 $this->element('a',
                                array('href' => common_local_url('deleteaccount')),
@@ -469,7 +444,7 @@ class ProfilesettingsAction extends SettingsAction
                                _('Delete account'));
                 $this->elementEnd('li');
             }
-            if ($user->hasRight(Right::RESTOREACCOUNT)) {
+            if ($this->scoped->hasRight(Right::RESTOREACCOUNT)) {
                 $this->elementStart('li');
                 $this->element('a',
                                array('href' => common_local_url('restoreaccount')),
index 11db3b37a48c57a3252323fa358c670215a8970e..5dcff3ba3d2f973c11118c90ae7e20c7ad9c1678 100644 (file)
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 
-if (!defined('STATUSNET') && !defined('LACONICA')) {
-    exit(1);
-}
-
-require_once INSTALLDIR.'/lib/rssaction.php';
+if (!defined('GNUSOCIAL')) { exit(1); }
 
 /**
  * RSS feed for public timeline.
@@ -48,29 +44,6 @@ require_once INSTALLDIR.'/lib/rssaction.php';
  */
 class PublicrssAction extends Rss10Action
 {
-    /**
-     * Read arguments and initialize members
-     *
-     * @param array $args Arguments from $_REQUEST
-     * @return boolean success
-     */
-    function prepare($args)
-    {
-        parent::prepare($args);
-        $this->notices = $this->getNotices($this->limit);
-        return true;
-    }
-
-    /**
-     * Initialization.
-     *
-     * @return boolean true
-     */
-    function init()
-    {
-        return true;
-    }
-
     /**
      * Get notices
      *
@@ -78,15 +51,10 @@ class PublicrssAction extends Rss10Action
      *
      * @return array notices
      */
-    function getNotices($limit=0)
+    protected function getNotices()
     {
-        $notices = array();
-        $notice  = Notice::publicStream(0, ($limit == 0) ? 48 : $limit);
-        while ($notice->fetch()) {
-            $notices[] = clone($notice);
-        }
-
-        return $notices;
+        $stream  = Notice::publicStream(0, $this->limit);
+        return $stream->fetchAll();
     }
 
      /**
index 060ba83510b44fb82fc870e7f7d7f74e49e6a5c3..1cbb73fd4a21fa5528fcabcaf6506dfb4848b083 100644 (file)
@@ -325,7 +325,7 @@ class RecoverpasswordAction extends Action
 
         $original = clone($user);
 
-        $user->password = common_munge_password($newpassword, $user->id);
+        $user->password = common_munge_password($newpassword, $user->getProfile());
 
         if (!$user->update($original)) {
             common_log_db_error($user, 'UPDATE', __FILE__);
index 4befa4ab840c843c014c712f2b4d3e6e611593f1..db3784bf31d70b4bb09f9eb816ec107d5225c863 100644 (file)
  * @link      http://status.net/
  */
 
-if (!defined('STATUSNET')) {
-    // This check helps protect against security problems;
-    // your code file can't be executed directly from the web.
-    exit(1);
-}
+if (!defined('GNUSOCIAL')) { exit(1); }
 
 /**
  * Redirect to a given URL
@@ -47,75 +43,27 @@ if (!defined('STATUSNET')) {
  * @link      http://status.net/
  */
 
-class RedirecturlAction extends Action
+class RedirecturlAction extends ManagedAction
 {
-    protected $id   = null;
     protected $file = null;
 
-    /**
-     * For initializing members of the class.
-     *
-     * @param array $argarray misc. arguments
-     *
-     * @return boolean true
-     */
-    function prepare($argarray)
+    protected function doPreparation()
     {
-        parent::prepare($argarray);
-
-        $this->id = $this->trimmed('id');
-
-        if (empty($this->id)) {
-            // TRANS: Client exception thrown when no ID parameter was provided.
-            throw new ClientException(_('No id parameter.'));
-        }
-
-        $this->file = File::getKV('id', $this->id);
-
-        if (empty($this->file)) {
-            // TRANS: Client exception thrown when an invalid ID parameter was provided for a file.
-            // TRANS: %d is the provided ID for which the file is not present (number).
-            throw new ClientException(sprintf(_('No such file "%d".'),
-                                              $this->id),
-                                      404);
-        }
+        $this->file = File::getByID($this->int('id'));
 
         return true;
     }
 
-    /**
-     * Handler method
-     *
-     * @param array $argarray is ignored since it's now passed in in prepare()
-     *
-     * @return void
-     */
-    function handle($argarray=null)
+    public function showPage()
     {
         common_redirect($this->file->url, 307);
     }
 
-    /**
-     * Return true if read only.
-     *
-     * MAY override
-     *
-     * @param array $args other arguments
-     *
-     * @return boolean is read only action?
-     */
     function isReadOnly($args)
     {
         return true;
     }
 
-    /**
-     * Return last modified, if applicable.
-     *
-     * MAY override
-     *
-     * @return string last modified http header
-     */
     function lastModified()
     {
         // For comparison with If-Last-Modified
@@ -133,9 +81,9 @@ class RedirecturlAction extends Action
      */
     function etag()
     {
-        return 'W/"' . implode(':', array($this->arg('action'),
+        return 'W/"' . implode(':', array($this->getActionName(),
                                           common_user_cache_hash(),
                                           common_language(),
-                                          $this->file->id)) . '"';
+                                          $this->file->getID())) . '"';
     }
 }
index 8baf9d69e0af87410123c5af3cb5633c4c60dcc2..ae6ec90658dca67272bbbc39d1734012db92deee 100644 (file)
@@ -40,9 +40,6 @@ if (!defined('GNUSOCIAL')) { exit(1); }
  */
 class RepliesAction extends ShowstreamAction
 {
-    var $page = null;
-    var $notice;
-
     public function getStream()
     {
         return new ReplyNoticeStream($this->target->getID(), $this->scoped);
@@ -85,7 +82,7 @@ class RepliesAction extends ShowstreamAction
                               // TRANS: Link for feed with replies for a user.
                               // TRANS: %s is a user nickname.
                               sprintf(_('Replies feed for %s (Activity Streams JSON)'),
-                                      $this->user->nickname)),
+                                      $this->target->getNickname())),
                      new Feed(Feed::RSS1,
                               common_local_url('repliesrss',
                                                array('nickname' => $this->target->getNickname())),
index 145b51aaea99dfc58cb252c7c1210897dd773a39..54f83592c0ffa0dc0eca90a44d365c6aa9d38dc5 100644 (file)
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 
-if (!defined('STATUSNET') && !defined('LACONICA')) { exit(1); }
-
-require_once(INSTALLDIR.'/lib/rssaction.php');
+if (!defined('GNUSOCIAL')) { exit(1); }
 
 // Formatting of RSS handled by Rss10Action
 
-class RepliesrssAction extends Rss10Action
+class RepliesrssAction extends TargetedRss10Action
 {
-    var $user = null;
-
-    function prepare($args)
+    protected function getNotices()
     {
-        parent::prepare($args);
-        $nickname = $this->trimmed('nickname');
-        $this->user = User::getKV('nickname', $nickname);
-
-        if (!$this->user) {
-            // TRANS: Client error displayed when providing a non-existing nickname in a RSS 1.0 action.
-            $this->clientError(_('No such user.'));
-        } else {
-            $this->notices = $this->getNotices($this->limit);
-            return true;
-        }
-    }
-
-    function getNotices($limit=0)
-    {
-        $user = $this->user;
-
-        $notice = $user->getReplies(0, ($limit == 0) ? 48 : $limit);
-
-        $notices = array();
-
-        while ($notice->fetch()) {
-            $notices[] = clone($notice);
-        }
-
-        return $notices;
+        $stream = $this->target->getReplies(0, $this->limit);
+        return $stream->fetchAll();
     }
 
     function getChannel()
     {
-        $user = $this->user;
         $c = array('url' => common_local_url('repliesrss',
                                              array('nickname' =>
-                                                   $user->nickname)),
+                                                   $this->target->getNickname())),
                    // TRANS: RSS reply feed title. %s is a user nickname.
-                   'title' => sprintf(_("Replies to %s"), $user->nickname),
+                   'title' => sprintf(_("Replies to %s"), $this->target->getNickname()),
                    'link' => common_local_url('replies',
-                                              array('nickname' =>
-                                                    $user->nickname)),
+                                              array('nickname' => $this->target->getNickname())),
                    // TRANS: RSS reply feed description.
                    // TRANS: %1$s is a user nickname, %2$s is the StatusNet site name.
                    'description' => sprintf(_('Replies to %1$s on %2$s.'),
-                                              $user->nickname, common_config('site', 'name')));
+                                              $this->target->getNickname(), common_config('site', 'name')));
         return $c;
     }
 
-    function getImage()
-    {
-        $profile = $this->user->getProfile();
-        return $profile->avatarUrl(AVATAR_PROFILE_SIZE);
-    }
-
     function isReadOnly($args)
     {
         return true;
index d686042cb12fe8e52a2a74a4fb910c1a57a05582..fdfc2bd1bd650cdee7bbaf76d3c03a3a642619e7 100644 (file)
@@ -27,9 +27,7 @@
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 
-if (!defined('STATUSNET')) {
-    exit(1);
-}
+if (!defined('GNUSOCIAL')) { exit(1); }
 
 /**
  * Prints out a static robots.txt
@@ -40,19 +38,9 @@ if (!defined('STATUSNET')) {
  * @license  http://www.fsf.org/licensing/licenses/agpl.html AGPLv3
  * @link     http://status.net/
  */
-class RobotstxtAction extends Action
+class RobotstxtAction extends ManagedAction
 {
-    /**
-     * Handles requests
-     *
-     * Since this is a relatively static document, we
-     * don't do a prepare()
-     *
-     * @param array $args GET, POST, and URL params; unused.
-     *
-     * @return void
-     */
-    function handle($args)
+    public function showPage()
     {
         if (Event::handle('StartRobotsTxt', array($this))) {
 
index 4a1adfd7de938aac1061cb6d93c93e01363c736b..23386868ddbc1b042b3151b29340b952c86cf35c 100644 (file)
@@ -222,25 +222,12 @@ class ShownoticeAction extends ManagedAction
     /**
      * Extra <head> content
      *
-     * We show the microid(s) for the author, if any.
+     * Facebook OpenGraph metadata.
      *
      * @return void
      */
     function extraHead()
     {
-        $user = User::getKV($this->profile->id);
-
-        if (!$user instanceof User) {
-            return;
-        }
-
-        if ($user->emailmicroid && $user->email && $this->notice->uri) {
-            $id = new Microid('mailto:'. $user->email,
-                              $this->notice->uri);
-            $this->element('meta', array('name' => 'microid',
-                                         'content' => $id->toString()));
-        }
-
         // Extras to aid in sharing notices to Facebook
         $avatarUrl = $this->profile->avatarUrl(AVATAR_PROFILE_SIZE);
         $this->element('meta', array('property' => 'og:image',
index 6eccbd06bf49db0f33db1394df1ca3f828918f63..890c1e711b316a99207fb7a2ac736cb2ba70264c 100644 (file)
@@ -47,37 +47,6 @@ if (!defined('GNUSOCIAL')) { exit(1); }
  */
 class ShowstreamAction extends NoticestreamAction
 {
-    var $notice;
-
-    protected function doPreparation()
-    {
-        // showstream requires a nickname
-        $nickname_arg = $this->arg('nickname');
-        $nickname     = common_canonical_nickname($nickname_arg);
-
-        // Permanent redirect on non-canonical nickname
-
-        if ($nickname_arg != $nickname) {
-            $args = array('nickname' => $nickname);
-            if ($this->arg('page') && $this->arg('page') != 1) {
-                $args['page'] = $this->arg['page'];
-            }
-            common_redirect(common_local_url($this->getActionName(), $args), 301);
-        }
-        $this->user = User::getKV('nickname', $nickname);
-
-        if (!$this->user) {
-            $group = Local_group::getKV('nickname', $nickname);
-            if ($group instanceof Local_group) {
-                common_redirect($group->getProfile()->getUrl());
-            }
-            // TRANS: Client error displayed when calling a profile action without specifying a user.
-            $this->clientError(_('No such user.'), 404);
-        }
-
-        $this->target = $this->user->getProfile();
-    }
-
     public function getStream()
     {
         if (empty($this->tag)) {
@@ -194,13 +163,6 @@ class ShowstreamAction extends NoticestreamAction
                                          'content' => $this->target->getDescription()));
         }
 
-        if ($this->target->isLocal() && $this->target->getUser()->emailmicroid && $this->target->getUser()->email && $this->target->getUrl()) {
-            $id = new Microid('mailto:'.$this->target->getUser()->email,
-                              $this->selfUrl());
-            $this->element('meta', array('name' => 'microid',
-                                         'content' => $id->toString()));
-        }
-
         // See https://wiki.mozilla.org/Microsummaries
 
         $this->element('link', array('rel' => 'microsummary',
@@ -289,7 +251,7 @@ class ShowstreamAction extends NoticestreamAction
     {
         parent::showSections();
         if (!common_config('performance', 'high')) {
-            $cloud = new PersonalTagCloudSection($this, $this->user);
+            $cloud = new PersonalTagCloudSection($this->target, $this);
             $cloud->show();
         }
     }
@@ -298,7 +260,7 @@ class ShowstreamAction extends NoticestreamAction
     {
         $options = parent::noticeFormOptions();
 
-        if (!$this->scoped instanceof Profile || $this->scoped->id != $this->target->id) {
+        if (!$this->scoped instanceof Profile || !$this->scoped->sameAs($this->target)) {
             $options['to_profile'] =  $this->target;
         }
 
index ec8841281d2bf07c544910080002aacd7181e556..ca6a7d04efdec803cd5ebe2a2483b10d8b60e8be 100644 (file)
@@ -27,9 +27,7 @@
  * @link      http://status.net/
  */
 
-if (!defined('STATUSNET') && !defined('LACONICA')) {
-    exit(1);
-}
+if (!defined('GNUSOCIAL')) { exit(1); }
 
 /**
  * Settings for SMS
@@ -45,6 +43,14 @@ if (!defined('STATUSNET') && !defined('LACONICA')) {
 
 class SmssettingsAction extends SettingsAction
 {
+    protected function doPreparation()
+    {
+        if (!common_config('sms', 'enabled')) {
+            // TRANS: Message given in the SMS settings if SMS is not enabled on the site.
+            throw new ServerException(_('SMS is not available.'));
+        }
+    }
+
     /**
      * Title of the page
      *
@@ -86,14 +92,7 @@ class SmssettingsAction extends SettingsAction
      */
     function showContent()
     {
-        if (!common_config('sms', 'enabled')) {
-            $this->element('div', array('class' => 'error'),
-                           // TRANS: Message given in the SMS settings if SMS is not enabled on the site.
-                           _('SMS is not available.'));
-            return;
-        }
-
-        $user = common_current_user();
+        $user = $this->scoped->getUser();
 
         $this->elementStart('form', array('method' => 'post',
                                           'id' => 'form_settings_sms',
@@ -118,8 +117,8 @@ class SmssettingsAction extends SettingsAction
             // TRANS: Button label to remove a confirmed SMS address.
             $this->submit('remove', _m('BUTTON','Remove'));
         } else {
-            $confirm = $this->getConfirmation();
-            if ($confirm) {
+            try {
+                $confirm = $this->getConfirmation();
                 $carrier = Sms_carrier::getKV($confirm->address_extra);
                 $this->element('p', 'form_unconfirmed',
                                $confirm->address . ' (' . $carrier->name . ')');
@@ -141,7 +140,7 @@ class SmssettingsAction extends SettingsAction
                 $this->elementEnd('ul');
                 // TRANS: Button label to confirm SMS confirmation code in SMS settings.
                 $this->submit('confirm', _m('BUTTON','Confirm'));
-            } else {
+            } catch (NoResultException $e) {
                 $this->elementStart('ul', 'form_data');
                 $this->elementStart('li');
                 // TRANS: Field label for SMS phone number input in SMS settings form.
@@ -216,60 +215,38 @@ class SmssettingsAction extends SettingsAction
      */
     function getConfirmation()
     {
-        $user = common_current_user();
-
         $confirm = new Confirm_address();
 
-        $confirm->user_id      = $user->id;
+        $confirm->user_id      = $this->scoped->getID();
         $confirm->address_type = 'sms';
 
         if ($confirm->find(true)) {
             return $confirm;
-        } else {
-            return null;
         }
+
+        throw new NoResultException($confirm);
     }
 
-    /**
-     * Handle posts to this form
-     *
-     * Based on the button that was pressed, muxes out to other functions
-     * to do the actual task requested.
-     *
-     * All sub-functions reload the form with a message -- success or failure.
-     *
-     * @return void
-     */
-    function handlePost()
+    protected function doPost()
     {
-        // CSRF protection
-
-        $token = $this->trimmed('token');
-        if (!$token || $token != common_session_token()) {
-            // TRANS: Client error displayed when the session token does not match or is not given.
-            $this->showForm(_('There was a problem with your session token. '.
-                              'Try again, please.'));
-            return;
-        }
 
         if ($this->arg('save')) {
-            $this->savePreferences();
+            return $this->savePreferences();
         } else if ($this->arg('add')) {
-            $this->addAddress();
+            return $this->addAddress();
         } else if ($this->arg('cancel')) {
-            $this->cancelConfirmation();
+            return $this->cancelConfirmation();
         } else if ($this->arg('remove')) {
-            $this->removeAddress();
+            return $this->removeAddress();
         } else if ($this->arg('removeincoming')) {
-            $this->removeIncoming();
+            return $this->removeIncoming();
         } else if ($this->arg('newincoming')) {
-            $this->newIncoming();
+            return $this->newIncoming();
         } else if ($this->arg('confirm')) {
-            $this->confirmCode();
-        } else {
-            // TRANS: Message given submitting a form with an unknown action in SMS settings.
-            $this->showForm(_('Unexpected form submission.'));
+            return $this->confirmCode();
         }
+        // TRANS: Message given submitting a form with an unknown action in SMS settings.
+        throw new ClientException(_('Unexpected form submission.'));
     }
 
     /**
@@ -281,30 +258,26 @@ class SmssettingsAction extends SettingsAction
      */
     function savePreferences()
     {
-        $smsnotify = $this->boolean('smsnotify');
-
-        $user = common_current_user();
-
-        assert(!is_null($user)); // should already be checked
+        $user = $this->scoped->getUser();
 
         $user->query('BEGIN');
 
         $original = clone($user);
 
-        $user->smsnotify = $smsnotify;
+        $user->smsnotify = $this->boolean('smsnotify');
 
         $result = $user->update($original);
 
         if ($result === false) {
             common_log_db_error($user, 'UPDATE', __FILE__);
             // TRANS: Server error thrown on database error updating SMS preferences.
-            $this->serverError(_('Could not update user.'));
+            throw new ServerException(_('Could not update user.'));
         }
 
         $user->query('COMMIT');
 
         // TRANS: Confirmation message for successful SMS preferences save.
-        $this->showForm(_('SMS preferences saved.'), true);
+        return _('SMS preferences saved.');
     }
 
     /**
@@ -324,28 +297,24 @@ class SmssettingsAction extends SettingsAction
 
         // Some validation
 
-        if (!$sms) {
+        if (empty($sms)) {
             // TRANS: Message given saving SMS phone number without having provided one.
-            $this->showForm(_('No phone number.'));
-            return;
+            throw new ClientException(_('No phone number.'));
         }
 
-        if (!$carrier_id) {
+        if (empty($carrier_id)) {
             // TRANS: Message given saving SMS phone number without having selected a carrier.
-            $this->showForm(_('No carrier selected.'));
-            return;
+            throw new ClientException(_('No carrier selected.'));
         }
 
         $sms = common_canonical_sms($sms);
 
-        if ($user->sms == $sms) {
+        if ($user->sms === $sms) {
             // TRANS: Message given saving SMS phone number that is already set.
-            $this->showForm(_('That is already your phone number.'));
-            return;
+            throw new AlreadyFulfilledException(_('That is already your phone number.'));
         } else if ($this->smsExists($sms)) {
             // TRANS: Message given saving SMS phone number that is already set for another user.
-            $this->showForm(_('That phone number already belongs to another user.'));
-            return;
+            throw new ClientException(_('That phone number already belongs to another user.'));
         }
 
         $confirm = new Confirm_address();
@@ -353,7 +322,7 @@ class SmssettingsAction extends SettingsAction
         $confirm->address       = $sms;
         $confirm->address_extra = $carrier_id;
         $confirm->address_type  = 'sms';
-        $confirm->user_id       = $user->id;
+        $confirm->user_id       = $this->scoped->getID();
         $confirm->code          = common_confirmation_code(40);
 
         $result = $confirm->insert();
@@ -371,11 +340,9 @@ class SmssettingsAction extends SettingsAction
                          $carrier->toEmailAddress($sms));
 
         // TRANS: Message given saving valid SMS phone number that is to be confirmed.
-        $msg = _('A confirmation code was sent to the phone number you added. '.
+        return _('A confirmation code was sent to the phone number you added. '.
                  'Check your phone for the code and instructions '.
                  'on how to use it.');
-
-        $this->showForm($msg, true);
     }
 
     /**
@@ -390,29 +357,27 @@ class SmssettingsAction extends SettingsAction
         $sms     = $this->trimmed('sms');
         $carrier = $this->trimmed('carrier');
 
-        $confirm = $this->getConfirmation();
-
-        if (!$confirm) {
+        try {
+            $confirm = $this->getConfirmation();
+            if ($confirm->address != $sms) {
+                // TRANS: Message given canceling SMS phone number confirmation for the wrong phone number.
+                throw new ClientException(_('That is the wrong confirmation number.'));
+            }
+        } catch (NoResultException $e) {
             // TRANS: Message given canceling SMS phone number confirmation that is not pending.
-            $this->showForm(_('No pending confirmation to cancel.'));
-            return;
-        }
-        if ($confirm->address != $sms) {
-            // TRANS: Message given canceling SMS phone number confirmation for the wrong phone number.
-            $this->showForm(_('That is the wrong confirmation number.'));
-            return;
+            throw new AlreadyFulfilledException(_('No pending confirmation to cancel.'));
         }
 
         $result = $confirm->delete();
 
-        if (!$result) {
+        if ($result === false) {
             common_log_db_error($confirm, 'DELETE', __FILE__);
             // TRANS: Server error thrown on database error canceling SMS phone number confirmation.
-            $this->serverError(_('Could not delete SMS confirmation.'));
+            throw new ServerException(_('Could not delete SMS confirmation.'));
         }
 
         // TRANS: Message given after successfully canceling SMS phone number confirmation.
-        $this->showForm(_('SMS confirmation cancelled.'), true);
+        return _('SMS confirmation cancelled.');
     }
 
     /**
@@ -422,7 +387,7 @@ class SmssettingsAction extends SettingsAction
      */
     function removeAddress()
     {
-        $user = common_current_user();
+        $user = $this->scoped->getUser();
 
         $sms     = $this->arg('sms');
         $carrier = $this->arg('carrier');
@@ -432,8 +397,7 @@ class SmssettingsAction extends SettingsAction
         if ($user->sms != $sms) {
             // TRANS: Message given trying to remove an SMS phone number that is not
             // TRANS: registered for the active user.
-            $this->showForm(_('That is not your phone number.'));
-            return;
+            throw new ClientException(_('That is not your phone number.'));
         }
 
         $original = clone($user);
@@ -446,7 +410,7 @@ class SmssettingsAction extends SettingsAction
         $user->updateWithKeys($original);
 
         // TRANS: Message given after successfully removing a registered SMS phone number.
-        $this->showForm(_('The SMS phone number was removed.'), true);
+        return _('The SMS phone number was removed.');
     }
 
     /**
@@ -460,15 +424,13 @@ class SmssettingsAction extends SettingsAction
      */
     function smsExists($sms)
     {
-        $user = common_current_user();
-
         $other = User::getKV('sms', $sms);
 
-        if (!$other) {
+        if (!$other instanceof User) {
             return false;
-        } else {
-            return $other->id != $user->id;
         }
+
+        return !$this->scoped->sameAs($other->getProfile());
     }
 
     /**
@@ -519,15 +481,12 @@ class SmssettingsAction extends SettingsAction
     {
         $code = $this->trimmed('code');
 
-        if (!$code) {
+        if (empty($code)) {
             // TRANS: Message given saving SMS phone number confirmation code without having provided one.
-            $this->showForm(_('No code entered.'));
-            return;
+            throw new ClientException(_('No code entered.'));
         }
 
-        common_redirect(common_local_url('confirmaddress',
-                                         array('code' => $code)),
-                        303);
+        common_redirect(common_local_url('confirmaddress', array('code' => $code)), 303);
     }
 
     /**
@@ -541,8 +500,7 @@ class SmssettingsAction extends SettingsAction
 
         if (!$user->incomingemail) {
             // TRANS: Form validation error displayed when trying to remove an incoming e-mail address while no address has been set.
-            $this->showForm(_('No incoming email address.'));
-            return;
+            throw new ClientException(_('No incoming email address.'));
         }
 
         $orig = clone($user);
@@ -553,7 +511,7 @@ class SmssettingsAction extends SettingsAction
         $user->updateWithKeys($orig);
 
         // TRANS: Confirmation text after updating SMS settings.
-        $this->showForm(_('Incoming email address removed.'), true);
+        return _('Incoming email address removed.');
     }
 
     /**
@@ -565,7 +523,7 @@ class SmssettingsAction extends SettingsAction
      */
     function newIncoming()
     {
-        $user = common_current_user();
+        $user = $this->scoped->getUser();
 
         $orig = clone($user);
 
@@ -575,6 +533,6 @@ class SmssettingsAction extends SettingsAction
         $user->updateWithKeys($orig);
 
         // TRANS: Confirmation text after updating SMS settings.
-        $this->showForm(_('New incoming email address added.'), true);
+        return _('New incoming email address added.');
     }
 }
diff --git a/actions/startpage.php b/actions/startpage.php
deleted file mode 100644 (file)
index 9ce00d9..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-<?php
-/**
- * Startpage action. Decides what to show on the first page.
- */
-
-if (!defined('GNUSOCIAL')) { exit(1); }
-
-class StartpageAction extends ManagedAction
-{
-    function isReadOnly($args)
-    {
-        return true;
-    }
-
-    function showPage()
-    {
-        if (common_config('singleuser', 'enabled')) {
-            $user = User::singleUser();
-            common_redirect(common_local_url('showstream', array('nickname' => $user->nickname)), 303);
-        } elseif (common_config('public', 'localonly')) {
-            common_redirect(common_local_url('public'), 303);
-        } else {
-            common_redirect(common_local_url('networkpublic'), 303);
-        }
-    }
-}
index 231a697230601822f3eaf3c4ff2f28fad80de05e..b5734b3747ee38900339a480fc2858b25190a1c7 100644 (file)
@@ -28,9 +28,7 @@
  * @link      http://status.net/
  */
 
-if (!defined('STATUSNET') && !defined('LACONICA')) {
-    exit(1);
-}
+if (!defined('GNUSOCIAL')) { exit(1); }
 
 /**
  * A list of the user's subscriptions
@@ -60,7 +58,7 @@ class SubscriptionsAction extends GalleryAction
 
     function showPageNotice()
     {
-        if ($this->scoped instanceof Profile && $this->scoped->id === $this->target->id) {
+        if ($this->scoped instanceof Profile && $this->scoped->sameAs($this->getTarget())) {
             $this->element('p', null,
                            // TRANS: Page notice for page with an overview of all subscriptions
                            // TRANS: of the logged in user's own profile.
index 8a1494f1317ad469519b741700299d4bb4619537..0d4d68ffba1c4c7594ab12b90a75eb6b0c38ac52 100644 (file)
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 
-if (!defined('STATUSNET') && !defined('LACONICA')) { exit(1); }
-
-require_once(INSTALLDIR.'/lib/rssaction.php');
+if (!defined('GNUSOCIAL')) { exit(1); }
 
 // Formatting of RSS handled by Rss10Action
+
 class TagrssAction extends Rss10Action
 {
-    var $tag;
+    protected $tag;
 
-    function prepare($args) {
-        parent::prepare($args);
+    protected function doStreamPreparation()
+    {
         $tag = common_canonical_tag($this->trimmed('tag'));
         $this->tag = Notice_tag::getKV('tag', $tag);
-        if (!$this->tag) {
+        if (!$this->tag instanceof Notice_tag) {
             // TRANS: Client error when requesting a tag feed for a non-existing tag.
             $this->clientError(_('No such tag.'));
-        } else {
-            $this->notices = $this->getNotices($this->limit);
-            return true;
         }
     }
 
-    function getNotices($limit=0)
+    protected function getNotices()
     {
-        $tag = $this->tag;
-
-        if (is_null($tag)) {
-            return null;
-        }
-
-        $notice = Notice_tag::getStream($tag->tag)->getNotices(0, ($limit == 0) ? NOTICES_PER_PAGE : $limit);
-        return $notice->fetchAll();
+        $stream = Notice_tag::getStream($this->tag->tag)->getNotices(0, $this->limit);
+        return $stream->fetchAll();
     }
 
     function getChannel()
index 39abe3df26ff772e597a859eca0e5361f1214094..d30a40bafeebe5cf7e26d8570d785f11467b5789 100644 (file)
  * 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  Top
- * @package   StatusNet
- * @author    Evan Prodromou <evan@status.net>
- * @copyright 2010 StatusNet, Inc.
- * @license   http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0
- * @link      http://status.net/
- */
-
-if (!defined('STATUSNET')) {
-    // This check helps protect against security problems;
-    // your code file can't be executed directly from the web.
-    exit(1);
-}
-
-/**
- * An action to redirect to the top of the site
- *
  * @category  Action
- * @package   StatusNet
+ * @package   GNUsocial
  * @author    Evan Prodromou <evan@status.net>
+ * @author    Mikael Nordfeldth <mmn@hethane.se>
  * @copyright 2010 StatusNet, Inc.
- * @license   http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0
- * @link      http://status.net/
+ * @copyright 2015 Free Software Foundation, Inc.
+ * @license   https://www.gnu.org/licenses/agpl-3.0.html AGPL 3.0
+ * @link      https://gnu.io/social
  */
 
-class TopAction extends Action
-{
-    /**
-     * For initializing members of the class.
-     *
-     * @param array $argarray misc. arguments
-     *
-     * @return boolean true
-     */
+if (!defined('GNUSOCIAL')) { exit(1); }
 
-    function prepare($argarray)
-    {
-        parent::prepare($argarray);
-        return true;
-    }
-
-    /**
-     * Handler method
-     *
-     * @param array $argarray is ignored since it's now passed in in prepare()
-     *
-     * @return void
-     */
-
-    function handle($argarray=null)
+class TopAction extends ManagedAction
+{
+    public function showPage()
     {
         if (common_config('singleuser', 'enabled')) {
-            $url = common_local_url('showstream', array('nickname' => User::singleUserNickname()));
+            $user = User::singleUser();
+            common_redirect(common_local_url('showstream', array('nickname' => $user->getNickname())), 303);
+        } elseif (common_config('public', 'localonly')) {
+            common_redirect(common_local_url('public'), 303);
         } else {
-            $url = common_local_url('public');
+            common_redirect(common_local_url('networkpublic'), 303);
         }
-
-        // XXX: Permanent? I think so.
-
-        common_redirect($url, 301);
-
-        return;
     }
 }
index 69ad4c869066fb2434b117577560c4507b03ea37..c3e4ed50b2ac10cce4147394375562a3f271271c 100644 (file)
@@ -28,9 +28,7 @@
  * @link      http://status.net/
  */
 
-if (!defined('STATUSNET') && !defined('LACONICA')) {
-    exit(1);
-}
+if (!defined('GNUSOCIAL')) { exit(1); }
 
 /**
  * Miscellaneous settings actions
@@ -83,7 +81,7 @@ class UrlsettingsAction extends SettingsAction
      */
     function showContent()
     {
-        $user = common_current_user();
+        $user = $this->scoped->getUser();
 
         $this->elementStart('form', array('method' => 'post',
                                           'id' => 'form_settings_other',
@@ -154,31 +152,13 @@ class UrlsettingsAction extends SettingsAction
         $this->elementEnd('form');
     }
 
-    /**
-     * Handle a post
-     *
-     * Saves the changes to url-shortening prefs and shows a success or failure
-     * message.
-     *
-     * @return void
-     */
-    function handlePost()
+    protected function doPost()
     {
-        // CSRF protection
-        $token = $this->trimmed('token');
-        if (!$token || $token != common_session_token()) {
-            // TRANS: Client error displayed when the session token does not match or is not given.
-            $this->showForm(_('There was a problem with your session token. '.
-                              'Try again, please.'));
-            return;
-        }
-
         $urlshorteningservice = $this->trimmed('urlshorteningservice');
 
         if (!is_null($urlshorteningservice) && strlen($urlshorteningservice) > 50) {
             // TRANS: Form validation error for form "Other settings" in user profile.
-            $this->showForm(_('URL shortening service is too long (maximum 50 characters).'));
-            return;
+            throw new ClientException(_('URL shortening service is too long (maximum 50 characters).'));
         }
 
         $maxurllength = $this->trimmed('maxurllength');
@@ -195,9 +175,7 @@ class UrlsettingsAction extends SettingsAction
             throw new ClientException(_('Invalid number for maximum notice length.'));
         }
 
-        $user = common_current_user();
-
-        assert(!is_null($user)); // should already be checked
+        $user = $this->scoped->getUser();
 
         $user->query('BEGIN');
 
@@ -209,14 +187,15 @@ class UrlsettingsAction extends SettingsAction
 
         if ($result === false) {
             common_log_db_error($user, 'UPDATE', __FILE__);
+            $user->query('ROLLBACK');
             // TRANS: Server error displayed when "Other" settings in user profile could not be updated on the server.
-            $this->serverError(_('Could not update user.'));
+            throw new ServerException(_('Could not update user.'));
         }
 
         $prefs = User_urlshortener_prefs::getPrefs($user);
         $orig  = null;
 
-        if (empty($prefs)) {
+        if (!$prefs instanceof User_urlshortener_prefs) {
             $prefs = new User_urlshortener_prefs();
 
             $prefs->user_id = $user->id;
@@ -229,13 +208,14 @@ class UrlsettingsAction extends SettingsAction
         $prefs->maxurllength         = $maxurllength;
         $prefs->maxnoticelength      = $maxnoticelength;
 
-        if (!empty($orig)) {
+        if ($orig instanceof User_urlshortener_prefs) {
             $result = $prefs->update($orig);
         } else {
             $result = $prefs->insert();
         }
 
-        if (!$result) {
+        if ($result === null) {
+            $user->query('ROLLBACK');
             // TRANS: Server exception thrown in profile URL settings when preferences could not be saved.
             throw new ServerException(_('Error saving user URL shortening preferences.'));
         }
@@ -243,6 +223,6 @@ class UrlsettingsAction extends SettingsAction
         $user->query('COMMIT');
 
         // TRANS: Confirmation message after saving preferences.
-        $this->showForm(_('Preferences saved.'), true);
+        return _('Preferences saved.');
     }
 }
index fd112ba8ecba7af85d714077deee3dbce97beee9..d4756dffb5914a995eaa0feac300b48a3ab86eb3 100644 (file)
@@ -52,12 +52,12 @@ class UsergroupsAction extends GalleryAction
         if ($this->page == 1) {
             // TRANS: Page title for first page of groups for a user.
             // TRANS: %s is a nickname.
-            return sprintf(_('%s groups'), $this->user->nickname);
+            return sprintf(_('%s groups'), $this->getTarget()->getNickname());
         } else {
             // TRANS: Page title for all but the first page of groups for a user.
             // TRANS: %1$s is a nickname, %2$d is a page number.
             return sprintf(_('%1$s groups, page %2$d'),
-                           $this->user->nickname,
+                           $this->getTarget()->getNickname(),
                            $this->page);
         }
     }
@@ -82,14 +82,14 @@ class UsergroupsAction extends GalleryAction
             $offset = ($this->page-1) * GROUPS_PER_PAGE;
             $limit =  GROUPS_PER_PAGE + 1;
 
-            $groups = $this->user->getGroups($offset, $limit);
+            $groups = $this->getTarget()->getGroups($offset, $limit);
 
             if ($groups instanceof User_group) {
-                $gl = new GroupList($groups, $this->user, $this);
+                $gl = new GroupList($groups, $this->getTarget(), $this);
                 $cnt = $gl->show();
                 $this->pagination($this->page > 1, $cnt > GROUPS_PER_PAGE,
                               $this->page, 'usergroups',
-                              array('nickname' => $this->user->nickname));
+                              array('nickname' => $this->getTarget()->getNickname()));
             } else {
                 $this->showEmptyListMessage();
             }
@@ -102,11 +102,11 @@ class UsergroupsAction extends GalleryAction
     {
         // TRANS: Text on group page for a user that is not a member of any group.
         // TRANS: %s is a user nickname.
-        $message = sprintf(_('%s is not a member of any group.'), $this->user->nickname) . ' ';
+        $message = sprintf(_('%s is not a member of any group.'), $this->getTarget()->getNickname()) . ' ';
 
         if (common_logged_in()) {
             $current_user = common_current_user();
-            if ($this->user->id === $current_user->id) {
+            if ($this->scoped->sameAs($this->getTarget())) {
                 // TRANS: Text on group page for a user that is not a member of any group. This message contains
                 // TRANS: a Markdown link in the form [link text](link) and a variable that should not be changed.
                 $message .= _('Try [searching for groups](%%action.groupsearch%%) and joining them.');
@@ -119,7 +119,7 @@ class UsergroupsAction extends GalleryAction
 
     function showProfileBlock()
     {
-        $block = new AccountProfileBlock($this, $this->profile);
+        $block = new AccountProfileBlock($this, $this->getTarget());
         $block->show();
     }
 }
index 308db948918c079a9d4a1ce63463840c3b564a82..7bed1dd256bdf5db902e61841deea57dd86492fb 100644 (file)
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 
-if (!defined('STATUSNET') && !defined('LACONICA')) { exit(1); }
-
-require_once(INSTALLDIR.'/lib/rssaction.php');
+if (!defined('GNUSOCIAL')) { exit(1); }
 
 // Formatting of RSS handled by Rss10Action
 
-class UserrssAction extends Rss10Action
+class UserrssAction extends TargetedRss10Action
 {
-    var $tag  = null;
+    protected $tag = null;
 
-    function prepare($args)
+    protected function doStreamPreparation()
     {
-        parent::prepare($args);
-        $nickname   = $this->trimmed('nickname');
-        $this->user = User::getKV('nickname', $nickname);
-        $this->tag  = $this->trimmed('tag');
-
-        if (!$this->user) {
-            // TRANS: Client error displayed when user not found for an action.
-            $this->clientError(_('No such user.'));
-        }
+        parent::doStreamPreparation();
 
-        if (!empty($this->tag)) {
-            $this->notices = $this->getTaggedNotices();
-        } else {
-            $this->notices = $this->getNotices();
-        }
-
-        return true;
-    }
-
-    function getTaggedNotices()
-    {
-        $notice = $this->user->getTaggedNotices(
-            $this->tag,
-            0,
-            ($this->limit == 0) ? NOTICES_PER_PAGE : $this->limit,
-            0,
-            0
-        );
-
-        $notices = array();
-        while ($notice->fetch()) {
-            $notices[] = clone($notice);
-        }
-
-        return $notices;
+        $this->tag  = $this->trimmed('tag');
     }
 
-
-    function getNotices()
+    protected function getNotices()
     {
-        $notice = $this->user->getNotices(
-            0,
-            ($this->limit == 0) ? NOTICES_PER_PAGE : $this->limit
-        );
-
-        $notices = array();
-        while ($notice->fetch()) {
-            $notices[] = clone($notice);
+        if (!empty($this->tag)) {
+            $stream = $this->getTarget()->getTaggedNotices($this->tag, 0, $this->limit);
+            return $stream->fetchAll();
         }
+        // otherwise we fetch a normal user stream
 
-        return $notices;
+        $stream = $this->getTarget()->getNotices(0, $this->limit);
+        return $stream->fetchAll();
     }
 
     function getChannel()
     {
-        $user = $this->user;
-        $profile = $user->getProfile();
         $c = array('url' => common_local_url('userrss',
                                              array('nickname' =>
-                                                   $user->nickname)),
+                                                   $this->target->getNickname())),
                    // TRANS: Message is used as link title. %s is a user nickname.
-                   'title' => sprintf(_('%s timeline'), $user->nickname),
-                   'link' => $profile->profileurl,
+                   'title' => sprintf(_('%s timeline'), $this->target->getNickname()),
+                   'link' => $this->target->getUrl(),
                    // TRANS: Message is used as link description. %1$s is a username, %2$s is a site name.
                    'description' => sprintf(_('Updates from %1$s on %2$s!'),
-                                            $user->nickname, common_config('site', 'name')));
+                                            $this->target->getNickname(), common_config('site', 'name')));
         return $c;
     }
 
-    function getImage()
-    {
-        $profile = $this->user->getProfile();
-        return $profile->avatarUrl(AVATAR_PROFILE_SIZE);
-    }
-
     // override parent to add X-SUP-ID URL
 
-    function initRss($limit=0)
+    function initRss()
     {
-        $url = common_local_url('sup', null, null, $this->user->id);
+        $url = common_local_url('sup', null, null, $this->target->getID());
         header('X-SUP-ID: '.$url);
-        parent::initRss($limit);
+        parent::initRss();
     }
 
     function isReadOnly($args)
diff --git a/avatar/.gitignore b/avatar/.gitignore
deleted file mode 100644 (file)
index e69de29..0000000
diff --git a/background/.gitignore b/background/.gitignore
deleted file mode 100644 (file)
index e69de29..0000000
index 537c214a4c21991b54a20fea942a5c6a0ff2c325..9ef1e06b76a73d14d789c580dd8b6652553baf84 100644 (file)
@@ -110,8 +110,7 @@ class Conversation extends Managed_DataObject
     {
         $conv = new Conversation();
         $conv->id = $notice->conversation;
-        $conv->find(true);
-        if (!$conv instanceof Conversation) {
+        if (!$conv->find(true)) {
             common_debug('Conversation does not exist for notice ID: '.$notice->id);
             throw new NoResultException($conv);
         }
index ba516e462325698847294a89cf965bb7f395b214..2b6f86ed2728beb507d8a63bc09d7fec98de224f 100644 (file)
@@ -166,7 +166,7 @@ class File_redirection extends Managed_DataObject
      *                size (optional): byte size from Content-Length header
      *                time (optional): timestamp from Last-Modified header
      */
-    public function where($in_url, $discover=true) {
+    static function where($in_url, $discover=true) {
         // let's see if we know this...
         try {
             $a = File::getByUrl($in_url);
@@ -176,7 +176,7 @@ class File_redirection extends Managed_DataObject
             try {
                 $b = File_redirection::getByUrl($in_url);
                 // this is a redirect to $b->file_id
-                $a = File::getKV('id', $b->file_id);
+                $a = File::getByID($b->file_id);
                 return $a->url;
             } catch (NoResultException $e) {
                 // Oh well, let's keep going
@@ -186,10 +186,10 @@ class File_redirection extends Managed_DataObject
         if ($discover) {
             $ret = File_redirection::lookupWhere($in_url);
             return $ret;
-        } else {
-            // No manual dereferencing; leave the unknown URL as is.
-            return $in_url;
         }
+
+        // No manual dereferencing; leave the unknown URL as is.
+        return $in_url;
     }
 
     /**
@@ -206,7 +206,7 @@ class File_redirection extends Managed_DataObject
      * @param User $user whose shortening options to use; defaults to the current web session user
      * @return string
      */
-    function makeShort($long_url, $user=null)
+    static function makeShort($long_url, $user=null)
     {
         $canon = File_redirection::_canonUrl($long_url);
 
@@ -214,11 +214,7 @@ class File_redirection extends Managed_DataObject
 
         // Did we get one? Is it shorter?
 
-        if (!empty($short_url)) {
-            return $short_url;
-        } else {
-            return $long_url;
-        }
+        return !empty($short_url) ? $short_url : $long_url;
     }
 
     /**
@@ -235,18 +231,14 @@ class File_redirection extends Managed_DataObject
      * @return string
      */
 
-    function forceShort($long_url, $user)
+    static function forceShort($long_url, $user)
     {
         $canon = File_redirection::_canonUrl($long_url);
 
         $short_url = File_redirection::_userMakeShort($canon, $user, true);
 
         // Did we get one? Is it shorter?
-        if (!empty($short_url)) {
-            return $short_url;
-        } else {
-            return $long_url;
-        }
+        return !empty($short_url) ? $short_url : $long_url;
     }
 
     static function _userMakeShort($long_url, User $user=null, $force = false) {
index 6176ec43bc3f3a1bf568ce4effb3e66726697219..b3757448ade7e59f5d04d27fbff555154b8f6cb0 100644 (file)
@@ -56,34 +56,37 @@ class Foreign_link extends Managed_DataObject
     static function getByUserID($user_id, $service)
     {
         if (empty($user_id) || empty($service)) {
-            return null;
+            throw new ServerException('Empty user_id or service for Foreign_link::getByUserID');
         }
 
         $flink = new Foreign_link();
-
         $flink->service = $service;
         $flink->user_id = $user_id;
         $flink->limit(1);
 
-        $result = $flink->find(true);
+        if (!$flink->find(true)) {
+            throw new NoResultException($flink);
+        }
 
-        return empty($result) ? null : $flink;
+        return $flink;
     }
 
     static function getByForeignID($foreign_id, $service)
     {
         if (empty($foreign_id) || empty($service)) {
-            return null;
-        } else {
-            $flink = new Foreign_link();
-            $flink->service = $service;
-            $flink->foreign_id = $foreign_id;
-            $flink->limit(1);
+            throw new ServerException('Empty foreign_id or service for Foreign_link::getByForeignID');
+        }
 
-            $result = $flink->find(true);
+        $flink = new Foreign_link();
+        $flink->service = $service;
+        $flink->foreign_id = $foreign_id;
+        $flink->limit(1);
 
-            return empty($result) ? null : $flink;
+        if (!$flink->find(true)) {
+            throw new NoResultException($flink);
         }
+
+        return $flink;
     }
 
     function set_flags($noticesend, $noticerecv, $replysync, $friendsync)
@@ -124,21 +127,21 @@ class Foreign_link extends Managed_DataObject
 
         $fuser->limit(1);
 
-        if ($fuser->find(true)) {
-            return $fuser;
+        if (!$fuser->find(true)) {
+            throw new NoResultException($fuser);
         }
 
-        return null;
+        return $fuser;
     }
 
     function getUser()
     {
-        return User::getKV($this->user_id);
+        return Profile::getByID($this->user_id)->getUser();
     }
 
     function getProfile()
     {
-        return Profile::getKV('id', $this->user_id);
+        return Profile::getByID($this->user_id);
     }
 
     // Make sure we only ever delete one record at a time
index c1739d318a08737cedccfec1a8af17b316ee9e71..1f6c77851d8768ef2275ec6fb52dea004dc3b414 100644 (file)
@@ -41,33 +41,39 @@ class Foreign_user extends Managed_DataObject
         );
     }
 
-    static function getForeignUser($id, $service) {
+    static function getForeignUser($id, $service)
+    {
+        if (empty($id) || empty($service)) {
+            throw new ServerException('Empty foreign user id or service for Foreign_user::getForeignUser');
+        }
 
         $fuser = new Foreign_user();
-
         $fuser->id      = $id;
         $fuser->service = $service;
-
         $fuser->limit(1);
 
-        $result = $fuser->find(true);
+        if (!$fuser->find(true)) {
+            throw new NoResultException($fuser);
+        }
 
-        return empty($result) ? null : $fuser;
+        return $fuser;
     }
 
     static function getByNickname($nickname, $service)
     {
         if (empty($nickname) || empty($service)) {
-            return null;
-        } else {
-            $fuser = new Foreign_user();
-           $fuser->service = $service;
-           $fuser->nickname = $nickname;
-            $fuser->limit(1);
+            throw new ServerException('Empty nickname or service for Foreign_user::getByNickname');
+        }
 
-            $result = $fuser->find(true);
+        $fuser = new Foreign_user();
+        $fuser->service = $service;
+        $fuser->nickname = $nickname;
+        $fuser->limit(1);
 
-            return empty($result) ? null : $fuser;
+        if (!$fuser->find(true)) {
+            throw new NoResultException($fuser);
         }
+
+        return $fuser;
     }
 }
index 9e95102d8503753a034bc28ee9fd53da391436cd..1cebd4c40c3a777bbb31b95ab8dcf3230485c0f2 100644 (file)
@@ -50,7 +50,7 @@ class Local_group extends Managed_DataObject
         $group->find(true);
         if (!$group instanceof User_group) {
             common_log(LOG_ERR, 'User_group does not exist for Local_group: '.$this->group_id);
-            throw new NoResultException($group);
+            throw new NoSuchGroupException(array('id' => $this->group_id));
         }
         return $group;
     }
index c1f6f644db010d9e85e4d121b73474f3cb547724..41ce715210bec85bcf8f4cf314475a99a34c084c 100644 (file)
@@ -74,7 +74,7 @@ class Memcached_DataObject extends Safe_DataObject
     {
         $obj = new $cls;
 
-        // php-compatible, for settype(), datatype
+        // PHP compatible datatype for settype() below
         $colType = $obj->columnType($keyCol);
 
         if (!in_array($colType, array('integer', 'int'))) {
index 8c9957958b943a9ef9cac8a8c289549a520e9df8..0d0933115e74615ac24f73ccfec7fe79592b2719 100644 (file)
@@ -65,10 +65,6 @@ class Notice extends Managed_DataObject
     public $is_local;                        // int(4)
     public $source;                          // varchar(32)
     public $conversation;                    // int(4)
-    public $lat;                             // decimal(10,7)
-    public $lon;                             // decimal(10,7)
-    public $location_id;                     // int(4)
-    public $location_ns;                     // int(4)
     public $repeat_of;                       // int(4)
     public $verb;                            // varchar(191)   not 255 because utf8mb4 takes more space
     public $object_type;                     // varchar(191)   not 255 because utf8mb4 takes more space
@@ -93,10 +89,6 @@ class Notice extends Managed_DataObject
                 'is_local' => array('type' => 'int', 'size' => 'tiny', 'default' => 0, 'description' => 'notice was generated by a user'),
                 'source' => array('type' => 'varchar', 'length' => 32, 'description' => 'source of comment, like "web", "im", or "clientname"'),
                 'conversation' => array('type' => 'int', 'description' => 'id of root notice in this conversation'),
-                'lat' => array('type' => 'numeric', 'precision' => 10, 'scale' => 7, 'description' => 'latitude'),
-                'lon' => array('type' => 'numeric', 'precision' => 10, 'scale' => 7, 'description' => 'longitude'),
-                'location_id' => array('type' => 'int', 'description' => 'location id if possible'),
-                'location_ns' => array('type' => 'int', 'description' => 'namespace for location'),
                 'repeat_of' => array('type' => 'int', 'description' => 'notice this is a repeat of'),
                 'object_type' => array('type' => 'varchar', 'length' => 191, 'description' => 'URI representing activity streams object type', 'default' => 'http://activitystrea.ms/schema/1.0/note'),
                 'verb' => array('type' => 'varchar', 'length' => 191, 'description' => 'URI representing activity streams verb', 'default' => 'http://activitystrea.ms/schema/1.0/post'),
@@ -196,6 +188,7 @@ class Notice extends Managed_DataObject
             // Clear related records
 
             $this->clearReplies();
+            $this->clearLocation();
             $this->clearRepeats();
             $this->clearTags();
             $this->clearGroupInboxes();
@@ -523,18 +516,13 @@ class Notice extends Managed_DataObject
 
         // Handle repeat case
 
-        if (isset($repeat_of)) {
+        if (!empty($options['repeat_of'])) {
 
             // Check for a private one
 
-            $repeat = Notice::getKV('id', $repeat_of);
+            $repeat = Notice::getByID($options['repeat_of']);
 
-            if (!($repeat instanceof Notice)) {
-                // TRANS: Client exception thrown in notice when trying to repeat a missing or deleted notice.
-                throw new ClientException(_('Cannot repeat; original notice is missing or deleted.'));
-            }
-
-            if ($profile->id == $repeat->profile_id) {
+            if ($profile->sameAs($repeat->getProfile())) {
                 // TRANS: Client error displayed when trying to repeat an own notice.
                 throw new ClientException(_('You cannot repeat your own notice.'));
             }
@@ -610,12 +598,13 @@ class Notice extends Managed_DataObject
             if (empty($notice->conversation) and !empty($options['conversation'])) {
                 $conv = Conversation::getKV('uri', $options['conversation']);
                 if ($conv instanceof Conversation) {
-                    common_debug('Conversation stitched together from (probably) reply to unknown remote user. Activity creation time ('.$notice->created.') should maybe be compared to conversation creation time ('.$conv->created.').');
+                    common_debug('Conversation stitched together from (probably) reply to unknown remote user. Activity creation time ('.$notice->created.') should maybe be compared to conversation creation time ('.$conv->created.').');
                     $notice->conversation = $conv->id;
                 } else {
                     // Conversation URI was not found, so we must create it. But we can't create it
                     // until we have a Notice ID because of the database layout...
-                    $notice->tmp_conv_uri = $options['conversation'];
+                    // $options['conversation'] will be used later after the $notice->insert();
+                    common_debug('Conversation URI not found, so we have to create it after inserting this Notice: '.$options['conversation']);
                 }
             } else {
                 // If we're not using the attached conversation URI let's remove it
@@ -625,14 +614,15 @@ class Notice extends Managed_DataObject
             }
         }
 
+        $notloc = new Notice_location();
         if (!empty($lat) && !empty($lon)) {
-            $notice->lat = $lat;
-            $notice->lon = $lon;
+            $notloc->lat = $lat;
+            $notloc->lon = $lon;
         }
 
         if (!empty($location_ns) && !empty($location_id)) {
-            $notice->location_id = $location_id;
-            $notice->location_ns = $location_ns;
+            $notloc->location_id = $location_id;
+            $notloc->location_ns = $location_ns;
         }
 
         if (!empty($rendered)) {
@@ -671,12 +661,19 @@ class Notice extends Managed_DataObject
             // XXX: some of these functions write to the DB
 
             try {
-                $notice->insert();  // throws exception on failure
+                $notice->insert();  // throws exception on failure, if successful we have an ->id
+
+                if (($notloc->lat && $notloc->lon) || ($notloc->location_id && $notloc->location_ns)) {
+                    $notloc->notice_id = $notice->getID();
+                    $notloc->insert();  // store the notice location if it had any information
+                }
+
                 // If it's not part of a conversation, it's
                 // the beginning of a new conversation.
                 if (empty($notice->conversation)) {
                     $orig = clone($notice);
                     // $act->context->conversation will be null if it was not provided
+
                     $conv = Conversation::create($notice, $options['conversation']);
                     $notice->conversation = $conv->id;
                     $notice->update($orig);
@@ -853,17 +850,28 @@ class Notice extends Managed_DataObject
             if (is_null($scope)) {
                 $scope = $reply->scope;
             }
+        } else {
+            // If we don't know the reply, we might know the conversation!
+            // This will happen if a known remote user replies to an
+            // unknown remote user - within a known conversation.
+            if (empty($stored->conversation) and !empty($act->context->conversation)) {
+                $conv = Conversation::getKV('uri', $act->context->conversation);
+                if ($conv instanceof Conversation) {
+                    common_debug('Conversation stitched together from (probably) a reply activity to unknown remote user. Activity creation time ('.$stored->created.') should maybe be compared to conversation creation time ('.$conv->created.').');
+                    $stored->conversation = $conv->id;
+                } else {
+                    // Conversation URI was not found, so we must create it. But we can't create it
+                    // until we have a Notice ID because of the database layout...
+                    // $options['conversation'] will be used later after the $stored->insert();
+                    common_debug('Conversation URI from activity context not found, so we have to create it after inserting this Notice: '.$act->context->conversation);
+                }
+            }
         }
 
+        $notloc = null;
         if ($act->context instanceof ActivityContext) {
-            $location = $act->context->location;
-            if ($location) {
-                $stored->lat = $location->lat;
-                $stored->lon = $location->lon;
-                if ($location->location_id) {
-                    $stored->location_ns = $location->location_ns;
-                    $stored->location_id = $location->location_id;
-                }
+            if ($act->context->location instanceof Location) {
+                $notloc = Notice_location::fromLocation($act->context->location);
             }
         } else {
             $act->context = new ActivityContext();
@@ -890,6 +898,12 @@ class Notice extends Managed_DataObject
 
             try {
                 $stored->insert();    // throws exception on error
+
+                if ($notloc instanceof Notice_location) {
+                    $notloc->notice_id = $stored->getID();
+                    $notloc->insert();
+                }
+
                 $orig = clone($stored); // for updating later in this try clause
 
                 $object = null;
@@ -898,10 +912,11 @@ class Notice extends Managed_DataObject
                     throw new ServerException('Unsuccessful call to StoreActivityObject '.$stored->uri . ': '.$act->asString());
                 }
 
-                // If it's not part of a conversation, it's
-                // the beginning of a new conversation.
+                // If it's not part of a conversation, it's the beginning
+                // of a new one (or belongs to a previously unknown URI).
                 if (empty($stored->conversation)) {
                     // $act->context->conversation will be null if it was not provided
+                    common_debug('Creating a new conversation for stored notice ID='.$stored->getID().' with URI: '.$act->context->conversation);
                     $conv = Conversation::create($stored, $act->context->conversation);
                     $stored->conversation = $conv->id;
                 }
@@ -1203,17 +1218,15 @@ class Notice extends Managed_DataObject
            $this->_attachments[$this->id] = $attachments;
        }
 
-    function publicStream($offset=0, $limit=20, $since_id=0, $max_id=0)
+    static function publicStream($offset=0, $limit=20, $since_id=null, $max_id=null)
     {
         $stream = new PublicNoticeStream();
         return $stream->getNotices($offset, $limit, $since_id, $max_id);
     }
 
-
-    function conversationStream($id, $offset=0, $limit=20, $since_id=0, $max_id=0)
+    static function conversationStream($id, $offset=0, $limit=20, $since_id=null, $max_id=null)
     {
         $stream = new ConversationNoticeStream($id);
-
         return $stream->getNotices($offset, $limit, $since_id, $max_id);
     }
 
@@ -1225,18 +1238,17 @@ class Notice extends Managed_DataObject
      */
     function hasConversation()
     {
-        if (!empty($this->conversation)) {
-            $conversation = Notice::conversationStream(
-                $this->conversation,
-                1,
-                1
-            );
-
-            if ($conversation->N > 0) {
-                return true;
-            }
+        if (empty($this->conversation)) {
+            // this notice is not part of a conversation apparently
+            // FIXME: all notices should have a conversation value, right?
+            return false;
         }
-        return false;
+
+        $stream = new ConversationNoticeStream($this->conversation);
+        $notice = $stream->getNotices(/*offset*/ 1, /*limit*/ 1);
+
+        // if our "offset 1, limit 1" query got a result, return true else false
+        return $notice->N > 0;
     }
 
     /**
@@ -1271,8 +1283,7 @@ class Notice extends Managed_DataObject
             $root = new Notice;
             $root->conversation = $this->conversation;
             $root->orderBy('notice.created ASC');
-            $root->find();
-            $root->fetch();
+            $root->find(true);  // true means "fetch first result"
             $root->free();
             return $root;
         }
@@ -1660,32 +1671,22 @@ class Notice extends Managed_DataObject
     protected $_replies = array();
 
     /**
-     * Pull the complete list of @-reply targets for this notice.
+     * Pull the complete list of @-mentioned profile IDs for this notice.
      *
      * @return array of integer profile ids
      */
     function getReplies()
     {
-        if (isset($this->_replies[$this->id])) {
-            return $this->_replies[$this->id];
-        }
-
-        $replyMap = Reply::listGet('notice_id', array($this->id));
-
-        $ids = array();
-
-        foreach ($replyMap[$this->id] as $reply) {
-            $ids[] = $reply->profile_id;
+        if (!isset($this->_replies[$this->getID()])) {
+            $mentions = Reply::multiGet('notice_id', array($this->getID()));
+            $this->_replies[$this->getID()] = $mentions->fetchAll('profile_id');
         }
-
-        $this->_replies[$this->id] = $ids;
-
-        return $ids;
+        return $this->_replies[$this->getID()];
     }
 
     function _setReplies($replies)
     {
-        $this->_replies[$this->id] = $replies;
+        $this->_replies[$this->getID()] = $replies;
     }
 
     /**
@@ -1844,7 +1845,11 @@ class Notice extends Managed_DataObject
                 // This is not a reply to something
             }
 
-            $ctx->location = $this->getLocation();
+            try {
+                $ctx->location = Notice_location::locFromStored($this);
+            } catch (ServerException $e) {
+                $ctx->location = null;
+            }
 
             $conv = null;
 
@@ -2090,23 +2095,6 @@ class Notice extends Managed_DataObject
         return ($contentlimit > 0 && !empty($content) && (mb_strlen($content) > $contentlimit));
     }
 
-    function getLocation()
-    {
-        $location = null;
-
-        if (!empty($this->location_id) && !empty($this->location_ns)) {
-            $location = Location::fromId($this->location_id, $this->location_ns);
-        }
-
-        if (is_null($location)) { // no ID, or Location::fromId() failed
-            if (!empty($this->lat) && !empty($this->lon)) {
-                $location = Location::fromLatLon($this->lat, $this->lon);
-            }
-        }
-
-        return $location;
-    }
-
     /**
      * Convenience function for posting a repeat of an existing message.
      *
@@ -2193,7 +2181,7 @@ class Notice extends Managed_DataObject
         return $notice->fetchAll('id');
     }
 
-    function locationOptions($lat, $lon, $location_id, $location_ns, $profile = null)
+    static function locationOptions($lat, $lon, $location_id, $location_ns, $profile = null)
     {
         $options = array();
 
@@ -2277,6 +2265,16 @@ class Notice extends Managed_DataObject
         $reply->free();
     }
 
+    function clearLocation()
+    {
+        $loc = new Notice_location();
+        $loc->notice_id = $this->id;
+
+        if ($loc->find()) {
+            $loc->delete();
+        }
+    }
+
     function clearFiles()
     {
         $f2p = new File_to_post();
@@ -2885,4 +2883,51 @@ class Notice extends Managed_DataObject
             $notice->_setReplies($ids);
         }
     }
+
+    static public function beforeSchemaUpdate()
+    {
+        $table = strtolower(get_called_class());
+        $schema = Schema::get();
+        $schemadef = $schema->getTableDef($table);
+
+        // 2015-09-04 We move Notice location data to Notice_location
+        // First we see if we have to do this at all
+        if (!isset($schemadef['fields']['lat'])
+                && !isset($schemadef['fields']['lon'])
+                && !isset($schemadef['fields']['location_id'])
+                && !isset($schemadef['fields']['location_ns'])) {
+            // We have already removed the location fields, so no need to migrate.
+            return;
+        }
+        // Then we make sure the Notice_location table is created!
+        $schema->ensureTable('notice_location', Notice_location::schemaDef());
+
+        // Then we continue on our road to migration!
+        echo "\nFound old $table table, moving location data to 'notice_location' table... (this will probably take a LONG time, but can be aborted and continued)";
+
+        $notice = new Notice();
+        $notice->query(sprintf('SELECT id, lat, lon, location_id, location_ns FROM %1$s ' .
+                             'WHERE lat IS NOT NULL ' .
+                                'OR lon IS NOT NULL ' .
+                                'OR location_id IS NOT NULL ' .
+                                'OR location_ns IS NOT NULL',
+                             $schema->quoteIdentifier($table)));
+        print "\nFound {$notice->N} notices with location data, inserting";
+        while ($notice->fetch()) {
+            $notloc = Notice_location::getKV('notice_id', $notice->id);
+            if ($notloc instanceof Notice_location) {
+                print "-";
+                continue;
+            }
+            $notloc = new Notice_location();
+            $notloc->notice_id = $notice->id;
+            $notloc->lat= $notice->lat;
+            $notloc->lon= $notice->lon;
+            $notloc->location_id= $notice->location_id;
+            $notloc->location_ns= $notice->location_ns;
+            $notloc->insert();
+            print ".";
+        }
+        print "\n";
+    }
 }
diff --git a/classes/Notice_location.php b/classes/Notice_location.php
new file mode 100644 (file)
index 0000000..1574414
--- /dev/null
@@ -0,0 +1,75 @@
+<?php
+/**
+ * Table Definition for notice_location
+ */
+
+class Notice_location extends Managed_DataObject
+{
+    public $__table = 'notice_location';     // table name
+    public $notice_id;                       // int(4)  primary_key not_null
+    public $lat;                             // decimal(10,7)
+    public $lon;                             // decimal(10,7)
+    public $location_id;                     // int(4)
+    public $location_ns;                     // int(4)
+    public $modified;                        // timestamp()   not_null default_CURRENT_TIMESTAMP
+
+    public static function schemaDef()
+    {
+        return array(
+            'fields' => array(
+                'notice_id' => array('type' => 'int', 'not null' => true, 'description' => 'notice that is the reply'),
+                'lat' => array('type' => 'numeric', 'precision' => 10, 'scale' => 7, 'description' => 'latitude'),
+                'lon' => array('type' => 'numeric', 'precision' => 10, 'scale' => 7, 'description' => 'longitude'),
+                'location_id' => array('type' => 'int', 'description' => 'location id if possible'),
+                'location_ns' => array('type' => 'int', 'description' => 'namespace for location'),
+                'modified' => array('type' => 'timestamp', 'not null' => true, 'description' => 'date this record was modified'),
+            ),
+            'primary key' => array('notice_id'),
+            'foreign keys' => array(
+                'notice_location_notice_id_fkey' => array('notice', array('notice_id' => 'id')),
+            ),
+            'indexes' => array(
+                'notice_location_location_id_idx' => array('location_id'),
+            ),
+        );
+    }    
+
+    static function locFromStored(Notice $stored)
+    {
+        $loc = new Notice_location();
+        $loc->notice_id = $stored->getID();
+        if (!$loc->find(true)) {
+            throw new NoResultException($loc);
+        }
+        return $loc->asLocation();
+    }
+
+    static function fromLocation(Location $location)
+    {
+        $notloc = new Notice_location();
+        $notloc->lat = $location->lat;
+        $notloc->lon = $location->lon;
+        $notloc->location_ns = $location->location_ns;
+        $notloc->location_id = $location->location_id;
+        return $notloc;
+    }
+
+    public function asLocation()
+    {
+        $location = null;
+
+        if (!empty($this->location_id) && !empty($this->location_ns)) {
+            $location = Location::fromId($this->location_id, $this->location_ns);
+        }
+
+        if (is_null($location)) { // no ID, or Location::fromId() failed
+            $location = Location::fromLatLon($this->lat, $this->lon);
+        }
+
+        if (is_null($location)) {
+            throw new ServerException('Location could not be looked up from existing data.');
+        }
+
+        return $location;
+    }
+}
index b5ba00caa9e24dc625e61efb88ab85e5962baedf..09f9ca71d109933db6509cb883ec1bee866d222c 100644 (file)
@@ -138,6 +138,18 @@ class Profile extends Managed_DataObject
         return true;
     }
 
+    // Returns false if the user has no password (which will always
+    // be the case for remote users). This can be the case for OpenID
+    // logins or other mechanisms which don't store a password hash.
+    public function hasPassword()
+    {
+        try {
+            return !empty($this->getUser()->hasPassword());
+        } catch (NoSuchUserException $e) {
+            return false;
+        }
+    }
+
     public function getObjectType()
     {
         // FIXME: More types... like peopletags and whatever
@@ -242,6 +254,11 @@ class Profile extends Managed_DataObject
         return null;
     }
 
+    function getReplies($offset=0, $limit=NOTICES_PER_PAGE, $since_id=0, $before_id=0)
+    {
+        return Reply::stream($this->getID(), $offset, $limit, $since_id, $before_id);
+    }
+
     function getTaggedNotices($tag, $offset=0, $limit=NOTICES_PER_PAGE, $since_id=0, $max_id=0)
     {
         $stream = new TaggedProfileNoticeStream($this, $tag);
@@ -860,6 +877,11 @@ class Profile extends Managed_DataObject
 
     function delete($useWhere=false)
     {
+        // just in case it hadn't been done before... (usually set before adding deluser to queue handling!)
+        if (!$this->hasRole(Profile_role::DELETED)) {
+            $this->grantRole(Profile_role::DELETED);
+        }
+
         $this->_deleteNotices();
         $this->_deleteSubscriptions();
         $this->_deleteTags();
@@ -1390,6 +1412,11 @@ class Profile extends Managed_DataObject
         return $this->fullname;
     }
 
+    public function getHomepage()
+    {
+        return $this->homepage;
+    }
+
     public function getDescription()
     {
         return $this->bio;
@@ -1566,6 +1593,11 @@ class Profile extends Managed_DataObject
         return $this;
     }
 
+    public function sameAs(Profile $other)
+    {
+        return $this->getID() === $other->getID();
+    }
+
     /**
      * This will perform shortenLinks with the connected User object.
      *
@@ -1613,4 +1645,9 @@ class Profile extends Managed_DataObject
     public function setPref($namespace, $topic, $data) {
         return Profile_prefs::setData($this, $namespace, $topic, $data);
     }
+
+    public function getConnectedApps($offset=0, $limit=null)
+    {
+        return $this->getUser()->getConnectedApps($offset, $limit);
+    }
 }
index 6d6f49bedc634abf174d6d5d663da38e18d35302..8034e68ccf728cd73adba3c80874e41029b1e535 100644 (file)
@@ -2,22 +2,15 @@
 /**
  * Table Definition for profile_tag
  */
-require_once INSTALLDIR.'/classes/Memcached_DataObject.php';
 
 class Profile_tag extends Managed_DataObject
 {
-    ###START_AUTOCODE
-    /* the code below is auto generated do not remove the above tag */
-
     public $__table = 'profile_tag';                     // table name
     public $tagger;                          // int(4)  primary_key not_null
     public $tagged;                          // int(4)  primary_key not_null
     public $tag;                             // varchar(64)  primary_key not_null
     public $modified;                        // timestamp()   not_null default_CURRENT_TIMESTAMP
 
-    /* the code above is auto generated do not remove the tag below */
-    ###END_AUTOCODE
-
     public static function schemaDef()
     {
         return array(
@@ -52,6 +45,16 @@ class Profile_tag extends Managed_DataObject
         return Profile_list::pkeyGet(array('tagger' => $this->tagger, 'tag' => $this->tag));
     }
 
+    static function getSelfTagsArray(Profile $target)
+    {
+        return self::getTagsArray($target->getID(), $target->getID(), $target);
+    }
+
+    static function setSelfTags(Profile $target, array $newtags, array $privacy=array())
+    {
+        return self::setTags($target->getID(), $target->getID(), $newtags, $privacy);
+    }
+
     static function getTags($tagger, $tagged, $auth_user=null) {
 
         $profile_list = new Profile_list();
@@ -88,7 +91,7 @@ class Profile_tag extends Managed_DataObject
         return $profile_list;
     }
 
-    static function getTagsArray($tagger, $tagged, $auth_user_id=null)
+    static function getTagsArray($tagger, $tagged, Profile $scoped=null)
     {
         $ptag = new Profile_tag();
 
@@ -100,7 +103,7 @@ class Profile_tag extends Managed_DataObject
                        'and   profile_tag.tagged = %d ',
                        $tagger, $tagged);
 
-        if ($auth_user_id != $tagger) {
+        if (!$scoped instanceof Profile || $scoped->getID() !== $tagger) {
             $qry .= 'and profile_list.private = 0';
         }
 
@@ -115,10 +118,10 @@ class Profile_tag extends Managed_DataObject
         return $tags;
     }
 
-    static function setTags($tagger, $tagged, $newtags, $privacy=array()) {
+    static function setTags($tagger, $tagged, array $newtags, array $privacy=array()) {
 
         $newtags = array_unique($newtags);
-        $oldtags = self::getTagsArray($tagger, $tagged, $tagger);
+        $oldtags = self::getTagsArray($tagger, $tagged, Profile::getByID($tagger));
 
         $ptag = new Profile_tag();
 
@@ -149,19 +152,18 @@ class Profile_tag extends Managed_DataObject
                                            'tag' => $tag));
 
         # if tag already exists, return it
-        if(!empty($ptag)) {
+        if ($ptag instanceof Profile_tag) {
             return $ptag;
         }
 
-        $tagger_profile = Profile::getKV('id', $tagger);
-        $tagged_profile = Profile::getKV('id', $tagged);
+        $tagger_profile = Profile::getByID($tagger);
+        $tagged_profile = Profile::getByID($tagged);
 
         if (Event::handle('StartTagProfile', array($tagger_profile, $tagged_profile, $tag))) {
 
             if (!$tagger_profile->canTag($tagged_profile)) {
                 // TRANS: Client exception thrown trying to set a tag for a user that cannot be tagged.
                 throw new ClientException(_('You cannot tag this user.'));
-                return false;
             }
 
             $tags = new Profile_list();
@@ -174,7 +176,6 @@ class Profile_tag extends Managed_DataObject
                                                     'which is the maximum allowed number of tags. ' .
                                                     'Try using or deleting some existing tags.'),
                                                     common_config('peopletag', 'maxtags')));
-                return false;
             }
 
             $plist = new Profile_list();
@@ -188,7 +189,6 @@ class Profile_tag extends Managed_DataObject
                                                     'which is the maximum allowed number. ' .
                                                     'Try unlisting others first.'),
                                                     common_config('peopletag', 'maxpeople'), $tag));
-                return false;
             }
 
             $newtag = new Profile_tag();
@@ -199,9 +199,9 @@ class Profile_tag extends Managed_DataObject
 
             $result = $newtag->insert();
 
-
             if (!$result) {
                 common_log_db_error($newtag, 'INSERT', __FILE__);
+                $plist->query('ROLLBACK');
                 return false;
             }
 
@@ -212,7 +212,6 @@ class Profile_tag extends Managed_DataObject
                 $newtag->delete();
                 $profile_list->delete();
                 throw $e;
-                return false;
             }
 
             $profile_list->taggedCount(true);
@@ -233,20 +232,17 @@ class Profile_tag extends Managed_DataObject
         if (Event::handle('StartUntagProfile', array($ptag))) {
             $orig = clone($ptag);
             $result = $ptag->delete();
-            if (!$result) {
+            if ($result === false) {
                 common_log_db_error($this, 'DELETE', __FILE__);
                 return false;
             }
             Event::handle('EndUntagProfile', array($orig));
-            if ($result) {
-                $profile_list = Profile_list::pkeyGet(array('tag' => $tag, 'tagger' => $tagger));
-                if (!empty($profile_list)) {
-                    $profile_list->taggedCount(true);
-                }
-                self::blowCaches($tagger, $tagged);
-                return true;
+            $profile_list = Profile_list::pkeyGet(array('tag' => $tag, 'tagger' => $tagger));
+            if (!empty($profile_list)) {
+                $profile_list->taggedCount(true);
             }
-            return false;
+            self::blowCaches($tagger, $tagged);
+            return true;
         }
     }
 
index 3a7d05adef7249d203a7dee5c24f2c64f39392e2..d41c53e0e068dac5a264030d70eaacd5f388d747 100644 (file)
@@ -40,7 +40,7 @@ class Queue_item extends Managed_DataObject
      * @param mixed $transports name of a single queue or array of queues to pull from
      *                          If not specified, checks all queues in the system.
      */
-    static function top($transports=null) {
+    static function top($transports=null, array $ignored_transports=array()) {
 
         $qi = new Queue_item();
         if ($transports) {
@@ -52,6 +52,11 @@ class Queue_item extends Managed_DataObject
                 $qi->transport = $transports;
             }
         }
+        if (!empty($ignored_transports)) {
+            // @fixme use safer escaping
+            $list = implode("','", array_map(array($qi, 'escape'), $ignored_transports));
+            $qi->whereAdd("transport NOT IN ('$list')");
+        }
         $qi->orderBy('created');
         $qi->whereAdd('claimed is null');
 
index 36686d0c76d6cb579edebba1af0eb72bca3b27d4..d3405e6581c26213a9d658e5e8408ef9c2912a71 100644 (file)
@@ -55,10 +55,9 @@ class Reply extends Managed_DataObject
         return $result;
     }
 
-    function stream($user_id, $offset=0, $limit=NOTICES_PER_PAGE, $since_id=0, $max_id=0)
+    static function stream($user_id, $offset=0, $limit=NOTICES_PER_PAGE, $since_id=0, $max_id=0)
     {
         $stream = new ReplyNoticeStream($user_id);
-
         return $stream->getNotices($offset, $limit, $since_id, $max_id);
     }
 }
index 878fcf5796968028b7464b441a00aeb9e1eaf2a2..a60293e2158e9bf8b42ff6f01ff079b1a9056c1b 100644 (file)
@@ -47,10 +47,10 @@ class Subscription_queue extends Managed_DataObject
         return $rq;
     }
 
-    public function exists(Profile $subscriber, Profile $other)
+    static function exists(Profile $subscriber, Profile $other)
     {
-        $sub = Subscription_queue::pkeyGet(array('subscriber' => $subscriber->id,
-                                                 'subscribed' => $other->id));
+        $sub = Subscription_queue::pkeyGet(array('subscriber' => $subscriber->getID(),
+                                                 'subscribed' => $other->getID()));
         return ($sub instanceof Subscription_queue);
     }
 
index 3efaa5e72131b5ba7cda2262ba4e4879d0277b1d..e33c83e89cf0f74f3c07957a4caec50e94f84624 100644 (file)
@@ -42,7 +42,6 @@ class User extends Managed_DataObject
     public $emailnotifynudge;                // tinyint(1)   default_1
     public $emailnotifymsg;                  // tinyint(1)   default_1
     public $emailnotifyattn;                 // tinyint(1)   default_1
-    public $emailmicroid;                    // tinyint(1)   default_1
     public $language;                        // varchar(50)
     public $timezone;                        // varchar(50)
     public $emailpost;                       // tinyint(1)   default_1
@@ -77,7 +76,6 @@ class User extends Managed_DataObject
                 'emailnotifynudge' => array('type' => 'int', 'size' => 'tiny', 'default' => 1, 'description' => 'Notify by email of nudges'),
                 'emailnotifymsg' => array('type' => 'int', 'size' => 'tiny', 'default' => 1, 'description' => 'Notify by email of direct messages'),
                 'emailnotifyattn' => array('type' => 'int', 'size' => 'tiny', 'default' => 1, 'description' => 'Notify by email of @-replies'),
-                'emailmicroid' => array('type' => 'int', 'size' => 'tiny', 'default' => 1, 'description' => 'whether to publish email microid'),
                 'language' => array('type' => 'varchar', 'length' => 50, 'description' => 'preferred language'),
                 'timezone' => array('type' => 'varchar', 'length' => 50, 'description' => 'timezone'),
                 'emailpost' => array('type' => 'int', 'size' => 'tiny', 'default' => 1, 'description' => 'Post by email'),
@@ -132,6 +130,11 @@ class User extends Managed_DataObject
         return $this->_profile[$this->id];
     }
 
+    public function sameAs(Profile $other)
+    {
+        return $this->getProfile()->sameAs($other);
+    }
+
     public function getUri()
     {
         return $this->uri;
@@ -142,6 +145,16 @@ class User extends Managed_DataObject
         return $this->getProfile()->getNickname();
     }
 
+    static function getByNickname($nickname)
+    {
+        $user = User::getKV('nickname', $nickname);
+        if (!$user instanceof User) {
+            throw new NoSuchUserException(array('nickname' => $nickname));
+        }
+
+        return $user;
+    }
+
     function isSubscribed(Profile $other)
     {
         return $this->getProfile()->isSubscribed($other);
@@ -261,9 +274,7 @@ class User extends Managed_DataObject
         $user->emailnotifynudge = 1;
         $user->emailnotifymsg = 1;
         $user->emailnotifyattn = 1;
-        $user->emailmicroid = 1;
         $user->emailpost = 1;
-        $user->jabbermicroid = 1;
 
         $user->created = common_sql_now();
 
@@ -288,7 +299,7 @@ class User extends Managed_DataObject
             }
 
             if (!empty($password)) { // may not have a password for OpenID users
-                $user->password = common_munge_password($password, $id);
+                $user->password = common_munge_password($password);
             }
 
             $result = $user->insert();
@@ -439,7 +450,7 @@ class User extends Managed_DataObject
 
     function getReplies($offset=0, $limit=NOTICES_PER_PAGE, $since_id=0, $before_id=0)
     {
-        return Reply::stream($this->id, $offset, $limit, $since_id, $before_id);
+        return $this->getProfile()->getReplies($offset, $limit, $since_id, $before_id);
     }
 
     function getTaggedNotices($tag, $offset=0, $limit=NOTICES_PER_PAGE, $since_id=0, $before_id=0) {
@@ -451,16 +462,6 @@ class User extends Managed_DataObject
         return $this->getProfile()->getNotices($offset, $limit, $since_id, $before_id);
     }
 
-    function getSelfTags()
-    {
-        return Profile_tag::getTagsArray($this->id, $this->id, $this->id);
-    }
-
-    function setSelfTags($newtags, $privacy)
-    {
-        return Profile_tag::setTags($this->id, $this->id, $newtags, $privacy);
-    }
-
     function block(Profile $other)
     {
         // Add a new block record
@@ -597,8 +598,10 @@ class User extends Managed_DataObject
         }
 
         try {
-            $profile = $this->getProfile();
-            $profile->delete();
+            if (!$this->hasRole(Profile_role::DELETED)) {
+                $profile = $this->getProfile();
+                $profile->delete();
+            }
         } catch (UserNoProfileException $unp) {
             common_log(LOG_INFO, "User {$this->nickname} has no profile; continuing deletion.");
         }
@@ -1004,6 +1007,11 @@ class User extends Managed_DataObject
         return $this->getProfile()->isPrivateStream();
     }
 
+    public function hasPassword()
+    {
+        return !empty($this->password);
+    }
+
     public function delPref($namespace, $topic)
     {
         return $this->getProfile()->delPref($namespace, $topic);
index 16fd030bb42ce43c35307ef4d8826fb3fa5fd263..6a5fc7f3ab55a70b4df8f8b060d5bba2c3e97c20 100644 (file)
@@ -40,7 +40,6 @@ class User_im_prefs extends Managed_DataObject
     public $transport;                       // varchar(191)  not_null   not 255 because utf8mb4 takes more space
     public $notify;                          // tinyint(1)
     public $replies;                         // tinyint(1)
-    public $microid;                         // tinyint(1)
     public $updatefrompresence;              // tinyint(1)
     public $created;                         // datetime   not_null default_0000-00-00%2000%3A00%3A00
     public $modified;                        // timestamp   not_null default_CURRENT_TIMESTAMP
@@ -57,7 +56,6 @@ class User_im_prefs extends Managed_DataObject
                 'transport' => array('type' => 'varchar', 'length' => 191, 'not null' => true, 'description' => 'transport (ex xmpp, aim)'),
                 'notify' => array('type' => 'int', 'size' => 'tiny', 'not null' => true, 'default' => 0, 'description' => 'Notify when a new notice is sent'),
                 'replies' => array('type' => 'int', 'size' => 'tiny', 'not null' => true, 'default' => 0, 'description' => 'Send replies  from people not subscribed to'),
-                'microid' => array('type' => 'int', 'size' => 'tiny', 'not null' => true, 'default' => 1, 'description' => 'Publish a MicroID'),
                 'updatefrompresence' => array('type' => 'int', 'size' => 'tiny', 'not null' => true, 'default' => 0, 'description' => 'Send replies from people not subscribed to.'),
                 'created' => array('type' => 'datetime', 'not null' => true, 'description' => 'date this record was created'),
                 'modified' => array('type' => 'timestamp', 'not null' => true, 'description' => 'date this record was modified'),
index ec3fe7f736c55830358762cfb3edb753c799e8db..d779717fd4a4447efbeec38231f9b6bb08bd7de7 100644 (file)
@@ -39,6 +39,7 @@ $classes = array('Schema_version',
                  'Subscription_queue',
                  'Oauth_token_association',
                  'Notice',
+                 'Notice_location',
                  'Notice_source',
                  'Reply',
                  'Consumer',
index aaa870c509ca7d5e0a968dbb20518c00c1aaf2a6..a0d06942f4b5f417408ebc11a678913916432904 100644 (file)
@@ -52,7 +52,7 @@
  * @author     Sean Coates <sean@php.net>
  * @copyright  2003-2006 PEAR <pear-group@php.net>
  * @license    http://www.opensource.org/licenses/bsd-license.php BSD License
- * @version    CVS: $Id: mimeDecode.php,v 1.48 2006/12/03 13:43:33 cipri Exp $
+ * @version    CVS: $Id: mimeDecode.php 305875 2010-12-01 07:17:10Z alan_k $
  * @link       http://pear.php.net/package/Mail_mime
  */
 
@@ -147,6 +147,15 @@ class Mail_mimeDecode extends PEAR
      */
     var $_decode_headers;
 
+    /**
+     * Flag to determine whether to include attached messages
+     * as body in the returned object. Depends on $_include_bodies
+     *
+     * @var    boolean
+     * @access private
+     */
+    var $_rfc822_bodies;
+
     /**
      * Constructor.
      *
@@ -165,6 +174,7 @@ class Mail_mimeDecode extends PEAR
         $this->_body           = $body;
         $this->_decode_bodies  = false;
         $this->_include_bodies = true;
+        $this->_rfc822_bodies  = false;
     }
 
     /**
@@ -187,7 +197,7 @@ class Mail_mimeDecode extends PEAR
     function decode($params = null)
     {
         // determine if this method has been called statically
-        $isStatic = !(isset($this) && get_class($this) == __CLASS__);
+        $isStatic = empty($this) || !is_a($this, __CLASS__);
 
         // Have we been called statically?
        // If so, create an object and pass details to that.
@@ -208,6 +218,8 @@ class Mail_mimeDecode extends PEAR
                                     $params['decode_bodies']  : false;
             $this->_decode_headers = isset($params['decode_headers']) ?
                                     $params['decode_headers'] : false;
+            $this->_rfc822_bodies  = isset($params['rfc_822bodies']) ?
+                                    $params['rfc_822bodies']  : false;
 
             $structure = $this->_decode($this->_header, $this->_body);
             if ($structure === false) {
@@ -235,6 +247,7 @@ class Mail_mimeDecode extends PEAR
         $headers = $this->_parseHeaders($headers);
 
         foreach ($headers as $value) {
+            $value['value'] = $this->_decode_headers ? $this->_decodeHeader($value['value']) : $value['value'];
             if (isset($return->headers[strtolower($value['name'])]) AND !is_array($return->headers[strtolower($value['name'])])) {
                 $return->headers[strtolower($value['name'])]   = array($return->headers[strtolower($value['name'])]);
                 $return->headers[strtolower($value['name'])][] = $value['value'];
@@ -247,8 +260,8 @@ class Mail_mimeDecode extends PEAR
             }
         }
 
-        reset($headers);
-        while (list($key, $value) = each($headers)) {
+
+        foreach ($headers as $key => $value) {
             $headers[$key]['name'] = strtolower($headers[$key]['name']);
             switch ($headers[$key]['name']) {
 
@@ -261,7 +274,7 @@ class Mail_mimeDecode extends PEAR
                     }
 
                     if (isset($content_type['other'])) {
-                        while (list($p_name, $p_value) = each($content_type['other'])) {
+                        foreach($content_type['other'] as $p_name => $p_value) {
                             $return->ctype_parameters[$p_name] = $p_value;
                         }
                     }
@@ -271,7 +284,7 @@ class Mail_mimeDecode extends PEAR
                     $content_disposition = $this->_parseHeaderValue($headers[$key]['value']);
                     $return->disposition   = $content_disposition['value'];
                     if (isset($content_disposition['other'])) {
-                        while (list($p_name, $p_value) = each($content_disposition['other'])) {
+                        foreach($content_disposition['other'] as $p_name => $p_value) {
                             $return->d_parameters[$p_name] = $p_value;
                         }
                     }
@@ -303,6 +316,7 @@ class Mail_mimeDecode extends PEAR
                 case 'multipart/alternative':
                 case 'multipart/related':
                 case 'multipart/mixed':
+                case 'application/vnd.wap.multipart.related':
                     if(!isset($content_type['other']['boundary'])){
                         $this->_error = 'No boundary found for ' . $content_type['value'] . ' part';
                         return false;
@@ -321,7 +335,11 @@ class Mail_mimeDecode extends PEAR
                     break;
 
                 case 'message/rfc822':
-                    $obj = &new Mail_mimeDecode($body);
+                                       if ($this->_rfc822_bodies) {
+                                               $encoding = isset($content_transfer_encoding) ? $content_transfer_encoding['value'] : '7bit';
+                                               $return->body = ($this->_decode_bodies ? $this->_decodeBody($body, $encoding) : $body);
+                                       }
+                    $obj = new Mail_mimeDecode($body);
                     $return->parts[] = $obj->decode(array('include_bodies' => $this->_include_bodies,
                                                                              'decode_bodies'  => $this->_decode_bodies,
                                                                                                                  'decode_headers' => $this->_decode_headers));
@@ -401,6 +419,11 @@ class Mail_mimeDecode extends PEAR
         if (preg_match("/^(.*?)\r?\n\r?\n(.*)/s", $input, $match)) {
             return array($match[1], $match[2]);
         }
+        // bug #17325 - empty bodies are allowed. - we just check that at least one line 
+        // of headers exist..
+        if (count(explode("\n",$input))) {
+            return array($input, '');
+        }
         $this->_error = 'Could not split header and body';
         return false;
     }
@@ -419,7 +442,12 @@ class Mail_mimeDecode extends PEAR
         if ($input !== '') {
             // Unfold the input
             $input   = preg_replace("/\r?\n/", "\r\n", $input);
+            //#7065 - wrapping.. with encoded stuff.. - probably not needed,
+            // wrapping space should only get removed if the trailing item on previous line is a 
+            // encoded character
+            $input   = preg_replace("/=\r\n(\t| )+/", '=', $input);
             $input   = preg_replace("/\r\n(\t| )+/", ' ', $input);
+            
             $headers = explode("\r\n", trim($input));
 
             foreach ($headers as $value) {
@@ -430,7 +458,7 @@ class Mail_mimeDecode extends PEAR
 
                 $return[] = array(
                                   'name'  => $hdr_name,
-                                  'value' => $this->_decode_headers ? $this->_decodeHeader($hdr_value) : $hdr_value
+                                  'value' =>  $hdr_value
                                  );
             }
         } else {
@@ -454,41 +482,161 @@ class Mail_mimeDecode extends PEAR
     function _parseHeaderValue($input)
     {
 
-        if (($pos = strpos($input, ';')) !== false) {
+        if (($pos = strpos($input, ';')) === false) {
+            $input = $this->_decode_headers ? $this->_decodeHeader($input) : $input;
+            $return['value'] = trim($input);
+            return $return;
+        }
+
+
 
-            $return['value'] = trim(substr($input, 0, $pos));
-            $input = trim(substr($input, $pos+1));
+        $value = substr($input, 0, $pos);
+        $value = $this->_decode_headers ? $this->_decodeHeader($value) : $value;
+        $return['value'] = trim($value);
+        $input = trim(substr($input, $pos+1));
 
-            if (strlen($input) > 0) {
+        if (!strlen($input) > 0) {
+            return $return;
+        }
+        // at this point input contains xxxx=".....";zzzz="...."
+        // since we are dealing with quoted strings, we need to handle this properly..
+        $i = 0;
+        $l = strlen($input);
+        $key = '';
+        $val = false; // our string - including quotes..
+        $q = false; // in quote..
+        $lq = ''; // last quote..
+
+        while ($i < $l) {
+            
+            $c = $input[$i];
+            //var_dump(array('i'=>$i,'c'=>$c,'q'=>$q, 'lq'=>$lq, 'key'=>$key, 'val' =>$val));
 
-                // This splits on a semi-colon, if there's no preceeding backslash
-                // Now works with quoted values; had to glue the \; breaks in PHP
-                // the regex is already bordering on incomprehensible
-                $splitRegex = '/([^;\'"]*[\'"]([^\'"]*([^\'"]*)*)[\'"][^;\'"]*|([^;]+))(;|$)/';
-                preg_match_all($splitRegex, $input, $matches);
-                $parameters = array();
-                for ($i=0; $i<count($matches[0]); $i++) {
-                    $param = $matches[0][$i];
-                    while (substr($param, -2) == '\;') {
-                        $param .= $matches[0][++$i];
+            $escaped = false;
+            if ($c == '\\') {
+                $i++;
+                if ($i == $l-1) { // end of string.
+                    break;
+                }
+                $escaped = true;
+                $c = $input[$i];
+            }            
+
+
+            // state - in key..
+            if ($val === false) {
+                if (!$escaped && $c == '=') {
+                    $val = '';
+                    $key = trim($key);
+                    $i++;
+                    continue;
+                }
+                if (!$escaped && $c == ';') {
+                    if ($key) { // a key without a value..
+                        $key= trim($key);
+                        $return['other'][$key] = '';
+                        $return['other'][strtolower($key)] = '';
+                    }
+                    $key = '';
+                }
+                $key .= $c;
+                $i++;
+                continue;
+            }
+                     
+            // state - in value.. (as $val is set..)
+
+            if ($q === false) {
+                // not in quote yet.
+                if ((!strlen($val) || $lq !== false) && $c == ' ' ||  $c == "\t") {
+                    $i++;
+                    continue; // skip leading spaces after '=' or after '"'
+                }
+                if (!$escaped && ($c == '"' || $c == "'")) {
+                    // start quoted area..
+                    $q = $c;
+                    // in theory should not happen raw text in value part..
+                    // but we will handle it as a merged part of the string..
+                    $val = !strlen(trim($val)) ? '' : trim($val);
+                    $i++;
+                    continue;
+                }
+                // got end....
+                if (!$escaped && $c == ';') {
+
+                    $val = trim($val);
+                    $added = false;
+                    if (preg_match('/\*[0-9]+$/', $key)) {
+                        // this is the extended aaa*0=...;aaa*1=.... code
+                        // it assumes the pieces arrive in order, and are valid...
+                        $key = preg_replace('/\*[0-9]+$/', '', $key);
+                        if (isset($return['other'][$key])) {
+                            $return['other'][$key] .= $val;
+                            if (strtolower($key) != $key) {
+                                $return['other'][strtolower($key)] .= $val;
+                            }
+                            $added = true;
+                        }
+                        // continue and use standard setters..
+                    }
+                    if (!$added) {
+                        $return['other'][$key] = $val;
+                        $return['other'][strtolower($key)] = $val;
                     }
-                    $parameters[] = $param;
+                    $val = false;
+                    $key = '';
+                    $lq = false;
+                    $i++;
+                    continue;
                 }
 
-                for ($i = 0; $i < count($parameters); $i++) {
-                    $param_name  = trim(substr($parameters[$i], 0, $pos = strpos($parameters[$i], '=')), "'\";\t\\ ");
-                    $param_value = trim(str_replace('\;', ';', substr($parameters[$i], $pos + 1)), "'\";\t\\ ");
-                    if ($param_value[0] == '"') {
-                        $param_value = substr($param_value, 1, -1);
+                $val .= $c;
+                $i++;
+                continue;
+            }
+            
+            // state - in quote..
+            if (!$escaped && $c == $q) {  // potential exit state..
+
+                // end of quoted string..
+                $lq = $q;
+                $q = false;
+                $i++;
+                continue;
+            }
+                
+            // normal char inside of quoted string..
+            $val.= $c;
+            $i++;
+        }
+        
+        // do we have anything left..
+        if (strlen(trim($key)) || $val !== false) {
+           
+            $val = trim($val);
+            $added = false;
+            if ($val !== false && preg_match('/\*[0-9]+$/', $key)) {
+                // no dupes due to our crazy regexp.
+                $key = preg_replace('/\*[0-9]+$/', '', $key);
+                if (isset($return['other'][$key])) {
+                    $return['other'][$key] .= $val;
+                    if (strtolower($key) != $key) {
+                        $return['other'][strtolower($key)] .= $val;
                     }
-                    $return['other'][$param_name] = $param_value;
-                    $return['other'][strtolower($param_name)] = $param_value;
+                    $added = true;
                 }
+                // continue and use standard setters..
+            }
+            if (!$added) {
+                $return['other'][$key] = $val;
+                $return['other'][strtolower($key)] = $val;
             }
-        } else {
-            $return['value'] = trim($input);
         }
-
+        // decode values.
+        foreach($return['other'] as $key =>$val) {
+            $return['other'][$key] = $this->_decode_headers ? $this->_decodeHeader($val) : $val;
+        }
+       //print_r($return);
         return $return;
     }
 
@@ -510,13 +658,19 @@ class Mail_mimeDecode extends PEAR
         if ($boundary == $bs_check) {
             $boundary = $bs_possible;
         }
+        $tmp = preg_split("/--".preg_quote($boundary, '/')."((?=\s)|--)/", $input);
 
-        $tmp = explode('--' . $boundary, $input);
-
-        for ($i = 1; $i < count($tmp) - 1; $i++) {
-            $parts[] = $tmp[$i];
+        $len = count($tmp) -1;
+        for ($i = 1; $i < $len; $i++) {
+            if (strlen(trim($tmp[$i]))) {
+                $parts[] = $tmp[$i];
+            }
+        }
+        
+        // add the last part on if it does not end with the 'closing indicator'
+        if (!empty($tmp[$len]) && strlen(trim($tmp[$len])) && $tmp[$len][0] != '-') {
+            $parts[] = $tmp[$len];
         }
-
         return $parts;
     }
 
@@ -719,7 +873,7 @@ class Mail_mimeDecode extends PEAR
                 case "to":
                 case "cc":
                 case "bcc":
-                    $to = ",".$item['value'];
+                    $to .= ",".$item['value'];
                 default:
                    break;
             }
index 27805f2324e54b0802e7f6a18d053be15ac98bff..b8a954f2c8631f965c7880b45ec5c2e67f29da0e 100644 (file)
@@ -13,17 +13,17 @@ use stdClass;
 
 /**
  * Parse Microformats2
- * 
+ *
  * Functional shortcut for the commonest cases of parsing microformats2 from HTML.
- * 
+ *
  * Example usage:
- * 
+ *
  *     use Mf2;
  *     $output = Mf2\parse('<span class="h-card">Barnaby Walters</span>');
  *     echo json_encode($output, JSON_PRETTY_PRINT);
- * 
+ *
  * Produces:
- * 
+ *
  *     {
  *      "items": [
  *       {
@@ -35,7 +35,7 @@ use stdClass;
  *      ],
  *      "rels": {}
  *     }
- * 
+ *
  * @param string|DOMDocument $input The HTML string or DOMDocument object to parse
  * @param string $url The URL the input document was found at, for relative URL resolution
  * @param bool $convertClassic whether or not to convert classic microformats
@@ -84,7 +84,7 @@ function fetch($url, $convertClassic = true, &$curlInfo=null) {
 /**
  * Unicode to HTML Entities
  * @param string $input String containing characters to convert into HTML entities
- * @return string 
+ * @return string
  */
 function unicodeToHtmlEntities($input) {
        return mb_convert_encoding($input, 'HTML-ENTITIES', mb_detect_encoding($input));
@@ -92,10 +92,10 @@ function unicodeToHtmlEntities($input) {
 
 /**
  * Collapse Whitespace
- * 
+ *
  * Collapses any sequences of whitespace within a string into a single space
  * character.
- * 
+ *
  * @deprecated since v0.2.3
  * @param string $str
  * @return string
@@ -113,10 +113,10 @@ function unicodeTrim($str) {
 
 /**
  * Microformat Name From Class string
- * 
- * Given the value of @class, get the relevant mf classnames (e.g. h-card, 
+ *
+ * Given the value of @class, get the relevant mf classnames (e.g. h-card,
  * p-name).
- * 
+ *
  * @param string $class A space delimited list of classnames
  * @param string $prefix The prefix to look for
  * @return string|array The prefixed name of the first microfomats class found or false
@@ -127,9 +127,9 @@ function mfNamesFromClass($class, $prefix='h-') {
        $matches = array();
 
        foreach ($classes as $classname) {
-               $compare_classname = strtolower(' ' . $classname);
-               $compare_prefix = strtolower(' ' . $prefix);
-               if (stristr($compare_classname, $compare_prefix) !== false && ($compare_classname != $compare_prefix)) {
+               $compare_classname = ' ' . $classname;
+               $compare_prefix = ' ' . $prefix;
+               if (strstr($compare_classname, $compare_prefix) !== false && ($compare_classname != $compare_prefix)) {
                        $matches[] = ($prefix === 'h-') ? $classname : substr($classname, strlen($prefix));
                }
        }
@@ -139,10 +139,10 @@ function mfNamesFromClass($class, $prefix='h-') {
 
 /**
  * Get Nested µf Property Name From Class
- * 
- * Returns all the p-, u-, dt- or e- prefixed classnames it finds in a 
+ *
+ * Returns all the p-, u-, dt- or e- prefixed classnames it finds in a
  * space-separated string.
- * 
+ *
  * @param string $class
  * @return array
  */
@@ -153,19 +153,24 @@ function nestedMfPropertyNamesFromClass($class) {
        $class = str_replace(array(' ', '       ', "\n"), ' ', $class);
        foreach (explode(' ', $class) as $classname) {
                foreach ($prefixes as $prefix) {
-                       $compare_classname = strtolower(' ' . $classname);
-                       if (stristr($compare_classname, $prefix) && ($compare_classname != $prefix)) {
-                               $propertyNames = array_merge($propertyNames, mfNamesFromClass($classname, ltrim($prefix)));
+                       // Check if $classname is a valid property classname for $prefix.
+                       if (mb_substr($classname, 0, mb_strlen($prefix)) == $prefix && $classname != $prefix) {
+                               $propertyName = mb_substr($classname, mb_strlen($prefix));
+                               $propertyNames[$propertyName][] = $prefix;
                        }
                }
        }
+       
+       foreach ($propertyNames as $property => $prefixes) {
+               $propertyNames[$property] = array_unique($prefixes);
+       }
 
        return $propertyNames;
 }
 
 /**
  * Wraps mfNamesFromClass to handle an element as input (common)
- * 
+ *
  * @param DOMElement $e The element to get the classname for
  * @param string $prefix The prefix to look for
  * @return mixed See return value of mf2\Parser::mfNameFromClass()
@@ -192,28 +197,27 @@ function convertTimeFormat($time) {
        $hh = $mm = $ss = '';
        preg_match('/(\d{1,2}):?(\d{2})?:?(\d{2})?(a\.?m\.?|p\.?m\.?)?/i', $time, $matches);
 
-       // if no am/pm specified
+       // If no am/pm is specified:
        if (empty($matches[4])) {
                return $time;
-       }
-       // else am/pm specified
-       else {
+       } else {
+               // Otherwise, am/pm is specified.
                $meridiem = strtolower(str_replace('.', '', $matches[4]));
 
-               // hours
+               // Hours.
                $hh = $matches[1];
 
-               // add 12 to the pm hours
+               // Add 12 to hours if pm applies.
                if ($meridiem == 'pm' && ($hh < 12)) {
                        $hh += 12;
                }
 
                $hh = str_pad($hh, 2, '0', STR_PAD_LEFT);
 
-               // minutes
+               // Minutes.
                $mm = (empty($matches[2]) ) ? '00' : $matches[2];
 
-               // seconds, only if supplied
+               // Seconds, only if supplied.
                if (!empty($matches[3])) {
                        $ss = $matches[3];
                }
@@ -229,11 +233,11 @@ function convertTimeFormat($time) {
 
 /**
  * Microformats2 Parser
- * 
+ *
  * A class which holds state for parsing microformats2 from HTML.
- * 
+ *
  * Example usage:
- * 
+ *
  *     use Mf2;
  *     $parser = new Mf2\Parser('<p class="h-card">Barnaby Walters</p>');
  *     $output = $parser->parse();
@@ -244,18 +248,18 @@ class Parser {
 
        /** @var DOMXPath object which can be used to query over any fragment*/
        public $xpath;
-       
+
        /** @var DOMDocument */
        public $doc;
-       
+
        /** @var SplObjectStorage */
        protected $parsed;
-       
+
        public $jsonMode;
 
        /**
         * Constructor
-        * 
+        *
         * @param DOMDocument|string $input The data to parse. A string of HTML or a DOMDocument
         * @param string $url The URL of the parsed document, for relative URL resolution
         * @param boolean $jsonMode Whether or not to use a stdClass instance for an empty `rels` dictionary. This breaks PHP looping over rels, but allows the output to be correctly serialized as JSON.
@@ -271,20 +275,20 @@ class Parser {
                        $doc = new DOMDocument();
                        @$doc->loadHTML('');
                }
-               
+
                $this->xpath = new DOMXPath($doc);
-               
+
                $baseurl = $url;
                foreach ($this->xpath->query('//base[@href]') as $base) {
                        $baseElementUrl = $base->getAttribute('href');
-                       
+
                        if (parse_url($baseElementUrl, PHP_URL_SCHEME) === null) {
                                /* The base element URL is relative to the document URL.
                                 *
                                 * :/
                                 *
                                 * Perhaps the author was high? */
-                               
+
                                $baseurl = resolveUrl($url, $baseElementUrl);
                        } else {
                                $baseurl = $baseElementUrl;
@@ -296,31 +300,31 @@ class Parser {
                foreach ($this->xpath->query('//template') as $templateEl) {
                        $templateEl->parentNode->removeChild($templateEl);
                }
-               
+
                $this->baseurl = $baseurl;
                $this->doc = $doc;
                $this->parsed = new SplObjectStorage();
                $this->jsonMode = $jsonMode;
        }
-       
+
        private function elementPrefixParsed(\DOMElement $e, $prefix) {
                if (!$this->parsed->contains($e))
                        $this->parsed->attach($e, array());
-               
+
                $prefixes = $this->parsed[$e];
                $prefixes[] = $prefix;
                $this->parsed[$e] = $prefixes;
        }
-       
+
        private function isElementParsed(\DOMElement $e, $prefix) {
                if (!$this->parsed->contains($e))
                        return false;
-               
+
                $prefixes = $this->parsed[$e];
-               
+
                if (!in_array($prefix, $prefixes))
                        return false;
-               
+
                return true;
        }
 
@@ -352,72 +356,72 @@ class Parser {
 
        // TODO: figure out if this has problems with sms: and geo: URLs
        public function resolveUrl($url) {
-               // If the URL is seriously malformed it’s probably beyond the scope of this 
+               // If the URL is seriously malformed it’s probably beyond the scope of this
                // parser to try to do anything with it.
                if (parse_url($url) === false)
                        return $url;
-               
+
                $scheme = parse_url($url, PHP_URL_SCHEME);
-               
+
                if (empty($scheme) and !empty($this->baseurl)) {
                        return resolveUrl($this->baseurl, $url);
                } else {
                        return $url;
                }
        }
-       
+
        // Parsing Functions
-       
+
        /**
-        * Parse value-class/value-title on an element, joining with $separator if 
+        * Parse value-class/value-title on an element, joining with $separator if
         * there are multiple.
-        * 
+        *
         * @param \DOMElement $e
         * @param string $separator = '' if multiple value-title elements, join with this string
         * @return string|null the parsed value or null if value-class or -title aren’t in use
         */
        public function parseValueClassTitle(\DOMElement $e, $separator = '') {
                $valueClassElements = $this->xpath->query('./*[contains(concat(" ", @class, " "), " value ")]', $e);
-               
+
                if ($valueClassElements->length !== 0) {
                        // Process value-class stuff
                        $val = '';
                        foreach ($valueClassElements as $el) {
                                $val .= $this->textContent($el);
                        }
-                       
+
                        return unicodeTrim($val);
                }
-               
+
                $valueTitleElements = $this->xpath->query('./*[contains(concat(" ", @class, " "), " value-title ")]', $e);
-               
+
                if ($valueTitleElements->length !== 0) {
                        // Process value-title stuff
                        $val = '';
                        foreach ($valueTitleElements as $el) {
                                $val .= $el->getAttribute('title');
                        }
-                       
+
                        return unicodeTrim($val);
                }
-               
+
                // No value-title or -class in this element
                return null;
        }
-       
+
        /**
         * Given an element with class="p-*", get it’s value
-        * 
+        *
         * @param DOMElement $p The element to parse
         * @return string The plaintext value of $p, dependant on type
         * @todo Make this adhere to value-class
         */
        public function parseP(\DOMElement $p) {
                $classTitle = $this->parseValueClassTitle($p, ' ');
-               
+
                if ($classTitle !== null)
                        return $classTitle;
-               
+
                if ($p->tagName == 'img' and $p->getAttribute('alt') !== '') {
                        $pValue = $p->getAttribute('alt');
                } elseif ($p->tagName == 'area' and $p->getAttribute('alt') !== '') {
@@ -429,13 +433,13 @@ class Parser {
                } else {
                        $pValue = unicodeTrim($this->textContent($p));
                }
-               
+
                return $pValue;
        }
 
        /**
         * Given an element with class="u-*", get the value of the URL
-        * 
+        *
         * @param DOMElement $u The element to parse
         * @return string The plaintext value of $u, dependant on type
         * @todo make this adhere to value-class
@@ -443,18 +447,18 @@ class Parser {
        public function parseU(\DOMElement $u) {
                if (($u->tagName == 'a' or $u->tagName == 'area') and $u->getAttribute('href') !== null) {
                        $uValue = $u->getAttribute('href');
-               } elseif ($u->tagName == 'img' and $u->getAttribute('src') !== null) {
+               } elseif (in_array($u->tagName, array('img', 'audio', 'video', 'source')) and $u->getAttribute('src') !== null) {
                        $uValue = $u->getAttribute('src');
                } elseif ($u->tagName == 'object' and $u->getAttribute('data') !== null) {
                        $uValue = $u->getAttribute('data');
                }
-               
+
                if (isset($uValue)) {
                        return $this->resolveUrl($uValue);
                }
-               
+
                $classTitle = $this->parseValueClassTitle($u);
-               
+
                if ($classTitle !== null) {
                        return $classTitle;
                } elseif ($u->tagName == 'abbr' and $u->getAttribute('title') !== null) {
@@ -468,7 +472,7 @@ class Parser {
 
        /**
         * Given an element with class="dt-*", get the value of the datetime as a php date object
-        * 
+        *
         * @param DOMElement $dt The element to parse
         * @param array $dates Array of dates processed so far
         * @return string The datetime string found
@@ -477,11 +481,11 @@ class Parser {
                // Check for value-class pattern
                $valueClassChildren = $this->xpath->query('./*[contains(concat(" ", @class, " "), " value ") or contains(concat(" ", @class, " "), " value-title ")]', $dt);
                $dtValue = false;
-               
+
                if ($valueClassChildren->length > 0) {
                        // They’re using value-class
                        $dateParts = array();
-                       
+
                        foreach ($valueClassChildren as $e) {
                                if (strstr(' ' . $e->getAttribute('class') . ' ', ' value-title ')) {
                                        $title = $e->getAttribute('title');
@@ -591,16 +595,16 @@ class Parser {
                                $dtValue = $dt->nodeValue;
                        }
 
-                       if ( preg_match('/(\d{4}-\d{2}-\d{2})/', $dtValue, $matches) ) {
+                       if (preg_match('/(\d{4}-\d{2}-\d{2})/', $dtValue, $matches)) {
                                $dates[] = $matches[0];
                        }
                }
 
                /**
-                * if $dtValue is only a time and there are recently parsed dates, 
-                * form the full date-time using the most recnetly parsed dt- value
+                * if $dtValue is only a time and there are recently parsed dates,
+                * form the full date-time using the most recently parsed dt- value
                 */
-               if ( (preg_match('/^\d{1,2}:\d{1,2}(Z?[+|-]\d{2}:?\d{2})?/', $dtValue) or preg_match('/^\d{1,2}[a|p]m/', $dtValue)) && !empty($dates) ) {
+               if ((preg_match('/^\d{1,2}:\d{1,2}(Z?[+|-]\d{2}:?\d{2})?/', $dtValue) or preg_match('/^\d{1,2}[a|p]m/', $dtValue)) && !empty($dates)) {
                        $dtValue = convertTimeFormat($dtValue);
                        $dtValue = end($dates) . 'T' . unicodeTrim($dtValue, 'T');
                }
@@ -613,15 +617,15 @@ class Parser {
         *
         *      @param DOMElement $e The element to parse
         *      @return string $e’s innerHTML
-        * 
+        *
         * @todo need to mark this element as e- parsed so it doesn’t get parsed as it’s parent’s e-* too
         */
        public function parseE(\DOMElement $e) {
                $classTitle = $this->parseValueClassTitle($e);
-               
+
                if ($classTitle !== null)
                        return $classTitle;
-               
+
                // Expand relative URLs within children of this element
                // TODO: as it is this is not relative to only children, make this .// and rerun tests
                $this->resolveChildUrls($e);
@@ -630,7 +634,7 @@ class Parser {
                foreach ($e->childNodes as $node) {
                        $html .= $node->C14N();
                }
-               
+
                return array(
                        'html' => $html,
                        'value' => unicodeTrim($this->textContent($e))
@@ -639,7 +643,7 @@ class Parser {
 
        /**
         * Recursively parse microformats
-        * 
+        *
         * @param DOMElement $e The element to parse
         * @return array A representation of the values contained within microformat $e
         */
@@ -660,26 +664,39 @@ class Parser {
                foreach ($this->xpath->query('.//*[contains(concat(" ", @class)," h-")]', $e) as $subMF) {
                        // Parse
                        $result = $this->parseH($subMF);
-                       
+
                        // If result was already parsed, skip it
                        if (null === $result)
                                continue;
                        
+                       // In most cases, the value attribute of the nested microformat should be the p- parsed value of the elemnt.
+                       // The only times this is different is when the microformat is nested under certain prefixes, which are handled below.
                        $result['value'] = $this->parseP($subMF);
 
                        // Does this µf have any property names other than h-*?
                        $properties = nestedMfPropertyNamesFromElement($subMF);
-                       
+
                        if (!empty($properties)) {
                                // Yes! It’s a nested property µf
-                               foreach ($properties as $property) {
-                                       $return[$property][] = $result;
+                               foreach ($properties as $property => $prefixes) {
+                                       // Note: handling microformat nesting under multiple conflicting prefixes is not currently specified by the mf2 parsing spec.
+                                       $prefixSpecificResult = $result;
+                                       if (in_array('p-', $prefixes)) {
+                                               $prefixSpecificResult['value'] = $prefixSpecificResult['properties']['name'][0];
+                                       } elseif (in_array('e-', $prefixes)) {
+                                               $eParsedResult = $this->parseE($subMF);
+                                               $prefixSpecificResult['html'] = $eParsedResult['html'];
+                                               $prefixSpecificResult['value'] = $eParsedResult['value'];
+                                       } elseif (in_array('u-', $prefixes)) {
+                                               $prefixSpecificResult['value'] = $this->parseU($subMF);
+                                       }
+                                       $return[$property][] = $prefixSpecificResult;
                                }
                        } else {
                                // No, it’s a child µf
                                $children[] = $result;
                        }
-                       
+
                        // Make sure this sub-mf won’t get parsed as a µf or property
                        // TODO: Determine if clearing this is required?
                        $this->elementPrefixParsed($subMF, 'h');
@@ -689,19 +706,24 @@ class Parser {
                        $this->elementPrefixParsed($subMF, 'e');
                }
 
+               if($e->tagName == 'area') {
+                       $coords = $e->getAttribute('coords');
+                       $shape = $e->getAttribute('shape');
+               }
+
                // Handle p-*
                foreach ($this->xpath->query('.//*[contains(concat(" ", @class) ," p-")]', $e) as $p) {
                        if ($this->isElementParsed($p, 'p'))
                                continue;
 
                        $pValue = $this->parseP($p);
-                       
+
                        // Add the value to the array for it’s p- properties
                        foreach (mfNamesFromElement($p, 'p-') as $propName) {
                                if (!empty($propName))
                                        $return[$propName][] = $pValue;
                        }
-                       
+
                        // Make sure this sub-mf won’t get parsed as a top level mf
                        $this->elementPrefixParsed($p, 'p');
                }
@@ -710,32 +732,32 @@ class Parser {
                foreach ($this->xpath->query('.//*[contains(concat(" ",  @class)," u-")]', $e) as $u) {
                        if ($this->isElementParsed($u, 'u'))
                                continue;
-                       
+
                        $uValue = $this->parseU($u);
-                       
+
                        // Add the value to the array for it’s property types
                        foreach (mfNamesFromElement($u, 'u-') as $propName) {
                                $return[$propName][] = $uValue;
                        }
-                       
+
                        // Make sure this sub-mf won’t get parsed as a top level mf
                        $this->elementPrefixParsed($u, 'u');
                }
-               
+
                // Handle dt-*
                foreach ($this->xpath->query('.//*[contains(concat(" ", @class), " dt-")]', $e) as $dt) {
                        if ($this->isElementParsed($dt, 'dt'))
                                continue;
-                       
+
                        $dtValue = $this->parseDT($dt, $dates);
-                       
+
                        if ($dtValue) {
                                // Add the value to the array for dt- properties
                                foreach (mfNamesFromElement($dt, 'dt-') as $propName) {
                                        $return[$propName][] = $dtValue;
                                }
                        }
-                       
+
                        // Make sure this sub-mf won’t get parsed as a top level mf
                        $this->elementPrefixParsed($dt, 'dt');
                }
@@ -762,22 +784,43 @@ class Parser {
                if (!array_key_exists('name', $return)) {
                        try {
                                // Look for img @alt
-                               if ($e->tagName == 'img' and $e->getAttribute('alt') != '')
+                               if (($e->tagName == 'img' or $e->tagName == 'area') and $e->getAttribute('alt') != '')
                                        throw new Exception($e->getAttribute('alt'));
-                               
+
                                if ($e->tagName == 'abbr' and $e->hasAttribute('title'))
                                        throw new Exception($e->getAttribute('title'));
-                               
+
                                // Look for nested img @alt
                                foreach ($this->xpath->query('./img[count(preceding-sibling::*)+count(following-sibling::*)=0]', $e) as $em) {
-                                       if ($em->getAttribute('alt') != '')
+                                       $emNames = mfNamesFromElement($em, 'h-');
+                                       if (empty($emNames) && $em->getAttribute('alt') != '') {
                                                throw new Exception($em->getAttribute('alt'));
+                                       }
+                               }
+
+                               // Look for nested area @alt
+                               foreach ($this->xpath->query('./area[count(preceding-sibling::*)+count(following-sibling::*)=0]', $e) as $em) {
+                                       $emNames = mfNamesFromElement($em, 'h-');
+                                       if (empty($emNames) && $em->getAttribute('alt') != '') {
+                                               throw new Exception($em->getAttribute('alt'));
+                                       }
                                }
 
+
                                // Look for double nested img @alt
                                foreach ($this->xpath->query('./*[count(preceding-sibling::*)+count(following-sibling::*)=0]/img[count(preceding-sibling::*)+count(following-sibling::*)=0]', $e) as $em) {
-                                       if ($em->getAttribute('alt') != '')
+                                       $emNames = mfNamesFromElement($em, 'h-');
+                                       if (empty($emNames) && $em->getAttribute('alt') != '') {
+                                               throw new Exception($em->getAttribute('alt'));
+                                       }
+                               }
+
+                               // Look for double nested img @alt
+                               foreach ($this->xpath->query('./*[count(preceding-sibling::*)+count(following-sibling::*)=0]/area[count(preceding-sibling::*)+count(following-sibling::*)=0]', $e) as $em) {
+                                       $emNames = mfNamesFromElement($em, 'h-');
+                                       if (empty($emNames) && $em->getAttribute('alt') != '') {
                                                throw new Exception($em->getAttribute('alt'));
+                                       }
                                }
 
                                throw new Exception($e->nodeValue);
@@ -812,36 +855,58 @@ class Parser {
                // Check for u-url
                if (!array_key_exists('url', $return)) {
                        // Look for img @src
-                       if ($e->tagName == 'a')
+                       if ($e->tagName == 'a' or $e->tagName == 'area')
                                $url = $e->getAttribute('href');
-                       
-                       // Look for nested img @src
+
+                       // Look for nested a @href
                        foreach ($this->xpath->query('./a[count(preceding-sibling::a)+count(following-sibling::a)=0]', $e) as $em) {
-                               $url = $em->getAttribute('href');
-                               break;
+                               $emNames = mfNamesFromElement($em, 'h-');
+                               if (empty($emNames)) {
+                                       $url = $em->getAttribute('href');
+                                       break;
+                               }
                        }
-                       
+
+                       // Look for nested area @src
+                       foreach ($this->xpath->query('./area[count(preceding-sibling::area)+count(following-sibling::area)=0]', $e) as $em) {
+                               $emNames = mfNamesFromElement($em, 'h-');
+                               if (empty($emNames)) {
+                                       $url = $em->getAttribute('href');
+                                       break;
+                               }
+                       }
+
                        if (!empty($url))
                                $return['url'][] = $this->resolveUrl($url);
                }
 
                // Make sure things are in alphabetical order
                sort($mfTypes);
-               
+
                // Phew. Return the final result.
                $parsed = array(
                        'type' => $mfTypes,
                        'properties' => $return
                );
-               if (!empty($children))
+
+               if (!empty($shape)) {
+                       $parsed['shape'] = $shape;
+               }
+
+               if (!empty($coords)) {
+                       $parsed['coords'] = $coords;
+               }
+
+               if (!empty($children)) {
                        $parsed['children'] = array_values(array_filter($children));
+               }
                return $parsed;
        }
-       
+
        /**
         * Parse Rels and Alternatives
-        * 
-        * Returns [$rels, $alternatives]. If the $rels value is to be empty, i.e. there are no links on the page 
+        *
+        * Returns [$rels, $alternatives]. If the $rels value is to be empty, i.e. there are no links on the page
         * with a rel value *not* containing `alternate`, then the type of $rels depends on $this->jsonMode. If set
         * to true, it will be a stdClass instance, optimising for JSON serialisation. Otherwise (the default case),
         * it will be an empty array.
@@ -849,18 +914,18 @@ class Parser {
        public function parseRelsAndAlternates() {
                $rels = array();
                $alternates = array();
-               
+
                // Iterate through all a, area and link elements with rel attributes
                foreach ($this->xpath->query('//*[@rel and @href]') as $hyperlink) {
                        if ($hyperlink->getAttribute('rel') == '')
                                continue;
-                       
+
                        // Resolve the href
                        $href = $this->resolveUrl($hyperlink->getAttribute('href'));
-                       
+
                        // Split up the rel into space-separated values
                        $linkRels = array_filter(explode(' ', $hyperlink->getAttribute('rel')));
-                       
+
                        // If alternate in rels, create alternate structure, append
                        if (in_array('alternate', $linkRels)) {
                                $alt = array(
@@ -869,10 +934,19 @@ class Parser {
                                );
                                if ($hyperlink->hasAttribute('media'))
                                        $alt['media'] = $hyperlink->getAttribute('media');
-                               
+
                                if ($hyperlink->hasAttribute('hreflang'))
                                        $alt['hreflang'] = $hyperlink->getAttribute('hreflang');
-                               
+
+                               if ($hyperlink->hasAttribute('title'))
+                                       $alt['title'] = $hyperlink->getAttribute('title');
+
+                               if ($hyperlink->hasAttribute('type'))
+                                       $alt['type'] = $hyperlink->getAttribute('type');
+
+                               if ($hyperlink->nodeValue)
+                                       $alt['text'] = $hyperlink->nodeValue;
+
                                $alternates[] = $alt;
                        } else {
                                foreach ($linkRels as $rel) {
@@ -880,38 +954,38 @@ class Parser {
                                }
                        }
                }
-               
+
                if (empty($rels) and $this->jsonMode) {
                        $rels = new stdClass();
                }
-               
+
                return array($rels, $alternates);
        }
-       
+
        /**
         * Kicks off the parsing routine
-        * 
+        *
         * If `$htmlSafe` is set, any angle brackets in the results from non e-* properties
         * will be HTML-encoded, bringing all output to the same level of encoding.
-        * 
+        *
         * If a DOMElement is set as the $context, only descendants of that element will
         * be parsed for microformats.
-        * 
+        *
         * @param bool $htmlSafe whether or not to html-encode non e-* properties. Defaults to false
         * @param DOMElement $context optionally an element from which to parse microformats
         * @return array An array containing all the µfs found in the current document
         */
        public function parse($convertClassic = true, DOMElement $context = null) {
                $mfs = array();
-               
+
                if ($convertClassic) {
                        $this->convertLegacy();
                }
-               
+
                $mfElements = null === $context
                        ? $this->xpath->query('//*[contains(concat(" ", @class), " h-")]')
                        : $this->xpath->query('.//*[contains(concat(" ",        @class), " h-")]', $context);
-               
+
                // Parser microformats
                foreach ($mfElements as $node) {
                        // For each microformat
@@ -920,64 +994,64 @@ class Parser {
                        // Add the value to the array for this property type
                        $mfs[] = $result;
                }
-               
+
                // Parse rels
                list($rels, $alternates) = $this->parseRelsAndAlternates();
-               
+
                $top = array(
                        'items' => array_values(array_filter($mfs)),
                        'rels' => $rels
                );
-               
+
                if (count($alternates))
                        $top['alternates'] = $alternates;
-               
+
                return $top;
        }
-       
+
        /**
         * Parse From ID
-        * 
+        *
         * Given an ID, parse all microformats which are children of the element with
         * that ID.
-        * 
+        *
         * Note that rel values are still document-wide.
-        * 
-        * If an element with the ID is not found, an empty skeleton mf2 array structure 
+        *
+        * If an element with the ID is not found, an empty skeleton mf2 array structure
         * will be returned.
-        * 
+        *
         * @param string $id
         * @param bool $htmlSafe = false whether or not to HTML-encode angle brackets in non e-* properties
         * @return array
         */
        public function parseFromId($id, $convertClassic=true) {
                $matches = $this->xpath->query("//*[@id='{$id}']");
-               
+
                if (empty($matches))
                        return array('items' => array(), 'rels' => array(), 'alternates' => array());
-               
+
                return $this->parse($convertClassic, $matches->item(0));
        }
 
        /**
         * Convert Legacy Classnames
-        * 
+        *
         * Adds microformats2 classnames into a document containing only legacy
         * semantic classnames.
-        * 
+        *
         * @return Parser $this
         */
        public function convertLegacy() {
                $doc = $this->doc;
                $xp = new DOMXPath($doc);
-               
+
                // replace all roots
                foreach ($this->classicRootMap as $old => $new) {
                        foreach ($xp->query('//*[contains(concat(" ", @class, " "), " ' . $old . ' ") and not(contains(concat(" ", @class, " "), " ' . $new . ' "))]') as $el) {
                                $el->setAttribute('class', $el->getAttribute('class') . ' ' . $new);
                        }
                }
-               
+
                foreach ($this->classicPropertyMap as $oldRoot => $properties) {
                        $newRoot = $this->classicRootMap[$oldRoot];
                        foreach ($properties as $old => $new) {
@@ -986,16 +1060,16 @@ class Parser {
                                }
                        }
                }
-               
+
                return $this;
        }
-       
+
        /**
         * XPath Query
-        * 
+        *
         * Runs an XPath query over the current document. Works in exactly the same
         * way as DOMXPath::query.
-        * 
+        *
         * @param string $expression
         * @param DOMNode $context
         * @return DOMNodeList
@@ -1003,7 +1077,7 @@ class Parser {
        public function query($expression, $context = null) {
                return $this->xpath->query($expression, $context);
        }
-       
+
        /**
         * Classic Root Classname map
         */
@@ -1013,11 +1087,11 @@ class Parser {
                'hentry' => 'h-entry',
                'hrecipe' => 'h-recipe',
                'hresume' => 'h-resume',
-               'hevent' => 'h-event',
+               'vevent' => 'h-event',
                'hreview' => 'h-review',
                'hproduct' => 'h-product'
        );
-       
+
        public $classicPropertyMap = array(
                'vcard' => array(
                        'fn' => 'p-name',
@@ -1084,7 +1158,7 @@ class Parser {
                        'skill' => 'p-skill',
                        'affiliation' => 'p-affiliation h-card',
                ),
-               'hevent' => array(
+               'vevent' => array(
                        'dtstart' => 'dt-start',
                        'dtend' => 'dt-end',
                        'duration' => 'dt-duration',
@@ -1246,7 +1320,7 @@ function resolveUrl($baseURI, $referenceURI) {
 # 5.2.3 Merge Paths
 function mergePaths($base, $reference) {
        # If the base URI has a defined authority component and an empty
-       #    path, 
+       #    path,
        if($base['authority'] && $base['path'] == null) {
                # then return a string consisting of "/" concatenated with the
                # reference's path; otherwise,
diff --git a/extlib/get_temp_dir.php b/extlib/get_temp_dir.php
deleted file mode 100644 (file)
index 4ec96e5..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-<?php
-if ( !function_exists('sys_get_temp_dir')) {
-       function sys_get_temp_dir() {
-               if (!empty($_ENV['TMP'])) { return realpath($_ENV['TMP']); }
-               if (!empty($_ENV['TMPDIR'])) { return realpath( $_ENV['TMPDIR']); }
-               if (!empty($_ENV['TEMP'])) { return realpath( $_ENV['TEMP']); }
-               $tempfile=tempnam(uniqid(rand(),TRUE),'');
-               if (file_exists($tempfile)) {
-                       unlink($tempfile);
-               }
-               return realpath(dirname($tempfile));
-       }
-}
-?>
diff --git a/file/.gitignore b/file/.gitignore
deleted file mode 100644 (file)
index e69de29..0000000
index b0274a91bad4dfc6b1d75f77be76f8129696697e..cd982bbb179c279d50fe28945e23654a011b459d 100644 (file)
@@ -1081,12 +1081,12 @@ var SN = { // StatusNet
                 label.attr('title', label.text());
 
                 check.change(function () {
-                    if (check.prop('checked') === true || $.cookie(SN.C.S.NoticeDataGeoCookie) === null) {
+                    if (check.prop('checked') === true || $.cookie(SN.C.S.NoticeDataGeoCookie) === undefined) {
                         label
                             .attr('title', NoticeDataGeo_text.ShareDisable)
                             .addClass('checked');
 
-                        if ($.cookie(SN.C.S.NoticeDataGeoCookie) === null || $.cookie(SN.C.S.NoticeDataGeoCookie) == 'disabled') {
+                        if ($.cookie(SN.C.S.NoticeDataGeoCookie) === undefined || $.cookie(SN.C.S.NoticeDataGeoCookie) == 'disabled') {
                             if (navigator.geolocation) {
                                 SN.U.NoticeGeoStatus(form, 'Requesting location from browser...');
                                 navigator.geolocation.getCurrentPosition(
@@ -1297,7 +1297,7 @@ var SN = { // StatusNet
              * @fixme what is this?
              */
             Delete: function () {
-                $.cookie(SN.C.S.StatusNetInstance, null);
+                $.removeCookie(SN.C.S.StatusNetInstance);
             }
         },
 
index 29fadbf8836894c989064860000652653788fbd5..7f3aea9c1a74115d2bbaccf4787faff1ad1ac4fc 100644 (file)
@@ -205,7 +205,7 @@ class Action extends HTMLOutputter // lawsuit
      *
      * @return nothing
      */
-    function showPage()
+    public function showPage()
     {
         if (GNUsocial::isAjax()) {
             self::showAjax();
index d4c01232ec283e8e97ae5d54dcb96040de37df60..f3383efda5b4db936a75e8611a09147aa9a0cfc9 100644 (file)
@@ -281,19 +281,20 @@ class ActivityUtils
     static function validateUri($uri)
     {
         // Check mailto: URIs first
+        $validate = new Validate();
 
         if (preg_match('/^mailto:(.*)$/', $uri, $match)) {
-            return Validate::email($match[1], common_config('email', 'check_domain'));
+            return $validate->email($match[1], common_config('email', 'check_domain'));
         }
 
-        if (Validate::uri($uri)) {
+        if ($validate->uri($uri)) {
             return true;
         }
 
         // Possibly an upstream bug; tag: URIs aren't validated properly
         // unless you explicitly ask for them. All other schemes are accepted
         // for basic URI validation without asking.
-        if (Validate::uri($uri, array('allowed_scheme' => array('tag')))) {
+        if ($validate->uri($uri, array('allowed_scheme' => array('tag')))) {
             return true;
         }
 
index 724447f120cbadc7df1c66bd09ee095d597ba0fb..fae8f33d0e0707150612f70c7e2be0cb56d30893 100644 (file)
@@ -248,7 +248,7 @@ class ApiAction extends Action
 
         $twitter_user['friends_count'] = $profile->subscriptionCount();
 
-        $twitter_user['created_at'] = $this->dateTwitter($profile->created);
+        $twitter_user['created_at'] = self::dateTwitter($profile->created);
 
         $timezone = 'UTC';
 
@@ -322,7 +322,7 @@ class ApiAction extends Action
         $twitter_status = array();
         $twitter_status['text'] = $notice->content;
         $twitter_status['truncated'] = false; # Not possible on StatusNet
-        $twitter_status['created_at'] = $this->dateTwitter($notice->created);
+        $twitter_status['created_at'] = self::dateTwitter($notice->created);
         try {
             // We could just do $notice->reply_to but maybe the future holds a
             // different story for parenting.
@@ -366,12 +366,13 @@ class ApiAction extends Action
         $twitter_status['in_reply_to_screen_name'] =
             ($replier_profile) ? $replier_profile->nickname : null;
 
-        if (isset($notice->lat) && isset($notice->lon)) {
+        try {
+            $notloc = Notice_location::locFromStored($notice);
             // This is the format that GeoJSON expects stuff to be in
             $twitter_status['geo'] = array('type' => 'Point',
-                                           'coordinates' => array((float) $notice->lat,
-                                                                  (float) $notice->lon));
-        } else {
+                                           'coordinates' => array((float) $notloc->lat,
+                                                                  (float) $notloc->lon));
+        } catch (ServerException $e) {
             $twitter_status['geo'] = null;
         }
 
@@ -440,8 +441,8 @@ class ApiAction extends Action
         $twitter_group['homepage'] = $group->homepage;
         $twitter_group['description'] = $group->description;
         $twitter_group['location'] = $group->location;
-        $twitter_group['created'] = $this->dateTwitter($group->created);
-        $twitter_group['modified'] = $this->dateTwitter($group->modified);
+        $twitter_group['created'] = self::dateTwitter($group->created);
+        $twitter_group['modified'] = self::dateTwitter($group->modified);
 
         return $twitter_group;
     }
@@ -547,13 +548,14 @@ class ApiAction extends Action
             $entry['pubDate'] = common_date_rfc2822($notice->created);
             $entry['guid'] = $entry['link'];
 
-            if (isset($notice->lat) && isset($notice->lon)) {
+            try {
+                $notloc = Notice_location::locFromStored($notice);
                 // This is the format that GeoJSON expects stuff to be in.
                 // showGeoRSS() below uses it for XML output, so we reuse it
                 $entry['geo'] = array('type' => 'Point',
-                                      'coordinates' => array((float) $notice->lat,
-                                                             (float) $notice->lon));
-            } else {
+                                      'coordinates' => array((float) $notloc->lat,
+                                                             (float) $notloc->lon));
+            } catch (ServerException $e) {
                 $entry['geo'] = null;
             }
 
@@ -997,7 +999,13 @@ class ApiAction extends Action
         $statuses = array();
 
         if (is_array($notice)) {
-            $notice = new ArrayWrapper($notice);
+            //FIXME: make everything calling showJsonTimeline use only Notice objects
+            common_debug('ArrayWrapper avoidance in progress! Beep boop, make showJsonTimeline only receive Notice objects!');
+            $ids = array();
+            foreach ($notice as $n) {
+                $ids[] = $n->getID();
+            }
+            $notice = Notice::multiGet('id', $ids);
         }
 
         while ($notice->fetch()) {
@@ -1196,7 +1204,7 @@ class ApiAction extends Action
         $this->endDocument('xml');
     }
 
-    function dateTwitter($dt)
+    static function dateTwitter($dt)
     {
         $dateStr = date('d F Y H:i:s', strtotime($dt));
         $d = new DateTime($dateStr, new DateTimeZone('UTC'));
index da412df8d298bfe9a55a946a37b4df71c7a79ecc..6f4403dec73860aaebf9fbb1e00776e85703cf50 100644 (file)
@@ -26,20 +26,20 @@ require_once 'OAuth.php';
  */
 class ApiGNUsocialOAuthDataStore extends OAuthDataStore
 {
-    function lookup_consumer($consumerKey)
+    function lookup_consumer($consumer_key)
     {
-        $con = Consumer::getKV('consumer_key', $consumerKey);
+        $con = Consumer::getKV('consumer_key', $consumer_key);
 
         if (!$con instanceof Consumer) {
 
             // Create an anon consumer and anon application if one
             // doesn't exist already
-            if ($consumerKey == 'anonymous') {
+            if ($consumer_key == 'anonymous') {
 
                 common_debug("API OAuth - creating anonymous consumer");
                 $con = new Consumer();
-                $con->consumer_key    = $consumerKey;
-                $con->consumer_secret = $consumerKey;
+                $con->consumer_key    = $consumer_key;
+                $con->consumer_secret = $consumer_key;
                 $con->created         = common_sql_now();
 
                 $result = $con->insert();
@@ -388,7 +388,7 @@ class ApiGNUsocialOAuthDataStore extends OAuthDataStore
      *
      * @return OAuthToken   $token a new unauthorized OAuth request token
      */
-    function new_request_token($consumer, $callback)
+    function new_request_token($consumer, $callback = null)
     {
         $t = new Token();
         $t->consumer_key = $consumer->key;
@@ -473,13 +473,13 @@ class ApiGNUsocialOAuthDataStore extends OAuthDataStore
      * @param type $token_key
      * @return OAuthToken
      */
-    function lookup_token($consumer, $token_type, $token_key)
+    function lookup_token($consumer, $token_type, $token)
     {
         $t = new Token();
         if (!is_null($consumer)) {
             $t->consumer_key = $consumer->key;
         }
-        $t->tok = $token_key;
+        $t->tok = $token;
         $t->type = ($token_type == 'access') ? 1 : 0;
         if ($t->find(true)) {
             return new OAuthToken($t->tok, $t->secret);
index d0c9256df714ed39763075d061b38542b4f79677..ab51a73096c50c637dd6cc078f1c5fddde2a5daa 100644 (file)
  * @link      http://status.net/
  */
 
-if (!defined('STATUSNET') && !defined('LACONICA')) {
-    exit(1);
-}
-
-require_once INSTALLDIR . '/lib/widget.php';
-
-define('APPS_PER_PAGE', 20);
+if (!defined('GNUSOCIAL')) { exit(1); }
 
 /**
  * Widget to show a list of OAuth applications
@@ -52,16 +46,12 @@ class ApplicationList extends Widget
     /** Owner of this list */
     var $owner = null;
 
-    /** Action object using us. */
-    var $action = null;
-
-    function __construct($application, $owner=null, $action=null)
+    function __construct($application, Profile $owner, Action $out=null)
     {
-        parent::__construct($action);
+        parent::__construct($out);
 
         $this->application = $application;
         $this->owner       = $owner;
-        $this->action      = $action;
     }
 
     function show()
@@ -75,7 +65,7 @@ class ApplicationList extends Widget
             if($cnt > APPS_PER_PAGE) {
                 break;
             }
-            $this->showapplication();
+            $this->showApplication();
         }
 
         $this->out->elementEnd('ul');
@@ -85,8 +75,6 @@ class ApplicationList extends Widget
 
     function showApplication()
     {
-        $user = common_current_user();
-
         $this->out->elementStart('li', array('class' => 'application h-entry',
                                              'id'    => 'oauthclient-' . $this->application->id));
 
@@ -119,140 +107,3 @@ class ApplicationList extends Widget
         return;
     }
 }
-
-/**
- * Widget to show a list of connected OAuth clients
- *
- * @category Application
- * @package  StatusNet
- * @author   Zach Copley <zach@status.net>
- * @license  http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
- * @link     http://status.net/
- */
-class ConnectedAppsList extends Widget
-{
-    /** Current connected application query */
-    var $connection = null;
-
-    /** Owner of this list */
-    var $owner = null;
-
-    /** Action object using us. */
-    var $action = null;
-
-    function __construct($connection, $owner=null, $action=null)
-    {
-        parent::__construct($action);
-
-        common_debug("ConnectedAppsList constructor");
-
-        $this->connection = $connection;
-        $this->owner       = $owner;
-        $this->action      = $action;
-    }
-
-    /* Override this in subclasses. */
-    function showOwnerControls()
-    {
-        return;
-    }
-
-    function show()
-    {
-        $this->out->elementStart('ul', 'applications');
-
-        $cnt = 0;
-
-        while ($this->connection->fetch()) {
-            $cnt++;
-            if($cnt > APPS_PER_PAGE) {
-                break;
-            }
-            $this->showConnection();
-        }
-
-        $this->out->elementEnd('ul');
-
-        return $cnt;
-    }
-
-    function showConnection()
-    {
-        $app = Oauth_application::getKV('id', $this->connection->application_id);
-
-        $this->out->elementStart('li', array('class' => 'application h-entry',
-                                             'id'    => 'oauthclient-' . $app->id));
-
-        $this->out->elementStart('a', array('href' => $app->source_url,
-                                            'class' => 'h-card p-name'));
-
-        if (!empty($app->icon)) {
-            $this->out->element('img', array('src' => $app->icon,
-                                             'class' => 'avatar u-photo'));
-        }
-        if ($app->name != 'anonymous') {
-            $this->out->text($app->name);
-        } else {
-            // TRANS: Name for an anonymous application in application list.
-            $this->out->element('span', 'p-name', _('Unknown application'));
-        }
-        $this->out->elementEnd('a');
-
-        if ($app->name != 'anonymous') {
-            // @todo FIXME: i18n trouble.
-            // TRANS: Message has a leading space and a trailing space. Used in application list.
-            // TRANS: Before this message the application name is put, behind it the organisation that manages it.
-            $this->out->raw(_(' by '));
-
-            $this->out->element('a', array('href' => $app->homepage,
-                                           'class' => 'h-card'),
-                                $app->organization);
-        }
-
-        // TRANS: Application access type
-        $readWriteText = _('read-write');
-        // TRANS: Application access type
-        $readOnlyText = _('read-only');
-
-        $access = ($this->connection->access_type & Oauth_application::$writeAccess)
-            ? $readWriteText : $readOnlyText;
-        $modifiedDate = common_date_string($this->connection->modified);
-        // TRANS: Used in application list. %1$s is a modified date, %2$s is access type ("read-write" or "read-only")
-        $txt = sprintf(_('Approved %1$s - "%2$s" access.'), $modifiedDate, $access);
-
-        // @todo FIXME: i18n trouble.
-        $this->out->raw(" - $txt");
-        if (!empty($app->description)) {
-            $this->out->element(
-                'p', array('class' => 'application_description'),
-                $app->description
-            );
-        }
-        $this->out->element(
-            'p', array(
-            'class' => 'access_token'),
-            // TRANS: Access token in the application list.
-            // TRANS: %s are the first 7 characters of the access token.
-            sprintf(_('Access token starting with: %s'), substr($this->connection->token, 0, 7))
-        );
-
-        $this->out->elementStart(
-            'form',
-            array(
-                'id' => 'form_revoke_app',
-                'class' => 'form_revoke_app',
-                'method' => 'POST',
-                'action' => common_local_url('oauthconnectionssettings')
-            )
-        );
-        $this->out->elementStart('fieldset');
-        $this->out->hidden('oauth_token', $this->connection->token);
-        $this->out->hidden('token', common_session_token());
-        // TRANS: Button label in application list to revoke access to user data.
-        $this->out->submit('revoke', _m('BUTTON','Revoke'));
-        $this->out->elementEnd('fieldset');
-        $this->out->elementEnd('form');
-
-        $this->out->elementEnd('li');
-    }
-}
index 292bc97e8584ccfe0819bb93522d175051a5451d..b7e1ed1b41c1178cb8b1ff1f44c4b670f3f06f19 100644 (file)
@@ -113,10 +113,12 @@ class AtomNoticeFeed extends Atom10Feed
             foreach ($notices as $notice) {
                 $this->addEntryFromNotice($notice);
             }
-        } else {
+        } elseif ($notices instanceof Notice) {
             while ($notices->fetch()) {
                 $this->addEntryFromNotice($notices);
             }
+        } else {
+            throw new ServerException('addEntryFromNotices got neither an array nor a Notice object');
         }
     }
 
@@ -125,7 +127,7 @@ class AtomNoticeFeed extends Atom10Feed
      *
      * @param Notice $notice a Notice to add
      */
-    function addEntryFromNotice($notice)
+    function addEntryFromNotice(Notice $notice)
     {
         try {
             $source = $this->showSource();
index 66f11ca1a9507a5850bdb11418314b8407a39020..c33b0ef8a8b3dac054248cbb8390668482c41f87 100644 (file)
@@ -201,13 +201,13 @@ abstract class AuthenticationPlugin extends Plugin
         }
     }
 
-    function onStartChangePassword($user,$oldpassword,$newpassword)
+    function onStartChangePassword(Profile $target ,$oldpassword, $newpassword)
     {
         if($this->password_changeable){
             $user_username = new User_username();
-            $user_username->user_id=$user->id;
+            $user_username->user_id = $target->getID();
             $user_username->provider_name=$this->provider_name;
-            if($user_username->find() && $user_username->fetch()){
+            if ($user_username->find(true)) {
                 $authenticated = $this->checkPassword($user_username->username, $oldpassword);
                 if($authenticated){
                     $result = $this->changePassword($user_username->username,$oldpassword,$newpassword);
diff --git a/lib/connectedappslist.php b/lib/connectedappslist.php
new file mode 100644 (file)
index 0000000..c2a27e7
--- /dev/null
@@ -0,0 +1,163 @@
+<?php
+/**
+ * StatusNet, the distributed open-source microblogging tool
+ *
+ * Widget to show a list of OAuth applications
+ *
+ * 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  Application
+ * @package   StatusNet
+ * @author    Zach Copley <zach@status.net>
+ * @copyright 2008-2010 StatusNet, Inc.
+ * @license   http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
+ * @link      http://status.net/
+ */
+
+if (!defined('GNUSOCIAL')) { exit(1); }
+
+/**
+ * Widget to show a list of connected OAuth clients
+ *
+ * @category Application
+ * @package  StatusNet
+ * @author   Zach Copley <zach@status.net>
+ * @license  http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
+ * @link     http://status.net/
+ */
+class ConnectedAppsList extends Widget
+{
+    /** Current connected application query */
+    var $connection = null;
+
+    /** Owner of this list */
+    var $owner = null;
+
+    function __construct($connection, Profile $owner, Action $out=null)
+    {
+        parent::__construct($out);
+
+        common_debug("ConnectedAppsList constructor");
+
+        $this->connection = $connection;
+        $this->owner      = $owner;
+    }
+
+    /* Override this in subclasses. */
+    function showOwnerControls()
+    {
+        return;
+    }
+
+    function show()
+    {
+        $this->out->elementStart('ul', 'applications');
+
+        $cnt = 0;
+
+        while ($this->connection->fetch()) {
+            $cnt++;
+            if($cnt > APPS_PER_PAGE) {
+                break;
+            }
+            $this->showConnection();
+        }
+
+        $this->out->elementEnd('ul');
+
+        return $cnt;
+    }
+
+    function showConnection()
+    {
+        $app = Oauth_application::getKV('id', $this->connection->application_id);
+
+        $this->out->elementStart('li', array('class' => 'application h-entry',
+                                             'id'    => 'oauthclient-' . $app->id));
+
+        $this->out->elementStart('a', array('href' => $app->source_url,
+                                            'class' => 'h-card p-name'));
+
+        if (!empty($app->icon)) {
+            $this->out->element('img', array('src' => $app->icon,
+                                             'class' => 'avatar u-photo'));
+        }
+        if ($app->name != 'anonymous') {
+            $this->out->text($app->name);
+        } else {
+            // TRANS: Name for an anonymous application in application list.
+            $this->out->element('span', 'p-name', _('Unknown application'));
+        }
+        $this->out->elementEnd('a');
+
+        if ($app->name != 'anonymous') {
+            // @todo FIXME: i18n trouble.
+            // TRANS: Message has a leading space and a trailing space. Used in application list.
+            // TRANS: Before this message the application name is put, behind it the organisation that manages it.
+            $this->out->raw(_(' by '));
+
+            $this->out->element('a', array('href' => $app->homepage,
+                                           'class' => 'h-card'),
+                                $app->organization);
+        }
+
+        // TRANS: Application access type
+        $readWriteText = _('read-write');
+        // TRANS: Application access type
+        $readOnlyText = _('read-only');
+
+        $access = ($this->connection->access_type & Oauth_application::$writeAccess)
+            ? $readWriteText : $readOnlyText;
+        $modifiedDate = common_date_string($this->connection->modified);
+        // TRANS: Used in application list. %1$s is a modified date, %2$s is access type ("read-write" or "read-only")
+        $txt = sprintf(_('Approved %1$s - "%2$s" access.'), $modifiedDate, $access);
+
+        // @todo FIXME: i18n trouble.
+        $this->out->raw(" - $txt");
+        if (!empty($app->description)) {
+            $this->out->element(
+                'p', array('class' => 'application_description'),
+                $app->description
+            );
+        }
+        $this->out->element(
+            'p', array(
+            'class' => 'access_token'),
+            // TRANS: Access token in the application list.
+            // TRANS: %s are the first 7 characters of the access token.
+            sprintf(_('Access token starting with: %s'), substr($this->connection->token, 0, 7))
+        );
+
+        $this->out->elementStart(
+            'form',
+            array(
+                'id' => 'form_revoke_app',
+                'class' => 'form_revoke_app',
+                'method' => 'POST',
+                'action' => common_local_url('oauthconnectionssettings')
+            )
+        );
+        $this->out->elementStart('fieldset');
+        $this->out->hidden('oauth_token', $this->connection->token);
+        $this->out->hidden('token', common_session_token());
+        // TRANS: Button label in application list to revoke access to user data.
+        $this->out->submit('revoke', _m('BUTTON','Revoke'));
+        $this->out->elementEnd('fieldset');
+        $this->out->elementEnd('form');
+
+        $this->out->elementEnd('li');
+    }
+}
index 45c4b694d2e4848237bcae4563461fbb79ab55be..9fb77eed9645c380beb0901042e21a7854048321 100644 (file)
@@ -72,7 +72,7 @@ class DBQueueManager extends QueueManager
     public function poll()
     {
         //$this->_log(LOG_DEBUG, 'Checking for notices...');
-        $qi = Queue_item::top($this->activeQueues());
+        $qi = Queue_item::top($this->activeQueues(), $this->getIgnoredTransports());
         if (!$qi instanceof Queue_item) {
             //$this->_log(LOG_DEBUG, 'No notices waiting; idling.');
             return false;
index cf40f678ed017b4a375f71876e50d5b0b0e189d8..5bec29cc5233880c169f0dcf3da8828748c23302 100644 (file)
@@ -129,7 +129,7 @@ $default =
               'biolimit' => null,
               'changenick' => false,
               'backup' => true,
-              'restore' => true,
+              'restore' => false,
               'delete' => false,
               'move' => true),
         'image' =>
diff --git a/lib/deletenoticeform.php b/lib/deletenoticeform.php
new file mode 100644 (file)
index 0000000..d060046
--- /dev/null
@@ -0,0 +1,67 @@
+<?php
+
+if (!defined('GNUSOCIAL')) { exit(1); }
+
+class DeletenoticeForm extends Form
+{
+    protected $notice = null;
+
+    function __construct(HTMLOutputter $out=null, array $formOpts=array())
+    {
+        if (!array_key_exists('notice', $formOpts) || !$formOpts['notice'] instanceof Notice) {
+            throw new ServerException('No notice provided to DeletenoticeForm');
+        }
+
+        parent::__construct($out);
+
+        $this->notice = $formOpts['notice'];
+    }
+
+    function id()
+    {
+        return 'form_notice_delete-' . $this->notice->getID();
+    }
+
+    function formClass()
+    {
+        return 'form_settings';
+    }
+
+    function action()
+    {
+        return common_local_url('deletenotice', array('notice' => $this->notice->getID()));
+    }
+
+    function formLegend()
+    {
+        $this->out->element('legend', null, _('Delete notice'));
+    }
+
+    function formData()
+    {
+        $this->out->element('p', null, _('Are you sure you want to delete this notice?'));
+    }
+
+    /**
+     * Action elements
+     *
+     * @return void
+     */
+    function formActions()
+    {
+        $this->out->submit('form_action-no',
+                      // TRANS: Button label on the delete notice form.
+                      _m('BUTTON','No'),
+                      'submit form_action-primary',
+                      'no',
+                      // TRANS: Submit button title for 'No' when deleting a notice.
+                      _('Do not delete this notice.'));
+        $this->out->submit('form_action-yes',
+                      // TRANS: Button label on the delete notice form.
+                      _m('BUTTON','Yes'),
+                      'submit form_action-secondary',
+                      'yes',
+                      // TRANS: Submit button title for 'Yes' when deleting a notice.
+                      _('Delete this notice.'));
+    }
+}
index 1baaf9331f2bf7e9752ec8565ca6ab08c1efd511..65866af4184d20fe43e48fdfeeba64156a5ee46b 100644 (file)
@@ -74,8 +74,13 @@ class DelUserQueueHandler extends QueueHandler
             $qm = QueueManager::get();
             $qm->enqueue($user, 'deluser');
         } else {
-            // Out of notices? Let's finish deleting this guy!
-            $user->delete();
+            // Out of notices? Let's finish deleting this profile!
+            try {
+                $user->getProfile()->delete();
+            } catch (UserNoProfileException $e) {
+                // in case a profile didn't exist for some reason, just delete the User directly
+                $user->delete();
+            }
             common_log(LOG_INFO, "User $user->id $user->nickname deleted.");
             return true;
         }
index 5cf05d4a324fede134e48eb9f0024a979f80b6f8..7d74fc47130eaf20f6bb23b116e21eab8f9d6664 100644 (file)
@@ -50,7 +50,7 @@ class FormAction extends ManagedAction
     protected function prepare(array $args=array()) {
         parent::prepare($args);
 
-        $this->form = $this->form ?: $this->action;
+        $this->form = $this->form ?: ucfirst($this->action);
         $this->args['form'] = $this->form;
 
         $this->type = !is_null($this->type) ? $this->type : $this->trimmed('type');
index da43297d1050222d0ec1b42f10ee33d601b44663..d749d23bdff32c8e3144ffb4322f7ebd232dc3c2 100644 (file)
@@ -23,7 +23,7 @@ define('GNUSOCIAL_ENGINE', 'GNU social');
 define('GNUSOCIAL_ENGINE_URL', 'https://www.gnu.org/software/social/');
 
 define('GNUSOCIAL_BASE_VERSION', '1.2.0');
-define('GNUSOCIAL_LIFECYCLE', 'alpha1'); // 'dev', 'alpha[0-9]+', 'beta[0-9]+', 'rc[0-9]+', 'release'
+define('GNUSOCIAL_LIFECYCLE', 'alpha2'); // 'dev', 'alpha[0-9]+', 'beta[0-9]+', 'rc[0-9]+', 'release'
 
 define('GNUSOCIAL_VERSION', GNUSOCIAL_BASE_VERSION . '-' . GNUSOCIAL_LIFECYCLE);
 
@@ -37,6 +37,7 @@ define('NOTICES_PER_PAGE', 20);
 define('PROFILES_PER_PAGE', 20);
 define('MESSAGES_PER_PAGE', 20);
 define('GROUPS_PER_PAGE', 20);
+define('APPS_PER_PAGE', 20);
 
 define('GROUPS_PER_MINILIST', 8);
 define('PROFILES_PER_MINILIST', 8);
@@ -136,9 +137,18 @@ spl_autoload_register('GNUsocial_class_autoload');
  * and is available here: http://www.php-fig.org/psr/psr-0/
 */
 spl_autoload_register(function($class){
-    $file = INSTALLDIR.'/extlib/'.preg_replace('{\\\\|_(?!.*\\\\)}', DIRECTORY_SEPARATOR, ltrim($class, '\\')).'.php';
+    $class_path = preg_replace('{\\\\|_(?!.*\\\\)}', DIRECTORY_SEPARATOR, ltrim($class, '\\')).'.php';
+    $file = INSTALLDIR.'/extlib/'.$class_path;
     if (file_exists($file)) {
         require_once $file;
+        return;
+    }
+
+    # Try if the system has this external library
+    $file = '/usr/share/php/'.$class_path;
+    if (file_exists($file)) {
+        require_once $file;
+        return;
     }
 });
 
index f87043ac063840ced2c0d16fed372e1d2f0e1a45..5dd0cfcfa766c9843baa364a4f5c14f3d8f2a031 100644 (file)
@@ -36,35 +36,6 @@ class GalleryAction extends ProfileAction
         parent::handle();
     }
 
-    protected function doPreparation()
-    {
-        // showstream requires a nickname
-        $nickname_arg = $this->arg('nickname');
-        $nickname     = common_canonical_nickname($nickname_arg);
-
-        // Permanent redirect on non-canonical nickname
-
-        if ($nickname_arg != $nickname) {
-            $args = array('nickname' => $nickname);
-            if ($this->arg('page') && $this->arg('page') != 1) {
-                $args['page'] = $this->arg['page'];
-            }
-            common_redirect(common_local_url($this->getActionName(), $args), 301);
-        }
-        $this->user = User::getKV('nickname', $nickname);
-
-        if (!$this->user) {
-            $group = Local_group::getKV('nickname', $nickname);
-            if ($group instanceof Local_group) {
-                common_redirect($group->getProfile()->getUrl());
-            }
-            // TRANS: Client error displayed when calling a profile action without specifying a user.
-            $this->clientError(_('No such user.'), 404);
-        }
-
-        $this->target = $this->user->getProfile();
-    }
-
     function showContent()
     {
         $this->showTagsDropdown();
index 2d1a3af02efba2aa68f50ce796c9fa6d4078ae78..68cfea48e7e01051eb26cbc72b1caad98887a72f 100644 (file)
@@ -189,6 +189,8 @@ class ImageFile
 
          case UPLOAD_ERR_NO_FILE:
             // No file; probably just a non-AJAX submission.
+            throw new ClientException(_('No file uploaded.'));
+
          default:
             common_log(LOG_ERR, __METHOD__ . ": Unknown upload error " . $_FILES[$param]['error']);
             // TRANS: Exception thrown when uploading an image fails for an unknown reason.
index 2da4fa961a6cf4962a1dafbdcbb80b72235334b4..742147dbbdc90ae3502fd88f9c62a3a8273d6d45 100644 (file)
@@ -126,17 +126,6 @@ abstract class ImPlugin extends Plugin
      */
     abstract function daemonScreenname();
 
-    /**
-     * get the microid uri of a given screenname
-     *
-     * @param string $screenname screenname
-     *
-     * @return string microid uri
-     */
-    function microiduri($screenname)
-    {
-        return $this->transport . ':' . $screenname;
-    }
     //========================UTILITY FUNCTIONS USEFUL TO IMPLEMENTATIONS - MISC ========================\
 
     /**
@@ -254,11 +243,11 @@ abstract class ImPlugin extends Plugin
      *
      * @param string $screenname screenname sending to
      * @param string $code the confirmation code
-     * @param User $user user sending to
+     * @param Profile $target For whom the code is valid for
      *
      * @return boolean success value
      */
-    function sendConfirmationCode($screenname, $code, $user)
+    function sendConfirmationCode($screenname, $code, Profile $target)
     {
         // TRANS: Body text for confirmation code e-mail.
         // TRANS: %1$s is a user nickname, %2$s is the StatusNet sitename,
@@ -269,7 +258,7 @@ abstract class ImPlugin extends Plugin
           ' . (If you cannot click it, copy-and-paste it into the ' .
           'address bar of your browser). If that user is not you, ' .
           'or if you did not request this confirmation, just ignore this message.'),
-          $user->nickname, common_config('site', 'name'), $this->getDisplayName(), common_local_url('confirmaddress', null, array('code' => $code)));
+          $target->getNickname(), common_config('site', 'name'), $this->getDisplayName(), common_local_url('confirmaddress', null, array('code' => $code)));
 
         return $this->sendMessage($screenname, $body);
     }
@@ -563,35 +552,20 @@ abstract class ImPlugin extends Plugin
         return true;
     }
 
-    function onEndShowHeadElements($action)
+    function onEndShowHeadElements(Action $action)
     {
-        $aname = $action->trimmed('action');
-
-        if ($aname == 'shownotice') {
+        if ($action instanceof ShownoticeAction) {
 
             $user_im_prefs = new User_im_prefs();
-            $user_im_prefs->user_id = $action->profile->id;
+            $user_im_prefs->user_id = $action->notice->getProfile()->getID();
             $user_im_prefs->transport = $this->transport;
 
-            if ($user_im_prefs->find() && $user_im_prefs->fetch() && $user_im_prefs->microid && $action->notice->uri) {
-                $id = new Microid($this->microiduri($user_im_prefs->screenname),
-                                  $action->notice->uri);
-                $action->element('meta', array('name' => 'microid',
-                                             'content' => $id->toString()));
-            }
-
-        } else if ($aname == 'showstream') {
+        } elseif ($action instanceof ShowstreamAction) {
 
             $user_im_prefs = new User_im_prefs();
-            $user_im_prefs->user_id = $action->user->id;
+            $user_im_prefs->user_id = $action->getTarget()->getID();
             $user_im_prefs->transport = $this->transport;
 
-            if ($user_im_prefs->find() && $user_im_prefs->fetch() && $user_im_prefs->microid && $action->profile->profileurl) {
-                $id = new Microid($this->microiduri($user_im_prefs->screenname),
-                                  $action->selfUrl());
-                $action->element('meta', array('name' => 'microid',
-                                               'content' => $id->toString()));
-            }
         }
     }
 
@@ -620,11 +594,11 @@ abstract class ImPlugin extends Plugin
             'daemonScreenname' => $this->daemonScreenname());
     }
 
-    function onSendImConfirmationCode($transport, $screenname, $code, $user)
+    function onSendImConfirmationCode($transport, $screenname, $code, Profile $target)
     {
         if($transport == $this->transport)
         {
-            $this->sendConfirmationCode($screenname, $code, $user);
+            $this->sendConfirmationCode($screenname, $code, $target);
             return false;
         }
     }
index 0a46b2a50815e697647d7c87371d9faf3bcf0b42..29a43833022c902ecaf7e0c0bd00e4de6e10a738 100644 (file)
@@ -622,7 +622,7 @@ abstract class Installer
 
         $this->updateStatus("GNU social has been installed at $link");
         $this->updateStatus(
-            '<strong>DONE!</strong> You can visit your <a href="'.htmlspecialchars($link).'">new GNU social site</a> (log in as "'.htmlspecialchars($this->adminNick).'"). If this is your first GNU social install, make your experience the best possible by visiting our resource site to join the <a href="https://gnu.io/social/resources/">mailing list or IRC.</a>. <a href="'.htmlspecialchars($link).'/doc/faq/">FAQ is found here</a>.'
+            '<strong>DONE!</strong> You can visit your <a href="'.htmlspecialchars($link).'">new GNU social site</a> (log in as "'.htmlspecialchars($this->adminNick).'"). If this is your first GNU social install, make your experience the best possible by visiting our resource site to join the <a href="https://gnu.io/social/resources/">mailing list or IRC</a>. <a href="'.htmlspecialchars($link).'/doc/faq">FAQ is found here</a>.'
         );
 
         return true;
index 188792d02a0511fab7493318435a05604a8bb50a..7ac743bfee8d58fa9dae64de2bf3a0af0cfae725 100644 (file)
@@ -47,11 +47,13 @@ require_once 'Mail.php';
 function mail_backend()
 {
     static $backend = null;
+    global $_PEAR;
 
     if (!$backend) {
-        $backend = Mail::factory(common_config('mail', 'backend'),
+        $mail = new Mail();
+        $backend = $mail->factory(common_config('mail', 'backend'),
                                  common_config('mail', 'params') ?: array());
-        if (PEAR::isError($backend)) {
+        if ($_PEAR->isError($backend)) {
             common_server_error($backend->getMessage(), 500);
         }
     }
diff --git a/lib/microid.php b/lib/microid.php
deleted file mode 100644 (file)
index e2e7d76..0000000
+++ /dev/null
@@ -1,97 +0,0 @@
-<?php
-/**
- * StatusNet, the distributed open-source microblogging tool
- *
- * Microid class
- *
- * 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  ID
- * @package   StatusNet
- * @author    Evan Prodromou <evan@status.net>
- * @copyright 2008 StatusNet, Inc.
- * @license   http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
- * @link      http://status.net/
- */
-
-if (!defined('STATUSNET') && !defined('LACONICA')) {
-    exit(1);
-}
-
-/**
- * A class for microids
- *
- * @category ID
- * @package  StatusNet
- * @author   Evan Prodromou <evan@status.net>
- * @license  http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
- * @link     http://status.net/
- * @see      http://microid.org/
- */
-
-class Microid
-{
-    /** Agent part of the ID. */
-
-    var $agent = null;
-
-    /** Resource part of the ID. */
-
-    var $resource = null;
-
-    /**
-     * Constructor
-     *
-     * @param string $agent    Agent of the ID
-     * @param string $resource Resource part
-     */
-
-    function __construct($agent, $resource)
-    {
-        $this->agent    = $agent;
-        $this->resource = $resource;
-
-    }
-
-    /**
-     * Generate a MicroID string
-     *
-     * @return string MicroID for agent and resource
-     */
-
-    function toString()
-    {
-        $agent_proto    = $this->_getProto($this->agent);
-        $resource_proto = $this->_getProto($this->resource);
-
-        return $agent_proto.'+'.$resource_proto.':sha1:'.
-          sha1(sha1($this->agent).sha1($this->resource));
-    }
-
-    /**
-     * Utility for getting the protocol part of a URI
-     *
-     * @param string $uri URI to parse
-     *
-     * @return string scheme part of the URI
-     */
-
-    function _getProto($uri)
-    {
-        $colon = strpos($uri, ':');
-        return substr($uri, 0, $colon);
-    }
-}
index f25613b9a96988972946b96b024cda003c735697..dc171409f41e8042040c38a174a242d3c0c9f3cd 100644 (file)
@@ -368,18 +368,19 @@ class NoticeListItem extends Widget
      */
     function showNoticeLocation()
     {
-        $id = $this->notice->id;
-
-        $location = $this->notice->getLocation();
-
-        if (empty($location)) {
+        return;
+        try {
+            $location = Notice_location::locFromStored($this->notice);
+        } catch (NoResultException $e) {
+            return;
+        } catch (ServerException $e) {
             return;
         }
 
         $name = $location->getName();
 
-        $lat = $this->notice->lat;
-        $lon = $this->notice->lon;
+        $lat = $location->lat;
+        $lon = $location->lon;
         $latlon = (!empty($lat) && !empty($lon)) ? $lat.';'.$lon : '';
 
         if (empty($name)) {
index 39c19d551f0500110f8c8d1520eb1a6233694d12..ed8921860efa40744845d6d5f0c32ed01b15d7bf 100644 (file)
@@ -4,6 +4,7 @@ if (!defined('GNUSOCIAL')) { exit(1); }
 
 abstract class NoticestreamAction extends ProfileAction
 {
+    protected $notice = null;   // holds the stream result
 
     protected function prepare(array $args=array()) {
         parent::prepare($args);
index c861c4f57f90fb6ceee594b719d2be842cc34acc..46b4661e897ec1f8242f1185d5d7a885c6b493e9 100644 (file)
@@ -27,9 +27,7 @@
  * @link      http://status.net/
  */
 
-if (!defined('STATUSNET') && !defined('LACONICA')) {
-    exit(1);
-}
+if (!defined('GNUSOCIAL')) { exit(1); }
 
 /**
  * Personal tag cloud section
@@ -42,12 +40,12 @@ if (!defined('STATUSNET') && !defined('LACONICA')) {
  */
 class PersonalTagCloudSection extends TagCloudSection
 {
-    var $user = null;
+    protected $profile = null;
 
-    function __construct($out=null, $user=null)
+    function __construct(Profile $profile, HTMLOutputter $out=null)
     {
         parent::__construct($out);
-        $this->user = $user;
+        $this->profile = $profile;
     }
 
     function title()
@@ -80,7 +78,7 @@ class PersonalTagCloudSection extends TagCloudSection
 
         $tag = Memcached_DataObject::cachedQuery('Notice_tag',
                                                  sprintf($qry,
-                                                         $this->user->id),
+                                                         $this->profile->getID()),
                                                  3600);
         return $tag;
     }
index d98bcd7f7433387a45715ab706bfda5b4a1115a0..3dc28a7cc48fd56ec6f4de30588660373e2d1584 100644 (file)
@@ -48,6 +48,36 @@ abstract class ProfileAction extends ManagedAction
 
     protected $target  = null;    // Profile that we're showing
 
+    protected function doPreparation()
+    {
+        // showstream requires a nickname
+        $nickname_arg = $this->trimmed('nickname');
+        $nickname     = common_canonical_nickname($nickname_arg);
+
+        // Permanent redirect on non-canonical nickname
+        if ($nickname_arg != $nickname) {
+            $args = array('nickname' => $nickname);
+            if ($this->arg('page') && $this->arg('page') != 1) {
+                $args['page'] = $this->arg['page'];
+            }
+            common_redirect(common_local_url($this->getActionName(), $args), 301);
+        }
+
+        try {
+            $user = User::getByNickname($nickname);
+        } catch (NoSuchUserException $e) {
+            $group = Local_group::getKV('nickname', $nickname);
+            if ($group instanceof Local_group) {
+                common_redirect($group->getProfile()->getUrl());
+            }
+
+            // No user nor group found, throw the NoSuchUserException again
+            throw $e;
+        }
+
+        $this->target = $user->getProfile();
+    }
+
     protected function prepare(array $args=array())
     {
         // this will call ->doPreparation() which child classes use to set $this->target
@@ -58,9 +88,6 @@ abstract class ProfileAction extends ManagedAction
             throw new ClientException(_('This profile has been silenced by site moderators'), 403);
         }
 
-        // backwards compatibility until all actions are fixed to use $this->target
-        $this->profile = $this->target;
-
         $this->tag = $this->trimmed('tag');
         $this->page = ($this->arg('page')) ? ($this->arg('page')+0) : 1;
         common_set_returnto($this->selfUrl());
@@ -68,13 +95,11 @@ abstract class ProfileAction extends ManagedAction
         return true;
     }
 
-    protected function profileActionPreparation()
-    {
-        // Nothing to do by default.
-    }
-
     public function getTarget()
     {
+        if (!$this->target instanceof Profile) {
+            throw new ServerException('No target profile in ProfileAction class');
+        }
         return $this->target;
     }
 
index e0b94ac76a67b07985f6f08a5ec7be4d49b4c593..6fe7b99c7b3a967515815df5a3e1bde0c425fa04 100644 (file)
@@ -32,18 +32,26 @@ if (!defined('GNUSOCIAL')) { exit(1); }
 class ProfileListItem extends Widget
 {
     /** Current profile. */
+    protected $target = null;
     var $profile = null;
     /** Action object using us. */
     var $action = null;
 
-    function __construct($profile, $action)
+    // FIXME: Directory plugin sends a User_group here, but should send a Profile and handle User_group specifics itself
+    function __construct($target, HTMLOutputter $action)
     {
         parent::__construct($action);
 
-        $this->profile = $profile;
+        $this->target = $target;
+        $this->profile = $this->target;
         $this->action  = $action;
     }
 
+    function getTarget()
+    {
+        return $this->target;
+    }
+
     function show()
     {
         if (Event::handle('StartProfileListItem', array($this))) {
index 45fe1e4ab43040343989833046206622bfc2f72b..487104099a9e0c5d716be87e786907b9ae0980a2 100644 (file)
@@ -43,6 +43,7 @@ abstract class QueueManager extends IoManager
     protected $handlers = array();
     protected $groups = array();
     protected $activeGroups = array();
+    protected $ignoredTransports = array();
 
     /**
      * Factory function to pull the appropriate QueueManager object
@@ -255,6 +256,17 @@ abstract class QueueManager extends IoManager
         return array_keys($queues);
     }
 
+    function getIgnoredTransports()
+    {
+        return array_keys($this->ignoredTransports);
+    }
+
+    function ignoreTransport($transport)
+    {
+        // key is used for uniqueness, value doesn't mean anything
+        $this->ignoredTransports[$transport] = true;
+    }
+
     /**
      * Initialize the list of queue handlers for the current site.
      *
index ca8daf5a906f65744ace2d77d8bbea7c1850e5c3..b13c51c32834c92fb24facdbfeccc59454699871 100644 (file)
@@ -108,6 +108,11 @@ class Router
 
         if (Event::handle('StartInitializeRouter', array(&$m))) {
 
+            // top of the menu hierarchy, sometimes "Home"
+            $m->connect('', array('action' => 'top'));
+
+            // public endpoints
+
             $m->connect('robots.txt', array('action' => 'robotstxt'));
 
             $m->connect('opensearch/people', array('action' => 'opensearch',
@@ -156,13 +161,13 @@ class Router
                           'deleteaccount',
                           'restoreaccount',
                           'top',
+                          'public',
             );
 
             foreach ($main as $a) {
                 $m->connect('main/'.$a, array('action' => $a));
             }
 
-            $m->connect('main/public', array('action' => 'public'));
             $m->connect('main/all', array('action' => 'networkpublic'));
 
             $m->connect('main/tagprofile/:id', array('action' => 'tagprofile'),
@@ -239,12 +244,10 @@ class Router
                         array('action' => 'shownotice'),
                         array('notice' => '[0-9]+'));
 
-            $m->connect('notice/delete/:notice',
+            $m->connect('notice/:notice/delete',
                         array('action' => 'deletenotice'),
                         array('notice' => '[0-9]+'));
 
-            $m->connect('notice/delete', array('action' => 'deletenotice'));
-
             // conversation
 
             $m->connect('conversation/:id',
@@ -875,9 +878,6 @@ class Router
                             array('action' => 'rsd',
                                   'nickname' => $nickname));
 
-                $m->connect('',
-                            array('action' => 'startpage'));
-
                 // peopletags
 
                 $m->connect('peopletags',
@@ -930,9 +930,6 @@ class Router
                 }
             }
 
-            $m->connect('', array('action' => 'startpage'));
-            $m->connect('main/public', array('action' => 'public'));
-            $m->connect('main/all', array('action' => 'networkpublic'));
             $m->connect('rss', array('action' => 'publicrss'));
             $m->connect('featuredrss', array('action' => 'featuredrss'));
             $m->connect('featured/', array('action' => 'featured'));
@@ -950,6 +947,13 @@ class Router
                         array('action' => 'subqueue'),
                         array('nickname' => Nickname::DISPLAY_FMT));
 
+            // some targeted RSS 1.0 actions (extends TargetedRss10Action)
+            foreach (array('all', 'replies') as $a) {
+                $m->connect(':nickname/'.$a.'/rss',
+                            array('action' => $a.'rss'),
+                            array('nickname' => Nickname::DISPLAY_FMT));
+            }
+
             // people tags
 
             $m->connect(':nickname/peopletags',
@@ -1017,12 +1021,6 @@ class Router
                             array('nickname' => Nickname::DISPLAY_FMT));
             }
 
-            foreach (array('all', 'replies') as $a) {
-                $m->connect(':nickname/'.$a.'/rss',
-                            array('action' => $a.'rss'),
-                            array('nickname' => Nickname::DISPLAY_FMT));
-            }
-
             $m->connect(':nickname/avatar',
                         array('action' => 'avatarbynickname'),
                         array('nickname' => Nickname::DISPLAY_FMT));
diff --git a/lib/rss10action.php b/lib/rss10action.php
new file mode 100644 (file)
index 0000000..1370155
--- /dev/null
@@ -0,0 +1,379 @@
+<?php
+/**
+ * StatusNet, the distributed open-source microblogging tool
+ *
+ * Base class for RSS 1.0 feed actions
+ *
+ * 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  Mail
+ * @package   StatusNet
+ * @author    Evan Prodromou <evan@status.net>
+ * @author    Earle Martin <earle@downlode.org>
+ * @copyright 2008-9 StatusNet, Inc.
+ * @license   http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
+ * @link      http://status.net/
+ */
+
+if (!defined('GNUSOCIAL')) { exit(1); }
+
+define('DEFAULT_RSS_LIMIT', 48);
+
+class Rss10Action extends ManagedAction
+{
+    // This will contain the details of each feed item's author and be used to generate SIOC data.
+
+    var $creators = array();
+    var $limit = DEFAULT_RSS_LIMIT;
+    var $notices = null;
+    var $tags_already_output = array();
+
+    public function isReadOnly($args)
+    {
+        return true;
+    }
+
+    protected function doPreparation()
+    {
+        $this->limit = $this->int('limit');
+
+        if (empty($this->limit)) {
+            $this->limit = DEFAULT_RSS_LIMIT;
+        }
+
+        if (common_config('site', 'private')) {
+            if (!isset($_SERVER['PHP_AUTH_USER'])) {
+
+                // This header makes basic auth go
+                header('WWW-Authenticate: Basic realm="GNU social RSS"');
+
+                // If the user hits cancel -- bam!
+                $this->show_basic_auth_error();
+                // the above calls 'exit'
+            } else {
+                $nickname = $_SERVER['PHP_AUTH_USER'];
+                $password = $_SERVER['PHP_AUTH_PW'];
+
+                if (!common_check_user($nickname, $password)) {
+                    // basic authentication failed
+                    list($proxy, $ip) = common_client_ip();
+
+                    common_log(LOG_WARNING, "Failed RSS auth attempt, nickname = $nickname, proxy = $proxy, ip = $ip.");
+                    $this->show_basic_auth_error();
+                    // the above calls 'exit'
+                }
+            }
+        }
+
+        $this->doStreamPreparation();
+
+        $this->notices = $this->getNotices($this->limit);
+    }
+
+    protected function doStreamPreparation()
+    {
+        // for example if we need to set $this->target or something
+    }
+
+    function show_basic_auth_error()
+    {
+        header('HTTP/1.1 401 Unauthorized');
+        header('Content-Type: application/xml; charset=utf-8');
+        $this->startXML();
+        $this->elementStart('hash');
+        $this->element('error', null, 'Could not authenticate you.');
+        $this->element('request', null, $_SERVER['REQUEST_URI']);
+        $this->elementEnd('hash');
+        $this->endXML();
+        exit;
+    }
+
+    /**
+     * Get the notices to output in this stream.
+     *
+     * @return array an array of Notice objects sorted in reverse chron
+     */
+
+    protected function getNotices()
+    {
+        return array();
+    }
+
+    /**
+     * Get a description of the channel
+     *
+     * Returns an array with the following
+     * @return array
+     */
+
+    function getChannel()
+    {
+        return array('url' => '',
+                     'title' => '',
+                     'link' => '',
+                     'description' => '');
+    }
+
+    function getImage()
+    {
+        return null;
+    }
+
+    function showPage()
+    {
+        $this->initRss();
+        $this->showChannel();
+        $this->showImage();
+
+        if (count($this->notices)) {
+            foreach ($this->notices as $n) {
+                try {
+                    $this->showItem($n);
+                } catch (Exception $e) {
+                    // log exceptions and continue
+                    common_log(LOG_ERR, $e->getMessage());
+                    continue;
+                }
+            }
+        }
+
+        $this->showCreators();
+        $this->endRss();
+    }
+
+    function showChannel()
+    {
+
+        $channel = $this->getChannel();
+        $image = $this->getImage();
+
+        $this->elementStart('channel', array('rdf:about' => $channel['url']));
+        $this->element('title', null, $channel['title']);
+        $this->element('link', null, $channel['link']);
+        $this->element('description', null, $channel['description']);
+        $this->element('cc:licence', array('rdf:resource' => common_config('license','url')));
+
+        if ($image) {
+            $this->element('image', array('rdf:resource' => $image));
+        }
+
+        $this->elementStart('items');
+        $this->elementStart('rdf:Seq');
+
+        if (count($this->notices)) {
+            foreach ($this->notices as $notice) {
+                $this->element('rdf:li', array('rdf:resource' => $notice->uri));
+            }
+        }
+
+        $this->elementEnd('rdf:Seq');
+        $this->elementEnd('items');
+
+        $this->elementEnd('channel');
+    }
+
+    function showImage()
+    {
+        $image = $this->getImage();
+        if ($image) {
+            $channel = $this->getChannel();
+            $this->elementStart('image', array('rdf:about' => $image));
+            $this->element('title', null, $channel['title']);
+            $this->element('link', null, $channel['link']);
+            $this->element('url', null, $image);
+            $this->elementEnd('image');
+        }
+    }
+
+    function showItem($notice)
+    {
+        $profile = $notice->getProfile();
+        $nurl = common_local_url('shownotice', array('notice' => $notice->id));
+        $creator_uri = common_profile_uri($profile);
+        $this->elementStart('item', array('rdf:about' => $notice->uri,
+                            'rdf:type' => 'http://rdfs.org/sioc/types#MicroblogPost'));
+        $title = $profile->nickname . ': ' . common_xml_safe_str(trim($notice->content));
+        $this->element('title', null, $title);
+        $this->element('link', null, $nurl);
+        $this->element('description', null, $profile->nickname."'s status on ".common_exact_date($notice->created));
+        if ($notice->rendered) {
+            $this->element('content:encoded', null, common_xml_safe_str($notice->rendered));
+        }
+        $this->element('dc:date', null, common_date_w3dtf($notice->created));
+        $this->element('dc:creator', null, ($profile->fullname) ? $profile->fullname : $profile->nickname);
+        $this->element('foaf:maker', array('rdf:resource' => $creator_uri));
+        $this->element('sioc:has_creator', array('rdf:resource' => $creator_uri.'#acct'));
+        try {
+            $location = Notice_location::locFromStored($notice);
+            if (isset($location->lat) && isset($location->lon)) {
+                $location_uri = $location->getRdfURL();
+                $attrs = array('geo:lat' => $location->lat,
+                               'geo:long' => $location->lon);
+                if (strlen($location_uri)) {
+                    $attrs['rdf:resource'] = $location_uri;
+                }
+                $this->element('statusnet:origin', $attrs);
+            }
+        } catch (ServerException $e) {
+            // No result, so no location data
+        }
+        $this->element('statusnet:postIcon', array('rdf:resource' => $profile->avatarUrl()));
+        $this->element('cc:licence', array('rdf:resource' => common_config('license', 'url')));
+        if ($notice->reply_to) {
+            $replyurl = common_local_url('shownotice', array('notice' => $notice->reply_to));
+            $this->element('sioc:reply_of', array('rdf:resource' => $replyurl));
+        }
+        if (!empty($notice->conversation)) {
+            $conversationurl = common_local_url('conversation',
+                                         array('id' => $notice->conversation));
+            $this->element('sioc:has_discussion', array('rdf:resource' => $conversationurl));
+        }
+        $attachments = $notice->attachments();
+        if($attachments){
+            foreach($attachments as $attachment){
+                try {
+                    $enclosure = $attachment->getEnclosure();
+                    $attribs = array('rdf:resource' => $enclosure->url);
+                    if ($enclosure->title) {
+                        $attribs['dc:title'] = $enclosure->title;
+                    }
+                    if ($enclosure->modified) {
+                        $attribs['dc:date'] = common_date_w3dtf($enclosure->modified);
+                    }
+                    if ($enclosure->size) {
+                        $attribs['enc:length'] = $enclosure->size;
+                    }
+                    if ($enclosure->mimetype) {
+                        $attribs['enc:type'] = $enclosure->mimetype;
+                    }
+                    $this->element('enc:enclosure', $attribs);
+                } catch (ServerException $e) {
+                    // There was not enough metadata available
+                }
+                $this->element('sioc:links_to', array('rdf:resource'=>$attachment->url));
+            }
+        }
+
+        $tag = new Notice_tag();
+        $tag->notice_id = $notice->id;
+        if ($tag->find()) {
+            $entry['tags']=array();
+            while ($tag->fetch()) {
+                $tagpage = common_local_url('tag', array('tag' => $tag->tag));
+
+                if ( in_array($tag, $this->tags_already_output) ) {
+                    $this->element('ctag:tagged', array('rdf:resource'=>$tagpage.'#concept'));
+                    continue;
+                }
+
+                $tagrss  = common_local_url('tagrss', array('tag' => $tag->tag));
+                $this->elementStart('ctag:tagged');
+                $this->elementStart('ctag:Tag', array('rdf:about'=>$tagpage.'#concept', 'ctag:label'=>$tag->tag));
+                $this->element('foaf:page', array('rdf:resource'=>$tagpage));
+                $this->element('rdfs:seeAlso', array('rdf:resource'=>$tagrss));
+                $this->elementEnd('ctag:Tag');
+                $this->elementEnd('ctag:tagged');
+
+                $this->tags_already_output[] = $tag->tag;
+            }
+        }
+        $this->elementEnd('item');
+        $this->creators[$creator_uri] = $profile;
+    }
+
+    function showCreators()
+    {
+        foreach ($this->creators as $uri => $profile) {
+            $id = $profile->id;
+            $nickname = $profile->nickname;
+            $this->elementStart('foaf:Agent', array('rdf:about' => $uri));
+            $this->element('foaf:nick', null, $nickname);
+            if ($profile->fullname) {
+                $this->element('foaf:name', null, $profile->fullname);
+            }
+            $this->element('foaf:holdsAccount', array('rdf:resource' => $uri.'#acct'));
+            $avatar = $profile->avatarUrl();
+            $this->element('foaf:depiction', array('rdf:resource' => $avatar));
+            $this->elementEnd('foaf:Agent');
+        }
+    }
+
+    function initRss()
+    {
+        $channel = $this->getChannel();
+        header('Content-Type: application/rdf+xml');
+
+        $this->startXml();
+        $this->elementStart('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://creativecommons.org/ns#',
+                                              'xmlns:content' =>
+                                              'http://purl.org/rss/1.0/modules/content/',
+                                              'xmlns:ctag' =>
+                                              'http://commontag.org/ns#',
+                                              'xmlns:foaf' =>
+                                              'http://xmlns.com/foaf/0.1/',
+                                              'xmlns:enc' =>
+                                              'http://purl.oclc.org/net/rss_2.0/enc#',
+                                              'xmlns:sioc' =>
+                                              'http://rdfs.org/sioc/ns#',
+                                              'xmlns:sioct' =>
+                                              'http://rdfs.org/sioc/types#',
+                                              'xmlns:rdfs' =>
+                                              'http://www.w3.org/2000/01/rdf-schema#',
+                                              'xmlns:geo' =>
+                                              'http://www.w3.org/2003/01/geo/wgs84_pos#',
+                                              'xmlns:statusnet' =>
+                                              'http://status.net/ont/',
+                                              'xmlns' => 'http://purl.org/rss/1.0/'));
+        $this->elementStart('sioc:Site', array('rdf:about' => common_root_url()));
+        $this->element('sioc:name', null, common_config('site', 'name'));
+        $this->elementStart('sioc:space_of');
+        $this->element('sioc:Container', array('rdf:about' =>
+                                               $channel['url']));
+        $this->elementEnd('sioc:space_of');
+        $this->elementEnd('sioc:Site');
+    }
+
+    function endRss()
+    {
+        $this->elementEnd('rdf:RDF');
+    }
+
+    /**
+     * When was this page last modified?
+     *
+     */
+
+    function lastModified()
+    {
+        if (empty($this->notices)) {
+            return null;
+        }
+
+        if (count($this->notices) == 0) {
+            return null;
+        }
+
+        // FIXME: doesn't handle modified profiles, avatars, deleted notices
+
+        return strtotime($this->notices[0]->created);
+    }
+}
+
diff --git a/lib/rssaction.php b/lib/rssaction.php
deleted file mode 100644 (file)
index c3e1283..0000000
+++ /dev/null
@@ -1,413 +0,0 @@
-<?php
-/**
- * StatusNet, the distributed open-source microblogging tool
- *
- * Base class for RSS 1.0 feed actions
- *
- * 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  Mail
- * @package   StatusNet
- * @author    Evan Prodromou <evan@status.net>
- * @author    Earle Martin <earle@downlode.org>
- * @copyright 2008-9 StatusNet, Inc.
- * @license   http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
- * @link      http://status.net/
- */
-
-if (!defined('STATUSNET') && !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();
-    var $limit = DEFAULT_RSS_LIMIT;
-    var $notices = null;
-    var $tags_already_output = array();
-
-    /**
-     * Constructor
-     *
-     * Just wraps the Action constructor.
-     *
-     * @param string  $output URI to output to, default = stdout
-     * @param boolean $indent Whether to indent output, default true
-     *
-     * @see Action::__construct
-     */
-
-    function __construct($output='php://output', $indent=null)
-    {
-        parent::__construct($output, $indent);
-    }
-
-    /**
-     * Do we need to write to the database?
-     *
-     * @return boolean true
-     */
-
-    function isReadonly()
-    {
-        return true;
-    }
-
-    /**
-     * Read arguments and initialize members
-     *
-     * @param array $args Arguments from $_REQUEST
-     * @return boolean success
-     */
-
-    function prepare($args)
-    {
-        parent::prepare($args);
-
-        $this->limit = (int) $this->trimmed('limit');
-
-        if ($this->limit == 0) {
-            $this->limit = DEFAULT_RSS_LIMIT;
-        }
-
-        if (common_config('site', 'private')) {
-            if (!isset($_SERVER['PHP_AUTH_USER'])) {
-
-                // This header makes basic auth go
-                header('WWW-Authenticate: Basic realm="GNU social RSS"');
-
-                // If the user hits cancel -- bam!
-                $this->show_basic_auth_error();
-                return;
-            } else {
-                $nickname = $_SERVER['PHP_AUTH_USER'];
-                $password = $_SERVER['PHP_AUTH_PW'];
-
-                if (!common_check_user($nickname, $password)) {
-                    // basic authentication failed
-                    list($proxy, $ip) = common_client_ip();
-
-                    common_log(LOG_WARNING, "Failed RSS auth attempt, nickname = $nickname, proxy = $proxy, ip = $ip.");
-                    $this->show_basic_auth_error();
-                    return;
-                }
-            }
-        }
-
-        return true;
-    }
-
-    /**
-     * Handle a request
-     *
-     * @param array $args Arguments from $_REQUEST
-     *
-     * @return void
-     */
-
-    function handle($args)
-    {
-        // Parent handling, including cache check
-        parent::handle($args);
-        $this->showRss();
-    }
-
-    function show_basic_auth_error()
-    {
-        header('HTTP/1.1 401 Unauthorized');
-        header('Content-Type: application/xml; charset=utf-8');
-        $this->startXML();
-        $this->elementStart('hash');
-        $this->element('error', null, 'Could not authenticate you.');
-        $this->element('request', null, $_SERVER['REQUEST_URI']);
-        $this->elementEnd('hash');
-        $this->endXML();
-    }
-
-    /**
-     * Get the notices to output in this stream.
-     *
-     * @return array an array of Notice objects sorted in reverse chron
-     */
-
-    function getNotices()
-    {
-        return array();
-    }
-
-    /**
-     * Get a description of the channel
-     *
-     * Returns an array with the following
-     * @return array
-     */
-
-    function getChannel()
-    {
-        return array('url' => '',
-                     'title' => '',
-                     'link' => '',
-                     'description' => '');
-    }
-
-    function getImage()
-    {
-        return null;
-    }
-
-    function showRss()
-    {
-        $this->initRss();
-        $this->showChannel();
-        $this->showImage();
-
-        if (count($this->notices)) {
-            foreach ($this->notices as $n) {
-                try {
-                    $this->showItem($n);
-                } catch (Exception $e) {
-                    // log exceptions and continue
-                    common_log(LOG_ERR, $e->getMessage());
-                    continue;
-                }
-            }
-        }
-
-        $this->showCreators();
-        $this->endRss();
-    }
-
-    function showChannel()
-    {
-
-        $channel = $this->getChannel();
-        $image = $this->getImage();
-
-        $this->elementStart('channel', array('rdf:about' => $channel['url']));
-        $this->element('title', null, $channel['title']);
-        $this->element('link', null, $channel['link']);
-        $this->element('description', null, $channel['description']);
-        $this->element('cc:licence', array('rdf:resource' => common_config('license','url')));
-
-        if ($image) {
-            $this->element('image', array('rdf:resource' => $image));
-        }
-
-        $this->elementStart('items');
-        $this->elementStart('rdf:Seq');
-
-        if (count($this->notices)) {
-            foreach ($this->notices as $notice) {
-                $this->element('rdf:li', array('rdf:resource' => $notice->uri));
-            }
-        }
-
-        $this->elementEnd('rdf:Seq');
-        $this->elementEnd('items');
-
-        $this->elementEnd('channel');
-    }
-
-    function showImage()
-    {
-        $image = $this->getImage();
-        if ($image) {
-            $channel = $this->getChannel();
-            $this->elementStart('image', array('rdf:about' => $image));
-            $this->element('title', null, $channel['title']);
-            $this->element('link', null, $channel['link']);
-            $this->element('url', null, $image);
-            $this->elementEnd('image');
-        }
-    }
-
-    function showItem($notice)
-    {
-        $profile = $notice->getProfile();
-        $nurl = common_local_url('shownotice', array('notice' => $notice->id));
-        $creator_uri = common_profile_uri($profile);
-        $this->elementStart('item', array('rdf:about' => $notice->uri,
-                            'rdf:type' => 'http://rdfs.org/sioc/types#MicroblogPost'));
-        $title = $profile->nickname . ': ' . common_xml_safe_str(trim($notice->content));
-        $this->element('title', null, $title);
-        $this->element('link', null, $nurl);
-        $this->element('description', null, $profile->nickname."'s status on ".common_exact_date($notice->created));
-        if ($notice->rendered) {
-            $this->element('content:encoded', null, common_xml_safe_str($notice->rendered));
-        }
-        $this->element('dc:date', null, common_date_w3dtf($notice->created));
-        $this->element('dc:creator', null, ($profile->fullname) ? $profile->fullname : $profile->nickname);
-        $this->element('foaf:maker', array('rdf:resource' => $creator_uri));
-        $this->element('sioc:has_creator', array('rdf:resource' => $creator_uri.'#acct'));
-        $location = $notice->getLocation();
-        if ($location && isset($location->lat) && isset($location->lon)) {
-            $location_uri = $location->getRdfURL();
-            $attrs = array('geo:lat' => $location->lat,
-                'geo:long' => $location->lon);
-            if (strlen($location_uri)) {
-                $attrs['rdf:resource'] = $location_uri;
-            }
-            $this->element('statusnet:origin', $attrs);
-        }
-        $this->element('statusnet:postIcon', array('rdf:resource' => $profile->avatarUrl()));
-        $this->element('cc:licence', array('rdf:resource' => common_config('license', 'url')));
-        if ($notice->reply_to) {
-            $replyurl = common_local_url('shownotice', array('notice' => $notice->reply_to));
-            $this->element('sioc:reply_of', array('rdf:resource' => $replyurl));
-        }
-        if (!empty($notice->conversation)) {
-            $conversationurl = common_local_url('conversation',
-                                         array('id' => $notice->conversation));
-            $this->element('sioc:has_discussion', array('rdf:resource' => $conversationurl));
-        }
-        $attachments = $notice->attachments();
-        if($attachments){
-            foreach($attachments as $attachment){
-                try {
-                    $enclosure = $attachment->getEnclosure();
-                    $attribs = array('rdf:resource' => $enclosure->url);
-                    if ($enclosure->title) {
-                        $attribs['dc:title'] = $enclosure->title;
-                    }
-                    if ($enclosure->modified) {
-                        $attribs['dc:date'] = common_date_w3dtf($enclosure->modified);
-                    }
-                    if ($enclosure->size) {
-                        $attribs['enc:length'] = $enclosure->size;
-                    }
-                    if ($enclosure->mimetype) {
-                        $attribs['enc:type'] = $enclosure->mimetype;
-                    }
-                    $this->element('enc:enclosure', $attribs);
-                } catch (ServerException $e) {
-                    // There was not enough metadata available
-                }
-                $this->element('sioc:links_to', array('rdf:resource'=>$attachment->url));
-            }
-        }
-
-        $tag = new Notice_tag();
-        $tag->notice_id = $notice->id;
-        if ($tag->find()) {
-            $entry['tags']=array();
-            while ($tag->fetch()) {
-                $tagpage = common_local_url('tag', array('tag' => $tag->tag));
-
-                if ( in_array($tag, $this->tags_already_output) ) {
-                    $this->element('ctag:tagged', array('rdf:resource'=>$tagpage.'#concept'));
-                    continue;
-                }
-
-                $tagrss  = common_local_url('tagrss', array('tag' => $tag->tag));
-                $this->elementStart('ctag:tagged');
-                $this->elementStart('ctag:Tag', array('rdf:about'=>$tagpage.'#concept', 'ctag:label'=>$tag->tag));
-                $this->element('foaf:page', array('rdf:resource'=>$tagpage));
-                $this->element('rdfs:seeAlso', array('rdf:resource'=>$tagrss));
-                $this->elementEnd('ctag:Tag');
-                $this->elementEnd('ctag:tagged');
-
-                $this->tags_already_output[] = $tag->tag;
-            }
-        }
-        $this->elementEnd('item');
-        $this->creators[$creator_uri] = $profile;
-    }
-
-    function showCreators()
-    {
-        foreach ($this->creators as $uri => $profile) {
-            $id = $profile->id;
-            $nickname = $profile->nickname;
-            $this->elementStart('foaf:Agent', array('rdf:about' => $uri));
-            $this->element('foaf:nick', null, $nickname);
-            if ($profile->fullname) {
-                $this->element('foaf:name', null, $profile->fullname);
-            }
-            $this->element('foaf:holdsAccount', array('rdf:resource' => $uri.'#acct'));
-            $avatar = $profile->avatarUrl();
-            $this->element('foaf:depiction', array('rdf:resource' => $avatar));
-            $this->elementEnd('foaf:Agent');
-        }
-    }
-
-    function initRss()
-    {
-        $channel = $this->getChannel();
-        header('Content-Type: application/rdf+xml');
-
-        $this->startXml();
-        $this->elementStart('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://creativecommons.org/ns#',
-                                              'xmlns:content' =>
-                                              'http://purl.org/rss/1.0/modules/content/',
-                                              'xmlns:ctag' =>
-                                              'http://commontag.org/ns#',
-                                              'xmlns:foaf' =>
-                                              'http://xmlns.com/foaf/0.1/',
-                                              'xmlns:enc' =>
-                                              'http://purl.oclc.org/net/rss_2.0/enc#',
-                                              'xmlns:sioc' =>
-                                              'http://rdfs.org/sioc/ns#',
-                                              'xmlns:sioct' =>
-                                              'http://rdfs.org/sioc/types#',
-                                              'xmlns:rdfs' =>
-                                              'http://www.w3.org/2000/01/rdf-schema#',
-                                              'xmlns:geo' =>
-                                              'http://www.w3.org/2003/01/geo/wgs84_pos#',
-                                              'xmlns:statusnet' =>
-                                              'http://status.net/ont/',
-                                              'xmlns' => 'http://purl.org/rss/1.0/'));
-        $this->elementStart('sioc:Site', array('rdf:about' => common_root_url()));
-        $this->element('sioc:name', null, common_config('site', 'name'));
-        $this->elementStart('sioc:space_of');
-        $this->element('sioc:Container', array('rdf:about' =>
-                                               $channel['url']));
-        $this->elementEnd('sioc:space_of');
-        $this->elementEnd('sioc:Site');
-    }
-
-    function endRss()
-    {
-        $this->elementEnd('rdf:RDF');
-    }
-
-    /**
-     * When was this page last modified?
-     *
-     */
-
-    function lastModified()
-    {
-        if (empty($this->notices)) {
-            return null;
-        }
-
-        if (count($this->notices) == 0) {
-            return null;
-        }
-
-        // FIXME: doesn't handle modified profiles, avatars, deleted notices
-
-        return strtotime($this->notices[0]->created);
-    }
-}
-
index fd4885c830223072a9421435def6fb756b448613..a98d002ca411a7d83fb8d0ea11dc0fca3fd8add6 100644 (file)
@@ -27,9 +27,7 @@
  * @link      http://status.net/
  */
 
-if (!defined('STATUSNET') && !defined('LACONICA')) {
-    exit(1);
-}
+if (!defined('GNUSOCIAL')) { exit(1); }
 
 /**
  * Base class for settings group of actions
@@ -43,113 +41,8 @@ if (!defined('STATUSNET') && !defined('LACONICA')) {
  * @see      Widget
  */
 
-class SettingsAction extends Action
+class SettingsAction extends FormAction
 {
-    /**
-     * A message for the user.
-     */
-
-    var $msg = null;
-
-    /**
-     * Whether the message is a good one or a bad one.
-     */
-
-    var $success = false;
-
-    /**
-     * Handle input and output a page
-     *
-     * @param array $args $_REQUEST arguments
-     *
-     * @return void
-     */
-
-    function handle($args)
-    {
-        parent::handle($args);
-        if (!common_logged_in()) {
-            // TRANS: Error message displayed when trying to perform an action that requires a logged in user.
-            $this->clientError(_('Not logged in.'));
-        } 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
-            common_set_returnto($this->selfUrl());
-            $user = common_current_user();
-            if (Event::handle('RedirectToLogin', array($this, $user))) {
-                common_redirect(common_local_url('login'), 303);
-            }
-        } else if ($_SERVER['REQUEST_METHOD'] == 'POST') {
-            $this->handlePost();
-        } else {
-            $this->showForm();
-        }
-    }
-
-    /**
-     * Handle a POST request
-     *
-     * @return boolean success flag
-     */
-
-    function handlePost()
-    {
-        return false;
-    }
-
-    /**
-     * show the settings form
-     *
-     * @param string $msg     an extra message for the user
-     * @param string $success good message or bad message?
-     *
-     * @return void
-     */
-
-    function showForm($msg=null, $success=false)
-    {
-        $this->msg     = $msg;
-        $this->success = $success;
-
-        $this->showPage();
-    }
-
-    /**
-     * show human-readable instructions for the page
-     *
-     * @return void
-     */
-
-    function showPageNotice()
-    {
-        if ($this->msg) {
-            $this->element('div', ($this->success) ? 'success' : 'error',
-                           $this->msg);
-        } else {
-            $inst   = $this->getInstructions();
-            $output = common_markup_to_html($inst);
-
-            $this->elementStart('div', 'instructions');
-            $this->raw($output);
-            $this->elementEnd('div');
-        }
-    }
-
-    /**
-     * instructions recipe for sub-classes
-     *
-     * Subclasses should override this to return readable instructions. They'll
-     * be processed by common_markup_to_html().
-     *
-     * @return string instructions text
-     */
-
-    function getInstructions()
-    {
-        return '';
-    }
-
     /**
      * Show the local navigation menu
      *
index 4bbffea7542ccd149ded02acad15b64f4762c4bb..a2c09efb2f6be08f5dc0919573ff1a0b601d5d71 100644 (file)
@@ -110,7 +110,6 @@ class PublicSite extends SiteProfileSettings
             'plugins' => array(
                 'core'    => self::corePlugins(),
                 'default' => array_merge(self::defaultPlugins(), array(
-                    'ExtendedProfile'         => array(),
                     'RegisterThrottle'        => array(),
                 ))
             ),
index 24a3bd98af96bf6c2baac39b53630217efe06a50..80a9042e0f1e0bac68016dabe147b2284b25e7b8 100644 (file)
@@ -115,11 +115,10 @@ class TagCloudSection extends Section
 
     function tagUrl($tag)
     {
-        if ('showstream' === $this->out->trimmed('action')) {
-            return common_local_url('showstream', array('nickname' => $this->out->profile->nickname, 'tag' => $tag));
-        } else {
-            return common_local_url('tag', array('tag' => $tag));
+        if ($this->out instanceof ShowstreamAction) {
+            return common_local_url('showstream', array('nickname' => $this->out->getTarget()->getNickname(), 'tag' => $tag));
         }
+        return common_local_url('tag', array('tag' => $tag));
     }
 
     function divId()
diff --git a/lib/targetedrss10action.php b/lib/targetedrss10action.php
new file mode 100644 (file)
index 0000000..ed7e262
--- /dev/null
@@ -0,0 +1,51 @@
+<?php
+/**
+ * StatusNet, the distributed open-source microblogging tool
+ *
+ * Base class for RSS 1.0 feed actions
+ *
+ * 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  Mail
+ * @package   StatusNet
+ * @author    Evan Prodromou <evan@status.net>
+ * @author    Earle Martin <earle@downlode.org>
+ * @copyright 2008-9 StatusNet, Inc.
+ * @license   http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
+ * @link      http://status.net/
+ */
+
+if (!defined('GNUSOCIAL')) { exit(1); }
+
+class TargetedRss10Action extends Rss10Action
+{
+    protected $target = null;
+
+    protected function doStreamPreparation()
+    {
+        $this->target = User::getByNickname($this->trimmed('nickname'))->getProfile();
+    }
+
+    public function getTarget()
+    {
+        return $this->target;
+    }
+
+    function getImage()
+    {
+        return $this->target->avatarUrl(AVATAR_PROFILE_SIZE);
+    }
+}
index acb9efb972efd702b9ba5a3c3a82b3809cd39ec3..ebf0a460897069db61f43398e403e5905ee3b932 100644 (file)
@@ -195,7 +195,7 @@ class ThreadedNoticeListItem extends NoticeListItem
     function showEnd()
     {
         $max = $this->initialItems();
-        if (!$this->repeat) {
+        if (!$this->repeat instanceof Notice) {
             $stream = new ConversationNoticeStream($this->notice->conversation, $this->userProfile);
             $notice = $stream->getNotices(0, $max + 2);
             $notices = array();
index f29d9559b9b7af119a2c1499b5201b1e951cf7d6..66847a435004815c1569deb0ee3fdc137ecf0eaf 100644 (file)
@@ -210,7 +210,7 @@ function common_language()
 /**
  * Salted, hashed passwords are stored in the DB.
  */
-function common_munge_password($password, $id, Profile $profile=null)
+function common_munge_password($password, Profile $profile=null)
 {
     $hashed = null;
 
@@ -245,8 +245,7 @@ function common_check_user($nickname, $password)
         }
 
         if ($user instanceof User && !empty($password)) {
-            if (0 == strcmp(common_munge_password($password, $user->id),
-                            $user->password)) {
+            if (0 == strcmp(common_munge_password($password, $user->getProfile()), $user->password)) {
                 //internal checking passed
                 $authenticatedUser = $user;
             }
@@ -710,26 +709,22 @@ function common_find_mentions($text, Notice $notice)
 
         // Is it a reply?
 
-        if ($notice instanceof Notice) {
-            try {
-                $origNotice = $notice->getParent();
-                $origAuthor = $origNotice->getProfile();
+        try {
+            $origNotice = $notice->getParent();
+            $origAuthor = $origNotice->getProfile();
 
-                $ids = $origNotice->getReplies();
+            $ids = $origNotice->getReplies();
 
-                foreach ($ids as $id) {
-                    $repliedTo = Profile::getKV('id', $id);
-                    if ($repliedTo instanceof Profile) {
-                        $origMentions[$repliedTo->nickname] = $repliedTo;
-                    }
+            foreach ($ids as $id) {
+                try {
+                    $repliedTo = Profile::getByID($id);
+                    $origMentions[$repliedTo->getNickname()] = $repliedTo;
+                } catch (NoResultException $e) {
+                    // continue foreach
                 }
-            } catch (NoProfileException $e) {
-                common_log(LOG_WARNING, sprintf('Notice %d author profile id %d does not exist', $origNotice->id, $origNotice->profile_id));
-            } catch (NoParentNoticeException $e) {
-                // This notice is not in reply to anything
-            } catch (Exception $e) {
-                common_log(LOG_WARNING, __METHOD__ . ' got exception ' . get_class($e) . ' : ' . $e->getMessage());
             }
+        } catch (NoParentNoticeException $e) {
+            // It wasn't a reply to anything, so we can't harvest nickname-relations.
         }
 
         $matches = common_find_mentions_raw($text);
@@ -2434,3 +2429,12 @@ function common_strip_html($html, $trim=true, $save_whitespace=false)
     $text = html_entity_decode(strip_tags($html), ENT_QUOTES, 'UTF-8');
     return $trim ? trim($text) : $text;
 }
+
+function html_sprintf()
+{
+    $args = func_get_args();
+    for ($i=1; $i<count($args); $i++) {
+        $args[$i] = htmlspecialchars($args[$i]);
+    }
+    return call_user_func_array('sprintf', $args);
+}
index 71d57e2d56647afad12e413dda029a912c6e19bc..463f91be305a8d542b24e42d188589170f585cfd 100644 (file)
@@ -63,12 +63,15 @@ class XMLOutputter
      *
      * Initializes the wrapped XMLWriter.
      *
-     * @param string  $output URL for outputting, defaults to stdout
+     * @param string  $output URL for outputting, if null it defaults to stdout ('php://output')
      * @param boolean $indent Whether to indent output, default true
      */
 
-    function __construct($output='php://output', $indent=null)
+    function __construct($output=null, $indent=null)
     {
+        if (is_null($output)) {
+            $output = 'php://output';
+        }
         $this->xw = new XMLWriter();
         $this->xw->openURI($output);
         if(is_null($indent)) {
diff --git a/nginx.conf.sample b/nginx.conf.sample
new file mode 100644 (file)
index 0000000..d05c676
--- /dev/null
@@ -0,0 +1,53 @@
+server {
+  # Ports
+  listen 80;
+  # Uncomment the following line
+  # to enable HTTPS
+  #listen 443 ssl;
+
+  # Server name
+  # Change "example.org" to your domain name
+  server_name example.org;
+
+  # SSL
+  # Uncomment and change the paths to setup
+  # your SSL key/cert. See https://cipherli.st/
+  # for more information
+  #ssl_certificate       /path/to/ssl.cert;
+  #ssl_certificate_key   /path/to/ssl.key;
+
+  # Logs
+  # Uncomment and change the paths to setup
+  # logging
+  #access_log /path/to/access.log;
+  #error_log  /path/to/error.log;
+
+  # Root
+  # Change the path below to where you installed
+  # GNU social
+  root /path/to/gnusocial/root;
+
+  # Index
+  index index.php;
+
+  # PHP
+  location ~ \.php {
+    fastcgi_pass unix:/run/php-fpm/php-fpm.sock;
+    # Remove the "fastcgi_pass" line above and uncomment
+    # the one below to use TCP sockets instead of Unix sockets
+    #fastcgi_pass 127.0.0.1:9000;
+    fastcgi_index index.php;
+    include fastcgi.conf;
+  }
+
+  # Location
+  location / {
+    try_files $uri $uri/ @gnusocial;
+  }
+
+  # Fancy URLs
+  location @gnusocial {
+    rewrite ^(.*)$ /index.php?p=$1 last;
+  }
+}
+
index 5144eb46662f3f86a4c1c25969b008aef3da4c99..d8f3c6c50228b2480befa3cc7efeb59ca80dd2a8 100644 (file)
@@ -72,7 +72,7 @@ class ActivityPlugin extends Plugin
         // TRANS: Text for "started following" item in activity plugin.
         // TRANS: %1$s is a profile URL, %2$s is a profile name,
         // TRANS: %3$s is a profile URL, %4$s is a profile name.
-        $rendered = sprintf(_m('<a href="%1$s">%2$s</a> started following <a href="%3$s">%4$s</a>.'),
+        $rendered = html_sprintf(_m('<a href="%1$s">%2$s</a> started following <a href="%3$s">%4$s</a>.'),
                             $profile->getUrl(),
                             $profile->getBestName(),
                             $other->getUrl(),
@@ -110,7 +110,7 @@ class ActivityPlugin extends Plugin
         // TRANS: Text for "stopped following" item in activity plugin.
         // TRANS: %1$s is a profile URL, %2$s is a profile name,
         // TRANS: %3$s is a profile URL, %4$s is a profile name.
-        $rendered = sprintf(_m('<a href="%1$s">%2$s</a> stopped following <a href="%3$s">%4$s</a>.'),
+        $rendered = html_sprintf(_m('<a href="%1$s">%2$s</a> stopped following <a href="%3$s">%4$s</a>.'),
                             $profile->getUrl(),
                             $profile->getBestName(),
                             $other->getUrl(),
@@ -155,7 +155,7 @@ class ActivityPlugin extends Plugin
         // TRANS: Text for "stopped liking" item in activity plugin.
         // TRANS: %1$s is a profile URL, %2$s is a profile name,
         // TRANS: %3$s is a notice URL, %4$s is an author name.
-        $rendered = sprintf(_m('<a href="%1$s">%2$s</a> stopped liking <a href="%3$s">%4$s\'s update</a>.'),
+        $rendered = html_sprintf(_m('<a href="%1$s">%2$s</a> stopped liking <a href="%3$s">%4$s\'s update</a>.'),
                             $profile->getUrl(),
                             $profile->getBestName(),
                             $notice->getUrl(),
@@ -200,7 +200,7 @@ class ActivityPlugin extends Plugin
         // TRANS: Text for "joined group" item in activity plugin.
         // TRANS: %1$s is a profile URL, %2$s is a profile name,
         // TRANS: %3$s is a group URL, %4$s is a group name.
-        $rendered = sprintf(_m('<a href="%1$s">%2$s</a> joined the group <a href="%3$s">%4$s</a>.'),
+        $rendered = html_sprintf(_m('<a href="%1$s">%2$s</a> joined the group <a href="%3$s">%4$s</a>.'),
                             $profile->getUrl(),
                             $profile->getBestName(),
                             $group->homeUrl(),
@@ -241,7 +241,7 @@ class ActivityPlugin extends Plugin
         // TRANS: Text for "left group" item in activity plugin.
         // TRANS: %1$s is a profile URL, %2$s is a profile name,
         // TRANS: %3$s is a group URL, %4$s is a group name.
-        $rendered = sprintf(_m('<a href="%1$s">%2$s</a> left the group <a href="%3$s">%4$s</a>.'),
+        $rendered = html_sprintf(_m('<a href="%1$s">%2$s</a> left the group <a href="%3$s">%4$s</a>.'),
                             $profile->getUrl(),
                             $profile->getBestName(),
                             $group->homeUrl(),
index c6695667725d904683e38d926568ee59dfd881d2..540019f9c25955f28aa9d864182e8861dd2998c9 100644 (file)
@@ -110,17 +110,17 @@ class AuthCryptPlugin extends AuthenticationPlugin
      * EVENTS
      */
 
-    public function onStartChangePassword($user, $oldpassword, $newpassword)
+    public function onStartChangePassword(Profile $target, $oldpassword, $newpassword)
     {
-        if (!$this->checkPassword($user->nickname, $oldpassword)) {
+        if (!$this->checkPassword($target->getNickname(), $oldpassword)) {
             // if we ARE in overwrite mode, test password with common_check_user
-            if (!$this->overwrite || !common_check_user($user->nickname, $oldpassword)) {
+            if (!$this->overwrite || !common_check_user($target->getNickname(), $oldpassword)) {
                 // either we're not in overwrite mode, or the password was incorrect
                 return !$this->authoritative;
             }
             // oldpassword was apparently ok
         }
-        $changed = $this->changePassword($user->nickname, $oldpassword, $newpassword);
+        $changed = $this->changePassword($target->getNickname(), $oldpassword, $newpassword);
 
         return (!$changed && empty($this->authoritative));
     }
index fc3331482f9538b752d6d20818f47ad079c433fe..955b78266660bad2ffa3b5d530ef807e71e40d06 100644 (file)
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 
-if (!defined('STATUSNET') && !defined('LACONICA')) {
-    exit(1);
-}
-
-require_once INSTALLDIR.'/lib/rssaction.php';
+if (!defined('GNUSOCIAL')) { exit(1); }
 
 /**
  * RSS feed for user bookmarks action class.
@@ -48,54 +44,12 @@ require_once INSTALLDIR.'/lib/rssaction.php';
  * @license  http://www.fsf.org/licensing/licenses/agpl.html AGPLv3
  * @link     http://status.net/
  */
-class BookmarksrssAction extends Rss10Action
+class BookmarksrssAction extends TargetedRss10Action
 {
-    /** The user whose bookmarks to display */
-
-    var $user = null;
-
-    /**
-     * Find the user to display by supplied nickname
-     *
-     * @param array $args Arguments from $_REQUEST
-     *
-     * @return boolean success
-     */
-    function prepare($args)
-    {        
-        parent::prepare($args);
-
-        $nickname   = $this->trimmed('nickname');
-        $this->user = User::getKV('nickname', $nickname);
-
-        if (!$this->user) {
-            // TRANS: Client error displayed when trying to get the RSS feed with bookmarks of a user that does not exist.
-            $this->clientError(_('No such user.'));
-        } else {
-            $this->notices = $this->getNotices($this->limit);
-            return true;
-        }
-    }
-
-    /**
-     * Get notices
-     *
-     * @param integer $limit max number of notices to return
-     *
-     * @return array notices
-     */
-    function getNotices($limit=0)
+    protected function getNotices()
     {
-        $user    = $this->user;
-
-        $notice = new BookmarksNoticeStream($this->user->id, true);
-        $notice = $notice->getNotices(0, NOTICES_PER_PAGE);
-
-        $notices = array();
-        while ($notice->fetch()) {
-            $notices[] = clone($notice);
-        }
-        return $notices;
+        $stream = new BookmarksNoticeStream($this->target->getID(), true);
+        return $stream->getNotices(0, $this->limit)->fetchAll();
     }
 
      /**
@@ -105,31 +59,19 @@ class BookmarksrssAction extends Rss10Action
      */
     function getChannel()
     {
-        $user = $this->user;
         $c    = array('url' => common_local_url('bookmarksrss',
                                         array('nickname' =>
-                                        $user->nickname)),
+                                        $this->target->getNickname())),
                    // TRANS: Title of RSS feed with bookmarks of a user.
                    // TRANS: %s is a user's nickname.
-                   'title' => sprintf(_("%s's bookmarks"), $user->nickname),
+                   'title' => sprintf(_("%s's bookmarks"), $this->target->getNickname()),
                    'link' => common_local_url('bookmarks',
                                         array('nickname' =>
-                                        $user->nickname)),
+                                        $this->target->getNickname())),
                    // TRANS: Desciption of RSS feed with bookmarks of a user.
                    // TRANS: %1$s is a user's nickname, %2$s is the name of the StatusNet site.
                    'description' => sprintf(_('Bookmarks posted by %1$s on %2$s!'),
-                                        $user->nickname, common_config('site', 'name')));
+                                        $this->target->getNickname(), common_config('site', 'name')));
         return $c;
     }
-
-    /**
-     * Get image.
-     *
-     * @return void
-    */
-    function getImage()
-    {
-        return null;
-    }
-
 }
diff --git a/plugins/ChooseTheme/ChooseThemePlugin.php b/plugins/ChooseTheme/ChooseThemePlugin.php
new file mode 100644 (file)
index 0000000..b54e3d0
--- /dev/null
@@ -0,0 +1,74 @@
+<?php
+/**
+ * ChooseTheme - GNU social plugin enabling user to select a preferred theme
+ * Copyright (C) 2015, kollektivet0x242.
+ *
+ * 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/>.
+ *
+ * @author   Knut Erik Hollund <knut.erik@unlike.no>
+ * @copyright 2015 kollektivet0x242. http://www.kollektivet0x242.no
+ *
+ * @license  GNU Affero General Public License http://www.gnu.org/licenses/
+ */
+
+class ChooseThemePlugin extends Plugin {
+
+    public function onRouterInitialized(URLMapper $m) {
+        $m->connect('main/choosethemesettings', array('action' => 'choosethemesettings'));
+    }
+
+    public function onPluginVersion(array &$versions) {
+               
+        $versions[] = array('name' => 'ChooseTheme',
+                            'version' => '0.1',
+                            'author' => 'Knut Erik "abjectio" Hollund',
+                            'homepage' => 'https://gitlab.com/kollektivet0x242/gsp-choosetheme',
+                            'rawdescription' =>
+                            // TRANS: Plugin description.
+                            _m('Allowing user to select the preferred theme.'));
+        return true;
+    }
+    
+    /**
+     * Menu item for ChooseTheme
+     *
+     * @param Action $action action being executed
+     *
+     * @return boolean hook return
+     */
+    function onEndAccountSettingsNav(Action $action) {
+        $action_name = $action->getActionName();
+
+        $action->menuItem(common_local_url('choosethemesettings'),
+                          // TRANS: Poll plugin menu item on user settings page.
+                          _m('MENU', 'Theme'),
+                          // TRANS: Poll plugin tooltip for user settings menu item.
+                          _m('Choose Theme'),
+                          $action_name === 'themesettings');
+
+        return true;
+    }
+
+
+    function onStartShowStylesheets(Action $action) {
+
+               //get the theme and set the current config for site and theme.
+               if($action->getScoped() instanceof Profile) {
+                       $site_theme = common_config('site','theme');
+                       $user_theme = $action->getScoped()->getPref('chosen_theme', 'theme', $site_theme);
+                       common_config_set('site', 'theme', $user_theme);
+               }               
+               return true;
+       }
+}
diff --git a/plugins/ChooseTheme/README.md b/plugins/ChooseTheme/README.md
new file mode 100644 (file)
index 0000000..2e0a761
--- /dev/null
@@ -0,0 +1,13 @@
+### Choose theme
+A simple plugin for [GNU social software](http://gnu.io/social/). 
+The plugin enables the user to select their own theme, independently on site setting and other users.
+
+#### Enable plugin
+- Include this code in your GNU social instance. 
+- Edit your `config.php` to include `addPlugin("ChooseTheme");`
+
+#### How-to
+- Choose settings from the GNU social menu. Choose 'Theme' on left menu.
+- Select a theme and press 'Save'.
+
+
diff --git a/plugins/ChooseTheme/actions/choosethemesettings.php b/plugins/ChooseTheme/actions/choosethemesettings.php
new file mode 100644 (file)
index 0000000..97ef722
--- /dev/null
@@ -0,0 +1,187 @@
+<?php
+/**
+ * ChooseTheme - GNU social plugin enabling user to select preferred theme
+ * Copyright (C) 2015, kollektivet0x242.
+ *
+ * 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/>.
+ *
+ * @author   Knut Erik Hollund <knut.erik@unlike.no>
+ * @copyright 2015 kollektivet0x242. http://www.kollektivet0x242.no
+ *
+ * @license  GNU Affero General Public License http://www.gnu.org/licenses/
+ */
+
+if (!defined('STATUSNET') && !defined('GNUSOCIAL')) {
+    exit(1);
+}
+
+class ChooseThemeSettingsAction extends SettingsAction {
+       
+
+    /**
+     * Title of the page
+     * @return string Page title
+     */
+    function title() {
+        // TRANS: Page title.
+        return _m('Choose theme settings');
+    }
+
+    /**
+     * Instructions for use
+     * @return string Instructions for use
+     */
+    function getInstructions() {
+        // TRANS: Page instructions.
+        return _m('Choose theme');
+    }
+
+    /**
+     * Show the form for ChooseTheme
+     * @return void
+     */
+    function showContent() {
+
+       $site_theme = common_config('site','theme');
+       $prefs = $this->scoped->getPref('chosen_theme', 'theme',$site_theme);
+        if ($prefs === null) {
+            common_debug('No chosen theme found in database for user.');
+        }
+       
+       //Get a list of available themes on instance
+       $available_themes = Theme::listAvailable();             
+       $chosenone = array_search($prefs,$available_themes,true);
+        $form = new ChooseThemeForm($this, $chosenone);
+        $form->show();
+    }
+
+
+    /**
+     * Handler method
+     *
+     * @param array $argarray is ignored since it's now passed in in prepare()
+     * @return void
+     */
+    function handlePost() {
+               
+       //Get a list of available themes on instance
+       $available_themes = Theme::listAvailable();
+       $chosen_theme = $available_themes[(int)$this->arg('dwct','0')];
+               
+        $this->success = true;
+        $this->msg = _m('Settings saved.');
+
+       $this->success = $this->scoped->setPref('chosen_theme', 'theme', $chosen_theme);
+        // TRANS: Confirmation shown when user profile settings are saved.        
+       if(!$this->success) $this->msg = _('No valid theme chosen.');
+        $this->showForm(_($this->msg), $this->success);
+    }
+}
+
+
+class ChooseThemeForm extends Form {
+
+    protected $prefs = null;
+    
+
+    function __construct($out, $prefs) {
+        parent::__construct($out);
+
+        if ($prefs!=null) {
+                       $this->prefs = $prefs;
+       } else {
+                       $prefs = common_config('site','theme');
+       }
+       
+}
+
+    /**
+     * Visible or invisible data elements
+     *
+     * Display the form fields that make up the data of the form.
+     * Sub-classes should overload this to show their data.
+     * @return void
+     */
+
+    function formData() {
+
+       //Get a list of available themes on instance
+       $available_themes = Theme::listAvailable();
+               
+       //Remove theme 'licenses' from selectable themes.
+       //The 'licenses' theme is not an actual theme and
+       //will just mess-up the gui.
+       $key = array_search('licenses',$available_themes);
+       if($key!=false){
+               unset($available_themes[$key]);
+       }               
+               
+        $this->elementStart('fieldset');
+        $this->elementStart('ul', 'form_data');
+        $this->elementStart('li');
+        $this->dropdown('dwct',_m('Themes'),$available_themes,_m('Select a theme'),false, $this->prefs);
+        $this->elementEnd('li');
+        $this->elementEnd('ul');
+        $this->elementEnd('fieldset');
+      
+    }
+
+    /**
+     * Buttons for form actions
+     *
+     * Submit and cancel buttons (or whatever)
+     * Sub-classes should overload this to show their own buttons.
+     * @return void
+     */
+
+    function formActions()
+    {
+        $this->submit('submit', _('Save'));
+    }
+
+    /**
+     * ID of the form
+     *
+     * Should be unique on the page. Sub-classes should overload this
+     * to show their own IDs.
+     * @return int ID of the form
+     */
+
+    function id() {
+        return 'form_choosetheme_prefs';
+    }
+
+    /**
+     * Action of the form.
+     *
+     * URL to post to. Should be overloaded by subclasses to give
+     * somewhere to post to.
+     * @return string URL to post to
+     */
+
+    function action() {        
+        return common_local_url('choosethemesettings');
+    }
+
+    /**
+     * Class of the form. May include space-separated list of multiple classes.
+     *
+     * @return string the form's class
+     */
+
+    function formClass() {
+        return 'form_settings';
+    }
+}
diff --git a/plugins/ChooseTheme/locale/ChooseTheme.pot b/plugins/ChooseTheme/locale/ChooseTheme.pot
new file mode 100644 (file)
index 0000000..df6c0ca
--- /dev/null
@@ -0,0 +1,62 @@
+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the GNU social package.
+# FIRST AUTHOR abjectio@kollektivet0x242.no, 2015.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: Choose Theme\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2015-06-10 22:00+0100\n"
+"PO-Revision-Date: 2015-06-10 22:01+0100\n"
+"Last-Translator: Knut Erik Hollund <knut.erik@unlike.no>\n"
+"Language-Team: kollektivet0x242.no <abjectio@kollektivet0x242.no>\n"
+"Language: en\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Generator: Poedit 1.5.4\n"
+"X-Poedit-Basepath: ./actions\n"
+"X-Poedit-KeywordsList: _m\n"
+"X-Poedit-SearchPath-0: ./actions\n"
+"X-Poedit-SearchPath-1: .\n"
+
+#: actions/choosethemesettings.php:38
+msgid "Choose theme settings"
+msgstr ""
+
+#: actions/choosethemesettings.php:47
+msgid "Choose theme"
+msgstr ""
+
+#: actions/choosethemesettings.php:83
+msgid "Settings saved."
+msgstr ""
+
+#: actions/choosethemesettings.php:87
+msgid "No valid theme chosen."
+msgstr ""
+
+#: actions/choosethemesettings.php:134
+msgid "Themes"
+msgstr ""
+
+#: actions/choosethemesettings.php:134
+msgid "Select a theme"
+msgstr ""
+
+#: actions/choosethemesettings.php:151
+msgid "Save"
+msgstr ""
+
+#: ChooseThemePlugin.php:39
+msgid "Allowing user to select the preferred theme."
+msgstr ""
+
+#: ChooseThemePlugin.php:55
+msgid "MENU"
+msgstr ""
+
+#: ChooseThemePlugin.php:57
+msgid "Choose Theme"
+msgstr ""
diff --git a/plugins/ChooseTheme/locale/nb/LC_MESSAGES/ChooseTheme.po b/plugins/ChooseTheme/locale/nb/LC_MESSAGES/ChooseTheme.po
new file mode 100644 (file)
index 0000000..206a477
--- /dev/null
@@ -0,0 +1,62 @@
+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the GNU social package.
+# FIRST AUTHOR abjectio@kollektivet0x242.no, 2015.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: Choose Theme\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2015-06-10 22:00+0100\n"
+"PO-Revision-Date: 2015-06-10 22:04+0100\n"
+"Last-Translator: Knut Erik Hollund <knut.erik@unlike.no>\n"
+"Language-Team: kollektivet0x242.no <abjectio@kollektivet0x242.no>\n"
+"Language: nb\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Generator: Poedit 1.5.4\n"
+"X-Poedit-Basepath: ./actions\n"
+"X-Poedit-KeywordsList: _m\n"
+"X-Poedit-SearchPath-0: ./actions\n"
+"X-Poedit-SearchPath-1: .\n"
+
+#: actions/choosethemesettings.php:38
+msgid "Choose theme settings"
+msgstr "Innstillinger"
+
+#: actions/choosethemesettings.php:47
+msgid "Choose theme"
+msgstr "Velg tema"
+
+#: actions/choosethemesettings.php:83
+msgid "Settings saved."
+msgstr "Innstillinger lagret."
+
+#: actions/choosethemesettings.php:87
+msgid "No valid theme chosen."
+msgstr "Ingen gyldige tema er valgt."
+
+#: actions/choosethemesettings.php:134
+msgid "Themes"
+msgstr "Temaer"
+
+#: actions/choosethemesettings.php:134
+msgid "Select a theme"
+msgstr "Velg tema"
+
+#: actions/choosethemesettings.php:151
+msgid "Save"
+msgstr "Lagre"
+
+#: ChooseThemePlugin.php:39
+msgid "Allowing user to select the preferred theme."
+msgstr "Lar brukeren velge sitt foretrukne tema."
+
+#: ChooseThemePlugin.php:55
+msgid "MENU"
+msgstr "Tema"
+
+#: ChooseThemePlugin.php:57
+msgid "Choose Theme"
+msgstr "Velg tema"
index c18559f49daaf1a4419e7ff53923c1b9e11f99cb..8e7f6f806152cb03e9b88e4ea6927614b1701650 100644 (file)
@@ -30,9 +30,7 @@
  * @link      http://status.net/
  */
 
-if (!defined('STATUSNET')) {
-    exit(1);
-}
+if (!defined('GNUSOCIAL')) { exit(1); }
 
 /**
  * Show a list of direct messages from or to the authenticating user
@@ -62,13 +60,11 @@ class ApiDirectMessageAction extends ApiAuthAction
      *
      * @return boolean success flag
      */
-    function prepare($args)
+    protected function prepare(array $args=array())
     {
         parent::prepare($args);
 
-        $this->user = $this->auth_user;
-
-        if (empty($this->user)) {
+        if (!$this->scoped instanceof Profile) {
             // TRANS: Client error given when a user was not found (404).
             $this->clientError(_('No such user.'), 404);
         }
@@ -83,30 +79,30 @@ class ApiDirectMessageAction extends ApiAuthAction
             $this->title = sprintf(
                 // TRANS: Title. %s is a user nickname.
                 _("Direct messages from %s"),
-                $this->user->nickname
+                $this->scoped->getNickname()
             );
             $this->subtitle = sprintf(
                 // TRANS: Subtitle. %s is a user nickname.
                 _("All the direct messages sent from %s"),
-                $this->user->nickname
+                $this->scoped->getNickname()
             );
-            $this->link = $server . $this->user->nickname . '/outbox';
+            $this->link = $server . $this->scoped->getNickname() . '/outbox';
             $this->selfuri_base = common_root_url() . 'api/direct_messages/sent';
-            $this->id = "tag:$taguribase:SentDirectMessages:" . $this->user->id;
+            $this->id = "tag:$taguribase:SentDirectMessages:" . $this->scoped->getID();
         } else {
             $this->title = sprintf(
                 // TRANS: Title. %s is a user nickname.
                 _("Direct messages to %s"),
-                $this->user->nickname
+                $this->scoped->getNickname()
             );
             $this->subtitle = sprintf(
                 // TRANS: Subtitle. %s is a user nickname.
                 _("All the direct messages sent to %s"),
-                $this->user->nickname
+                $this->scoped->getNickname()
             );
-            $this->link = $server . $this->user->nickname . '/inbox';
+            $this->link = $server . $this->scoped->getNickname() . '/inbox';
             $this->selfuri_base = common_root_url() . 'api/direct_messages';
-            $this->id = "tag:$taguribase:DirectMessages:" . $this->user->id;
+            $this->id = "tag:$taguribase:DirectMessages:" . $this->scoped->getID();
         }
 
         $this->messages = $this->getMessages();
@@ -114,18 +110,9 @@ class ApiDirectMessageAction extends ApiAuthAction
         return true;
     }
 
-    /**
-     * Handle the request
-     *
-     * Show the messages
-     *
-     * @param array $args $_REQUEST data (unused)
-     *
-     * @return void
-     */
-    function handle($args)
+    protected function handle()
     {
-        parent::handle($args);
+        parent::handle();
         $this->showMessages();
     }
 
@@ -166,9 +153,9 @@ class ApiDirectMessageAction extends ApiAuthAction
         $message  = new Message();
 
         if ($this->arg('sent')) {
-            $message->from_profile = $this->user->id;
+            $message->from_profile = $this->scoped->getID();
         } else {
-            $message->to_profile = $this->user->id;
+            $message->to_profile = $this->scoped->getID();
         }
 
         if (!empty($this->max_id)) {
index 653fa3a9ed0ce88c045d996d509393a5fd64faa7..e2c7ab5ca726ba7bdf8acd4162a4e44a2129e744 100644 (file)
@@ -30,9 +30,7 @@
  * @link      http://status.net/
  */
 
-if (!defined('STATUSNET')) {
-    exit(1);
-}
+if (!defined('GNUSOCIAL')) { exit(1); }
 
 /**
  * Creates a new direct message from the authenticating user to
@@ -65,7 +63,7 @@ class ApiDirectMessageNewAction extends ApiAuthAction
     {
         parent::prepare($args);
 
-        if (empty($this->user)) {
+        if (!$this->scoped instanceof Profile) {
             // TRANS: Client error when user not found for an API direct message action.
             $this->clientError(_('No such user.'), 404);
         }
@@ -111,10 +109,10 @@ class ApiDirectMessageNewAction extends ApiAuthAction
         if (!$this->other instanceof Profile) {
             // TRANS: Client error displayed if a recipient user could not be found (403).
             $this->clientError(_('Recipient user not found.'), 403);
-        } else if (!$this->user->mutuallySubscribed($this->other)) {
+        } else if (!$this->scoped->mutuallySubscribed($this->other)) {
             // TRANS: Client error displayed trying to direct message another user who's not a friend (403).
             $this->clientError(_('Cannot send direct messages to users who aren\'t your friend.'), 403);
-        } else if ($this->user->id == $this->other->id) {
+        } else if ($this->scoped->getID() === $this->other->getID()) {
 
             // Note: sending msgs to yourself is allowed by Twitter
 
@@ -123,8 +121,8 @@ class ApiDirectMessageNewAction extends ApiAuthAction
         }
 
         $message = Message::saveNew(
-            $this->user->id,
-            $this->other->id,
+            $this->scoped->getID(),
+            $this->other->getID(),
             html_entity_decode($this->content, ENT_NOQUOTES, 'UTF-8'),
             $this->source
         );
index d49c28fe559cb73dbad001a16de656d140770c57..b4fe68d4cc202695536ed20a46742e5ebe2bd85e 100644 (file)
@@ -41,10 +41,6 @@ table.profile_list tr {
     float: none;
 }
 
-table.profile_list tr.alt {
-    background-color: #def; /* zebra stripe */
-}
-
 table.profie_list td {
     width: 100%;
     padding: 0;
@@ -61,4 +57,4 @@ th.current.reverse {
     background-image: url(../images/control_arrow_up.gif);
     background-repeat: no-repeat;
     background-position: 60% 2px;
-}
\ No newline at end of file
+}
index 7474d0daa608f9cfa9a037a8da1b4f71bf11e13a..ab00068f6d20a5f438794e1986dc3d07a98db8b8 100644 (file)
  * @link      http://status.net/
  */
 
-if (!defined('STATUSNET')) {
-    exit(1);
-}
-
-require_once INSTALLDIR . '/lib/subscriptionlist.php';
+if (!defined('GNUSOCIAL')) { exit(1); }
 
 /**
  * Widget to show a sortable list of subscriptions
@@ -44,16 +40,6 @@ require_once INSTALLDIR . '/lib/subscriptionlist.php';
  */
 class SortableGroupList extends SortableSubscriptionList
 {
-    /** Owner of this list */
-    var $owner = null;
-
-    function __construct($profile, $owner=null, $action=null)
-    {
-        parent::__construct($profile, $owner, $action);
-
-        $this->owner = $owner;
-    }
-
     function startList()
     {
         $this->out->elementStart('table', array('class' => 'profile_list xoxo'));
@@ -119,25 +105,14 @@ class SortableGroupList extends SortableSubscriptionList
         $this->out->elementStart('tbody');
     }
 
-    function newListItem($profile, $odd)
+    function newListItem($profile)
     {
-        return new SortableGroupListItem($profile, $this->owner, $this->action, $odd);
+        return new SortableGroupListItem($profile, $this->owner, $this->action);
     }
 }
 
 class SortableGroupListItem extends SortableSubscriptionListItem
 {
-    /** Owner of this list */
-    var $owner = null;
-
-    function __construct($profile, $owner, $action, $alt)
-    {
-        parent::__construct($profile, $owner, $action, $alt);
-
-        $this->alt   = $alt; // is this row alternate?
-        $this->owner = $owner;
-    }
-
     function showHomepage()
     {
         if (!empty($this->profile->homepage)) {
index 75c42a5fdfc06fd254d6aca69b482295d0822dcc..719834bc917d3aa9c5e17a74c0e63e9470646725 100644 (file)
  * @link      http://status.net/
  */
 
-if (!defined('STATUSNET')) {
-    exit(1);
-}
-
-require_once INSTALLDIR . '/lib/subscriptionlist.php';
+if (!defined('GNUSOCIAL')) { exit(1); }
 
 /**
  * Widget to show a sortable list of subscriptions
@@ -44,16 +40,6 @@ require_once INSTALLDIR . '/lib/subscriptionlist.php';
  */
 class SortableSubscriptionList extends SubscriptionList
 {
-    /** Owner of this list */
-    var $owner = null;
-
-    function __construct($profile, $owner=null, $action=null)
-    {
-        parent::__construct($profile, $owner, $action);
-
-        $this->owner = $owner;
-    }
-
     function startList()
     {
         $this->out->elementStart('table', array('class' => 'profile_list xoxo'));
@@ -128,48 +114,14 @@ class SortableSubscriptionList extends SubscriptionList
         $this->out->elementEnd('table');
     }
 
-    function showProfiles()
+    function newListItem($profile)
     {
-        // Note: we don't use fetchAll() because it's borked with query()
-
-        $profiles = array();
-
-        while ($this->profile->fetch()) {
-            $profiles[] = clone($this->profile);
-        }
-
-        $cnt = count($profiles);
-
-        $max = min($cnt, $this->maxProfiles());
-
-        for ($i = 0; $i < $max; $i++) {
-            $odd = ($i % 2 == 0); // for zebra striping
-            $pli = $this->newListItem($profiles[$i], $odd);
-            $pli->show();
-        }
-
-        return $cnt;
-    }
-
-    function newListItem($profile, $odd)
-    {
-        return new SortableSubscriptionListItem($profile, $this->owner, $this->action, $odd);
+        return new SortableSubscriptionListItem($profile, $this->owner, $this->action);
     }
 }
 
 class SortableSubscriptionListItem extends SubscriptionListItem
 {
-    /** Owner of this list */
-    var $owner = null;
-
-    function __construct($profile, $owner, $action, $alt)
-    {
-        parent::__construct($profile, $owner, $action);
-
-        $this->alt   = $alt; // is this row alternate?
-        $this->owner = $owner;
-    }
-
     function startItem()
     {
         $attr = array(
@@ -177,10 +129,6 @@ class SortableSubscriptionListItem extends SubscriptionListItem
             'id'    => 'profile-' . $this->profile->id
         );
 
-        if ($this->alt) {
-            $attr['class'] .= ' alt';
-        }
-
         $this->out->elementStart('tr', $attr);
     }
 
index a777a28e031cacbab9a47b2335fc97ad12c689da..ea0b8ad6309ef263131b4e91835414dd1700da8f 100644 (file)
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 
-if (!defined('STATUSNET')) {
-    exit(1);
-}
+if (!defined('GNUSOCIAL')) { exit(1); }
 
 class ProfileDetailAction extends ShowstreamAction
 {
-
     function isReadOnly($args)
     {
         return true;
@@ -31,7 +28,7 @@ class ProfileDetailAction extends ShowstreamAction
 
     function title()
     {
-        return $this->profile->getFancyName();
+        return $this->target->getFancyName();
     }
 
     function showStylesheets() {
@@ -43,7 +40,7 @@ class ProfileDetailAction extends ShowstreamAction
     function showContent()
     {
         $cur = common_current_user();
-        if ($cur && $cur->id == $this->profile->id) { // your own page
+        if ($this->scoped instanceof Profile && $this->scoped->sameAs($this->target)) {
             $this->elementStart('div', 'entity_actions');
             $this->elementStart('ul');
             $this->elementStart('li', 'entity_edit');
@@ -57,7 +54,7 @@ class ProfileDetailAction extends ShowstreamAction
             $this->elementEnd('div');
         }
 
-        $widget = new ExtendedProfileWidget($this, $this->profile);
+        $widget = new ExtendedProfileWidget($this, $this->target);
         $widget->show();
     }
 }
index 8d8a33ec4493e03b84541b8223e875971442a8bd..73bf364c7b8daed8d072e42bf02858ced1c65d5b 100644 (file)
@@ -17,9 +17,7 @@
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 
-if (!defined('STATUSNET')) {
-    exit(1);
-}
+if (!defined('GNUSOCIAL')) { exit(1); }
 
 class ProfileDetailSettingsAction extends ProfileSettingsAction
 {
@@ -29,18 +27,6 @@ class ProfileDetailSettingsAction extends ProfileSettingsAction
         return _m('Extended profile settings');
     }
 
-    /**
-     * Instructions for use
-     *
-     * @return instructions for use
-     */
-    function getInstructions()
-    {
-        // TRANS: Usage instructions for profile settings.
-        return _m('You can update your personal profile info here '.
-                 'so people know more about you.');
-    }
-
     function showStylesheets() {
         parent::showStylesheets();
         $this->cssLink('plugins/ExtendedProfile/css/profiledetail.css');
@@ -53,36 +39,21 @@ class ProfileDetailSettingsAction extends ProfileSettingsAction
         return true;
     }
 
-    function handlePost()
+    protected function doPost()
     {
-        // CSRF protection
-        $token = $this->trimmed('token');
-        if (!$token || $token != common_session_token()) {
-            $this->showForm(
-                // TRANS: Client error displayed when the session token does not match or is not given.
-                _m('There was a problem with your session token. '
-                    .   'Try again, please.'
-                  )
-            );
-            return;
-        }
-
         if ($this->arg('save')) {
-            $this->saveDetails();
-        } else {
-            // TRANS: Message given submitting a form with an unknown action.
-            $this->showForm(_m('Unexpected form submission.'));
+            return $this->saveDetails();
         }
+
+        // TRANS: Message given submitting a form with an unknown action.
+        throw new ClientException(_m('Unexpected form submission.'));
     }
 
     function showContent()
     {
-        $cur = common_current_user();
-        $profile = $cur->getProfile();
-
         $widget = new ExtendedProfileWidget(
             $this,
-            $profile,
+            $this->scoped,
             ExtendedProfileWidget::EDITABLE
         );
         $widget->show();
@@ -92,49 +63,38 @@ class ProfileDetailSettingsAction extends ProfileSettingsAction
     {
         common_debug(var_export($_POST, true));
 
-        $user = common_current_user();
-
-        try {
-            $this->saveStandardProfileDetails($user);
+        $this->saveStandardProfileDetails();
 
-            $profile = $user->getProfile();
+        $simpleFieldNames = array('title', 'spouse', 'kids', 'manager');
+        $dateFieldNames   = array('birthday');
 
-            $simpleFieldNames = array('title', 'spouse', 'kids', 'manager');
-            $dateFieldNames   = array('birthday');
-
-            foreach ($simpleFieldNames as $name) {
-                $value = $this->trimmed('extprofile-' . $name);
-                if (!empty($value)) {
-                    $this->saveField($user, $name, $value);
-                }
+        foreach ($simpleFieldNames as $name) {
+            $value = $this->trimmed('extprofile-' . $name);
+            if (!empty($value)) {
+                $this->saveField($name, $value);
             }
+        }
 
-            foreach ($dateFieldNames as $name) {
-                $value = $this->trimmed('extprofile-' . $name);
-                $dateVal = $this->parseDate($name, $value);
-                $this->saveField(
-                    $user,
-                    $name,
-                    null,
-                    null,
-                    null,
-                    $dateVal
-                );
-            }
-
-            $this->savePhoneNumbers($user);
-            $this->saveIms($user);
-            $this->saveWebsites($user);
-            $this->saveExperiences($user);
-            $this->saveEducations($user);
-
-        } catch (Exception $e) {
-            $this->showForm($e->getMessage(), false);
-            return;
+        foreach ($dateFieldNames as $name) {
+            $value = $this->trimmed('extprofile-' . $name);
+            $dateVal = $this->parseDate($name, $value);
+            $this->saveField(
+                $name,
+                null,
+                null,
+                null,
+                $dateVal
+            );
         }
 
+        $this->savePhoneNumbers();
+        $this->saveIms();
+        $this->saveWebsites();
+        $this->saveExperiences();
+        $this->saveEducations();
+
         // TRANS: Success message after saving extended profile details.
-        $this->showForm(_m('Details saved.'), true);
+        return _m('Details saved.');
 
     }
 
@@ -168,15 +128,14 @@ class ProfileDetailSettingsAction extends ProfileSettingsAction
         return null;
     }
 
-    function savePhoneNumbers($user) {
+    function savePhoneNumbers() {
         $phones = $this->findPhoneNumbers();
-        $this->removeAll($user, 'phone');
+        $this->removeAll('phone');
         $i = 0;
         foreach($phones as $phone) {
             if (!empty($phone['value'])) {
                 ++$i;
                 $this->saveField(
-                    $user,
                     'phone',
                     $phone['value'],
                     $phone['rel'],
@@ -226,15 +185,14 @@ class ProfileDetailSettingsAction extends ProfileSettingsAction
         return $imArray;
     }
 
-    function saveIms($user) {
+    function saveIms() {
         $ims = $this->findIms();
-        $this->removeAll($user, 'im');
+        $this->removeAll('im');
         $i = 0;
         foreach($ims as $im) {
             if (!empty($im['value'])) {
                 ++$i;
                 $this->saveField(
-                    $user,
                     'im',
                     $im['value'],
                     $im['rel'],
@@ -262,9 +220,9 @@ class ProfileDetailSettingsAction extends ProfileSettingsAction
         return $wsArray;
     }
 
-    function saveWebsites($user) {
+    function saveWebsites() {
         $sites = $this->findWebsites();
-        $this->removeAll($user, 'website');
+        $this->removeAll('website');
         $i = 0;
         foreach($sites as $site) {
             if (!empty($site['value']) && !common_valid_http_url($site['value'])) {
@@ -276,7 +234,6 @@ class ProfileDetailSettingsAction extends ProfileSettingsAction
             if (!empty($site['value'])) {
                 ++$i;
                 $this->saveField(
-                    $user,
                     'website',
                     $site['value'],
                     $site['rel'],
@@ -317,20 +274,19 @@ class ProfileDetailSettingsAction extends ProfileSettingsAction
         return $expArray;
     }
 
-    function saveExperiences($user) {
+    function saveExperiences() {
         common_debug('save experiences');
         $experiences = $this->findExperiences();
 
-        $this->removeAll($user, 'company');
-        $this->removeAll($user, 'start');
-        $this->removeAll($user, 'end'); // also stores 'current'
+        $this->removeAll('company');
+        $this->removeAll('start');
+        $this->removeAll('end'); // also stores 'current'
 
         $i = 0;
         foreach($experiences as $experience) {
             if (!empty($experience['company'])) {
                 ++$i;
                 $this->saveField(
-                    $user,
                     'company',
                     $experience['company'],
                     null,
@@ -338,7 +294,6 @@ class ProfileDetailSettingsAction extends ProfileSettingsAction
                 );
 
                 $this->saveField(
-                    $user,
                     'start',
                     null,
                     null,
@@ -349,7 +304,6 @@ class ProfileDetailSettingsAction extends ProfileSettingsAction
                 // Save "current" employer indicator in rel
                 if ($experience['current']) {
                     $this->saveField(
-                        $user,
                         'end',
                         null,
                         'current', // rel
@@ -357,7 +311,6 @@ class ProfileDetailSettingsAction extends ProfileSettingsAction
                     );
                 } else {
                     $this->saveField(
-                        $user,
                         'end',
                         null,
                         null,
@@ -399,44 +352,40 @@ class ProfileDetailSettingsAction extends ProfileSettingsAction
     }
 
 
-    function saveEducations($user) {
+    function saveEducations() {
          common_debug('save education');
          $edus = $this->findEducations();
          common_debug(var_export($edus, true));
 
-         $this->removeAll($user, 'school');
-         $this->removeAll($user, 'degree');
-         $this->removeAll($user, 'degree_descr');
-         $this->removeAll($user, 'school_start');
-         $this->removeAll($user, 'school_end');
+         $this->removeAll('school');
+         $this->removeAll('degree');
+         $this->removeAll('degree_descr');
+         $this->removeAll('school_start');
+         $this->removeAll('school_end');
 
          $i = 0;
          foreach($edus as $edu) {
              if (!empty($edu['school'])) {
                  ++$i;
                  $this->saveField(
-                     $user,
                      'school',
                      $edu['school'],
                      null,
                      $i
                  );
                  $this->saveField(
-                     $user,
                      'degree',
                      $edu['degree'],
                      null,
                      $i
                  );
                  $this->saveField(
-                     $user,
                      'degree_descr',
                      $edu['description'],
                      null,
                      $i
                  );
                  $this->saveField(
-                     $user,
                      'school_start',
                      null,
                      null,
@@ -445,7 +394,6 @@ class ProfileDetailSettingsAction extends ProfileSettingsAction
                  );
 
                  $this->saveField(
-                     $user,
                      'school_end',
                      null,
                      null,
@@ -491,35 +439,33 @@ class ProfileDetailSettingsAction extends ProfileSettingsAction
     /**
      * Save an extended profile field as a Profile_detail
      *
-     * @param User   $user    the current user
      * @param string $name    field name
      * @param string $value   field value
      * @param string $rel     field rel (type)
      * @param int    $index   index (fields can have multiple values)
      * @param date   $date    related date
      */
-    function saveField($user, $name, $value, $rel = null, $index = null, $date = null)
+    function saveField($name, $value, $rel = null, $index = null, $date = null)
     {
-        $profile = $user->getProfile();
         $detail  = new Profile_detail();
 
-        $detail->profile_id  = $profile->id;
+        $detail->profile_id  = $this->scoped->getID();
         $detail->field_name  = $name;
         $detail->value_index = $index;
 
         $result = $detail->find(true);
 
-        if (empty($result)) {
-            $detial->value_index = $index;
+        if (!$result instanceof Profile_detail) {
+            $detail->value_index = $index;
             $detail->rel         = $rel;
             $detail->field_value = $value;
             $detail->date        = $date;
             $detail->created     = common_sql_now();
             $result = $detail->insert();
-            if (empty($result)) {
+            if ($result === false) {
                 common_log_db_error($detail, 'INSERT', __FILE__);
                 // TRANS: Server error displayed when a field could not be saved in the database.
-                $this->serverError(_m('Could not save profile details.'));
+                throw new ServerException(_m('Could not save profile details.'));
             }
         } else {
             $orig = clone($detail);
@@ -529,21 +475,20 @@ class ProfileDetailSettingsAction extends ProfileSettingsAction
             $detail->date        = $date;
 
             $result = $detail->update($orig);
-            if (empty($result)) {
+            if ($result === false) {
                 common_log_db_error($detail, 'UPDATE', __FILE__);
                 // TRANS: Server error displayed when a field could not be saved in the database.
-                $this->serverError(_m('Could not save profile details.'));
+                throw new ServerException(_m('Could not save profile details.'));
             }
         }
 
         $detail->free();
     }
 
-    function removeAll($user, $name)
+    function removeAll($name)
     {
-        $profile = $user->getProfile();
         $detail  = new Profile_detail();
-        $detail->profile_id  = $profile->id;
+        $detail->profile_id  = $this->scoped->getID();
         $detail->field_name  = $name;
         $detail->delete();
         $detail->free();
@@ -554,10 +499,8 @@ class ProfileDetailSettingsAction extends ProfileSettingsAction
      *
      * XXX: There's a lot of dupe code here from ProfileSettingsAction.
      *      Do not want.
-     *
-     * @param User $user the current user
      */
-    function saveStandardProfileDetails($user)
+    function saveStandardProfileDetails()
     {
         $fullname  = $this->trimmed('extprofile-fullname');
         $location  = $this->trimmed('extprofile-location');
@@ -581,54 +524,47 @@ class ProfileDetailSettingsAction extends ProfileSettingsAction
             }
         }
 
-        $profile = $user->getProfile();
-
-        $oldTags = $user->getSelfTags();
+        $oldTags = Profile_tag::getSelfTagsArray($this->scoped);
         $newTags = array_diff($tags, $oldTags);
 
-        if ($fullname    != $profile->fullname
-            || $location != $profile->location
+        if ($fullname    != $this->scoped->getFullname()
+            || $location != $this->scoped->location
             || !empty($newTags)
-            || $bio      != $profile->bio) {
+            || $bio      != $this->scoped->getDescription()) {
 
-            $orig = clone($profile);
+            $orig = clone($this->scoped);
 
-            $profile->nickname = $user->nickname;
-            $profile->fullname = $fullname;
-            $profile->bio      = $bio;
-            $profile->location = $location;
+            // Skipping nickname change here until we add logic for when the site allows it or not
+            // old Profilesettings will still let us do that.
+
+            $this->scoped->fullname = $fullname;
+            $this->scoped->bio      = $bio;
+            $this->scoped->location = $location;
 
             $loc = Location::fromName($location);
 
             if (empty($loc)) {
-                $profile->lat         = null;
-                $profile->lon         = null;
-                $profile->location_id = null;
-                $profile->location_ns = null;
+                $this->scoped->lat         = null;
+                $this->scoped->lon         = null;
+                $this->scoped->location_id = null;
+                $this->scoped->location_ns = null;
             } else {
-                $profile->lat         = $loc->lat;
-                $profile->lon         = $loc->lon;
-                $profile->location_id = $loc->location_id;
-                $profile->location_ns = $loc->location_ns;
+                $this->scoped->lat         = $loc->lat;
+                $this->scoped->lon         = $loc->lon;
+                $this->scoped->location_id = $loc->location_id;
+                $this->scoped->location_ns = $loc->location_ns;
             }
 
-            $profile->profileurl = common_profile_url($user->nickname);
-
-            $result = $profile->update($orig);
+            $result = $this->scoped->update($orig);
 
             if ($result === false) {
-                common_log_db_error($profile, 'UPDATE', __FILE__);
+                common_log_db_error($this->scoped, 'UPDATE', __FILE__);
                 // TRANS: Server error thrown when user profile settings could not be saved.
-                $this->serverError(_m('Could not save profile.'));
+                throw new ServerException(_m('Could not save profile.'));
             }
 
             // Set the user tags
-            $result = $user->setSelfTags($tags);
-
-            if (!$result) {
-                // TRANS: Server error thrown when user profile settings tags could not be saved.
-                $this->serverError(_m('Could not save tags.'));
-            }
+            $result = Profile_tag::setSelfTags($this->scoped, $tags);
 
             Event::handle('EndProfileSaveForm', array($this));
         }
index d73170b235a6355b0918e3bbdfd185fdb1f95fcd..3682e6fc9dc35ec1c4c6cdfe9687f1f41cda3b9b 100644 (file)
@@ -52,7 +52,7 @@ class ExtendedProfile
     function loadFields()
     {
         $detail = new Profile_detail();
-        $detail->profile_id = $this->profile->id;
+        $detail->profile_id = $this->profile->getID();
         $detail->find();
 
         $fields = array();
@@ -71,7 +71,7 @@ class ExtendedProfile
      */
     function getTags()
     {
-        return implode(' ', $this->user->getSelfTags());
+        return implode(' ', Profile_tag::getSelfTagsArray($this->profile));
     }
 
     /**
index 080c59612cfaa9d29359661a81a5a91e1b711697..7cf493a994101cb6ca5214fab58545c986fdcac6 100644 (file)
@@ -519,34 +519,30 @@ class FacebookfinishloginAction extends Action
 
     function tryLogin()
     {
-        $flink = Foreign_link::getByForeignID($this->fbuid, FACEBOOK_SERVICE);
-
-        if (!empty($flink)) {
+        try {
+            $flink = Foreign_link::getByForeignID($this->fbuid, FACEBOOK_SERVICE);
             $user = $flink->getUser();
 
-            if (!empty($user)) {
-
-                common_log(
-                    LOG_INFO,
-                    sprintf(
-                        'Logged in Facebook user %s as user %d (%s)',
-                        $this->fbuid,
-                        $user->nickname,
-                        $user->id
-                    ),
-                    __FILE__
-                );
+            common_log(
+                LOG_INFO,
+                sprintf(
+                    'Logged in Facebook user %s as user %d (%s)',
+                    $this->fbuid,
+                    $user->nickname,
+                    $user->id
+                ),
+                __FILE__
+            );
 
-                common_set_user($user);
-                common_real_login(true);
+            common_set_user($user);
+            common_real_login(true);
 
-                // clear out the stupid cookie
-                setcookie('fb_access_token', '', time() - 3600); // one hour ago
+            // clear out the stupid cookie
+            setcookie('fb_access_token', '', time() - 3600); // one hour ago
 
-                $this->goHome($user->nickname);
-            }
+            $this->goHome($user->nickname);
 
-        } else {
+        } catch (NoResultException $e) {
             $this->showForm(null, $this->bestNewNickname());
         }
     }
index 31e020a3ce7a42351856245ae2d13b0a82007946..67dd20e036dfd09a870e88bc56d0e6749e78712e 100644 (file)
@@ -26,9 +26,7 @@
  * @license   http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
  * @link      http://status.net/
  */
-if (!defined('STATUSNET')) {
-    exit(1);
-}
+if (!defined('GNUSOCIAL')) { exit(1); }
 
 /**
  * Edit user settings for Facebook
@@ -43,19 +41,11 @@ if (!defined('STATUSNET')) {
  */
 class FacebooksettingsAction extends SettingsAction {
     private $facebook; // Facebook PHP-SDK client obj
-    private $flink;
-    private $user;
 
-    /**
-     * For initializing members of the class.
-     *
-     * @param array $argarray misc. arguments
-     *
-     * @return boolean true
-     */
-    function prepare($args) {
-        parent::prepare($args);
+    protected $flink;
 
+    protected function doPreparation()
+    {
         $this->facebook = new Facebook(
             array(
                 'appId'  => common_config('facebook', 'appid'),
@@ -64,36 +54,21 @@ class FacebooksettingsAction extends SettingsAction {
             )
         );
 
-        $this->user = common_current_user();
-
         $this->flink = Foreign_link::getByUserID(
-            $this->user->id,
+            $this->scoped->getID(),
             FACEBOOK_SERVICE
         );
-
-        return true;
     }
 
-    /*
-     * Check the sessions token and dispatch
-     */
-    function handlePost($args) {
-        // CSRF protection
-
-        $token = $this->trimmed('token');
-        if (!$token || $token != common_session_token()) {
-            $this->showForm(
-                // TRANS: Client error displayed when the session token does not match or is not given.
-                _m('There was a problem with your session token. Try again, please.')
-            );
-            return;
-        }
-
+    protected function doPost()
+    {
         if ($this->arg('save')) {
-            $this->saveSettings();
+            return $this->saveSettings();
         } else if ($this->arg('disconnect')) {
-            $this->disconnect();
+            return $this->disconnect();
         }
+
+        throw new ClientException(_('No action to take on POST.'));
     }
 
     /**
@@ -122,109 +97,110 @@ class FacebooksettingsAction extends SettingsAction {
      * @return void
      */
     function showContent() {
-        if (!empty($this->flink)) {
-
-            $this->elementStart(
-                'form',
-                array(
-                    'method' => 'post',
-                    'id' => 'form_settings_facebook',
-                    'class' => 'form_settings',
-                    'action' => common_local_url('facebooksettings')
-                )
-            );
+        if (!$this->flink instanceof Foreign_link) {
+            throw new ServerException(_m('You have not linked this account to Facebook.'));
+        }
 
-            $this->hidden('token', common_session_token());
+        $this->elementStart(
+            'form',
+            array(
+                'method' => 'post',
+                'id' => 'form_settings_facebook',
+                'class' => 'form_settings',
+                'action' => common_local_url('facebooksettings')
+            )
+        );
 
-            // TRANS: Form note. User is connected to facebook.
-            $this->element('p', 'form_note', _m('Connected Facebook user'));
+        $this->hidden('token', common_session_token());
 
-            $this->elementStart('p', array('class' => 'facebook-user-display'));
+        // TRANS: Form note. User is connected to facebook.
+        $this->element('p', 'form_note', _m('Connected Facebook user'));
 
-            $this->element(
-                'fb:profile-pic',
-                array(
-                    'uid' => $this->flink->foreign_id,
-                    'size' => 'small',
-                    'linked' => 'true',
-                    'facebook-logo' => 'true'
-                )
-            );
+        $this->elementStart('p', array('class' => 'facebook-user-display'));
 
-            $this->element(
-                'fb:name',
-                array('uid' => $this->flink->foreign_id, 'useyou' => 'false')
-            );
+        $this->element(
+            'fb:profile-pic',
+            array(
+                'uid' => $this->flink->foreign_id,
+                'size' => 'small',
+                'linked' => 'true',
+                'facebook-logo' => 'true'
+            )
+        );
 
-            $this->elementEnd('p');
+        $this->element(
+            'fb:name',
+            array('uid' => $this->flink->foreign_id, 'useyou' => 'false')
+        );
 
-            $this->elementStart('ul', 'form_data');
+        $this->elementEnd('p');
 
-            $this->elementStart('li');
+        $this->elementStart('ul', 'form_data');
 
-            $this->checkbox(
-                'noticesync',
-                // TRANS: Checkbox label in Facebook settings.
-                _m('Publish my notices to Facebook.'),
-                ($this->flink) ? ($this->flink->noticesync & FOREIGN_NOTICE_SEND) : true
-            );
+        $this->elementStart('li');
 
-            $this->elementEnd('li');
+        $this->checkbox(
+            'noticesync',
+            // TRANS: Checkbox label in Facebook settings.
+            _m('Publish my notices to Facebook.'),
+            $this->flink->noticesync & FOREIGN_NOTICE_SEND
+        );
 
-            $this->elementStart('li');
+        $this->elementEnd('li');
 
-            $this->checkbox(
-                    'replysync',
-                    // TRANS: Checkbox label in Facebook settings.
-                    _m('Send "@" replies to Facebook.'),
-                    ($this->flink) ? ($this->flink->noticesync & FOREIGN_NOTICE_SEND_REPLY) : true
-            );
+        $this->elementStart('li');
 
-            $this->elementEnd('li');
+        $this->checkbox(
+                'replysync',
+                // TRANS: Checkbox label in Facebook settings.
+                _m('Send "@" replies to Facebook.'),
+                $this->flink->noticesync & FOREIGN_NOTICE_SEND_REPLY
+        );
 
-            $this->elementStart('li');
+        $this->elementEnd('li');
 
-            // TRANS: Submit button to save synchronisation settings.
-            $this->submit('save', _m('BUTTON', 'Save'));
+        $this->elementStart('li');
 
-            $this->elementEnd('li');
+        // TRANS: Submit button to save synchronisation settings.
+        $this->submit('save', _m('BUTTON', 'Save'));
 
-            $this->elementEnd('ul');
+        $this->elementEnd('li');
 
-            $this->elementStart('fieldset');
+        $this->elementEnd('ul');
 
-            // TRANS: Fieldset legend for form to disconnect from Facebook.
-            $this->element('legend', null, _m('Disconnect my account from Facebook'));
+        $this->elementStart('fieldset');
 
-            if (empty($this->user->password)) {
-                $this->elementStart('p', array('class' => 'form_guide'));
+        // TRANS: Fieldset legend for form to disconnect from Facebook.
+        $this->element('legend', null, _m('Disconnect my account from Facebook'));
 
-                $msg = sprintf(
-                    // TRANS: Notice in disconnect from Facebook form if user has no local StatusNet password.
-                    _m('Disconnecting your Faceboook would make it impossible to '.
-                       'log in! Please [set a password](%s) first.'),
-                    common_local_url('passwordsettings')
-                );
+        if (!$this->scoped->hasPassword()) {
+            $this->elementStart('p', array('class' => 'form_guide'));
 
-                $this->raw(common_markup_to_html($msg));
-                $this->elementEnd('p');
-            } else {
-                // @todo FIXME: i18n: This message is not being used.
-                // TRANS: Message displayed when initiating disconnect of a StatusNet user
-                // TRANS: from a Facebook account. %1$s is the StatusNet site name.
-                $msg = sprintf(_m('Keep your %1$s account but disconnect from Facebook. ' .
-                                  'You\'ll use your %1$s password to log in.'),
-                               common_config('site', 'name')
-                );
+            $msg = sprintf(
+                // TRANS: Notice in disconnect from Facebook form if user has no local StatusNet password.
+                _m('Disconnecting your Faceboook would make it impossible to '.
+                   'log in! Please [set a password](%s) first.'),
+                common_local_url('passwordsettings')
+            );
 
-                // TRANS: Submit button.
-                $this->submit('disconnect', _m('BUTTON', 'Disconnect'));
-            }
+            $this->raw(common_markup_to_html($msg));
+            $this->elementEnd('p');
+        } else {
+            // @todo FIXME: i18n: This message is not being used.
+            // TRANS: Message displayed when initiating disconnect of a StatusNet user
+            // TRANS: from a Facebook account. %1$s is the StatusNet site name.
+            $msg = sprintf(_m('Keep your %1$s account but disconnect from Facebook. ' .
+                              'You\'ll use your %1$s password to log in.'),
+                           common_config('site', 'name')
+            );
+
+            // TRANS: Submit button.
+            $this->submit('disconnect', _m('BUTTON', 'Disconnect'));
+        }
 
-            $this->elementEnd('fieldset');
+        $this->elementEnd('fieldset');
 
-            $this->elementEnd('form');
-         }
+        $this->elementEnd('form');
     }
 
     /*
@@ -242,11 +218,10 @@ class FacebooksettingsAction extends SettingsAction {
 
         if ($result === false) {
             // TRANS: Notice in case saving of synchronisation preferences fail.
-            $this->showForm(_m('There was a problem saving your sync preferences.'));
-        } else {
-            // TRANS: Confirmation that synchronisation settings have been saved into the system.
-            $this->showForm(_m('Sync preferences saved.'), true);
+            throw new ServerException(_m('There was a problem saving your sync preferences.'));
         }
+        // TRANS: Confirmation that synchronisation settings have been saved into the system.
+        return _m('Sync preferences saved.');
     }
 
     /*
@@ -258,12 +233,12 @@ class FacebooksettingsAction extends SettingsAction {
         $this->flink = null;
 
         if ($result === false) {
-            common_log_db_error($user, 'DELETE', __FILE__);
+            common_log_db_error($this->flink, 'DELETE', __FILE__);
             // TRANS: Server error displayed when deleting the link to a Facebook account fails.
-            $this->serverError(_m('Could not delete link to Facebook.'));
+            throw new ServerException(_m('Could not delete link to Facebook.'));
         }
 
-        // TRANS: Confirmation message. StatusNet account was unlinked from Facebook.
-        $this->showForm(_m('You have disconnected from Facebook.'), true);
+        // TRANS: Confirmation message. GNU social account was unlinked from Facebook.
+        return _m('You have disconnected this account from Facebook.');
     }
 }
index 5b512dfdff6cb5ca70ea660601cb38582dab08ac..5faad5dfb767f009606311147d935408a6a57dce 100644 (file)
@@ -66,13 +66,12 @@ class Facebookclient
         $this->notice = $notice;
 
         $profile_id = $profile ? $profile->id : $notice->profile_id;
-        $this->flink = Foreign_link::getByUserID(
-            $profile_id,
-            FACEBOOK_SERVICE
-        );
-
-        if (!empty($this->flink)) {
+        try {
+            $this->flink = Foreign_link::getByUserID($profile_id, FACEBOOK_SERVICE);
             $this->user = $this->flink->getUser();
+        } catch (NoResultException $e) {
+            // at least $this->flink could've gotten set to something,
+            // but the logic that was here before didn't care, so let's not care either
         }
     }
 
@@ -918,12 +917,9 @@ class Facebookclient
     static function addFacebookUser($fbuser)
     {
         // remove any existing, possibly outdated, record
-        $luser = Foreign_user::getForeignUser($fbuser->id, FACEBOOK_SERVICE);
-
-        if (!empty($luser)) {
-
-            $result = $luser->delete();
-
+        try {
+            $fuser = Foreign_user::getForeignUser($fbuser->id, FACEBOOK_SERVICE);
+            $result = $fuser->delete();
             if ($result != false) {
                 common_log(
                     LOG_INFO,
@@ -935,6 +931,8 @@ class Facebookclient
                     __FILE__
                 );
             }
+        } catch (NoResultException $e) {
+            // no old foreign users exist for this id
         }
 
         $fuser = new Foreign_user();
index 0cbebd723cf6ad430818134bb601119f3ce05af1..ca5602d5ec16ba1616ab8a818a02039d4b91847c 100644 (file)
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 
-if (!defined('STATUSNET') && !defined('LACONICA')) {
-    exit(1);
-}
-
-require_once INSTALLDIR.'/lib/rssaction.php';
+if (!defined('GNUSOCIAL')) { exit(1); }
 
 /**
  * RSS feed for user favorites action class.
@@ -47,50 +43,15 @@ require_once INSTALLDIR.'/lib/rssaction.php';
  * @license  http://www.fsf.org/licensing/licenses/agpl.html AGPLv3
  * @link     http://status.net/
  */
-class FavoritesrssAction extends Rss10Action
+class FavoritesrssAction extends TargetedRss10Action
 {
-    /** The user whose favorites to display */
-
-    var $user = null;
-
-    /**
-     * Find the user to display by supplied nickname
-     *
-     * @param array $args Arguments from $_REQUEST
-     *
-     * @return boolean success
-     */
-    function prepare($args)
+    protected function getNotices()
     {
-        parent::prepare($args);
-
-        $nickname   = $this->trimmed('nickname');
-        $this->user = User::getKV('nickname', $nickname);
+        // is this our own stream?
+        $own = $this->scoped instanceof Profile ? $this->target->getID() === $this->scoped->getID() : false;
 
-        if (!$this->user) {
-            // TRANS: Client error displayed when trying to get the RSS feed with favorites of a user that does not exist.
-            $this->clientError(_('No such user.'));
-        } else {
-            $this->notices = $this->getNotices($this->limit);
-            return true;
-        }
-    }
-
-    /**
-     * Get notices
-     *
-     * @param integer $limit max number of notices to return
-     *
-     * @return array notices
-     */
-    function getNotices($limit=0)
-    {
-        $notice  = Fave::stream($this->user->id, 0, $limit, $false);
-        $notices = array();
-        while ($notice->fetch()) {
-            $notices[] = clone($notice);
-        }
-        return $notices;
+        $stream = Fave::stream($this->target->getID(), 0, $this->limit, $own);
+        return $stream->fetchAll();
     }
 
      /**
@@ -116,15 +77,4 @@ class FavoritesrssAction extends Rss10Action
                                         $user->nickname, common_config('site', 'name')));
         return $c;
     }
-
-    /**
-     * Get image.
-     *
-     * @return void
-    */
-    function getImage()
-    {
-        return null;
-    }
-
 }
index 98a6bfc5bfbe30dfb7a7e05903b0c446792fa470..cba29063c28b2de8787890db5c0920ac98ac5c8b 100644 (file)
  * @link      http://status.net/
  */
 
-if (!defined('STATUSNET') && !defined('LACONICA')) {
-    exit(1);
-}
-
-require_once INSTALLDIR.'/lib/personalgroupnav.php';
-require_once INSTALLDIR.'/lib/noticelist.php';
-require_once INSTALLDIR.'/lib/feedlist.php';
+if (!defined('GNUSOCIAL')) { exit(1); }
 
 /**
  * List of replies
@@ -44,119 +38,29 @@ require_once INSTALLDIR.'/lib/feedlist.php';
  * @license  http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
  * @link     http://status.net/
  */
-class ShowfavoritesAction extends Action
+class ShowfavoritesAction extends ShowstreamAction
 {
-    /** User we're getting the faves of */
-    var $user = null;
-    /** Page of the faves we're on */
-    var $page = null;
-
-    /**
-     * Is this a read-only page?
-     *
-     * @return boolean true
-     */
-    function isReadOnly($args)
-    {
-        return true;
-    }
-
-    /**
-     * Title of the page
-     *
-     * Includes name of user and page number.
-     *
-     * @return string title of page
-     */
     function title()
     {
         if ($this->page == 1) {
             // TRANS: Title for first page of favourite notices of a user.
             // TRANS: %s is the user for whom the favourite notices are displayed.
-            return sprintf(_('%s\'s favorite notices'), $this->user->nickname);
+            return sprintf(_('%s\'s favorite notices'), $this->getTarget()->getNickname());
         } else {
             // TRANS: Title for all but the first page of favourite notices of a user.
             // TRANS: %1$s is the user for whom the favourite notices are displayed, %2$d is the page number.
             return sprintf(_('%1$s\'s favorite notices, page %2$d'),
-                           $this->user->nickname,
+                           $this->getTarget()->getNickname(),
                            $this->page);
         }
     }
 
-    /**
-     * Prepare the object
-     *
-     * Check the input values and initialize the object.
-     * Shows an error page on bad input.
-     *
-     * @param array $args $_REQUEST data
-     *
-     * @return boolean success flag
-     */
-    function prepare($args)
+    public function getStream()
     {
-        parent::prepare($args);
-
-        $nickname = common_canonical_nickname($this->arg('nickname'));
-
-        $this->user = User::getKV('nickname', $nickname);
-
-        if (!$this->user) {
-            // TRANS: Client error displayed when trying to display favourite notices for a non-existing user.
-            $this->clientError(_('No such user.'));
-        }
-
-        $this->page = $this->trimmed('page');
-
-        if (!$this->page) {
-            $this->page = 1;
-        }
-
-        common_set_returnto($this->selfUrl());
-
-        $cur = common_current_user();
-
-        // Show imported/gateway notices as well as local if
-        // the user is looking at their own favorites, otherwise not.
-        $this->notice = Fave::stream($this->user->id,
-                                     ($this->page-1)*NOTICES_PER_PAGE,  // offset
-                                     NOTICES_PER_PAGE + 1,              // limit
-                                     (!empty($cur) && $cur->id == $this->user->id)  // own feed?
-                                    );
-
-        if (empty($this->notice)) {
-            // TRANS: Server error displayed when favourite notices could not be retrieved from the database.
-            $this->serverError(_('Could not retrieve favorite notices.'));
-        }
-
-        if($this->page > 1 && $this->notice->N == 0){
-            // TRANS: Client error when page not found (404)
-            $this->clientError(_('No such page.'), 404);
-        }
-
-        return true;
-    }
-
-    /**
-     * Handle a request
-     *
-     * Just show the page. All args already handled.
-     *
-     * @param array $args $_REQUEST data
-     *
-     * @return void
-     */
-    function handle($args)
-    {
-        parent::handle($args);
-        $this->showPage();
+        $own = $this->scoped instanceof Profile ? $this->scoped->sameAs($this->getTarget()) : false;
+        return new FaveNoticeStream($this->getTarget()->getID(), $own);
     }
 
-    /**
-     * Feeds for the <head> section
-     *
-     * @return array Feed objects to show
-     */
     function getFeeds()
     {
         return array(new Feed(Feed::JSON,
@@ -223,7 +127,7 @@ class ShowfavoritesAction extends Action
      *
      * @return void
      */
-    function showContent()
+    function showNotices()
     {
         $nl = new FavoritesNoticeList($this->notice, $this);
 
@@ -234,7 +138,7 @@ class ShowfavoritesAction extends Action
 
         $this->pagination($this->page > 1, $cnt > NOTICES_PER_PAGE,
                           $this->page, 'showfavorites',
-                          array('nickname' => $this->user->nickname));
+                          array('nickname' => $this->getTarget()->getNickname()));
     }
 
     function showPageNotice() {
index caad8fde11f0a77da6e6ee9441791c93cbda560e..a8e2546c4f846b05b1eb22b97f98c1a0fab7cee9 100644 (file)
@@ -57,25 +57,27 @@ class GeoURLPlugin extends Plugin
      *
      * @return boolean event handler flag
      */
-    function onEndShowHeadElements($action)
+    function onEndShowHeadElements(Action $action)
     {
         $name = $action->trimmed('action');
 
         $location = null;
 
-        if ($name == 'showstream') {
-            $profile = $action->profile;
-            if (!empty($profile) && !empty($profile->lat) && !empty($profile->lon)) {
+        if ($action instanceof ShowstreamAction) {
+            $profile = $action->getTarget();
+            if (!empty($profile->lat) && !empty($profile->lon)) {
                 $location = $profile->lat . ', ' . $profile->lon;
             }
-        } else if ($name == 'shownotice') {
-            $notice = $action->profile;
-            if (!empty($notice) && !empty($notice->lat) && !empty($notice->lon)) {
+        } elseif ($action instanceof ShownoticeAction) {
+            // FIXME: getNotice in ShownoticeAction will do a new lookup, we should fix those classes
+            // so they can reliably just get a pre-stored notice object which was fetched in Shownotice prepare()...
+            $notice = $action->notice;
+            if ($notice instanceof Notice && !empty($notice->lat) && !empty($notice->lon)) {
                 $location = $notice->lat . ', ' . $notice->lon;
             }
         }
 
-        if (!empty($location)) {
+        if (!is_null($location)) {
             $action->element('meta', array('name' => 'ICBM',
                                            'content' => $location));
             $action->element('meta', array('name' => 'DC.title',
diff --git a/plugins/Gravatar/GravatarPlugin.php b/plugins/Gravatar/GravatarPlugin.php
deleted file mode 100644 (file)
index cf9e3a0..0000000
+++ /dev/null
@@ -1,74 +0,0 @@
-<?php
-/*
- * StatusNet - the distributed open-source microblogging tool
- * Copyright (C) 2009,2011 StatusNet, 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/>.
- */
-
-/**
- * @package GravatarPlugin
- * @maintainer Eric Helgeson <erichelgeson@gmail.com>
- */
-
-if (!defined('STATUSNET') && !defined('LACONICA')) {
-    // This check helps protect against security problems;
-    // your code file can't be executed directly from the web.
-    exit(1);
-}
-
-class GravatarPlugin extends Plugin
-{
-    function onEndProfileGetAvatar($profile, $size, &$avatar)
-    {
-        if (empty($avatar)) {
-            try {
-                $user = $profile->getUser();
-                if (!empty($user->email)) {
-                    // Fake one!
-                    $avatar = new Avatar();
-                    $avatar->width = $avatar->height = $size;
-                    $avatar->url = $this->gravatar_url($user->email, $size);
-                    return false;
-                }
-            } catch (NoSuchUserException $e) {
-                return true;
-            }
-        }
-
-        return true;
-    }
-
-    function gravatar_url($email, $size)
-    {
-        $url = "https://secure.gravatar.com/avatar.php?gravatar_id=".
-                md5(strtolower($email)).
-                "&default=".urlencode(Avatar::defaultImage($size)).
-                "&size=".$size;
-            return $url;
-    }
-
-    function onPluginVersion(array &$versions)
-    {
-        $versions[] = array('name' => 'Gravatar',
-                            'version' => GNUSOCIAL_VERSION,
-                            'author' => 'Eric Helgeson, Evan Prodromou',
-                            'homepage' => 'http://status.net/wiki/Plugin:Gravatar',
-                            'rawdescription' =>
-                            // TRANS: Plugin decsription.
-                            _m('The Gravatar plugin allows users to use their <a href="http://www.gravatar.com/">Gravatar</a> with StatusNet.'));
-
-        return true;
-    }
-}
diff --git a/plugins/Gravatar/README b/plugins/Gravatar/README
deleted file mode 100644 (file)
index 0f6c728..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-GravatarPlugin 0.1
-
-About:
-This will allow users to use their Gravatar Avatar with your StatusNet install.
-
-Configuration:
-add this to your config.php:
-addPlugin('Gravatar', array());
-
-To do:
-Site default all on for gravatar by default
-Migration Script
diff --git a/plugins/Gravatar/locale/Gravatar.pot b/plugins/Gravatar/locale/Gravatar.pot
deleted file mode 100644 (file)
index 01bcc5d..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-# SOME DESCRIPTIVE TITLE.
-# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
-# This file is distributed under the same license as the PACKAGE package.
-# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
-#
-#, fuzzy
-msgid ""
-msgstr ""
-"Project-Id-Version: PACKAGE VERSION\n"
-"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2015-02-27 16:31+0100\n"
-"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
-"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
-"Language-Team: LANGUAGE <LL@li.org>\n"
-"Language: \n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=CHARSET\n"
-"Content-Transfer-Encoding: 8bit\n"
-
-#. TRANS: Plugin decsription.
-#: GravatarPlugin.php:70
-msgid ""
-"The Gravatar plugin allows users to use their <a href=\"http://www.gravatar."
-"com/\">Gravatar</a> with StatusNet."
-msgstr ""
diff --git a/plugins/Gravatar/locale/af/LC_MESSAGES/Gravatar.po b/plugins/Gravatar/locale/af/LC_MESSAGES/Gravatar.po
deleted file mode 100644 (file)
index 0f97b86..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-# SOME DESCRIPTIVE TITLE.
-# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
-# This file is distributed under the same license as the PACKAGE package.
-# 
-# Translators:
-msgid ""
-msgstr ""
-"Project-Id-Version: GNU social\n"
-"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2015-02-02 17:47+0100\n"
-"PO-Revision-Date: 2015-02-06 16:27+0000\n"
-"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
-"Language-Team: Afrikaans (http://www.transifex.com/projects/p/gnu-social/language/af/)\n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
-"Content-Transfer-Encoding: 8bit\n"
-"Language: af\n"
-"Plural-Forms: nplurals=2; plural=(n != 1);\n"
-
-#. TRANS: Plugin decsription.
-#: GravatarPlugin.php:70
-msgid ""
-"The Gravatar plugin allows users to use their <a "
-"href=\"http://www.gravatar.com/\">Gravatar</a> with StatusNet."
-msgstr ""
diff --git a/plugins/Gravatar/locale/ar/LC_MESSAGES/Gravatar.po b/plugins/Gravatar/locale/ar/LC_MESSAGES/Gravatar.po
deleted file mode 100644 (file)
index 0ffd7f7..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-# SOME DESCRIPTIVE TITLE.
-# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
-# This file is distributed under the same license as the PACKAGE package.
-# 
-# Translators:
-msgid ""
-msgstr ""
-"Project-Id-Version: GNU social\n"
-"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2015-02-02 17:47+0100\n"
-"PO-Revision-Date: 2015-02-06 16:27+0000\n"
-"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
-"Language-Team: Arabic (http://www.transifex.com/projects/p/gnu-social/language/ar/)\n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
-"Content-Transfer-Encoding: 8bit\n"
-"Language: ar\n"
-"Plural-Forms: nplurals=6; plural=n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n%100>=3 && n%100<=10 ? 3 : n%100>=11 && n%100<=99 ? 4 : 5;\n"
-
-#. TRANS: Plugin decsription.
-#: GravatarPlugin.php:70
-msgid ""
-"The Gravatar plugin allows users to use their <a "
-"href=\"http://www.gravatar.com/\">Gravatar</a> with StatusNet."
-msgstr ""
diff --git a/plugins/Gravatar/locale/arz/LC_MESSAGES/Gravatar.po b/plugins/Gravatar/locale/arz/LC_MESSAGES/Gravatar.po
deleted file mode 100644 (file)
index 86ede50..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-# SOME DESCRIPTIVE TITLE.
-# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
-# This file is distributed under the same license as the PACKAGE package.
-# 
-# Translators:
-msgid ""
-msgstr ""
-"Project-Id-Version: GNU social\n"
-"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2015-02-02 17:47+0100\n"
-"PO-Revision-Date: 2015-02-06 16:27+0000\n"
-"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
-"Language-Team: Arabic (Egypt) (http://www.transifex.com/projects/p/gnu-social/language/ar_EG/)\n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
-"Content-Transfer-Encoding: 8bit\n"
-"Language: ar_EG\n"
-"Plural-Forms: nplurals=6; plural=n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n%100>=3 && n%100<=10 ? 3 : n%100>=11 && n%100<=99 ? 4 : 5;\n"
-
-#. TRANS: Plugin decsription.
-#: GravatarPlugin.php:70
-msgid ""
-"The Gravatar plugin allows users to use their <a "
-"href=\"http://www.gravatar.com/\">Gravatar</a> with StatusNet."
-msgstr ""
diff --git a/plugins/Gravatar/locale/ast/LC_MESSAGES/Gravatar.po b/plugins/Gravatar/locale/ast/LC_MESSAGES/Gravatar.po
deleted file mode 100644 (file)
index fe73afa..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-# SOME DESCRIPTIVE TITLE.
-# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
-# This file is distributed under the same license as the PACKAGE package.
-# 
-# Translators:
-msgid ""
-msgstr ""
-"Project-Id-Version: GNU social\n"
-"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2015-02-02 17:47+0100\n"
-"PO-Revision-Date: 2015-02-06 16:27+0000\n"
-"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
-"Language-Team: Asturian (http://www.transifex.com/projects/p/gnu-social/language/ast/)\n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
-"Content-Transfer-Encoding: 8bit\n"
-"Language: ast\n"
-"Plural-Forms: nplurals=2; plural=(n != 1);\n"
-
-#. TRANS: Plugin decsription.
-#: GravatarPlugin.php:70
-msgid ""
-"The Gravatar plugin allows users to use their <a "
-"href=\"http://www.gravatar.com/\">Gravatar</a> with StatusNet."
-msgstr ""
diff --git a/plugins/Gravatar/locale/be-tarask/LC_MESSAGES/Gravatar.po b/plugins/Gravatar/locale/be-tarask/LC_MESSAGES/Gravatar.po
deleted file mode 100644 (file)
index b495ade..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-# SOME DESCRIPTIVE TITLE.
-# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
-# This file is distributed under the same license as the PACKAGE package.
-# 
-# Translators:
-msgid ""
-msgstr ""
-"Project-Id-Version: GNU social\n"
-"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2015-02-02 17:47+0100\n"
-"PO-Revision-Date: 2015-02-06 16:27+0000\n"
-"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
-"Language-Team: Belarusian (Tarask) (http://www.transifex.com/projects/p/gnu-social/language/be@tarask/)\n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
-"Content-Transfer-Encoding: 8bit\n"
-"Language: be@tarask\n"
-"Plural-Forms: nplurals=4; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n"
-
-#. TRANS: Plugin decsription.
-#: GravatarPlugin.php:70
-msgid ""
-"The Gravatar plugin allows users to use their <a "
-"href=\"http://www.gravatar.com/\">Gravatar</a> with StatusNet."
-msgstr ""
diff --git a/plugins/Gravatar/locale/bg/LC_MESSAGES/Gravatar.po b/plugins/Gravatar/locale/bg/LC_MESSAGES/Gravatar.po
deleted file mode 100644 (file)
index 7cd09ef..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-# SOME DESCRIPTIVE TITLE.
-# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
-# This file is distributed under the same license as the PACKAGE package.
-# 
-# Translators:
-msgid ""
-msgstr ""
-"Project-Id-Version: GNU social\n"
-"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2015-02-02 17:47+0100\n"
-"PO-Revision-Date: 2015-02-06 16:27+0000\n"
-"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
-"Language-Team: Bulgarian (http://www.transifex.com/projects/p/gnu-social/language/bg/)\n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
-"Content-Transfer-Encoding: 8bit\n"
-"Language: bg\n"
-"Plural-Forms: nplurals=2; plural=(n != 1);\n"
-
-#. TRANS: Plugin decsription.
-#: GravatarPlugin.php:70
-msgid ""
-"The Gravatar plugin allows users to use their <a "
-"href=\"http://www.gravatar.com/\">Gravatar</a> with StatusNet."
-msgstr ""
diff --git a/plugins/Gravatar/locale/br/LC_MESSAGES/Gravatar.po b/plugins/Gravatar/locale/br/LC_MESSAGES/Gravatar.po
deleted file mode 100644 (file)
index 92ab60a..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-# SOME DESCRIPTIVE TITLE.
-# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
-# This file is distributed under the same license as the PACKAGE package.
-# 
-# Translators:
-msgid ""
-msgstr ""
-"Project-Id-Version: GNU social\n"
-"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2015-02-02 17:47+0100\n"
-"PO-Revision-Date: 2015-02-06 16:27+0000\n"
-"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
-"Language-Team: Breton (http://www.transifex.com/projects/p/gnu-social/language/br/)\n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
-"Content-Transfer-Encoding: 8bit\n"
-"Language: br\n"
-"Plural-Forms: nplurals=2; plural=(n > 1);\n"
-
-#. TRANS: Plugin decsription.
-#: GravatarPlugin.php:70
-msgid ""
-"The Gravatar plugin allows users to use their <a "
-"href=\"http://www.gravatar.com/\">Gravatar</a> with StatusNet."
-msgstr ""
diff --git a/plugins/Gravatar/locale/ca/LC_MESSAGES/Gravatar.po b/plugins/Gravatar/locale/ca/LC_MESSAGES/Gravatar.po
deleted file mode 100644 (file)
index 1191b68..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-# SOME DESCRIPTIVE TITLE.
-# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
-# This file is distributed under the same license as the PACKAGE package.
-# 
-# Translators:
-msgid ""
-msgstr ""
-"Project-Id-Version: GNU social\n"
-"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2015-02-02 17:47+0100\n"
-"PO-Revision-Date: 2015-02-06 16:43+0000\n"
-"Last-Translator: digitaldreamer <digitaldreamer@email.cz>\n"
-"Language-Team: Catalan (http://www.transifex.com/projects/p/gnu-social/language/ca/)\n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
-"Content-Transfer-Encoding: 8bit\n"
-"Language: ca\n"
-"Plural-Forms: nplurals=2; plural=(n != 1);\n"
-
-#. TRANS: Plugin decsription.
-#: GravatarPlugin.php:70
-msgid ""
-"The Gravatar plugin allows users to use their <a "
-"href=\"http://www.gravatar.com/\">Gravatar</a> with StatusNet."
-msgstr "El connector del Gravatar permet als usuaris fer servir llur <a href=\"http://www.gravatar.com/\">Gravatar</a> amb l'StatusNet."
diff --git a/plugins/Gravatar/locale/cs/LC_MESSAGES/Gravatar.po b/plugins/Gravatar/locale/cs/LC_MESSAGES/Gravatar.po
deleted file mode 100644 (file)
index 2ce5576..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-# SOME DESCRIPTIVE TITLE.
-# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
-# This file is distributed under the same license as the PACKAGE package.
-# 
-# Translators:
-msgid ""
-msgstr ""
-"Project-Id-Version: GNU social\n"
-"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2015-02-02 17:47+0100\n"
-"PO-Revision-Date: 2015-02-06 16:27+0000\n"
-"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
-"Language-Team: Czech (http://www.transifex.com/projects/p/gnu-social/language/cs/)\n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
-"Content-Transfer-Encoding: 8bit\n"
-"Language: cs\n"
-"Plural-Forms: nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;\n"
-
-#. TRANS: Plugin decsription.
-#: GravatarPlugin.php:70
-msgid ""
-"The Gravatar plugin allows users to use their <a "
-"href=\"http://www.gravatar.com/\">Gravatar</a> with StatusNet."
-msgstr ""
diff --git a/plugins/Gravatar/locale/da/LC_MESSAGES/Gravatar.po b/plugins/Gravatar/locale/da/LC_MESSAGES/Gravatar.po
deleted file mode 100644 (file)
index d47b755..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-# SOME DESCRIPTIVE TITLE.
-# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
-# This file is distributed under the same license as the PACKAGE package.
-# 
-# Translators:
-msgid ""
-msgstr ""
-"Project-Id-Version: GNU social\n"
-"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2015-02-02 17:47+0100\n"
-"PO-Revision-Date: 2015-02-06 16:27+0000\n"
-"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
-"Language-Team: Danish (http://www.transifex.com/projects/p/gnu-social/language/da/)\n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
-"Content-Transfer-Encoding: 8bit\n"
-"Language: da\n"
-"Plural-Forms: nplurals=2; plural=(n != 1);\n"
-
-#. TRANS: Plugin decsription.
-#: GravatarPlugin.php:70
-msgid ""
-"The Gravatar plugin allows users to use their <a "
-"href=\"http://www.gravatar.com/\">Gravatar</a> with StatusNet."
-msgstr ""
diff --git a/plugins/Gravatar/locale/de/LC_MESSAGES/Gravatar.po b/plugins/Gravatar/locale/de/LC_MESSAGES/Gravatar.po
deleted file mode 100644 (file)
index 625c20c..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-# SOME DESCRIPTIVE TITLE.
-# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
-# This file is distributed under the same license as the PACKAGE package.
-# 
-# Translators:
-msgid ""
-msgstr ""
-"Project-Id-Version: GNU social\n"
-"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2015-02-02 17:47+0100\n"
-"PO-Revision-Date: 2015-02-06 16:43+0000\n"
-"Last-Translator: digitaldreamer <digitaldreamer@email.cz>\n"
-"Language-Team: German (http://www.transifex.com/projects/p/gnu-social/language/de/)\n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
-"Content-Transfer-Encoding: 8bit\n"
-"Language: de\n"
-"Plural-Forms: nplurals=2; plural=(n != 1);\n"
-
-#. TRANS: Plugin decsription.
-#: GravatarPlugin.php:70
-msgid ""
-"The Gravatar plugin allows users to use their <a "
-"href=\"http://www.gravatar.com/\">Gravatar</a> with StatusNet."
-msgstr "Das Gravatar-Plugin erlaubt es Benutzern, ihr <a href=\"http://www.gravatar.com/\">Gravatar</a> mit StatusNet zu verwenden."
diff --git a/plugins/Gravatar/locale/el/LC_MESSAGES/Gravatar.po b/plugins/Gravatar/locale/el/LC_MESSAGES/Gravatar.po
deleted file mode 100644 (file)
index 021657d..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-# SOME DESCRIPTIVE TITLE.
-# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
-# This file is distributed under the same license as the PACKAGE package.
-# 
-# Translators:
-msgid ""
-msgstr ""
-"Project-Id-Version: GNU social\n"
-"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2015-02-02 17:47+0100\n"
-"PO-Revision-Date: 2015-02-06 16:27+0000\n"
-"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
-"Language-Team: Greek (http://www.transifex.com/projects/p/gnu-social/language/el/)\n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
-"Content-Transfer-Encoding: 8bit\n"
-"Language: el\n"
-"Plural-Forms: nplurals=2; plural=(n != 1);\n"
-
-#. TRANS: Plugin decsription.
-#: GravatarPlugin.php:70
-msgid ""
-"The Gravatar plugin allows users to use their <a "
-"href=\"http://www.gravatar.com/\">Gravatar</a> with StatusNet."
-msgstr ""
diff --git a/plugins/Gravatar/locale/en_GB/LC_MESSAGES/Gravatar.po b/plugins/Gravatar/locale/en_GB/LC_MESSAGES/Gravatar.po
deleted file mode 100644 (file)
index 7bc45a1..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-# SOME DESCRIPTIVE TITLE.
-# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
-# This file is distributed under the same license as the PACKAGE package.
-# 
-# Translators:
-msgid ""
-msgstr ""
-"Project-Id-Version: GNU social\n"
-"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2015-02-02 17:47+0100\n"
-"PO-Revision-Date: 2015-02-06 16:27+0000\n"
-"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
-"Language-Team: English (United Kingdom) (http://www.transifex.com/projects/p/gnu-social/language/en_GB/)\n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
-"Content-Transfer-Encoding: 8bit\n"
-"Language: en_GB\n"
-"Plural-Forms: nplurals=2; plural=(n != 1);\n"
-
-#. TRANS: Plugin decsription.
-#: GravatarPlugin.php:70
-msgid ""
-"The Gravatar plugin allows users to use their <a "
-"href=\"http://www.gravatar.com/\">Gravatar</a> with StatusNet."
-msgstr ""
diff --git a/plugins/Gravatar/locale/eo/LC_MESSAGES/Gravatar.po b/plugins/Gravatar/locale/eo/LC_MESSAGES/Gravatar.po
deleted file mode 100644 (file)
index a955db7..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-# SOME DESCRIPTIVE TITLE.
-# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
-# This file is distributed under the same license as the PACKAGE package.
-# 
-# Translators:
-msgid ""
-msgstr ""
-"Project-Id-Version: GNU social\n"
-"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2015-02-02 17:47+0100\n"
-"PO-Revision-Date: 2015-02-06 16:27+0000\n"
-"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
-"Language-Team: Esperanto (http://www.transifex.com/projects/p/gnu-social/language/eo/)\n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
-"Content-Transfer-Encoding: 8bit\n"
-"Language: eo\n"
-"Plural-Forms: nplurals=2; plural=(n != 1);\n"
-
-#. TRANS: Plugin decsription.
-#: GravatarPlugin.php:70
-msgid ""
-"The Gravatar plugin allows users to use their <a "
-"href=\"http://www.gravatar.com/\">Gravatar</a> with StatusNet."
-msgstr ""
diff --git a/plugins/Gravatar/locale/es/LC_MESSAGES/Gravatar.po b/plugins/Gravatar/locale/es/LC_MESSAGES/Gravatar.po
deleted file mode 100644 (file)
index b289d4f..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-# SOME DESCRIPTIVE TITLE.
-# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
-# This file is distributed under the same license as the PACKAGE package.
-# 
-# Translators:
-# Juan Riquelme González <soulchainer@gmail.com>, 2015
-msgid ""
-msgstr ""
-"Project-Id-Version: GNU social\n"
-"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2015-02-02 17:47+0100\n"
-"PO-Revision-Date: 2015-02-27 12:21+0000\n"
-"Last-Translator: Juan Riquelme González <soulchainer@gmail.com>\n"
-"Language-Team: Spanish (http://www.transifex.com/projects/p/gnu-social/language/es/)\n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
-"Content-Transfer-Encoding: 8bit\n"
-"Language: es\n"
-"Plural-Forms: nplurals=2; plural=(n != 1);\n"
-
-#. TRANS: Plugin decsription.
-#: GravatarPlugin.php:70
-msgid ""
-"The Gravatar plugin allows users to use their <a "
-"href=\"http://www.gravatar.com/\">Gravatar</a> with StatusNet."
-msgstr "El complemento Gravatar permite a los usuarios utilizar su <a href=\"http://www.gravatar.com/\">Gravatar</a> en GNU social."
diff --git a/plugins/Gravatar/locale/eu/LC_MESSAGES/Gravatar.po b/plugins/Gravatar/locale/eu/LC_MESSAGES/Gravatar.po
deleted file mode 100644 (file)
index bb87408..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-# SOME DESCRIPTIVE TITLE.
-# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
-# This file is distributed under the same license as the PACKAGE package.
-# 
-# Translators:
-msgid ""
-msgstr ""
-"Project-Id-Version: GNU social\n"
-"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2015-02-02 17:47+0100\n"
-"PO-Revision-Date: 2015-02-06 16:43+0000\n"
-"Last-Translator: digitaldreamer <digitaldreamer@email.cz>\n"
-"Language-Team: Basque (http://www.transifex.com/projects/p/gnu-social/language/eu/)\n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
-"Content-Transfer-Encoding: 8bit\n"
-"Language: eu\n"
-"Plural-Forms: nplurals=2; plural=(n != 1);\n"
-
-#. TRANS: Plugin decsription.
-#: GravatarPlugin.php:70
-msgid ""
-"The Gravatar plugin allows users to use their <a "
-"href=\"http://www.gravatar.com/\">Gravatar</a> with StatusNet."
-msgstr "Gravatar pluginak erabiltzaileei heuren <a href=\"http://www.gravatar.com/\">Gravatar</a>ra StatusNet-en erabiltzen uzten die."
diff --git a/plugins/Gravatar/locale/fa/LC_MESSAGES/Gravatar.po b/plugins/Gravatar/locale/fa/LC_MESSAGES/Gravatar.po
deleted file mode 100644 (file)
index c7ee433..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-# SOME DESCRIPTIVE TITLE.
-# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
-# This file is distributed under the same license as the PACKAGE package.
-# 
-# Translators:
-msgid ""
-msgstr ""
-"Project-Id-Version: GNU social\n"
-"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2015-02-02 17:47+0100\n"
-"PO-Revision-Date: 2015-02-06 16:27+0000\n"
-"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
-"Language-Team: Persian (http://www.transifex.com/projects/p/gnu-social/language/fa/)\n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
-"Content-Transfer-Encoding: 8bit\n"
-"Language: fa\n"
-"Plural-Forms: nplurals=1; plural=0;\n"
-
-#. TRANS: Plugin decsription.
-#: GravatarPlugin.php:70
-msgid ""
-"The Gravatar plugin allows users to use their <a "
-"href=\"http://www.gravatar.com/\">Gravatar</a> with StatusNet."
-msgstr ""
diff --git a/plugins/Gravatar/locale/fi/LC_MESSAGES/Gravatar.po b/plugins/Gravatar/locale/fi/LC_MESSAGES/Gravatar.po
deleted file mode 100644 (file)
index 7b0e4e1..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-# SOME DESCRIPTIVE TITLE.
-# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
-# This file is distributed under the same license as the PACKAGE package.
-# 
-# Translators:
-msgid ""
-msgstr ""
-"Project-Id-Version: GNU social\n"
-"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2015-02-02 17:47+0100\n"
-"PO-Revision-Date: 2015-02-06 16:27+0000\n"
-"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
-"Language-Team: Finnish (http://www.transifex.com/projects/p/gnu-social/language/fi/)\n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
-"Content-Transfer-Encoding: 8bit\n"
-"Language: fi\n"
-"Plural-Forms: nplurals=2; plural=(n != 1);\n"
-
-#. TRANS: Plugin decsription.
-#: GravatarPlugin.php:70
-msgid ""
-"The Gravatar plugin allows users to use their <a "
-"href=\"http://www.gravatar.com/\">Gravatar</a> with StatusNet."
-msgstr ""
diff --git a/plugins/Gravatar/locale/fr/LC_MESSAGES/Gravatar.po b/plugins/Gravatar/locale/fr/LC_MESSAGES/Gravatar.po
deleted file mode 100644 (file)
index c24e581..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-# SOME DESCRIPTIVE TITLE.
-# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
-# This file is distributed under the same license as the PACKAGE package.
-# 
-# Translators:
-msgid ""
-msgstr ""
-"Project-Id-Version: GNU social\n"
-"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2015-02-02 17:47+0100\n"
-"PO-Revision-Date: 2015-02-06 16:43+0000\n"
-"Last-Translator: digitaldreamer <digitaldreamer@email.cz>\n"
-"Language-Team: French (http://www.transifex.com/projects/p/gnu-social/language/fr/)\n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
-"Content-Transfer-Encoding: 8bit\n"
-"Language: fr\n"
-"Plural-Forms: nplurals=2; plural=(n > 1);\n"
-
-#. TRANS: Plugin decsription.
-#: GravatarPlugin.php:70
-msgid ""
-"The Gravatar plugin allows users to use their <a "
-"href=\"http://www.gravatar.com/\">Gravatar</a> with StatusNet."
-msgstr "Le greffon Gravatar permet aux utilisateurs d’utiliser leur image <a href=\"http://www.gravatar.com/\">Gravatar</a> avec StatusNet."
diff --git a/plugins/Gravatar/locale/fur/LC_MESSAGES/Gravatar.po b/plugins/Gravatar/locale/fur/LC_MESSAGES/Gravatar.po
deleted file mode 100644 (file)
index 3cd3fdf..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-# SOME DESCRIPTIVE TITLE.
-# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
-# This file is distributed under the same license as the PACKAGE package.
-# 
-# Translators:
-msgid ""
-msgstr ""
-"Project-Id-Version: GNU social\n"
-"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2015-02-02 17:47+0100\n"
-"PO-Revision-Date: 2015-02-06 16:27+0000\n"
-"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
-"Language-Team: Friulian (http://www.transifex.com/projects/p/gnu-social/language/fur/)\n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
-"Content-Transfer-Encoding: 8bit\n"
-"Language: fur\n"
-"Plural-Forms: nplurals=2; plural=(n != 1);\n"
-
-#. TRANS: Plugin decsription.
-#: GravatarPlugin.php:70
-msgid ""
-"The Gravatar plugin allows users to use their <a "
-"href=\"http://www.gravatar.com/\">Gravatar</a> with StatusNet."
-msgstr ""
diff --git a/plugins/Gravatar/locale/gl/LC_MESSAGES/Gravatar.po b/plugins/Gravatar/locale/gl/LC_MESSAGES/Gravatar.po
deleted file mode 100644 (file)
index 629918e..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-# SOME DESCRIPTIVE TITLE.
-# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
-# This file is distributed under the same license as the PACKAGE package.
-# 
-# Translators:
-msgid ""
-msgstr ""
-"Project-Id-Version: GNU social\n"
-"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2015-02-02 17:47+0100\n"
-"PO-Revision-Date: 2015-02-06 16:43+0000\n"
-"Last-Translator: digitaldreamer <digitaldreamer@email.cz>\n"
-"Language-Team: Galician (http://www.transifex.com/projects/p/gnu-social/language/gl/)\n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
-"Content-Transfer-Encoding: 8bit\n"
-"Language: gl\n"
-"Plural-Forms: nplurals=2; plural=(n != 1);\n"
-
-#. TRANS: Plugin decsription.
-#: GravatarPlugin.php:70
-msgid ""
-"The Gravatar plugin allows users to use their <a "
-"href=\"http://www.gravatar.com/\">Gravatar</a> with StatusNet."
-msgstr "O complemento Gravatar permite aos usuarios usar o seu <a href=\"http://www.gravatar.com/\">Gravatar</a> co StatusNet."
diff --git a/plugins/Gravatar/locale/he/LC_MESSAGES/Gravatar.po b/plugins/Gravatar/locale/he/LC_MESSAGES/Gravatar.po
deleted file mode 100644 (file)
index 475f35c..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-# SOME DESCRIPTIVE TITLE.
-# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
-# This file is distributed under the same license as the PACKAGE package.
-# 
-# Translators:
-msgid ""
-msgstr ""
-"Project-Id-Version: GNU social\n"
-"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2015-02-02 17:47+0100\n"
-"PO-Revision-Date: 2015-02-06 16:43+0000\n"
-"Last-Translator: digitaldreamer <digitaldreamer@email.cz>\n"
-"Language-Team: Hebrew (http://www.transifex.com/projects/p/gnu-social/language/he/)\n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
-"Content-Transfer-Encoding: 8bit\n"
-"Language: he\n"
-"Plural-Forms: nplurals=2; plural=(n != 1);\n"
-
-#. TRANS: Plugin decsription.
-#: GravatarPlugin.php:70
-msgid ""
-"The Gravatar plugin allows users to use their <a "
-"href=\"http://www.gravatar.com/\">Gravatar</a> with StatusNet."
-msgstr "תוסף Gravatar מאפשר למשתמשים להציג את ה־<a href=\"http://www.gravatar.com/\">Gravatar</a> שלהם בסטטוסנט."
diff --git a/plugins/Gravatar/locale/hsb/LC_MESSAGES/Gravatar.po b/plugins/Gravatar/locale/hsb/LC_MESSAGES/Gravatar.po
deleted file mode 100644 (file)
index 63410e7..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-# SOME DESCRIPTIVE TITLE.
-# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
-# This file is distributed under the same license as the PACKAGE package.
-# 
-# Translators:
-msgid ""
-msgstr ""
-"Project-Id-Version: GNU social\n"
-"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2015-02-02 17:47+0100\n"
-"PO-Revision-Date: 2015-02-06 16:27+0000\n"
-"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
-"Language-Team: Upper Sorbian (http://www.transifex.com/projects/p/gnu-social/language/hsb/)\n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
-"Content-Transfer-Encoding: 8bit\n"
-"Language: hsb\n"
-"Plural-Forms: nplurals=4; plural=(n%100==1 ? 0 : n%100==2 ? 1 : n%100==3 || n%100==4 ? 2 : 3);\n"
-
-#. TRANS: Plugin decsription.
-#: GravatarPlugin.php:70
-msgid ""
-"The Gravatar plugin allows users to use their <a "
-"href=\"http://www.gravatar.com/\">Gravatar</a> with StatusNet."
-msgstr ""
diff --git a/plugins/Gravatar/locale/hu/LC_MESSAGES/Gravatar.po b/plugins/Gravatar/locale/hu/LC_MESSAGES/Gravatar.po
deleted file mode 100644 (file)
index 16c5f1b..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-# SOME DESCRIPTIVE TITLE.
-# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
-# This file is distributed under the same license as the PACKAGE package.
-# 
-# Translators:
-msgid ""
-msgstr ""
-"Project-Id-Version: GNU social\n"
-"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2015-02-02 17:47+0100\n"
-"PO-Revision-Date: 2015-02-06 16:27+0000\n"
-"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
-"Language-Team: Hungarian (http://www.transifex.com/projects/p/gnu-social/language/hu/)\n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
-"Content-Transfer-Encoding: 8bit\n"
-"Language: hu\n"
-"Plural-Forms: nplurals=2; plural=(n != 1);\n"
-
-#. TRANS: Plugin decsription.
-#: GravatarPlugin.php:70
-msgid ""
-"The Gravatar plugin allows users to use their <a "
-"href=\"http://www.gravatar.com/\">Gravatar</a> with StatusNet."
-msgstr ""
diff --git a/plugins/Gravatar/locale/ia/LC_MESSAGES/Gravatar.po b/plugins/Gravatar/locale/ia/LC_MESSAGES/Gravatar.po
deleted file mode 100644 (file)
index 63ffdb9..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-# SOME DESCRIPTIVE TITLE.
-# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
-# This file is distributed under the same license as the PACKAGE package.
-# 
-# Translators:
-msgid ""
-msgstr ""
-"Project-Id-Version: GNU social\n"
-"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2015-02-02 17:47+0100\n"
-"PO-Revision-Date: 2015-02-06 16:43+0000\n"
-"Last-Translator: digitaldreamer <digitaldreamer@email.cz>\n"
-"Language-Team: Interlingua (http://www.transifex.com/projects/p/gnu-social/language/ia/)\n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
-"Content-Transfer-Encoding: 8bit\n"
-"Language: ia\n"
-"Plural-Forms: nplurals=2; plural=(n != 1);\n"
-
-#. TRANS: Plugin decsription.
-#: GravatarPlugin.php:70
-msgid ""
-"The Gravatar plugin allows users to use their <a "
-"href=\"http://www.gravatar.com/\">Gravatar</a> with StatusNet."
-msgstr "Le plug-in Gravatar permitte al usatores de usar lor <a href=\"http://www.gravatar.com/\">Gravatar</a> con StatusNet."
diff --git a/plugins/Gravatar/locale/id/LC_MESSAGES/Gravatar.po b/plugins/Gravatar/locale/id/LC_MESSAGES/Gravatar.po
deleted file mode 100644 (file)
index 3c2b453..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-# SOME DESCRIPTIVE TITLE.
-# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
-# This file is distributed under the same license as the PACKAGE package.
-# 
-# Translators:
-msgid ""
-msgstr ""
-"Project-Id-Version: GNU social\n"
-"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2015-02-02 17:47+0100\n"
-"PO-Revision-Date: 2015-02-06 16:27+0000\n"
-"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
-"Language-Team: Indonesian (http://www.transifex.com/projects/p/gnu-social/language/id/)\n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
-"Content-Transfer-Encoding: 8bit\n"
-"Language: id\n"
-"Plural-Forms: nplurals=1; plural=0;\n"
-
-#. TRANS: Plugin decsription.
-#: GravatarPlugin.php:70
-msgid ""
-"The Gravatar plugin allows users to use their <a "
-"href=\"http://www.gravatar.com/\">Gravatar</a> with StatusNet."
-msgstr ""
diff --git a/plugins/Gravatar/locale/is/LC_MESSAGES/Gravatar.po b/plugins/Gravatar/locale/is/LC_MESSAGES/Gravatar.po
deleted file mode 100644 (file)
index 3da39d3..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-# SOME DESCRIPTIVE TITLE.
-# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
-# This file is distributed under the same license as the PACKAGE package.
-# 
-# Translators:
-msgid ""
-msgstr ""
-"Project-Id-Version: GNU social\n"
-"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2015-02-02 17:47+0100\n"
-"PO-Revision-Date: 2015-02-06 16:27+0000\n"
-"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
-"Language-Team: Icelandic (http://www.transifex.com/projects/p/gnu-social/language/is/)\n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
-"Content-Transfer-Encoding: 8bit\n"
-"Language: is\n"
-"Plural-Forms: nplurals=2; plural=(n != 1);\n"
-
-#. TRANS: Plugin decsription.
-#: GravatarPlugin.php:70
-msgid ""
-"The Gravatar plugin allows users to use their <a "
-"href=\"http://www.gravatar.com/\">Gravatar</a> with StatusNet."
-msgstr ""
diff --git a/plugins/Gravatar/locale/it/LC_MESSAGES/Gravatar.po b/plugins/Gravatar/locale/it/LC_MESSAGES/Gravatar.po
deleted file mode 100644 (file)
index 5793afc..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-# SOME DESCRIPTIVE TITLE.
-# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
-# This file is distributed under the same license as the PACKAGE package.
-# 
-# Translators:
-msgid ""
-msgstr ""
-"Project-Id-Version: GNU social\n"
-"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2015-02-02 17:47+0100\n"
-"PO-Revision-Date: 2015-02-06 16:43+0000\n"
-"Last-Translator: digitaldreamer <digitaldreamer@email.cz>\n"
-"Language-Team: Italian (http://www.transifex.com/projects/p/gnu-social/language/it/)\n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
-"Content-Transfer-Encoding: 8bit\n"
-"Language: it\n"
-"Plural-Forms: nplurals=2; plural=(n != 1);\n"
-
-#. TRANS: Plugin decsription.
-#: GravatarPlugin.php:70
-msgid ""
-"The Gravatar plugin allows users to use their <a "
-"href=\"http://www.gravatar.com/\">Gravatar</a> with StatusNet."
-msgstr "Il plugin Gravatar consente agli utenti di utilizzare i loro <a href=\"http://www.gravatar.com/\">Gravatar</a> con StatusNet."
diff --git a/plugins/Gravatar/locale/ja/LC_MESSAGES/Gravatar.po b/plugins/Gravatar/locale/ja/LC_MESSAGES/Gravatar.po
deleted file mode 100644 (file)
index 53263e5..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-# SOME DESCRIPTIVE TITLE.
-# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
-# This file is distributed under the same license as the PACKAGE package.
-# 
-# Translators:
-msgid ""
-msgstr ""
-"Project-Id-Version: GNU social\n"
-"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2015-02-02 17:47+0100\n"
-"PO-Revision-Date: 2015-02-06 16:27+0000\n"
-"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
-"Language-Team: Japanese (http://www.transifex.com/projects/p/gnu-social/language/ja/)\n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
-"Content-Transfer-Encoding: 8bit\n"
-"Language: ja\n"
-"Plural-Forms: nplurals=1; plural=0;\n"
-
-#. TRANS: Plugin decsription.
-#: GravatarPlugin.php:70
-msgid ""
-"The Gravatar plugin allows users to use their <a "
-"href=\"http://www.gravatar.com/\">Gravatar</a> with StatusNet."
-msgstr ""
diff --git a/plugins/Gravatar/locale/ka/LC_MESSAGES/Gravatar.po b/plugins/Gravatar/locale/ka/LC_MESSAGES/Gravatar.po
deleted file mode 100644 (file)
index 1951146..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-# SOME DESCRIPTIVE TITLE.
-# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
-# This file is distributed under the same license as the PACKAGE package.
-# 
-# Translators:
-msgid ""
-msgstr ""
-"Project-Id-Version: GNU social\n"
-"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2015-02-02 17:47+0100\n"
-"PO-Revision-Date: 2015-02-06 16:27+0000\n"
-"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
-"Language-Team: Georgian (http://www.transifex.com/projects/p/gnu-social/language/ka/)\n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
-"Content-Transfer-Encoding: 8bit\n"
-"Language: ka\n"
-"Plural-Forms: nplurals=1; plural=0;\n"
-
-#. TRANS: Plugin decsription.
-#: GravatarPlugin.php:70
-msgid ""
-"The Gravatar plugin allows users to use their <a "
-"href=\"http://www.gravatar.com/\">Gravatar</a> with StatusNet."
-msgstr ""
diff --git a/plugins/Gravatar/locale/ko/LC_MESSAGES/Gravatar.po b/plugins/Gravatar/locale/ko/LC_MESSAGES/Gravatar.po
deleted file mode 100644 (file)
index cde819b..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-# SOME DESCRIPTIVE TITLE.
-# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
-# This file is distributed under the same license as the PACKAGE package.
-# 
-# Translators:
-msgid ""
-msgstr ""
-"Project-Id-Version: GNU social\n"
-"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2015-02-02 17:47+0100\n"
-"PO-Revision-Date: 2015-02-06 16:27+0000\n"
-"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
-"Language-Team: Korean (http://www.transifex.com/projects/p/gnu-social/language/ko/)\n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
-"Content-Transfer-Encoding: 8bit\n"
-"Language: ko\n"
-"Plural-Forms: nplurals=1; plural=0;\n"
-
-#. TRANS: Plugin decsription.
-#: GravatarPlugin.php:70
-msgid ""
-"The Gravatar plugin allows users to use their <a "
-"href=\"http://www.gravatar.com/\">Gravatar</a> with StatusNet."
-msgstr ""
diff --git a/plugins/Gravatar/locale/ksh/LC_MESSAGES/Gravatar.po b/plugins/Gravatar/locale/ksh/LC_MESSAGES/Gravatar.po
deleted file mode 100644 (file)
index 2212303..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-# SOME DESCRIPTIVE TITLE.
-# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
-# This file is distributed under the same license as the PACKAGE package.
-# 
-# Translators:
-msgid ""
-msgstr ""
-"Project-Id-Version: GNU social\n"
-"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2015-02-02 17:47+0100\n"
-"PO-Revision-Date: 2015-02-06 16:27+0000\n"
-"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
-"Language-Team: Colognian (http://www.transifex.com/projects/p/gnu-social/language/ksh/)\n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
-"Content-Transfer-Encoding: 8bit\n"
-"Language: ksh\n"
-"Plural-Forms: nplurals=3; plural=(n==0) ? 0 : (n==1) ? 1 : 2;\n"
-
-#. TRANS: Plugin decsription.
-#: GravatarPlugin.php:70
-msgid ""
-"The Gravatar plugin allows users to use their <a "
-"href=\"http://www.gravatar.com/\">Gravatar</a> with StatusNet."
-msgstr ""
diff --git a/plugins/Gravatar/locale/lb/LC_MESSAGES/Gravatar.po b/plugins/Gravatar/locale/lb/LC_MESSAGES/Gravatar.po
deleted file mode 100644 (file)
index dd0a27f..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-# SOME DESCRIPTIVE TITLE.
-# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
-# This file is distributed under the same license as the PACKAGE package.
-# 
-# Translators:
-msgid ""
-msgstr ""
-"Project-Id-Version: GNU social\n"
-"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2015-02-02 17:47+0100\n"
-"PO-Revision-Date: 2015-02-06 16:27+0000\n"
-"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
-"Language-Team: Luxembourgish (http://www.transifex.com/projects/p/gnu-social/language/lb/)\n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
-"Content-Transfer-Encoding: 8bit\n"
-"Language: lb\n"
-"Plural-Forms: nplurals=2; plural=(n != 1);\n"
-
-#. TRANS: Plugin decsription.
-#: GravatarPlugin.php:70
-msgid ""
-"The Gravatar plugin allows users to use their <a "
-"href=\"http://www.gravatar.com/\">Gravatar</a> with StatusNet."
-msgstr ""
diff --git a/plugins/Gravatar/locale/lt/LC_MESSAGES/Gravatar.po b/plugins/Gravatar/locale/lt/LC_MESSAGES/Gravatar.po
deleted file mode 100644 (file)
index be4f887..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-# SOME DESCRIPTIVE TITLE.
-# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
-# This file is distributed under the same license as the PACKAGE package.
-# 
-# Translators:
-msgid ""
-msgstr ""
-"Project-Id-Version: GNU social\n"
-"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2015-02-02 17:47+0100\n"
-"PO-Revision-Date: 2015-02-06 16:27+0000\n"
-"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
-"Language-Team: Lithuanian (http://www.transifex.com/projects/p/gnu-social/language/lt/)\n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
-"Content-Transfer-Encoding: 8bit\n"
-"Language: lt\n"
-"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && (n%100<10 || n%100>=20) ? 1 : 2);\n"
-
-#. TRANS: Plugin decsription.
-#: GravatarPlugin.php:70
-msgid ""
-"The Gravatar plugin allows users to use their <a "
-"href=\"http://www.gravatar.com/\">Gravatar</a> with StatusNet."
-msgstr ""
diff --git a/plugins/Gravatar/locale/lv/LC_MESSAGES/Gravatar.po b/plugins/Gravatar/locale/lv/LC_MESSAGES/Gravatar.po
deleted file mode 100644 (file)
index 370e8f7..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-# SOME DESCRIPTIVE TITLE.
-# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
-# This file is distributed under the same license as the PACKAGE package.
-# 
-# Translators:
-msgid ""
-msgstr ""
-"Project-Id-Version: GNU social\n"
-"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2015-02-02 17:47+0100\n"
-"PO-Revision-Date: 2015-02-07 09:39+0000\n"
-"Last-Translator: digitaldreamer <digitaldreamer@email.cz>\n"
-"Language-Team: Latvian (http://www.transifex.com/projects/p/gnu-social/language/lv/)\n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
-"Content-Transfer-Encoding: 8bit\n"
-"Language: lv\n"
-"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n != 0 ? 1 : 2);\n"
-
-#. TRANS: Plugin decsription.
-#: GravatarPlugin.php:70
-msgid ""
-"The Gravatar plugin allows users to use their <a "
-"href=\"http://www.gravatar.com/\">Gravatar</a> with StatusNet."
-msgstr ""
diff --git a/plugins/Gravatar/locale/mg/LC_MESSAGES/Gravatar.po b/plugins/Gravatar/locale/mg/LC_MESSAGES/Gravatar.po
deleted file mode 100644 (file)
index 1f3889e..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-# SOME DESCRIPTIVE TITLE.
-# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
-# This file is distributed under the same license as the PACKAGE package.
-# 
-# Translators:
-msgid ""
-msgstr ""
-"Project-Id-Version: GNU social\n"
-"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2015-02-02 17:47+0100\n"
-"PO-Revision-Date: 2015-02-06 16:27+0000\n"
-"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
-"Language-Team: Malagasy (http://www.transifex.com/projects/p/gnu-social/language/mg/)\n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
-"Content-Transfer-Encoding: 8bit\n"
-"Language: mg\n"
-"Plural-Forms: nplurals=2; plural=(n > 1);\n"
-
-#. TRANS: Plugin decsription.
-#: GravatarPlugin.php:70
-msgid ""
-"The Gravatar plugin allows users to use their <a "
-"href=\"http://www.gravatar.com/\">Gravatar</a> with StatusNet."
-msgstr ""
diff --git a/plugins/Gravatar/locale/mk/LC_MESSAGES/Gravatar.po b/plugins/Gravatar/locale/mk/LC_MESSAGES/Gravatar.po
deleted file mode 100644 (file)
index 14015f3..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-# SOME DESCRIPTIVE TITLE.
-# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
-# This file is distributed under the same license as the PACKAGE package.
-# 
-# Translators:
-msgid ""
-msgstr ""
-"Project-Id-Version: GNU social\n"
-"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2015-02-02 17:47+0100\n"
-"PO-Revision-Date: 2015-02-06 16:43+0000\n"
-"Last-Translator: digitaldreamer <digitaldreamer@email.cz>\n"
-"Language-Team: Macedonian (http://www.transifex.com/projects/p/gnu-social/language/mk/)\n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
-"Content-Transfer-Encoding: 8bit\n"
-"Language: mk\n"
-"Plural-Forms: nplurals=2; plural=(n % 10 == 1 && n % 100 != 11) ? 0 : 1;\n"
-
-#. TRANS: Plugin decsription.
-#: GravatarPlugin.php:70
-msgid ""
-"The Gravatar plugin allows users to use their <a "
-"href=\"http://www.gravatar.com/\">Gravatar</a> with StatusNet."
-msgstr "Приклучокот Gravatar им овозможува на корисниците да го користат својот <a href=\"http://www.gravatar.com/\">Gravatar</a> со StatusNet."
diff --git a/plugins/Gravatar/locale/ml/LC_MESSAGES/Gravatar.po b/plugins/Gravatar/locale/ml/LC_MESSAGES/Gravatar.po
deleted file mode 100644 (file)
index 71920fd..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-# SOME DESCRIPTIVE TITLE.
-# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
-# This file is distributed under the same license as the PACKAGE package.
-# 
-# Translators:
-msgid ""
-msgstr ""
-"Project-Id-Version: GNU social\n"
-"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2015-02-02 17:47+0100\n"
-"PO-Revision-Date: 2015-02-06 16:27+0000\n"
-"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
-"Language-Team: Malayalam (http://www.transifex.com/projects/p/gnu-social/language/ml/)\n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
-"Content-Transfer-Encoding: 8bit\n"
-"Language: ml\n"
-"Plural-Forms: nplurals=2; plural=(n != 1);\n"
-
-#. TRANS: Plugin decsription.
-#: GravatarPlugin.php:70
-msgid ""
-"The Gravatar plugin allows users to use their <a "
-"href=\"http://www.gravatar.com/\">Gravatar</a> with StatusNet."
-msgstr ""
diff --git a/plugins/Gravatar/locale/ms/LC_MESSAGES/Gravatar.po b/plugins/Gravatar/locale/ms/LC_MESSAGES/Gravatar.po
deleted file mode 100644 (file)
index 2bcaa63..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-# SOME DESCRIPTIVE TITLE.
-# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
-# This file is distributed under the same license as the PACKAGE package.
-# 
-# Translators:
-msgid ""
-msgstr ""
-"Project-Id-Version: GNU social\n"
-"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2015-02-02 17:47+0100\n"
-"PO-Revision-Date: 2015-02-06 16:27+0000\n"
-"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
-"Language-Team: Malay (http://www.transifex.com/projects/p/gnu-social/language/ms/)\n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
-"Content-Transfer-Encoding: 8bit\n"
-"Language: ms\n"
-"Plural-Forms: nplurals=1; plural=0;\n"
-
-#. TRANS: Plugin decsription.
-#: GravatarPlugin.php:70
-msgid ""
-"The Gravatar plugin allows users to use their <a "
-"href=\"http://www.gravatar.com/\">Gravatar</a> with StatusNet."
-msgstr ""
diff --git a/plugins/Gravatar/locale/my/LC_MESSAGES/Gravatar.po b/plugins/Gravatar/locale/my/LC_MESSAGES/Gravatar.po
deleted file mode 100644 (file)
index 2bd1d77..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-# SOME DESCRIPTIVE TITLE.
-# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
-# This file is distributed under the same license as the PACKAGE package.
-# 
-# Translators:
-msgid ""
-msgstr ""
-"Project-Id-Version: GNU social\n"
-"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2015-02-02 17:47+0100\n"
-"PO-Revision-Date: 2015-02-06 16:27+0000\n"
-"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
-"Language-Team: Burmese (http://www.transifex.com/projects/p/gnu-social/language/my/)\n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
-"Content-Transfer-Encoding: 8bit\n"
-"Language: my\n"
-"Plural-Forms: nplurals=1; plural=0;\n"
-
-#. TRANS: Plugin decsription.
-#: GravatarPlugin.php:70
-msgid ""
-"The Gravatar plugin allows users to use their <a "
-"href=\"http://www.gravatar.com/\">Gravatar</a> with StatusNet."
-msgstr ""
diff --git a/plugins/Gravatar/locale/nb/LC_MESSAGES/Gravatar.po b/plugins/Gravatar/locale/nb/LC_MESSAGES/Gravatar.po
deleted file mode 100644 (file)
index 5bfca90..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-# SOME DESCRIPTIVE TITLE.
-# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
-# This file is distributed under the same license as the PACKAGE package.
-# 
-# Translators:
-msgid ""
-msgstr ""
-"Project-Id-Version: GNU social\n"
-"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2015-02-02 17:47+0100\n"
-"PO-Revision-Date: 2015-02-06 16:27+0000\n"
-"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
-"Language-Team: Norwegian Bokmål (http://www.transifex.com/projects/p/gnu-social/language/nb/)\n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
-"Content-Transfer-Encoding: 8bit\n"
-"Language: nb\n"
-"Plural-Forms: nplurals=2; plural=(n != 1);\n"
-
-#. TRANS: Plugin decsription.
-#: GravatarPlugin.php:70
-msgid ""
-"The Gravatar plugin allows users to use their <a "
-"href=\"http://www.gravatar.com/\">Gravatar</a> with StatusNet."
-msgstr ""
diff --git a/plugins/Gravatar/locale/ne/LC_MESSAGES/Gravatar.po b/plugins/Gravatar/locale/ne/LC_MESSAGES/Gravatar.po
deleted file mode 100644 (file)
index 0a8a3f5..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-# SOME DESCRIPTIVE TITLE.
-# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
-# This file is distributed under the same license as the PACKAGE package.
-# 
-# Translators:
-msgid ""
-msgstr ""
-"Project-Id-Version: GNU social\n"
-"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2015-02-02 17:47+0100\n"
-"PO-Revision-Date: 2015-02-07 09:30+0000\n"
-"Last-Translator: digitaldreamer <digitaldreamer@email.cz>\n"
-"Language-Team: Nepali (http://www.transifex.com/projects/p/gnu-social/language/ne/)\n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
-"Content-Transfer-Encoding: 8bit\n"
-"Language: ne\n"
-"Plural-Forms: nplurals=2; plural=(n != 1);\n"
-
-#. TRANS: Plugin decsription.
-#: GravatarPlugin.php:70
-msgid ""
-"The Gravatar plugin allows users to use their <a "
-"href=\"http://www.gravatar.com/\">Gravatar</a> with StatusNet."
-msgstr ""
diff --git a/plugins/Gravatar/locale/nl/LC_MESSAGES/Gravatar.po b/plugins/Gravatar/locale/nl/LC_MESSAGES/Gravatar.po
deleted file mode 100644 (file)
index 39339a3..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-# SOME DESCRIPTIVE TITLE.
-# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
-# This file is distributed under the same license as the PACKAGE package.
-# 
-# Translators:
-msgid ""
-msgstr ""
-"Project-Id-Version: GNU social\n"
-"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2015-02-02 17:47+0100\n"
-"PO-Revision-Date: 2015-02-06 16:43+0000\n"
-"Last-Translator: digitaldreamer <digitaldreamer@email.cz>\n"
-"Language-Team: Dutch (http://www.transifex.com/projects/p/gnu-social/language/nl/)\n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
-"Content-Transfer-Encoding: 8bit\n"
-"Language: nl\n"
-"Plural-Forms: nplurals=2; plural=(n != 1);\n"
-
-#. TRANS: Plugin decsription.
-#: GravatarPlugin.php:70
-msgid ""
-"The Gravatar plugin allows users to use their <a "
-"href=\"http://www.gravatar.com/\">Gravatar</a> with StatusNet."
-msgstr "De plug-in Gravatar maak het mogelijk dat gebruikers hun <a href=\"http://www.gravatar.com/\">Gravatar</a> gebruiken in StatusNet."
diff --git a/plugins/Gravatar/locale/nn/LC_MESSAGES/Gravatar.po b/plugins/Gravatar/locale/nn/LC_MESSAGES/Gravatar.po
deleted file mode 100644 (file)
index 6c7a1ec..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-# SOME DESCRIPTIVE TITLE.
-# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
-# This file is distributed under the same license as the PACKAGE package.
-# 
-# Translators:
-msgid ""
-msgstr ""
-"Project-Id-Version: GNU social\n"
-"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2015-02-02 17:47+0100\n"
-"PO-Revision-Date: 2015-02-06 16:27+0000\n"
-"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
-"Language-Team: Norwegian Nynorsk (http://www.transifex.com/projects/p/gnu-social/language/nn/)\n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
-"Content-Transfer-Encoding: 8bit\n"
-"Language: nn\n"
-"Plural-Forms: nplurals=2; plural=(n != 1);\n"
-
-#. TRANS: Plugin decsription.
-#: GravatarPlugin.php:70
-msgid ""
-"The Gravatar plugin allows users to use their <a "
-"href=\"http://www.gravatar.com/\">Gravatar</a> with StatusNet."
-msgstr ""
diff --git a/plugins/Gravatar/locale/pl/LC_MESSAGES/Gravatar.po b/plugins/Gravatar/locale/pl/LC_MESSAGES/Gravatar.po
deleted file mode 100644 (file)
index 4bf9e1a..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-# SOME DESCRIPTIVE TITLE.
-# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
-# This file is distributed under the same license as the PACKAGE package.
-# 
-# Translators:
-msgid ""
-msgstr ""
-"Project-Id-Version: GNU social\n"
-"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2015-02-02 17:47+0100\n"
-"PO-Revision-Date: 2015-02-06 16:43+0000\n"
-"Last-Translator: digitaldreamer <digitaldreamer@email.cz>\n"
-"Language-Team: Polish (http://www.transifex.com/projects/p/gnu-social/language/pl/)\n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
-"Content-Transfer-Encoding: 8bit\n"
-"Language: pl\n"
-"Plural-Forms: nplurals=3; plural=(n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n"
-
-#. TRANS: Plugin decsription.
-#: GravatarPlugin.php:70
-msgid ""
-"The Gravatar plugin allows users to use their <a "
-"href=\"http://www.gravatar.com/\">Gravatar</a> with StatusNet."
-msgstr "Wtyczka Gravatar umożliwia użytkownikom używanie obrazów <a href=\"http://www.gravatar.com/\">Gravatar</a> w StatusNet."
diff --git a/plugins/Gravatar/locale/pt/LC_MESSAGES/Gravatar.po b/plugins/Gravatar/locale/pt/LC_MESSAGES/Gravatar.po
deleted file mode 100644 (file)
index 50b36f6..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-# SOME DESCRIPTIVE TITLE.
-# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
-# This file is distributed under the same license as the PACKAGE package.
-# 
-# Translators:
-msgid ""
-msgstr ""
-"Project-Id-Version: GNU social\n"
-"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2015-02-02 17:47+0100\n"
-"PO-Revision-Date: 2015-02-06 16:43+0000\n"
-"Last-Translator: digitaldreamer <digitaldreamer@email.cz>\n"
-"Language-Team: Portuguese (http://www.transifex.com/projects/p/gnu-social/language/pt/)\n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
-"Content-Transfer-Encoding: 8bit\n"
-"Language: pt\n"
-"Plural-Forms: nplurals=2; plural=(n != 1);\n"
-
-#. TRANS: Plugin decsription.
-#: GravatarPlugin.php:70
-msgid ""
-"The Gravatar plugin allows users to use their <a "
-"href=\"http://www.gravatar.com/\">Gravatar</a> with StatusNet."
-msgstr "O plugin Gravatar permite que os utilizadores usem o seu <a href=\"http://www.gravatar.com/\">Gravatar</a> com o StatusNet."
diff --git a/plugins/Gravatar/locale/pt_BR/LC_MESSAGES/Gravatar.po b/plugins/Gravatar/locale/pt_BR/LC_MESSAGES/Gravatar.po
deleted file mode 100644 (file)
index 3bd93e4..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-# SOME DESCRIPTIVE TITLE.
-# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
-# This file is distributed under the same license as the PACKAGE package.
-# 
-# Translators:
-msgid ""
-msgstr ""
-"Project-Id-Version: GNU social\n"
-"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2015-02-02 17:47+0100\n"
-"PO-Revision-Date: 2015-02-06 16:27+0000\n"
-"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
-"Language-Team: Portuguese (Brazil) (http://www.transifex.com/projects/p/gnu-social/language/pt_BR/)\n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
-"Content-Transfer-Encoding: 8bit\n"
-"Language: pt_BR\n"
-"Plural-Forms: nplurals=2; plural=(n > 1);\n"
-
-#. TRANS: Plugin decsription.
-#: GravatarPlugin.php:70
-msgid ""
-"The Gravatar plugin allows users to use their <a "
-"href=\"http://www.gravatar.com/\">Gravatar</a> with StatusNet."
-msgstr ""
diff --git a/plugins/Gravatar/locale/ru/LC_MESSAGES/Gravatar.po b/plugins/Gravatar/locale/ru/LC_MESSAGES/Gravatar.po
deleted file mode 100644 (file)
index 1f304ef..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-# SOME DESCRIPTIVE TITLE.
-# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
-# This file is distributed under the same license as the PACKAGE package.
-# 
-# Translators:
-msgid ""
-msgstr ""
-"Project-Id-Version: GNU social\n"
-"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2015-02-02 17:47+0100\n"
-"PO-Revision-Date: 2015-02-06 16:27+0000\n"
-"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
-"Language-Team: Russian (http://www.transifex.com/projects/p/gnu-social/language/ru/)\n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
-"Content-Transfer-Encoding: 8bit\n"
-"Language: ru\n"
-"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n"
-
-#. TRANS: Plugin decsription.
-#: GravatarPlugin.php:70
-msgid ""
-"The Gravatar plugin allows users to use their <a "
-"href=\"http://www.gravatar.com/\">Gravatar</a> with StatusNet."
-msgstr ""
diff --git a/plugins/Gravatar/locale/sr-ec/LC_MESSAGES/Gravatar.po b/plugins/Gravatar/locale/sr-ec/LC_MESSAGES/Gravatar.po
deleted file mode 100644 (file)
index 32a78b6..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-# SOME DESCRIPTIVE TITLE.
-# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
-# This file is distributed under the same license as the PACKAGE package.
-# 
-# Translators:
-msgid ""
-msgstr ""
-"Project-Id-Version: GNU social\n"
-"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2015-02-02 17:47+0100\n"
-"PO-Revision-Date: 2015-02-06 16:27+0000\n"
-"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
-"Language-Team: Serbian (http://www.transifex.com/projects/p/gnu-social/language/sr/)\n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
-"Content-Transfer-Encoding: 8bit\n"
-"Language: sr\n"
-"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n"
-
-#. TRANS: Plugin decsription.
-#: GravatarPlugin.php:70
-msgid ""
-"The Gravatar plugin allows users to use their <a "
-"href=\"http://www.gravatar.com/\">Gravatar</a> with StatusNet."
-msgstr ""
diff --git a/plugins/Gravatar/locale/sv/LC_MESSAGES/Gravatar.po b/plugins/Gravatar/locale/sv/LC_MESSAGES/Gravatar.po
deleted file mode 100644 (file)
index a3f459f..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-# SOME DESCRIPTIVE TITLE.
-# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
-# This file is distributed under the same license as the PACKAGE package.
-# 
-# Translators:
-msgid ""
-msgstr ""
-"Project-Id-Version: GNU social\n"
-"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2015-02-02 17:47+0100\n"
-"PO-Revision-Date: 2015-02-06 16:43+0000\n"
-"Last-Translator: digitaldreamer <digitaldreamer@email.cz>\n"
-"Language-Team: Swedish (http://www.transifex.com/projects/p/gnu-social/language/sv/)\n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
-"Content-Transfer-Encoding: 8bit\n"
-"Language: sv\n"
-"Plural-Forms: nplurals=2; plural=(n != 1);\n"
-
-#. TRANS: Plugin decsription.
-#: GravatarPlugin.php:70
-msgid ""
-"The Gravatar plugin allows users to use their <a "
-"href=\"http://www.gravatar.com/\">Gravatar</a> with StatusNet."
-msgstr "Gravatar-tillägget låter användare använda deras <a href=\"http://www.gravatar.com/\">Gravatar</a> med StatusNet."
diff --git a/plugins/Gravatar/locale/ta/LC_MESSAGES/Gravatar.po b/plugins/Gravatar/locale/ta/LC_MESSAGES/Gravatar.po
deleted file mode 100644 (file)
index c5b0596..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-# SOME DESCRIPTIVE TITLE.
-# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
-# This file is distributed under the same license as the PACKAGE package.
-# 
-# Translators:
-msgid ""
-msgstr ""
-"Project-Id-Version: GNU social\n"
-"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2015-02-02 17:47+0100\n"
-"PO-Revision-Date: 2015-02-07 08:48+0000\n"
-"Last-Translator: digitaldreamer <digitaldreamer@email.cz>\n"
-"Language-Team: Tamil (http://www.transifex.com/projects/p/gnu-social/language/ta/)\n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
-"Content-Transfer-Encoding: 8bit\n"
-"Language: ta\n"
-"Plural-Forms: nplurals=2; plural=(n != 1);\n"
-
-#. TRANS: Plugin decsription.
-#: GravatarPlugin.php:70
-msgid ""
-"The Gravatar plugin allows users to use their <a "
-"href=\"http://www.gravatar.com/\">Gravatar</a> with StatusNet."
-msgstr ""
diff --git a/plugins/Gravatar/locale/te/LC_MESSAGES/Gravatar.po b/plugins/Gravatar/locale/te/LC_MESSAGES/Gravatar.po
deleted file mode 100644 (file)
index f842abd..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-# SOME DESCRIPTIVE TITLE.
-# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
-# This file is distributed under the same license as the PACKAGE package.
-# 
-# Translators:
-msgid ""
-msgstr ""
-"Project-Id-Version: GNU social\n"
-"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2015-02-02 17:47+0100\n"
-"PO-Revision-Date: 2015-02-06 16:27+0000\n"
-"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
-"Language-Team: Telugu (http://www.transifex.com/projects/p/gnu-social/language/te/)\n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
-"Content-Transfer-Encoding: 8bit\n"
-"Language: te\n"
-"Plural-Forms: nplurals=2; plural=(n != 1);\n"
-
-#. TRANS: Plugin decsription.
-#: GravatarPlugin.php:70
-msgid ""
-"The Gravatar plugin allows users to use their <a "
-"href=\"http://www.gravatar.com/\">Gravatar</a> with StatusNet."
-msgstr ""
diff --git a/plugins/Gravatar/locale/tl/LC_MESSAGES/Gravatar.po b/plugins/Gravatar/locale/tl/LC_MESSAGES/Gravatar.po
deleted file mode 100644 (file)
index 76efd0d..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-# SOME DESCRIPTIVE TITLE.
-# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
-# This file is distributed under the same license as the PACKAGE package.
-# 
-# Translators:
-msgid ""
-msgstr ""
-"Project-Id-Version: GNU social\n"
-"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2015-02-02 17:47+0100\n"
-"PO-Revision-Date: 2015-02-06 16:43+0000\n"
-"Last-Translator: digitaldreamer <digitaldreamer@email.cz>\n"
-"Language-Team: Tagalog (http://www.transifex.com/projects/p/gnu-social/language/tl/)\n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
-"Content-Transfer-Encoding: 8bit\n"
-"Language: tl\n"
-"Plural-Forms: nplurals=2; plural=(n > 1);\n"
-
-#. TRANS: Plugin decsription.
-#: GravatarPlugin.php:70
-msgid ""
-"The Gravatar plugin allows users to use their <a "
-"href=\"http://www.gravatar.com/\">Gravatar</a> with StatusNet."
-msgstr "Ang pamasak na Gravatar ay nagpapahintulot sa mga tagagamit na gamitin ang kanilang <a href=\"http://www.gravatar.com/\">Gravatar</a> na may StatusNet."
diff --git a/plugins/Gravatar/locale/tr/LC_MESSAGES/Gravatar.po b/plugins/Gravatar/locale/tr/LC_MESSAGES/Gravatar.po
deleted file mode 100644 (file)
index afd8152..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-# SOME DESCRIPTIVE TITLE.
-# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
-# This file is distributed under the same license as the PACKAGE package.
-# 
-# Translators:
-msgid ""
-msgstr ""
-"Project-Id-Version: GNU social\n"
-"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2015-02-02 17:47+0100\n"
-"PO-Revision-Date: 2015-02-06 16:27+0000\n"
-"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
-"Language-Team: Turkish (http://www.transifex.com/projects/p/gnu-social/language/tr/)\n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
-"Content-Transfer-Encoding: 8bit\n"
-"Language: tr\n"
-"Plural-Forms: nplurals=2; plural=(n > 1);\n"
-
-#. TRANS: Plugin decsription.
-#: GravatarPlugin.php:70
-msgid ""
-"The Gravatar plugin allows users to use their <a "
-"href=\"http://www.gravatar.com/\">Gravatar</a> with StatusNet."
-msgstr ""
diff --git a/plugins/Gravatar/locale/uk/LC_MESSAGES/Gravatar.po b/plugins/Gravatar/locale/uk/LC_MESSAGES/Gravatar.po
deleted file mode 100644 (file)
index c84ec1d..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-# SOME DESCRIPTIVE TITLE.
-# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
-# This file is distributed under the same license as the PACKAGE package.
-# 
-# Translators:
-msgid ""
-msgstr ""
-"Project-Id-Version: GNU social\n"
-"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2015-02-02 17:47+0100\n"
-"PO-Revision-Date: 2015-02-06 16:43+0000\n"
-"Last-Translator: digitaldreamer <digitaldreamer@email.cz>\n"
-"Language-Team: Ukrainian (http://www.transifex.com/projects/p/gnu-social/language/uk/)\n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
-"Content-Transfer-Encoding: 8bit\n"
-"Language: uk\n"
-"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n"
-
-#. TRANS: Plugin decsription.
-#: GravatarPlugin.php:70
-msgid ""
-"The Gravatar plugin allows users to use their <a "
-"href=\"http://www.gravatar.com/\">Gravatar</a> with StatusNet."
-msgstr "Додаток Gravatar дозволяє користувачам встановлювати аватарки з <a href=\"http://www.gravatar.com/\">Gravatar</a> для сайту StatusNet."
diff --git a/plugins/Gravatar/locale/ur_PK/LC_MESSAGES/Gravatar.po b/plugins/Gravatar/locale/ur_PK/LC_MESSAGES/Gravatar.po
deleted file mode 100644 (file)
index f7de61f..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-# SOME DESCRIPTIVE TITLE.
-# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
-# This file is distributed under the same license as the PACKAGE package.
-# 
-# Translators:
-msgid ""
-msgstr ""
-"Project-Id-Version: GNU social\n"
-"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2015-02-02 17:47+0100\n"
-"PO-Revision-Date: 2015-02-06 16:27+0000\n"
-"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
-"Language-Team: Urdu (Pakistan) (http://www.transifex.com/projects/p/gnu-social/language/ur_PK/)\n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
-"Content-Transfer-Encoding: 8bit\n"
-"Language: ur_PK\n"
-"Plural-Forms: nplurals=2; plural=(n != 1);\n"
-
-#. TRANS: Plugin decsription.
-#: GravatarPlugin.php:70
-msgid ""
-"The Gravatar plugin allows users to use their <a "
-"href=\"http://www.gravatar.com/\">Gravatar</a> with StatusNet."
-msgstr ""
diff --git a/plugins/Gravatar/locale/vi/LC_MESSAGES/Gravatar.po b/plugins/Gravatar/locale/vi/LC_MESSAGES/Gravatar.po
deleted file mode 100644 (file)
index 0cdfdcc..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-# SOME DESCRIPTIVE TITLE.
-# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
-# This file is distributed under the same license as the PACKAGE package.
-# 
-# Translators:
-msgid ""
-msgstr ""
-"Project-Id-Version: GNU social\n"
-"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2015-02-02 17:47+0100\n"
-"PO-Revision-Date: 2015-02-06 16:27+0000\n"
-"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
-"Language-Team: Vietnamese (http://www.transifex.com/projects/p/gnu-social/language/vi/)\n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
-"Content-Transfer-Encoding: 8bit\n"
-"Language: vi\n"
-"Plural-Forms: nplurals=1; plural=0;\n"
-
-#. TRANS: Plugin decsription.
-#: GravatarPlugin.php:70
-msgid ""
-"The Gravatar plugin allows users to use their <a "
-"href=\"http://www.gravatar.com/\">Gravatar</a> with StatusNet."
-msgstr ""
diff --git a/plugins/Gravatar/locale/zh_CN/LC_MESSAGES/Gravatar.po b/plugins/Gravatar/locale/zh_CN/LC_MESSAGES/Gravatar.po
deleted file mode 100644 (file)
index 8a2a5c6..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-# SOME DESCRIPTIVE TITLE.
-# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
-# This file is distributed under the same license as the PACKAGE package.
-# 
-# Translators:
-msgid ""
-msgstr ""
-"Project-Id-Version: GNU social\n"
-"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2015-02-02 17:47+0100\n"
-"PO-Revision-Date: 2015-02-06 16:43+0000\n"
-"Last-Translator: digitaldreamer <digitaldreamer@email.cz>\n"
-"Language-Team: Chinese (China) (http://www.transifex.com/projects/p/gnu-social/language/zh_CN/)\n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
-"Content-Transfer-Encoding: 8bit\n"
-"Language: zh_CN\n"
-"Plural-Forms: nplurals=1; plural=0;\n"
-
-#. TRANS: Plugin decsription.
-#: GravatarPlugin.php:70
-msgid ""
-"The Gravatar plugin allows users to use their <a "
-"href=\"http://www.gravatar.com/\">Gravatar</a> with StatusNet."
-msgstr "Gravatar 插件可以让用户在 StatusNet 站点使用自己的 <a href=\"http://www.gravatar.com/\">Gravatar</a>。"
diff --git a/plugins/Gravatar/locale/zh_TW/LC_MESSAGES/Gravatar.po b/plugins/Gravatar/locale/zh_TW/LC_MESSAGES/Gravatar.po
deleted file mode 100644 (file)
index 2a603ff..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-# SOME DESCRIPTIVE TITLE.
-# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
-# This file is distributed under the same license as the PACKAGE package.
-# 
-# Translators:
-msgid ""
-msgstr ""
-"Project-Id-Version: GNU social\n"
-"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2015-02-02 17:47+0100\n"
-"PO-Revision-Date: 2015-02-06 16:27+0000\n"
-"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
-"Language-Team: Chinese (Taiwan) (http://www.transifex.com/projects/p/gnu-social/language/zh_TW/)\n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
-"Content-Transfer-Encoding: 8bit\n"
-"Language: zh_TW\n"
-"Plural-Forms: nplurals=1; plural=0;\n"
-
-#. TRANS: Plugin decsription.
-#: GravatarPlugin.php:70
-msgid ""
-"The Gravatar plugin allows users to use their <a "
-"href=\"http://www.gravatar.com/\">Gravatar</a> with StatusNet."
-msgstr ""
index be59f5ba0b5ecb63f755dbeb8ac853a9e4a3649f..48861af9942605295b9b81bf775ed9c7032420c3 100644 (file)
@@ -120,9 +120,11 @@ class MapAction extends Action
         $jsonArray = array();
 
         while ($this->notice->fetch()) {
-            if (!empty($this->notice->lat) && !empty($this->notice->lon)) {
-                $jsonNotice = $this->noticeAsJson($this->notice);
-                $jsonArray[] = $jsonNotice;
+            try {
+                $notloc = Notice_location::locFromStored($this->notice);
+                $jsonArray[] = $this->noticeAsJson($this->notice);
+            } catch (ServerException $e) {
+                // no location data
             }
         }
 
index 32c96be0e8c0722b5d7249adc0012beacc7455d6..d1e01ca8496da938607e3d414ed2c2f734298121 100644 (file)
@@ -101,10 +101,10 @@ class ModLogPlugin extends Plugin
 
         $modlog->profile_id = $profile->id;
 
-        $cur = common_current_user();
+        $scoped = Profile::current();
         
-        if (!empty($cur)) {
-            $modlog->moderator_id = $cur->id;
+        if ($scoped instanceof Profile) {
+            $modlog->moderator_id = $scoped->getID();
         }
 
         $modlog->role     = $role;
@@ -118,21 +118,22 @@ class ModLogPlugin extends Plugin
 
     function onEndShowSections(Action $action)
     {
-        if ($action->arg('action') != 'showstream') {
+        if (!$action instanceof ShowstreamAction) {
+            // early return for actions we're not interested in
             return true;
         }
 
-        $cur = common_current_user();
-
-        if (empty($cur) || !$cur->hasRight(self::VIEWMODLOG)) {
+        $scoped = $action->getScoped();
+        if (!$scoped instanceof Profile || !$scoped->hasRight(self::VIEWMODLOG)) {
+            // only continue if we are allowed to VIEWMODLOG
             return true;
         }
 
-        $profile = $action->profile;
+        $profile = $action->getTarget();
 
         $ml = new ModLog();
 
-        $ml->profile_id = $profile->id;
+        $ml->profile_id = $profile->getID();
         $ml->orderBy("created");
 
         $cnt = $ml->find();
@@ -152,13 +153,13 @@ class ModLogPlugin extends Plugin
                 $action->element('td', null, sprintf(($ml->is_grant) ? _('+%s') : _('-%s'), $ml->role));
                 $action->elementStart('td');
                 if ($ml->moderator_id) {
-                    $mod = Profile::getKV('id', $ml->moderator_id);
+                    $mod = Profile::getByID($ml->moderator_id);
                     if (empty($mod)) {
                         $action->text(_('[unknown]'));
                     } else {
-                        $action->element('a', array('href' => $mod->profileurl,
-                                                    'title' => $mod->fullname),
-                                         $mod->nickname);
+                        $action->element('a', array('href' => $mod->getUrl(),
+                                                    'title' => $mod->getFullname()),
+                                         $mod->getNickname());
                     }
                 } else {
                     $action->text(_('[unknown]'));
index 630031fdde06916a44d0238a6d71e2be61c7db2b..0dace39db0a542da1031df2f40de0abe0560ee61 100644 (file)
@@ -1063,8 +1063,12 @@ class OStatusPlugin extends Plugin
 
     function showEntityRemoteSubscribe($action, $target='ostatussub')
     {
-        $user = common_current_user();
-        if ($user && ($user->id == $action->profile->id)) {
+        if (!$action->getScoped() instanceof Profile) {
+            // early return if we're not logged in
+            return true;
+        }
+
+        if ($action->getScoped()->sameAs($action->getTarget())) {
             $action->elementStart('div', 'entity_actions');
             $action->elementStart('p', array('id' => 'entity_remote_subscribe',
                                              'class' => 'entity_subscribe'));
@@ -1127,42 +1131,45 @@ class OStatusPlugin extends Plugin
         return true;
     }
 
-    function onStartProfileListItemActionElements($item, $profile=null)
+    // FIXME: This one can accept both an Action and a Widget. Confusing! Refactor to (HTMLOutputter $out, Profile $target)!
+    function onStartProfileListItemActionElements($item)
     {
-        if (!common_logged_in()) {
-
-            $profileUser = User::getKV('id', $item->profile->id);
-
-            if (!empty($profileUser)) {
-
-                if ($item instanceof Action) {
-                    $output = $item;
-                    $profile = $item->profile;
-                } else {
-                    $output = $item->out;
-                }
+        if (common_logged_in()) {
+            // only non-logged in users get to see the "remote subscribe" form
+            return true;
+        } elseif (!$item->getTarget()->isLocal()) {
+            // we can (for now) only provide remote subscribe forms for local users
+            return true;
+        }
 
-                // Add an OStatus subscribe
-                $output->elementStart('li', 'entity_subscribe');
-                $url = common_local_url('ostatusinit',
-                                        array('nickname' => $profileUser->nickname));
-                $output->element('a', array('href' => $url,
-                                            'class' => 'entity_remote_subscribe'),
-                                  // TRANS: Link text for a user to subscribe to an OStatus user.
-                                 _m('Subscribe'));
-                $output->elementEnd('li');
-
-                $output->elementStart('li', 'entity_tag');
-                $url = common_local_url('ostatustag',
-                                        array('nickname' => $profileUser->nickname));
-                $output->element('a', array('href' => $url,
-                                            'class' => 'entity_remote_tag'),
-                                  // TRANS: Link text for a user to list an OStatus user.
-                                 _m('List'));
-                $output->elementEnd('li');
-            }
+        if ($item instanceof ProfileAction) {
+            $output = $item;
+        } elseif ($item instanceof Widget) {
+            $output = $item->out;
+        } else {
+            // Bad $item class, don't know how to use this for outputting!
+            throw new ServerException('Bad item type for onStartProfileListItemActionElements');
         }
 
+        // Add an OStatus subscribe
+        $output->elementStart('li', 'entity_subscribe');
+        $url = common_local_url('ostatusinit',
+                                array('nickname' => $item->getTarget()->getNickname()));
+        $output->element('a', array('href' => $url,
+                                    'class' => 'entity_remote_subscribe'),
+                          // TRANS: Link text for a user to subscribe to an OStatus user.
+                         _m('Subscribe'));
+        $output->elementEnd('li');
+
+        $output->elementStart('li', 'entity_tag');
+        $url = common_local_url('ostatustag',
+                                array('nickname' => $item->getTarget()->getNickname()));
+        $output->element('a', array('href' => $url,
+                                    'class' => 'entity_remote_tag'),
+                          // TRANS: Link text for a user to list an OStatus user.
+                         _m('List'));
+        $output->elementEnd('li');
+
         return true;
     }
 
index cb961dc96ba8f164bf2105e5d51d0134339b82e2..1c4428b16df7ed17e1e90949c9d452ef9f5f383e 100644 (file)
@@ -1977,6 +1977,38 @@ class Ostatus_profile extends Managed_DataObject
 
         return $oprofile->localProfile();
     }
+
+    public function updateUriKeys($profile_uri, array $hints=array())
+    {
+        $orig = clone($this);
+
+        common_debug('URIFIX These identities both say they are each other: "'.$orig->uri.'" and "'.$profile_uri.'"');
+        $this->uri = $profile_uri;
+
+        if (array_key_exists('feedurl', $hints)) {
+            if (!empty($this->feeduri)) {
+                common_debug('URIFIX Changing FeedSub ['.$feedsub->id.'] feeduri "'.$feedsub->uri.'" to "'.$hints['feedurl']);
+                $feedsub = FeedSub::getKV('uri', $this->feeduri);
+                $feedorig = clone($feedsub);
+                $feedsub->uri = $hints['feedurl'];
+                $feedsub->updateWithKeys($feedorig);
+            } else {
+                common_debug('URIFIX Old Ostatus_profile did not have feedurl set, ensuring feed: '.$hints['feedurl']);
+                FeedSub::ensureFeed($hints['feedurl']);
+            }
+            $this->feeduri = $hints['feedurl'];
+        }
+        if (array_key_exists('salmon', $hints)) {
+            common_debug('URIFIX Changing Ostatus_profile salmonuri from "'.$this->salmonuri.'" to "'.$hints['salmon'].'"');
+            $this->salmonuri = $hints['salmon'];
+        }
+
+        common_debug('URIFIX Updating Ostatus_profile URI for '.$orig->uri.' to '.$this->uri);
+        $this->updateWithKeys($orig, 'uri');    // 'uri' is the primary key column
+
+        common_debug('URIFIX Subscribing/renewing feedsub for Ostatus_profile '.$this->uri);
+        $this->subscribe();
+    }
 }
 
 /**
index 9e02f5eab5e3f8963ae7020bb3223058a86f8498..dfd3abaeabd401cc6852e6721b59474a19eddc17 100644 (file)
@@ -50,8 +50,8 @@ class MagicEnvelope
      */
     public function __construct($xml=null) {
         if (!empty($xml)) {
-            $dom = DOMDocument::loadXML($xml);
-            if (!$dom instanceof DOMDocument) {
+            $dom = new DOMDocument();
+            if (!$dom->loadXML($xml)) {
                 throw new ServerException('Tried to load malformed XML as DOM');
             } elseif (!$this->fromDom($dom)) {
                 throw new ServerException('Could not load MagicEnvelope from DOM');
index 5193d302f1e1ebf7a7f096acf0a9ed7c5ba1044b..320ea6cdfa6f980b9d51ad7e7301d4953bfd5e30 100644 (file)
@@ -259,12 +259,7 @@ class SalmonAction extends Action
                 // Step 4: Is the newly introduced https://example.com/user/1 URI in the list of aliases
                 //         presented by http://example.com/user/1 (i.e. do they both say they are the same identity?)
                 if (in_array($e->object_uri, $doublecheck_aliases)) {
-                    common_debug('URIFIX These identities both say they are each other: "'.$aliased_uri.'" and "'.$e->object_uri.'"');
-                    $orig = clone($oprofile);
-                    $oprofile->uri = $e->object_uri;
-                    common_debug('URIFIX Updating Ostatus_profile URI for '.$aliased_uri.' to '.$oprofile->uri);
-                    $oprofile->updateWithKeys($orig, 'uri');    // 'uri' is the primary key column
-                    unset($orig);
+                    $oprofile->updateUriKeys($e->object_uri, DiscoveryHints::fromXRD($xrd));
                     $this->oprofile = $oprofile;
                     break;  // don't iterate through aliases anymore
                 }
index 710a34410ac6e81551fb94068a26bae84e022463..2e9ada98064e3b36ae0d7457d98bfd3322c59488 100644 (file)
@@ -390,11 +390,11 @@ class OpenIDPlugin extends Plugin
             $action->element('link', array('rel' => 'openid2.provider',
                                            'href' => common_local_url('openidserver')));
             $action->element('link', array('rel' => 'openid2.local_id',
-                                           'href' => $action->profile->profileurl));
+                                           'href' => $action->getTarget()->getUrl()));
             $action->element('link', array('rel' => 'openid.server',
                                            'href' => common_local_url('openidserver')));
             $action->element('link', array('rel' => 'openid.delegate',
-                                           'href' => $action->profile->profileurl));
+                                           'href' => $action->getTarget()->getUrl()));
         }
 
         if ($action instanceof SitestreamAction) {
index 0c20dac4cdde86557ef2247ab453e02840d37423..bf5d8886f179a0fee2be3d6670047a100ad2da0d 100644 (file)
@@ -27,9 +27,7 @@
  * @link      http://status.net/
  */
 
-if (!defined('STATUSNET')) {
-    exit(1);
-}
+if (!defined('GNUSOCIAL')) { exit(1); }
 
 require_once INSTALLDIR.'/plugins/OpenID/openid.php';
 
@@ -86,8 +84,6 @@ class OpenidsettingsAction extends SettingsAction
      */
     function showContent()
     {
-        $user = common_current_user();
-
         if (!common_config('openid', 'trusted_provider')) {
             $this->elementStart('form', array('method' => 'post',
                                               'id' => 'form_settings_openid_add',
@@ -115,7 +111,7 @@ class OpenidsettingsAction extends SettingsAction
         }
         $oid = new User_openid();
 
-        $oid->user_id = $user->id;
+        $oid->user_id = $this->scoped->getID();
 
         $cnt = $oid->find();
 
@@ -123,7 +119,7 @@ class OpenidsettingsAction extends SettingsAction
             // TRANS: Header on OpenID settings page.
             $this->element('h2', null, _m('HEADER','Remove OpenID'));
 
-            if ($cnt == 1 && !$user->password) {
+            if ($cnt == 1 && !$this->scoped->hasPassword()) {
 
                 $this->element('p', 'form_guide',
                                // TRANS: Form guide.
@@ -184,7 +180,7 @@ class OpenidsettingsAction extends SettingsAction
                        'this list to deny it access to your OpenID.'));
         $this->elementStart('ul', 'form_data');
         $user_openid_trustroot = new User_openid_trustroot();
-        $user_openid_trustroot->user_id=$user->id;
+        $user_openid_trustroot->user_id = $this->scoped->getID();
         if($user_openid_trustroot->find()) {
             while($user_openid_trustroot->fetch()) {
                 $this->elementStart('li');
@@ -203,7 +199,7 @@ class OpenidsettingsAction extends SettingsAction
         $this->submit('settings_openid_trustroots_action-submit', _m('BUTTON','Remove'), 'submit', 'remove_trustroots');
         $this->elementEnd('fieldset');
         
-        $prefs = User_openid_prefs::getKV('user_id', $user->id);
+        $prefs = User_openid_prefs::getKV('user_id', $this->scoped->getID());
 
         $this->elementStart('fieldset');
         $this->element('legend', null, _m('LEGEND','Preferences'));
@@ -224,38 +220,29 @@ class OpenidsettingsAction extends SettingsAction
      *
      * @return void
      */
-    function handlePost()
+    protected function doPost()
     {
-        // CSRF protection
-        $token = $this->trimmed('token');
-        if (!$token || $token != common_session_token()) {
-            // TRANS: Client error displayed when the session token does not match or is not given.
-            $this->showForm(_m('There was a problem with your session token. '.
-                              'Try again, please.'));
-            return;
-        }
-
         if ($this->arg('add')) {
             if (common_config('openid', 'trusted_provider')) {
                 // TRANS: Form validation error if no OpenID providers can be added.
-                $this->showForm(_m('Cannot add new providers.'));
+                throw new ServerException(_m('Cannot add new providers.'));
             } else {
-                $result = oid_authenticate($this->trimmed('openid_url'),
-                                           'finishaddopenid');
+                $result = oid_authenticate($this->trimmed('openid_url'), 'finishaddopenid');
                 if (is_string($result)) { // error message
-                    $this->showForm($result);
+                    throw new ServerException($result);
                 }
+                return _('Added new provider.');
             }
         } else if ($this->arg('remove')) {
-            $this->removeOpenid();
+            return $this->removeOpenid();
         } else if($this->arg('remove_trustroots')) {
-            $this->removeTrustroots();
+            return $this->removeTrustroots();
         } else if($this->arg('save_prefs')) {
-            $this->savePrefs();
-        } else {
-            // TRANS: Unexpected form validation error.
-            $this->showForm(_m('Something weird happened.'));
+            return $this->savePrefs();
         }
+
+        // TRANS: Unexpected form validation error.
+        throw new ServerException(_m('No known action for POST.'));
     }
 
     /**
@@ -268,26 +255,20 @@ class OpenidsettingsAction extends SettingsAction
      */
     function removeTrustroots()
     {
-        $user = common_current_user();
-        $trustroots = $this->arg('openid_trustroot');
-        if($trustroots) {
-            foreach($trustroots as $trustroot) {
-                $user_openid_trustroot = User_openid_trustroot::pkeyGet(
-                                                array('user_id'=>$user->id, 'trustroot'=>$trustroot));
-                if($user_openid_trustroot) {
-                    $user_openid_trustroot->delete();
-                } else {
-                    // TRANS: Form validation error when trying to remove a non-existing trustroot.
-                    $this->showForm(_m('No such OpenID trustroot.'));
-                    return;
-                }
+        $trustroots = $this->arg('openid_trustroot', array());
+        foreach($trustroots as $trustroot) {
+            $user_openid_trustroot = User_openid_trustroot::pkeyGet(
+                                            array('user_id'=>$this->scoped->getID(), 'trustroot'=>$trustroot));
+            if($user_openid_trustroot) {
+                $user_openid_trustroot->delete();
+            } else {
+                // TRANS: Form validation error when trying to remove a non-existing trustroot.
+                throw new ClientException(_m('No such OpenID trustroot.'));
             }
-            // TRANS: Success message after removing trustroots.
-            $this->showForm(_m('Trustroots removed.'), true);
-        } else {
-            $this->showForm();
         }
-        return;
+
+        // TRANS: Success message after removing trustroots.
+        return _m('Trustroots removed.');
     }
 
     /**
@@ -300,25 +281,19 @@ class OpenidsettingsAction extends SettingsAction
      */
     function removeOpenid()
     {
-        $openid_url = $this->trimmed('openid_url');
-
-        $oid = User_openid::getKV('canonical', $openid_url);
+        $oid = User_openid::getKV('canonical', $this->trimmed('openid_url'));
 
-        if (!$oid) {
+        if (!$oid instanceof User_openid) {
             // TRANS: Form validation error for a non-existing OpenID.
-            $this->showForm(_m('No such OpenID.'));
-            return;
+            throw new ClientException(_m('No such OpenID.'));
         }
-        $cur = common_current_user();
-        if (!$cur || $oid->user_id != $cur->id) {
+        if ($this->scoped->getID() !== $oid->user_id) {
             // TRANS: Form validation error if OpenID is connected to another user.
-            $this->showForm(_m('That OpenID does not belong to you.'));
-            return;
+            throw new ClientException(_m('That OpenID does not belong to you.'));
         }
         $oid->delete();
         // TRANS: Success message after removing an OpenID.
-        $this->showForm(_m('OpenID removed.'), true);
-        return;
+        return _m('OpenID removed.');
     }
 
     /**
@@ -331,18 +306,12 @@ class OpenidsettingsAction extends SettingsAction
      */
     function savePrefs()
     {
-        $cur = common_current_user();
-
-        if (empty($cur)) {
-            throw new ClientException(_("Not logged in."));
-        }
-
         $orig  = null;
-        $prefs = User_openid_prefs::getKV('user_id', $cur->id);
+        $prefs = User_openid_prefs::getKV('user_id', $this->scoped->getID());
 
-        if (empty($prefs)) {
+        if (!$prefs instanceof User_openid_prefs) {
             $prefs          = new User_openid_prefs();
-            $prefs->user_id = $cur->id;
+            $prefs->user_id = $this->scoped->getID();
             $prefs->created = common_sql_now();
         } else {
             $orig = clone($prefs);
@@ -350,13 +319,12 @@ class OpenidsettingsAction extends SettingsAction
 
         $prefs->hide_profile_link = $this->booleanintstring('hide_profile_link');
 
-        if (empty($orig)) {
-            $prefs->insert();
-        } else {
+        if ($orig instanceof User_openid_prefs) {
             $prefs->update($orig);
+        } else {
+            $prefs->insert();
         }
 
-        $this->showForm(_m('OpenID preferences saved.'), true);
-        return;
+        return _m('OpenID preferences saved.');
     }
 }
index 91a34bd6e364edbe58b291519ef2dc938b6f2080..ee854e8140e274433b6decd6e08be0f15e576277 100644 (file)
@@ -131,13 +131,15 @@ function oid_check_immediate($openid_url, $backto=null)
 
 function oid_authenticate($openid_url, $returnto, $immediate=false)
 {
+    if (!common_valid_http_url($openid_url)) {
+        throw new ClientException(_m('No valid URL provided for OpenID.'));
+    }
 
     $consumer = oid_consumer();
 
     if (!$consumer) {
         // TRANS: OpenID plugin server error.
-        common_server_error(_m('Cannot instantiate OpenID consumer object.'));
-        return false;
+        throw new ServerException(_m('Cannot instantiate OpenID consumer object.'));
     }
 
     common_ensure_session();
@@ -148,12 +150,12 @@ function oid_authenticate($openid_url, $returnto, $immediate=false)
     if (!$auth_request) {
         common_log(LOG_ERR, __METHOD__ . ": mystery fail contacting $openid_url");
         // TRANS: OpenID plugin message. Given when an OpenID is not valid.
-        return _m('Not a valid OpenID.');
+        throw new ServerException(_m('Not a valid OpenID.'));
     } else if (Auth_OpenID::isFailure($auth_request)) {
         common_log(LOG_ERR, __METHOD__ . ": OpenID fail to $openid_url: $auth_request->message");
         // TRANS: OpenID plugin server error. Given when the OpenID authentication request fails.
         // TRANS: %s is the failure message.
-        return sprintf(_m('OpenID failure: %s.'), $auth_request->message);
+        throw new ServerException(sprintf(_m('OpenID failure: %s.'), $auth_request->message));
     }
 
     $sreg_request = Auth_OpenID_SRegRequest::build(// Required
@@ -199,14 +201,12 @@ function oid_authenticate($openid_url, $returnto, $immediate=false)
         $redirect_url = $auth_request->redirectURL($trust_root,
                                                    $process_url,
                                                    $immediate);
-        if (!$redirect_url) {
-        } else if (Auth_OpenID::isFailure($redirect_url)) {
+        if (Auth_OpenID::isFailure($redirect_url)) {
             // TRANS: OpenID plugin server error. Given when the OpenID authentication request cannot be redirected.
             // TRANS: %s is the failure message.
-            return sprintf(_m('Could not redirect to server: %s.'), $redirect_url->message);
-        } else {
-            common_redirect($redirect_url, 303);
+            throw new ServerException(sprintf(_m('Could not redirect to server: %s.'), $redirect_url->message));
         }
+        common_redirect($redirect_url, 303);
     /*
     } else {
         // Generate form markup and render it.
index 4b2b679b580217846dab25d20b03e3b144c5fb08..b2dc61e15fe8bf66ecf1741c00825bf7a50efe25 100644 (file)
@@ -83,10 +83,17 @@ class OpportunisticQueueManager extends DBQueueManager
     // OpportunisticQM shouldn't discard items it can't handle, we're
     // only here to take care of what we _can_ handle!
     protected function noHandlerFound(Queue_item $qi, $rep=null) {
-        $this->_log(LOG_WARNING, "[{$qi->transport}:item {$qi->id}] Releasing claim for queue item without a handler");
+        $this->_log(LOG_WARNING, "[{$qi->transport}:item {$qi->id}] Releasing claim for queue item without a handler");              
         $this->_fail($qi, true);    // true here means "releaseOnly", so no error statistics since it's not an _error_
     }
 
+    protected function _fail(Queue_item $qi, $releaseOnly=false)
+    {
+        parent::_fail($qi, $releaseOnly);
+        $this->_log(LOG_DEBUG, "[{$qi->transport}:item {$qi->id}] Ignoring this transport for the rest of this execution");
+        $this->ignoreTransport($qi->transport);
+    }
+
     /**
      * Takes care of running through the queue items, returning when
      * the limits setup in __construct are met.
index b390812cf41a4c4a812f583af164b8da7ce3a481..b95465d8d6e0e99b3a57cf3149ff2664a99e6279 100644 (file)
@@ -27,9 +27,7 @@
  * @link      http://status.net/
  */
 
-if (!defined('STATUSNET') && !defined('LACONICA')) {
-    exit(1);
-}
+if (!defined('GNUSOCIAL')) { exit(1); }
 
 class PollSettingsAction extends SettingsAction
 {
@@ -56,143 +54,36 @@ class PollSettingsAction extends SettingsAction
         return _m('Set your poll preferences');
     }
 
-    /**
-     * Show the form for Poll
-     *
-     * @return void
-     */
-    function showContent()
+    protected function getForm()
     {
-        $user = common_current_user();
-
-        $prefs = User_poll_prefs::getKV('user_id', $user->id);
-
+        $prefs = User_poll_prefs::getKV('user_id', $this->scoped->getID());
         $form = new PollPrefsForm($this, $prefs);
-
-        $form->show();
+        return $form;
     }
 
-    /**
-     * Handler method
-     *
-     * @param array $argarray is ignored since it's now passed in in prepare()
-     *
-     * @return void
-     */
-
-    function handlePost()
+    protected function doPost()
     {
-        $user = common_current_user();
-
-        $upp = User_poll_prefs::getKV('user_id', $user->id);
+        $upp = User_poll_prefs::getKV('user_id', $this->scoped->getID());
         $orig = null;
 
-        if (!empty($upp)) {
+        if ($upp instanceof User_poll_prefs) {
             $orig = clone($upp);
         } else {
             $upp = new User_poll_prefs();
-            $upp->user_id = $user->id;
+            $upp->user_id = $this->scoped->getID();
             $upp->created = common_sql_now();
         }
 
         $upp->hide_responses = $this->boolean('hide_responses');
         $upp->modified       = common_sql_now();
 
-        if (!empty($orig)) {
+        if ($orig instanceof User_poll_prefs) {
             $upp->update($orig);
         } else {
             $upp->insert();
         }
 
         // TRANS: Confirmation shown when user profile settings are saved.
-        $this->showForm(_('Settings saved.'), true);
-
-        return;
-    }
-}
-
-class PollPrefsForm extends Form
-{
-    var $prefs;
-
-    function __construct($out, $prefs)
-    {
-        parent::__construct($out);
-        $this->prefs = $prefs;
-    }
-
-    /**
-     * Visible or invisible data elements
-     *
-     * Display the form fields that make up the data of the form.
-     * Sub-classes should overload this to show their data.
-     *
-     * @return void
-     */
-
-    function formData()
-    {
-        $this->elementStart('fieldset');
-        $this->elementStart('ul', 'form_data');
-        $this->elementStart('li');
-        $this->checkbox('hide_responses',
-                        _('Do not deliver poll responses to my home timeline'),
-                        (!empty($this->prefs) && $this->prefs->hide_responses));
-        $this->elementEnd('li');
-        $this->elementEnd('ul');
-        $this->elementEnd('fieldset');
-    }
-
-    /**
-     * Buttons for form actions
-     *
-     * Submit and cancel buttons (or whatever)
-     * Sub-classes should overload this to show their own buttons.
-     *
-     * @return void
-     */
-
-    function formActions()
-    {
-        $this->submit('submit', _('Save'));
-    }
-
-    /**
-     * ID of the form
-     *
-     * Should be unique on the page. Sub-classes should overload this
-     * to show their own IDs.
-     *
-     * @return int ID of the form
-     */
-
-    function id()
-    {
-        return 'form_poll_prefs';
-    }
-
-    /**
-     * Action of the form.
-     *
-     * URL to post to. Should be overloaded by subclasses to give
-     * somewhere to post to.
-     *
-     * @return string URL to post to
-     */
-
-    function action()
-    {
-        return common_local_url('pollsettings');
-    }
-
-    /**
-     * Class of the form. May include space-separated list of multiple classes.
-     *
-     * @return string the form's class
-     */
-
-    function formClass()
-    {
-        return 'form_settings';
+        return _('Settings saved.');
     }
 }
diff --git a/plugins/Poll/forms/pollprefs.php b/plugins/Poll/forms/pollprefs.php
new file mode 100644 (file)
index 0000000..627b77d
--- /dev/null
@@ -0,0 +1,87 @@
+<?php
+
+if (!defined('GNUSOCIAL')) { exit(1); }
+
+class PollPrefsForm extends Form
+{
+    function __construct(Action $out, User_poll_prefs $prefs=null)
+    {
+        parent::__construct($out);
+        $this->prefs = $prefs;
+    }
+
+    /**
+     * Visible or invisible data elements
+     *
+     * Display the form fields that make up the data of the form.
+     * Sub-classes should overload this to show their data.
+     *
+     * @return void
+     */
+
+    function formData()
+    {
+        $this->elementStart('fieldset');
+        $this->elementStart('ul', 'form_data');
+        $this->elementStart('li');
+        $this->checkbox('hide_responses',
+                        _('Do not deliver poll responses to my home timeline'),
+                        ($this->prefs instanceof User_poll_prefs && $this->prefs->hide_responses));
+        $this->elementEnd('li');
+        $this->elementEnd('ul');
+        $this->elementEnd('fieldset');
+    }
+
+    /**
+     * Buttons for form actions
+     *
+     * Submit and cancel buttons (or whatever)
+     * Sub-classes should overload this to show their own buttons.
+     *
+     * @return void
+     */
+
+    function formActions()
+    {
+        $this->submit('submit', _('Save'));
+    }
+
+    /**
+     * ID of the form
+     *
+     * Should be unique on the page. Sub-classes should overload this
+     * to show their own IDs.
+     *
+     * @return int ID of the form
+     */
+
+    function id()
+    {
+        return 'form_poll_prefs';
+    }
+
+    /**
+     * Action of the form.
+     *
+     * URL to post to. Should be overloaded by subclasses to give
+     * somewhere to post to.
+     *
+     * @return string URL to post to
+     */
+
+    function action()
+    {
+        return common_local_url('pollsettings');
+    }
+
+    /**
+     * Class of the form. May include space-separated list of multiple classes.
+     *
+     * @return string the form's class
+     */
+
+    function formClass()
+    {
+        return 'form_settings';
+    }
+}
index cc4b646f6b024c37e84fb01d370af8f8687b7498..d0d1893739bd03400d91cef554bce9b5aa5ab67e 100644 (file)
@@ -157,7 +157,7 @@ class ConfirmfirstemailAction extends Action
 
         $orig = clone($this->user);
 
-        $this->user->password = common_munge_password($this->password, $this->user->id);
+        $this->user->password = common_munge_password($this->password, $this->user->getProfile());
 
         $this->user->update($orig);
 
index 54563ed0e7162c862092d9fd3fb004e081cbe9b8..fd89075032eedbe862499e173baa5fd2a81e7c78 100644 (file)
@@ -28,9 +28,7 @@
  * @link      http://status.net/
  */
 
-if (!defined('STATUSNET') && !defined('LACONICA')) {
-    exit(1);
-}
+if (!defined('GNUSOCIAL')) { exit(1); }
 
 /**
  * A list of the user's subscriptions
@@ -48,20 +46,19 @@ class SearchSubsAction extends GalleryAction
         if ($this->page == 1) {
             // TRANS: Header for subscriptions overview for a user (first page).
             // TRANS: %s is a user nickname.
-            return sprintf(_m('%s\'s search subscriptions'), $this->user->nickname);
+            return sprintf(_m('%s\'s search subscriptions'), $this->getTarget()->getNickname());
         } else {
             // TRANS: Header for subscriptions overview for a user (not first page).
             // TRANS: %1$s is a user nickname, %2$d is the page number.
             return sprintf(_m('%1$s\'s search subscriptions, page %2$d'),
-                           $this->user->nickname,
+                           $this->getTarget()->getNickname(),
                            $this->page);
         }
     }
 
     function showPageNotice()
     {
-        $user = common_current_user();
-        if ($user && ($user->id == $this->profile->id)) {
+        if ($this->scoped instanceof Profile && $this->scoped->sameAs($this->getTarget())) {
             $this->element('p', null,
                            // TRANS: Page notice for page with an overview of all search subscriptions
                            // TRANS: of the logged in user's own profile.
@@ -71,7 +68,7 @@ class SearchSubsAction extends GalleryAction
                            // TRANS: Page notice for page with an overview of all subscriptions of a user other
                            // TRANS: than the logged in user. %s is the user nickname.
                            sprintf(_m('%s has subscribed to receive all notices on this site matching the following searches:'),
-                                   $this->profile->nickname));
+                                   $this->getTarget()->getNickname()));
         }
     }
 
@@ -86,12 +83,12 @@ class SearchSubsAction extends GalleryAction
             $cnt = 0;
 
             $searchsub = new SearchSub();
-            $searchsub->profile_id = $this->user->id;
+            $searchsub->profile_id = $this->getTarget()->getID();
             $searchsub->limit($limit, $offset);
             $searchsub->find();
 
             if ($searchsub->N) {
-                $list = new SearchSubscriptionsList($searchsub, $this->user, $this);
+                $list = new SearchSubscriptionsList($searchsub, $this->getTarget(), $this);
                 $cnt = $list->show();
                 if (0 == $cnt) {
                     $this->showEmptyListMessage();
@@ -102,7 +99,7 @@ class SearchSubsAction extends GalleryAction
 
             $this->pagination($this->page > 1, $cnt > PROFILES_PER_PAGE,
                               $this->page, 'searchsubs',
-                              array('nickname' => $this->user->nickname));
+                              array('nickname' => $this->getTarget()->getNickname()));
 
 
             Event::handle('EndShowTagSubscriptionsContent', array($this));
@@ -112,8 +109,7 @@ class SearchSubsAction extends GalleryAction
     function showEmptyListMessage()
     {
         if (common_logged_in()) {
-            $current_user = common_current_user();
-            if ($this->user->id === $current_user->id) {
+            if ($this->scoped->sameAs($this->getTarget())) {
                 // TRANS: Search subscription list text when the logged in user has no search subscriptions.
                 $message = _m('You are not subscribed to any text searches right now. You can push the "Subscribe" button ' .
                              'on any notice text search to automatically receive any public messages on this site that match that ' .
@@ -121,13 +117,13 @@ class SearchSubsAction extends GalleryAction
             } else {
                 // TRANS: Search subscription list text when looking at the subscriptions for a of a user other
                 // TRANS: than the logged in user that has no search subscriptions. %s is the user nickname.
-                $message = sprintf(_m('%s is not subscribed to any searches.'), $this->user->nickname);
+                $message = sprintf(_m('%s is not subscribed to any searches.'), $this->getTarget()->getNickname());
             }
         }
         else {
             // TRANS: Subscription list text when looking at the subscriptions for a of a user that has none
             // TRANS: as an anonymous user. %s is the user nickname.
-            $message = sprintf(_m('%s is not subscribed to any searches.'), $this->user->nickname);
+            $message = sprintf(_m('%s is not subscribed to any searches.'), $this->getTarget()->getNickname());
         }
 
         $this->elementStart('div', 'guide');
index fa5b34942b00694183806c8ef8202636b2692207..434ed8982c838d2cd2b59f8567c51d80eae2cffc 100644 (file)
@@ -86,7 +86,7 @@ class SearchSubMenu extends MoreMenu
         return $items;
     } 
 
-    function item($actionName, $args, $label, $description, $id=null, $cls=null)
+    function item($actionName, array $args, $label, $description, $id=null, $cls=null)
     {
         if (empty($id)) {
             $id = $this->menuItemID($actionName, $args);
index b5a49fe4fadb84846ef0968e46c01e3e60bede6e..1bfc848ebbbbda41686d1d7a2f10ab23ea103b99 100644 (file)
@@ -25,7 +25,7 @@
  * @link      http://status.net/
  */
 
-if (!defined('GNUSOCIAL') && !defined('STATUSNET')) { exit(1); }
+if (!defined('GNUSOCIAL')) { exit(1); }
 
 class MirrorSettingsAction extends SettingsAction
 {
@@ -62,9 +62,8 @@ class MirrorSettingsAction extends SettingsAction
      */
     function showContent()
     {
-        $user = common_current_user();
         $provider = $this->trimmed('provider');
-        if ($provider) {
+        if (!empty($provider) || GNUsocial::isAjax()) {
             $this->showAddFeedForm($provider);
         } else {
             $this->elementStart('div', array('id' => 'add-mirror'));
@@ -72,7 +71,7 @@ class MirrorSettingsAction extends SettingsAction
             $this->elementEnd('div');
 
             $mirror = new SubMirror();
-            $mirror->subscriber = $user->id;
+            $mirror->subscriber = $this->scoped->getID();
             if ($mirror->find()) {
                 while ($mirror->fetch()) {
                     $this->showFeedForm($mirror);
@@ -87,13 +86,11 @@ class MirrorSettingsAction extends SettingsAction
         $form->show();
     }
 
-    function showFeedForm($mirror)
+    function showFeedForm(SubMirror $mirror)
     {
-        $profile = Profile::getKV('id', $mirror->subscribed);
-        if ($profile) {
-            $form = new EditMirrorForm($this, $profile);
-            $form->show();
-        }
+        $profile = Profile::getByID($mirror->subscribed);
+        $form = new EditMirrorForm($this, $profile);
+        $form->show();
     }
 
     function showAddFeedForm()
@@ -112,41 +109,6 @@ class MirrorSettingsAction extends SettingsAction
         $form->show();
     }
 
-    /**
-     *
-     * @param array $args
-     *
-     * @todo move the ajax display handling to common code
-     */
-    function handle($args)
-    {
-        if ($this->boolean('ajax')) {
-            $this->startHTML('text/xml;charset=utf-8');
-            $this->elementStart('head');
-            // TRANS: Title for page with form to add a mirror feed provider on.
-            $this->element('title', null, _m('Provider add'));
-            $this->elementEnd('head');
-            $this->elementStart('body');
-
-            $this->showAddFeedForm();
-
-            $this->elementEnd('body');
-            $this->endHTML();
-        } else {
-            return parent::handle($args);
-        }
-    }
-    /**
-     * Handle a POST request
-     *
-     * Muxes to different sub-functions based on which button was pushed
-     *
-     * @return void
-     */
-    function handlePost()
-    {
-    }
-
     /**
      * Show the local navigation menu
      *
index be195250f679027c715177dc6e1dc9c8cd0fe617..1e927b4fd175437133808b33fd04dd1885073366 100644 (file)
@@ -28,9 +28,7 @@
  * @link      http://status.net/
  */
 
-if (!defined('STATUSNET') && !defined('LACONICA')) {
-    exit(1);
-}
+if (!defined('GNUSOCIAL')) { exit(1); }
 
 /**
  * A list of the user's subscriptions
@@ -48,20 +46,19 @@ class TagSubsAction extends GalleryAction
         if ($this->page == 1) {
             // TRANS: Header for subscriptions overview for a user (first page).
             // TRANS: %s is a user nickname.
-            return sprintf(_m('%s\'s tag subscriptions'), $this->user->nickname);
+            return sprintf(_m('%s\'s tag subscriptions'), $this->getTarget()->getNickname());
         } else {
             // TRANS: Header for subscriptions overview for a user (not first page).
             // TRANS: %1$s is a user nickname, %2$d is the page number.
             return sprintf(_m('%1$s\'s tag subscriptions, page %2$d'),
-                           $this->user->nickname,
+                           $this->getTarget()->getNickname(),
                            $this->page);
         }
     }
 
     function showPageNotice()
     {
-        $user = common_current_user();
-        if ($user && ($user->id == $this->profile->id)) {
+        if ($this->scoped instanceof Profile && $this->scoped->sameAs($this->getTarget())) {
             $this->element('p', null,
                            // TRANS: Page notice for page with an overview of all tag subscriptions
                            // TRANS: of the logged in user's own profile.
@@ -71,7 +68,7 @@ class TagSubsAction extends GalleryAction
                            // TRANS: Page notice for page with an overview of all subscriptions of a user other
                            // TRANS: than the logged in user. %s is the user nickname.
                            sprintf(_m('%s has subscribed to receive all notices on this site containing the following tags:'),
-                                   $this->profile->nickname));
+                                   $this->getTarget()->getNickname()));
         }
     }
 
@@ -86,12 +83,12 @@ class TagSubsAction extends GalleryAction
             $cnt = 0;
 
             $tagsub = new TagSub();
-            $tagsub->profile_id = $this->user->id;
+            $tagsub->profile_id = $this->getTarget()->getID();
             $tagsub->limit($limit, $offset);
             $tagsub->find();
 
             if ($tagsub->N) {
-                $list = new TagSubscriptionsList($tagsub, $this->user, $this);
+                $list = new TagSubscriptionsList($tagsub, $this->getTarget(), $this);
                 $cnt = $list->show();
                 if (0 == $cnt) {
                     $this->showEmptyListMessage();
@@ -102,7 +99,7 @@ class TagSubsAction extends GalleryAction
 
             $this->pagination($this->page > 1, $cnt > PROFILES_PER_PAGE,
                               $this->page, 'tagsubs',
-                              array('nickname' => $this->user->nickname));
+                              array('nickname' => $this->getTarget()->getNickname()));
 
 
             Event::handle('EndShowTagSubscriptionsContent', array($this));
@@ -112,8 +109,7 @@ class TagSubsAction extends GalleryAction
     function showEmptyListMessage()
     {
         if (common_logged_in()) {
-            $current_user = common_current_user();
-            if ($this->user->id === $current_user->id) {
+            if ($this->scoped->sameAs($this->getTarget())) {
                 // TRANS: Tag subscription list text when the logged in user has no tag subscriptions.
                 $message = _m('You are not listening to any hash tags right now. You can push the "Subscribe" button ' .
                               'on any hashtag page to automatically receive any public messages on this site that use that ' .
@@ -121,13 +117,13 @@ class TagSubsAction extends GalleryAction
             } else {
                 // TRANS: Tag subscription list text when looking at the subscriptions for a of a user other
                 // TRANS: than the logged in user that has no tag subscriptions. %s is the user nickname.
-                $message = sprintf(_m('%s is not following any tags.'), $this->user->nickname);
+                $message = sprintf(_m('%s is not following any tags.'), $this->getTarget()->getNickname());
             }
         }
         else {
             // TRANS: Subscription list text when looking at the subscriptions for a of a user that has none
             // TRANS: as an anonymous user. %s is the user nickname.
-            $message = sprintf(_m('%s is not following any tags.'), $this->user->nickname);
+            $message = sprintf(_m('%s is not following any tags.'), $this->getTarget()->getNickname());
         }
 
         $this->elementStart('div', 'guide');
index 9b129ea21be69067f84d50ad20ec96bc1d740eae..dd3007e309400a3b3456e7b9255034830e9f65db 100644 (file)
@@ -26,9 +26,7 @@
  * @link      http://status.net/
  */
 
-if (!defined('STATUSNET')) {
-    exit(1);
-}
+if (!defined('GNUSOCIAL')) { exit(1); }
 
 require_once __DIR__ . '/twitter.php';
 
@@ -387,12 +385,11 @@ class TwitterBridgePlugin extends Plugin
     {
         $n2s = Notice_to_status::getKV('notice_id', $notice->id);
 
-        if (!empty($n2s)) {
-
-            $flink = Foreign_link::getByUserID($notice->profile_id,
-                                               TWITTER_SERVICE); // twitter service
+        if ($n2s instanceof Notice_to_status) {
 
-            if (empty($flink)) {
+            try {
+                $flink = Foreign_link::getByUserID($notice->profile_id, TWITTER_SERVICE); // twitter service
+            } catch (NoResultException $e) {
                 return true;
             }
 
@@ -424,15 +421,14 @@ class TwitterBridgePlugin extends Plugin
      */
     function onEndFavorNotice(Profile $profile, Notice $notice)
     {
-        $flink = Foreign_link::getByUserID($profile->id,
-                                           TWITTER_SERVICE); // twitter service
-
-        if (empty($flink)) {
+        try {
+            $flink = Foreign_link::getByUserID($profile->getID(), TWITTER_SERVICE); // twitter service
+        } catch (NoResultException $e) {
             return true;
         }
 
         if (!TwitterOAuthClient::isPackedToken($flink->credentials)) {
-            $this->log(LOG_INFO, "Skipping fave processing for {$profile->id} since link is not OAuth.");
+            $this->log(LOG_INFO, "Skipping fave processing for {$profile->getID()} since link is not OAuth.");
             return true;
         }
 
@@ -464,10 +460,9 @@ class TwitterBridgePlugin extends Plugin
      */
     function onEndDisfavorNotice(Profile $profile, Notice $notice)
     {
-        $flink = Foreign_link::getByUserID($profile->id,
-                                           TWITTER_SERVICE); // twitter service
-
-        if (empty($flink)) {
+        try {
+            $flink = Foreign_link::getByUserID($profile->getID(), TWITTER_SERVICE); // twitter service
+        } catch (NoResultException $e) {
             return true;
         }
 
@@ -516,16 +511,15 @@ class TwitterBridgePlugin extends Plugin
     {
         $fuser = null;
 
-        $flink = Foreign_link::getByUserID($profile->id, TWITTER_SERVICE);
-
-        if (!empty($flink)) {
+        try {
+            $flink = Foreign_link::getByUserID($profile->id, TWITTER_SERVICE);
             $fuser = $flink->getForeignUser();
 
-            if (!empty($fuser)) {
-                $links[] = array("href" => $fuser->uri,
-                                 "text" => sprintf(_("@%s on Twitter"), $fuser->nickname),
-                                 "image" => $this->path("icons/twitter-bird-white-on-blue.png"));
-            }
+            $links[] = array("href" => $fuser->uri,
+                             "text" => sprintf(_("@%s on Twitter"), $fuser->nickname),
+                             "image" => $this->path("icons/twitter-bird-white-on-blue.png"));
+        } catch (NoResultException $e) {
+            // no foreign link and/or user for Twitter on this profile ID
         }
 
         return true;
@@ -569,16 +563,17 @@ class TwitterBridgePlugin extends Plugin
                 if( count($noticeArray) != 1 ) { break; }
                 $post = $noticeArray[0];
 
-                $flink = Foreign_link::getByUserID($post->profile_id, TWITTER_SERVICE);
-                if( $flink ) { // Our local user has registered Twitter Gateway
+                try {
+                    $flink = Foreign_link::getByUserID($post->profile_id, TWITTER_SERVICE);
                     $fuser = Foreign_user::getForeignUser($flink->foreign_id, TWITTER_SERVICE);
-                    if( $fuser ) { // Got nickname for local user's Twitter account
-                        $action->element('meta', array('name'    => 'twitter:creator',
-                                                     'content' => '@'.$fuser->nickname));
-                    }
+                    $action->element('meta', array('name'    => 'twitter:creator',
+                                                   'content' => '@'.$fuser->nickname));
+                } catch (NoResultException $e) {
+                    // no foreign link and/or user for Twitter on this profile ID
                 }
                 break;
-            default: break;
+            default:
+                break;
         }
 
         return true;
index ae293edcf7942db0fe403c62449b3aaa6dfc662c..c9b892b6408d74ec5b388cf0333704c92699dfae 100644 (file)
  * @link      http://status.net/
  */
 
-if (!defined('GNUSOCIAL') && !defined('STATUSNET')) { exit(1); }
+if (!defined('GNUSOCIAL')) { exit(1); }
 
 require_once dirname(__DIR__) . '/twitter.php';
+require_once INSTALLDIR . '/lib/oauthclient.php';
 
 /**
  * Class for doing OAuth authentication against Twitter
@@ -48,127 +49,81 @@ require_once dirname(__DIR__) . '/twitter.php';
  * @link     http://status.net/
  *
  */
-class TwitterauthorizationAction extends Action
+class TwitterauthorizationAction extends FormAction
 {
     var $twuid        = null;
     var $tw_fields    = null;
     var $access_token = null;
-    var $signin       = null;
     var $verifier     = null;
 
-    /**
-     * Initialize class members. Looks for 'oauth_token' parameter.
-     *
-     * @param array $args misc. arguments
-     *
-     * @return boolean true
-     */
-    function prepare($args)
-    {
-        parent::prepare($args);
+    protected $needLogin = false;   // authorization page can also be used to create a new user
 
-        $this->signin      = $this->boolean('signin');
+    protected function doPreparation()
+    {
         $this->oauth_token = $this->arg('oauth_token');
         $this->verifier    = $this->arg('oauth_verifier');
 
-        return true;
-    }
-
-    /**
-     * Handler method
-     *
-     * @param array $args is ignored since it's now passed in in prepare()
-     *
-     * @return nothing
-     */
-    function handle($args)
-    {
-        parent::handle($args);
-
-        if (common_logged_in()) {
-            $user  = common_current_user();
-            $flink = Foreign_link::getByUserID($user->id, TWITTER_SERVICE);
+        if ($this->scoped instanceof Profile) {
+            try {
+                $flink = Foreign_link::getByUserID($this->scoped->getID(), TWITTER_SERVICE);
+                $fuser = $flink->getForeignUser();
 
-            // If there's already a foreign link record and a foreign user
-            // it means the accounts are already linked, and this is unecessary.
-            // So go back.
+                // If there's already a foreign link record and a foreign user
+                // (no exceptions were thrown when fetching either of them...)
+                // it means the accounts are already linked, and this is unecessary.
+                // So go back.
 
-            if (isset($flink)) {
-                $fuser = $flink->getForeignUser();
-                if (!empty($fuser)) {
-                    common_redirect(common_local_url('twittersettings'));
-                }
+                common_redirect(common_local_url('twittersettings'));
+            } catch (NoResultException $e) {
+                // but if we don't have a foreign user linked, let's continue authorization procedure.                
             }
         }
+    }
 
-        if ($_SERVER['REQUEST_METHOD'] == 'POST') {
-
-            // User was not logged in to StatusNet before
-
-            $this->twuid = $this->trimmed('twuid');
-
-            $this->tw_fields = array('screen_name' => $this->trimmed('tw_fields_screen_name'),
-                                     'fullname' => $this->trimmed('tw_fields_fullname'));
+    protected function doPost()
+    {
+        // User was not logged in to StatusNet before
 
-            $this->access_token = new OAuthToken($this->trimmed('access_token_key'), $this->trimmed('access_token_secret'));
+        $this->twuid = $this->trimmed('twuid');
 
-            $token = $this->trimmed('token');
+        $this->tw_fields = array('screen_name' => $this->trimmed('tw_fields_screen_name'),
+                                 'fullname' => $this->trimmed('tw_fields_fullname'));
 
-            if (!$token || $token != common_session_token()) {
-                // TRANS: Client error displayed when the session token does not match or is not given.
-                $this->showForm(_m('There was a problem with your session token. Try again, please.'));
-                return;
-            }
+        $this->access_token = new OAuthToken($this->trimmed('access_token_key'), $this->trimmed('access_token_secret'));
 
-            if ($this->arg('create')) {
-                if (!$this->boolean('license')) {
-                    // TRANS: Form validation error displayed when the checkbox to agree to the license has not been checked.
-                    $this->showForm(_m('You cannot register if you do not agree to the license.'),
-                                    $this->trimmed('newname'));
-                    return;
-                }
-                $this->createNewUser();
-            } else if ($this->arg('connect')) {
-                $this->connectNewUser();
-            } else {
-                common_debug('Twitter bridge - ' . print_r($this->args, true));
-                // TRANS: Form validation error displayed when an unhandled error occurs.
-                $this->showForm(_m('Something weird happened.'),
-                                $this->trimmed('newname'));
-            }
-        } else {
-            // $this->oauth_token is only populated once Twitter authorizes our
-            // request token. If it's empty we're at the beginning of the auth
-            // process
-
-            if (empty($this->oauth_token)) {
-                $this->authorizeRequestToken();
-            } else {
-                $this->saveAccessToken();
+        if ($this->arg('create')) {
+            common_debug('TwitterBridgeDebug - POST with create');
+            if (!$this->boolean('license')) {
+                // TRANS: Form validation error displayed when the checkbox to agree to the license has not been checked.
+                throw new ClientException(_m('You cannot register if you do not agree to the license.'));
             }
+            return $this->createNewUser();
+        } elseif ($this->arg('connect')) {
+            common_debug('TwitterBridgeDebug - POST with connect');
+            return $this->connectNewUser();
         }
+
+        common_debug('TwitterBridgeDebug - ' . print_r($this->args, true));
+        // TRANS: Form validation error displayed when an unhandled error occurs.
+        throw new ClientException(_m('No known action for POST.'));
     }
 
     /**
      * Asks Twitter for a request token, and then redirects to Twitter
      * to authorize it.
-     *
-     * @return nothing
      */
-    function authorizeRequestToken()
+    protected function authorizeRequestToken()
     {
         try {
             // Get a new request token and authorize it
-
             $client  = new TwitterOAuthClient();
-            $req_tok = $client->getRequestToken();
+            $req_tok = $client->getTwitterRequestToken();
 
             // Sock the request token away in the session temporarily
-
             $_SESSION['twitter_request_token']        = $req_tok->key;
             $_SESSION['twitter_request_token_secret'] = $req_tok->secret;
 
-            $auth_link = $client->getAuthorizeLink($req_tok, $this->signin);
+            $auth_link = $client->getTwitterAuthorizeLink($req_tok, $this->boolean('signin'));
         } catch (OAuthClientException $e) {
             $msg = sprintf(
                 'OAuth client error - code: %1s, msg: %2s',
@@ -176,10 +131,8 @@ class TwitterauthorizationAction extends Action
                 $e->getMessage()
             );
             common_log(LOG_INFO, 'Twitter bridge - ' . $msg);
-            $this->serverError(
-                // TRANS: Server error displayed when linking to a Twitter account fails.
-                _m('Could not link your Twitter account.')
-            );
+            // TRANS: Server error displayed when linking to a Twitter account fails.
+            throw new ServerException(_m('Could not link your Twitter account.'));
         }
 
         common_redirect($auth_link);
@@ -197,25 +150,19 @@ class TwitterauthorizationAction extends Action
         // token we sent them
 
         if ($_SESSION['twitter_request_token'] != $this->oauth_token) {
-            $this->serverError(
-                // TRANS: Server error displayed when linking to a Twitter account fails because of an incorrect oauth_token.
-                _m('Could not link your Twitter account: oauth_token mismatch.')
-            );
+            // TRANS: Server error displayed when linking to a Twitter account fails because of an incorrect oauth_token.
+            throw new ServerException(_m('Could not link your Twitter account: oauth_token mismatch.'));
         }
 
         $twitter_user = null;
 
         try {
-
-            $client = new TwitterOAuthClient($_SESSION['twitter_request_token'],
-                $_SESSION['twitter_request_token_secret']);
+            $client = new TwitterOAuthClient($_SESSION['twitter_request_token'], $_SESSION['twitter_request_token_secret']);
 
             // Exchange the request token for an access token
-
-            $atok = $client->getAccessToken($this->verifier);
+            $atok = $client->getTwitterAccessToken($this->verifier);
 
             // Test the access token and get the user's Twitter info
-
             $client       = new TwitterOAuthClient($atok->key, $atok->secret);
             $twitter_user = $client->verifyCredentials();
 
@@ -226,17 +173,14 @@ class TwitterauthorizationAction extends Action
                 $e->getMessage()
             );
             common_log(LOG_INFO, 'Twitter bridge - ' . $msg);
-            $this->serverError(
-                // TRANS: Server error displayed when linking to a Twitter account fails.
-                _m('Could not link your Twitter account.')
-            );
+            // TRANS: Server error displayed when linking to a Twitter account fails.
+            throw new ServerException(_m('Could not link your Twitter account.'));
         }
 
-        if (common_logged_in()) {
+        if ($this->scoped instanceof Profile) {
             // Save the access token and Twitter user info
 
-            $user = common_current_user();
-            $this->saveForeignLink($user->id, $twitter_user->id, $atok);
+            $this->saveForeignLink($this->scoped->getID(), $twitter_user->id, $atok);
             save_twitter_user($twitter_user->id, $twitter_user->screen_name);
 
         } else {
@@ -245,7 +189,7 @@ class TwitterauthorizationAction extends Action
             $this->tw_fields = array("screen_name" => $twitter_user->screen_name,
                                      "fullname" => $twitter_user->name);
             $this->access_token = $atok;
-            $this->tryLogin();
+            return $this->tryLogin();
         }
 
         // Clean up the the mess we made in the session
@@ -297,24 +241,20 @@ class TwitterauthorizationAction extends Action
 
         $flink_id = $flink->insert();
 
+        // We want to make sure we got a numerical >0 value, not just failed the insert (which would be === false)
         if (empty($flink_id)) {
             common_log_db_error($flink, 'INSERT', __FILE__);
             // TRANS: Server error displayed when linking to a Twitter account fails.
-            $this->serverError(_m('Could not link your Twitter account.'));
+            throw new ServerException(_m('Could not link your Twitter account.'));
         }
 
         return $flink_id;
     }
 
-    function showPageNotice()
+    function getInstructions()
     {
-        if ($this->error) {
-            $this->element('div', array('class' => 'error'), $this->error);
-        } else {
-            $this->element('div', 'instructions',
-                           // TRANS: Page instruction. %s is the StatusNet sitename.
-                           sprintf(_m('This is the first time you have logged into %s so we must connect your Twitter account to a local account. You can either create a new account, or connect with your existing account, if you have one.'), common_config('site', 'name')));
-        }
+        // TRANS: Page instruction. %s is the StatusNet sitename.
+        return sprintf(_m('This is the first time you have logged into %s so we must connect your Twitter account to a local account. You can either create a new account, or connect with your existing account, if you have one.'), common_config('site', 'name'));
     }
 
     function title()
@@ -323,16 +263,20 @@ class TwitterauthorizationAction extends Action
         return _m('Twitter Account Setup');
     }
 
-    function showForm($error=null, $username=null)
+    public function showPage()
     {
-        $this->error = $error;
-        $this->username = $username;
-
-        $this->showPage();
-    }
+        // $this->oauth_token is only populated once Twitter authorizes our
+        // request token. If it's empty we're at the beginning of the auth
+        // process
+        if (empty($this->error)) {
+            if (empty($this->oauth_token)) {
+                // authorizeRequestToken either throws an exception or redirects
+                $this->authorizeRequestToken();
+            } else {
+                $this->saveAccessToken();
+            }
+        }
 
-    function showPage()
-    {
         parent::showPage();
     }
 
@@ -343,11 +287,6 @@ class TwitterauthorizationAction extends Action
      */
     function showContent()
     {
-        if (!empty($this->message_text)) {
-            $this->element('p', null, $this->message);
-            return;
-        }
-
         $this->elementStart('form', array('method' => 'post',
                                           'id' => 'form_settings_twitter_connect',
                                           'class' => 'form_settings',
@@ -363,8 +302,8 @@ class TwitterauthorizationAction extends Action
         $this->hidden('tw_fields_name', $this->tw_fields['fullname']);
         $this->hidden('token', common_session_token());
 
-        // Don't allow new account creation if site is flagged as invite only
-       if (common_config('site', 'inviteonly') == false) {
+        // Only allow new account creation if site is not flagged invite-only
+        if (!common_config('site', 'inviteonly')) {
             $this->elementStart('fieldset');
             $this->element('legend', null,
                            // TRANS: Fieldset legend.
@@ -380,7 +319,7 @@ class TwitterauthorizationAction extends Action
             $this->elementStart('li');
             // TRANS: Field label.
             $this->input('newname', _m('New nickname'),
-                         ($this->username) ? $this->username : '',
+                         $this->username ?: '',
                          // TRANS: Field title for nickname field.
                          _m('1-64 lowercase letters or numbers, no punctuation or spaces.'));
             $this->elementEnd('li');
@@ -479,46 +418,43 @@ class TwitterauthorizationAction extends Action
         return '';
     }
 
-    function message($msg)
-    {
-        $this->message_text = $msg;
-        $this->showPage();
-    }
-
-    function createNewUser()
+    protected function createNewUser()
     {
+        common_debug('TwitterBridgeDebug - createNewUser');
         if (!Event::handle('StartRegistrationTry', array($this))) {
-            return;
+            common_debug('TwitterBridgeDebug - StartRegistrationTry failed');
+            // TRANS: Client error displayed when trying to create a new user but a plugin aborted the process.
+            throw new ClientException(_m('Registration of new user was aborted, maybe you failed a captcha?'));
         }
 
         if (common_config('site', 'closed')) {
+            common_debug('TwitterBridgeDebug - site is closed for registrations');
             // TRANS: Client error displayed when trying to create a new user while creating new users is not allowed.
-            $this->clientError(_m('Registration not allowed.'));
+            throw new ClientException(_m('Registration not allowed.'));
         }
 
         $invite = null;
 
         if (common_config('site', 'inviteonly')) {
+            common_debug('TwitterBridgeDebug - site is inviteonly');
             $code = $_SESSION['invitecode'];
             if (empty($code)) {
                 // TRANS: Client error displayed when trying to create a new user while creating new users is not allowed.
-                $this->clientError(_m('Registration not allowed.'));
+                throw new ClientException(_m('Registration not allowed.'));
             }
 
-            $invite = Invitation::getKV($code);
+            $invite = Invitation::getKV('code', $code);
 
-            if (empty($invite)) {
+            if (!$invite instanceof Invite) {
+                common_debug('TwitterBridgeDebug - and we failed the invite code test');
                 // TRANS: Client error displayed when trying to create a new user with an invalid invitation code.
-                $this->clientError(_m('Not a valid invitation code.'));
+                throw new ClientException(_m('Not a valid invitation code.'));
             }
         }
 
-        try {
-            $nickname = Nickname::normalize($this->trimmed('newname'), true);
-        } catch (NicknameException $e) {
-            $this->showForm($e->getMessage());
-            return;
-        }
+        common_debug('TwitterBridgeDebug - trying our nickname: '.$this->trimmed('newname'));
+        // Nickname::normalize throws exception if the nickname is taken
+        $nickname = Nickname::normalize($this->trimmed('newname'), true);
 
         $fullname = trim($this->tw_fields['fullname']);
 
@@ -533,22 +469,17 @@ class TwitterauthorizationAction extends Action
             $args['email'] = $email;
         }
 
-        try {
-            $user = User::register($args);
-        } catch (Exception $e) {
-            $this->serverError($e->getMessage());
-        }
+        common_debug('TwitterBridgeDebug - registering user with args:'.var_export($args,true));
+        $user = User::register($args);
 
-        $result = $this->saveForeignLink($user->id,
-                                         $this->twuid,
-                                         $this->access_token);
+        common_debug('TwitterBridgeDebug - registered the user and saving foreign link for '.$user->id);
 
-        save_twitter_user($this->twuid, $this->tw_fields['screen_name']);
+        $this->saveForeignLink($user->id,
+                               $this->twuid,
+                               $this->access_token);
 
-        if (!$result) {
-            // TRANS: Server error displayed when connecting a user to a Twitter user has failed.
-            $this->serverError(_m('Error connecting user to Twitter.'));
-        }
+        common_debug('TwitterBridgeDebug - saving twitter user after creating new local user '.$user->id);
+        save_twitter_user($this->twuid, $this->tw_fields['screen_name']);
 
         common_set_user($user);
         common_real_login(true);
@@ -569,28 +500,23 @@ class TwitterauthorizationAction extends Action
         if (!common_check_user($nickname, $password)) {
             // TRANS: Form validation error displayed when connecting an existing user to a Twitter user fails because
             // TRANS: the provided username and/or password are incorrect.
-            $this->showForm(_m('Invalid username or password.'));
-            return;
+            throw new ClientException(_m('Invalid username or password.'));
         }
 
         $user = User::getKV('nickname', $nickname);
 
-        if (!empty($user)) {
+        if ($user instanceof User) {
             common_debug('TwitterBridge Plugin - ' .
                          "Legit user to connect to Twitter: $nickname");
         }
 
-        $result = $this->saveForeignLink($user->id,
-                                         $this->twuid,
-                                         $this->access_token);
+        // throws exception on failure
+        $this->saveForeignLink($user->id,
+                               $this->twuid,
+                               $this->access_token);
 
         save_twitter_user($this->twuid, $this->tw_fields['screen_name']);
 
-        if (!$result) {
-            // TRANS: Server error displayed connecting a user to a Twitter user has failed.
-            $this->serverError(_m('Error connecting user to Twitter.'));
-        }
-
         common_debug('TwitterBridge Plugin - ' .
                      "Connected Twitter user $this->twuid to local user $user->id");
 
@@ -618,34 +544,30 @@ class TwitterauthorizationAction extends Action
         common_redirect(common_local_url('twittersettings'), 303);
     }
 
-    function tryLogin()
+    protected function tryLogin()
     {
         common_debug('TwitterBridge Plugin - ' .
                      "Trying login for Twitter user $this->twuid.");
 
-        $flink = Foreign_link::getByForeignID($this->twuid,
-                                              TWITTER_SERVICE);
-
-        if (!empty($flink)) {
+        try {
+            $flink = Foreign_link::getByForeignID($this->twuid, TWITTER_SERVICE);
             $user = $flink->getUser();
 
-            if (!empty($user)) {
-
-                common_debug('TwitterBridge Plugin - ' .
-                             "Logged in Twitter user $flink->foreign_id as user $user->id ($user->nickname)");
-
-                common_set_user($user);
-                common_real_login(true);
-                $this->goHome($user->nickname);
-            }
-
-        } else {
-
             common_debug('TwitterBridge Plugin - ' .
-                         "No flink found for twuid: $this->twuid - new user");
-
-            $this->showForm(null, $this->bestNewNickname());
+                         "Logged in Twitter user $flink->foreign_id as user $user->id ($user->nickname)");
+
+            common_set_user($user);
+            common_real_login(true);
+            $this->goHome($user->nickname);
+        } catch (NoResultException $e) {
+            // Either no Foreign_link was found or not the user connected to it.
+            // Let's just continue to allow creating or logging in as a new user.
         }
+        common_debug("TwitterBridge Plugin - No flink found for twuid: {$this->twuid} - new user");
+
+        // FIXME: what do we want to do here? I forgot
+        return;
+        throw new ServerException(_m('No foreign link found for Twitter user'));
     }
 
     function goHome($nickname)
index ee00714c9f18f14f9adfb369da93b4b5cd6921b5..f4af7d577d754e789cad215d9ec09053b37652e9 100644 (file)
@@ -28,9 +28,7 @@
  * @link      http://status.net/
  */
 
-if (!defined('STATUSNET') && !defined('LACONICA')) {
-    exit(1);
-}
+if (!defined('GNUSOCIAL')) { exit(1); }
 
 require_once dirname(__DIR__) . '/twitter.php';
 
@@ -46,20 +44,8 @@ require_once dirname(__DIR__) . '/twitter.php';
  *
  * @see      SettingsAction
  */
-class TwitterloginAction extends Action
+class TwitterloginAction extends LoginAction
 {
-    function handle($args)
-    {
-        parent::handle($args);
-
-        if (common_is_real_login()) {
-            // TRANS: Client error displayed when trying to log in using Twitter while already logged in to StatusNet.
-            $this->clientError(_m('Already logged in.'));
-        }
-
-        $this->showPage();
-    }
-
     function title()
     {
         // TRANS: Title for login using Twitter page.
@@ -72,15 +58,6 @@ class TwitterloginAction extends Action
         return _m('Login with your Twitter account');
     }
 
-    function showPageNotice()
-    {
-        $instr = $this->getInstructions();
-        $output = common_markup_to_html($instr);
-        $this->elementStart('div', 'instructions');
-        $this->raw($output);
-        $this->elementEnd('div');
-    }
-
     function showContent()
     {
         $this->elementStart('a', array('href' => common_local_url('twitterauthorization',
index 37abb4d27297281e501313ab17a147d0fe246d45..ccdb44fcb9869fa524acdbf5ce8cd741bd196a08 100644 (file)
@@ -27,9 +27,7 @@
  * @link      http://status.net/
  */
 
-if (!defined('STATUSNET') && !defined('LACONICA')) {
-    exit(1);
-}
+if (!defined('GNUSOCIAL')) { exit(1); }
 
 require_once dirname(__DIR__) . '/twitter.php';
 
@@ -46,6 +44,18 @@ require_once dirname(__DIR__) . '/twitter.php';
  */
 class TwittersettingsAction extends ProfileSettingsAction
 {
+    protected $flink = null;
+    protected $fuser = null;
+
+    protected function doPreparation()
+    {
+        try {
+            $this->flink = Foreign_link::getByUserID($this->scoped->getID(), TWITTER_SERVICE);
+            $this->fuser = $this->flink->getForeignUser();
+        } catch (NoResultException $e) {
+            // No foreign link found for this user!
+        }
+    }
     /**
      * Title of the page
      *
@@ -81,19 +91,6 @@ class TwittersettingsAction extends ProfileSettingsAction
      */
     function showContent()
     {
-
-        $user = common_current_user();
-
-        $profile = $user->getProfile();
-
-        $fuser = null;
-
-        $flink = Foreign_link::getByUserID($user->id, TWITTER_SERVICE);
-
-        if (!empty($flink)) {
-            $fuser = $flink->getForeignUser();
-        }
-
         $this->elementStart('form', array('method' => 'post',
                                           'id' => 'form_settings_twitter',
                                           'class' => 'form_settings',
@@ -104,21 +101,11 @@ class TwittersettingsAction extends ProfileSettingsAction
 
         $this->elementStart('fieldset', array('id' => 'settings_twitter_account'));
 
-        if (empty($fuser)) {
-            $this->elementStart('ul', 'form_data');
-            $this->elementStart('li', array('id' => 'settings_twitter_login_button'));
-            $this->element('a', array('href' => common_local_url('twitterauthorization')),
-                           // TRANS: Link description to connect to a Twitter account.
-                           'Connect my Twitter account');
-            $this->elementEnd('li');
-            $this->elementEnd('ul');
-
-            $this->elementEnd('fieldset');
-        } else {
+        if ($this->fuser instanceof Foreign_user) {
             // TRANS: Fieldset legend.
             $this->element('legend', null, _m('Twitter account'));
             $this->elementStart('p', array('id' => 'form_confirmed'));
-            $this->element('a', array('href' => $fuser->uri), $fuser->nickname);
+            $this->element('a', array('href' => $this->fuser->uri), $this->fuser->nickname);
             $this->elementEnd('p');
             $this->element('p', 'form_note',
                            // TRANS: Form note when a Twitter account has been connected.
@@ -130,7 +117,7 @@ class TwittersettingsAction extends ProfileSettingsAction
             // TRANS: Fieldset legend.
             $this->element('legend', null, _m('Disconnect my account from Twitter'));
 
-            if (!$user->password) {
+            if (!$this->scoped->hasPassword()) {
                 $this->elementStart('p', array('class' => 'form_guide'));
                 // TRANS: Form guide. %s is a URL to the password settings.
                 // TRANS: This message contains a Markdown link in the form [description](link).
@@ -165,25 +152,19 @@ class TwittersettingsAction extends ProfileSettingsAction
             $this->checkbox('noticesend',
                             // TRANS: Checkbox label.
                             _m('Automatically send my notices to Twitter.'),
-                            ($flink) ?
-                            ($flink->noticesync & FOREIGN_NOTICE_SEND) :
-                            true);
+                            $this->flink->noticesync & FOREIGN_NOTICE_SEND);
             $this->elementEnd('li');
             $this->elementStart('li');
             $this->checkbox('replysync',
                             // TRANS: Checkbox label.
                             _m('Send local "@" replies to Twitter.'),
-                            ($flink) ?
-                            ($flink->noticesync & FOREIGN_NOTICE_SEND_REPLY) :
-                            true);
+                            $this->flink->noticesync & FOREIGN_NOTICE_SEND_REPLY);
             $this->elementEnd('li');
             $this->elementStart('li');
             $this->checkbox('friendsync',
                             // TRANS: Checkbox label.
                             _m('Subscribe to my Twitter friends here.'),
-                            ($flink) ?
-                            ($flink->friendsync & FOREIGN_FRIEND_RECV) :
-                            false);
+                            $this->flink->friendsync & FOREIGN_FRIEND_RECV);
             $this->elementEnd('li');
 
             if (common_config('twitterimport','enabled')) {
@@ -191,31 +172,37 @@ class TwittersettingsAction extends ProfileSettingsAction
                 $this->checkbox('noticerecv',
                                 // TRANS: Checkbox label.
                                 _m('Import my friends timeline.'),
-                                ($flink) ?
-                                ($flink->noticesync & FOREIGN_NOTICE_RECV) :
-                                false);
+                                $this->flink->noticesync & FOREIGN_NOTICE_RECV);
                 $this->elementEnd('li');
             } else {
                 // preserve setting even if bidrection bridge toggled off
 
-                if ($flink && ($flink->noticesync & FOREIGN_NOTICE_RECV)) {
+                if ($this->flink->noticesync & FOREIGN_NOTICE_RECV) {
                     $this->hidden('noticerecv', true, 'noticerecv');
                 }
             }
 
             $this->elementEnd('ul');
 
-            if ($flink) {
+            if ($this->flink instanceof Foreign_link) {
                 // TRANS: Button text for saving Twitter integration settings.
                 $this->submit('save', _m('BUTTON','Save'));
             } else {
                 // TRANS: Button text for adding Twitter integration.
                 $this->submit('add', _m('BUTTON','Add'));
             }
-
-            $this->elementEnd('fieldset');
+        } else {
+            $this->elementStart('ul', 'form_data');
+            $this->elementStart('li', array('id' => 'settings_twitter_login_button'));
+            $this->element('a', array('href' => common_local_url('twitterauthorization')),
+                           // TRANS: Link description to connect to a Twitter account.
+                           'Connect my Twitter account');
+            $this->elementEnd('li');
+            $this->elementEnd('ul');
         }
 
+        $this->elementEnd('fieldset');
+
         $this->elementEnd('form');
     }
 
@@ -229,25 +216,15 @@ class TwittersettingsAction extends ProfileSettingsAction
      *
      * @return void
      */
-    function handlePost()
+    protected function doPost()
     {
-        // CSRF protection
-        $token = $this->trimmed('token');
-        if (!$token || $token != common_session_token()) {
-            // TRANS: Client error displayed when the session token does not match or is not given.
-            $this->showForm(_m('There was a problem with your session token. '.
-                               'Try again, please.'));
-            return;
-        }
-
         if ($this->arg('save')) {
-            $this->savePreferences();
+            return $this->savePreferences();
         } else if ($this->arg('disconnect')) {
-            $this->removeTwitterAccount();
-        } else {
-            // TRANS: Client error displayed when the submitted form contains unexpected data.
-            $this->showForm(_m('Unexpected form submission.'));
+            return $this->removeTwitterAccount();
         }
+        // TRANS: Client error displayed when the submitted form contains unexpected data.
+        throw new ClientException(_m('Unexpected form submission.'));
     }
 
     /**
@@ -255,26 +232,26 @@ class TwittersettingsAction extends ProfileSettingsAction
      *
      * @return void
      */
-    function removeTwitterAccount()
+    protected function removeTwitterAccount()
     {
-        $user = common_current_user();
-        $flink = Foreign_link::getByUserID($user->id, TWITTER_SERVICE);
-
-        if (empty($flink)) {
-            // TRANS: Client error displayed when trying to remove a connected Twitter account when there isn't one connected.
-            $this->clientError(_m('No Twitter connection to remove.'));
+        if (!$this->flink instanceof Foreign_link) {
+            // TRANS: Error message possibly displayed when trying to remove a connected Twitter account when there isn't one connected.
+            throw new AlreadyFulfilledException(_m('No Twitter connection to remove.'));
         }
 
-        $result = $flink->safeDelete();
+        $result = $this->flink->safeDelete();
 
-        if (empty($result)) {
-            common_log_db_error($flink, 'DELETE', __FILE__);
+        if ($result === false) {
+            common_log_db_error($this->flink, 'DELETE', __FILE__);
             // TRANS: Server error displayed when trying to remove a connected Twitter account fails.
-            $this->serverError(_m('Could not remove Twitter user.'));
+            throw new ServerException(_m('Could not remove Twitter user.'));
         }
 
+        $this->flink = null;
+        $this->fuser = null;
+
         // TRANS: Success message displayed after disconnecting a Twitter account.
-        $this->showForm(_m('Twitter account disconnected.'), true);
+        return _m('Twitter account disconnected.');
     }
 
     /**
@@ -282,43 +259,36 @@ class TwittersettingsAction extends ProfileSettingsAction
      *
      * @return void
      */
-    function savePreferences()
+    protected function savePreferences()
     {
         $noticesend = $this->boolean('noticesend');
         $noticerecv = $this->boolean('noticerecv');
         $friendsync = $this->boolean('friendsync');
         $replysync  = $this->boolean('replysync');
 
-        $user = common_current_user();
-        $flink = Foreign_link::getByUserID($user->id, TWITTER_SERVICE);
-
-        if (empty($flink)) {
-            common_log_db_error($flink, 'SELECT', __FILE__);
-            // @todo FIXME: Shouldn't this be a serverError()?
+        if (!$this->flink instanceof Foreign_link) {
+            common_log_db_error($this->flink, 'SELECT', __FILE__);
             // TRANS: Server error displayed when saving Twitter integration preferences fails.
-            $this->showForm(_m('Could not save Twitter preferences.'));
-            return;
+            throw new ServerException(_m('Your account is not linked to Twitter.'));
         }
 
-        $original = clone($flink);
+        $original = clone($this->flink);
         $wasReceiving = (bool)($original->noticesync & FOREIGN_NOTICE_RECV);
-        $flink->set_flags($noticesend, $noticerecv, $replysync, $friendsync);
-        $result = $flink->update($original);
+        $this->flink->set_flags($noticesend, $noticerecv, $replysync, $friendsync);
+        $result = $this->flink->update($original);
 
         if ($result === false) {
-            common_log_db_error($flink, 'UPDATE', __FILE__);
-            // @todo FIXME: Shouldn't this be a serverError()?
+            common_log_db_error($this->flink, 'UPDATE', __FILE__);
             // TRANS: Server error displayed when saving Twitter integration preferences fails.
-            $this->showForm(_m('Could not save Twitter preferences.'));
-            return;
+            throw new ServerException(_m('Could not save Twitter preferences.'));
         }
 
         if ($wasReceiving xor $noticerecv) {
-            $this->notifyDaemon($flink->foreign_id, $noticerecv);
+            $this->notifyDaemon($this->flink->foreign_id, $noticerecv);
         }
 
         // TRANS: Success message after saving Twitter integration preferences.
-        $this->showForm(_m('Twitter preferences saved.'), true);
+        return _m('Twitter preferences saved.');
     }
 
     /**
index a3862eedfde45e9fcd67da1aa4101cb71b8fd87a..9fa3b282b47ef8ba73e218707f20f6296ea9a38e 100755 (executable)
@@ -104,6 +104,7 @@ class SyncTwitterFriendsDaemon extends ParallelizingDaemon
         return $flinks;
     }
 
+    // FIXME: make it so we can force a Foreign_link here without colliding with parent
     function childTask($flink) {
         // Each child ps needs its own DB connection
 
@@ -124,7 +125,7 @@ class SyncTwitterFriendsDaemon extends ParallelizingDaemon
         unset($_DB_DATAOBJECT['CONNECTIONS']);
     }
 
-    function fetchTwitterFriends($flink)
+    function fetchTwitterFriends(Foreign_link $flink)
     {
         $friends = array();
 
@@ -192,8 +193,14 @@ class SyncTwitterFriendsDaemon extends ParallelizingDaemon
         return $friends;
     }
 
-    function subscribeTwitterFriends($flink)
+    function subscribeTwitterFriends(Foreign_link $flink)
     {
+        try {
+            $profile = $flink->getProfile();
+        } catch (NoResultException $e) {
+            common_log(LOG_WARNING, 'Foreign_link has no matching local profile for local ID: '.$flink->user_id);
+        }
+
         $friends = $this->fetchTwitterFriends($flink);
 
         if (empty($friends)) {
@@ -203,8 +210,6 @@ class SyncTwitterFriendsDaemon extends ParallelizingDaemon
             return false;
         }
 
-        $profile = $flink->getProfile();
-
         foreach ($friends as $friend) {
 
             $friend_name = $friend->screen_name;
@@ -219,31 +224,24 @@ class SyncTwitterFriendsDaemon extends ParallelizingDaemon
                 continue;
             }
 
-            // Check to see if there's a related local user
-
-            $friend_flink = Foreign_link::getByForeignID($friend_id,
-                                                         TWITTER_SERVICE);
-
-            if (!empty($friend_flink)) {
+            // Check to see if there's a related local user and try to subscribe
+            try {
+                $friend_flink = Foreign_link::getByForeignID($friend_id, TWITTER_SERVICE);
 
                 // Get associated user and subscribe her
-
-                $friend_profile = Profile::getKV('id', $friend_flink->user_id);
-
-                if ($friend_profile instanceof Profile) {
-                    try {
-                        $other = Profile::getKV('id', $invites->user_id);
-                        Subscription::start($profile, $friend_profile);
-                        common_log(LOG_INFO,
-                                   $this->name() . ' - Subscribed ' .
-                                   "{$friend_profile->nickname} to {$profile->nickname}.");
-                    } catch (Exception $e) {
-                        common_debug($this->name() .
-                                     ' - Tried and failed subscribing ' .
-                                     "{$friend_profile->nickname} to {$profile->nickname} - " .
-                                     $e->getMessage());
-                    }
-                }
+                $friend_profile = $friend_flink->getProfile();
+
+                Subscription::start($profile, $friend_profile);
+                common_log(LOG_INFO,
+                           $this->name() . ' - Subscribed ' .
+                           "{$friend_profile->nickname} to {$profile->nickname}.");
+            } catch (NoResultException $e) {
+                // either no foreign link for this friend's foreign ID or no profile found on local ID.
+            } catch (Exception $e) {
+                common_debug($this->name() .
+                             ' - Tried and failed subscribing ' .
+                             "{$friend_profile->nickname} to {$profile->nickname} - " .
+                             $e->getMessage());
             }
         }
 
index d444b8aa5dd70cd3f5c66ae090ad3d0ff33edaa3..83e8a0df5e57350503478530a1759c898a0e24c1 100755 (executable)
@@ -128,6 +128,7 @@ class TwitterStatusFetcher extends ParallelizingDaemon
         return $flinks;
     }
 
+    // FIXME: make it so we can force a Foreign_link here without colliding with parent
     function childTask($flink) {
         // Each child ps needs its own DB connection
 
@@ -149,14 +150,8 @@ class TwitterStatusFetcher extends ParallelizingDaemon
         unset($_DB_DATAOBJECT['CONNECTIONS']);
     }
 
-    function getTimeline($flink, $timelineUri = 'home_timeline')
+    function getTimeline(Foreign_link $flink, $timelineUri = 'home_timeline')
     {
-        if (empty($flink)) {
-            common_log(LOG_ERR, $this->name() .
-                       " - Can't retrieve Foreign_link for foreign ID $fid");
-            return;
-        }
-
         common_log(LOG_DEBUG, $this->name() . ' - Trying to get ' . $timelineUri .
                    ' timeline for Twitter user ' . $flink->foreign_id);
 
index cc0c05f9a669abbe2bfd4496c526021f2341dda4..69ce5a61e97302518ee4011b8b15749adb34c414 100644 (file)
@@ -51,8 +51,8 @@ class TweetInQueueHandler extends QueueHandler
         $importer = new TwitterImport();
         $notice = $importer->importStatus($status);
         if ($notice instanceof Notice) {
-            $flink = Foreign_link::getByForeignID($receiver, TWITTER_SERVICE);
-            if ($flink instanceof Foreign_link) {
+            try {
+                $flink = Foreign_link::getByForeignID($receiver, TWITTER_SERVICE);
                 common_log(LOG_DEBUG, "TweetInQueueHandler - Got flink so add notice ".
                            $notice->id." to attentions for user ".$flink->user_id);
                 try {
@@ -63,7 +63,7 @@ class TweetInQueueHandler extends QueueHandler
                     common_log(LOG_ERR, "Failed adding notice {$notice->id} to attentions for user {$flink->user_id}: " .
                                         $e->getMessage());
                 }
-            } else {
+            } catch (NoResultException $e) {
                common_log(LOG_DEBUG, "TweetInQueueHandler - No flink found for foreign user ".$receiver);
             }
         }
index 45b7547ce2fe7e5b79b6fef2bba0f2686eab0cd9..d929fecf83291deff3b5b218cce37a1e1c7485a1 100644 (file)
@@ -542,17 +542,17 @@ class TwitterImport
         }
 
         foreach ($status->entities->user_mentions as $mention) {
-            $flink = Foreign_link::getByForeignID($mention->id, TWITTER_SERVICE);
-            if (!empty($flink)) {
-                $user = User::getKV('id', $flink->user_id);
-                if (!empty($user)) {
-                    $reply = new Reply();
-                    $reply->notice_id  = $notice->id;
-                    $reply->profile_id = $user->id;
-                    $reply->modified   = $notice->created;
-                    common_log(LOG_INFO, __METHOD__ . ": saving reply: notice {$notice->id} to profile {$user->id}");
-                    $id = $reply->insert();
-                }
+            try {
+                $flink = Foreign_link::getByForeignID($mention->id, TWITTER_SERVICE);
+                $user = $flink->getUser();
+                $reply = new Reply();
+                $reply->notice_id  = $notice->id;
+                $reply->profile_id = $user->id;
+                $reply->modified   = $notice->created;
+                common_log(LOG_INFO, __METHOD__ . ": saving reply: notice {$notice->id} to profile {$user->id}");
+                $id = $reply->insert();
+            } catch (NoResultException $e) {
+                common_log(LOG_WARNING, 'No local user found for Foreign_link with local User id: '.$flink->user_id);
             }
         }
     }
index f992a09079299d6bba4691d575445a99f389123f..93d10b8d48ed20be6182c0ca015e6c73578c183c 100644 (file)
@@ -111,7 +111,7 @@ class TwitterOAuthClient extends OAuthClient
      *
      * @return OAuthToken $token the request token
      */
-    function getRequestToken()
+    function getTwitterRequestToken()
     {
         return parent::getRequestToken(
             self::$requestTokenURL,
@@ -126,7 +126,7 @@ class TwitterOAuthClient extends OAuthClient
      *
      * @return the link
      */
-    function getAuthorizeLink($request_token, $signin = false)
+    function getTwitterAuthorizeLink($request_token, $signin = false)
     {
         $url = ($signin) ? self::$signinUrl : self::$authorizeURL;
 
@@ -142,7 +142,7 @@ class TwitterOAuthClient extends OAuthClient
      *
      * @return OAuthToken $token the access token
      */
-    function getAccessToken($verifier = null)
+    function getTwitterAccessToken($verifier = null)
     {
         return parent::getAccessToken(
             self::$accessTokenURL,
index e827a07117ca7b44623c0db3875c323cfc3341f3..5d965e7394f383df85867c267891b21a8ca6c3d2 100644 (file)
@@ -62,12 +62,7 @@ if (have_option('n')) {
  */
 function twitterAuthForUser(User $user)
 {
-    $flink = Foreign_link::getByUserID($user->id,
-                                       TWITTER_SERVICE);
-    if (!$flink) {
-        throw new ServerException("No Twitter config for this user.");
-    }
-
+    $flink = Foreign_link::getByUserID($user->id, TWITTER_SERVICE);
     $token = TwitterOAuthClient::unpackToken($flink->credentials);
     if (!$token) {
         throw new ServerException("No Twitter OAuth credentials for this user.");
index 4e8340bb3f7c9a27473a22d3ccf4a67458446653..a642920cee908e09b0363c03a0c9cc52c4958dd2 100644 (file)
@@ -63,12 +63,7 @@ if (have_option('n')) {
  */
 function twitterAuthForUser(User $user)
 {
-    $flink = Foreign_link::getByUserID($user->id,
-                                       TWITTER_SERVICE);
-    if (!$flink) {
-        throw new ServerException("No Twitter config for this user.");
-    }
-
+    $flink = Foreign_link::getByUserID($user->id, TWITTER_SERVICE);
     $token = TwitterOAuthClient::unpackToken($flink->credentials);
     if (!$token) {
         throw new ServerException("No Twitter OAuth credentials for this user.");
index b607fe605275e49fba5837207b6e9b87e4eb60bd..0f1e686ac8865b35548cf5f0de62f6904372d8ea 100644 (file)
@@ -28,16 +28,17 @@ function add_twitter_user($twitter_id, $screen_name)
     // Clear out any bad old foreign_users with the new user's legit URL
     // This can happen when users move around or fakester accounts get
     // repoed, and things like that.
-    $luser = Foreign_user::getForeignUser($twitter_id, TWITTER_SERVICE);
-
-    if (!empty($luser)) {
-        $result = $luser->delete();
+    try {
+        $fuser = Foreign_user::getForeignUser($twitter_id, TWITTER_SERVICE);
+        $result = $fuser->delete();
         if ($result != false) {
             common_log(
                 LOG_INFO,
                 "Twitter bridge - removed old Twitter user: $screen_name ($twitter_id)."
             );
         }
+    } catch (NoResultException $e) {
+        // no old foreign users exist for this id
     }
 
     $fuser = new Foreign_user();
@@ -49,9 +50,8 @@ function add_twitter_user($twitter_id, $screen_name)
     $fuser->created = common_sql_now();
     $result = $fuser->insert();
 
-    if (empty($result)) {
-        common_log(LOG_WARNING,
-            "Twitter bridge - failed to add new Twitter user: $twitter_id - $screen_name.");
+    if ($result === false) {
+        common_log(LOG_WARNING, "Twitter bridge - failed to add new Twitter user: $twitter_id - $screen_name.");
         common_log_db_error($fuser, 'INSERT', __FILE__);
     } else {
         common_log(LOG_INFO,
@@ -66,11 +66,10 @@ 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, TWITTER_SERVICE);
+    try {
+        $fuser = Foreign_user::getForeignUser($twitter_id, TWITTER_SERVICE);
 
-    if (!empty($fuser)) {
         // Delete old record if Twitter user changed screen name
-
         if ($fuser->nickname != $screen_name) {
             $oldname = $fuser->nickname;
             $fuser->delete();
@@ -80,11 +79,13 @@ function save_twitter_user($twitter_id, $screen_name)
                                          $screen_name,
                                          $oldname));
         }
-    } else {
+    } catch (NoResultException $e) {
+        // No old users exist for this id
+    
         // Kill any old, invalid records for this screen name
-        $fuser = Foreign_user::getByNickname($screen_name, TWITTER_SERVICE);
-
-        if (!empty($fuser)) {
+        // XXX: Is this really only supposed to be run if the above getForeignUser fails?
+        try {
+            $fuser = Foreign_user::getByNickname($screen_name, TWITTER_SERVICE);
             $fuser->delete();
             common_log(
                 LOG_INFO,
@@ -95,6 +96,8 @@ function save_twitter_user($twitter_id, $screen_name)
                     $fuser->id
                 )
             );
+        } catch (NoResultException $e) {
+            // No old users exist for this screen_name
         }
     }
 
@@ -178,11 +181,15 @@ function twitter_id($status, $field='id')
  */
 function broadcast_twitter($notice)
 {
-    $flink = Foreign_link::getByUserID($notice->profile_id,
-                                       TWITTER_SERVICE);
+    try {
+        $flink = Foreign_link::getByUserID($notice->profile_id, TWITTER_SERVICE);
+    } catch (NoResultException $e) {
+        // Alright so don't broadcast it then! (since there's no foreign link)
+        return true;
+    }
 
     // Don't bother with basic auth, since it's no longer allowed
-    if (!empty($flink) && TwitterOAuthClient::isPackedToken($flink->credentials)) {
+    if (TwitterOAuthClient::isPackedToken($flink->credentials)) {
         if (is_twitter_bound($notice, $flink)) {
             if (!empty($notice->repeat_of) && is_twitter_notice($notice->repeat_of)) {
                 $retweet = retweet_notice($flink, Notice::getKV('id', $notice->repeat_of));
@@ -270,8 +277,13 @@ function twitter_update_params($notice)
     return $params;
 }
 
-function broadcast_oauth($notice, $flink) {
-    $user = $flink->getUser();
+function broadcast_oauth($notice, Foreign_link $flink) {
+    try {
+        $user = $flink->getUser();
+    } catch (ServerException $e) {
+        common_log(LOG_WARNING, 'Discarding broadcast_oauth for notice '.$notice->id.' because of exception: '.$e->getMessage());
+        return true;
+    }
     $statustxt = format_status($notice);
     $params = twitter_update_params($notice);
 
index 91dc9b53f797f060d65e47f8e361566d949bf9b9..c2a9c69d0c9342adb0922967455de308397ca3a1 100644 (file)
@@ -144,7 +144,7 @@ class WebFingerPlugin extends Plugin
     public function onStartShowHTML($action)
     {
         if ($action instanceof ShowstreamAction) {
-            $acct = 'acct:'. $action->profile->nickname .'@'. common_config('site', 'server');
+            $acct = 'acct:'. $action->getTarget()->getNickname() .'@'. common_config('site', 'server');
             $url = common_local_url('webfinger') . '?resource='.$acct;
 
             foreach (array(Discovery::JRD_MIMETYPE, Discovery::XRD_MIMETYPE) as $type) {
index 0a702687359e1c95fa76b50943f7d61a887e872f..04101a8e2b933f15d6f6c06de104b7d8c63b514a 100644 (file)
@@ -308,11 +308,6 @@ class XmppPlugin extends ImPlugin
         return true;
     }
 
-    function microiduri($screenname)
-    {
-        return 'xmpp:' . $screenname;
-    }
-
     function sendMessage($screenname, $body)
     {
         $this->queuedConnection()->message($screenname, $body, 'chat');
diff --git a/scripts/delete_notice.php b/scripts/delete_notice.php
new file mode 100755 (executable)
index 0000000..bf10cbb
--- /dev/null
@@ -0,0 +1,68 @@
+#!/usr/bin/env php
+<?php
+/*
+ * StatusNet - a distributed open-source microblogging tool
+ * Copyright (C) 2008, 2009, StatusNet, 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/>.
+ */
+
+define('INSTALLDIR', realpath(dirname(__FILE__) . '/..'));
+
+$shortoptions = 'i::n::u::y';
+$longoptions = array('id=', 'nickname=', 'uri=', 'yes');
+
+$helptext = <<<END_OF_HELP
+delete_notice.php [options]
+deletes a notice (but not related File objects) from the database
+
+  -i --id       Local ID of the notice
+  -u --uri      Notice URI
+  -y --yes      do not wait for confirmation
+
+END_OF_HELP;
+
+require_once INSTALLDIR.'/scripts/commandline.inc';
+
+if (have_option('i', 'id')) {
+    $id = get_option_value('i', 'id');
+    $notice = Notice::getByID($id);
+    if (!$notice instanceof Notice) {
+        print "Can't find notice with ID $id\n";
+        exit(1);
+    }
+} else if (have_option('u', 'uri')) {
+    $uri = get_option_value('u', 'uri');
+    $notice = Notice::getKV('uri', $uri);
+    if (!$notice instanceof Notice) {
+        print "Can't find notice with URI '$uri'\n";
+        exit(1);
+    }
+} else {
+    print "You must provide either an ID, a URI or a nickname.\n";
+    exit(1);
+}
+
+if (!have_option('y', 'yes')) {
+    print "About to PERMANENTLY delete notice ".$notice->getID()." by '".$notice->getProfile()->getNickname()."'. Are you sure? [y/N] ";
+    $response = fgets(STDIN);
+    if (strtolower(trim($response)) != 'y') {
+        print "Aborting.\n";
+        exit(0);
+    }
+}
+
+print "Deleting...";
+$notice->delete();
+print "DONE.\n";
index ddc225fb82d073f8288e1534b1e3e30dc7fc5f9c..20f9aa775fe16613735e3d360d29009fcdbc72cb 100644 (file)
@@ -1622,6 +1622,11 @@ ul.profile_list li {
     display: block;
 }
 
+table.profile_list tbody tr:nth-child(2n+1) {
+    background-color: #fafafa !important;
+    border: none !important;
+}
+
 .entity_profile .entity_nickname,
 .entity_profile .entity_fn {
 margin-left:0;
index 39cce89e482edb178fd01b8aeca1c89de754c53a..be9b80d41c5b9fbad12b35f552d2a408cccd3490 100644 (file)
@@ -1141,11 +1141,6 @@ table.profile_list {
         background: url(../images/bluearrow_up.png) no-repeat top right;
 }
 
-table.profile_list tr.alt {
-    background-color: #fafafa !important;
-    border: none !important;
-}
-
 td.entity_profile {
     width: auto;
     min-width: 250px;
index 601845164b5d532d3465492fb116c63de102bac9..575e6b73868c8a06340a6be015698e810011e2f8 100644 (file)
@@ -938,11 +938,6 @@ table.profile_list {
         background: url(../images/bluearrow_up.png) no-repeat top right;
 }
 
-table.profile_list tr.alt {
-    background-color: #fafafa !important;
-    border: none !important;
-}
-
 td.entity_profile {
     width: auto;
     min-width: 250px;