Merge remote-tracking branch 'upstream/master' into social-master
authorRoland Haeder <roland@mxchange.org>
Sun, 3 Jan 2016 17:55:37 +0000 (18:55 +0100)
committerRoland Haeder <roland@mxchange.org>
Sun, 3 Jan 2016 17:55:37 +0000 (18:55 +0100)
Signed-off-by: Roland Haeder <roland@mxchange.org>
495 files changed:
.gitignore
actions/addpeopletag.php
actions/apiaccountratelimitstatus.php
actions/apiaccountupdatedeliverydevice.php
actions/apiaccountverifycredentials.php
actions/apiatomservice.php
actions/apiattachment.php
actions/apicheckhub.php
actions/apiconversation.php
actions/apiexternalprofileshow.php
actions/apifriendshipsexists.php
actions/apifriendshipsshow.php
actions/apignusocialconfig.php
actions/apignusocialversion.php
actions/apigroupadmins.php
actions/apigroupismember.php
actions/apigrouplist.php
actions/apigrouplistall.php
actions/apigroupmembership.php
actions/apigroupshow.php
actions/apihelptest.php
actions/apilist.php
actions/apilistmemberships.php
actions/apilists.php
actions/apilistsubscriber.php
actions/apilistsubscriptions.php
actions/apimediaupload.php
actions/apioauthaccesstoken.php
actions/apioauthauthorize.php
actions/apioauthrequesttoken.php
actions/apisearchatom.php
actions/apisearchjson.php
actions/apistatusesdestroy.php
actions/apistatusesshow.php
actions/apisubscriptions.php
actions/apitimelinefriends.php
actions/apitimelinegroup.php
actions/apitimelinehome.php
actions/apitimelinelist.php
actions/apitimelinementions.php
actions/apitimelinepublic.php
actions/apitimelinetag.php
actions/apitimelineuser.php
actions/apitrends.php
actions/apiuserprofileimage.php
actions/apiusershow.php
actions/approvegroup.php
actions/approvesub.php
actions/atompubshowsubscription.php
actions/attachment.php
actions/avatarbynickname.php
actions/backupaccount.php
actions/block.php
actions/blockedfromgroup.php
actions/cancelgroup.php
actions/confirmaddress.php
actions/deleteaccount.php
actions/deleteapplication.php
actions/deletegroup.php
actions/deleteuser.php
actions/doc.php
actions/editapplication.php
actions/editpeopletag.php
actions/featured.php
actions/foaf.php
actions/foafgroup.php
actions/geocode.php
actions/getfile.php
actions/grantrole.php
actions/groupblock.php
actions/groupmembers.php
actions/groupqueue.php
actions/grouprss.php
actions/groups.php
actions/groupunblock.php
actions/invite.php
actions/logout.php
actions/makeadmin.php
actions/microsummary.php
actions/noticesearch.php
actions/noticesearchrss.php
actions/nudge.php
actions/opensearch.php
actions/otp.php
actions/peopletag.php
actions/peopletagautocomplete.php
actions/peopletagged.php
actions/peopletagsbyuser.php
actions/peopletagsforuser.php
actions/peopletagsubscribers.php
actions/peopletagsubscriptions.php
actions/pluginenable.php
actions/profilecompletion.php
actions/profiletagbyid.php
actions/publicrss.php
actions/publictagcloud.php
actions/recoverpassword.php
actions/redirect.php
actions/register.php
actions/removepeopletag.php
actions/replies.php
actions/restoreaccount.php
actions/revokerole.php
actions/robotstxt.php
actions/rsd.php
actions/sandbox.php
actions/selftag.php
actions/showapplication.php
actions/showgroup.php
actions/shownotice.php
actions/silence.php
actions/subedit.php
actions/subqueue.php
actions/subscribe.php
actions/subscribepeopletag.php
actions/subscribers.php
actions/subscriptions.php
actions/sup.php
actions/tag.php
actions/tagrss.php
actions/unblock.php
actions/unsandbox.php
actions/unsilence.php
actions/unsubscribe.php
actions/unsubscribepeopletag.php
actions/userrss.php
actions/version.php
classes/Avatar.php
classes/Confirm_address.php
classes/File_redirection.php
classes/File_thumbnail.php
classes/Memcached_DataObject.php
classes/Notice.php
classes/Notice_tag.php
classes/User_group.php
extlib/DB/DataObject/createTables.php [changed mode: 0755->0644]
index.php
installer.txt [new file with mode: 0644]
lib/action.php
lib/activity.php
lib/activityimporter.php
lib/activityutils.php
lib/adminpanelaction.php
lib/apilistusers.php
lib/apioauthaction.php
lib/attachmentlist.php
lib/attachmentlistitem.php
lib/attachmenttagcloudsection.php
lib/command.php
lib/default.php
lib/docfile.php
lib/formaction.php
lib/framework.php
lib/groupaction.php
lib/grouplist.php
lib/groupmemberlist.php
lib/grouptagcloudsection.php
lib/httpclient.php
lib/imagefile.php
lib/implugin.php
lib/inboxtagcloudsection.php
lib/infoaction.php
lib/installer.php
lib/inviteform.php
lib/iomaster.php
lib/menu.php
lib/noticeform.php
lib/noticelist.php
lib/noticelistitem.php
lib/personaltagcloudsection.php
lib/pluginlist.php
lib/profileaction.php
lib/profileformaction.php
lib/profilelist.php
lib/profileminilist.php
lib/publictagcloudsection.php
lib/router.php
lib/schemaupdater.php
lib/search_engines.php
lib/searchaction.php
lib/subscriptionlist.php
lib/tagcloudsection.php
lib/threadednoticelist.php
lib/urlmapper.php
lib/urlshortenerplugin2.php [new file with mode: 0644]
lib/util.php
plugins/APC/APCPlugin.php [new file with mode: 0644]
plugins/AccountManager/AccountManagerPlugin.php
plugins/AccountManager/actions/accountmanagementcontroldocument.php
plugins/AccountManager/actions/accountmanagementsessionstatus.php
plugins/Activity/ActivityPlugin.php
plugins/ActivitySpam/ActivitySpamPlugin.php
plugins/ActivitySpam/actions/spam.php
plugins/ActivitySpam/classes/spam_score.php
plugins/ActivitySpam/scripts/silencespammer.php
plugins/ActivitySpam/scripts/testuser.php
plugins/ActivitySpam/scripts/trainuser.php
plugins/Adsense/AdsensePlugin.php [new file with mode: 0644]
plugins/Aim/AimPlugin.php [new file with mode: 0644]
plugins/Aim/lib/aimmanager.php [new file with mode: 0644]
plugins/AnonymousFave/AnonymousFavePlugin.php
plugins/AnonymousFave/actions/anondisfavor.php
plugins/AnonymousFave/actions/anonfavor.php
plugins/AnonymousFave/scripts/initialize_fave_tallys.php
plugins/ApiLogger/ApiLoggerPlugin.php
plugins/Autocomplete/AutocompletePlugin.php
plugins/Autocomplete/actions/autocomplete.php
plugins/BitlyUrl/BitlyUrlPlugin.php
plugins/Blacklist/BlacklistPlugin.php
plugins/BlogspamNet/BlogspamNetPlugin.php [deleted file]
plugins/BlogspamNet/locale/BlogspamNet.pot [deleted file]
plugins/BlogspamNet/locale/zh_TW/LC_MESSAGES/BlogspamNet.po [deleted file]
plugins/Bookmark/BookmarkPlugin.php
plugins/Bookmark/actions/apitimelinebookmarks.php
plugins/Bookmark/actions/bookmarkforurl.php
plugins/Bookmark/actions/bookmarks.php
plugins/Bookmark/actions/importdelicious.php
plugins/Bookmark/actions/newbookmark.php
plugins/Bookmark/actions/noticebyurl.php
plugins/Bookmark/scripts/importbookmarks.php
plugins/CasAuthentication/CasAuthenticationPlugin.php
plugins/CasAuthentication/actions/caslogin.php
plugins/ClientSideShorten/ClientSideShortenPlugin.php
plugins/ClientSideShorten/actions/shorten.php
plugins/ConversationTree/lib/conversationtree.php
plugins/DirectMessage/DirectMessagePlugin.php
plugins/DirectMessage/actions/apidirectmessage.php
plugins/DirectMessage/actions/showmessage.php
plugins/DirectMessage/classes/Message.php
plugins/DirectionDetector/DirectionDetectorPlugin.php
plugins/Directory/DirectoryPlugin.php
plugins/Directory/actions/groupdirectory.php
plugins/Directory/actions/userdirectory.php
plugins/Directory/lib/sortablegrouplist.php
plugins/DomainStatusNetwork/DomainStatusNetworkPlugin.php
plugins/DomainStatusNetwork/actions/globalapi.php
plugins/DomainStatusNetwork/scripts/installforemail.php
plugins/DomainStatusNetwork/scripts/proposesite.php
plugins/DomainStatusNetwork/scripts/sitefordomain.php
plugins/DomainWhitelist/DomainWhitelistPlugin.php
plugins/EmailRegistration/EmailRegistrationPlugin.php
plugins/EmailRegistration/actions/emailregister.php
plugins/EmailRegistration/scripts/cancelemailregistration.php
plugins/EmailRegistration/scripts/registeremailuser.php
plugins/EmailReminder/EmailReminderPlugin.php
plugins/EmailReminder/scripts/sendemailreminder.php
plugins/EmailSummary/EmailSummaryPlugin.php
plugins/EmailSummary/scripts/sendemailsummary.php
plugins/Event/EventPlugin.php
plugins/Event/actions/cancelrsvp.php
plugins/Event/actions/newevent.php
plugins/Event/actions/newrsvp.php
plugins/Event/actions/timelist.php
plugins/Event/classes/Happening.php
plugins/Event/classes/RSVP.php
plugins/ExtendedProfile/ExtendedProfilePlugin.php
plugins/ExtendedProfile/actions/userautocomplete.php
plugins/FacebookBridge/FacebookBridgePlugin.php
plugins/FacebookBridge/actions/facebookdeauthorize.php
plugins/FacebookBridge/actions/facebookfinishlogin.php
plugins/FacebookBridge/actions/facebooklogin.php
plugins/Favorite/actions/apifavoritecreate.php
plugins/Favorite/actions/apifavoritedestroy.php
plugins/Favorite/actions/apistatusesfavs.php
plugins/Favorite/actions/apitimelinefavorites.php
plugins/Favorite/actions/atompubfavoritefeed.php
plugins/Favorite/actions/atompubshowfavorite.php
plugins/Favorite/actions/favorited.php
plugins/Favorite/actions/showfavorites.php
plugins/Favorite/classes/Fave.php
plugins/GNUsocialPhoto/GNUsocialPhotoPlugin.php
plugins/GNUsocialPhoto/actions/newphoto.php
plugins/GNUsocialPhoto/classes/Photo.php
plugins/GNUsocialPhotos/GNUsocialPhotosPlugin.php
plugins/GNUsocialPhotos/actions/editphoto.php
plugins/GNUsocialPhotos/actions/photos.php
plugins/GNUsocialPhotos/actions/photoupload.php
plugins/GNUsocialProfileExtensions/GNUsocialProfileExtensionsPlugin.php
plugins/GNUsocialProfileExtensions/actions/bio.php
plugins/GNUsocialProfileExtensions/lib/noticetree.php
plugins/GNUsocialVideo/GNUsocialVideoPlugin.php
plugins/GNUsocialVideo/actions/postvideo.php
plugins/GNUsocialVideo/actions/showvideo.php
plugins/GNUsocialVideo/classes/Video.php
plugins/GoogleAnalytics/GoogleAnalyticsPlugin.php
plugins/GroupPrivateMessage/GroupPrivateMessagePlugin.php
plugins/GroupPrivateMessage/actions/groupinbox.php
plugins/GroupPrivateMessage/actions/showgroupmessage.php
plugins/Irc/IrcPlugin.php [new file with mode: 0644]
plugins/Irc/extlib/phergie/Tests/Phergie/Plugin/HandlerTest.php [new file with mode: 0644]
plugins/Irc/lib/ircmanager.php [new file with mode: 0644]
plugins/LdapCommon/LdapCommon.php
plugins/LinkPreview/LinkPreviewPlugin.php
plugins/LinkPreview/actions/oembedproxy.php
plugins/Linkback/LinkbackPlugin.php
plugins/Mapstraction/MapstractionPlugin.php
plugins/Mapstraction/actions/allmap.php
plugins/Mapstraction/actions/map.php
plugins/Mapstraction/actions/usermap.php
plugins/Minify/MinifyPlugin.php
plugins/Minify/actions/minify.php
plugins/Minify/extlib/minify/min/lib/Solar/Dir.php
plugins/ModHelper/ModHelperPlugin.php
plugins/ModLog/ModLogPlugin.php
plugins/ModPlus/ModPlusPlugin.php
plugins/Mollom/MollomPlugin.php
plugins/NoticeTitle/NoticeTitlePlugin.php
plugins/NoticeTitle/classes/Notice_title.php
plugins/OStatus/OStatusPlugin.php
plugins/OStatus/actions/ostatusinit.php
plugins/OStatus/actions/ostatustag.php
plugins/OStatus/classes/FeedSub.php
plugins/OStatus/classes/Ostatus_profile.php
plugins/OStatus/lib/magicenvelope.php
plugins/OStatus/lib/ostatusqueuehandler.php
plugins/OStatus/lib/salmonaction.php
plugins/OStatus/scripts/fixup-shadow.php
plugins/OStatus/scripts/gcfeeds.php
plugins/OStatus/scripts/renew-feeds.php
plugins/OStatus/scripts/resub-feed.php
plugins/OStatus/scripts/rm_bad_feedsubs.php
plugins/OStatus/scripts/testfeed.php
plugins/OStatus/scripts/update-profile-data.php
plugins/OStatus/scripts/update-profile.php
plugins/OStatus/scripts/update_ostatus_profiles.php
plugins/OStatus/tests/gettext-speedtest.php
plugins/OStatus/tests/slap.php
plugins/Oembed/actions/oembed.php
plugins/Oembed/classes/File_oembed.php
plugins/Oembed/scripts/fixup_files.php
plugins/OfflineBackup/OfflineBackupPlugin.php
plugins/OfflineBackup/lib/offlinebackupqueuehandler.php
plugins/OpenExternalLinkTarget/OpenExternalLinkTargetPlugin.php
plugins/OpenID/OpenIDPlugin.php
plugins/OpenID/actions/finishaddopenid.php
plugins/OpenID/actions/finishopenidlogin.php
plugins/OpenID/actions/openidlogin.php
plugins/OpenID/actions/openidserver.php
plugins/OpenID/actions/openidtrust.php
plugins/OpenID/actions/publicxrds.php
plugins/OpenID/openid.php
plugins/OpenX/OpenXPlugin.php
plugins/OpportunisticQM/OpportunisticQMPlugin.php
plugins/OpportunisticQM/lib/opportunisticqueuemanager.php
plugins/PiwikAnalytics/PiwikAnalyticsPlugin.php
plugins/Poll/PollPlugin.php
plugins/Poll/actions/newpoll.php
plugins/Poll/actions/respondpoll.php
plugins/Poll/classes/Poll.php
plugins/Poll/classes/Poll_response.php
plugins/PostDebug/PostDebugPlugin.php
plugins/PtitUrl/PtitUrlPlugin.php
plugins/QnA/QnAPlugin.php
plugins/QnA/actions/qnaclosequestion.php
plugins/QnA/actions/qnanewanswer.php
plugins/QnA/actions/qnanewquestion.php
plugins/QnA/actions/qnareviseanswer.php
plugins/QnA/actions/qnavote.php
plugins/QnA/classes/QnA_Answer.php
plugins/QnA/classes/QnA_Question.php
plugins/QnA/classes/QnA_Vote.php
plugins/QnA/forms/qnanewquestion.php
plugins/RSSCloud/RSSCloudPlugin.php
plugins/RSSCloud/actions/loggingaggregator.php
plugins/RSSCloud/actions/rsscloudrequestnotify.php
plugins/Realtime/RealtimePlugin.php
plugins/Realtime/actions/closechannel.php
plugins/Realtime/actions/keepalivechannel.php
plugins/Realtime/scripts/cleanupchannels.php
plugins/Recaptcha/RecaptchaPlugin.php
plugins/RegisterThrottle/RegisterThrottlePlugin.php
plugins/RequireValidatedEmail/RequireValidatedEmailPlugin.php
plugins/RequireValidatedEmail/scripts/registerbyemail.php
plugins/SQLProfile/SQLProfilePlugin.php
plugins/Sample/actions/hello.php
plugins/Scroller [new symlink]
plugins/SearchSub/SearchSubPlugin.php
plugins/SearchSub/actions/searchsub.php
plugins/SearchSub/actions/searchsubs.php
plugins/SearchSub/actions/searchunsub.php
plugins/SearchSub/classes/SearchSub.php
plugins/Share/actions/apistatusesretweets.php
plugins/Share/actions/apitimelineretweetedbyme.php
plugins/Share/actions/apitimelineretweetedtome.php
plugins/Share/actions/apitimelineretweetsofme.php
plugins/ShareNotice/ShareNoticePlugin.php
plugins/SiteNoticeInSidebar/SiteNoticeInSidebarPlugin.php
plugins/Sitemap/SitemapPlugin.php
plugins/Sitemap/actions/noticesitemap.php
plugins/Sitemap/actions/sitemap.php
plugins/Sitemap/actions/sitemapindex.php
plugins/Sitemap/actions/usersitemap.php
plugins/Sitemap/scripts/updatecounts.php
plugins/SlicedFavorites/SlicedFavoritesPlugin.php
plugins/SlicedFavorites/actions/favoritedslice.php
plugins/SphinxSearch/scripts/gen_config.php
plugins/SphinxSearch/scripts/index_update.php
plugins/Spotify/SpotifyPlugin.php [new file with mode: 0644]
plugins/Statistics/README.md [new symlink]
plugins/Statistics/StatisticsPlugin.php [new symlink]
plugins/Statistics/actions [new symlink]
plugins/StrictTransportSecurity/StrictTransportSecurityPlugin.php
plugins/SubMirror/SubMirrorPlugin.php
plugins/SubMirror/classes/SubMirror.php
plugins/TabFocus/TabFocusPlugin.php
plugins/TagSub/TagSubPlugin.php
plugins/TagSub/actions/tagsub.php
plugins/TagSub/actions/tagsubs.php
plugins/TagSub/actions/tagunsub.php
plugins/TagSub/classes/TagSub.php
plugins/TinyMCE/TinyMCEPlugin.php [new file with mode: 0644]
plugins/TwitterBridge/TwitterBridgePlugin.php
plugins/TwitterBridge/daemons/synctwitterfriends.php [changed mode: 0755->0644]
plugins/TwitterBridge/daemons/twitterdaemon.php
plugins/TwitterBridge/daemons/twitterstatusfetcher.php [changed mode: 0755->0644]
plugins/TwitterBridge/lib/jsonstreamreader.php
plugins/TwitterBridge/scripts/fakestream.php
plugins/TwitterBridge/scripts/initialize_notice_to_status.php
plugins/TwitterBridge/scripts/streamtest.php
plugins/UserFlag/UserFlagPlugin.php
plugins/UserFlag/actions/adminprofileflag.php
plugins/UserFlag/actions/clearflag.php
plugins/UserFlag/actions/flagprofile.php
plugins/UserLimit/UserLimitPlugin.php
plugins/WebFinger/WebFingerPlugin.php
plugins/WebFinger/lib/xrdaction.php
plugins/WikiHowProfile/WikiHowProfilePlugin.php
plugins/XCache/XCachePlugin.php [new file with mode: 0644]
plugins/Xmpp/XmppPlugin.php
plugins/Xmpp/lib/xmppmanager.php
plugins/YammerImport/actions/yammeradminpanel.php [new file with mode: 0644]
plugins/YammerImport/actions/yammerauth.php [new file with mode: 0644]
plugins/YammerImport/lib/yammerimporter.php [new file with mode: 0644]
scripts/allsites.php
scripts/backupuser.php
scripts/checkschema.php
scripts/clean_file_table.php
scripts/clean_profiles.php
scripts/clean_thumbnails.php
scripts/clear_jabber.php
scripts/clearcache.php
scripts/command.php
scripts/commandline.inc [deleted file]
scripts/commandline.inc.php [new file with mode: 0644]
scripts/console.php
scripts/createsim.php
scripts/deletegroup.php
scripts/deleteprofile.php
scripts/docgen.php
scripts/dumpschema.php
scripts/fixup_deletions.php
scripts/fixup_group_profiles.php [new file with mode: 0755]
scripts/flushrouter.php
scripts/flushsite.php
scripts/getpiddir.php
scripts/getvaliddaemons.php
scripts/gnusocialversion.php
scripts/handlequeued.php
scripts/imdaemon.php
scripts/importtwitteratom.php
scripts/joingroup.php
scripts/leavegroup.php
scripts/maildaemon.php
scripts/make-release.php
scripts/makegroupadmin.php
scripts/moveuser.php
scripts/nukefile.php
scripts/queuectl.php
scripts/queuedaemon.php
scripts/registeruser.php
scripts/remove_duplicate_file_urls.php
scripts/restoreuser.php
scripts/sendemail.php
scripts/sessiongc.php
scripts/setconfig.php
scripts/setpassword.php
scripts/settag.php
scripts/showcache.php
scripts/showplugins.php
scripts/showtable.php
scripts/startdaemons.sh
scripts/stopdaemons.sh
scripts/strip_geo.php
scripts/uncache_users.php
scripts/updatelocation.php
scripts/updateurls.php
scripts/upgrade.php
scripts/useremail.php
scripts/userrole.php
tests/UserRightsTest.php
tests/atompub/atompub_test.php
tests/oauth/fetch_temp_creds.php [changed mode: 0755->0644]
tests/oauth/fetch_token_creds.php [changed mode: 0755->0644]
tests/oauth/oauth_post_notice.php
tests/oauth/oauth_verify_creds.php [changed mode: 0755->0644]

index 102173e832708f11078f366b3ec8fb8ceca3f51b..00383151a6401dfbfde841ba02bceb70845f04fd 100644 (file)
@@ -28,4 +28,9 @@ php.log
 .DS_Store
 nbproject
 *.mo
-
+*log*
+htaccess-sample
+installer.txt
+extlib/DB.php
+.gitmodules
+*_plugin/*
index b501ce0fd9679b245d36f300164f7b433e9cce26..56bb206dc44016aeacbd7f062312ccc371934ae0 100644 (file)
@@ -65,7 +65,7 @@ class AddpeopletagAction extends Action
      *
      * @return boolean success flag
      */
-    function prepare($args)
+    function prepare(array $args=array())
     {
         parent::prepare($args);
 
@@ -119,7 +119,7 @@ class AddpeopletagAction extends Action
      *
      * @return void
      */
-    function handle($args)
+    function handle(array $args=array())
     {
         // Throws exception on error
         $ptag = Profile_tag::setTag($this->user->id, $this->tagged->id,
@@ -127,7 +127,8 @@ class AddpeopletagAction extends Action
 
         if (!$ptag) {
             $user = User::getKV('id', $id);
-            if ($user) {
+
+            if ($user instanceof User) {
                 $this->clientError(
                         // TRANS: Client error displayed when an unknown error occurs when adding a user to a list.
                         // TRANS: %s is a username.
index 592cf908fcf49d71dcfe896411361862b8180fe8..167a2dd6f55b9c7b0957f169ac27b24aeedfb8a1 100644 (file)
@@ -112,7 +112,7 @@ class ApiAccountRateLimitStatusAction extends ApiBareAuthAction
      *
      * @return boolean is read only action?
      */
-    function isReadOnly($args)
+    function isReadOnly(array $args=array())
     {
         return true;
     }
index a3cbb418b65d60c899ca865fbbe9a34efcbc69e1..370423ad2e9bd37d8e63e28e3ee7d2f58e525ce8 100644 (file)
@@ -54,7 +54,7 @@ class ApiAccountUpdateDeliveryDeviceAction extends ApiAuthAction
      *
      * @return boolean success flag
      */
-    function prepare($args)
+    function prepare(array $args=array())
     {
         parent::prepare($args);
 
@@ -73,7 +73,7 @@ class ApiAccountUpdateDeliveryDeviceAction extends ApiAuthAction
      *
      * @return void
      */
-    function handle($args)
+    function handle(array $args=array())
     {
         parent::handle($args);
 
index 9b98fa6d810ba384fbea24599c7f47ae4285c3bc..12daf3e1e6fe68150ea652154ee420bf32bf0ba8 100644 (file)
@@ -48,6 +48,13 @@ if (!defined('STATUSNET')) {
  */
 class ApiAccountVerifyCredentialsAction extends ApiAuthAction
 {
+    /**
+     * Handle the request
+     *
+     * Check whether the credentials are valid and output the result
+     *
+     * @return void
+     */
     protected function handle()
     {
         parent::handle();
@@ -78,7 +85,7 @@ class ApiAccountVerifyCredentialsAction extends ApiAuthAction
      *
      * @return boolean true
      */
-    function isReadOnly($args)
+    function isReadOnly(array $args=array())
     {
         return true;
     }
index 9e45a30fcc2e883434254f4ddd421b2b3747b714..6ee3eba5957766b01a78ef2986bfa50ab6265b68 100644 (file)
@@ -51,7 +51,7 @@ class ApiAtomServiceAction extends ApiBareAuthAction
      * @return boolean success flag
      *
      */
-    function prepare($args)
+    function prepare(array $args=array())
     {
         parent::prepare($args);
         $this->user = $this->getTargetUser($this->arg('id'));
@@ -71,7 +71,7 @@ class ApiAtomServiceAction extends ApiBareAuthAction
      *
      * @return void
      */
-    function handle($args)
+    function handle(array $args=array())
     {
         parent::handle($args);
 
index 505d50330e045ab5a095043c0eb6aa60d3967188..b92709f5d6419b9407f407c42fd2a91bb68f1324 100644 (file)
@@ -99,7 +99,7 @@ class ApiAttachmentAction extends ApiAuthAction
      * @return boolean is read only action?
      */
 
-    function isReadOnly($args)
+    function isReadOnly(array $args=array())
     {
         return true;
     }
index e11b7da4b75793a2cbf74382c1519ab9f2cf5ecb..19cc4d19f63041ec46480ef9335054357ba0761e 100644 (file)
@@ -108,7 +108,7 @@ class ApiCheckHubAction extends ApiAuthAction
      * @return boolean is read only action?
      */
 
-    function isReadOnly($args)
+    function isReadOnly(array $args=array())
     {
         return true;
     }
index 5e1102b2f6f415928dc1cabd4b05247738083459..728d62c24b6f7f9a2c7a3c3dfb431183627b6dc1 100644 (file)
@@ -156,7 +156,7 @@ class ApiconversationAction extends ApiAuthAction
      *
      * @return boolean is read only action?
      */
-    function isReadOnly($args)
+    function isReadOnly(array $args=array())
     {
         if ($_SERVER['REQUEST_METHOD'] == 'GET' ||
             $_SERVER['REQUEST_METHOD'] == 'HEAD') {
index 4e8419cf6b60723f2a561a4a5717ac26865fd2ee..2fe7450034f404adb108798abb4eb01d4d4c841f 100644 (file)
@@ -92,7 +92,7 @@ class ApiExternalProfileShowAction extends ApiPrivateAuthAction
      *
      * @return boolean is read only action?
      */
-    function isReadOnly($args)
+    function isReadOnly(array $args=array())
     {
         return true;
     }
index 4bb771292d61ab964fab7fef40954bf494ad7323..21d82f96fd13f20fc41cf77bf247ccc12709d355 100644 (file)
@@ -111,7 +111,7 @@ class ApiFriendshipsExistsAction extends ApiPrivateAuthAction
      *
      * @return boolean is read only action?
      */
-    function isReadOnly($args)
+    function isReadOnly(array $args=array())
     {
         return true;
     }
index c08e984b9ad3d2bb288efc36494e9b59566bafb5..31f47ce2f15f59dd0d07ded6e9991e0a9bf22cde 100644 (file)
@@ -162,7 +162,7 @@ class ApiFriendshipsShowAction extends ApiBareAuthAction
      * @return boolean is read only action?
      */
 
-    function isReadOnly($args)
+    function isReadOnly(array $args=array())
     {
         return true;
     }
index 813073a9edcb4bf959b4e713bb77b365734c81b0..e86a5636e3cb4e117c9c8a5e62454ec003d0e847 100644 (file)
@@ -141,7 +141,7 @@ class ApiGNUsocialConfigAction extends ApiAction
      *
      * @return boolean is read only action?
      */
-    function isReadOnly($args)
+    function isReadOnly(array $args=array())
     {
         return true;
     }
index a56630c666f5d33e6531f66e4f3c7cabe8fba0b7..772e40270d5c4e2050d82e4bb39e7c2fc724949d 100644 (file)
@@ -75,7 +75,7 @@ class ApiGNUsocialVersionAction extends ApiPrivateAuthAction
      *
      * @return boolean is read only action?
      */
-    function isReadOnly($args)
+    function isReadOnly(array $args=array())
     {
         return true;
     }
index e0b2475072c5dd9ed32321c4a439bb1a37ddd020..3754a831d4efe587c8d3f2a7a1557e807166c0ce 100644 (file)
@@ -139,7 +139,7 @@ class ApiGroupAdminsAction extends ApiPrivateAuthAction
      *
      * @return boolean true
      */
-    function isReadOnly($args)
+    function isReadOnly(array $args=array())
     {
         return true;
     }
index c085f7b3c1fbefaa7e1ae36d66f741512da99a5e..97ae325cb56c125d5489a15e6a785a66f8692424 100644 (file)
@@ -118,7 +118,7 @@ class ApiGroupIsMemberAction extends ApiBareAuthAction
      *
      * @return boolean is read only action?
      */
-    function isReadOnly($args)
+    function isReadOnly(array $args=array())
     {
         return true;
     }
index 1953752b020f6a67b07b3a83499c60b2c1759242..2f288bf04fe0d3d8fe674fdc2754cc13b2d922a2 100644 (file)
@@ -160,7 +160,7 @@ class ApiGroupListAction extends ApiBareAuthAction
      *
      * @return boolean true
      */
-    function isReadOnly($args)
+    function isReadOnly(array $args=array())
     {
         return true;
     }
index 2fb3714257f7677258a07390539d807771633888..6d7000e6b85f841e1be72bb5d8686863a4daf9f2 100644 (file)
@@ -58,7 +58,7 @@ class ApiGroupListAllAction extends ApiPrivateAuthAction
      *
      * @return boolean success flag
      */
-    function prepare($args)
+    function prepare(array $args=array())
     {
         parent::prepare($args);
 
@@ -77,7 +77,7 @@ class ApiGroupListAllAction extends ApiPrivateAuthAction
      *
      * @return void
      */
-    function handle($args)
+    function handle(array $args=array())
     {
         parent::handle($args);
 
@@ -159,7 +159,7 @@ class ApiGroupListAllAction extends ApiPrivateAuthAction
      *
      * @return boolean true
      */
-    function isReadOnly($args)
+    function isReadOnly(array $args=array())
     {
         return true;
     }
index 0e01f92f001dd1db76da5874b4feedba0bdb41f7..86ae091162fe1781b0a134391b12fef229469455 100644 (file)
@@ -130,7 +130,7 @@ class ApiGroupMembershipAction extends ApiPrivateAuthAction
      *
      * @return boolean true
      */
-    function isReadOnly($args)
+    function isReadOnly(array $args=array())
     {
         return true;
     }
index a1643302e1cab8b8ed11b51a484d403671efdf09..9a45d231a99e7fc94020e92499c4cb8cdeb0f68e 100644 (file)
@@ -156,7 +156,7 @@ class ApiGroupShowAction extends ApiPrivateAuthAction
      *
      * @return boolean is read only action?
      */
-    function isReadOnly($args)
+    function isReadOnly(array $args=array())
     {
         return true;
     }
index a9cd7394c92817b845246931f661039f80d407f6..a41ebc936732a2e8962267e099f61778175db796 100644 (file)
@@ -51,7 +51,7 @@ class ApiHelpTestAction extends ApiPrivateAuthAction
      *
      * @return boolean success flag
      */
-    function prepare($args)
+    function prepare(array $args=array())
     {
         parent::prepare($args);
         return true;
@@ -64,7 +64,7 @@ class ApiHelpTestAction extends ApiPrivateAuthAction
      *
      * @return void
      */
-    function handle($args)
+    function handle(array $args=array())
     {
         parent::handle($args);
 
@@ -95,7 +95,7 @@ class ApiHelpTestAction extends ApiPrivateAuthAction
      *
      * @return boolean is read only action?
      */
-    function isReadOnly($args)
+    function isReadOnly(array $args=array())
     {
         return true;
     }
index dc909e62a603bceca70929918ef3f7320997172f..94d95df5ef71f1744cb44747a8be3fa94bcd6e64 100644 (file)
@@ -194,7 +194,7 @@ class ApiListAction extends ApiBareAuthAction
      *
      * @return boolean is_read-only=false
      */
-    function isReadOnly($args)
+    function isReadOnly(array $args=array())
     {
         return false;
     }
index 04c771536306fa4779ea13165e24e98a944c716b..c1aa017deab1d1c35ada2db868df4210ff264092 100644 (file)
@@ -108,7 +108,7 @@ class ApiListMembershipsAction extends ApiBareAuthAction
      *
      * @return boolean is read only action?
      */
-    function isReadOnly($args)
+    function isReadOnly(array $args=array())
     {
         return true;
     }
index 4134577e099d27a2b4c9aa9368df8aba5f466e24..129691a3b42f8c58b09835c38b906c179f12dea4 100644 (file)
@@ -188,7 +188,7 @@ class ApiListsAction extends ApiBareAuthAction
              $this->prev_cursor) = Profile_list::getAtCursor($fn, array($this->auth_user), $cursor, $count);
     }
 
-    function isReadOnly($args)
+    function isReadOnly(array $args=array())
     {
         return false;
     }
index f5cda15ae94aa8ce17d47b74f1d797ac722536f8..a19ceec2fd93b18cf92550a04aedbc8a698b5045 100644 (file)
@@ -33,7 +33,7 @@ class ApiListSubscriberAction extends ApiBareAuthAction
 {
     var $list   = null;
 
-    function prepare($args)
+    function prepare(array $args=array())
     {
         parent::prepare($args);
 
@@ -52,7 +52,7 @@ class ApiListSubscriberAction extends ApiBareAuthAction
         return true;
     }
 
-    function handle($args)
+    function handle(array $args=array())
     {
         parent::handle($args);
 
index e5d8aebc4f7b74e5db898ae4c0fddf10fa061a55..5fe4c378ae40d4c0cc655cc2841fa0bfebd77664 100644 (file)
@@ -95,7 +95,7 @@ class ApiListSubscriptionsAction extends ApiBareAuthAction
      *
      * @return boolean is read only action?
      */
-    function isReadOnly($args)
+    function isReadOnly(array $args=array())
     {
         return true;
     }
index fd1ff565c74422a80bff4d97084644f7578d7d4b..c2b4a47b9a277d799acd799d5d1e2c4a597f22fb 100644 (file)
@@ -48,9 +48,6 @@ class ApiMediaUploadAction extends ApiAuthAction
      * Grab the file from the 'media' param, then store, and shorten
      *
      * @todo Upload throttle!
-     *
-     * @param array $args $_REQUEST data (unused)
-     *
      * @return void
      */
     protected function handle()
index a1a70a9b9e2be36aa949c163b1a142cca48863a9..20802466073f2cfc275327d4236d4fca5d0a2c00 100644 (file)
@@ -52,7 +52,7 @@ class ApiOAuthAccessTokenAction extends ApiOAuthAction
      *
      * @return void
      */
-    function handle($args)
+    function handle(array $args=array())
     {
         parent::handle($args);
 
index d0dcf9c9c7a48f065258eb4b27dc112b74d140db..68d19a398e2264fa6c9655f47248657e6f6f2c83 100644 (file)
@@ -55,12 +55,12 @@ class ApiOAuthAuthorizeAction extends ApiOAuthAction
      *
      * @return boolean false
      */
-    function isReadOnly($args)
+    function isReadOnly(array $args=array())
     {
         return false;
     }
 
-    function prepare($args)
+    function prepare(array $args=array())
     {
         parent::prepare($args);
 
@@ -88,7 +88,7 @@ class ApiOAuthAuthorizeAction extends ApiOAuthAction
      *
      * @return void
      */
-    function handle($args)
+    function handle(array $args=array())
     {
         parent::handle($args);
 
index e961f4f46464cf8463af219ba41a45f5a0cfb460..4f5a469caa9dbb1a5bb3db1ad83bb01052578577 100644 (file)
@@ -49,7 +49,7 @@ class ApiOAuthRequestTokenAction extends ApiOAuthAction
      *
      * @return boolean success flag
      */
-    function prepare($args)
+    function prepare(array $args=array())
     {
         parent::prepare($args);
 
@@ -69,7 +69,7 @@ class ApiOAuthRequestTokenAction extends ApiOAuthAction
      *
      * @return void
      */
-    function handle($args)
+    function handle(array $args=array())
     {
         parent::handle($args);
 
index b686edb00aeabb9a89e0243e23f1bf93ec6a59ae..c1aa43483e4549b1cc04b2b45d48997e301a78a8 100644 (file)
@@ -88,7 +88,7 @@ class ApiSearchAtomAction extends ApiPrivateAuthAction
      *
      * @return boolean success
      */
-    function prepare($args)
+    function prepare(array $args=array())
     {
         parent::prepare($args);
 
@@ -128,7 +128,7 @@ class ApiSearchAtomAction extends ApiPrivateAuthAction
      *
      * @return void
      */
-    function handle($args)
+    function handle(array $args=array())
     {
         parent::handle($args);
         common_debug("In apisearchatom handle()");
@@ -167,6 +167,12 @@ class ApiSearchAtomAction extends ApiPrivateAuthAction
 
         if ($this->cnt > 0) {
             while ($notice->fetch()) {
+                // Check scope of notice to current profile (including guests)
+                if (!$notice->isCurrentProfileInScope()) {
+                    // Not in scope
+                    continue;
+                }
+
                 ++$cnt;
 
                 if (!$this->max_id) {
index 794f23077bacbc1184c972888dad3c7db2b774c8..4b46109b982e1d1988e3531a0c0539d641aa8f43 100644 (file)
@@ -57,7 +57,7 @@ class ApiSearchJSONAction extends ApiPrivateAuthAction
      *
      * @return boolean true if nothing goes wrong
      */
-    function prepare($args)
+    function prepare(array $args=array())
     {
         parent::prepare($args);
 
@@ -95,7 +95,7 @@ class ApiSearchJSONAction extends ApiPrivateAuthAction
      *
      * @return void
      */
-    function handle($args)
+    function handle(array $args=array())
     {
         parent::handle($args);
         $this->showResults();
@@ -118,7 +118,16 @@ class ApiSearchJSONAction extends ApiPrivateAuthAction
         $search_engine->limit(($this->page - 1) * $this->rpp, $this->rpp + 1);
         if ($search_engine->query($this->query)) {
             $cnt = $notice->find();
-            $this->notices = $notice->fetchAll();
+            foreach ($notice->fetchAll() as $testNotice) {
+                // Must be true
+                assert($testNotice instanceof Notice);
+
+                // Check scope of notice to current profile (including guests)
+                if ($testNotice->isCurrentProfileInScope()) {
+                    // In scope
+                    $this->notices[] = $testNotice;
+                }
+            } // END - if
         }
 
        $this->showJsonTimeline($this->notices);
@@ -129,7 +138,7 @@ class ApiSearchJSONAction extends ApiPrivateAuthAction
      *
      * @return boolean true
      */
-    function isReadOnly($args)
+    function isReadOnly(array $args=array())
     {
         return true;
     }
index 2d32124c42d48bcd984f0423848f1b374cb05322..e1783f258ac5728f7936e827b0678c0377047cad 100644 (file)
@@ -64,7 +64,7 @@ class ApiStatusesDestroyAction extends ApiAuthAction
      *
      * @return boolean success flag
      */
-    function prepare($args)
+    function prepare(array $args=array())
     {
         parent::prepare($args);
 
@@ -89,7 +89,7 @@ class ApiStatusesDestroyAction extends ApiAuthAction
      *
      * @return void
      */
-    function handle($args)
+    function handle(array $args=array())
     {
         parent::handle($args);
 
index 70b9a9c27a49427fc3ab6eed4ed5cea7bb92c9d5..988ed804e91fddf7c52ea80639afbfb76d84c485 100644 (file)
@@ -176,7 +176,7 @@ class ApiStatusesShowAction extends ApiPrivateAuthAction
      * @return boolean true
      */
 
-    function isReadOnly($args)
+    function isReadOnly(array $args=array())
     {
         return ($_SERVER['REQUEST_METHOD'] == 'GET' || $_SERVER['REQUEST_METHOD'] == 'HEAD');
     }
index 081445129dfd37e4f35785cd0a3f2a84aa4cd592..3f5d5f797b32d84f408ee4a922623b1115ff435d 100644 (file)
@@ -129,7 +129,7 @@ abstract class ApiSubscriptionsAction extends ApiBareAuthAction
      *
      * @return boolean true
      */
-    function isReadOnly($args)
+    function isReadOnly(array $args=array())
     {
         return true;
     }
index b14635ac33e5fcf6662d05f7d79f098639476317..b809699c7f4d154d845452b78c413c85b64f1b9f 100644 (file)
@@ -295,7 +295,7 @@ class ApiTimelineFriendsAction extends ApiBareAuthAction
      *
      * @return boolean true
      */
-    function isReadOnly($args)
+    function isReadOnly(array $args=array())
     {
         return true;
     }
index 4201eb55f83b0eaf59d0d515786314a551170aa3..c9d375d4c98bcd769eeb5452dbf74054e2d94f72 100644 (file)
@@ -171,7 +171,7 @@ class ApiTimelineGroupAction extends ApiPrivateAuthAction
      *
      * @return boolean true
      */
-    function isReadOnly($args)
+    function isReadOnly(array $args=array())
     {
         return true;
     }
index 42cd08cad75e276f93396d8dc5168fbec156c195..5dca9a42cd19d9536a5141556c1d007543ffb805 100644 (file)
@@ -199,7 +199,7 @@ class ApiTimelineHomeAction extends ApiBareAuthAction
      *
      * @return boolean true
      */
-    function isReadOnly($args)
+    function isReadOnly(array $args=array())
     {
         return true;
     }
index 91b26bf6c7714dc3465e963d7c961a88a9a39504..75c9da034da347ad23a21628602d8eaeb741201d 100644 (file)
@@ -199,7 +199,7 @@ class ApiTimelineListAction extends ApiPrivateAuthAction
      *
      * @return boolean true
      */
-    function isReadOnly($args)
+    function isReadOnly(array $args=array())
     {
         return true;
     }
index c1811ac01bb77e9fcdc23385f7136cb3581f8b2e..6465cdf85e58ec6e525a866b233a69567679a56d 100644 (file)
@@ -204,7 +204,7 @@ class ApiTimelineMentionsAction extends ApiBareAuthAction
      *
      * @return boolean true
      */
-    function isReadOnly($args)
+    function isReadOnly(array $args=array())
     {
         return true;
     }
index 07dcace942457b254660005ca48b18135c5e837d..957c187f9ff6b938a2cb403781b465b203cccd0e 100644 (file)
@@ -286,7 +286,7 @@ class ApiTimelinePublicAction extends ApiPrivateAuthAction
      *
      * @return boolean true
      */
-    function isReadOnly($args)
+    function isReadOnly(array $args=array())
     {
         return true;
     }
index 1184440c7ddd9742f8388ad84130e61b8e53d9e5..08b2f083563d805ee341ec281f428e5dedf2fc3d 100644 (file)
@@ -178,7 +178,7 @@ class ApiTimelineTagAction extends ApiPrivateAuthAction
      *
      * @return boolean true
      */
-    function isReadOnly($args)
+    function isReadOnly(array $args=array())
     {
         return true;
     }
index 5debe3ed8ca0d6550e6161bd53d21e21f24f7e77..f593b4da21b6764c54679126e6cff3e561e8838e 100644 (file)
@@ -270,7 +270,7 @@ class ApiTimelineUserAction extends ApiBareAuthAction
      * @return boolean true
      */
 
-    function isReadOnly($args)
+    function isReadOnly(array $args=array())
     {
         return ($_SERVER['REQUEST_METHOD'] == 'GET' || $_SERVER['REQUEST_METHOD'] == 'HEAD');
     }
index a39769a34e60024fb1744d2ecc2cba109d2bf678..6e6810b95d2ffad61f2cefcd0c02afa8d673d1d3 100644 (file)
@@ -53,7 +53,7 @@ class ApiTrendsAction extends ApiPrivateAuthAction
      *
      * @return boolean false if user doesn't exist
      */
-    function prepare($args)
+    function prepare(array $args=array())
     {
         parent::prepare($args);
         return true;
@@ -66,7 +66,7 @@ class ApiTrendsAction extends ApiPrivateAuthAction
      *
      * @return void
      */
-    function handle($args)
+    function handle(array $args=array())
     {
         parent::handle($args);
         $this->showTrends();
index 47fc5e69ac1d0b33dd6d56d71de732badfca4bf2..c9c8eab9af5fce75c3bcf2876a53dc9c752063b5 100644 (file)
@@ -110,7 +110,7 @@ class ApiUserProfileImageAction extends ApiPrivateAuthAction
      *
      * @return boolean is read only action?
      */
-    function isReadOnly($args)
+    function isReadOnly(array $args=array())
     {
         return true;
     }
index 35b50698609baa6ea84da23ddb641925e57e43aa..04fcb7dd8961f500a259ae5dc9a42735632d3678 100644 (file)
@@ -118,7 +118,7 @@ class ApiUserShowAction extends ApiPrivateAuthAction
      *
      * @return boolean is read only action?
      */
-    function isReadOnly($args)
+    function isReadOnly(array $args=array())
     {
         return true;
     }
index 2c8b354d347539bba7a630b81a640ef09e6bdf1a..b532a9b95541837273fdc41ff4ef540e703c55cd 100644 (file)
@@ -50,7 +50,7 @@ class ApprovegroupAction extends Action
     /**
      * Prepare to run
      */
-    function prepare($args)
+    function prepare(array $args=array())
     {
         parent::prepare($args);
 
@@ -139,7 +139,7 @@ class ApprovegroupAction extends Action
      *
      * @return void
      */
-    function handle($args)
+    function handle(array $args=array())
     {
         parent::handle($args);
 
index c9fa804412a97b4abd0669c38be051b77cc81a64..0e70e3429ec995781b8989d6da9a9340d2f6d9d5 100644 (file)
@@ -50,7 +50,7 @@ class ApprovesubAction extends Action
     /**
      * Prepare to run
      */
-    function prepare($args)
+    function prepare(array $args=array())
     {
         parent::prepare($args);
 
@@ -97,7 +97,7 @@ class ApprovesubAction extends Action
      *
      * @return void
      */
-    function handle($args)
+    function handle(array $args=array())
     {
         parent::handle($args);
         $cur = common_current_user();
index ee5a477d49eca4a75d04264b8137f8dd4c33260e..d80dd609e3aba1dfcff24f222d3127f7d8e9d01a 100644 (file)
@@ -132,7 +132,7 @@ class AtompubshowsubscriptionAction extends AtompubAction
      *
      * @return boolean true
      */
-    function isReadOnly($args)
+    function isReadOnly(array $args=array())
     {
         if ($_SERVER['REQUEST_METHOD'] == 'DELETE') {
             return false;
index 1126759832a65799744a29c67c6c257d80a8ddb5..0bdead84a07e62806c4a7306c1c8d3c9f197e52e 100644 (file)
@@ -76,7 +76,7 @@ class AttachmentAction extends ManagedAction
      *
      * @return boolean true
      */
-    function isReadOnly($args)
+    function isReadOnly(array $args=array())
     {
         return true;
     }
index 10a22e77bc199c61627b836135aaa600e3c0f898..b366c62d80259181ee07f793a2f82ff24461d9d0 100644 (file)
@@ -85,7 +85,7 @@ class AvatarbynicknameAction extends Action
         common_redirect($url, 302);
     }
 
-    function isReadOnly($args)
+    function isReadOnly(array $args=array())
     {
         return true;
     }
index 8f642f3b7708e61463237cfe74f80916fb955f3f..4d7b6fcfcd653f4ed2b5f0d978b3ed83ffb5e9f4 100644 (file)
@@ -149,7 +149,7 @@ class BackupaccountAction extends Action
      *
      * @return boolean is read only action?
      */
-    function isReadOnly($args)
+    function isReadOnly(array $args=array())
     {
         return true;
     }
index 53d8ae7ae0600c17a800cfc5e927a7efd40facfd..018c6782fcbd5f368b1a856dfcde64c62e5e03e8 100644 (file)
@@ -53,7 +53,7 @@ class BlockAction extends ProfileFormAction
      *
      * @return boolean success flag
      */
-    function prepare($args)
+    function prepare(array $args=array())
     {
         if (!parent::prepare($args)) {
             return false;
@@ -78,7 +78,7 @@ class BlockAction extends ProfileFormAction
      *
      * @return void
      */
-    function handle($args)
+    function handle(array $args=array())
     {
         if ($_SERVER['REQUEST_METHOD'] == 'POST') {
             if ($this->arg('no')) {
@@ -220,7 +220,8 @@ class BlockAction extends ProfileFormAction
     function defaultReturnTo()
     {
         $user = common_current_user();
-        if ($user) {
+
+        if ($user instanceof User) {
             return common_local_url('subscribers',
                                     array('nickname' => $user->nickname));
         } else {
index a2e7c5767f64be9610681f638be8ef899140ff0a..60f108dee383a333a35dbcec167655cd1c10512d 100644 (file)
@@ -44,7 +44,7 @@ class BlockedfromgroupAction extends GroupAction
 {
     var $page = null;
 
-    function isReadOnly($args)
+    function isReadOnly(array $args=array())
     {
         return true;
     }
@@ -151,7 +151,7 @@ class GroupBlockList extends ProfileList
         $this->group = $group;
     }
 
-    function newListItem($profile)
+    function newListItem(Profile $profile)
     {
         return new GroupBlockListItem($profile, $this->group, $this->action);
     }
index 93f630e0609123a59757bc96fc880279b1bdcffe..90675d79bc8146177eb51c63aa73bc5f09ab7c2c 100644 (file)
@@ -50,7 +50,7 @@ class CancelgroupAction extends Action
     /**
      * Prepare to run
      */
-    function prepare($args)
+    function prepare(array $args=array())
     {
         parent::prepare($args);
 
@@ -127,7 +127,7 @@ class CancelgroupAction extends Action
      *
      * @return void
      */
-    function handle($args)
+    function handle(array $args=array())
     {
         parent::handle($args);
 
index 806851001e3cf45e4a0f13717b9589b8cd89060d..e2e8c1b834100b85a961341fa8c5b9c53dcb1a99 100644 (file)
@@ -60,7 +60,7 @@ class ConfirmaddressAction extends Action
      *
      * @return void
      */
-    function handle($args)
+    function handle(array $args=array())
     {
         parent::handle($args);
         if (!common_logged_in()) {
index 8b80c6c6f23c503f1d52d82c80cd6535b035aa62..cd7f6578fcbb5eec2afa2c30afeaa64841edfb93 100644 (file)
@@ -108,7 +108,7 @@ class DeleteaccountAction extends Action
      *
      * @return boolean is read only action?
      */
-    function isReadOnly($args)
+    function isReadOnly(array $args=array())
     {
         return false;
     }
index 5d7441098c8f73f1068491d5509208935626420e..1d9e6d1bb5bf84c6ebc715c882782d1522541772 100644 (file)
@@ -51,7 +51,7 @@ class DeleteapplicationAction extends Action
      *
      * @return boolean success flag
      */
-    function prepare($args)
+    function prepare(array $args=array())
     {
         if (!parent::prepare($args)) {
             return false;
@@ -89,7 +89,7 @@ class DeleteapplicationAction extends Action
      *
      * @return void
      */
-    function handle($args)
+    function handle(array $args=array())
     {
         if ($_SERVER['REQUEST_METHOD'] == 'POST') {
 
index c64bc1d8e90fd47fb91cfd4d0cd4743b358f8ad0..87f518eb41ca22b702cae9db8b5479bd32012785 100644 (file)
@@ -55,7 +55,7 @@ class DeletegroupAction extends RedirectingAction
      * @fixme merge common setup code with other group actions
      * @fixme allow group admins to delete their own groups
      */
-    function prepare($args)
+    function prepare(array $args=array())
     {
         parent::prepare($args);
 
@@ -114,7 +114,7 @@ class DeletegroupAction extends RedirectingAction
      *
      * @return void
      */
-    function handle($args)
+    function handle(array $args=array())
     {
         parent::handle($args);
         if ($_SERVER['REQUEST_METHOD'] == 'POST') {
index 6b74575ab435e0d149b53ef788ca4fafde95c4d5..fd0beb80acd0b8b9b6d00e7bd64ea3d1bd5d846a 100644 (file)
@@ -51,7 +51,7 @@ class DeleteuserAction extends ProfileFormAction
      *
      * @return boolean success flag
      */
-    function prepare($args)
+    function prepare(array $args=array())
     {
         if (!parent::prepare($args)) {
             return false;
@@ -85,7 +85,7 @@ class DeleteuserAction extends ProfileFormAction
      *
      * @return void
      */
-    function handle($args)
+    function handle(array $args=array())
     {
         if ($_SERVER['REQUEST_METHOD'] == 'POST') {
             if ($this->arg('no')) {
index 694544dd038c0a02ce6ec47e15bcdb835546535d..d897b4e58c5131d452066c57c52a58a456847bd9 100644 (file)
@@ -86,7 +86,7 @@ class DocAction extends ManagedAction
      *
      * @return boolean read-only flag (false)
      */
-    function isReadOnly($args)
+    function isReadOnly(array $args=array())
     {
         return true;
     }
index c7e5f9052c77fc81271687f72fd09edd34496c18..95ed98ad90ddf57e74cfa40eabbb9af0f97f2c38 100644 (file)
@@ -57,7 +57,7 @@ class EditApplicationAction extends Action
     /**
      * Prepare to run
      */
-    function prepare($args)
+    function prepare(array $args=array())
     {
         parent::prepare($args);
 
@@ -94,7 +94,7 @@ class EditApplicationAction extends Action
      *
      * @return void
      */
-    function handle($args)
+    function handle(array $args=array())
     {
         parent::handle($args);
 
index 45c8adaa7d59fc933a4ec70ddb157c5dfebfdc0f..4e00cb2442e1c6a36b129ce78f5d074c954b5b20 100644 (file)
@@ -60,7 +60,7 @@ class EditpeopletagAction extends Action
      * Prepare to run
      */
 
-    function prepare($args)
+    function prepare(array $args=array())
     {
         parent::prepare($args);
 
@@ -135,7 +135,7 @@ class EditpeopletagAction extends Action
      *
      * @return void
      */
-    function handle($args)
+    function handle(array $args=array())
     {
         parent::handle($args);
         if ($_SERVER['REQUEST_METHOD'] == 'POST') {
index 394cfe6a8b9ef456325179533a3e5c00dbb48cc5..dfd9f6f3befd834dee8b9443b882945042e6d26c 100644 (file)
@@ -49,12 +49,12 @@ class FeaturedAction extends Action
 {
     var $page = null;
 
-    function isReadOnly($args)
+    function isReadOnly(array $args=array())
     {
         return true;
     }
 
-    function prepare($args)
+    function prepare(array $args=array())
     {
         parent::prepare($args);
         $this->page = ($this->arg('page')) ? ($this->arg('page')+0) : 1;
@@ -74,7 +74,7 @@ class FeaturedAction extends Action
         }
     }
 
-    function handle($args)
+    function handle(array $args=array())
     {
         parent::handle($args);
 
index 260388ba447b72819ea0f908e4da35e9ade80391..4420c2d5036cc59bf6bb4ad08fbcacce749e436a 100644 (file)
@@ -26,7 +26,7 @@ define('BOTH', 0);
 // @todo XXX: Documentation missing.
 class FoafAction extends ManagedAction
 {
-    function isReadOnly($args)
+    function isReadOnly(array $args=array())
     {
         return true;
     }
index f9c61ac5dcda9f7a409917ec569fc82e59d84af9..a9cf5d9dc0964e7fe01049c82030a3829ef85609 100644 (file)
@@ -30,12 +30,12 @@ if (!defined('STATUSNET') && !defined('LACONICA')) { exit(1); }
 // @todo XXX: Documentation missing.
 class FoafGroupAction extends Action
 {
-    function isReadOnly($args)
+    function isReadOnly(array $args=array())
     {
         return true;
     }
 
-    function prepare($args)
+    function prepare(array $args=array())
     {
         parent::prepare($args);
 
@@ -76,7 +76,7 @@ class FoafGroupAction extends Action
         return true;
     }
 
-    function handle($args)
+    function handle(array $args=array())
     {
         parent::handle($args);
 
index 9e208914c16ca088cf63cd7f08c43e07eb83cefc..a0cd2fa159ff127e3b80e29377bc25af00da3235 100644 (file)
@@ -47,7 +47,7 @@ class GeocodeAction extends Action
     var $lon = null;
     var $location = null;
 
-    function prepare($args)
+    function prepare(array $args=array())
     {
         parent::prepare($args);
         $token = $this->trimmed('token');
@@ -70,7 +70,7 @@ class GeocodeAction extends Action
      * @return nothing
      *
      */
-    function handle($args)
+    function handle(array $args=array())
     {
         header('Content-Type: application/json; charset=utf-8');
         $location_object = array();
@@ -90,7 +90,7 @@ class GeocodeAction extends Action
      *
      * @return boolean true
      */
-    function isReadOnly($args)
+    function isReadOnly(array $args=array())
     {
         return true;
     }
index f0c98f74167702ef6bcdc4daeffb2f5e1d67f055..abdf5b69fc3904928e06419fff0ce467a967cf00 100644 (file)
@@ -86,7 +86,7 @@ class GetfileAction extends Action
      *
      * @return boolean true
      */
-    function isReadOnly($args)
+    function isReadOnly(array $args=array())
     {
         return true;
     }
index 35f0dcf961d02fc328466cc163f56fbec3407fd7..59cb1cdd8eb39d320bc79b1db9e34a72ff3b5f75 100644 (file)
@@ -49,7 +49,7 @@ class GrantRoleAction extends ProfileFormAction
      *
      * @return boolean success flag
      */
-    function prepare($args)
+    function prepare(array $args=array())
     {
         if (!parent::prepare($args)) {
             return false;
index d65b62bdff7980128e5d634ddc687729448973d0..209284a85d5a003dfb1d81dd8288194c68289534 100644 (file)
@@ -52,7 +52,7 @@ class GroupblockAction extends RedirectingAction
      *
      * @return boolean success flag
      */
-    function prepare($args)
+    function prepare(array $args=array())
     {
         parent::prepare($args);
         if (!common_logged_in()) {
@@ -110,7 +110,7 @@ class GroupblockAction extends RedirectingAction
      *
      * @return void
      */
-    function handle($args)
+    function handle(array $args=array())
     {
         parent::handle($args);
         if ($_SERVER['REQUEST_METHOD'] == 'POST') {
index 44c4dd6f9963d27dbda9bbcf1a8be576f03e306b..b83854d043f74d4cbf1a9571e31eae0aab779f9f 100644 (file)
@@ -47,7 +47,7 @@ class GroupmembersAction extends GroupAction
 {
     var $page = null;
 
-    function isReadOnly($args)
+    function isReadOnly(array $args=array())
     {
         return true;
     }
index c50eff36f83c5bc9279bacdc5d3095db15000ec0..060b5a2e7d10753a61feca6f0bb4c2cb6e2896c4 100644 (file)
@@ -47,7 +47,7 @@ class GroupqueueAction extends GroupAction
 {
     var $page = null;
 
-    function isReadOnly($args)
+    function isReadOnly(array $args=array())
     {
         return true;
     }
@@ -153,7 +153,7 @@ class GroupqueueAction extends GroupAction
 // @todo FIXME: documentation missing.
 class GroupQueueList extends GroupMemberList
 {
-    function newListItem($profile)
+    function newListItem(Profile $profile)
     {
         return new GroupQueueListItem($profile, $this->group, $this->action);
     }
index 14d85d89cd9e5c06a8ceed43e85011289a11620e..166118b4ea7c76d0c28197d3591049d8da5291cf 100644 (file)
@@ -51,7 +51,7 @@ class GroupRssAction extends TargetedRss10Action
      *
      * @return boolean true
      */
-    function isReadOnly($args)
+    function isReadOnly(array $args=array())
     {
         return true;
     }
index d1bc8d94583bd67169dfaad27d7bde211d1934a1..1bbce26f20cf2f6ba3ca71fb9462175004f06ffc 100644 (file)
@@ -50,7 +50,7 @@ class GroupsAction extends Action
     var $page = null;
     var $profile = null;
 
-    function isReadOnly($args)
+    function isReadOnly(array $args=array())
     {
         return true;
     }
@@ -67,14 +67,14 @@ class GroupsAction extends Action
         }
     }
 
-    function prepare($args)
+    function prepare(array $args=array())
     {
         parent::prepare($args);
         $this->page = ($this->arg('page')) ? ($this->arg('page')+0) : 1;
         return true;
     }
 
-    function handle($args)
+    function handle(array $args=array())
     {
         parent::handle($args);
         $this->showPage();
index a24177f64c0d94d8a50dd5b06abfa7066ac2ec09..a72486be487ce31acccd6b0616d95dfa01c3fb22 100644 (file)
@@ -52,7 +52,7 @@ class GroupunblockAction extends Action
      *
      * @return boolean success flag
      */
-    function prepare($args)
+    function prepare(array $args=array())
     {
         parent::prepare($args);
         if (!common_logged_in()) {
@@ -103,7 +103,7 @@ class GroupunblockAction extends Action
      *
      * @return void
      */
-    function handle($args)
+    function handle(array $args=array())
     {
         parent::handle($args);
         if ($_SERVER['REQUEST_METHOD'] == 'POST') {
index 89b7e83bf6d19a32899e05db5fe2b32ac1439cb3..0deb7a76ee2d997a5dd66236fc5fc1774e31e1cc 100644 (file)
@@ -33,12 +33,12 @@ class InviteAction extends Action
         return;
     }
 
-    function isReadOnly($args)
+    function isReadOnly(array $args=array())
     {
         return false;
     }
 
-    function handle($args)
+    function handle(array $args=array())
     {
         parent::handle($args);
         if (!common_config('invite', 'enabled')) {
@@ -74,6 +74,7 @@ class InviteAction extends Action
             $bestname = $profile->getBestName();
             $sitename = common_config('site', 'name');
             $personal = $this->trimmed('personal');
+            $language = $this->trimmed('language');
 
             $addresses = explode("\n", $this->trimmed('addresses'));
             foreach ($addresses as $email) {
@@ -128,7 +129,7 @@ class InviteAction extends Action
                 } catch (NoSuchUserException $e) {
                     // If email was not known, let's send an invite!
                     $this->sent[] = $email;
-                    $this->sendInvitation($email, $user, $personal);
+                    $this->sendInvitation($email, $user, $personal, $language);
                 }
             }
 
@@ -248,7 +249,7 @@ class InviteAction extends Action
         }
     }
 
-    function sendInvitation($email, $user, $personal)
+    function sendInvitation($email, $user, $personal, $language)
     {
         $profile = $user->getProfile();
         $bestname = $profile->getBestName();
@@ -284,7 +285,7 @@ class InviteAction extends Action
         $title = (empty($personal)) ? 'invite' : 'invitepersonal';
 
         // @todo FIXME: i18n issue.
-        $inviteTemplate = DocFile::forTitle($title, DocFile::mailPaths());
+        $inviteTemplate = DocFile::forTitle($title, DocFile::mailPaths(), $language);
 
         $body = $inviteTemplate->toHTML(array('inviter' => $bestname,
                                               'inviterurl' => $profile->profileurl,
index 5394a38c9fb573684ae8e28ff3ad95c0210f666a..b9dfe3b8114b58106448706f5c5bf7d6b8c634c9 100644 (file)
@@ -47,11 +47,16 @@ class LogoutAction extends ManagedAction
      *
      * @return boolean true
      */
-    function isReadOnly($args)
+    function isReadOnly(array $args=array())
     {
         return false;
     }
 
+    /**
+     * Class handler.
+     *
+     * @return nothing
+     */
     protected function doPreparation()
     {
         if (!common_logged_in()) {
index 05912e150cc4d493b537394c836edba78705aa1c..24a7c02ee8ae8d459c32b99aa162706976796de4 100644 (file)
@@ -54,7 +54,7 @@ class MakeadminAction extends RedirectingAction
      * @return boolean success flag
      */
 
-    function prepare($args)
+    function prepare(array $args=array())
     {
         parent::prepare($args);
         if (!common_logged_in()) {
@@ -111,7 +111,7 @@ class MakeadminAction extends RedirectingAction
      * @return void
      */
 
-    function handle($args)
+    function handle(array $args=array())
     {
         parent::handle($args);
         if ($_SERVER['REQUEST_METHOD'] == 'POST') {
index 2742eb9a048f8977dcc0e674949a25605826b490..03348617da9b1541b9094f1b85129dea234eda5b 100644 (file)
@@ -51,7 +51,7 @@ class MicrosummaryAction extends Action
      *
      * @return nothing
      */
-    function handle($args)
+    function handle(array $args=array())
     {
         parent::handle($args);
 
@@ -75,7 +75,7 @@ class MicrosummaryAction extends Action
         print $user->nickname . ': ' . $notice->content;
     }
 
-    function isReadOnly($args)
+    function isReadOnly(array $args=array())
     {
         return true;
     }
index fd8fdf68e52f38139956ab5350aca4e1cee44a97..bcd2eb5065009597d1f079e5b89f109fed6d3a3b 100644 (file)
@@ -50,7 +50,7 @@ class NoticesearchAction extends SearchAction
 {
     protected $q = null;
 
-    function prepare($args)
+    function prepare(array $args=array())
     {
         parent::prepare($args);
 
@@ -186,7 +186,7 @@ class SearchNoticeList extends NoticeList {
         $this->terms = $terms;
     }
 
-    function newListItem($notice)
+    function newListItem(Notice $notice)
     {
         return new SearchNoticeListItem($notice, $this->out, $this->terms);
     }
index 2a5187b885dba53f440a1553fb1fc2eb3a261fb0..2e3a0548e5be7aca5f7c1b13ba03ed55d9a677cd 100644 (file)
@@ -63,7 +63,11 @@ class NoticesearchrssAction extends Rss10Action
 
         if ($cnt > 0) {
             while ($notice->fetch()) {
-                $notices[] = clone($notice);
+                // Check scope of notice to current profile (including guests)
+                if ($notice->isCurrentProfileInScope()) {
+                    // Is in scope
+                    $notices[] = clone($notice);
+                }
             }
         }
 
@@ -89,7 +93,7 @@ class NoticesearchrssAction extends Rss10Action
         return null;
     }
 
-    function isReadOnly($args)
+    function isReadOnly(array $args=array())
     {
         return true;
     }
index 801d1f06810aa343dbfe78e2cb37e005db519cd8..5ceaa180636c76e743fa4d587b355d0dba9e7299 100644 (file)
@@ -55,7 +55,7 @@ class NudgeAction extends Action
      *
      * @return nothing
      */
-    function handle($args)
+    function handle(array $args=array())
     {
         parent::handle($args);
 
@@ -125,7 +125,7 @@ class NudgeAction extends Action
         }
     }
 
-    function isReadOnly($args)
+    function isReadOnly(array $args=array())
     {
         return true;
     }
index b1529860a87487cd3382211e3fe4e7260a49e0c6..c3a494be1be23d65012b0da05791a3d64c619fd5 100644 (file)
@@ -53,7 +53,7 @@ class OpensearchAction extends Action
      *
      * @return boolean false if user doesn't exist
      */
-    function handle($args)
+    function handle(array $args=array())
     {
         parent::handle($args);
         $type       = $this->trimmed('type');
@@ -85,7 +85,7 @@ class OpensearchAction extends Action
         $this->endXML();
     }
 
-    function isReadOnly($args)
+    function isReadOnly(array $args=array())
     {
         return true;
     }
index c44f3673ae7524f2902158a67fa645dcfec10fb9..143eb6bdc189c05d0362761e1012b9f51e2cd4ff 100644 (file)
@@ -53,7 +53,7 @@ class OtpAction extends Action
     var $returnto;
     var $lt;
 
-    function prepare($args)
+    function prepare(array $args=array())
     {
         parent::prepare($args);
 
@@ -110,7 +110,7 @@ class OtpAction extends Action
         return true;
     }
 
-    function handle($args)
+    function handle(array $args=array())
     {
         parent::handle($args);
 
index b0a6e2635deb72b94a2cb63b2de2ebe2e72418f9..46bdd165cf3566ad9f193b2e7c1ac21034bb480e 100644 (file)
@@ -44,7 +44,7 @@ class PeopletagAction extends Action
     var $page = null;
     var $tag = null;
 
-    function isReadOnly($args)
+    function isReadOnly(array $args=array())
     {
         return true;
     }
@@ -62,7 +62,7 @@ class PeopletagAction extends Action
         }
     }
 
-    function prepare($args)
+    function prepare(array $args=array())
     {
         parent::prepare($args);
         $this->page = ($this->arg('page')) ? ($this->arg('page')+0) : 1;
@@ -84,7 +84,7 @@ class PeopletagAction extends Action
         return true;
     }
 
-    function handle($args)
+    function handle(array $args=array())
     {
         parent::handle($args);
         $this->showPage();
index 86d63545dcb0b4ed2aa4040e78aef8e8ebf9899e..dc083fd0282b3d7c39862d53a9a49b211d2a088e 100644 (file)
@@ -44,7 +44,7 @@ class PeopletagautocompleteAction extends Action
      *
      * @return boolean success flag
      */
-    function prepare($args)
+    function prepare(array $args=array())
     {
         parent::prepare($args);
 
@@ -112,9 +112,9 @@ class PeopletagautocompleteAction extends Action
      *
      * @return void
      */
-    function handle($args)
+    function handle(array $args=array())
     {
-        //common_log(LOG_DEBUG, 'Autocomplete data: ' . json_encode($this->tags));
+        //common_debug('Autocomplete data: ' . json_encode($this->tags));
         if ($this->tags) {
             print(json_encode($this->tags));
             exit(0);
index cf9ec053ed404b64b243c8bfeeb8ccde3a0bb46d..98e0cd7125c009b8306881c7ddf2e88816117c9c 100644 (file)
@@ -48,12 +48,12 @@ class PeopletaggedAction extends Action
     var $peopletag = null;
     var $tagger = null;
 
-    function isReadOnly($args)
+    function isReadOnly(array $args=array())
     {
         return true;
     }
 
-    function prepare($args)
+    function prepare(array $args=array())
     {
         parent::prepare($args);
         $this->page = ($this->arg('page')) ? ($this->arg('page')+0) : 1;
@@ -117,7 +117,7 @@ class PeopletaggedAction extends Action
         }
     }
 
-    function handle($args)
+    function handle(array $args=array())
     {
         parent::handle($args);
         $this->showPage();
@@ -167,7 +167,7 @@ class PeopletagMemberList extends ProfileList
         $this->peopletag = $peopletag;
     }
 
-    function newListItem($profile)
+    function newListItem(Profile $profile)
     {
         return new PeopletagMemberListItem($profile, $this->peopletag, $this->action);
     }
index 8b3a91917a5f0611b7fbebbc8b847edba393e67f..9a5f9106f41086885f271459874b0448632b3af8 100644 (file)
@@ -39,7 +39,7 @@ class PeopletagsbyuserAction extends Action
     var $tagger = null;
     var $tags = null;
 
-    function isReadOnly($args)
+    function isReadOnly(array $args=array())
     {
         return true;
     }
@@ -68,7 +68,7 @@ class PeopletagsbyuserAction extends Action
         }
     }
 
-    function prepare($args)
+    function prepare(array $args=array())
     {
         parent::prepare($args);
 
@@ -135,15 +135,15 @@ class PeopletagsbyuserAction extends Action
         return true;
     }
 
-    function handle($args)
+    function handle(array $args=array())
     {
         parent::handle($args);
 
-               # Post from the tag dropdown; redirect to a GET
+        // Post from the tag dropdown; redirect to a GET
 
-               if ($_SERVER['REQUEST_METHOD'] == 'POST') {
-                   common_redirect(common_local_url('peopletagsbyuser', $this->getSelfUrlArgs()), 303);
-               }
+        if ($_SERVER['REQUEST_METHOD'] == 'POST') {
+            common_redirect(common_local_url('peopletagsbyuser', $this->getSelfUrlArgs()), 303);
+        }
 
         $this->showPage();
     }
index 827b284d5c3acf567cf550f5afdae99ed06c721b..9dcee09f1a1b44ca9eeb1789f3ed761703c39f27 100644 (file)
@@ -38,7 +38,7 @@ class PeopletagsforuserAction extends Action
     var $page = null;
     var $tagged = null;
 
-    function isReadOnly($args)
+    function isReadOnly(array $args=array())
     {
         return true;
     }
@@ -54,7 +54,7 @@ class PeopletagsforuserAction extends Action
         }
     }
 
-    function prepare($args)
+    function prepare(array $args=array())
     {
         parent::prepare($args);
 
@@ -95,7 +95,7 @@ class PeopletagsforuserAction extends Action
         return true;
     }
 
-    function handle($args)
+    function handle(array $args=array())
     {
         parent::handle($args);
         $this->showPage();
index 589d49caa3be8469eddc6c3b7ba456039bf482c8..dcb3af5c9fba43f3032832931c4c472e8bde2512 100644 (file)
@@ -48,12 +48,12 @@ class PeopletagsubscribersAction extends Action
     var $peopletag = null;
     var $tagger = null;
 
-    function isReadOnly($args)
+    function isReadOnly(array $args=array())
     {
         return true;
     }
 
-    function prepare($args)
+    function prepare(array $args=array())
     {
         parent::prepare($args);
         $this->page = ($this->arg('page')) ? ($this->arg('page')+0) : 1;
@@ -117,7 +117,7 @@ class PeopletagsubscribersAction extends Action
         }
     }
 
-    function handle($args)
+    function handle(array $args=array())
     {
         parent::handle($args);
         $this->showPage();
@@ -167,7 +167,7 @@ class PeopletagSubscriberList extends ProfileList
         $this->peopletag = $peopletag;
     }
 
-    function newListItem($profile)
+    function newListItem(Profile $profile)
     {
         return new PeopletagSubscriberListItem($profile, $this->peopletag, $this->action);
     }
index 64edd0929025b6c126955cfb8d22d4810b3c3d3f..4b84bb368834e73cbb708cd47be74091e48c5d3b 100644 (file)
@@ -38,7 +38,7 @@ class PeopletagsubscriptionsAction extends Action
     var $page = null;
     var $profile = null;
 
-    function isReadOnly($args)
+    function isReadOnly(array $args=array())
     {
         return true;
     }
@@ -56,7 +56,7 @@ class PeopletagsubscriptionsAction extends Action
         }
     }
 
-    function prepare($args)
+    function prepare(array $args=array())
     {
         parent::prepare($args);
 
@@ -97,7 +97,7 @@ class PeopletagsubscriptionsAction extends Action
         return true;
     }
 
-    function handle($args)
+    function handle(array $args=array())
     {
         parent::handle($args);
         $this->showPage();
index 707cbdecaab45870995a43d0d08c2354e1c9a9b1..711b1b2c56d273149f65c50c87651307d625082a 100644 (file)
@@ -64,7 +64,7 @@ class PluginEnableAction extends Action
      *
      * @return boolean success flag
      */
-    function prepare($args)
+    function prepare(array $args=array())
     {
         parent::prepare($args);
 
@@ -121,7 +121,7 @@ class PluginEnableAction extends Action
      *
      * @return void
      */
-    function handle($args)
+    function handle(array $args=array())
     {
         $key = 'disable-' . $this->plugin;
         Config::save('plugins', $key, $this->overrideValue());
index aaf6026eb58115c0ccef5134f0cc5e6da8c2e3b9..5880752fcf933faa069ad60a3b9761c4ef450a4e 100644 (file)
@@ -68,7 +68,7 @@ class ProfilecompletionAction extends Action
      *
      * @return boolean success flag
      */
-    function prepare($args)
+    function prepare(array $args=array())
     {
         parent::prepare($args);
 
@@ -120,7 +120,7 @@ class ProfilecompletionAction extends Action
      * @return void
      */
 
-    function handle($args)
+    function handle(array $args=array())
     {
         $this->msg = null;
 
index ce7298a2f6b7038829c872533aff2026d2d700dd..af27b245c879a9085005fcb127ec61ef3e6f377e 100644 (file)
@@ -40,12 +40,12 @@ class ProfiletagbyidAction extends Action
      *
      * @return boolean true
      */
-    function isReadOnly($args)
+    function isReadOnly(array $args=array())
     {
         return true;
     }
 
-    function prepare($args)
+    function prepare(array $args=array())
     {
         parent::prepare($args);
 
@@ -83,7 +83,7 @@ class ProfiletagbyidAction extends Action
      *
      * @return void
      */
-    function handle($args)
+    function handle(array $args=array())
     {
         common_redirect($this->peopletag->homeUrl(), 303);
     }
index 5dcff3ba3d2f973c11118c90ae7e20c7ad9c1678..85da8ed0c99263caf695d8309ce0c3663fa633e2 100644 (file)
@@ -85,7 +85,7 @@ class PublicrssAction extends Rss10Action
         // nop
     }
 
-    function isReadOnly($args)
+    function isReadOnly(array $args=array())
     {
         return true;
     }
index db8185bb13d8a7eb142b0b9a29621d9a4eab12a8..8daf18d5042bd8b4dbe2653f6b3a8edb7f551b00 100644 (file)
@@ -46,7 +46,7 @@ define('TAGS_PER_PAGE', 100);
  */
 class PublictagcloudAction extends Action
 {
-    function isReadOnly($args)
+    function isReadOnly(array $args=array())
     {
         return true;
     }
@@ -92,7 +92,7 @@ class PublictagcloudAction extends Action
         $this->elementEnd('div');
     }
 
-    function handle($args)
+    function handle(array $args=array())
     {
         parent::handle($args);
         $this->showPage();
@@ -103,18 +103,23 @@ class PublictagcloudAction extends Action
         // This should probably be cached rather than recalculated
         $tags = new Notice_tag();
 
-        #Need to clear the selection and then only re-add the field
-        #we are grouping by, otherwise it's not a valid 'group by'
-        #even though MySQL seems to let it slide...
+        /*
+         * Need to clear the selection and then only re-add the field
+         * we are grouping by, otherwise it's not a valid 'group by'
+         * even though MySQL seems to let it slide...
+         */
         $tags->selectAdd();
         $tags->selectAdd('tag');
+        $tags->selectAdd('notice_id');
+        $tags->selectAdd('scope');
 
-        #Add the aggregated columns...
+        // Add the aggregated columns...
         $tags->selectAdd('max(notice_id) as last_notice_id');
         $calc = common_sql_weight('created', common_config('tag', 'dropoff'));
         $cutoff = sprintf("notice_tag.created > '%s'",
                           common_sql_date(time() - common_config('tag', 'cutoff')));
         $tags->selectAdd($calc . ' as weight');
+        $tags->joinAdd(array('notice_id', 'notice:id'));
         $tags->whereAdd($cutoff);
         $tags->groupBy('tag');
         $tags->orderBy('weight DESC');
@@ -130,8 +135,11 @@ class PublictagcloudAction extends Action
             $tw = array();
             $sum = 0;
             while ($tags->fetch()) {
-                $tw[$tags->tag] = $tags->weight;
-                $sum += $tags->weight;
+                // Check scope:
+                if ($tags->isCurrentProfileInScope()) {
+                    $tw[$tags->tag] = $tags->weight;
+                    $sum += $tags->weight;
+                }
             }
 
             ksort($tw);
index a3a5b8e5bc6ea41b4c52792296070f9e577b2c92..14ed582db122f391aaaac0016a5c7e0c36c21498 100644 (file)
@@ -29,7 +29,7 @@ class RecoverpasswordAction extends Action
     var $msg = null;
     var $success = null;
 
-    function handle($args)
+    function handle(array $args=array())
     {
         parent::handle($args);
         if (common_logged_in()) {
index 9cb03708db8a94ba0b78553cf7911fe0c05be856..c18a27f3a3a05ee8de0764eae47b68e8d95bce1c 100644 (file)
@@ -51,7 +51,7 @@ class RedirectAction extends Action
      * @return boolean read-only flag (false)
      */
 
-    function isReadOnly($args)
+    function isReadOnly(array $args=array())
     {
         return true;
     }
@@ -63,7 +63,7 @@ class RedirectAction extends Action
      *
      * @return nothing
      */
-    function handle($args)
+    function handle(array $args=array())
     {
         common_redirect(common_local_url($this->arg('nextAction'), $this->arg('args')));
     }
index 7ab04534f6ffaf6ae72d7ebe6d237ff6f5581438..f030c279d878c8f6083915a94baf188b049b1aa5 100644 (file)
@@ -120,7 +120,7 @@ class RegisterAction extends Action
      *
      * @return void
      */
-    function handle($args)
+    function handle(array $args=array())
     {
         parent::handle($args);
 
index 8192e86b44fd4246c932136a92f6c01eee9f5022..ee33517fdab1606e8c711487cc8209f6209c995c 100644 (file)
@@ -66,7 +66,7 @@ class RemovepeopletagAction extends Action
      *
      * @return boolean success flag
      */
-    function prepare($args)
+    function prepare(array $args=array())
     {
         parent::prepare($args);
 
@@ -120,7 +120,7 @@ class RemovepeopletagAction extends Action
      *
      * @return void
      */
-    function handle($args)
+    function handle(array $args=array())
     {
         // Throws exception on error
 
@@ -129,7 +129,7 @@ class RemovepeopletagAction extends Action
 
         if (!$ptag) {
             $user = User::getKV('id', $this->tagged->id);
-            if ($user) {
+            if ($user instanceof User) {
                 $this->clientError(
                         // TRANS: Client error displayed when an unknown error occurs while delisting a user.
                         // TRANS: %s is a username.
index ae6ec90658dca67272bbbc39d1734012db92deee..efe0d62beb9b59337b9f9df0f8978b24e9ce6434 100644 (file)
@@ -152,7 +152,7 @@ class RepliesAction extends ShowstreamAction
         $this->elementEnd('div');
     }
 
-    public function isReadOnly($args)
+    public function isReadOnly(array $args = array())
     {
         return true;
     }
index 81c792bd008b7b0afb1f172cc62b5aeb6ac7c452..6b6cd64f9412dcb7b7dd660a32033dae279afdfe 100644 (file)
@@ -258,7 +258,7 @@ class RestoreaccountAction extends Action
      *
      * @return boolean is read only action?
      */
-    function isReadOnly($args)
+    function isReadOnly(array $args=array())
     {
         return false;
     }
index b55399598eebd81c4e982de0b1d2d7ac71e4e0a9..d3ec2ecdfa1f5f6eda4c09c1d260156e181b4b26 100644 (file)
@@ -49,7 +49,7 @@ class RevokeRoleAction extends ProfileFormAction
      *
      * @return boolean success flag
      */
-    function prepare($args)
+    function prepare(array $args=array())
     {
         if (!parent::prepare($args)) {
             return false;
index fdfc2bd1bd650cdee7bbaf76d3c03a3a642619e7..4df04b564a5b46127578c12c611f352dd80e2de6 100644 (file)
@@ -76,7 +76,7 @@ class RobotstxtAction extends ManagedAction
      *
      * @return boolean is read only action?
      */
-    function isReadOnly($args)
+    function isReadOnly(array $args=array())
     {
         return true;
     }
index bd8042f0cd86cc3a10945a25b01c8d1f32f11bd2..6c47eeeff531b754f06fbe5cf6ef49d656384101 100644 (file)
@@ -85,7 +85,7 @@ class RsdAction extends Action
      *
      * @return boolean success flag
      */
-    function prepare($args)
+    function prepare(array $args=array())
     {
         parent::prepare($args);
 
@@ -126,7 +126,7 @@ class RsdAction extends Action
      *
      * @return nothing
      */
-    function handle($args)
+    function handle(array $args=array())
     {
         header('Content-Type: application/rsd+xml');
 
@@ -207,7 +207,7 @@ class RsdAction extends Action
      *
      * @return boolean true
      */
-    function isReadOnly($args)
+    function isReadOnly(array $args=array())
     {
         return true;
     }
index af2eab3842d268add1d5a8c0693464a81fb91871..9397a093031ee046cfb510b2de372256bcd222c3 100644 (file)
@@ -49,7 +49,7 @@ class SandboxAction extends ProfileFormAction
      *
      * @return boolean success flag
      */
-    function prepare($args)
+    function prepare(array $args=array())
     {
         if (!parent::prepare($args)) {
             return false;
index b886c3d9f731cc28e4e041df35c3e40159eb5365..58f0460997536a662c8d59ba235a4fc226bf75eb 100644 (file)
@@ -158,7 +158,7 @@ class SelftagAction extends Action
 
 class SelfTagProfileList extends ProfileList
 {
-    function newListItem($profile)
+    function newListItem(Profile $profile)
     {
         return new SelfTagProfileListItem($profile, $this->action);
     }
index d8ac293d404138719d69e6f79bfd0c93ac44d218..c10883942f5f19f5377494262fdf7a5832adf08b 100644 (file)
@@ -65,7 +65,7 @@ class ShowApplicationAction extends Action
      *
      * @return success flag
      */
-    function prepare($args)
+    function prepare(array $args=array())
     {
         parent::prepare($args);
 
@@ -101,7 +101,7 @@ class ShowApplicationAction extends Action
      *
      * @return void
      */
-    function handle($args)
+    function handle(array $args=array())
     {
         parent::handle($args);
 
index 46d0a227f536ecc4253212e6b55cb5fe2ba71d1b..da95b6a411b4b811c4ae4bc81edb21fdd27c2130 100644 (file)
@@ -56,7 +56,7 @@ class ShowgroupAction extends GroupAction
      *
      * @return boolean true
      */
-    function isReadOnly($args)
+    function isReadOnly(array $args=array())
     {
         return true;
     }
index 23386868ddbc1b042b3151b29340b952c86cf35c..f627b71f714ef8870228d5a0629a3a550ae7e92a 100644 (file)
@@ -134,7 +134,7 @@ class ShownoticeAction extends ManagedAction
      *
      * @return boolean true
      */
-    function isReadOnly($args)
+    function isReadOnly(array $args=array())
     {
         return true;
     }
index 6a4f84deb9a15390d89548750597af81a7735630..ac25a0d18440153db23c6d7efc35ca9f63ffaf05 100644 (file)
@@ -49,7 +49,7 @@ class SilenceAction extends ProfileFormAction
      *
      * @return boolean success flag
      */
-    function prepare($args)
+    function prepare(array $args=array())
     {
         if (!parent::prepare($args)) {
             return false;
index 47fe19ea244f0c2cee9ed8cc77a9e4e08cfb0d3f..4dc3e855aa3b0f4dd3d804149c8e756b2476ea10 100644 (file)
@@ -24,7 +24,7 @@ class SubeditAction extends Action
 {
     var $profile = null;
 
-    function prepare($args)
+    function prepare(array $args=array())
     {
         parent::prepare($args);
 
@@ -58,7 +58,7 @@ class SubeditAction extends Action
         return true;
     }
 
-    function handle($args)
+    function handle(array $args=array())
     {
         parent::handle($args);
         if ($_SERVER['REQUEST_METHOD'] == 'POST') {
index ba473456004ef06ffa364d1fc7ad4b59e56415bd..c87202ddf1cc602ff8bc996c61d435c3824cc1cf 100644 (file)
@@ -106,7 +106,7 @@ class SubqueueAction extends GalleryAction
 
 class SubQueueList extends ProfileList
 {
-    function newListItem($profile)
+    function newListItem(Profile $profile)
     {
         return new SubQueueListItem($profile, $this->action);
     }
index 320409afa07460d36c94d427c4ee8bc014667375..1da061819baf835b90d10610127e780fad3ca2a2 100644 (file)
@@ -64,7 +64,7 @@ class SubscribeAction extends Action
      *
      * @return boolean success flag
      */
-    function prepare($args)
+    function prepare(array $args=array())
     {
         parent::prepare($args);
 
@@ -118,7 +118,7 @@ class SubscribeAction extends Action
      *
      * @return void
      */
-    function handle($args)
+    function handle(array $args=array())
     {
         // Throws exception on error
 
index b83ff70010e15c60a42a61de89d70b5a9a5d0d34..ed9f282cfdd241bf504cdc539dab6f3c30cc5618 100644 (file)
@@ -50,7 +50,7 @@ class SubscribepeopletagAction extends Action
     /**
      * Prepare to run
      */
-    function prepare($args)
+    function prepare(array $args=array())
     {
         parent::prepare($args);
 
@@ -106,7 +106,7 @@ class SubscribepeopletagAction extends Action
      * @return void
      */
 
-    function handle($args)
+    function handle(array $args=array())
     {
         parent::handle($args);
 
index 2724927878c586d640c0a827317dd61e59993f3a..682faf869e44d437728c63d62afa87f78f9a8b24 100644 (file)
@@ -135,7 +135,7 @@ class SubscribersAction extends GalleryAction
 
 class SubscribersList extends SubscriptionList
 {
-    function newListItem($profile)
+    function newListItem(Profile $profile)
     {
         return new SubscribersListItem($profile, $this->owner, $this->action);
     }
index b5734b3747ee38900339a480fc2858b25190a1c7..adf337dfc8bca8c655ccb61330001a771e25a1b5 100644 (file)
@@ -159,7 +159,7 @@ class SubscriptionsAction extends GalleryAction
 
 class SubscriptionsList extends SubscriptionList
 {
-    function newListItem($profile)
+    function newListItem(Profile $profile)
     {
         return new SubscriptionsListItem($profile, $this->owner, $this->action);
     }
index 911f0d9e5551955916e45c1dcbb4c9b815452352..b871983185a5f66fff3e944ab354ff730810eea2 100644 (file)
@@ -22,7 +22,7 @@ if (!defined('STATUSNET') && !defined('LACONICA')) { exit(1); }
 // @todo FIXME: documentation needed.
 class SupAction extends Action
 {
-    function handle($args)
+    function handle(array $args=array())
     {
         parent::handle($args);
 
@@ -84,7 +84,7 @@ class SupAction extends Action
         return $updates;
     }
 
-    function isReadOnly($args)
+    function isReadOnly(array $args=array())
     {
         return true;
     }
index 751e8dcec52e92ef65c5a5bdce6ba4ce1159109b..9159e7c043b9509c28787bfb0a109c50facae7f4 100644 (file)
@@ -122,7 +122,7 @@ class TagAction extends ManagedAction
         }
     }
 
-    function isReadOnly($args)
+    function isReadOnly(array $args=array())
     {
         return true;
     }
index 0d4d68ffba1c4c7594ab12b90a75eb6b0c38ac52..286d1688579513a16ae4bf1aa9c57eb62aacae83 100644 (file)
@@ -54,7 +54,7 @@ class TagrssAction extends Rss10Action
         return $c;
     }
 
-    function isReadOnly($args)
+    function isReadOnly(array $args=array())
     {
         return true;
     }
index 82d0d32c109149f3e732754c3bfffb61fd9e0121..cb03214a9f02db44144b720e0c86da2275ed62b4 100644 (file)
@@ -44,7 +44,7 @@ if (!defined('STATUSNET') && !defined('LACONICA')) {
  */
 class UnblockAction extends ProfileFormAction
 {
-    function prepare($args)
+    function prepare(array $args=array())
     {
         if (!parent::prepare($args)) {
             return false;
index b87736fcffffbf54d7537cd1a307eded9c2b7c86..5e1110aa87c3de30342fa3c90b98d44384d4bcca 100644 (file)
@@ -49,7 +49,7 @@ class UnsandboxAction extends ProfileFormAction
      *
      * @return boolean success flag
      */
-    function prepare($args)
+    function prepare(array $args=array())
     {
         if (!parent::prepare($args)) {
             return false;
index c01c141b1c193fd6337365b26497d9438bc71094..cde37201b16f66779c4879789c5e20a27f1e2963 100644 (file)
@@ -49,7 +49,7 @@ class UnsilenceAction extends ProfileFormAction
      *
      * @return boolean success flag
      */
-    function prepare($args)
+    function prepare(array $args=array())
     {
         if (!parent::prepare($args)) {
             return false;
index 4b85ba427ca1b18d611434865ffb0dfce1dcbff3..ddc222923b8264c844613b29d96c602283b7dae1 100644 (file)
@@ -44,7 +44,7 @@ if (!defined('STATUSNET') && !defined('LACONICA')) {
  */
 class UnsubscribeAction extends Action
 {
-    function handle($args)
+    function handle(array $args=array())
     {
         parent::handle($args);
         if (!common_logged_in()) {
index b5757ad6fdb7d719b7ba78e46b5635fe635de6d4..42f0c20e6f1e75b64896b6769f3fe1a97def469f 100644 (file)
@@ -51,7 +51,7 @@ class UnsubscribepeopletagAction extends Action
      * Prepare to run
      */
 
-    function prepare($args)
+    function prepare(array $args=array())
     {
         parent::prepare($args);
 
@@ -106,7 +106,7 @@ class UnsubscribepeopletagAction extends Action
      *
      * @return void
      */
-    function handle($args)
+    function handle(array $args=array())
     {
         parent::handle($args);
 
index 7bed1dd256bdf5db902e61841deea57dd86492fb..147d98cc261f557424dd274a1c347168dbb2acc8 100644 (file)
@@ -67,7 +67,7 @@ class UserrssAction extends TargetedRss10Action
         parent::initRss();
     }
 
-    function isReadOnly($args)
+    function isReadOnly(array $args=array())
     {
         return true;
     }
index 97115d23cd364089fadffe1bd270adcde5c5286a..49b2682c066b2bcab139f4cdf96b60d90f15dbe6 100644 (file)
@@ -55,7 +55,7 @@ class VersionAction extends Action
      *
      * @return boolean is read only action?
      */
-    function isReadOnly($args)
+    function isReadOnly(array $args=array())
     {
         return true;
     }
index 1722b85b6b926be5a1041b9f2ef981f2ac34e53c..6a66228a0e417fb86ca156dd230128607f482258 100644 (file)
@@ -70,10 +70,14 @@ class Avatar extends Managed_DataObject
     public static function deleteFromProfile(Profile $target, $original=true) {
         try {
             $avatars = self::getProfileAvatars($target);
+
             foreach ($avatars as $avatar) {
+                assert($avatar instanceof Avatar);
+
                 if ($avatar->original && !$original) {
                     continue;
                 }
+
                 $avatar->delete();
             }
         } catch (NoAvatarException $e) {
@@ -97,6 +101,7 @@ class Avatar extends Managed_DataObject
         }
 
         $size = "{$width}x{$height}";
+
         if (!isset(self::$_avatars[$target->id])) {
             self::$_avatars[$target->id] = array();
         } elseif (isset(self::$_avatars[$target->id][$size])){
@@ -104,6 +109,7 @@ class Avatar extends Managed_DataObject
         }
 
         $avatar = null;
+
         if (Event::handle('StartProfileGetAvatar', array($target, $width, &$avatar))) {
             $avatar = self::pkeyGet(
                 array(
@@ -112,6 +118,7 @@ class Avatar extends Managed_DataObject
                     'height'     => $height,
                 )
             );
+
             Event::handle('EndProfileGetAvatar', array($target, $width, &$avatar));
         }
 
@@ -184,7 +191,7 @@ class Avatar extends Managed_DataObject
         }
 
         if ($path[0] != '/') {
-            $path = '/'.$path;
+            $path = '/' . $path;
         }
 
         $server = common_config('avatar', 'server');
@@ -223,6 +230,12 @@ class Avatar extends Managed_DataObject
         try {
             return self::byProfile($target,  $width, $height)->displayUrl();
         } catch (Exception $e) {
+            common_debug(sprintf('target=>id=%s,width=%s,height=%s,message=%s',
+                $target->id,
+                $width,
+                $height,
+                $e->getMessage()
+            ));
             return self::defaultImage($width);
         }
     }
@@ -232,7 +245,7 @@ class Avatar extends Managed_DataObject
         static $sizenames = array(AVATAR_PROFILE_SIZE => 'profile',
                                   AVATAR_STREAM_SIZE => 'stream',
                                   AVATAR_MINI_SIZE => 'mini');
-        return Theme::path('default-avatar-'.$sizenames[$size].'.png');
+        return Theme::path('default-avatar-' . $sizenames[$size] . '.png');
     }
 
     static function newSize(Profile $target, $width) {
index 97e1a75dab78c231882ea82dbbf76f786e468600..af9dc9157ed127e9d4009a4fa97732232e99ed3d 100644 (file)
@@ -49,7 +49,7 @@ class Confirm_address extends Managed_DataObject
         return null;
     }
 
-    static function saveNew($user, $address, $addressType, $extra=null)
+    static function saveNew(User $user, $address, $addressType, $extra=null)
     {
         $ca = new Confirm_address();
 
index a324deaa5d59fbe1ca07e088e232c1e6e7594dd6..bc405311fef63365ff2132cc04bf271f4ef3895e 100644 (file)
@@ -337,7 +337,7 @@ class File_redirection extends Managed_DataObject
         return $out_url;
     }
 
-    static function saveNew($data, $file_id, $url) {
+    static function saveNew(array $data, $file_id, $url) {
         $file_redir = new File_redirection;
         $file_redir->urlhash = File::hashurl($url);
         $file_redir->url = $url;
index e1eb79e099e69212b7f560919e09e8a3ce835852..ef79eadc38efa892fad9d0e25a9832001bf69a97 100644 (file)
@@ -61,6 +61,9 @@ class File_thumbnail extends Managed_DataObject
      * @param int $file_id
      */
     public static function saveNew($data, $file_id) {
+        // @TODO Must be an object (see below code)
+        assert(is_object($data));
+
         if (!empty($data->thumbnail_url)) {
             // Non-photo types such as video will usually
             // show us a thumbnail, though it's not required.
index 41ce715210bec85bcf8f4cf314475a99a34c084c..b5057ba22043463f5c06dae96879564b1f69cb8c 100644 (file)
@@ -650,7 +650,7 @@ class Memcached_DataObject extends Safe_DataObject
             } else {
                 $msg = sprintf("DB query (%0.3fs): %s", $delta, $clean);
             }
-            common_log(LOG_DEBUG, $msg);
+            common_debug($msg);
         }
 
         if ($fail) {
index ab9d928e6440aba6a17c98ec621f126fdd5409d1..757205761a3e48ec43eca2eb7a3683ecdb43662b 100644 (file)
@@ -318,7 +318,7 @@ class Notice extends Managed_DataObject
      * Record the given set of hash tags in the db for this notice.
      * Given tag strings will be normalized and checked for dupes.
      */
-    function saveKnownTags($hashtags)
+    function saveKnownTags(array $hashtags)
     {
         //turn each into their canonical tag
         //this is needed to remove dupes before saving e.g. #hash.tag = #hashtag
@@ -402,7 +402,7 @@ class Notice extends Managed_DataObject
      * @return Notice
      * @throws ClientException
      */
-    static function saveNew($profile_id, $content, $source, array $options=null) {
+    static function saveNew($profile_id, $content, $source, array $options=array()) {
         $defaults = array('uri' => null,
                           'url' => null,
                           'conversation' => null,   // URI of conversation
@@ -413,13 +413,16 @@ class Notice extends Managed_DataObject
                           'object_type' => null,
                           'verb' => null);
 
-        if (!empty($options) && is_array($options)) {
+        /*
+         * Above type-hint is already array, so simply count it, this saves
+         * "some" CPU cycles.
+         */
+        if (count($options) > 0) {
             $options = array_merge($defaults, $options);
-            extract($options);
-        } else {
-            extract($defaults);
         }
 
+        extract($options);
+
         if (!isset($is_local)) {
             $is_local = Notice::LOCAL_PUBLIC;
         }
@@ -520,8 +523,7 @@ class Notice extends Managed_DataObject
                 throw new ClientException(_('You cannot repeat your own notice.'));
             }
 
-            if ($repeat->scope != Notice::SITE_SCOPE &&
-                $repeat->scope != Notice::PUBLIC_SCOPE) {
+            if ($repeat->isPrivateScope()) {
                 // TRANS: Client error displayed when trying to repeat a non-public notice.
                 throw new ClientException(_('Cannot repeat a private notice.'), 403);
             }
@@ -1171,7 +1173,7 @@ class Notice extends Managed_DataObject
      *
      * @return void
      */
-    function saveKnownUrls($urls)
+    function saveKnownUrls(array $urls)
     {
         if (common_config('attachments', 'process_links')) {
             // @fixme validation?
@@ -1722,7 +1724,7 @@ class Notice extends Managed_DataObject
         return $this->_replies[$this->getID()];
     }
 
-    function _setReplies($replies)
+    function _setReplies(array $replies)
     {
         $this->_replies[$this->getID()] = $replies;
     }
@@ -1800,11 +1802,11 @@ class Notice extends Managed_DataObject
                }
 
                $groups = User_group::multiGet('id', $ids);
-               $this->_groups[$this->id] = $groups->fetchAll();
+               $this->_setGroups($groups->fetchAll());
                return $this->_groups[$this->id];
     }
 
-    function _setGroups($groups)
+    function _setGroups(array $groups)
     {
         $this->_groups[$this->id] = $groups;
     }
@@ -2524,6 +2526,37 @@ class Notice extends Managed_DataObject
      */
     public function getTags()
     {
+        // Check default scope (non-private notices)
+        $inScope = (!$this->isPrivateScope());
+
+        // Get current profile
+        $profile = Profile::current();
+
+        // Is the general scope check okay and the user in logged in?
+        //* NOISY-DEBUG: */ common_debug('[' . __METHOD__ . ':' . __LINE__ . ']: inScope=' . intval($inScope) . ',profile[]=' . gettype($profile));
+        if (($inScope === TRUE) && ($profile instanceof Profile)) {
+            /*
+             * Check scope, else a privacy leaks happens this way:
+             *
+             * 1) Bob and Alice follow each other and write private notices
+             *    (this->scope=2) to each other.
+             * 2) Bob uses tags in his private notice to alice (which she can
+             *    read from him).
+             * 3) Alice adds that notice (with tags) to her favorites
+             *    ("faving") it.
+             * 4) The tags from Bob's private notice becomes visible in Alice's
+             *    profile.
+             *
+             * This has the simple background that the scope is not being
+             * re-checked. This has to be done here at this point because given
+             * above scenario is a privacy leak as the tags may be *really*
+             * private (nobody else shall see them) such as initmate words or
+             * very political words.
+             */
+            $inScope = $this->inScope($profile);
+            //* NOISY-DEBUG: */ common_debug('[' . __METHOD__ . ':' . __LINE__ . ']: inScope=' . intval($inScope) . ' - After inScope() has been called.');
+        }
+
         $tags = array();
 
         $keypart = sprintf('notice:tags:%d', $this->id);
@@ -2535,7 +2568,9 @@ class Notice extends Managed_DataObject
         } else {
             $tag = new Notice_tag();
             $tag->notice_id = $this->id;
-            if ($tag->find()) {
+
+            // Check scope for privacy-leak protection (see some lines above why)
+            if (($inScope === TRUE) && ($tag->find())) {
                 while ($tag->fetch()) {
                     $tags[] = $tag->tag;
                 }
@@ -2663,6 +2698,11 @@ class Notice extends Managed_DataObject
                 ($this->is_local != Notice::GATEWAY));
     }
 
+    public function isPrivateScope () {
+        return ($this->scope != Notice::SITE_SCOPE &&
+                $this->scope != Notice::PUBLIC_SCOPE);
+    }
+
     /**
      * Check that the given profile is allowed to read, respond to, or otherwise
      * act on this notice.
@@ -2677,7 +2717,7 @@ class Notice extends Managed_DataObject
      *
      * @return boolean whether the profile is in the notice's scope
      */
-    function inScope($profile)
+    function inScope(Profile $profile=null)
     {
         if (is_null($profile)) {
             $keypart = sprintf('notice:in-scope-for:%d:null', $this->id);
@@ -2700,7 +2740,7 @@ class Notice extends Managed_DataObject
         return ($result == 1) ? true : false;
     }
 
-    protected function _inScope($profile)
+    protected function _inScope(Profile $profile=null)
     {
         $scope = is_null($this->scope) ? self::defaultScope() : $this->getScope();
 
@@ -2765,7 +2805,7 @@ class Notice extends Managed_DataObject
         return !$this->isHiddenSpam($profile);
     }
 
-    function isHiddenSpam($profile) {
+    function isHiddenSpam(Profile $profile=null) {
 
         // Hide posts by silenced users from everyone but moderators.
 
@@ -2850,7 +2890,7 @@ class Notice extends Managed_DataObject
        return $scope;
     }
 
-       static function fillProfiles($notices)
+       static function fillProfiles(array $notices)
        {
                $map = self::getProfiles($notices);
                foreach ($notices as $entry=>$notice) {
@@ -2867,7 +2907,7 @@ class Notice extends Managed_DataObject
                return array_values($map);
        }
 
-       static function getProfiles(&$notices)
+       static function getProfiles(array &$notices)
        {
                $ids = array();
                foreach ($notices as $notice) {
@@ -2877,7 +2917,7 @@ class Notice extends Managed_DataObject
                return Profile::pivotGet('id', $ids);
        }
 
-       static function fillGroups(&$notices)
+       static function fillGroups(array &$notices)
        {
         $ids = self::_idsOf($notices);
         $gis = Group_inbox::listGet('notice_id', $ids);
@@ -2912,7 +2952,7 @@ class Notice extends Managed_DataObject
                return array_keys($ids);
     }
 
-    static function fillAttachments(&$notices)
+    static function fillAttachments(array &$notices)
     {
         $ids = self::_idsOf($notices);
         $f2pMap = File_to_post::listGet('post_id', $ids);
@@ -2936,7 +2976,7 @@ class Notice extends Managed_DataObject
                }
     }
 
-    static function fillReplies(&$notices)
+    static function fillReplies(array &$notices)
     {
         $ids = self::_idsOf($notices);
         $replyMap = Reply::listGet('notice_id', $ids);
@@ -2950,6 +2990,39 @@ class Notice extends Managed_DataObject
         }
     }
 
+    /**
+     * Checks whether the current profile is allowed (in scope) to see this notice.
+     *
+     * @return $inScope Whether the current profile is allowed to see this notice
+     */
+    function isCurrentProfileInScope () {
+        // Check scope, default is allowed
+        $inScope = TRUE;
+
+        //* NOISY-DEBUG: */ common_debug('[' . __METHOD__ . ':' . __LINE__ . '] this->tag=' . $this->tag . ',this->id=' . $this->id . ',this->scope=' . $this->scope);
+
+        // Is it private scope?
+        if ($this->isPrivateScope()) {
+            // 2) Get current profile
+            $profile = Profile::current();
+
+            // Is the profile not set?
+            if (!$profile instanceof Profile) {
+                // Public viewer shall not see a tag from a private dent (privacy leak)
+                //* NOISY-DEBUG: */ common_debug('[' . __METHOD__ . ':' . __LINE__ . '] Not logged in (public view).');
+                $inScope = FALSE;
+            } elseif (!$this->inScope($profile)) {
+                // Current profile is not in scope (not allowed to see) of notice
+                //* NOISY-DEBUG: */ common_debug('[' . __METHOD__ . ':' . __LINE__ . '] profile->id=' . $profile->id . ' is not allowed to see this notice.');
+                $inScope = FALSE;
+            }
+        }
+
+        // Return result
+        //* NOISY-DEBUG: */ common_debug('[' . __METHOD__ . ':' . __LINE__ . '] this->tag=' . $this->tag . ',this->weight=' . $this->weight . ',inScope=' . intval($inScope) . ' - EXIT!');
+        return $inScope;
+    }
+
     static public function beforeSchemaUpdate()
     {
         $table = strtolower(get_called_class());
index b864de80092b31001b03a8048519b0ab97b6e5ee..30394ef8f3bd220567a98e03a8aa703ed23feed5 100644 (file)
@@ -81,4 +81,35 @@ class Notice_tag extends Managed_DataObject
 
                return $url;
        }
+
+    /**
+     * Checks whether the current profile is allowed (in scope) to see this tag.
+     *
+     * @return $inScope Whether the current profile is allowed to see this tag
+     */
+    function isCurrentProfileInScope () {
+        // Check scope, default is allowed
+        $inScope = TRUE;
+
+        // 1) Get notice object and set id
+        $notice = new Notice();
+        $notice->id = $this->notice_id;
+
+        //* NOISY-DEBUG: */ common_debug('[' . __METHOD__ . ':' . __LINE__ . '] this->tag=' . $this->tag . ',this->notice_id=' . $this->notice_id . ' - Calling find() ... fetch() ...');
+
+        // Fetch notice
+        if ((!$notice->find()) || (!$notice->fetch())) {
+            // No longer valid, so better don't allow to see it
+            return FALSE;
+        }
+
+        //* NOISY-DEBUG: */ common_debug('[' . __METHOD__ . ':' . __LINE__ . '] this->tag=' . $this->tag . ',notice->id=' . $notice->id . ',notice->scope=' . $notice->scope);
+
+        // Is it private scope?
+        $inScope = $notice->isCurrentProfileInScope();
+
+        // Return result
+        //* NOISY-DEBUG: */ common_debug('[' . __METHOD__ . ':' . __LINE__ . '] this->tag=' . $this->tag . ',this->weight=' . $this->weight . ',inScope=' . intval($inScope) . ' - EXIT!');
+        return $inScope;
+    }
 }
index 7bfb16e27f67df7e04d2a91c43a2a820fe3c00e3..1546414011bcf3e3c700cd2a24d26a7dd31a6291 100644 (file)
@@ -91,9 +91,22 @@ class User_group extends Managed_DataObject
     {
         if (!isset($this->_profile[$this->profile_id])) {
             $profile = Profile::getKV('id', $this->profile_id);
+
             if (!$profile instanceof Profile) {
-                throw new GroupNoProfileException($this);
+
+                $profile = new Profile();
+                $profile->nickname   = $this->nickname;
+                $profile->fullname   = $this->fullname;
+                $profile->profileurl = $this->mainpage;
+                $profile->homepage   = $this->homepage;
+                $profile->bio        = $this->description;
+                $profile->location   = $this->location;
+                $profile->created    = common_sql_now();
+                $this->profile_id = $profile->insert();
+
+                //throw new GroupNoProfileException($this);
             }
+
             $this->_profile[$this->profile_id] = $profile;
         }
         return $this->_profile[$this->profile_id];
old mode 100755 (executable)
new mode 100644 (file)
index 44599d68e94b146465af18a657ecb7660981e757..c68e8836fdb97bf1e37d772f889b7f97d7512181 100644 (file)
--- a/index.php
+++ b/index.php
@@ -37,6 +37,9 @@
  * @license  GNU Affero General Public License http://www.gnu.org/licenses/
  */
 
+// Comment in if you have xdebug installed and need a detailed backtrace:
+//xdebug_start_trace();
+
 $_startTime = microtime(true);
 $_perfCounters = array();
 
@@ -314,14 +317,14 @@ function main()
     } else {
         try {
             call_user_func("$action_class::run", $args);
-        } catch (ClientException $cex) {
-            $cac = new ClientErrorAction($cex->getMessage(), $cex->getCode());
+        } catch (ClientException $e) {
+            $cac = new ClientErrorAction($e->getMessage(), $e->getCode());
             $cac->showPage();
-        } catch (ServerException $sex) { // snort snort guffaw
-            $sac = new ServerErrorAction($sex->getMessage(), $sex->getCode(), $sex);
+        } catch (ServerException $e) { // snort snort guffaw
+            $sac = new ServerErrorAction($e->getMessage(), $e->getCode(), $e);
             $sac->showPage();
-        } catch (Exception $ex) {
-            $sac = new ServerErrorAction($ex->getMessage(), 500, $ex);
+        } catch (Exception $e) {
+            $sac = new ServerErrorAction($e->getMessage(), 500, $e);
             $sac->showPage();
         }
     }
diff --git a/installer.txt b/installer.txt
new file mode 100644 (file)
index 0000000..b649dc3
--- /dev/null
@@ -0,0 +1,649 @@
+<?php
+
+/**
+ * StatusNet - the distributed open-source microblogging tool
+ * Copyright (C) 2009-2010, 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/>.
+ *
+ * @category Installation
+ * @package  Installation
+ *
+ * @author   Adrian Lang <mail@adrianlang.de>
+ * @author   Brenda Wallace <shiny@cpan.org>
+ * @author   Brett Taylor <brett@webfroot.co.nz>
+ * @author   Brion Vibber <brion@pobox.com>
+ * @author   CiaranG <ciaran@ciarang.com>
+ * @author   Craig Andrews <candrews@integralblue.com>
+ * @author   Eric Helgeson <helfire@Erics-MBP.local>
+ * @author   Evan Prodromou <evan@status.net>
+ * @author   Mikael Nordfeldth <mmn@hethane.se>
+ * @author   Robin Millette <millette@controlyourself.ca>
+ * @author   Sarven Capadisli <csarven@status.net>
+ * @author   Tom Adams <tom@holizz.com>
+ * @author   Zach Copley <zach@status.net>
+ * @copyright 2009-2010 StatusNet, Inc http://status.net
+ * @copyright 2009-2014 Free Software Foundation, Inc http://www.fsf.org
+ * @license  GNU Affero General Public License http://www.gnu.org/licenses/
+ * @version  1.0.x
+ * @link     http://status.net
+ */
+
+abstract class Installer
+{
+    /** Web site info */
+    public $sitename, $server, $path, $fancy, $siteProfile, $ssl;
+    /** DB info */
+    public $host, $database, $dbtype, $username, $password, $db;
+    /** Administrator info */
+    public $adminNick, $adminPass, $adminEmail, $adminUpdates;
+    /** Should we skip writing the configuration file? */
+    public $skipConfig = false;
+
+    public static $dbModules = array(
+        'mysql' => array(
+            'name' => 'MySQL',
+            'check_module' => 'mysqli',
+            'scheme' => 'mysqli', // DSN prefix for PEAR::DB
+        ),
+        'pgsql' => array(
+            'name' => 'PostgreSQL',
+            'check_module' => 'pgsql',
+            'scheme' => 'pgsql', // DSN prefix for PEAR::DB
+        ),
+    );
+
+    /**
+     * Attempt to include a PHP file and report if it worked, while
+     * suppressing the annoying warning messages on failure.
+     */
+    private function haveIncludeFile($filename) {
+        $old = error_reporting(error_reporting() & ~E_WARNING);
+        $ok = include_once($filename);
+        error_reporting($old);
+        return $ok;
+    }
+
+    /**
+     * Check if all is ready for installation
+     *
+     * @return void
+     */
+    function checkPrereqs()
+    {
+        $pass = true;
+
+        $config = INSTALLDIR.'/config.php';
+        if (file_exists($config)) {
+            if (!is_writable($config) || filesize($config) > 0) {
+                if (filesize($config) == 0) {
+                    $this->warning('Config file "config.php" already exists and is empty, but is not writable.');
+                } else {
+                    $this->warning('Config file "config.php" already exists.');
+                }
+                $pass = false;
+            }
+        }
+
+        if (version_compare(PHP_VERSION, '5.3.2', '<')) {
+            $this->warning('Require PHP version 5.3.2 or greater.');
+            $pass = false;
+        }
+
+        $reqs = array('gd', 'curl', 'json',
+                      'xmlwriter', 'mbstring', 'xml', 'dom', 'simplexml');
+
+        foreach ($reqs as $req) {
+            if (!$this->checkExtension($req)) {
+                $this->warning(sprintf('Cannot load required extension: <code>%s</code>', $req));
+                $pass = false;
+            }
+        }
+
+        // Make sure we have at least one database module available
+        $missingExtensions = array();
+        foreach (self::$dbModules as $type => $info) {
+            if (!$this->checkExtension($info['check_module'])) {
+                $missingExtensions[] = $info['check_module'];
+            }
+        }
+
+        if (count($missingExtensions) == count(self::$dbModules)) {
+            $req = implode(', ', $missingExtensions);
+            $this->warning(sprintf('Cannot find a database extension. You need at least one of %s.', $req));
+            $pass = false;
+        }
+
+        // @fixme this check seems to be insufficient with Windows ACLs
+        if (!is_writable(INSTALLDIR)) {
+            $this->warning(sprintf('Cannot write config file to: <code>%s</code></p>', INSTALLDIR),
+                           sprintf('On your server, try this command: <code>chmod a+w %s</code>', INSTALLDIR));
+            $pass = false;
+        }
+
+        // Check the subdirs used for file uploads
+        $fileSubdirs = array('avatar', 'background', 'file');
+        foreach ($fileSubdirs as $fileSubdir) {
+            $fileFullPath = INSTALLDIR."/$fileSubdir/";
+            if (!is_writable($fileFullPath)) {
+                $this->warning(sprintf('Cannot write to %s directory: <code>%s</code>', $fileSubdir, $fileFullPath),
+                               sprintf('On your server, try this command: <code>chmod a+w %s</code>', $fileFullPath));
+                $pass = false;
+            }
+        }
+
+        return $pass;
+    }
+
+    /**
+     * Checks if a php extension is both installed and loaded
+     *
+     * @param string $name of extension to check
+     *
+     * @return boolean whether extension is installed and loaded
+     */
+    function checkExtension($name)
+    {
+        if (extension_loaded($name)) {
+            return true;
+        } elseif (function_exists('dl') && ini_get('enable_dl') && !ini_get('safe_mode')) {
+            // dl will throw a fatal error if it's disabled or we're in safe mode.
+            // More fun, it may not even exist under some SAPIs in 5.3.0 or later...
+            $soname = $name . '.' . PHP_SHLIB_SUFFIX;
+            if (PHP_SHLIB_SUFFIX == 'dll') {
+                $soname = "php_" . $soname;
+            }
+            return @dl($soname);
+        } else {
+            return false;
+        }
+    }
+
+    /**
+     * Basic validation on the database paramters
+     * Side effects: error output if not valid
+     *
+     * @return boolean success
+     */
+    function validateDb()
+    {
+        $fail = false;
+
+        if (empty($this->host)) {
+            $this->updateStatus("No hostname specified.", true);
+            $fail = true;
+        }
+
+        if (empty($this->database)) {
+            $this->updateStatus("No database specified.", true);
+            $fail = true;
+        }
+
+        if (empty($this->username)) {
+            $this->updateStatus("No username specified.", true);
+            $fail = true;
+        }
+
+        if (empty($this->sitename)) {
+            $this->updateStatus("No sitename specified.", true);
+            $fail = true;
+        }
+
+        return !$fail;
+    }
+
+    /**
+     * Basic validation on the administrator user paramters
+     * Side effects: error output if not valid
+     *
+     * @return boolean success
+     */
+    function validateAdmin()
+    {
+        $fail = false;
+
+        if (empty($this->adminNick)) {
+            $this->updateStatus("No initial user nickname specified.", true);
+            $fail = true;
+        }
+        if ($this->adminNick && !preg_match('/^[0-9a-z]{1,64}$/', $this->adminNick)) {
+            $this->updateStatus('The user nickname "' . htmlspecialchars($this->adminNick) .
+                         '" is invalid; should be plain letters and numbers no longer than 64 characters.', true);
+            $fail = true;
+        }
+        // @fixme hardcoded list; should use Nickname::isValid()
+        // if/when it's safe to have loaded the infrastructure here
+        $blacklist = array('main', 'panel', 'twitter', 'settings', 'rsd.xml', 'favorited', 'featured', 'favoritedrss', 'featuredrss', 'rss', 'getfile', 'api', 'groups', 'group', 'peopletag', 'tag', 'user', 'message', 'conversation', 'bookmarklet', 'notice', 'attachment', 'search', 'index.php', 'doc', 'opensearch', 'robots.txt', 'xd_receiver.html', 'facebook');
+        if (in_array($this->adminNick, $blacklist)) {
+            $this->updateStatus('The user nickname "' . htmlspecialchars($this->adminNick) .
+                         '" is reserved.', true);
+            $fail = true;
+        }
+
+        if (empty($this->adminPass)) {
+            $this->updateStatus("No initial user password specified.", true);
+            $fail = true;
+        }
+
+        return !$fail;
+    }
+
+    /**
+     * Make sure a site profile was selected
+     *
+     * @return type boolean success
+     */
+    function validateSiteProfile()
+    {
+        if (empty($this->siteProfile))  {
+            $this->updateStatus("No site profile selected.", true);
+            return false;
+        }
+
+        return true;
+    }
+
+    /**
+     * Set up the database with the appropriate function for the selected type...
+     * Saves database info into $this->db.
+     *
+     * @fixme escape things in the connection string in case we have a funny pass etc
+     * @return mixed array of database connection params on success, false on failure
+     */
+    function setupDatabase()
+    {
+        if ($this->db) {
+            throw new Exception("Bad order of operations: DB already set up.");
+        }
+        $this->updateStatus("Starting installation...");
+
+        if (empty($this->password)) {
+            $auth = '';
+        } else {
+            $auth = ":$this->password";
+        }
+        $scheme = self::$dbModules[$this->dbtype]['scheme'];
+        $dsn = "{$scheme}://{$this->username}{$auth}@{$this->host}/{$this->database}";
+
+        $this->updateStatus("Checking database...");
+        $conn = $this->connectDatabase($dsn);
+
+        // ensure database encoding is UTF8
+        if ($this->dbtype == 'mysql') {
+            // @fixme utf8m4 support for mysql 5.5?
+            // Force the comms charset to utf8 for sanity
+            // This doesn't currently work. :P
+            //$conn->executes('set names utf8');
+        } else if ($this->dbtype == 'pgsql') {
+            $record = $conn->getRow('SHOW server_encoding');
+            if ($record->server_encoding != 'UTF8') {
+                $this->updateStatus("GNU social requires UTF8 character encoding. Your database is ". htmlentities($record->server_encoding));
+                return false;
+            }
+        }
+
+        $res = $this->updateStatus("Creating database tables...");
+        if (!$this->createCoreTables($conn)) {
+            $this->updateStatus("Error creating tables.", true);
+            return false;
+        }
+
+        foreach (array('sms_carrier' => 'SMS carrier',
+                    'notice_source' => 'notice source',
+                    'foreign_services' => 'foreign service')
+              as $scr => $name) {
+            $this->updateStatus(sprintf("Adding %s data to database...", $name));
+            $res = $this->runDbScript($scr.'.sql', $conn);
+            if ($res === false) {
+                $this->updateStatus(sprintf("Can't run %s script.", $name), true);
+                return false;
+            }
+        }
+
+        $db = array('type' => $this->dbtype, 'database' => $dsn);
+        return $db;
+    }
+
+    /**
+     * Open a connection to the database.
+     *
+     * @param <type> $dsn
+     * @return <type>
+     */
+    function connectDatabase($dsn)
+    {
+        global $_DB;
+        return $_DB->connect($dsn);
+    }
+
+    /**
+     * Create core tables on the given database connection.
+     *
+     * @param DB_common $conn
+     */
+    function createCoreTables(DB_common $conn)
+    {
+        $schema = Schema::get($conn);
+        $tableDefs = $this->getCoreSchema();
+        foreach ($tableDefs as $name => $def) {
+            if (defined('DEBUG_INSTALLER')) {
+                echo " $name ";
+            }
+            $schema->ensureTable($name, $def);
+        }
+        return true;
+    }
+
+    /**
+     * Fetch the core table schema definitions.
+     *
+     * @return array of table names => table def arrays
+     */
+    function getCoreSchema()
+    {
+        $schema = array();
+        include INSTALLDIR . '/db/core.php';
+        return $schema;
+    }
+
+    /**
+     * Return a parseable PHP literal for the given value.
+     * This will include quotes for strings, etc.
+     *
+     * @param mixed $val
+     * @return string
+     */
+    function phpVal($val)
+    {
+        return var_export($val, true);
+    }
+
+    /**
+     * Return an array of parseable PHP literal for the given values.
+     * These will include quotes for strings, etc.
+     *
+     * @param mixed $val
+     * @return array
+     */
+    function phpVals($map)
+    {
+        return array_map(array($this, 'phpVal'), $map);
+    }
+
+    /**
+     * Write a stock configuration file.
+     *
+     * @return boolean success
+     *
+     * @fixme escape variables in output in case we have funny chars, apostrophes etc
+     */
+    function writeConf()
+    {
+        $vals = $this->phpVals(array(
+            'sitename' => $this->sitename,
+            'server' => $this->server,
+            'path' => $this->path,
+            'ssl' => in_array($this->ssl, array('never', 'sometimes', 'always'))
+                     ? $this->ssl
+                     : 'never',
+            'db_database' => $this->db['database'],
+            'db_type' => $this->db['type']
+        ));
+
+        // assemble configuration file in a string
+        $cfg =  "<?php\n".
+                "if (!defined('GNUSOCIAL')) { exit(1); }\n\n".
+
+                // site name
+                "\$config['site']['name'] = {$vals['sitename']};\n\n".
+
+                // site location
+                "\$config['site']['server'] = {$vals['server']};\n".
+                "\$config['site']['path'] = {$vals['path']}; \n\n".
+                "\$config['site']['ssl'] = {$vals['ssl']}; \n\n".
+
+                // checks if fancy URLs are enabled
+                ($this->fancy ? "\$config['site']['fancy'] = true;\n\n":'').
+
+                // database
+                "\$config['db']['database'] = {$vals['db_database']};\n\n".
+                ($this->db['type'] == 'pgsql' ? "\$config['db']['quote_identifiers'] = true;\n\n":'').
+                "\$config['db']['type'] = {$vals['db_type']};\n\n";
+
+        // Normalize line endings for Windows servers
+        $cfg = str_replace("\n", PHP_EOL, $cfg);
+
+        // write configuration file out to install directory
+        $res = file_put_contents(INSTALLDIR.'/config.php', $cfg);
+
+        return $res;
+    }
+
+    /**
+     * Write the site profile. We do this after creating the initial user
+     * in case the site profile is set to single user. This gets around the
+     * 'chicken-and-egg' problem of the system requiring a valid user for
+     * single user mode, before the intial user is actually created. Yeah,
+     * we should probably do this in smarter way.
+     *
+     * @return int res number of bytes written
+     */
+    function writeSiteProfile()
+    {
+        $vals = $this->phpVals(array(
+            'site_profile' => $this->siteProfile,
+            'nickname' => $this->adminNick
+        ));
+
+        $cfg =
+        // site profile
+        "\$config['site']['profile'] = {$vals['site_profile']};\n";
+
+        if ($this->siteProfile == "singleuser") {
+            $cfg .= "\$config['singleuser']['nickname'] = {$vals['nickname']};\n\n";
+        } else {
+            $cfg .= "\n";
+        }
+
+        // Normalize line endings for Windows servers
+        $cfg = str_replace("\n", PHP_EOL, $cfg);
+
+        // write configuration file out to install directory
+        $res = file_put_contents(INSTALLDIR.'/config.php', $cfg, FILE_APPEND);
+
+        return $res;
+    }
+
+    /**
+     * Install schema into the database
+     *
+     * @param string    $filename location of database schema file
+     * @param DB_common $conn     connection to database
+     *
+     * @return boolean - indicating success or failure
+     */
+    function runDbScript($filename, DB_common $conn)
+    {
+        $sql = trim(file_get_contents(INSTALLDIR . '/db/' . $filename));
+        $stmts = explode(';', $sql);
+        foreach ($stmts as $stmt) {
+            $stmt = trim($stmt);
+            if (!mb_strlen($stmt)) {
+                continue;
+            }
+            try {
+                $res = $conn->simpleQuery($stmt);
+            } catch (Exception $e) {
+                $error = $e->getMessage();
+                $this->updateStatus("ERROR ($error) for SQL '$stmt'");
+                return false;
+            }
+        }
+        return true;
+    }
+
+    /**
+     * Create the initial admin user account.
+     * Side effect: may load portions of GNU social framework.
+     * Side effect: outputs program info
+     */
+    function registerInitialUser()
+    {
+        require_once INSTALLDIR . '/lib/common.php';
+
+        $data = array('nickname' => $this->adminNick,
+                      'password' => $this->adminPass,
+                      'fullname' => $this->adminNick);
+        if ($this->adminEmail) {
+            $data['email'] = $this->adminEmail;
+        }
+        $user = User::register($data);
+
+        if (empty($user)) {
+            return false;
+        }
+
+        // give initial user carte blanche
+
+        $user->grantRole('owner');
+        $user->grantRole('moderator');
+        $user->grantRole('administrator');
+
+        // Attempt to do a remote subscribe to update@status.net
+        // Will fail if instance is on a private network.
+
+        if ($this->adminUpdates && class_exists('Ostatus_profile')) {
+            try {
+                $oprofile = Ostatus_profile::ensureProfileURL('http://update.status.net/');
+                Subscription::start($user->getProfile(), $oprofile->localProfile());
+                $this->updateStatus("Set up subscription to <a href='http://update.status.net/'>update@status.net</a>.");
+            } catch (Exception $e) {
+                $this->updateStatus("Could not set up subscription to <a href='http://update.status.net/'>update@status.net</a>.", true);
+            }
+        }
+
+        return true;
+    }
+
+    /**
+     * The beef of the installer!
+     * Create database, config file, and admin user.
+     *
+     * Prerequisites: validation of input data.
+     *
+     * @return boolean success
+     */
+    function doInstall()
+    {
+        global $config;
+
+        $this->updateStatus("Initializing...");
+        ini_set('display_errors', 1);
+        error_reporting(E_ALL);
+        if (!defined('GNUSOCIAL')) {
+            define('GNUSOCIAL', true);
+        }
+        if (!defined('STATUSNET')) {
+            define('STATUSNET', true);
+        }
+
+        require_once INSTALLDIR . '/lib/framework.php';
+        StatusNet::initDefaults($this->server, $this->path);
+
+        if ($this->siteProfile == "singleuser") {
+            // Until we use ['site']['profile']==='singleuser' everywhere
+            $config['singleuser']['enabled'] = true;
+        }
+
+        try {
+            $this->db = $this->setupDatabase();
+            if (!$this->db) {
+                // database connection failed, do not move on to create config file.
+                return false;
+            }
+        } catch (Exception $e) {
+            // Lower-level DB error!
+            $this->updateStatus("Database error: " . $e->getMessage(), true);
+            return false;
+        }
+
+        // Make sure we can write to the file twice
+        $oldUmask = umask(000); 
+
+        if (!$this->skipConfig) {
+            $this->updateStatus("Writing config file...");
+            $res = $this->writeConf();
+
+            if (!$res) {
+                $this->updateStatus("Can't write config file.", true);
+                return false;
+            }
+        }
+
+        if (!empty($this->adminNick)) {
+            // Okay, cross fingers and try to register an initial user
+            if ($this->registerInitialUser()) {
+                $this->updateStatus(
+                    "An initial user with the administrator role has been created."
+                );
+            } else {
+                $this->updateStatus(
+                    "Could not create initial user account.",
+                    true
+                );
+                return false;
+            }
+        }
+
+        if (!$this->skipConfig) {
+            $this->updateStatus("Setting site profile...");
+            $res = $this->writeSiteProfile();
+
+            if (!$res) {
+                $this->updateStatus("Can't write to config file.", true);
+                return false;
+            }
+        }
+
+        // Restore original umask
+        umask($oldUmask);
+        // Set permissions back to something decent
+        chmod(INSTALLDIR.'/config.php', 0644);
+        
+        $scheme = $this->ssl === 'always' ? 'https' : 'http';
+        $link = "{$scheme}://{$this->server}/{$this->path}";
+
+        $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 mailing list and <a href="http://gnu.io/resources/">good documentation</a>.'
+        );
+
+        return true;
+    }
+
+    /**
+     * Output a pre-install-time warning message
+     * @param string $message HTML ok, but should be plaintext-able
+     * @param string $submessage HTML ok, but should be plaintext-able
+     */
+    abstract function warning($message, $submessage='');
+
+    /**
+     * Output an install-time progress message
+     * @param string $message HTML ok, but should be plaintext-able
+     * @param boolean $error true if this should be marked as an error condition
+     */
+    abstract function updateStatus($status, $error=false);
+
+}
index c2d60e11e974bec1414fe2b9b143b4babdb4ce0d..ca8ece7ebc1a075aa9d5e3e9813e72948d3b8db9 100644 (file)
@@ -1221,7 +1221,7 @@ class Action extends HTMLOutputter // lawsuit
      *
      * @return boolean is read only action?
      */
-    function isReadOnly($args)
+    function isReadOnly(array $args=array())
     {
         return false;
     }
index 3128088ca21b45772ff844e60ce98cc14378888d..9282461c1ccce4a29ef3c769191fcd3d426d32c2 100644 (file)
@@ -107,6 +107,7 @@ class Activity
     public $selfLink; // <link rel='self' type='application/atom+xml'>
     public $editLink; // <link rel='edit' type='application/atom+xml'>
     public $generator; // ActivityObject representing the generating application
+
     /**
      * Turns a regular old Atom <entry> into a magical activity
      *
index c4dd797e6d8076e11767e1fcb9a950b05aca30fa..51ea8ddf6bdca3d3871e03f103ca81a0f9a04cd3 100644 (file)
@@ -306,7 +306,7 @@ class ActivityImporter extends QueueHandler
             // Is the recipient a remote group?
             $oprofile = Ostatus_profile::ensureProfileURI($recipient);
 
-            if ($oprofile) {
+            if ($oprofile instanceof Ostatus_profile) {
                 if (!$oprofile->isGroup()) {
                     // may be canonicalized or something
                     $replies[] = $oprofile->uri;
@@ -321,10 +321,11 @@ class ActivityImporter extends QueueHandler
 
             if ($id) {
                 $group = User_group::getKV('id', $id);
-                if ($group) {
+                if ($group instanceof User_group) {
                     // Deliver to all members of this local group if allowed.
-                    $profile = $sender->localProfile();
-                    if ($profile->isMember($group)) {
+                    $profile = Profile::getKV('id', $recipient);
+
+                    if (($profile instanceof Profile) && ($profile->isMember($group))) {
                         $groups[] = $group->id;
                     } else {
                         common_log(LOG_INFO, "Skipping reply to local group {$group->nickname} as sender {$profile->id} is not a member");
index ef2e23224374b6a9ddd9629ef366e7f19ed0bdb7..bb430c6f7849b8f0818b18933d190f1d7005aab9 100644 (file)
@@ -301,7 +301,7 @@ class ActivityUtils
         return false;
     }
 
-    static function getFeedAuthor($feedEl)
+    static function getFeedAuthor(DOMElement $feedEl)
     {
         // Try old and deprecated activity:subject
 
@@ -348,10 +348,10 @@ class ActivityUtils
         return null;
     }
 
-    static function compareTypes($type, $objects)
+    static function compareTypes($type, array $objects)
     {
         $type = self::resolveUri($type);
-        foreach ((array)$objects as $object) {
+        foreach ($objects as $object) {
             if ($type === self::resolveUri($object)) {
                 return true;
             }
index 2ac92cb5c6522a38f8b6e6d789e9b21c20a0b890..af6e11a511487805f7c5aaf337c584f2d270fcd4 100644 (file)
@@ -60,7 +60,7 @@ class AdminPanelAction extends Action
      *
      * @return boolean success flag
      */
-    function prepare($args)
+    function prepare(array $args=array())
     {
         parent::prepare($args);
 
@@ -119,7 +119,7 @@ class AdminPanelAction extends Action
      *
      * @return void
      */
-    function handle($args)
+    function handle(array $args=array())
     {
         if ($_SERVER['REQUEST_METHOD'] == 'POST') {
             $this->checkSessionToken();
index 13d1a8c580d44e92f18c347040d5ff330a1708a4..cf3a86553869d3ce52944174e5cbeade7759282d 100644 (file)
@@ -163,7 +163,7 @@ class ApiListUsersAction extends ApiBareAuthAction
     {
     }
 
-    function isReadOnly($args)
+    function isReadOnly(array $args=array())
     {
         return false;
     }
index 95a3bec45d8a3ecd1aeb3b7c72dafb7473f7385d..53be050022bf2df3159949da976534e15e84a6ad 100644 (file)
@@ -49,7 +49,7 @@ class ApiOAuthAction extends ApiAction
      *
      * @return boolean false
      */
-    function isReadOnly($args)
+    function isReadOnly(array $args=array())
     {
         return false;
     }
index dcae917be36c17c8b0180d9d6982203601ba3016..f4f021dbfbc0c7c85b98a3cf1fed62ca91d25f38 100644 (file)
@@ -58,7 +58,7 @@ class AttachmentList extends Widget
      *
      * @param Notice $notice stream of notices from DB_DataObject
      */
-    function __construct(Notice $notice, $out=null)
+    function __construct(Notice $notice, Action $out=null)
     {
         parent::__construct($out);
         $this->notice = $notice;
@@ -99,12 +99,12 @@ class AttachmentList extends Widget
 
     function showListStart()
     {
-        $this->out->elementStart('ol', array('class' => 'attachments'));
+        $this->out->elementStart('div', array('class' => 'attachments'));
     }
 
     function showListEnd()
     {
-        $this->out->elementEnd('ol');
+        $this->out->elementEnd('div');
     }
 
     /**
index 3a95eb10c3f3c3d92e9b31a934e9ecb96a00bbe6..93dc4ca95e8840c3d9f4cb96d718400a9023a2fe 100644 (file)
@@ -204,7 +204,7 @@ class AttachmentListItem extends Widget
             $scripts[] = $script;
         }
         foreach ($scripts as $script) {
-            common_log(LOG_DEBUG, $script->textContent);
+            common_debug($script->textContent);
             $script->parentNode->removeChild($script);
         }
 
index 2c8fc5ee1a89c3da758924bc795f6e118a8408cb..5a8614ebb1bb9f3d394398992d473d3ff81d8cc3 100644 (file)
@@ -75,7 +75,7 @@ class AttachmentTagCloudSection extends TagCloudSection
     function getTags()
     {
         $notice_tag = new Notice_tag;
-        $query = 'select tag,count(tag) as weight from notice_tag join file_to_post on (notice_tag.notice_id=post_id) join notice on notice_id = notice.id where file_id=' . $notice_tag->escape($this->out->attachment->id) . ' group by tag order by weight desc';
+        $query = 'select tag, notice_id, count(tag) as weight from notice_tag join file_to_post on (notice_tag.notice_id=post_id) join notice on notice_id = notice.id where file_id=' . $notice_tag->escape($this->out->attachment->id) . ' group by tag order by weight desc';
         $notice_tag->query($query);
         return $notice_tag;
     }
index 830b97ee239e9d8ba693efb3aa7f3ebf1b5cde4a..4b7f1c4f7e283beabd020ca5434d9a9885d792c9 100644 (file)
@@ -795,7 +795,7 @@ class SubscriptionsCommand extends Command
             $out .= ' ';
             $out .= implode(', ',$nicknames);
         }
-        $channel->output($this->user,$out);
+        $channel->output($this->user, $out);
     }
 }
 
@@ -822,7 +822,7 @@ class SubscribersCommand extends Command
             $out .= ' ';
             $out .= implode(', ',$nicknames);
         }
-        $channel->output($this->user,$out);
+        $channel->output($this->user, $out);
     }
 }
 
@@ -848,7 +848,7 @@ class GroupsCommand extends Command
                 count($nicknames));
             $out.=implode(', ',$groups);
         }
-        $channel->output($this->user,$out);
+        $channel->output($this->user, $out);
     }
 }
 
index 5b504cea3f84e0a4ab47a5913a0bfbe28a83fdc8..65293a8c934342d0de76023da1b7a8993745506e 100644 (file)
@@ -133,7 +133,7 @@ $default =
               'delete' => false,
               'move' => true),
         'image' =>
-        array('jpegquality' => 85),
+        array('jpegquality' => 95),
         'avatar' =>
         array('server' => null,
               'dir' => INSTALLDIR . '/avatar/',
@@ -210,6 +210,7 @@ $default =
         array('server' => null,
               'dir' => INSTALLDIR . '/file/',
               'path' => $_path . '/file/',
+              'chmod' => 0644,        // Access rights (chmod) for any attachments
               'sslserver' => null,
               'sslpath' => null,
               'ssl' => null,
index 3331bcd19dc262597b97c9bebc00d8f60fae7350..583f7ebc9b3190353763ca2439f9d42f1815511c 100644 (file)
@@ -55,12 +55,8 @@ class DocFile
         $this->filename = $filename;
     }
 
-    static function forTitle($title, $paths)
+    static function forTitle($title, array $paths, $language=null)
     {
-        if (!is_array($paths)) {
-            $paths = array($paths);
-        }
-
         $filename = null;
 
         if (Event::handle('StartDocFileForTitle', array($title, &$paths, &$filename))) {
@@ -80,7 +76,7 @@ class DocFile
                 }
 
                 if (!empty($lang) || !empty($def)) {
-                    $filename = self::negotiateLanguage($lang, $def);
+                    $filename = self::negotiateLanguage($lang, $def, $language);
                     break;
                 }
             }
@@ -95,12 +91,8 @@ class DocFile
         }
     }
 
-    function toHTML($args=null)
+    function toHTML(array $args=array())
     {
-        if (is_null($args)) {
-            $args = array();
-        }
-
         if (empty($this->contents)) {
             $this->contents = file_get_contents($this->filename);
         }
@@ -114,7 +106,7 @@ class DocFile
                        INSTALLDIR.'/doc-src/');
 
         $site = GNUsocial::currentSite();
-        
+
         if (!empty($site)) {
             array_unshift($paths, INSTALLDIR.'/local/doc-src/'.$site.'/');
         }
@@ -128,7 +120,7 @@ class DocFile
                        INSTALLDIR.'/mail-src/');
 
         $site = GNUsocial::currentSite();
-        
+
         if (!empty($site)) {
             array_unshift($paths, INSTALLDIR.'/local/mail-src/'.$site.'/');
         }
@@ -136,12 +128,20 @@ class DocFile
         return $paths;
     }
 
-    static function negotiateLanguage($filenames, $defaultFilename=null)
+    private static function negotiateLanguage(array $filenames, $defaultFilename=null, $language = null)
     {
-        // XXX: do this better
-
+        // Default is current language
         $langcode = common_language();
 
+        // Is a language set?
+        if (!empty($language)) {
+            // And is it valid?
+            if (common_valid_language($language)) {
+                // Use this as language (e.g. from form)
+                $langcode = strval($language);
+            }
+        }
+
         foreach ($filenames as $filename) {
             if (preg_match('/\.'.$langcode.'$/', $filename)) {
                 return $filename;
index 7d74fc47130eaf20f6bb23b116e21eab8f9d6664..684f92bf96b68f164ec0f0e6d9b3e412e090baae 100644 (file)
@@ -63,7 +63,7 @@ class FormAction extends ManagedAction
         return true;
     }
 
-    public function isReadOnly($args) {
+    public function isReadOnly(array $args=array()) {
         return !$this->isPost();
     }
 
index 8b47197e76a6226330a578b0c95fe1ab0e164375..2ce4ed71f00f79bf04a094c8aac28424f76bf2a4 100644 (file)
@@ -27,7 +27,7 @@ define('GNUSOCIAL_LIFECYCLE', 'beta2'); // 'dev', 'alpha[0-9]+', 'beta[0-9]+', '
 
 define('GNUSOCIAL_VERSION', GNUSOCIAL_BASE_VERSION . '-' . GNUSOCIAL_LIFECYCLE);
 
-define('GNUSOCIAL_CODENAME', 'Not decided yet');
+define('GNUSOCIAL_CODENAME', 'Only a fixed bug is a good bug.');
 
 define('AVATAR_PROFILE_SIZE', 96);
 define('AVATAR_STREAM_SIZE', 48);
@@ -110,6 +110,28 @@ function _have_config()
     return GNUsocial::haveConfig();
 }
 
+function common_get_temp_dir()
+{
+    // Try to get it from php.ini first
+    $temp_path = trim(ini_get('upload_tmp_dir'));
+
+    // Is it empty?
+    if (strlen($temp_path) == 0) {
+        // Then try sys_get_temp_dir()
+        $temp_path = trim(sys_get_temp_dir());
+
+        // Still empty?
+        if (strlen($temp_path) == 0) {
+            // Then set it to /tmp (ugly)
+            // @TODO Hard-coded non-Windows stuff!
+            $temp_path = '/tmp';
+        }
+    }
+
+    // Return found path
+    return $temp_path;
+}
+
 function GNUsocial_class_autoload($cls)
 {
     if (file_exists(INSTALLDIR.'/classes/' . $cls . '.php')) {
@@ -126,6 +148,7 @@ function GNUsocial_class_autoload($cls)
     }
 }
 
+
 // Autoload function queue, starting with our own discovery method
 spl_autoload_register('GNUsocial_class_autoload');
 
index 5d11e6acddc7e2cdeeee5ae5c4e85ae82acf1f13..b1a5d771979caf5c432882ada033e0eddedd3d8c 100644 (file)
@@ -325,7 +325,7 @@ class GroupAdminSection extends ProfileSection
 
 class GroupMembersMiniList extends ProfileMiniList
 {
-    function newListItem($profile)
+    function newListItem(Profile $profile)
     {
         return new GroupMembersMiniListItem($profile, $this->action);
     }
@@ -347,7 +347,7 @@ class GroupMembersMiniListItem extends ProfileMiniListItem
 
 class GroupBlockedMiniList extends ProfileMiniList
 {
-    function newListItem($profile)
+    function newListItem(Profile $profile)
     {
         return new GroupBlockedMiniListItem($profile, $this->action);
     }
index 39e904222adc719af04cd06773ff4c639ede9d42..d29a149573323b56ffd612643de9a7aa59d49d0e 100644 (file)
@@ -136,7 +136,7 @@ class GroupList extends Widget
 
         $this->out->elementEnd('div');
 
-        if ($user) {
+        if ($user instanceof User) {
             $this->out->elementStart('div', 'entity_actions');
             $this->out->elementStart('ul');
             $this->out->elementStart('li', 'entity_subscribe');
index ba608213a43e2d37a3b68a1010b998ce6ae581a6..f055e24731fca0dcea02593938e31c6d8ee032f3 100644 (file)
@@ -12,7 +12,7 @@ class GroupMemberList extends ProfileList
         $this->group = $group;
     }
 
-    function newListItem($profile)
+    function newListItem(Profile $profile)
     {
         return new GroupMemberListItem($profile, $this->group, $this->action);
     }
index 5ed14560ce7a6efde2db81f3d91f24c3738805d5..68af4d307446396b9842a64a46c424770bbe4936 100644 (file)
@@ -76,7 +76,7 @@ class GroupTagCloudSection extends TagCloudSection
 
         $namestring = implode(',', $quoted);
 
-        $qry = 'SELECT notice_tag.tag, '.
+        $qry = 'SELECT notice_tag.tag, notice_tag.notice_id, '.
           $weightexpr . ' as weight ' .
           'FROM notice_tag JOIN notice ' .
           'ON notice_tag.notice_id = notice.id ' .
index 4b854914c929ac0dd54d3f7787fc4556e5e90050..4990d5ba844e192e3e11295270341e78a528f44d 100644 (file)
@@ -239,13 +239,16 @@ class HTTPClient extends HTTP_Request2
             $this->config['follow_redirects'] = $follow_redirects;
             return $this->doRequest($url, self::METHOD_HEAD, $headers);
         } catch (Exception $e) {
-            // Let the exception go on its merry way.
-            throw $e;
-        } finally {
             // reset to the old value
             $this->config['follow_redirects'] = $old_follow;
+
+            // Let the exception go on its merry way.
+            throw $e;
         }
         //we've either returned or thrown exception here
+
+        // reset to the old value
+        $this->config['follow_redirects'] = $old_follow;
     }
 
     /**
index 71074877374e4dc38feaeed032948501846b4596..1a23d7b5ab9f9f8535d46e9d5ab49d7bb742b2d1 100644 (file)
@@ -76,13 +76,12 @@ class ImageFile
 
         $info = @getimagesize($this->filepath);
 
-        if (!(
-            ($info[2] == IMAGETYPE_GIF && function_exists('imagecreatefromgif')) ||
-            ($info[2] == IMAGETYPE_JPEG && function_exists('imagecreatefromjpeg')) ||
-            $info[2] == IMAGETYPE_BMP ||
-            ($info[2] == IMAGETYPE_WBMP && function_exists('imagecreatefromwbmp')) ||
-            ($info[2] == IMAGETYPE_XBM && function_exists('imagecreatefromxbm')) ||
-            ($info[2] == IMAGETYPE_PNG && function_exists('imagecreatefrompng')))) {
+        if (
+            ($info[2] == IMAGETYPE_GIF && !function_exists('imagecreatefromgif')) ||
+            ($info[2] == IMAGETYPE_JPEG && !function_exists('imagecreatefromjpeg')) ||
+            ($info[2] == IMAGETYPE_WBMP && !function_exists('imagecreatefromwbmp')) ||
+            ($info[2] == IMAGETYPE_XBM && !function_exists('imagecreatefromxbm')) ||
+            ($info[2] == IMAGETYPE_PNG && !function_exists('imagecreatefrompng'))) {
 
             // TRANS: Exception thrown when trying to upload an unsupported image file format.
             throw new UnsupportedMediaException(_('Unsupported image format.'), $this->filepath);
@@ -254,6 +253,9 @@ class ImageFile
             if ($this->rotate == 0) {
                 // No rotational difference, just copy it as-is
                 @copy($this->filepath, $outpath);
+
+                // And set chmod
+                @chmod($outpath, common_config('attachments', 'chmod'));
                 return $outpath;
             } elseif (abs($this->rotate) == 90) {
                 // Box is rotated 90 degrees in either direction,
@@ -352,6 +354,9 @@ class ImageFile
             throw new Exception(_('Unknown file type'));
         }
 
+        // Always chmod 0644 (default) to have other processes (e.g. queue daemon read it)
+        @chmod($outpath, common_config('attachments', 'chmod'));
+
         imagedestroy($image_src);
         imagedestroy($image_dest);
     }
index 457c9dba5252d9528c3d5eb0568e97820d3d3cd6..9e4de6beb195fafaa675c25d7a4bee25d30bf1a3 100644 (file)
@@ -521,7 +521,7 @@ abstract class ImPlugin extends Plugin
      *
      * @return boolean hook return
      */
-    function onEndInitializeQueueManager($manager)
+    function onEndInitializeQueueManager(QueueManager $manager)
     {
         // If we don't require CLI mode, or if we do and GNUSOCIAL_CLI _is_ set, then connect the transports
         // This check is made mostly because some IM plugins can't deliver to transports unless they
@@ -540,7 +540,7 @@ abstract class ImPlugin extends Plugin
         return true;
     }
 
-    function onStartEnqueueNotice($notice, &$transports)
+    function onStartEnqueueNotice(Notice $notice, array &$transports)
     {
         $profile = Profile::getKV($notice->profile_id);
 
index d19f76366d6f09d072f8f04218d83d0c4f465d54..fbc137041fedfb9b8979ff6db79954e2dcce68ff 100644 (file)
@@ -72,7 +72,7 @@ class InboxTagCloudSection extends TagCloudSection
             $weightexpr = common_sql_weight('notice_tag.created', common_config('tag', 'dropoff'));
             // @fixme should we use the cutoff too? Doesn't help with indexing per-user.
 
-            $qry = 'SELECT notice_tag.tag, '.
+            $qry = 'SELECT notice_tag.tag, notice_tag.notice_id, '.
                 $weightexpr . ' as weight ' .
                 'FROM notice_tag JOIN notice ' .
                 'ON notice_tag.notice_id = notice.id ' .
index f72bed59d62a437b3714c7807c7c9ad357cc5775..d6c85d13d25ee6ff069541e902c17ac993b2dd72 100644 (file)
@@ -72,7 +72,7 @@ class InfoAction extends Action
         return empty($this->title) ? '' : $this->title;
     }
 
-    function isReadOnly($args)
+    function isReadOnly(array $args=array())
     {
         return true;
     }
index 971e2562b010d6fb5eb1897309943f32d5cbc46b..36f83a3ead5e723342022b2647d5ce8827e80c7e 100644 (file)
@@ -299,7 +299,10 @@ abstract class Installer
             }
         }
 
-        if (!$conn instanceof DB_common) {
+        if (!is_object($conn)) {
+            // No object at all
+            throw new Exception('Fatal error: conn is no object.');
+        } elseif (!$conn instanceof DB_common) {
             // Is not the right instance
             throw new Exception('Cannot connect to database: ' . $conn->getMessage());
         }
index 364ca75b9b32217b05ff245e195286ca6f9db1c2..be4dc163b059c56257b601f53188e08396f415e1 100644 (file)
@@ -93,6 +93,7 @@ class InviteForm extends Form
     function formData()
     {
         $this->out->elementStart('ul', 'form_data');
+
         $this->out->elementStart('li');
         $this->out->textarea(
             'addresses',
@@ -103,6 +104,7 @@ class InviteForm extends Form
             _('Addresses of friends to invite (one per line).')
         );
         $this->out->elementEnd('li');
+
         $this->out->elementStart('li');
         $this->out->textarea(
             // TRANS: Field label for a personal message to send to invitees.
@@ -112,6 +114,16 @@ class InviteForm extends Form
             _('Optionally add a personal message to the invitation.')
         );
         $this->out->elementEnd('li');
+
+        $language = common_language();
+
+        $this->out->elementStart('li');
+        $this->out->dropdown('language', _('Language'),
+            // TRANS: Tooltip for dropdown list label in form for profile settings.
+            get_nice_language_list(), _('Preferred language.'),
+            false, $language);
+        $this->out->elementEnd('li');
+
         $this->out->elementEnd('ul');
     }
 
index 7072761f2d2a03be6f34e5a66aae6eb445826044..e53fc6511e1eebce4694d4bc187a1c00fd60d605 100644 (file)
@@ -152,7 +152,7 @@ abstract class IoMaster
 
             if ($timeout > 0 && empty($sockets)) {
                 // If we had no listeners, sleep until the pollers' next requested wakeup.
-                common_log(LOG_DEBUG, "Sleeping $timeout seconds until next poll cycle...");
+                common_debug("Sleeping $timeout seconds until next poll cycle...");
                 $this->logState('sleep');
                 sleep($timeout);
             }
@@ -190,7 +190,7 @@ abstract class IoMaster
                 }
             } else if (common_config('queue', 'debug_memory')) {
                 $fmt = number_format($usage);
-                common_log(LOG_DEBUG, "Memory usage $fmt");
+                common_debug("Memory usage $fmt");
             }
         }
     }
index 236e99263d0bc418b18cb063f56c7b7eed938196..f0f797fe3257b609fa771d630667624b5b2e5989 100644 (file)
@@ -94,16 +94,20 @@ class Menu extends Widget
             $this->out->elementStart('ul', $attrs);
 
             foreach ($items as $item) {
+                assert(is_array($item));
+                assert(count($item) == 5);
+
                 list($actionName, $args, $label, $description, $id) = $item;
+
                 $this->item($actionName, $args, $label, $description, $id);
             }
-        
+
             $this->out->elementEnd('ul');
-            
+
             Event::handle('EndNav', array($this, $tag, $items));
         }
     }
-    
+
     function item($actionName, array $args, $label, $description, $id=null, $cls=null)
     {
         if (empty($id)) {
@@ -124,6 +128,12 @@ class Menu extends Widget
     {
         if ($actionName != $this->actionName) {
             return false;
+        } elseif (!is_array($args)) {
+            /*
+             * No array, then the below loop doesn't need to run and
+             * 'return false' will never be reached.
+             */
+            return true;
         }
 
         foreach ($this->actionArgs as $k => $v) {
@@ -134,11 +144,11 @@ class Menu extends Widget
 
         return true;
     }
-    
+
     function menuItemID($actionName, $args = null)
     {
         $id = sprintf('nav_%s', $actionName);
-        
+
         if (!is_null($args)) {
             foreach ($args as $key => $value) {
                 $id .= '_' . $key . '_' . $value;
index f9b2309119485aa12c72ee0df0f0fa2f133c35ce..698d1f6a609187339a158164c4c471cf2930b518 100644 (file)
@@ -97,17 +97,13 @@ class NoticeForm extends Form
      *                        'location_id' ID of location
      *                        'location_ns' Namespace of location
      */
-    function __construct($action, $options=null)
+    function __construct(Action $action, array $options = array())
     {
         parent::__construct($action);
 
         // When creating a notice form we don't want to collide with
         // possibly existing HTML elements, as naming conventions are similar.
-        $this->id_suffix = rand();
-
-        if (is_null($options)) {
-            $options = array();
-        }
+        $this->id_suffix = mt_rand();
 
         $this->actionName  = $action->trimmed('action');
 
@@ -269,7 +265,7 @@ class NoticeForm extends Form
                     'type' => 'checkbox',
                     'class' => 'checkbox',
                     'id' => $this->id() . '-notice_data-geo',
-                    'checked' => true, // ?
+                    'checked' => false, // Must be unchecked by default
                 ));
                 $this->out->element('label', array('class' => 'notice_data-geo',
                                                    'for'   => $this->id().'-notice_data-geo'),
index 727be89bc6d0da56effbe0c05bd9e176d323639d..317c7a3f03b8d3e290e9922e6901519f0c0fcf7b 100644 (file)
@@ -65,7 +65,7 @@ class NoticeList extends Widget
      *
      * @param Notice $notice stream of notices from DB_DataObject
      */
-    function __construct(Notice $notice, $out=null, array $prefs=array())
+    function __construct(Notice $notice, Action $out=null, array $prefs=array())
     {
         parent::__construct($out);
         $this->notice = $notice;
index 52dcbc1f6777507ae659d83c3cd3d8a3d191fbcd..2d538c6e6a9aa6f249cef1878b901acc0993df61 100644 (file)
@@ -199,7 +199,8 @@ class NoticeListItem extends Widget
     {
         if (Event::handle('StartShowNoticeOptions', array($this))) {
             $user = common_current_user();
-            if ($user) {
+
+            if ($user instanceof User) {
                 $this->out->elementStart('div', 'notice-options');
                 if (Event::handle('StartShowNoticeOptionItems', array($this))) {
                     $this->showReplyLink();
@@ -208,6 +209,7 @@ class NoticeListItem extends Widget
                 }
                 $this->out->elementEnd('div');
             }
+
             Event::handle('EndShowNoticeOptions', array($this));
         }
     }
index 46b4661e897ec1f8242f1185d5d7a885c6b493e9..3644de201524a4c0b27274c64624bfc917215325 100644 (file)
@@ -59,7 +59,7 @@ class PersonalTagCloudSection extends TagCloudSection
         $weightexpr = common_sql_weight('notice_tag.created', common_config('tag', 'dropoff'));
         // @fixme should we use the cutoff too? Doesn't help with indexing per-user.
 
-        $qry = 'SELECT notice_tag.tag, '.
+        $qry = 'SELECT notice_tag.tag, notice_tag.notice_id, '.
           $weightexpr . ' as weight ' .
           'FROM notice_tag JOIN notice ' .
           'ON notice_tag.notice_id = notice.id ' .
index 51c02aa2454a69d969e9900531d0ce4e93592ace..5085f161d58376095e7523378ef73dfccc3d0bfd 100644 (file)
@@ -31,8 +31,8 @@ if (!defined('STATUSNET')) {
     exit(1);
 }
 
-require INSTALLDIR . "/lib/pluginenableform.php";
-require INSTALLDIR . "/lib/plugindisableform.php";
+require INSTALLDIR . '/lib/pluginenableform.php';
+require INSTALLDIR . '/lib/plugindisableform.php';
 
 /**
  * Plugin list
@@ -45,12 +45,12 @@ require INSTALLDIR . "/lib/plugindisableform.php";
  */
 class PluginList extends Widget
 {
-    var $plugins = array();
+    var $pluginNames = array();
 
-    function __construct($plugins, $out)
+    function __construct(array $pluginNames, Action $out=null)
     {
         parent::__construct($out);
-        $this->plugins = $plugins;
+        $this->pluginNames = $pluginNames;
     }
 
     function show()
@@ -72,37 +72,37 @@ class PluginList extends Widget
 
     function showPlugins()
     {
-        foreach ($this->plugins as $plugin) {
-            $pli = $this->newListItem($plugin);
+        foreach ($this->pluginNames as $pluginName) {
+            $pli = $this->newListItem($pluginName);
             $pli->show();
         }
     }
 
-    function newListItem($plugin)
+    function newListItem($pluginName)
     {
-        return new PluginListItem($plugin, $this->out);
+        return new PluginListItem($pluginName, $this->out);
     }
 }
 
 class PluginListItem extends Widget
 {
     /** Current plugin. */
-    var $plugin = null;
+    private $pluginName = null;
 
     /** Local cache for plugin version info */
     protected static $versions = false;
 
-    function __construct($plugin, $out)
+    function __construct($pluginName, Action $out=null)
     {
         parent::__construct($out);
-        $this->plugin = $plugin;
+        $this->pluginName = $pluginName;
     }
 
     function show()
     {
         $meta = $this->metaInfo();
 
-        $this->out->elementStart('tr', array('id' => 'plugin-' . $this->plugin));
+        $this->out->elementStart('tr', array('id' => 'plugin-' . $this->pluginName));
 
         // Name and controls
         $this->out->elementStart('td');
@@ -110,7 +110,7 @@ class PluginListItem extends Widget
         if (!empty($meta['homepage'])) {
             $this->out->elementStart('a', array('href' => $meta['homepage']));
         }
-        $this->out->text($this->plugin);
+        $this->out->text($this->pluginName);
         if (!empty($meta['homepage'])) {
             $this->out->elementEnd('a');
         }
@@ -153,11 +153,11 @@ class PluginListItem extends Widget
      */
     protected function getControlForm()
     {
-        $key = 'disable-' . $this->plugin;
+        $key = 'disable-' . $this->pluginName;
         if (common_config('plugins', $key)) {
-            return new PluginEnableForm($this->out, $this->plugin);
+            return new PluginEnableForm($this->out, $this->pluginName);
         } else {
-            return new PluginDisableForm($this->out, $this->plugin);
+            return new PluginDisableForm($this->out, $this->pluginName);
         }
     }
 
@@ -177,7 +177,7 @@ class PluginListItem extends Widget
             // hack for URL shorteners... "LilUrl (ur1.ca)" etc
             list($name, ) = explode(' ', $info['name']);
 
-            if ($name == $this->plugin) {
+            if ($name == $this->pluginName) {
                 if ($found) {
                     // hack for URL shorteners...
                     $found['rawdescription'] .= "<br />\n" . $info['rawdescription'];
@@ -190,7 +190,7 @@ class PluginListItem extends Widget
         if ($found) {
             return $found;
         } else {
-            return array('name' => $this->plugin,
+            return array('name' => $this->pluginName,
                          // TRANS: Plugin description for a disabled plugin.
                          'rawdescription' => _m('plugin-description','(The plugin description is unavailable when a plugin has been disabled.)'));
         }
index bdcd575b6b6b946cb5fa2ce2390960b4b60cd0f9..1ba5ed77eb9abde963511aecd81d9c125bce7a3f 100644 (file)
@@ -103,7 +103,7 @@ abstract class ProfileAction extends ManagedAction
         return $this->target;
     }
 
-    function isReadOnly($args)
+    function isReadOnly(array $args=array())
     {
         return true;
     }
@@ -203,20 +203,19 @@ abstract class ProfileAction extends ManagedAction
         // TRANS: H2 text for user statistics.
         $this->element('h2', null, _('Statistics'));
 
-        $profile = $this->target;
-        $actionParams = array('nickname' => $profile->nickname);
+        $actionParams = array('nickname' => $this->target->nickname);
         $stats = array(
             array(
                 'id' => 'user-id',
                 // TRANS: Label for user statistics.
                 'label' => _('User ID'),
-                'value' => $profile->id,
+                'value' => $this->target->id,
             ),
             array(
                 'id' => 'member-since',
                 // TRANS: Label for user statistics.
                 'label' => _('Member since'),
-                'value' => date('j M Y', strtotime($profile->created))
+                'value' => date('j M Y', strtotime($this->target->created))
             ),
             array(
                 'id' => 'notices',
@@ -234,7 +233,7 @@ abstract class ProfileAction extends ManagedAction
         );
 
         // Give plugins a chance to add stats entries
-        Event::handle('ProfileStats', array($profile, &$stats));
+        Event::handle('ProfileStats', array($this->target, &$stats));
 
         foreach ($stats as $row) {
             $this->showStatsRow($row);
@@ -339,7 +338,7 @@ abstract class ProfileAction extends ManagedAction
 
 class SubscribersMiniList extends ProfileMiniList
 {
-    function newListItem($profile)
+    function newListItem(Profile $profile)
     {
         return new SubscribersMiniListItem($profile, $this->action);
     }
index 9ace6676c3b82fa16797c735f4b0630518dd429d..75f4359c9d8dd6c8b7c8780d4eff21cdde867c4e 100644 (file)
@@ -51,7 +51,7 @@ class ProfileFormAction extends RedirectingAction
      *
      * @return boolean success flag
      */
-    function prepare($args)
+    function prepare(array $args=array())
     {
         parent::prepare($args);
 
@@ -96,7 +96,7 @@ class ProfileFormAction extends RedirectingAction
      *
      * @return void
      */
-    function handle($args)
+    function handle(array $args=array())
     {
         parent::handle($args);
 
index 177560cdf568844ef7f2a070d463c343684a4f7b..8b2932f7247f7f546ca7df40a4a4d0675d21c568 100644 (file)
@@ -93,7 +93,7 @@ class ProfileList extends Widget
         return $cnt;
     }
 
-    function newListItem($profile)
+    function newListItem(Profile $profile)
     {
         return new ProfileListItem($profile, $this->action);
     }
index d2997d12de55cad30aa1a64d40a64b75570ae413..976c1819500d08a84dac8d52a48d36998846f7ee 100644 (file)
@@ -48,7 +48,7 @@ class ProfileMiniList extends ProfileList
         $this->out->elementStart('ul', 'entities users xoxo');
     }
 
-    function newListItem($profile)
+    function newListItem(Profile $profile)
     {
         return new ProfileMiniListItem($profile, $this->action);
     }
index bf88091a9020ab2324f018edb6e15c36ffa60af5..1ba4fa0cf4a1b564dde8f74c4ad14399787f1e2e 100644 (file)
@@ -77,7 +77,7 @@ class PublicTagCloudSection extends TagCloudSection
                 $weightexpr = common_sql_weight('notice_tag.created', common_config('tag', 'dropoff'));
                 // @fixme should we use the cutoff too? Doesn't help with indexing per-user.
 
-                $qry = 'SELECT notice_tag.tag, '.
+                $qry = 'SELECT notice_tag.tag, notice_tag.notice_id, '.
                     $weightexpr . ' as weight ' .
                     'FROM notice_tag JOIN notice ' .
                     'ON notice_tag.notice_id = notice.id ' .
index 28ee42662df5e3ec966f9400c38d422d9b1d1c35..1bbcd820a783cbafcbf75eb23b56130a9daa1817 100644 (file)
@@ -34,7 +34,7 @@ if (!defined('STATUSNET') && !defined('LACONICA')) {
 /**
  * URL Router
  *
- * Cheap wrapper around Net_URL_Mapper
+ * Cheap wrapper around URLMapper
  *
  * @category URL
  * @package  StatusNet
@@ -216,7 +216,7 @@ class Router
 
             // The second of these is needed to make the link work correctly
             // when inserted into the page. The first is needed to match the
-            // route on the way in. Seems to be another Net_URL_Mapper bug to me.
+            // route on the way in. Seems to be another URLMapper bug to me.
             $m->connect('search/notice/rss?q=:q', array('action' => 'noticesearchrss'),
                         array('q' => '.+'));
             $m->connect('search/notice/rss', array('action' => 'noticesearchrss'));
@@ -1119,7 +1119,7 @@ class Router
         }
 
         $url = $this->m->generate($args, $params, $fragment);
-        // Due to a bug in the Net_URL_Mapper code, the returned URL may
+        // Due to a bug in the URLMapper code, the returned URL may
         // contain a malformed query of the form ?p1=v1?p2=v2?p3=v3. We
         // repair that here rather than modifying the upstream code...
 
index 38b5b93865255cc719875385f9e927c999da4abe..575080a7bc2f906327a547dd8f18c686b51b9093 100644 (file)
@@ -63,12 +63,12 @@ class SchemaUpdater
         foreach ($this->tables as $table => $def) {
             $checksum = $this->checksum($def);
             if (empty($checksums[$table])) {
-                common_log(LOG_DEBUG, "No previous schema_version for $table: updating to $checksum");
+                common_debug("No previous schema_version for $table: updating to $checksum");
             } else if ($checksums[$table] == $checksum) {
-                common_log(LOG_DEBUG, "Last schema_version for $table up to date: $checksum");
+                common_debug("Last schema_version for $table up to date: $checksum");
                 continue;
             } else {
-                common_log(LOG_DEBUG, "Last schema_version for $table is {$checksums[$table]}: updating to $checksum");
+                common_debug("Last schema_version for $table is {$checksums[$table]}: updating to $checksum");
             }
             //$this->conn->query('BEGIN');
             $this->schema->ensureTable($table, $def);
@@ -108,7 +108,7 @@ class SchemaUpdater
             return $checksums;
         } catch (Exception $e) {
             // no dice!
-            common_log(LOG_DEBUG, "Possibly schema_version table doesn't exist yet.");
+            common_debug("Possibly schema_version table doesn't exist yet.");
         }
 
         return $checksums;
@@ -134,7 +134,7 @@ class SchemaUpdater
             }
         } catch (Exception $e) {
             // no dice!
-            common_log(LOG_DEBUG, "Possibly schema_version table doesn't exist yet.");
+            common_debug("Possibly schema_version table doesn't exist yet.");
         }
         $this->checksums[$table] = $checksum;
     }
index 6cb2ebcfd53929fa977fd64a7b866cef8be8d8c5..c33a786d8e9d80b7d6a34eada1e03c1e7d3398cc 100644 (file)
@@ -84,7 +84,6 @@ class MySQLSearch extends SearchEngine
                 $this->target->whereAdd('MATCH(nickname, fullname, location, bio, homepage) ' .
                                         'AGAINST (\''.$this->target->escape(strtolower($q)).'\' IN BOOLEAN MODE)', 'OR');
             }
-            return true;
         } else if ('notice' === $this->table) {
 
             // Don't show imported notices
@@ -100,10 +99,11 @@ class MySQLSearch extends SearchEngine
                                          'AGAINST (\''.$this->target->escape($q).'\' IN BOOLEAN MODE)');
             }
 
-            return true;
         } else {
             throw new ServerException('Unknown table: ' . $this->table);
         }
+
+        return true;
     }
 }
 
index f8acf34f072d69b5ca8f88cbdf4b2b9c96c409f6..450b04ba7a825140646f9e2a3a73eec9697761f4 100644 (file)
@@ -51,12 +51,12 @@ class SearchAction extends Action
      *
      * @return boolean true
      */
-    function isReadOnly($args)
+    function isReadOnly(array $args=array())
     {
         return true;
     }
 
-    function handle($args)
+    function handle(array $args=array())
     {
         parent::handle($args);
         $this->showPage();
index 29c12744076b301527ed8837ced2226ef2e6268e..f882b90c7f30b6e76094521914986943626ebd40 100644 (file)
@@ -53,7 +53,7 @@ class SubscriptionList extends ProfileList
         $this->owner = $owner;
     }
 
-    function newListItem($profile)
+    function newListItem(Profile $profile)
     {
         return new SubscriptionListItem($profile, $this->owner, $this->action);
     }
index 80a9042e0f1e0bac68016dabe147b2284b25e7b8..9f7320f2de41d750c96da518299e5ab843e4efac 100644 (file)
@@ -50,6 +50,7 @@ class TagCloudSection extends Section
     function showContent()
     {
         $tags = $this->getTags();
+        //* NOISY-DEBUG: */ common_debug('[' . __METHOD__ . ':' . __LINE__ . '] tags[]=' . gettype($tags));
 
         if (!$tags) {
             // TRANS: Content displayed in a tag cloud section if there are no tags.
@@ -63,8 +64,11 @@ class TagCloudSection extends Section
         $sum = 0;
 
         while ($tags->fetch() && ++$cnt <= TAGS_PER_SECTION) {
-            $tw[$tags->tag] = $tags->weight;
-            $sum += $tags->weight;
+            // Check scope of tag to current profile (including guests)
+            if ($tags->isCurrentProfileInScope()) {
+                $tw[$tags->tag] = $tags->weight;
+                $sum += $tags->weight;
+            }
         }
 
         if ($cnt == 0) {
index ebf0a460897069db61f43398e403e5905ee3b932..7f938df46ef50b85628ddec5983e83308d6e0d35 100644 (file)
@@ -261,7 +261,7 @@ class ThreadedNoticeListSubItem extends NoticeListItem
 {
     protected $root = null;
 
-    function __construct(Notice $notice, $root, $out)
+    function __construct(Notice $notice, $root, Action $out=null)
     {
         $this->root = $root;
         parent::__construct($notice, $out);
index 3a6f70fcdaee525cd5bf9c8b6326ee9bdfe82f74..bfc98ddd7970c4fbd33e8b6ab54513f67ffa5a39 100644 (file)
@@ -39,7 +39,7 @@ if (!defined('STATUSNET')) {
  *
  * Converts a path into a set of parameters, and vice versa
  *
- * We used to use Net_URL_Mapper, so there's a wrapper class at Router, q.v.
+ * We used to use URLMapper, so there's a wrapper class at Router, q.v.
  *
  * NUM's vagaries are the main reason we have weirdnesses here.
  *
diff --git a/lib/urlshortenerplugin2.php b/lib/urlshortenerplugin2.php
new file mode 100644 (file)
index 0000000..cb11b12
--- /dev/null
@@ -0,0 +1,212 @@
+<?php
+error_reporting(E_ALL );
+/**
+ * StatusNet, the distributed open-source microblogging tool
+ *
+ * Superclass(Version2) for plugins that do URL shortening
+ *
+ * PHP version >= 5.2
+ *
+ * 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 Plugin
+ * @package  StatusNet
+ * @author   Craig Andrews <candrews@integralblue.com>
+ * @license  http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
+ * @link     http://gnu.io
+ */
+define("STATUSNET", 1);
+if (!defined('STATUSNET') && !defined('LACONICA')) {
+    exit(1);
+}
+
+
+/**
+ * Class to handle Plugin exceptions
+ *
+ * @category Exception
+ * @package StatusNet
+ * @author   Craig Andrews <candrews@integralblue.com>
+ * @license  http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
+ * @link     http://gnu.io
+ */
+class PluginErrorException extends Exception {
+    protected $severity=0;
+    /**
+     * Setup costumizable Exceptions
+     * @var array $HTML Codes for Exceptionlists(see PluginErrorException::getFull())
+     */
+    protected $HTML=array(
+    'code'=>array("start"=>'<code>', "end"=>'</code'),
+    'ulist'=>array("start"=>'<ul>',  "end"=>'</ul>' ),
+    'list'=>array("start"=>"<li>", "end"=>"</li>"));
+    /**
+     * Create specific extension for PluginExceptions
+     * @
+     */
+    public function __construct($message, $code, $severity, $filename, $lineno, $HTML='') {
+        $this->message = $message;
+        $this->code = $code;
+        $this->severity = $severity;
+        $this->file = $filename;
+        $this->line = $lineno;
+    }
+
+    public function getSeverity() {
+        return $this->severity;
+    }
+    public function printFull() {
+      echo "Catched Exception: <ul><br />";
+      echo "<li>Message: <code>".$this->getMessage()."</code></li>  ";
+      echo "<li>Code: <code>".$this->getCode()."</code></li>        ";
+      echo "<li>Line: <code>".$this->getLine()."</code></li>        ";
+      echo "<li>File: <code>".$this->getFile()."</code></li>        ";
+      echo "<li>Severity: <code>".$this->getSeverity()."</code></li>";
+      echo "</ul><p>Code: 0 means an uncatched Exception, triggered ";
+      echo "by PHP's parsing. This is probally an Syntax-Error.</p> ";
+    }
+}
+/* Do done some exceptionrelated things done, befor
+ * we can start coding the real.
+ */
+function exception_error_handler($errno, $errstr, $errfile, $errline ) {
+    throw new PluginErrorException($errstr, 0, $errno, $errfile, $errline);
+}
+
+/* the Exceptionhandler for Syntax-Errors, throwed by PHP itself */
+/**
+ * Superclass for plugins that perform a url shortening
+ *
+ * @category Plugin
+ * @package  StatusNet
+ * @author   Craig Andrews <candrews@integralblue.com>
+ * @license  http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
+ * @link     http://darksider3.de/sn/urlshortenerplugin2.html
+ */
+
+abstract class UrlShortenerPlugin2
+{
+  public $shortenerName;
+  public $freeService = true;
+  /**
+  * Make an URL shorter.
+  *
+  * @param string $url URL to shorten
+  *
+  * @return string shortened version of the url/Null/Error
+  * @todo dont support old "shorten", name it to "shortUrl" to get well-named code.
+  */
+  protected abstract function shorten($url);
+
+
+  /**
+   * Utility to get the data at an URL
+   *
+   * @param     string $url             URL to fetch
+   * @exception PluginErrorExcpetion $e If HTTPClient throws an exception, print out.
+   * @return    string                  response body
+   * @todo throw an exception in HTTPClient and make the PluginErrorException more generally
+   *       so that we can use it more then ones, in every libfile.
+   */
+  protected function httpGet($url)
+  {
+    try
+    {
+      $request  = HTTPClient::start();
+      $response = $request->get($url);
+    } catch(PluginErrorException $e)
+    {
+      $e->printFull();
+      return false;
+    }
+    return $response->getBody();
+  }
+ /**
+  * Utility to post a request and get a response URL
+  *
+  * @param string $url  URL to fetch
+  * @param array  $data post parameters
+  *
+  * @return string response body
+  *
+  */
+  protected function httpPost($url, $data)
+  {
+    
+    $request  = HTTPClient::start();
+    $response = $request->post($url, null, $data);
+    return $response->getBody();
+  }
+  // Hook handlers
+
+  /**
+   * Called when all plugins have been initialized
+   *
+   * @return boolean hook value
+   */
+
+  function onInitializePlugin()
+  {
+    if (!isset($this->shortenerName))
+    {
+      throw new Exception("@Admin must specifiy $this->shortenerName");
+    }
+    return true;
+  }
+  /**
+   * Called when a showing the URL shortener drop-down box
+   *
+   * Properties of the shortening service currently only
+   * include whether it's a free service.
+   *
+   * @param array &$shorteners array mapping shortener name to properties
+   *
+   * @return boolean hook value
+   */
+  function onGetUrlShorteners(&$shorteners)
+  {
+    $shorteners[$this->shortenerName] =array('freeService' => $this->freeService);
+    return true;
+  }
+
+  /**
+   * Called to shorten an URL
+   *
+   * @param string $url           URL to shorten
+   * @param string $shortenerName Shortening service. Don't handle if it's
+   *                              not you!
+   * @param string &$shortenedUrl URL after shortening; out param.
+   *
+   * @return boolean hook value
+   */
+
+  function onStartShortenUrl($url, $shortenerName, &$shortenedUrl)
+  {
+    if ($shortenerName == $this->shortenerName)
+    {
+      $result = $this->shorten($url);
+      if (isset($result) && $result != null && $result !== false)
+      {
+        $shortenedUrl = $result;
+        //dont create an exception, so we can do that without.
+        common_log(LOG_INFO,
+                   __CLASS__ . ": $this->shortenerName ".
+                   "shortened $url to $shortenedUrl");
+        return false;
+      }
+    }
+    return true;
+  }
+}
+?>
index 3b5bb2de08aa2dde81822e7fd27d2b49b52ab7a3..62289ebe329d4d88bda89b1bdc07cd232d845ceb 100644 (file)
@@ -321,7 +321,7 @@ function common_set_user($user)
         return false;
     }
 
-    if ($user) {
+    if ($user instanceof User) {
         if (Event::handle('StartSetUser', array(&$user))) {
             if (!empty($user)) {
                 if (!$user->hasRight(Right::WEBLOGIN)) {
@@ -538,7 +538,7 @@ function common_user_cache_hash($user=false)
     if ($user === false) {
         $user = common_current_user();
     }
-    if ($user) {
+    if ($user instanceof User) {
         return crc32($user->id . ':' . $user->nickname);
     } else {
         return '0';
@@ -1285,7 +1285,7 @@ function common_is_sensitive($action)
 
 function common_path($relative, $ssl=false, $addSession=true)
 {
-    $pathpart = (common_config('site', 'path')) ? common_config('site', 'path')."/" : '';
+    $pathpart = (!empty(common_config('site', 'path'))) ? common_config('site', 'path') . '/' : '';
 
     if (($ssl && (common_config('site', 'ssl') === 'sometimes'))
         || GNUsocial::isHTTPS()
@@ -2355,7 +2355,7 @@ function common_perf_counter($key, $val=null)
                 $_perfCounters[$key] = array($val);
             }
             if (common_config('site', 'logperf_detail')) {
-                common_log(LOG_DEBUG, "PERF COUNTER HIT: $key $val");
+                common_debug("PERF COUNTER HIT: $key $val");
             }
         }
     }
@@ -2369,14 +2369,14 @@ function common_log_perf_counters()
         if (isset($_startTime)) {
             $endTime = microtime(true);
             $diff = round(($endTime - $_startTime) * 1000);
-            common_log(LOG_DEBUG, "PERF runtime: ${diff}ms");
+            common_debug("PERF runtime: ${diff}ms");
         }
         $counters = $_perfCounters;
         ksort($counters);
         foreach ($counters as $key => $values) {
             $count = count($values);
             $unique = count(array_unique($values));
-            common_log(LOG_DEBUG, "PERF COUNTER: $key $count ($unique unique)");
+            common_debug("PERF COUNTER: $key $count ($unique unique)");
         }
     }
 }
diff --git a/plugins/APC/APCPlugin.php b/plugins/APC/APCPlugin.php
new file mode 100644 (file)
index 0000000..8f2659d
--- /dev/null
@@ -0,0 +1,116 @@
+<?php
+/**
+ * StatusNet - the distributed open-source microblogging tool
+ * Copyright (C) 2009, StatusNet, Inc.
+ *
+ * Plugin to implement cache interface for APC variable cache
+ *
+ * PHP version 5
+ *
+ * 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  Cache
+ * @package   StatusNet
+ * @author    Evan Prodromou <evan@status.net>
+ * @copyright 2009 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')) {
+    // This check helps protect against security problems;
+    // your code file can't be executed directly from the web.
+    exit(1);
+}
+
+/**
+ * A plugin to use APC's variable cache for the cache interface
+ *
+ * New plugin interface lets us use alternative cache systems
+ * for caching. This one uses APC's variable cache.
+ *
+ * @category  Cache
+ * @package   StatusNet
+ * @author    Evan Prodromou <evan@status.net>
+ * @copyright 2009 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/
+ */
+
+class APCPlugin extends Plugin
+{
+    /**
+     * Get a value associated with a key
+     *
+     * The value should have been set previously.
+     *
+     * @param string &$key   in; Lookup key
+     * @param mixed  &$value out; value associated with key
+     *
+     * @return boolean hook success
+     */
+    function onStartCacheGet(&$key, &$value)
+    {
+        $value = apc_fetch($key);
+        Event::handle('EndCacheGet', array($key, &$value));
+        return false;
+    }
+
+    /**
+     * Associate a value with a key
+     *
+     * @param string  &$key     in; Key to use for lookups
+     * @param mixed   &$value   in; Value to associate
+     * @param integer &$flag    in; Flag (passed through to Memcache)
+     * @param integer &$expiry  in; Expiry (passed through to Memcache)
+     * @param boolean &$success out; Whether the set was successful
+     *
+     * @return boolean hook success
+     */
+    function onStartCacheSet(&$key, &$value, &$flag, &$expiry, &$success)
+    {
+        $success = apc_store($key, $value, ((is_null($expiry)) ? 0 : $expiry));
+
+        Event::handle('EndCacheSet', array($key, $value, $flag,
+                                           $expiry));
+        return false;
+    }
+
+    /**
+     * Delete a value associated with a key
+     *
+     * @param string  &$key     in; Key to lookup
+     * @param boolean &$success out; whether it worked
+     *
+     * @return boolean hook success
+     */
+    function onStartCacheDelete(&$key, &$success)
+    {
+        $success = apc_delete($key);
+        Event::handle('EndCacheDelete', array($key));
+        return false;
+    }
+
+    function onPluginVersion(array &$versions)
+    {
+        $versions[] = array('name' => 'APC',
+                            'version' => GNUSOCIAL_VERSION,
+                            'author' => 'Evan Prodromou',
+                            'homepage' => 'http://status.net/wiki/Plugin:APC',
+                            'rawdescription' =>
+                            // TRANS: Plugin description.
+                            _m('Use the <a href="http://pecl.php.net/package/apc">APC</a> variable cache to cache query results.'));
+        return true;
+    }
+}
index 768f71510f24c334752c9e223042eaf8008dd50e..24a95395a3d79ffbd3cabd0f4940c18c9abd0277 100644 (file)
@@ -61,7 +61,7 @@ class AccountManagerPlugin extends Plugin
                         common_local_url('AccountManagementControlDocument'));
     }
 
-    function onStartShowHTML($action)
+    function onStartShowHTML(Action $action)
     {
         //Account management discovery link
         header('Link: <'.common_local_url('AccountManagementControlDocument').'>; rel="'. AccountManagerPlugin::AM_REL.'"; type="application/json"');
index 955779b4ee6477bdea4ba4fcaea58c237a381d9f..c3c7c5955b44234a0a7a98562a7765f924365ca9 100644 (file)
@@ -49,7 +49,7 @@ class AccountManagementControlDocumentAction extends Action
      *
      * @return void
      */
-    function handle($args)
+    function handle(array $args=array())
     {
         parent::handle($args);
 
index 9eeff72402658bafdc365596b1e17e79715c76a3..b61fa59719f067abbf4f539e89d824e261cd6a66 100644 (file)
@@ -49,7 +49,7 @@ class AccountManagementSessionStatusAction extends Action
      *
      * @return void
      */
-    function handle($args)
+    function handle(array $args=array())
     {
         parent::handle($args);
 
index d8f3c6c50228b2480befa3cc7efeb59ca80dd2a8..0dc67cda637706b5cb47ebf4738db9e2f3a5ad43 100644 (file)
@@ -272,7 +272,7 @@ class ActivityPlugin extends Plugin
         return true;
     }
 
-    function onStartShowNoticeItem($nli)
+    function onStartShowNoticeItem(NoticeListItem $nli)
     {
         $notice = $nli->notice;
 
index 9d61b2ddddba392d34a59203dbe0fccbc14f512b..8d924dea97e015f6111de9c35b46d9bbfb01dbfb 100644 (file)
@@ -118,7 +118,7 @@ class ActivitySpamPlugin extends Plugin
         return true;
     }
 
-    function onNoticeDeleteRelated($notice) {
+    function onNoticeDeleteRelated(Notice $notice) {
         $score = Spam_score::getKV('notice_id', $notice->id);
         if (!empty($score)) {
             $score->delete();
@@ -126,7 +126,7 @@ class ActivitySpamPlugin extends Plugin
         return true;
     }
 
-    function onUserRightsCheck($profile, $right, &$result) {
+    function onUserRightsCheck(Profile $profile, $right, &$result) {
         switch ($right) {
         case self::REVIEWSPAM:
         case self::TRAINSPAM:
@@ -191,7 +191,7 @@ class ActivitySpamPlugin extends Plugin
         return true;
     }
 
-    function onEndShowStyles($action)
+    function onEndShowStyles(Action $action)
     {
         $action->element('style', null,
                          '.form-train-spam input.submit { background: url('.$this->path('icons/bullet_black.png').') no-repeat 0px 0px } ' . "\n" .
index a66b73a8294db0a1495d1560d56c6d3d08520af8..667b0a3612ad6a9fbf9aa6c3f25fde4214cf5d60 100644 (file)
@@ -154,11 +154,9 @@ class SpamAction extends Action
      * MAY override
      *
      * @param array $args other arguments
-     *
      * @return boolean is read only action?
      */
-
-    function isReadOnly($args)
+    function isReadOnly(array $args=array())
     {
         return true;
     }
index 5c583a2e0722ebb3d72d90b0623c3befac1cf39d..6a2a11d0698895d46a23ced6c58cca58cef3160e 100644 (file)
@@ -53,7 +53,7 @@ class Spam_score extends Managed_DataObject
     public $score;       // float
     public $created;     // datetime
 
-    function saveNew($notice, $result) {
+    function saveNew(Notice $notice, $result) {
 
         $score = new Spam_score();
 
index 3a5e585fd5218c4296678459990c37f3569f3981..4e710d10a7bac3735dbcef765fd442947eae4ebc 100644 (file)
@@ -31,7 +31,7 @@ Users who post a lot of spam get silenced
   -a --all      All users
 END_OF_SILENCESPAMMER_HELP;
 
-require_once INSTALLDIR.'/scripts/commandline.inc';
+require_once INSTALLDIR.'/scripts/commandline.inc.php';
 
 function testAllUsers($filter, $minimum, $percent) {
     $found = false;
index 0eee9324bf289bedf2992d31370b964e00592fdf..af3cc5b47a67ca18438e13fa1b605a9ed9e0858e 100644 (file)
@@ -31,7 +31,7 @@ Test user activities against the spam filter
   -a --all      All users
 END_OF_TESTUSER_HELP;
 
-require_once INSTALLDIR.'/scripts/commandline.inc';
+require_once INSTALLDIR.'/scripts/commandline.inc.php';
 
 function testAllUsers($filter) {
     $found = false;
index 974048b4c911211e63c9975031490344372d1460..a0d60b9a7b96943a44bd18ae843526e5da9bc65f 100644 (file)
@@ -32,7 +32,7 @@ Train user activities against the spam filter
 
 END_OF_TRAINUSER_HELP;
 
-require_once INSTALLDIR.'/scripts/commandline.inc';
+require_once INSTALLDIR.'/scripts/commandline.inc.php';
 
 function trainUser($filter, $user, $category) {
 
diff --git a/plugins/Adsense/AdsensePlugin.php b/plugins/Adsense/AdsensePlugin.php
new file mode 100644 (file)
index 0000000..80d90fa
--- /dev/null
@@ -0,0 +1,199 @@
+<?php
+/**
+ * StatusNet, the distributed open-source microblogging tool
+ *
+ * Plugin for Google Adsense
+ *
+ * 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  Ads
+ * @package   StatusNet
+ * @author    Evan Prodromou <evan@status.net>
+ * @copyright 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('STATUSNET')) {
+    exit(1);
+}
+
+/**
+ * Plugin to add Google Adsense to StatusNet sites
+ *
+ * This plugin lets you add Adsense ad units to your StatusNet site.
+ *
+ * We support the 4 ad sizes for the Universal Ad Platform (UAP):
+ *
+ *     Medium Rectangle
+ *     (Small) Rectangle
+ *     Leaderboard
+ *     Wide Skyscraper
+ *
+ * They fit in different places on the default theme. Some themes
+ * might interact quite poorly with this plugin.
+ *
+ * To enable advertising, you must sign up with Google Adsense and
+ * get a client ID.
+ *
+ *     https://www.google.com/adsense/
+ *
+ * You'll also need to create an Adsense for Content unit in one
+ * of the four sizes described above. At the end of the process,
+ * note the "google_ad_client" and "google_ad_slot" values in the
+ * resultant Javascript.
+ *
+ * Add the plugin to config.php like so:
+ *
+ *     addPlugin('Adsense', array('client' => 'Your client ID',
+ *                                'rectangle' => 'slot'));
+ *
+ * Here, your client ID is the value of google_ad_client and the
+ * slot is the value of google_ad_slot. Note that if you create
+ * a different size, you'll need to provide different arguments:
+ * 'mediumRectangle', 'leaderboard', or 'wideSkyscraper'.
+ *
+ * If for some reason your ad server is different from the default,
+ * use the 'adScript' parameter to set the full path to the ad script.
+ *
+ * @category Plugin
+ * @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/
+ *
+ * @seeAlso  UAPPlugin
+ */
+class AdsensePlugin extends UAPPlugin
+{
+    public $adScript = 'http://pagead2.googlesyndication.com/pagead/show_ads.js';
+    public $client   = null;
+
+    function initialize()
+    {
+        parent::initialize();
+
+        // A little bit of chicanery so we avoid overwriting values that
+        // are passed in with the constructor
+        foreach (array('mediumRectangle', 'rectangle', 'leaderboard', 'wideSkyscraper', 'adScript', 'client') as $setting) {
+            $value = common_config('adsense', strtolower($setting));
+            if (!empty($value)) { // not found
+                $this->$setting = $value;
+            }
+        }
+    }
+
+    /**
+     * Show a medium rectangle 'ad'
+     *
+     * @param Action $action Action being shown
+     *
+     * @return void
+     */
+    protected function showMediumRectangle($action)
+    {
+        $this->showAdsenseCode($action, 300, 250, $this->mediumRectangle);
+    }
+
+    /**
+     * Show a rectangle 'ad'
+     *
+     * @param Action $action Action being shown
+     *
+     * @return void
+     */
+    protected function showRectangle($action)
+    {
+        $this->showAdsenseCode($action, 180, 150, $this->rectangle);
+    }
+
+    /**
+     * Show a wide skyscraper ad
+     *
+     * @param Action $action Action being shown
+     *
+     * @return void
+     */
+    protected function showWideSkyscraper($action)
+    {
+        $this->showAdsenseCode($action, 160, 600, $this->wideSkyscraper);
+    }
+
+    /**
+     * Show a leaderboard ad
+     *
+     * @param Action $action Action being shown
+     *
+     * @return void
+     */
+    protected function showLeaderboard($action)
+    {
+        $this->showAdsenseCode($action, 728, 90, $this->leaderboard);
+    }
+
+    /**
+     * Output the bits of JavaScript code to show Adsense
+     *
+     * @param Action  $action Action being shown
+     * @param integer $width  Width of the block
+     * @param integer $height Height of the block
+     * @param string  $slot   Slot identifier
+     *
+     * @return void
+     */
+    protected function showAdsenseCode($action, $width, $height, $slot)
+    {
+        $code  = 'google_ad_client = "'.$this->client.'"; ';
+        $code .= 'google_ad_slot = "'.$slot.'"; ';
+        $code .= 'google_ad_width = '.$width.'; ';
+        $code .= 'google_ad_height = '.$height.'; ';
+
+        $action->inlineScript($code);
+
+        $action->script($this->adScript);
+    }
+
+    function onRouterInitialized(URLMapper $m)
+    {
+        $m->connect('panel/adsense',
+                    array('action' => 'adsenseadminpanel'));
+
+        return true;
+    }
+
+    function onEndAdminPanelNav(Menu $menu) {
+        if (AdminPanelAction::canAdmin('adsense')) {
+            // TRANS: Menu item title/tooltip
+            $menu_title = _m('AdSense configuration');
+            // TRANS: Menu item for site administration
+            $menu->out->menuItem(common_local_url('adsenseadminpanel'), _m('MENU','AdSense'),
+                                 $menu_title, $action_name == 'adsenseadminpanel', 'nav_adsense_admin_panel');
+        }
+        return true;
+    }
+
+    function onPluginVersion(array &$versions)
+    {
+        $versions[] = array('name' => 'BlankAdPlugin',
+                            'version' => GNUSOCIAL_VERSION,
+                            'author' => 'Evan Prodromou',
+                            'homepage' => 'http://status.net/wiki/Plugin:Adsense',
+                            'rawdescription' =>
+                            // TRANS: Plugin description.
+                            _m('Plugin to add Google AdSense to StatusNet sites.'));
+        return true;
+    }
+}
diff --git a/plugins/Aim/AimPlugin.php b/plugins/Aim/AimPlugin.php
new file mode 100644 (file)
index 0000000..1a90861
--- /dev/null
@@ -0,0 +1,165 @@
+<?php
+/**
+ * StatusNet - the distributed open-source microblogging tool
+ * Copyright (C) 2009, StatusNet, Inc.
+ *
+ * Send and receive notices using the AIM network
+ *
+ * PHP version 5
+ *
+ * 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  IM
+ * @package   StatusNet
+ * @author    Craig Andrews <candrews@integralblue.com>
+ * @copyright 2009 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);
+}
+// We bundle the phptoclib library...
+set_include_path(get_include_path() . PATH_SEPARATOR . dirname(__FILE__) . '/extlib/phptoclib');
+
+/**
+ * Plugin for AIM
+ *
+ * @category  Plugin
+ * @package   StatusNet
+ * @author    Craig Andrews <candrews@integralblue.com>
+ * @copyright 2009 StatusNet, Inc.
+ * @license   http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0
+ * @link      http://status.net/
+ */
+class AimPlugin extends ImPlugin
+{
+    public $user =  null;
+    public $password = null;
+    public $publicFeed = array();
+
+    public $transport = 'aim';
+
+    function getDisplayName()
+    {
+        // TRANS: Display name.
+        return _m('AIM');
+    }
+
+    function normalize($screenname)
+    {
+               $screenname = str_replace(" ","", $screenname);
+        return strtolower($screenname);
+    }
+
+    function daemonScreenname()
+    {
+        return $this->user;
+    }
+
+    function validate($screenname)
+    {
+        if(preg_match('/^[a-z]\w{2,15}$/i', $screenname)) {
+            return true;
+        }else{
+            return false;
+        }
+    }
+
+    /**
+     * Load related modules when needed
+     *
+     * @param string $cls Name of the class to be loaded
+     *
+     * @return boolean hook value; true means continue processing, false means stop.
+     */
+    function onAutoload($cls)
+    {
+        $dir = dirname(__FILE__);
+
+        switch ($cls)
+        {
+        case 'Aim':
+            require_once(INSTALLDIR.'/plugins/Aim/extlib/phptoclib/aimclassw.php');
+            return false;
+        }
+
+        return parent::onAutoload($cls);
+    }
+
+    function onStartImDaemonIoManagers(&$classes)
+    {
+        parent::onStartImDaemonIoManagers($classes);
+        $classes[] = new AimManager($this); // handles sending/receiving
+        return true;
+    }
+
+    function microiduri($screenname)
+    {
+        return 'aim:' . $screenname;
+    }
+
+    function sendMessage($screenname, $body)
+    {
+        $this->fake_aim->sendIm($screenname, $body);
+           $this->enqueueOutgoingRaw($this->fake_aim->would_be_sent);
+        return true;
+    }
+
+    /**
+     * Accept a queued input message.
+     *
+     * @return true if processing completed, false if message should be reprocessed
+     */
+    function receiveRawMessage($message)
+    {
+        $info=Aim::getMessageInfo($message);
+        $from = $info['from'];
+        $user = $this->getUser($from);
+        $notice_text = $info['message'];
+
+        $this->handleIncoming($from, $notice_text);
+
+        return true;
+    }
+
+    function initialize(){
+        if(!isset($this->user)){
+            // TRANS: Exception thrown in AIM plugin when user has not been specified.
+            throw new Exception(_m('Must specify a user.'));
+        }
+        if(!isset($this->password)){
+            // TRANS: Exception thrown in AIM plugin when password has not been specified.
+            throw new Exception(_m('Must specify a password.'));
+        }
+
+        $this->fake_aim = new Fake_Aim($this->user,$this->password,4);
+        return true;
+    }
+
+    function onPluginVersion(array &$versions)
+    {
+        $versions[] = array('name' => 'AIM',
+                            'version' => GNUSOCIAL_VERSION,
+                            'author' => 'Craig Andrews',
+                            'homepage' => 'http://status.net/wiki/Plugin:AIM',
+                            'rawdescription' =>
+                            // TRANS: Plugin description.
+                            _m('The AIM plugin allows users to send and receive notices over the AIM network.'));
+        return true;
+    }
+}
diff --git a/plugins/Aim/lib/aimmanager.php b/plugins/Aim/lib/aimmanager.php
new file mode 100644 (file)
index 0000000..dab4175
--- /dev/null
@@ -0,0 +1,100 @@
+<?php
+/*
+ * StatusNet - the 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/>.
+ */
+
+if (!defined('STATUSNET') && !defined('LACONICA')) { exit(1); }
+
+/**
+ * AIM background connection manager for AIM-using queue handlers,
+ * allowing them to send outgoing messages on the right connection.
+ *
+ * Input is handled during socket select loop, keepalive pings during idle.
+ * Any incoming messages will be handled.
+ *
+ * In a multi-site queuedaemon.php run, one connection will be instantiated
+ * for each site being handled by the current process that has XMPP enabled.
+ */
+class AimManager extends ImManager
+{
+    public $conn = null;
+    /**
+     * Initialize connection to server.
+     * @return boolean true on success
+     */
+    public function start($master)
+    {
+        if(parent::start($master))
+        {
+            $this->connect();
+            return true;
+        }else{
+            return false;
+        }
+    }
+
+    public function getSockets()
+    {
+        $this->connect();
+        if($this->conn){
+            return array($this->conn->myConnection);
+        }else{
+            return array();
+        }
+    }
+
+    /**
+     * Process AIM events that have come in over the wire.
+     * @param resource $socket
+     */
+    public function handleInput($socket)
+    {
+        common_debug("Servicing the AIM queue.");
+        $this->stats('aim_process');
+        $this->conn->receive();
+    }
+
+    function connect()
+    {
+        if (!$this->conn) {
+            $this->conn=new Aim($this->plugin->user,$this->plugin->password,4);
+            $this->conn->registerHandler("IMIn",array($this,"handle_aim_message"));
+            $this->conn->myServer="toc.oscar.aol.com";
+            $this->conn->signon();
+            // @todo i18n FIXME: Update translator documentation, please.
+            // TRANS: No idea what the use case for this message is.
+            $this->conn->setProfile(_m('Send me a message to post a notice'),false);
+        }
+        return $this->conn;
+    }
+
+    function handle_aim_message($data)
+    {
+        $this->plugin->enqueueIncomingRaw($data);
+        return true;
+    }
+
+    function send_raw_message($data)
+    {
+        $this->connect();
+        if (!$this->conn) {
+            return false;
+        }
+        $this->conn->sflapSend($data[0],$data[1],$data[2],$data[3]);
+        return true;
+    }
+}
index 841b6524012de81d5e2c72717bcbd900d78e9dc0..c00e0ecb509b17aa3bc5ff239f1b2fb7dd719eb4 100644 (file)
@@ -62,7 +62,7 @@ class AnonymousFavePlugin extends Plugin
     // that anonymous faving is allowed for all users.
     public $restricted = array();
 
-    function onArgsInitialize() {
+    function onArgsInitialize(array &$args) {
         // We always want a session because we're tracking anon users
         common_ensure_session();
     }
@@ -85,7 +85,7 @@ class AnonymousFavePlugin extends Plugin
         return true;
     }
 
-    function onEndShowHTML($action)
+    function onEndShowHTML(Action $action)
     {
         if (!common_logged_in()) {
             // Set a place to return to when submitting forms
@@ -93,7 +93,7 @@ class AnonymousFavePlugin extends Plugin
         }
     }
 
-    function onEndShowScripts($action)
+    function onEndShowScripts(Action $action)
     {
         // Setup ajax calls for favoriting. Usually this is only done when
         // a user is logged in.
index 6b0fae82c1584a58a621ab2cc831afa414f6f1db..1e42ca652bef22ca4763976cf0ec3d7308876ecd 100644 (file)
@@ -47,7 +47,7 @@ class AnonDisfavorAction extends RedirectingAction
      *
      * @return void
      */
-    function handle($args)
+    function handle(array $args=array())
     {
         parent::handle($args);
 
index 287c25cbe98455c12c698e7c31bbfa471554deea..6ce0e84a16d76347b7d3438eda68d51bbc03c152 100644 (file)
@@ -47,7 +47,7 @@ class AnonFavorAction extends RedirectingAction
      *
      * @return void
      */
-    function handle($args)
+    function handle(array $args=array())
     {
         parent::handle($args);
 
index a955620db57b3efa636bbdc62b39df7028a3e477..e0d0213d8f440b2dd8192a650f8fce52b6adad1d 100755 (executable)
@@ -27,7 +27,7 @@ Offline script to initialize notice fave tallys
 
 ENDOFHELP;
 
-require_once INSTALLDIR.'/scripts/commandline.inc';
+require_once INSTALLDIR.'/scripts/commandline.inc.php';
 
 $notice = new Notice();
 $notice->find();
index 920009de5ad9bc46c2117251b7cbc3af5ef962c6..0db34fd5aa1283334f3049ea2522945456db1689 100644 (file)
@@ -32,7 +32,7 @@ class ApiLoggerPlugin extends Plugin
     // 0.1 will check about 10% of hits, etc.
     public $frequency = 1.0;
 
-    function onArgsInitialize($args)
+    function onArgsInitialize(array &$args)
     {
         if (isset($args['action'])) {
             $action = strtolower($args['action']);
index 0f0c2592c2cd7bf7b3cbd0d832c71ce32e4268c9..0d3fdfc91dceab86f73c52ff39bddd96aef8021a 100644 (file)
@@ -39,7 +39,7 @@ class AutocompletePlugin extends Plugin
         parent::__construct();
     }
 
-    function onEndShowScripts($action){
+    function onEndShowScripts(Action $action){
         if (common_logged_in()) {
             $action->element('span', array('id' => 'autocomplete-api',
                                            'data-url' => common_local_url('autocomplete')));
@@ -47,7 +47,7 @@ class AutocompletePlugin extends Plugin
         }
     }
 
-    function onRouterInitialized($m)
+    function onRouterInitialized(URLMapper $m)
     {
         $m->connect('main/autocomplete/suggest', array('action'=>'autocomplete'));
     }
index 04acaefd38c5a5557035ac79b4af1f78fcc93194..c3e0433a891e1410acc98e1a9fc073fa2d5248ce 100644 (file)
@@ -178,7 +178,7 @@ class AutocompleteAction extends Action
      *
      * @return boolean is read only action?
      */
-    function isReadOnly($args)
+    function isReadOnly(array $args=array())
     {
         return true;
     }
index 13a1bf2ec4dc897fb82695701d5203a17e5cd7d9..3b6474dd86dd50b65d1a311039f1b546d3e61046 100644 (file)
@@ -188,7 +188,7 @@ class BitlyUrlPlugin extends UrlShortenerPlugin
     /**
      * Add the bit.ly admin panel to the list...
      */
-    function onEndAdminPanelNav($nav)
+    function onEndAdminPanelNav(Menu $nav)
     {
         if (AdminPanelAction::canAdmin('bitly')) {
             $action_name = $nav->action->trimmed('action');
index bad89f2457239a7f2fabbf3bbe24e4d0e51a9de2..1780f42e62736fdaedba9982513999251f10df8c 100644 (file)
@@ -122,7 +122,7 @@ class BlacklistPlugin extends Plugin
      *
      * @return boolean hook value
      */
-    function onStartRegisterUser(&$user, &$profile)
+    function onStartRegisterUser(User &$user, Profile &$profile)
     {
         $homepage = strtolower($profile->homepage);
 
@@ -330,7 +330,7 @@ class BlacklistPlugin extends Plugin
      *
      * @return boolean hook value
      */
-    function onEndAdminPanelNav($nav)
+    function onEndAdminPanelNav(Menu $nav)
     {
         if (AdminPanelAction::canAdmin('blacklist')) {
 
@@ -348,7 +348,7 @@ class BlacklistPlugin extends Plugin
         return true;
     }
 
-    function onEndDeleteUserForm($action, $user)
+    function onEndDeleteUserForm(Action $action, User $user)
     {
         $cur = common_current_user();
 
@@ -386,7 +386,7 @@ class BlacklistPlugin extends Plugin
         $action->elementEnd('ul');
     }
 
-    function onEndDeleteUser($action, $user)
+    function onEndDeleteUser(Action $action, User $user)
     {
         if ($action->boolean('blacklisthomepage')) {
             $pattern = $action->trimmed('blacklisthomepagepattern');
@@ -401,7 +401,7 @@ class BlacklistPlugin extends Plugin
         return true;
     }
 
-    function checkboxAndText($action, $checkID, $label, $textID, $value)
+    private function checkboxAndText(Action $action, $checkID, $label, $textID, $value)
     {
         $action->element('input', array('name' => $checkID,
                                         'type' => 'checkbox',
diff --git a/plugins/BlogspamNet/BlogspamNetPlugin.php b/plugins/BlogspamNet/BlogspamNetPlugin.php
deleted file mode 100644 (file)
index 2cab69b..0000000
+++ /dev/null
@@ -1,162 +0,0 @@
-<?php
-/**
- * StatusNet, the distributed open-source microblogging tool
- *
- * Plugin to check submitted notices with blogspam.net
- *
- * 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  Plugin
- * @package   StatusNet
- * @author    Evan Prodromou <evan@status.net>
- * @author    Brion Vibber <brion@status.net>
- * @copyright 2009 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')) {
-    exit(1);
-}
-
-define('BLOGSPAMNETPLUGIN_VERSION', '0.1');
-
-/**
- * Plugin to check submitted notices with blogspam.net
- *
- * When new notices are saved, we check their text with blogspam.net (or
- * a compatible service).
- *
- * Blogspam.net is supposed to catch blog comment spam, and I found that
- * some of its tests (min/max size, bayesian match) gave a lot of false positives.
- * So, I've turned those tests off by default. This may not get as many
- * hits, but it's better than nothing.
- *
- * @category Plugin
- * @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      Event
- */
-class BlogspamNetPlugin extends Plugin
-{
-    var $baseUrl = 'http://test.blogspam.net:8888/';
-
-    function __construct($url=null)
-    {
-        parent::__construct();
-        if ($url) {
-            $this->baseUrl = $url;
-        }
-    }
-
-    function onStartNoticeSave($notice)
-    {
-        $args = $this->testArgs($notice);
-        common_debug("Blogspamnet args = " . print_r($args, TRUE));
-        $requestBody = xmlrpc_encode_request('testComment', array($args));
-
-        $request = new HTTPClient($this->baseUrl, HTTPClient::METHOD_POST);
-        $request->setHeader('Content-Type', 'text/xml');
-        $request->setBody($requestBody);
-        $httpResponse = $request->send();
-
-        $response = xmlrpc_decode($httpResponse->getBody());
-        if (xmlrpc_is_fault($response)) {
-            throw new ServerException("$response[faultString] ($response[faultCode])", 500);
-        } else {
-            common_debug("Blogspamnet results = " . $response);
-            if (preg_match('/^ERROR(:(.*))?$/', $response, $match)) {
-                // TRANS: Server exception thrown when blogspam.net returns error status.
-                // TRANS: %1$s is the base URL, %2$s is the error (unknown contents; no period).
-                throw new ServerException(sprintf(_m('Error from %1$s: %2$s'), $this->baseUrl, $match[2]), 500);
-            } else if (preg_match('/^SPAM(:(.*))?$/', $response, $match)) {
-                // TRANS: Server exception thrown when blogspam.net returns spam status.
-                // TRANS: Does not end with period because of unknown contents for %s (spam match).
-                throw new ClientException(sprintf(_m('Spam checker results: %s'), $match[2]), 400);
-            } else if (preg_match('/^OK$/', $response)) {
-                // don't do anything
-            } else {
-                // TRANS: Server exception thrown when blogspam.net returns an unexpected status.
-                // TRANS: %1$s is the base URL, %2$s is the response (unknown contents; no period).
-                throw new ServerException(sprintf(_m('Unexpected response from %1$s: %2$s'), $this->baseUrl, $response), 500);
-            }
-        }
-        return true;
-    }
-
-    function testArgs($notice)
-    {
-        $args = array();
-        $args['comment'] = $notice->content;
-        $args['ip'] = $this->getClientIP();
-
-        if (isset($_SERVER) && array_key_exists('HTTP_USER_AGENT', $_SERVER)) {
-            $args['agent'] = $_SERVER['HTTP_USER_AGENT'];
-        }
-
-        $profile = $notice->getProfile();
-
-        if ($profile && $profile->homepage) {
-            $args['link'] = $profile->homepage;
-        }
-
-        if ($profile && $profile->fullname) {
-            $args['name'] = $profile->fullname;
-        } else {
-            $args['name'] = $profile->nickname;
-        }
-
-        $args['site'] = common_root_url();
-        $args['version'] = $this->userAgent();
-
-        $args['options'] = "max-size=" . common_config('site','textlimit') . ",min-size=0,min-words=0,exclude=bayasian";
-
-        return $args;
-    }
-
-    function getClientIP()
-    {
-        if (isset($_SERVER) && array_key_exists('REQUEST_METHOD', $_SERVER)) {
-            // Note: order matters here; use proxy-forwarded stuff first
-            foreach (array('HTTP_X_FORWARDED_FOR', 'CLIENT-IP', 'REMOTE_ADDR') as $k) {
-                if (isset($_SERVER[$k])) {
-                    return $_SERVER[$k];
-                }
-            }
-        }
-        return '127.0.0.1';
-    }
-
-    function version()
-    {
-        return BLOGSPAMNETPLUGIN_VERSION;
-    }
-
-    function onPluginVersion(array &$versions)
-    {
-        $versions[] = array('name' => 'BlogspamNet',
-                            'version' => BLOGSPAMNETPLUGIN_VERSION,
-                            'author' => 'Evan Prodromou, Brion Vibber',
-                            'homepage' => 'http://status.net/wiki/Plugin:BlogspamNet',
-                            'rawdescription' =>
-                            // TRANS: Plugin description.
-                            _m('Plugin to check submitted notices with blogspam.net.'));
-        return true;
-    }
-}
diff --git a/plugins/BlogspamNet/locale/BlogspamNet.pot b/plugins/BlogspamNet/locale/BlogspamNet.pot
deleted file mode 100644 (file)
index 0a0805c..0000000
+++ /dev/null
@@ -1,44 +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: Server exception thrown when blogspam.net returns error status.
-#. TRANS: %1$s is the base URL, %2$s is the error (unknown contents; no period).
-#: BlogspamNetPlugin.php:87
-#, php-format
-msgid "Error from %1$s: %2$s"
-msgstr ""
-
-#. TRANS: Server exception thrown when blogspam.net returns spam status.
-#. TRANS: Does not end with period because of unknown contents for %s (spam match).
-#: BlogspamNetPlugin.php:91
-#, php-format
-msgid "Spam checker results: %s"
-msgstr ""
-
-#. TRANS: Server exception thrown when blogspam.net returns an unexpected status.
-#. TRANS: %1$s is the base URL, %2$s is the response (unknown contents; no period).
-#: BlogspamNetPlugin.php:97
-#, php-format
-msgid "Unexpected response from %1$s: %2$s"
-msgstr ""
-
-#. TRANS: Plugin description.
-#: BlogspamNetPlugin.php:159
-msgid "Plugin to check submitted notices with blogspam.net."
-msgstr ""
diff --git a/plugins/BlogspamNet/locale/zh_TW/LC_MESSAGES/BlogspamNet.po b/plugins/BlogspamNet/locale/zh_TW/LC_MESSAGES/BlogspamNet.po
deleted file mode 100644 (file)
index 653fd2d..0000000
+++ /dev/null
@@ -1,48 +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 15:04+0000\n"
-"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
-"Language-Team: Chinese (Taiwan) (http://www.transifex.com/gnu-social/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: Server exception thrown when blogspam.net returns error status.
-#. TRANS: %1$s is the base URL, %2$s is the error (unknown contents; no
-#. period).
-#: BlogspamNetPlugin.php:87
-#, php-format
-msgid "Error from %1$s: %2$s"
-msgstr ""
-
-#. TRANS: Server exception thrown when blogspam.net returns spam status.
-#. TRANS: Does not end with period because of unknown contents for %s (spam
-#. match).
-#: BlogspamNetPlugin.php:91
-#, php-format
-msgid "Spam checker results: %s"
-msgstr ""
-
-#. TRANS: Server exception thrown when blogspam.net returns an unexpected
-#. status.
-#. TRANS: %1$s is the base URL, %2$s is the response (unknown contents; no
-#. period).
-#: BlogspamNetPlugin.php:97
-#, php-format
-msgid "Unexpected response from %1$s: %2$s"
-msgstr ""
-
-#. TRANS: Plugin description.
-#: BlogspamNetPlugin.php:159
-msgid "Plugin to check submitted notices with blogspam.net."
-msgstr ""
index 8b4abd2b42ba0c92e77c2680fceb7db58e936bd4..5186132d204abc5536d0ef8d385fbf5c9dbd6d2c 100644 (file)
@@ -57,7 +57,7 @@ class BookmarkPlugin extends MicroAppPlugin
      *
      * @return boolean hook value
      */
-    function onUserRightsCheck($profile, $right, &$result)
+    function onUserRightsCheck(Profile $profile, $right, &$result)
     {
         if ($right == self::IMPORTDELICIOUS) {
             $result = !$profile->isSilenced();
@@ -90,13 +90,13 @@ class BookmarkPlugin extends MicroAppPlugin
      *
      * @return boolean hook value
      */
-    function onEndShowStyles($action)
+    function onEndShowStyles(Action $action)
     {
         $action->cssLink($this->path('css/bookmark.css'));
         return true;
     }
 
-    function onEndShowScripts($action)
+    function onEndShowScripts(Action $action)
     {
         $action->script($this->path('js/bookmark.js'));
         return true;
@@ -163,7 +163,7 @@ class BookmarkPlugin extends MicroAppPlugin
      *
      * @return boolean hook value
      */
-    function onEndInitializeQueueManager($qm)
+    function onEndInitializeQueueManager(QueueManager $qm)
     {
         $qm->connect('dlcsback', 'DeliciousBackupImporter');
         $qm->connect('dlcsbkmk', 'DeliciousBookmarkImporter');
@@ -219,7 +219,7 @@ class BookmarkPlugin extends MicroAppPlugin
      *
      * @return boolean hook value
      */
-    function onEndProfileSettingsActions($action)
+    function onEndProfileSettingsActions(Action $action)
     {
         $user = common_current_user();
 
index ee43617127630e4859cf2bce4229063f19db424f..ac65722480e8166de9ecdcce05059f2ce48d892c 100644 (file)
@@ -57,7 +57,7 @@ class ApiTimelineBookmarksAction extends ApiBareAuthAction
      *
      * @return boolean success flag
      */
-    function prepare($args)
+    function prepare(array $args=array())
     {
         parent::prepare($args);
 
@@ -82,7 +82,7 @@ class ApiTimelineBookmarksAction extends ApiBareAuthAction
      *
      * @return void
      */
-    function handle($args)
+    function handle(array $args=array())
     {
         parent::handle($args);
         $this->showTimeline();
@@ -207,7 +207,7 @@ class ApiTimelineBookmarksAction extends ApiBareAuthAction
      *
      * @return boolean true
      */
-    function isReadOnly($args)
+    function isReadOnly(array $args=array())
     {
         return true;
     }
index c4cc4a8487cd81ed8c00f73036ca1b24c9d527ed..9fc0166b08b8661167c1f13be624d1e7d2a3e72e 100644 (file)
@@ -59,7 +59,7 @@ class BookmarkforurlAction extends Action
      *
      * @return boolean true
      */
-    function prepare($args)
+    function prepare(array $args=array())
     {
         parent::prepare($args);
 
@@ -103,11 +103,9 @@ class BookmarkforurlAction extends Action
      * Handler method
      *
      * @param array $args is ignored since it's now passed in in prepare()
-     *
      * @return void
      */
-
-    function handle($args=null)
+    function handle(array $args=array())
     {
         $this->startHTML('text/xml;charset=utf-8');
         $this->elementStart('head');
@@ -126,11 +124,9 @@ class BookmarkforurlAction extends Action
      * MAY override
      *
      * @param array $args other arguments
-     *
      * @return boolean is read only action?
      */
-
-    function isReadOnly($args)
+    function isReadOnly(array $args=array())
     {
         return false;
     }
index 6c79fa1d024ecdacac30111a3780964f1455974e..65a61a0bfb474c1e9f29abfccfbc8ee63f42f478 100644 (file)
@@ -60,7 +60,7 @@ class BookmarksAction extends Action
      *
      * @return boolean success flag
      */
-    function prepare($args)
+    function prepare(array $args=array())
     {
         parent::prepare($args);
 
@@ -74,7 +74,7 @@ class BookmarksAction extends Action
             $nickname = $this->returnToArgs();
             $nickname = $nickname[1]['nickname'];
         }
-        
+
         $this->user = User::getKV('nickname', $nickname);
 
         if (!$this->user) {
@@ -107,7 +107,7 @@ class BookmarksAction extends Action
      *
      * @return void
      */
-    function handle($args)
+    function handle(array $args=array())
     {
         parent::handle($args);
         $this->showPage();
@@ -223,7 +223,7 @@ class BookmarksAction extends Action
      *
      * @return boolean is read only action?
      */
-    function isReadOnly($args)
+    function isReadOnly(array $args=array())
     {
         return true;
     }
index 85a63e847063645f87abf69c4157e335d6b9e35a..149e8073432fa6503325c353c47c3440b3a602af 100644 (file)
@@ -245,7 +245,7 @@ class ImportdeliciousAction extends Action
      *
      * @return boolean is read only action?
      */
-    function isReadOnly($args)
+    function isReadOnly(array $args=array())
     {
         return !$this->isPost();
     }
index 470ad417a44a79b5ab2d033be144af1dbd1aabbc..466cbc5d801c55534082a4d226f469f34468013e 100644 (file)
@@ -143,7 +143,7 @@ class NewbookmarkAction extends FormAction
      *
      * @return boolean is read only action?
      */
-    function isReadOnly($args)
+    function isReadOnly(array $args=array())
     {
         if ($_SERVER['REQUEST_METHOD'] == 'GET' ||
             $_SERVER['REQUEST_METHOD'] == 'HEAD') {
index d5f9940805ef74b1689add1540b121de163044a7..e0eb61a05e6eafc207cb21d9fb426d4284b8132a 100644 (file)
@@ -142,7 +142,7 @@ class NoticebyurlAction extends Action
      *
      * @return boolean is read only action?
      */
-    function isReadOnly($args)
+    function isReadOnly(array $args=array())
     {
         return true;
     }
index c47a042973724f9b70ab008e87aee61757b4fe4a..af7dd2d1e06456b67e276e3c3a9eea1d9a394111 100644 (file)
@@ -42,7 +42,7 @@ Restore a backed-up Delicious.com bookmark file
 -f --file     file to read from (STDIN by default)
 END_OF_IMPORTBOOKMARKS_HELP;
 
-require_once INSTALLDIR.'/scripts/commandline.inc';
+require_once INSTALLDIR.'/scripts/commandline.inc.php';
 
 /**
  * Get the bookmarks file as a string
index 461655264e721e87ec7ecc3776980575b5872b56..7f467173b0766616d5f3d53575a8ca2520c42e77 100644 (file)
@@ -60,7 +60,7 @@ class CasAuthenticationPlugin extends AuthenticationPlugin
         return parent::onAutoload($cls);
     }
 
-    function onArgsInitialize(&$args)
+    function onArgsInitialize(array &$args)
     {
         if($this->takeOverLogin && $args['action'] == 'login')
         {
index 09377c62ebb8b763a6584dcb19a293d95f1dcedb..96e252b824c8bb1205b5ef74a52fa783b6953087 100644 (file)
@@ -21,7 +21,7 @@ if (!defined('STATUSNET') && !defined('LACONICA')) { exit(1); }
 
 class CasloginAction extends Action
 {
-    function handle($args)
+    function handle(array $args=array())
     {
         parent::handle($args);
         if (common_is_real_login()) {
index 4d87ab22404f905e30b2b5753bd99caf074a86eb..9dd3b1f5152157f2b94a2b8acdf2c103edbb94f6 100644 (file)
@@ -38,7 +38,7 @@ class ClientSideShortenPlugin extends Plugin
         parent::__construct();
     }
 
-    function onEndShowScripts($action){
+    function onEndShowScripts(Action $action){
         if (common_logged_in()) {
             $user = common_current_user();
             $action->inlineScript('var maxNoticeLength = ' . User_urlshortener_prefs::maxNoticeLength($user));
@@ -47,7 +47,7 @@ class ClientSideShortenPlugin extends Plugin
         }
     }
 
-    function onRouterInitialized($m)
+    function onRouterInitialized(URLMapper $m)
     {
         if (common_logged_in()) {
             $m->connect('plugins/ClientSideShorten/shorten', array('action'=>'shorten'));
index 6840d532aab720d4d21d2bdbf47431d9ccc3383f..376e245fc7f35b580e61ec28d45dc64addeeefc4 100644 (file)
@@ -45,7 +45,7 @@ class ShortenAction extends Action
 {
     private $text;
 
-    function prepare($args)
+    function prepare(array $args=array())
     {
         parent::prepare($args);
         $this->groups=array();
@@ -58,7 +58,7 @@ class ShortenAction extends Action
         return true;
     }
 
-    function handle($args=null)
+    function handle(array $args=array())
     {
         parent::handle($args);
         header('Content-Type: text/plain');
index 144902fce2316775a08b527467835f4fc2ae835d..ff39b3e4f4487ad97ecc2a5bc018f62f4e0017bd 100644 (file)
@@ -140,7 +140,7 @@ class ConversationTree extends NoticeList
      *
      * @return NoticeListItem a list item to show
      */
-    function newListItem($notice)
+    function newListItem(Notice $notice)
     {
         return new ConversationTreeItem($notice, $this->out);
     }
index de13ef680fa3cee7865ad5912519131794d77981..34533ba9e82cf5406c960aeb484168ca60d91c2e 100644 (file)
@@ -149,7 +149,7 @@ class DirectMessagePlugin extends Plugin
         return true;
     }
 
-    public function onProfileDeleteRelated(Profile $profile, &$related)
+    public function onProfileDeleteRelated(Profile $profile, array &$related)
     {
         $msg = new Message();
         $msg->from_profile = $profile->id;
index 8e7f6f806152cb03e9b88e4ea6927614b1701650..20cb0c28906551ffa9da8cd185f0b0a0a11dbb5b 100644 (file)
@@ -186,7 +186,7 @@ class ApiDirectMessageAction extends ApiAuthAction
      *
      * @return boolean true
      */
-    function isReadOnly($args)
+    function isReadOnly(array $args=array())
     {
         return true;
     }
index 86fbee8b73f95c303ac21f477da1a474d997b00c..0987ee3aa76d7d0f799c76ed9c2e4ec6bf4610a3 100644 (file)
@@ -62,7 +62,7 @@ class ShowmessageAction extends Action
      *
      * @return success flag
      */
-    function prepare($args)
+    function prepare(array $args=array())
     {
         parent::prepare($args);
 
@@ -89,7 +89,7 @@ class ShowmessageAction extends Action
         return true;
     }
 
-    function handle($args)
+    function handle(array $args=array())
     {
         $this->showPage();
     }
@@ -124,7 +124,7 @@ class ShowmessageAction extends Action
         $this->elementEnd('ul');
     }
 
-    function isReadOnly($args)
+    function isReadOnly(array $args=array())
     {
         return true;
     }
index 5f8d27b4f1584fa86069382de1dbcd344ab4e09b..29c177445ca0ffa094ef679eda6a325e45167c04 100644 (file)
@@ -83,12 +83,14 @@ class Message extends Managed_DataObject
 
         $msg->from_profile = $from;
         $msg->to_profile = $to;
-        if ($user) {
+
+        if ($user instanceof User) {
             // Use the sender's URL shortening options.
             $msg->content = $user->shortenLinks($content);
         } else {
             $msg->content = common_shorten_links($content);
         }
+
         $msg->rendered = common_render_text($msg->content);
         $msg->created = common_sql_now();
         $msg->source = $source;
index 561d38cd38f6fc0fbcee7ae9ecdc138b789233ba..73ea99940804e800b3d304c44725483937e22edc 100644 (file)
@@ -36,7 +36,7 @@ class DirectionDetectorPlugin extends Plugin {
      *
      * @param object $notice notice is going to be saved
      */
-    public function onStartNoticeSave($notice){
+    public function onStartNoticeSave(Notice $notice) {
         if(!preg_match('/<span class="rtl">/', $notice->rendered) && self::isRTL($notice->content))
             $notice->rendered = '<span class="rtl">'.$notice->rendered.'</span>';
         return true;
@@ -48,7 +48,7 @@ class DirectionDetectorPlugin extends Plugin {
      * @param string $content
      * @return boolean
      */
-    public static function isRTL($content){
+    public static function isRTL($content) {
         $content = self::getClearText($content);
         $words = explode(' ', $content);
         $rtl = 0;
@@ -71,7 +71,7 @@ class DirectionDetectorPlugin extends Plugin {
      * @param string $str
      * @return boolean
      */
-    public static function startsWithRTLCharacter($str){
+    public static function startsWithRTLCharacter($str ){
         if (strlen($str) < 1) {
             return false;
         }
@@ -106,7 +106,7 @@ class DirectionDetectorPlugin extends Plugin {
      * @param string $str
      * @return string
      */
-    private static function getClearText($str){
+    private static function getClearText($str) {
         $str = preg_replace('/@[^ ]+|![^ ]+|#[^ ]+/u', '', $str); // reply, tag, group
         $str = preg_replace('/^RT[: ]{1}| RT | RT: |^RD[: ]{1}| RD | RD: |[♺♻:]/u', '', $str); // redent, retweet
         $str = preg_replace("/[ \r\t\n]+/", ' ', trim($str)); // remove spaces
@@ -118,7 +118,7 @@ class DirectionDetectorPlugin extends Plugin {
      *
      * @param Action $action
      */
-    function onEndShowScripts($action){
+    function onEndShowScripts(Action $action){
         if (common_logged_in()) {
             $action->script($this->path('jquery.DirectionDetector.js'));
         }
index e06c1c7271c5b64a1cd42d510d77b2d9faf8722e..d940b813db2f4ae6f02922e3ea9b542e8b3e49c0 100644 (file)
@@ -82,37 +82,36 @@ class DirectoryPlugin extends Plugin
         $m->connect(
             'directory/users/:filter/sort_by/:sort/reverse/:reverse',
             array('action' => 'userdirectory'),
-            array('filter' => '[0-9a-zA-Z]|(0-9)'),            
+            array('filter' => '[0-9a-zA-Z]|(0-9)'),
             array('sort' => '[a-z]+'),
-            array('reverse' => '[0-9]')                        
+            array('reverse' => '[0-9]')
         );
 
         $m->connect(
             'directory/users/:filter/sort_by/:sort',
             array('action' => 'userdirectory'),
-            array('filter' => '[0-9a-zA-Z]|(0-9)'),            
-            array('sort' => '[a-z]+')            
-        );  
-
+            array('filter' => '[0-9a-zA-Z]|(0-9)'),
+            array('sort' => '[a-z]+')
+        );
 
         $m->connect(
             'directory/users/:filter',
             array('action' => 'userdirectory'),
             array('filter' => '[0-9a-zA-Z]|(0-9)')
         );
-        
+
         $m->connect(
             'directory/users/sort_by/:sort/reverse/:reverse',
             array('action' => 'userdirectory'),
             array('sort' => '[a-z]+'),
-            array('reverse' => '[0-9]')                        
+            array('reverse' => '[0-9]')
         );
 
         $m->connect(
             'directory/users/sort_by/:sort',
             array('action' => 'userdirectory'),
-            array('sort' => '[a-z]+')            
-        );        
+            array('sort' => '[a-z]+')
+        );
 
         $m->connect(
             'directory/users',
@@ -135,7 +134,6 @@ class DirectoryPlugin extends Plugin
             array('action' => 'groupdirectory')
         );
 
-
         return true;
     }
 
index 32e5ce50b4cdeb483831da0d9c3b150f4d7cfad4..8aef1742a884cc0f5b268fa81bd9f55f61ff0158 100644 (file)
@@ -129,7 +129,7 @@ class GroupdirectoryAction extends ManagedAction
      *
      * @return boolean true
      */
-    function isReadOnly($args)
+    function isReadOnly(array $args=array())
     {
         return true;
     }
index f178408e8bf11596d067fb5501ad1ead7c843956..55ce0de42086cbc4b80e33ca2d3deeab93594f3e 100644 (file)
@@ -127,7 +127,7 @@ class UserdirectoryAction extends ManagedAction
      *
      * @return boolean true
      */
-    function isReadOnly($args)
+    function isReadOnly(array $args=array())
     {
         return true;
     }
index ab00068f6d20a5f438794e1986dc3d07a98db8b8..fe0e1bcf676d041d8b8e52c4abf571ed1479dec8 100644 (file)
@@ -226,8 +226,8 @@ class SortableGroupListItem extends SortableSubscriptionListItem
     function showJoinButton()
     {
         $user = $this->owner;
-        if ($user) {
 
+        if ($user instanceof User) {
             $this->out->elementStart('li', 'entity_subscribe');
             // XXX: special-case for user looking at own
             // subscriptions page
index 062151db175acad33280425b628abec52dab6b04..2443139af6b02b0e6df1471674de529f1481bdb6 100644 (file)
@@ -124,7 +124,7 @@ class DomainStatusNetworkPlugin extends Plugin
         return true;
     }
 
-    function onRouterInitialized($m)
+    function onRouterInitialized(URLMapper $m)
     {
         if (common_config('globalapi', 'enabled')) {
             foreach (array('register', 'login', 'recover') as $method) {
index d47a254940e45dcc099c8004f810bb599706b2d1..b283ce8da6460cba97e48774f843b62c87860ffb 100644 (file)
@@ -57,7 +57,7 @@ class GlobalApiAction extends Action
      * @return boolean continuation flag
      */
 
-    function prepare($args)
+    function prepare(array $args=array())
     {
         GNUsocial::setApi(true); // reduce exception reports to aid in debugging
 
index f773094a74c426e9ccc023b43468d08e5a61cef2..1815b977596fe267ce731a1bf59a1de7b16a4040 100755 (executable)
@@ -35,7 +35,7 @@ Create a new account and, if necessary, a new network for the given email addres
 
 END_OF_INSTALLFOREMAIL_HELP;
 
-require_once INSTALLDIR.'/scripts/commandline.inc';
+require_once INSTALLDIR.'/scripts/commandline.inc.php';
 
 $email = $args[0];
 
index 96a722fdab775767ae943be3483be888905789eb..28741a5d4fb94a6cca6630d26c525e038e94ba8a 100755 (executable)
@@ -28,7 +28,7 @@ Prints site information for the domain given
 
 END_OF_SITEFORDOMAIN_HELP;
 
-require_once INSTALLDIR.'/scripts/commandline.inc';
+require_once INSTALLDIR.'/scripts/commandline.inc.php';
 
 $domain   = DomainStatusNetworkPlugin::toDomain($args[0]);
 
index 59412ccebab6929169091d7ccddae77aa837d6b4..2eaa600d2598009bffb075811eaabbbc133fe8b6 100755 (executable)
@@ -28,7 +28,7 @@ Prints site information for the domain given
 
 END_OF_SITEFORDOMAIN_HELP;
 
-require_once INSTALLDIR.'/scripts/commandline.inc';
+require_once INSTALLDIR.'/scripts/commandline.inc.php';
 
 $domain = DomainStatusNetworkPlugin::toDomain($args[0]);
 
index 2e15dd809a2c521974002006b39ae00603a9598a..76486f65b041f735a0fad43efcb19c97160b6294 100644 (file)
@@ -65,7 +65,7 @@ class DomainWhitelistPlugin extends Plugin
      *
      * @return boolean hook flag
      */
-    function onEndShowStatusNetScripts($action) {
+    public function onEndShowStatusNetScripts(Action $action) {
         $name = $action->arg('action');
         if ($name == 'invite') {
             $action->script($this->getPath() . '/js/whitelistinvite.js');
@@ -73,13 +73,14 @@ class DomainWhitelistPlugin extends Plugin
         return true;
     }
 
-    function onRequireValidatedEmailPlugin_Override($user, &$knownGood)
+    public function onRequireValidatedEmailPlugin_Override(User $user, &$knownGood)
     {
         $knownGood = (!empty($user->email) && $this->matchesWhitelist($user->email));
         return true;
     }
 
-    function onEndValidateUserEmail($user, $email, &$valid)
+    // @TODO Most callers are given NULL as first argument
+    public function onEndValidateUserEmail($user, $email, &$valid)
     {
         if ($valid) { // it's otherwise valid
             if (!$this->matchesWhitelist($email)) {
@@ -102,7 +103,7 @@ class DomainWhitelistPlugin extends Plugin
         return true;
     }
 
-    function onStartAddEmailAddress($user, $email)
+    public function onStartAddEmailAddress(User $user, $email)
     {
         if (!$this->matchesWhitelist($email)) {
             // TRANS: Exception thrown when an e-mail address does not match the site's domain whitelist.
index 9e0fd58856758894884d2692ee409de6e2c19f51..77ac763bd030df7a2a942afef7ec97c457dca1c6 100644 (file)
@@ -49,7 +49,7 @@ class EmailRegistrationPlugin extends Plugin
 {
     const CONFIRMTYPE = 'register';
 
-    function onArgsInitialize(&$args)
+    function onArgsInitialize(array &$args)
     {
         if (array_key_exists('action', $args) && $args['action'] == 'register') {
             // YOINK!
@@ -72,7 +72,7 @@ class EmailRegistrationPlugin extends Plugin
         $dir = dirname(__FILE__);
 
         // @todo FIXME: i18n issue.
-        $docFile = DocFile::forTitle($title, $dir.'/doc-src/');
+        $docFile = DocFile::forTitle($title, array($dir . '/doc-src/'));
 
         if (!empty($docFile)) {
             $output = $docFile->toHTML();
@@ -163,7 +163,7 @@ class EmailRegistrationPlugin extends Plugin
         mail_send($recipients, $headers, $body);
     }
 
-    function onEndDocFileForTitle($title, $paths, &$filename)
+    function onEndDocFileForTitle($title, array $paths, &$filename)
     {
         if ($title == 'confirmemailreg' && empty($filename)) {
             $filename = dirname(__FILE__).'/mail-src/'.$title;
index 7fa2aa22cf2efe06d0eae3c0858fc8043606074c..44c60e2cf2bddb2ef2676e69a1c08135ed0426a8 100644 (file)
@@ -391,7 +391,7 @@ class EmailregisterAction extends Action
      *
      * @return boolean is read only action?
      */
-    function isReadOnly($args)
+    function isReadOnly(array $args=array())
     {
         return false;
     }
index d834aade600abdb032570d35fb9dc1f9b7bf5b36..7ae81f7ccf8f48ead06666ce58052fa3c03817fc 100755 (executable)
@@ -33,7 +33,7 @@ Cancel an email registration code
 
 END_OF_REGISTEREMAILUSER_HELP;
 
-require_once INSTALLDIR.'/scripts/commandline.inc';
+require_once INSTALLDIR.'/scripts/commandline.inc.php';
 
 if (count($args) == 0) {
     show_help();
index 02915240d32d2e57b3abbff7f280e6dfd9256921..a785a76a6649080aefba71cc0323ed8172971292 100755 (executable)
@@ -34,7 +34,7 @@ register a new user by email address.
 
 END_OF_REGISTEREMAILUSER_HELP;
 
-require_once INSTALLDIR.'/scripts/commandline.inc';
+require_once INSTALLDIR.'/scripts/commandline.inc.php';
 
 if (count($args) == 0) {
     show_help();
index 9ac6275537afd6535de0a64f4e1aa0f23ae8157b..9ba3d125e11b0281279ab3a83d2fdffb7c34e27c 100644 (file)
@@ -68,7 +68,7 @@ class EmailReminderPlugin extends Plugin
      *
      * @return boolean hook value
      */
-    function onEndInitializeQueueManager($qm)
+    function onEndInitializeQueueManager(QueueManager $qm)
     {
         $qm->connect('siterem', 'SiteConfirmReminderHandler');
         $qm->connect('uregrem', 'UserConfirmRegReminderHandler');
@@ -77,7 +77,7 @@ class EmailReminderPlugin extends Plugin
         return true;
     }
 
-    function onEndDocFileForTitle($title, $paths, &$filename)
+    function onEndDocFileForTitle($title, array $paths, &$filename)
     {
         if (empty($filename)) {
             $filename = dirname(__FILE__) . '/mail-src/' . $title;
@@ -127,6 +127,7 @@ class EmailReminderPlugin extends Plugin
      * Send a real live email reminder
      *
      * @todo This would probably be better as two or more sep functions
+     * @todo Add language support?
      *
      * @param string $type      type of reminder
      * @param mixed  $object    Confirm_address or Invitation object
index 5b5b26dde38aa9a4d9a68e216336d64fd80a6dcc..b126f9e049329cdd2f56834d9a8f8991b0d8ad8c 100755 (executable)
@@ -35,7 +35,7 @@ Send an email summary of the inbox to users
 
 END_OF_SENDEMAILREMINDER_HELP;
 
-require_once INSTALLDIR . '/scripts/commandline.inc';
+require_once INSTALLDIR . '/scripts/commandline.inc.php';
 
 $quiet = have_option('q', 'quiet');
 
index bc47fdece946c628b95963a6b4994bd9a2ee5c2d..e00617ee3d44c464411be52f23e96fbb7a4576cc 100644 (file)
@@ -85,7 +85,7 @@ class EmailSummaryPlugin extends Plugin
      *
      * @return boolean hook value
      */
-    function onEndInitializeQueueManager($qm)
+    function onEndInitializeQueueManager(QueueManager $qm)
     {
         $qm->connect('sitesum', 'SiteEmailSummaryHandler');
         $qm->connect('usersum', 'UserEmailSummaryHandler');
index 721fede55b4e45c74e3dbf6cc47050df0e75af9b..b132975bcd9d2c4b60cba1743d6640c2d401de67 100644 (file)
@@ -33,7 +33,7 @@ Send an email summary of the inbox to users
 
 END_OF_SENDEMAILSUMMARY_HELP;
 
-require_once INSTALLDIR.'/scripts/commandline.inc';
+require_once INSTALLDIR.'/scripts/commandline.inc.php';
 
 if (have_option('u', 'universe')) {
     $sn = new Status_network();
index 5c4abc41d0200918cf9d6ea01480502ce014e7f4..a1d0761a4a03ce9042c23eab590b811b765e17da 100644 (file)
@@ -321,29 +321,29 @@ class EventPlugin extends MicroAppPlugin
     {
         switch ($notice->object_type) {
         case Happening::OBJECT_TYPE:
-            common_log(LOG_DEBUG, "Deleting event from notice...");
+            common_debug("Deleting event from notice...");
             $happening = Happening::fromNotice($notice);
             $happening->delete();
             break;
         case RSVP::POSITIVE:
         case RSVP::NEGATIVE:
         case RSVP::POSSIBLE:
-            common_log(LOG_DEBUG, "Deleting rsvp from notice...");
+            common_debug("Deleting rsvp from notice...");
             $rsvp = RSVP::fromNotice($notice);
-            common_log(LOG_DEBUG, "to delete: $rsvp->id");
+            common_debug("to delete: $rsvp->id");
             $rsvp->delete();
             break;
         default:
-            common_log(LOG_DEBUG, "Not deleting related, wtf...");
+            common_debug("Not deleting related, wtf...");
         }
     }
 
-    function onEndShowScripts($action)
+    function onEndShowScripts(Action $action)
     {
         $action->script($this->path('js/event.js'));
     }
 
-    function onEndShowStyles($action)
+    function onEndShowStyles(Action $action)
     {
         $action->cssLink($this->path('css/event.css'));
         return true;
index 662a1de0b36694a3ab9ff8816779e16af326c641..f7e922dffb6bccaba36d91304ec221e0cccc1e53 100644 (file)
@@ -137,10 +137,10 @@ class CancelrsvpAction extends Action
             $notice = $this->rsvp->getNotice();
             // NB: this will delete the rsvp, too
             if (!empty($notice)) {
-                common_log(LOG_DEBUG, "Deleting notice...");
-                $notice->deleteAs($this->scoped);
+                common_debug("Deleting notice...");
+                $notice->delete();
             } else {
-                common_log(LOG_DEBUG, "Deleting RSVP alone...");
+                common_debug("Deleting RSVP alone...");
                 $this->rsvp->delete();
             }
         } catch (ClientException $ce) {
@@ -190,7 +190,7 @@ class CancelrsvpAction extends Action
      *
      * @return boolean is read only action?
      */
-    function isReadOnly($args)
+    function isReadOnly(array $args=array())
     {
         if ($_SERVER['REQUEST_METHOD'] == 'GET' ||
             $_SERVER['REQUEST_METHOD'] == 'HEAD') {
index 57cd1bb37e1558aaa3fd55a261aa592b69582224..6d0165983dd851f93bec3c9ac4816c433c738a01 100644 (file)
@@ -300,7 +300,7 @@ class NeweventAction extends Action
      *
      * @return boolean is read only action?
      */
-    function isReadOnly($args)
+    function isReadOnly(array $args=array())
     {
         if ($_SERVER['REQUEST_METHOD'] == 'GET' ||
             $_SERVER['REQUEST_METHOD'] == 'HEAD') {
index adc97514486cd47dc8997d62bf0319847690185b..ea32b2b368e179a9c3f6121367f931d4a122dc1d 100644 (file)
@@ -197,7 +197,7 @@ class NewrsvpAction extends Action
      *
      * @return boolean is read only action?
      */
-    function isReadOnly($args)
+    function isReadOnly(array $args=array())
     {
         if ($_SERVER['REQUEST_METHOD'] == 'GET' ||
             $_SERVER['REQUEST_METHOD'] == 'HEAD') {
index 092fa6bda5922793551846452bc452a56a10e45c..580cfab74eb8f2468dd91b9379ef1430c22e7edf 100644 (file)
@@ -42,7 +42,7 @@ class TimelistAction extends Action {
      *
      * @return boolean true
      */
-    function prepare($args) {
+    function prepare(array $args=array()) {
         parent::prepare($args);
         $this->start = $this->arg('start');
         $this->duration = $this->boolean('duration', false);
@@ -56,7 +56,7 @@ class TimelistAction extends Action {
      *
      * @return void
      */
-    function handle($args)
+    function handle(array $args=array())
     {
         parent::handle($args);
 
index 9ef288eca4667c29b6134bc53fd77ad9c02d78a4..fd8c3c8a2aaf6ff841b6461ce48b4295bd30d924 100644 (file)
@@ -100,7 +100,7 @@ class Happening extends Managed_DataObject
         );
     }
 
-    static function saveNew($profile, $start_time, $end_time, $title, $location, $description, $url, $options=array())
+    static function saveNew(Profile $profile, $start_time, $end_time, $title, $location, $description, $url, array $options=array())
     {
         if (array_key_exists('uri', $options)) {
             $other = Happening::getKV('uri', $options['uri']);
@@ -210,7 +210,7 @@ class Happening extends Managed_DataObject
         return Notice::getKV('uri', $this->getUri());
     }
 
-    static function fromNotice($notice)
+    static function fromNotice(Notice $notice)
     {
         return Happening::getKV('uri', $notice->getUri());
     }
index 520347eeb629a731105e4f5cb9df745ec2931ccd..c4ffc3ee340bb74ba09be17eac457161f10167e7 100644 (file)
@@ -124,7 +124,7 @@ class RSVP extends Managed_DataObject
         print "Resuming core schema upgrade...";
     }
 
-    function saveNew($profile, $event, $verb, $options=array())
+    function saveNew(Profile $profile, $event, $verb, array $options = array())
     {
         if (array_key_exists('uri', $options)) {
             $other = RSVP::getKV('uri', $options['uri']);
@@ -330,7 +330,7 @@ class RSVP extends Managed_DataObject
                               $this->response);
     }
 
-    static function toHTML($profile, $event, $response)
+    static function toHTML(Profile $profile, Event $event, $response)
     {
         $fmt = null;
 
index ea928b995e054ace9f17e02bcdaf27896d3507c6..12541437020c7ced92cd3b73852d294d9d94a630 100644 (file)
@@ -81,7 +81,8 @@ class ExtendedProfilePlugin extends Plugin
 
     function onEndShowAccountProfileBlock(HTMLOutputter $out, Profile $profile) {
         $user = User::getKV('id', $profile->id);
-        if ($user) {
+
+        if ($user instanceof User) {
             $url = common_local_url('profiledetail', array('nickname' => $user->nickname));
             // TRANS: Link text on user profile page leading to extended profile page.
             $out->element('a', array('href' => $url, 'class' => 'profiledetail'), _m('More details...'));
index d4857429e0488df77507b116e92b834c6ffec3a2..a77c1ec49242c5cd6565cdb9f917cb0e6cf4a0e0 100644 (file)
@@ -43,7 +43,7 @@ class UserautocompleteAction extends Action
      *
      * @return boolean true if nothing goes wrong
      */
-    function prepare($args)
+    function prepare(array $args=array())
     {
         parent::prepare($args);
         $this->query = $this->trimmed('term');
@@ -57,7 +57,7 @@ class UserautocompleteAction extends Action
      *
      * @return void
      */
-    function handle($args)
+    function handle(array $args=array())
     {
         parent::handle($args);
         $this->showResults();
@@ -106,7 +106,7 @@ class UserautocompleteAction extends Action
      *
      * @return boolean true
      */
-    function isReadOnly($args)
+    function isReadOnly(array $args=array())
     {
         return true;
     }
index a19cc0349bf7b2a7f18bee6b8bba243f3fa4928a..e323a475e1576c021b8bba9dccd2051ca33110d3 100644 (file)
@@ -229,7 +229,7 @@ class FacebookBridgePlugin extends Plugin
      *
      * @return boolean hook value
      */
-    function onEndAdminPanelNav($nav)
+    function onEndAdminPanelNav(Menu $nav)
     {
         if (AdminPanelAction::canAdmin('facebook')) {
 
@@ -329,7 +329,7 @@ class FacebookBridgePlugin extends Plugin
      * @param Action $action the current action
      *
      */
-    function onEndShowScripts($action)
+    function onEndShowScripts(Action $action)
     {
         if ($this->needsScripts($action)) {
 
@@ -449,7 +449,7 @@ ENDOFSCRIPT;
      *
      * @return boolean hook return
      */
-    function onStartEnqueueNotice($notice, &$transports)
+    function onStartEnqueueNotice(Notice $notice, array &$transports)
     {
         if (self::hasApplication() && $notice->isLocal() && $notice->inScope(null)) {
             array_push($transports, 'facebook');
@@ -464,7 +464,7 @@ ENDOFSCRIPT;
      *
      * @return boolean hook return
      */
-    function onEndInitializeQueueManager($manager)
+    function onEndInitializeQueueManager(QueueManager $manager)
     {
         if (self::hasApplication()) {
             $manager->connect('facebook', 'FacebookQueueHandler');
index 443b768f5c83215db241e3ed132c7000abfa26cd..e714f4878965d93e1819ce62d826fd225c6106d1 100644 (file)
@@ -48,7 +48,7 @@ class FacebookdeauthorizeAction extends Action
      *
      * @return boolean true
      */
-    function prepare($args)
+    function prepare(array $args=array())
     {
         $this->facebook = Facebookclient::getFacebook();
 
@@ -60,7 +60,7 @@ class FacebookdeauthorizeAction extends Action
      *
      * @param array $args is ignored since it's now passed in in prepare()
      */
-    function handle($args)
+    function handle(array $args=array())
     {
         parent::handle($args);
 
index 7cf493a994101cb6ca5214fab58545c986fdcac6..4a9e09b53dfe1c27fe1f9a0ce2b7987c8d0e8a98 100644 (file)
@@ -37,7 +37,7 @@ class FacebookfinishloginAction extends Action
     private $fbuser      = null; // Facebook user object (JSON)
     private $accessToken = null; // Access token provided by Facebook JS API
 
-    function prepare($args) {
+    function prepare(array $args=array()) {
         parent::prepare($args);
 
         // Check cookie for a valid access_token
@@ -79,7 +79,7 @@ class FacebookfinishloginAction extends Action
         return true;
     }
 
-    function handle($args)
+    function handle(array $args=array())
     {
         parent::handle($args);
 
index f30822b63f536dfd78fbb89304d8c4495774033f..558dd1bfb720b19db388c15eac4e48a26e1ff675 100644 (file)
@@ -34,7 +34,7 @@ if (!defined('STATUSNET')) {
 
 class FacebookloginAction extends Action
 {
-    function handle($args)
+    function handle(array $args=array())
     {
         parent::handle($args);
 
index 7e63b199e2285a9fd77327816a40a2a7dbe0c51d..7ff8f391b2466309df4d109866c1e16df438cf49 100644 (file)
@@ -52,14 +52,19 @@ class ApiFavoriteCreateAction extends ApiAuthAction
 
     protected $needPost = true;
 
+    /**
+     * Take arguments for running
+     *
+     * @return boolean success flag
+     */
     protected function prepare(array $args=array())
     {
         parent::prepare($args);
 
         $this->notice = Notice::getKV($this->arg('id'));
         if (!empty($this->notice->repeat_of)) {
-                common_log(LOG_DEBUG, 'Trying to Fave '.$this->notice->id.', repeat of '.$this->notice->repeat_of);
-                common_log(LOG_DEBUG, 'Will Fave '.$this->notice->repeat_of.' instead');
+                common_debug('Trying to Fave '.$this->notice->id.', repeat of '.$this->notice->repeat_of);
+                common_debug('Will Fave '.$this->notice->repeat_of.' instead');
                 $real_notice_id = $this->notice->repeat_of;
                 $this->notice = Notice::getKV($real_notice_id);
         }
@@ -67,6 +72,13 @@ class ApiFavoriteCreateAction extends ApiAuthAction
         return true;
     }
 
+    /**
+     * Handle the request
+     *
+     * Check the format and show the user info
+     *
+     * @return void
+     */
     protected function handle()
     {
         parent::handle();
index 1c63ad26285c5da0b52214cf087f831c3baba8d9..03472ce6ba12f14ab33e6601b6410f559adc5daf 100644 (file)
@@ -57,15 +57,15 @@ class ApiFavoriteDestroyAction extends ApiAuthAction
      *
      * @return boolean success flag
      */
-    function prepare($args)
+    function prepare(array $args=array())
     {
         parent::prepare($args);
 
         $this->user   = $this->auth_user;
         $this->notice = Notice::getKV($this->arg('id'));
         if ($this->notice->repeat_of != '' ) {
-                common_log(LOG_DEBUG, 'Trying to unFave '.$this->notice->id);
-                common_log(LOG_DEBUG, 'Will unFave '.$this->notice->repeat_of.' instead');
+                common_debug('Trying to unFave '.$this->notice->id);
+                common_debug('Will unFave '.$this->notice->repeat_of.' instead');
                 $real_notice_id = $this->notice->repeat_of;
                 $this->notice = Notice::getKV($real_notice_id);
         }
@@ -82,7 +82,7 @@ class ApiFavoriteDestroyAction extends ApiAuthAction
      *
      * @return void
      */
-    function handle($args)
+    function handle(array $args=array())
     {
         parent::handle($args);
 
index 01a5d3014e1637ee51e4475cf6832b38e6bf1ba6..baba0c8db8cb9a7964ce9cc9f469c85360c1a59d 100644 (file)
@@ -105,12 +105,12 @@ class ApiStatusesFavsAction extends ApiAuthAction
                        $profile = Profile::getKV('id', $id);
                        $ids_with_profile_data[$i]['user_id'] = $id;
                        $ids_with_profile_data[$i]['nickname'] = $profile->nickname;
-                       $ids_with_profile_data[$i]['fullname'] = $profile->fullname;                    
-                       $ids_with_profile_data[$i]['profileurl'] = $profile->profileurl;                                                
+                       $ids_with_profile_data[$i]['fullname'] = $profile->fullname;
+                       $ids_with_profile_data[$i]['profileurl'] = $profile->profileurl;
                        $profile = new Profile();
                        $profile->id = $id;
                        $avatarurl = $profile->avatarUrl(24);
-                       $ids_with_profile_data[$i]['avatarurl'] = $avatarurl;                                                           
+                       $ids_with_profile_data[$i]['avatarurl'] = $avatarurl;
                        $i++;
                }
                
@@ -129,7 +129,7 @@ class ApiStatusesFavsAction extends ApiAuthAction
      * @return boolean is read only action?
      */
 
-    function isReadOnly($args)
+    function isReadOnly(array $args=array())
     {
         return true;
     }
index 366177078fd6b5ed98c6df1087010239a484340a..e3f6fd13b8e28759c3b60c29c5e17d5a8c1aff73 100644 (file)
@@ -203,7 +203,7 @@ class ApiTimelineFavoritesAction extends ApiBareAuthAction
      *
      * @return boolean true
      */
-    function isReadOnly($args)
+    function isReadOnly(array $args=array())
     {
         return true;
     }
index b8dae707b38fd900695c6a54026c945e7d0d01bd..cd8e8daddf781aafa7df3b1c6d683d134af23294 100644 (file)
@@ -233,7 +233,7 @@ class AtompubfavoritefeedAction extends ApiAuthAction
      *
      * @return boolean is read only action?
      */
-    function isReadOnly($args)
+    function isReadOnly(array $args=array())
     {
         if ($_SERVER['REQUEST_METHOD'] == 'GET' ||
             $_SERVER['REQUEST_METHOD'] == 'HEAD') {
index 2b8c9704aaa02adc23067aed0d3ecdc8fb89047f..bbdddc07d934e8aed4814d2d2c06ae76e731689b 100644 (file)
@@ -161,7 +161,7 @@ class AtompubshowfavoriteAction extends ApiAuthAction
      *
      * @return boolean is read only action?
      */
-    function isReadOnly($args)
+    function isReadOnly(array $args=array())
     {
         if ($_SERVER['REQUEST_METHOD'] == 'GET' ||
             $_SERVER['REQUEST_METHOD'] == 'HEAD') {
index 849a1c8b07a5662799b33b84f2c7fa1ed25d6d14..6914bd61f5eb32dd3b0e0e48796ba909e36ccc4d 100644 (file)
@@ -81,7 +81,7 @@ class FavoritedAction extends Action
      *
      * @return boolean true
      */
-    function isReadOnly($args)
+    function isReadOnly(array $args=array())
     {
         return true;
     }
@@ -95,7 +95,7 @@ class FavoritedAction extends Action
      *
      * @todo move queries from showContent() to here
      */
-    function prepare($args)
+    function prepare(array $args=array())
     {
         parent::prepare($args);
         $this->page = ($this->arg('page')) ? ($this->arg('page')+0) : 1;
@@ -114,7 +114,7 @@ class FavoritedAction extends Action
      *
      * @return void
      */
-    function handle($args)
+    function handle(array $args=array())
     {
         parent::handle($args);
 
index cba29063c28b2de8787890db5c0920ac98ac5c8b..ddb23cfe3f30034c141aead687189816b1a56972 100644 (file)
@@ -149,7 +149,7 @@ class ShowfavoritesAction extends ShowstreamAction
 
 class FavoritesNoticeList extends NoticeList
 {
-    function newListItem($notice)
+    function newListItem(Notice $notice)
     {
         return new FavoritesNoticeListItem($notice, $this->out);
     }
index ad7cc67df86ebccd10b9ac7c3a1a37430368cd77..eca4412b23068c0d5a114203269d77bd29c26bce 100644 (file)
@@ -250,7 +250,7 @@ class Fave extends Managed_DataObject
      *
      * @return array Array of Fave objects
      */
-    static public function byNotice($notice)
+    static public function byNotice(Notice $notice)
     {
         if (!isset(self::$_faves[$notice->id])) {
             self::fillFaves(array($notice->id));
index 44a6e3fe346ebc895e1fa469ba20d7a11058bd7c..78fe21d26d58b684866a12ad9bf2cafb28c62bc4 100644 (file)
@@ -44,7 +44,7 @@ class GNUsocialPhotoPlugin extends MicroAppPlugin
         return true;
     }
 
-    function onRouterInitialized($m)
+    function onRouterInitialized(URLMapper $m)
     {
         $m->connect('main/photo/new', array('action' => 'newphoto'));
         $m->connect('main/photo/:id', array('action' => 'showphoto'));
index 18ae5523a05aee25e8aa241eb1b2c9ca3cce5645..77c05e3807a3cda19445da805518350ccb2c9768 100644 (file)
@@ -33,7 +33,7 @@ class NewphotoAction extends Action
 {
     var $user = null;
 
-    function prepare($args)
+    function prepare(array $args=array())
     {
         parent::prepare($args);
         $this->user = common_current_user();
@@ -50,7 +50,7 @@ class NewphotoAction extends Action
         return true;
     }
 
-    function handle($args)
+    function handle(array $args=array())
     {
         parent::handle($args);
 
index 4e4ee69c9739c303a9fc946448304cfbe6fdf077..c10b64524d24dfe0a34c4785cbd37d04461880c1 100644 (file)
@@ -46,7 +46,7 @@ class Photo extends Managed_DataObject
     public $description;       // text
     public $profile_id;        // int
 
-    public static function getByNotice($notice)
+    public static function getByNotice(Notice $notice)
     {
         return self::getKV('uri', $notice->uri);
     }
@@ -81,7 +81,7 @@ class Photo extends Managed_DataObject
         );
     }
 
-    static function saveNew(Profile $profile, $photo_uri, $thumb_uri, $title, $description, $options=array())
+    static function saveNew(Profile $profile, $photo_uri, $thumb_uri, $title, $description, array $options=array())
     {
         $photo = new Photo();
 
index 36956e5b9b3b750a90f15c4aacb691b3826c4526..906509fef5d52573b1b07c53810bc7465ef0efde 100644 (file)
@@ -44,7 +44,7 @@ class GNUsocialPhotosPlugin extends Plugin
         $schema->ensureTable('GNUsocialPhotoAlbum', GNUsocialPhotoAlbum::schemaDef());
     }
 
-    function onRouterInitialized($m)
+    function onRouterInitialized(URLMapper $m)
     {
         $m->connect(':nickname/photos', array('action' => 'photos'));
         $m->connect(':nickname/photos/:albumid', array('action' => 'photos'));
@@ -157,12 +157,12 @@ class GNUsocialPhotosPlugin extends Plugin
                            _('Photo gallery'), $nav->action->trimmed('action') == 'photos', 'nav_photos');
     }
 
-    function onEndShowStyles($action)
+    function onEndShowStyles(Action $action)
     {
         $action->cssLink('/plugins/GNUsocialPhotos/res/style.css');
     }
 
-    function onEndShowScripts($action)
+    function onEndShowScripts(Action $action)
     {
         $action->script('plugins/GNUsocialPhotos/res/gnusocialphotos.js');
     }
index 35dac7bf3f6298d921d62f100ffdd8b7d6059e5b..8aa63a06d7b0f34924d1a621f3d33715708996a6 100644 (file)
@@ -36,7 +36,7 @@ class EditphotoAction extends Action
 {
     var $user = null;
 
-    function prepare($args)
+    function prepare(array $args=array())
     {
         parent::prepare($args);
         $args = $this->returnToArgs();
@@ -46,7 +46,7 @@ class EditphotoAction extends Action
         return true;
     }
 
-    function handle($args)
+    function handle(array $args=array())
     {
         parent::handle($args);
         if($_SERVER['REQUEST_METHOD'] == 'POST') {
index b1e1b73ff1198cb97b681477fab25b09e5994420..a180be8c12098295c3724287184dc8d5c218681a 100644 (file)
@@ -38,7 +38,7 @@ class PhotosAction extends Action
 {
     var $user = null;
 
-    function prepare($args)
+    function prepare(array $args=array())
     {
         parent::prepare($args);
 
@@ -53,7 +53,7 @@ class PhotosAction extends Action
         return true;
     }
 
-    function handle($args)
+    function handle(array $args=array())
     {
         parent::handle($args);
         $this->showPage();
@@ -82,7 +82,7 @@ class PhotosAction extends Action
         $this->element('option', array('value' => '120'), _("Medium"));
         $this->element('option', array('value' => '400'), _("Normal"));
         $this->elementEnd('select');
-    }        
+    }
 
     function showAlbums()
     {
index 25bd4f84d0e585ed0282968066698c7fc99fda35..a8874ea13b17a3da215e41c652d5ee005549ec46 100644 (file)
@@ -36,14 +36,14 @@ class PhotouploadAction extends Action
 {
     var $user = null;
 
-    function prepare($args)
+    function prepare(array $args=array())
     {
         parent::prepare($args);
         $this->user = common_current_user();
         return true;
     }
 
-    function handle($args)
+    function handle(array $args=array())
     {
         parent::handle($args);
         if($_SERVER['REQUEST_METHOD'] == 'POST') {
index c4628c4ecc844041e931b71b3719782f67c1ff74..6bf6a159848cc7d14a2c1472770ddd8ea754342e 100644 (file)
@@ -40,10 +40,9 @@ class GNUsocialProfileExtensionsPlugin extends Plugin
         $schema = Schema::get();
         $schema->ensureTable('GNUsocialProfileExtensionField', GNUsocialProfileExtensionField::schemaDef());
         $schema->ensureTable('GNUsocialProfileExtensionResponse', GNUsocialProfileExtensionResponse::schemaDef());
-                                          
     }
 
-    function onRouterInitialized($m)
+    function onRouterInitialized(URLMapper $m)
     {
         $m->connect(':nickname/bio', array('action' => 'bio'));
         $m->connect('admin/profilefields', array('action' => 'profilefieldsAdminPanel'));
@@ -103,17 +102,17 @@ class GNUsocialProfileExtensionsPlugin extends Plugin
         }
     }
     
-    function onEndShowStyles($action)
+    function onEndShowStyles(Action $action)
     {
         $action->cssLink('/plugins/GNUsocialProfileExtensions/res/style.css');
     }
 
-    function onEndShowScripts($action)
+    function onEndShowScripts(Action $action)
     {
         $action->script('plugins/GNUsocialProfileExtensions/js/profile.js');
     }
 
-    function onEndAdminPanelNav($nav)
+    function onEndAdminPanelNav(Menu $nav)
     {
         if (AdminPanelAction::canAdmin('profilefields')) {
 
index 269389e07dff451c2de832f3564745fe4c15f279..fc49003cb46ef8e6de867c747206046dc4d8eba9 100644 (file)
@@ -38,7 +38,7 @@ class BioAction extends Action
 {
     var $user = null;
 
-    function prepare($args)
+    function prepare(array $args=array())
     {
         parent::prepare($args);
 
@@ -51,7 +51,7 @@ class BioAction extends Action
 
     }
 
-    function handle($args)
+    function handle(array $args=array())
     {
         parent::handle($args);
         $this->showPage();
index 95df52838846d218ce296052f35bab5444b552a8..380672ebb535d688dafeaf7f1a216d68a61c00f1 100644 (file)
@@ -103,7 +103,7 @@ class NoticeTree extends NoticeList
         $this->out->elementEnd('li');
     }
 
-    function newListItem($notice)
+    function newListItem(Notice $notice)
     {
         return new NoticeTreeItem($notice, $this->out);
     }
index 3310712ba76da6b470a6ea6383fd3eb7212044d2..abf0f304301df01b419b226af352e04e561377d9 100644 (file)
@@ -44,7 +44,7 @@ class GNUsocialVideoPlugin extends MicroAppPlugin
         return true;
     }
 
-    function onRouterInitialized($m)
+    function onRouterInitialized(URLMapper $m)
     {
         $m->connect('main/postvideo', array('action' => 'postvideo'));
         $m->connect('showvideo/:id', array('action' => 'showvideo'));
index bdd86abc9e15b33b050c81c43a0ccd3fbde0ffbc..aae0fe98e649a4e3b5cc4280929a8b049c805851 100644 (file)
@@ -34,7 +34,7 @@ class PostvideoAction extends Action {
     var $user = null;
     var $url = null;
 
-    function prepare($args)
+    function prepare(array $args=array())
     {
         parent::prepare($args);
         $this->user = common_current_user();
@@ -54,7 +54,7 @@ class PostvideoAction extends Action {
         return true;
     }
    
-    function handle($args)
+    function handle(array $args=array())
     {
         parent::handle($args);
 
index 628d08642af2147cb064ec2c78bdd5e9bf3ebaaa..5021c19c9953fc723ce0b561b23b200581e85580 100644 (file)
@@ -34,7 +34,7 @@ class ShowvideoAction extends ShownoticeAction
     protected $id = null;
     protected $vid = null;
 
-    function prepare($args)
+    function prepare(array $args=array())
     {
         OwnerDesignAction::prepare($args);
         $this->id = $this->trimmed('id');
index 09c1f6b8443a0ee17ef11d8d8489228aebfc4156..9ba395d8cad839157f6f6a3ee75a0528280cda1b 100644 (file)
@@ -43,7 +43,7 @@ class Video extends Managed_DataObject
     public $url;               // varchar (191)   not 255 because utf8mb4 takes more space
     public $profile_id;        // int
 
-    public static function getByNotice($notice)
+    public static function getByNotice(Notice $notice)
     {
         return self::getKV('uri', $notice->uri);
     }
@@ -75,7 +75,7 @@ class Video extends Managed_DataObject
         );
     }
 
-    static function saveNew(Profile $profile, $url, $options=array())
+    static function saveNew(Profile $profile, $url, array $options=array())
     {
         $vid = new Video();
 
index 1dc0f0f07a402ca6955a808bdd3c4a5d55d11fc1..2f07747a4d9d065369705e0c59919306bad259e4 100644 (file)
@@ -64,7 +64,7 @@ class GoogleAnalyticsPlugin extends Plugin
         parent::__construct();
     }
 
-    function onEndShowScripts($action)
+    function onEndShowScripts(Action $action)
     {
         $code = common_config('googleanalytics', 'code');
         if (empty($code)) {
index 61828239cac793a19549de9e390f4927e3dc2ec9..0f5c1a88309a35d1f0f02bf8e6b9b5956750ea4b 100644 (file)
@@ -124,7 +124,7 @@ class GroupPrivateMessagePlugin extends Plugin
      *
      * @result boolean hook value
      */
-    function onEndGroupSave($group)
+    function onEndGroupSave(User_group $group)
     {
         $gps = new Group_privacy_settings();
 
@@ -193,9 +193,10 @@ class GroupPrivateMessagePlugin extends Plugin
         assert(is_callable(array($action, 'getGroup')));
 
         $gps = null;
+        $group = $action->getGroup();
 
-        if ($action->getGroup() instanceof User_group) {
-            $gps = Group_privacy_settings::getKV('group_id', $action->getGroup()->id);
+        if ($group instanceof User_group) {
+            $gps = Group_privacy_settings::getKV('group_id', $group->id);
         }
 
         $orig = null;
@@ -324,7 +325,7 @@ class GroupPrivateMessagePlugin extends Plugin
             foreach (array_unique($match[1]) as $nickname) {
                 $group = User_group::getForNickname($nickname, $profile);
 
-                if (empty($group)) {
+                if (!$group instanceof User_group) {
                     continue;
                 }
 
index f4656bfd8e4588fdf460a628750b0d5d7bedb37e..09bcbda3235f7518ad3dad4a6fe149bd0ad39cf2 100644 (file)
@@ -155,7 +155,7 @@ class GroupinboxAction extends GroupAction
      *
      * @return boolean is read only action?
      */
-    function isReadOnly($args)
+    function isReadOnly(array $args=array())
     {
         return true;
     }
index 4c2e7a71f6331e8752b18d584a5946527a6edb77..0c4d1342a9aa463db3703898b6dcd439bd6eda2a 100644 (file)
@@ -146,7 +146,7 @@ class ShowgroupmessageAction extends Action
      *
      * @return boolean is read only action?
      */
-    function isReadOnly($args)
+    function isReadOnly(array $args=array())
     {
         return true;
     }
diff --git a/plugins/Irc/IrcPlugin.php b/plugins/Irc/IrcPlugin.php
new file mode 100644 (file)
index 0000000..99dc4b2
--- /dev/null
@@ -0,0 +1,385 @@
+<?php
+/**
+ * StatusNet - the distributed open-source microblogging tool
+ * Copyright (C) 2010, StatusNet, Inc.
+ *
+ * Send and receive notices using an IRC network
+ *
+ * PHP version 5
+ *
+ * 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  IM
+ * @package   StatusNet
+ * @author    Luke Fitzgerald <lw.fitzgerald@googlemail.com>
+ * @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);
+}
+
+// We bundle the Phergie library...
+set_include_path(get_include_path() . PATH_SEPARATOR . dirname(__FILE__) . '/extlib/phergie');
+
+/**
+ * Plugin for IRC
+ *
+ * @category  Plugin
+ * @package   StatusNet
+ * @author    Luke Fitzgerald <lw.fitzgerald@googlemail.com>
+ * @copyright 2010 StatusNet, Inc.
+ * @license   http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0
+ * @link      http://status.net/
+ */
+class IrcPlugin extends ImPlugin {
+    public $host =  null;
+    public $port = null;
+    public $username = null;
+    public $realname = null;
+    public $nick = null;
+    public $password = null;
+    public $nickservidentifyregexp = null;
+    public $nickservpassword = null;
+    public $channels = null;
+    public $transporttype = null;
+    public $encoding = null;
+    public $pinginterval = null;
+
+    public $regcheck = null;
+    public $unregregexp = null;
+    public $regregexp = null;
+
+    public $transport = 'irc';
+    protected $whiteList;
+    protected $fake_irc;
+
+    /**
+     * Get the internationalized/translated display name of this IM service
+     *
+     * @return string Name of service
+     */
+    public function getDisplayName() {
+        // TRANS: Service name for IRC.
+        return _m('IRC');
+    }
+
+    /**
+     * Normalize a screenname for comparison
+     *
+     * @param string $screenname Screenname to normalize
+     * @return string An equivalent screenname in normalized form
+     */
+    public function normalize($screenname) {
+        $screenname = str_replace(" ","", $screenname);
+        return strtolower($screenname);
+    }
+
+    /**
+     * Get the screenname of the daemon that sends and receives messages
+     *
+     * @return string Screenname
+     */
+    public function daemonScreenname() {
+        return $this->nick;
+    }
+
+    /**
+     * Validate (ensure the validity of) a screenname
+     *
+     * @param string $screenname Screenname to validate
+     * @return boolean true if screenname is valid
+     */
+    public function validate($screenname) {
+        if (preg_match('/\A[a-z0-9\-_]{1,1000}\z/i', $screenname)) {
+            return true;
+        } else {
+            return false;
+        }
+    }
+
+    /**
+     * Load related modules when needed
+     *
+     * @param string $cls Name of the class to be loaded
+     * @return boolean hook value; true means continue processing, false means stop.
+     */
+    public function onAutoload($cls) {
+        // in the beginning of this file, we have added an include path
+        if (substr($cls, 0, 7) == 'Phergie') {
+            include_once str_replace('_', DIRECTORY_SEPARATOR, $cls) . '.php';
+            return false;
+        }
+
+        return parent::onAutoload($cls);
+    }
+
+    /*
+     * Start manager on daemon start
+     *
+     * @param array &$versions Array to insert manager into
+     * @return boolean
+     */
+    public function onStartImDaemonIoManagers(&$classes) {
+        parent::onStartImDaemonIoManagers($classes);
+        $classes[] = new IrcManager($this); // handles sending/receiving
+        return true;
+    }
+
+    /**
+    * Ensure the database table is present
+    *
+    */
+    public function onCheckSchema() {
+        $schema = Schema::get();
+
+        // For storing messages while sessions become ready
+        $schema->ensureTable('irc_waiting_message', Irc_waiting_message::schemaDef());
+        return true;
+    }
+
+    /**
+    * Get a microid URI for the given screenname
+    *
+    * @param string $screenname Screenname
+    * @return string microid URI
+    */
+    public function microiduri($screenname) {
+        return 'irc:' . $screenname;
+    }
+
+    /**
+     * Send a message to a given screenname
+     *
+     * @param string $screenname Screenname to send to
+     * @param string $body Text to send
+     * @return boolean true on success
+     */
+    public function sendMessage($screenname, $body) {
+        $lines = explode("\n", $body);
+        foreach ($lines as $line) {
+            $this->fake_irc->doPrivmsg($screenname, $line);
+            $this->enqueueOutgoingRaw(array('type' => 'message', 'prioritise' => 0, 'data' => $this->fake_irc->would_be_sent));
+        }
+        return true;
+    }
+
+    /**
+     * Accept a queued input message.
+     *
+     * @return boolean true if processing completed, false if message should be reprocessed
+     */
+    public function receiveRawMessage($data) {
+        if (strpos($data['source'], '#') === 0) {
+            $message = $data['message'];
+            $parts = explode(' ', $message, 2);
+            $command = $parts[0];
+            if (in_array($command, $this->whiteList)) {
+                $this->handle_channel_incoming($data['sender'], $data['source'], $message);
+            } else {
+                $this->handleIncoming($data['sender'], $message);
+            }
+        } else {
+            $this->handleIncoming($data['sender'], $data['message']);
+        }
+        return true;
+    }
+
+    /**
+     * Helper for handling incoming messages from a channel requiring response
+     * to the channel instead of via PM
+     *
+     * @param string $nick Screenname the message was sent from
+     * @param string $channel Channel the message originated from
+     * @param string $message Message text
+     * @param boolean true on success
+     */
+    protected function handle_channel_incoming($nick, $channel, $notice_text) {
+        $user = $this->getUser($nick);
+        // For common_current_user to work
+        global $_cur;
+        $_cur = $user;
+
+        if (!$user) {
+            $this->sendFromSite($nick, 'Unknown user; go to ' .
+                             common_local_url('imsettings') .
+                             ' to add your address to your account');
+            common_log(LOG_WARNING, 'Message from unknown user ' . $nick);
+            return;
+        }
+        if ($this->handle_channel_command($user, $channel, $notice_text)) {
+            common_log(LOG_INFO, "Command message by $nick handled.");
+            return;
+        } else if ($this->isAutoreply($notice_text)) {
+            common_log(LOG_INFO, 'Ignoring auto reply from ' . $nick);
+            return;
+        } else if ($this->isOtr($notice_text)) {
+            common_log(LOG_INFO, 'Ignoring OTR from ' . $nick);
+            return;
+        } else {
+            common_log(LOG_INFO, 'Posting a notice from ' . $user->nickname);
+            $this->addNotice($nick, $user, $notice_text);
+        }
+
+        $user->free();
+        unset($user);
+        unset($_cur);
+        unset($message);
+    }
+
+    /**
+     * Attempt to handle a message from a channel as a command
+     *
+     * @param User $user User the message is from
+     * @param string $channel Channel the message originated from
+     * @param string $body Message text
+     * @return boolean true if the message was a command and was executed, false if it was not a command
+     */
+    protected function handle_channel_command($user, $channel, $body) {
+        $inter = new CommandInterpreter();
+        $cmd = $inter->handle_command($user, $body);
+        if ($cmd) {
+            $chan = new ChannelResponseChannel($this, $channel);
+            $cmd->execute($chan);
+            return true;
+        } else {
+            return false;
+        }
+    }
+
+    /**
+     * Send a confirmation code to a user
+     *
+     * @param string $screenname screenname sending to
+     * @param string $code the confirmation code
+     * @param User $user user sending to
+     * @return boolean success value
+     */
+    public function sendConfirmationCode($screenname, $code, $user, $checked = false) {
+        // TRANS: Body text for e-mail confirmation message for IRC.
+        // TRANS: %1$s is a user nickname, %2$s is the StatusNet sitename,
+        // TRANS: %3$s is the plugin display name ("IRC"), %4$s is the confirm address URL.
+        $body = sprintf(_m('User "%1$s" on %2$s has said that your %3$s screenname belongs to them. ' .
+          'If that\'s true, you can confirm by clicking on this URL: ' .
+          '%4$s' .
+          ' . (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', array('code' => $code)));
+
+        if ($this->regcheck && !$checked) {
+            return $this->checked_sendConfirmationCode($screenname, $code, $user);
+        } else {
+            return $this->sendMessage($screenname, $body);
+        }
+    }
+
+    /**
+    * Only sends the confirmation message if the nick is
+    * registered
+    *
+    * @param string $screenname Screenname sending to
+    * @param string $code The confirmation code
+    * @param User $user User sending to
+    * @return boolean true on succes
+    */
+    public function checked_sendConfirmationCode($screenname, $code, $user) {
+        $this->fake_irc->doPrivmsg('NickServ', 'INFO '.$screenname);
+        $this->enqueueOutgoingRaw(
+            array(
+                'type' => 'nickcheck',
+                'prioritise' => 1,
+                'data' => $this->fake_irc->would_be_sent,
+                'nickdata' =>
+                    array(
+                        'screenname' => $screenname,
+                        'code' => $code,
+                        'user' => $user
+                    )
+            )
+        );
+        return true;
+    }
+
+    /**
+    * Initialize plugin
+    *
+    * @return boolean
+    */
+    public function initialize() {
+        if (!isset($this->host)) {
+            // TRANS: Exception thrown when initialising the IRC plugin fails because of an incorrect configuration.
+            throw new Exception(_m('You must specify a host.'));
+        }
+        if (!isset($this->username)) {
+            // TRANS: Exception thrown when initialising the IRC plugin fails because of an incorrect configuration.
+            throw new Exception(_m('You must specify a username.'));
+        }
+        if (!isset($this->realname)) {
+            // TRANS: Exception thrown when initialising the IRC plugin fails because of an incorrect configuration.
+            throw new Exception(_m('You must specify a "real name".'));
+        }
+        if (!isset($this->nick)) {
+            // TRANS: Exception thrown when initialising the IRC plugin fails because of an incorrect configuration.
+            throw new Exception(_m('You must specify a nickname.'));
+        }
+
+        if (!isset($this->port)) {
+            $this->port = 6667;
+        }
+        if (!isset($this->transporttype)) {
+            $this->transporttype = 'tcp';
+        }
+        if (!isset($this->encoding)) {
+            $this->encoding = 'UTF-8';
+        }
+        if (!isset($this->pinginterval)) {
+            $this->pinginterval = 120;
+        }
+
+        if (!isset($this->regcheck)) {
+            $this->regcheck = true;
+        }
+
+        $this->fake_irc = new FakeIrc;
+
+        /*
+         * Commands allowed to return output to a channel
+         */
+        $this->whiteList = array('stats', 'last', 'get');
+
+        return true;
+    }
+
+    /**
+     * Get plugin information
+     *
+     * @param array $versions Array to insert information into
+     * @return void
+     */
+    public function onPluginVersion(array &$versions) {
+        $versions[] = array('name' => 'IRC',
+                            'version' => GNUSOCIAL_VERSION,
+                            'author' => 'Luke Fitzgerald',
+                            'homepage' => 'http://status.net/wiki/Plugin:IRC',
+                            'rawdescription' =>
+                            // TRANS: Plugin description.
+                            _m('The IRC plugin allows users to send and receive notices over an IRC network.'));
+        return true;
+    }
+}
diff --git a/plugins/Irc/extlib/phergie/Tests/Phergie/Plugin/HandlerTest.php b/plugins/Irc/extlib/phergie/Tests/Phergie/Plugin/HandlerTest.php
new file mode 100644 (file)
index 0000000..98c70df
--- /dev/null
@@ -0,0 +1,837 @@
+<?php
+/**
+ * Phergie
+ *
+ * PHP version 5
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.
+ * It is also available through the world-wide-web at this URL:
+ * http://phergie.org/license
+ *
+ * @category  Phergie
+ * @package   Phergie_Tests
+ * @author    Phergie Development Team <team@phergie.org>
+ * @copyright 2008-2010 Phergie Development Team (http://phergie.org)
+ * @license   http://phergie.org/license New BSD License
+ * @link      http://pear.phergie.org/package/Phergie_Tests
+ */
+
+/**
+ * Unit test suite for Pherge_Plugin_Handler.
+ *
+ * @category Phergie
+ * @package  Phergie_Tests
+ * @author   Phergie Development Team <team@phergie.org>
+ * @license  http://phergie.org/license New BSD License
+ * @link     http://pear.phergie.org/package/Phergie_Tests
+ */
+class Phergie_Plugin_HandlerTest extends PHPUnit_Framework_TestCase
+{
+    /**
+     * Plugin handler instance being tested
+     *
+     * @var Phergie_Plugin_Handler
+     */
+    protected $handler;
+
+    /**
+     * Mock Phergie_Config instance passed to the plugin handler constructor
+     *
+     * @var Phergie_Config
+     */
+    protected $config;
+
+    /**
+     * Mock Phergie_Event_Handler instance passed to the plugin handler
+     * constructor
+     *
+     * @var Phergie_Event_Handler
+     */
+    protected $events;
+
+    /**
+     * Returns a mock plugin instance.
+     *
+     * @param string $name    Optional short name for the mock plugin, defaults
+     *        to 'TestPlugin'
+     * @param array  $methods Optional list of methods to override
+     *
+     * @return Phergie_Plugin_Abstract
+     */
+    protected function getMockPlugin($name = 'TestPlugin', array $methods = array())
+    {
+        $methods[] = 'getName';
+        $plugin = $this->getMock('Phergie_Plugin_Abstract', $methods);
+        $plugin
+            ->expects($this->any())
+            ->method('getName')
+            ->will($this->returnValue($name));
+        return $plugin;
+    }
+
+    /**
+     * Sets up a new handler instance before each test.
+     *
+     * @return void
+     */
+    public function setUp()
+    {
+        $this->config = $this->getMock('Phergie_Config');
+        $this->events = $this->getMock('Phergie_Event_Handler');
+        $this->handler = new Phergie_Plugin_Handler(
+            $this->config,
+            $this->events
+        );
+    }
+
+    /**
+     * Tests iterability of the plugin handler.
+     *
+     * @return void
+     */
+    public function testImplementsIteratorAggregate()
+    {
+        $reflection = new ReflectionObject($this->handler);
+
+        $this->assertTrue(
+            $reflection->implementsInterface('IteratorAggregate'),
+            'Handler does not implement IteratorAggregate'
+        );
+
+        $this->assertType(
+            'Iterator',
+            $this->handler->getIterator(),
+            'getIterator() must return an iterator'
+        );
+    }
+
+    /**
+     * Tests that a default iterator is returned if none is explicitly set.
+     *
+     * @return void
+     */
+    public function testGetIteratorReturnsDefault()
+    {
+        $this->assertType(
+            'Phergie_Plugin_Iterator',
+            $this->handler->getIterator()
+        );
+    }
+
+    /**
+     * Tests the ability to change the handler's iterator class when a valid
+     * class is specified.
+     *
+     * @return void
+     */
+    public function testSetIteratorClassWithValidClass()
+    {
+        eval('
+            class DummyIterator extends FilterIterator {
+                public function accept() {
+                    return true;
+                }
+            }
+        ');
+
+        $this->handler->setIteratorClass('DummyIterator');
+
+        $this->assertType(
+            'DummyIterator',
+            $this->handler->getIterator()
+        );
+    }
+
+    /**
+     * Tests that a failure occurs when a nonexistent iterator class is
+     * specified.
+     *
+     * @return void
+     */
+    public function testSetIteratorClassWithNonexistentClass()
+    {
+        try {
+            $this->handler->setIteratorClass('FooIterator');
+            $this->fail('Expected exception was not thrown');
+        } catch (Phergie_Plugin_Exception $e) {
+            return;
+        }
+        $this->fail('Unexpected exception was thrown');
+    }
+
+    /**
+     * Tests that a failure occurs when a class that is not a subclass of
+     * FilterIterator is specified.
+     *
+     * @return void
+     */
+    public function testSetIteratorClassWithNonFilterIteratorClass()
+    {
+        try {
+            $this->handler->setIteratorClass('ArrayIterator');
+            $this->fail('Expected exception was not thrown');
+        } catch (Phergie_Plugin_Exception $e) {
+            return;
+        }
+        $this->fail('Unexpected exception was thrown');
+    }
+
+    /**
+     * Tests countability of the plugin handler.
+     *
+     * @return void
+     */
+    public function testImplementsCountable()
+    {
+        $reflection = new ReflectionObject($this->handler);
+
+        $this->assertTrue(
+            $reflection->implementsInterface('Countable'),
+            'Handler does not implement Countable'
+        );
+
+        $this->assertType(
+            'int',
+            count($this->handler),
+            'count() must return an integer'
+        );
+    }
+
+    /**
+     * Tests the plugin handler exposing added plugins as instance
+     * properties of the handler via isset().
+     *
+     * @return void
+     */
+    public function testImplementsIsset()
+    {
+        $pluginName = 'TestPlugin';
+        $this->assertFalse(isset($this->handler->{$pluginName}));
+        $plugin = $this->getMockPlugin($pluginName);
+        $this->handler->addPlugin($plugin);
+        $this->assertTrue(isset($this->handler->{$pluginName}));
+    }
+
+    /**
+     * Tests the plugin handler exposing added plugins as instance
+     * properties of the handler.
+     *
+     * @depends testImplementsIsset
+     * @return void
+     */
+    public function testImplementsGet()
+    {
+        $plugin = $this->getMockPlugin();
+        $this->handler->addPlugin($plugin);
+        $name = $plugin->getName();
+        $getPlugin = $this->handler->getPlugin($name);
+        $this->assertTrue(isset($this->handler->$name));
+        $get = $this->handler->$name;
+        $this->assertSame($getPlugin, $get);
+    }
+
+    /**
+     * Tests the plugin handler allowing for plugin removal via unset().
+     *
+     * @depends testImplementsGet
+     * @return void
+     */
+    public function testImplementsUnset()
+    {
+        $plugin = $this->getMockPlugin();
+        $this->handler->addPlugin($plugin);
+        unset($this->handler->{$plugin->getName()});
+        $this->assertFalse($this->handler->hasPlugin($plugin->getName()));
+    }
+
+    /**
+     * Tests the plugin handler executing a callback on all contained
+     * plugins.
+     *
+     * @return void
+     */
+    public function testImplementsCall()
+    {
+        foreach (range(1, 2) as $index) {
+            $plugin = $this->getMockPlugin('TestPlugin' . $index, array('callback'));
+            $plugin
+                ->expects($this->once())
+                ->method('callback');
+            $this->handler->addPlugin($plugin);
+        }
+
+        $this->assertTrue($this->handler->callback());
+    }
+
+    /**
+     * Tests a newly instantiated handler not having plugins associated with
+     * it.
+     *
+     * @depends testImplementsCountable
+     * @return void
+     */
+    public function testEmptyHandlerHasNoPlugins()
+    {
+        $this->assertEquals(0, count($this->handler));
+    }
+
+    /**
+     * Tests a newly instantiated handler not having autoloading enabled by
+     * default.
+     *
+     * @return void
+     */
+    public function testGetAutoloadDefaultsToNotAutoload()
+    {
+        $this->assertFalse($this->handler->getAutoload());
+    }
+
+    /**
+     * Tests setAutoload().
+     *
+     * @depends testGetAutoloadDefaultsToNotAutoload
+     * @return void
+     */
+    public function testSetAutoload()
+    {
+        $this->assertSame(
+            $this->handler->setAutoload(true),
+            $this->handler,
+            'setAutoload() does not provide a fluent interface'
+        );
+
+        $this->assertTrue(
+            $this->handler->getAutoload(),
+            'setAutoload() had no effect on getAutoload()'
+        );
+    }
+
+    /**
+     * Tests addPath() providing a fluent interface.
+     *
+     * @return void
+     */
+    public function testAddPathProvidesFluentInterface()
+    {
+        $handler = $this->handler->addPath(dirname(__FILE__));
+        $this->assertSame($this->handler, $handler);
+    }
+
+    /**
+     * Tests addPath() throwing an exception when it cannot read the
+     * directory.
+     *
+     * @return void
+     */
+    public function testAddPathThrowsExceptionOnUnreadableDirectory()
+    {
+        try {
+            $this->handler->addPath('/an/unreadable/directory/path');
+        } catch(Phergie_Plugin_Exception $e) {
+            $this->assertEquals(
+                Phergie_Plugin_Exception::ERR_DIRECTORY_NOT_READABLE,
+                $e->getCode()
+            );
+            return;
+        }
+
+        $this->fail('An expected exception has not been raised');
+    }
+
+    /**
+     * Tests adding a path to the plugin handler.
+     *
+     * @return void
+     */
+    public function testAddPath()
+    {
+        $pluginName = 'Mock';
+
+        try {
+            $this->handler->addPlugin($pluginName);
+        } catch(Phergie_Plugin_Exception $e) {
+            $this->assertEquals(
+                Phergie_Plugin_Exception::ERR_CLASS_NOT_FOUND,
+                $e->getCode()
+            );
+        }
+
+        if (!isset($e)) {
+            $this->fail('Plugin loaded, path was already present');
+        }
+
+        $this->handler->addPath(dirname(__FILE__), 'Phergie_Plugin_');
+
+        try {
+            $this->handler->addPlugin($pluginName);
+        } catch(Phergie_Plugin_Exception $e) {
+            $this->fail('Added path, plugin still not found');
+        }
+    }
+
+    /**
+     * Tests addPlugin() returning an added plugin instance.
+     *
+     * @return void
+     */
+    public function testAddPluginByInstanceReturnsPluginInstance()
+    {
+        $plugin = $this->getMockPlugin();
+        $returnedPlugin = $this->handler->addPlugin($plugin);
+        $this->assertSame(
+            $returnedPlugin,
+            $plugin,
+            'addPlugin() does not return the instance passed to it'
+        );
+    }
+
+    /**
+     * Tests adding a plugin to the handler using the plugin's short name.
+     *
+     * @return void
+     */
+    public function testAddPluginByShortName()
+    {
+        $pluginName = 'Mock';
+        $this->handler->addPath(dirname(__FILE__), 'Phergie_Plugin_');
+
+        $returnedPlugin = $this->handler->addPlugin($pluginName);
+        $this->assertTrue($this->handler->hasPlugin($pluginName));
+
+        $this->assertType(
+            'Phergie_Plugin_Mock',
+            $this->handler->getPlugin($pluginName)
+        );
+
+        $this->assertSame(
+            $this->handler->getPlugin($pluginName),
+            $returnedPlugin,
+            'Handler does not contain added plugin'
+        );
+    }
+
+
+    /**
+     * Tests adding a plugin instance to the handler.
+     *
+     * @return void
+     */
+    public function testAddPluginByInstance()
+    {
+        $plugin = $this->getMockPlugin();
+        $returnedPlugin = $this->handler->addPlugin($plugin);
+        $this->assertTrue($this->handler->hasPlugin('TestPlugin'));
+
+        $this->assertSame(
+            $plugin,
+            $returnedPlugin,
+            'addPlugin() does not return added plugin instance'
+        );
+
+        $this->assertSame(
+            $plugin,
+            $this->handler->getPlugin('TestPlugin'),
+            'getPlugin() does not return added plugin instance'
+        );
+    }
+
+    /**
+     * Tests addPlugin() throwing an exception when the plugin class file
+     * can't be found.
+     *
+     * @return void
+     */
+    public function testAddPluginThrowsExceptionWhenPluginFileNotFound()
+    {
+        try {
+            $this->handler->addPlugin('TestPlugin');
+        } catch(Phergie_Plugin_Exception $e) {
+            $this->assertEquals(
+                Phergie_Plugin_Exception::ERR_CLASS_NOT_FOUND,
+                $e->getCode()
+            );
+            return;
+        }
+
+        $this->fail('An expected exception has not been raised');
+    }
+
+    /**
+     * Recursively removes all files and subdirectories in a directory.
+     *
+     * @param string $path Directory path
+     * @return void
+     */
+    private function removeDirectory($path)
+    {
+        if (file_exists($path)) {
+            $it = new RecursiveIteratorIterator(
+                new RecursiveDirectoryIterator($path),
+                RecursiveIteratorIterator::CHILD_FIRST
+            );
+            foreach ($it as $entry) {
+                if ($it->isDot()) {
+                    continue;
+                }
+                if ($entry->isDir()) {
+                    rmdir($entry->getPathname());
+                } else {
+                    unlink($entry->getPathname());
+                }
+            }
+        }
+    }
+
+    /**
+     * Tests addPlugin() throwing an exception when the plugin class file is
+     * found, but does not contain the plugin class as expected.
+     *
+     * @return void
+     */
+    public function testAddPluginThrowsExceptionWhenPluginClassNotFound()
+    {
+        $path = common_get_temp_dir() . '/Phergie/Plugin';
+        $this->removeDirectory(dirname($path));
+        mkdir($path, 0777, true);
+        touch($path . '/TestPlugin.php');
+        $this->handler->addPath($path, 'Phergie_Plugin_');
+
+        try {
+            $this->handler->addPlugin('TestPlugin');
+        } catch(Phergie_Plugin_Exception $e) { }
+
+        if (isset($e)) {
+            $this->assertEquals(
+                Phergie_Plugin_Exception::ERR_CLASS_NOT_FOUND,
+                $e->getCode()
+            );
+        } else {
+            $this->fail('An expected exception has not been raised');
+        }
+
+        $this->removeDirectory(dirname($path));
+    }
+
+    /**
+     * Tests addPlugin() throwing an exception when trying to instantiate a
+     * class that doesn't extend Phergie_Plugin_Abstract.
+     *
+     * @return void
+     */
+    public function testAddPluginThrowsExceptionIfRequestingNonPlugin()
+    {
+        try {
+            $this->handler->addPlugin('Handler');
+        } catch(Phergie_Plugin_Exception $e) {
+            $this->assertEquals(
+                Phergie_Plugin_Exception::ERR_INCORRECT_BASE_CLASS,
+                $e->getCode()
+            );
+            return;
+        }
+
+        $this->fail('An expected exception has not been raised');
+    }
+
+    /**
+     * Tests addPlugin() throwing an exception when trying to instantiate a
+     * class that can't be instantiated.
+     *
+     * @return void
+     */
+    public function testAddPluginThrowsExceptionIfPluginNotInstantiable()
+    {
+        $this->handler->addPath(dirname(__FILE__), 'Phergie_Plugin_');
+        try {
+            $this->handler->addPlugin('TestNonInstantiablePluginFromFile');
+        } catch(Phergie_Plugin_Exception $e) {
+            $this->assertEquals(
+                Phergie_Plugin_Exception::ERR_CLASS_NOT_INSTANTIABLE,
+                $e->getCode()
+            );
+            return;
+        }
+
+        $this->fail('An expected exception has not been raised');
+    }
+
+    /**
+     * Tests adding a plugin by its short name with arguments passed to the
+     * plugin constructor.
+     *
+     * @return void
+     */
+    public function testAddPluginShortNamePassesArgsToConstructor()
+    {
+        $pluginName = 'Mock';
+        $this->handler->addPath(dirname(__FILE__), 'Phergie_Plugin_');
+
+        $arguments = array('a', 'b', 'c');
+        $plugin = $this->handler->addPlugin($pluginName, $arguments);
+
+        $this->assertAttributeSame(
+            $arguments,
+            'arguments',
+            $plugin,
+            'Arguments do not match'
+        );
+    }
+
+    /**
+     * Tests addPlugin() passing Phergie_Config to an instantiated plugin.
+     *
+     * @return void
+     */
+    public function testAddPluginPassesConstructorArguments()
+    {
+        $pluginName = 'Mock';
+        $this->handler->addPath(dirname(__FILE__), 'Phergie_Plugin_');
+        $plugin = $this->handler->addPlugin($pluginName);
+
+        $this->assertSame(
+            $this->config,
+            $plugin->getConfig(),
+            'Phergie_Config instances do not match'
+        );
+
+        $this->assertSame(
+            $this->events,
+            $plugin->getEventHandler(),
+            'Phergie_Event_Handler instances do not match'
+        );
+    }
+
+    /**
+     * Tests addPlugin() calling onLoad() on an instantiated plugin.
+     *
+     * @return void
+     */
+    public function testAddPluginCallsOnLoadOnInstantiatedPlugin()
+    {
+        $plugin = $this->getMockPlugin(null, array('onLoad'));
+        $plugin
+            ->expects($this->once())
+            ->method('onLoad');
+        $this->handler->addPlugin($plugin);
+    }
+
+    /**
+     * Tests addPlugin() returning the same plugin when called twice.
+     *
+     * @return void
+     */
+    public function testAddPluginReturnsSamePluginWhenAskedTwice()
+    {
+        $pluginName = 'Mock';
+        $this->handler->addPath(dirname(__FILE__), 'Phergie_Plugin_');
+        $plugin1 = $this->handler->addPlugin($pluginName);
+        $plugin2 = $this->handler->addPlugin($pluginName);
+        $this->assertSame($plugin1, $plugin2);
+    }
+
+    /**
+     * Tests getPlugin() throwing an exception when trying to get an
+     * unloaded plugin with autoload disabled.
+     *
+     * @depends testGetAutoloadDefaultsToNotAutoload
+     * @return void
+     */
+    public function testExceptionThrownWhenLoadingPluginWithoutAutoload()
+    {
+        $this->handler->addPath(dirname(__FILE__), 'Phergie_Plugin_');
+
+        try {
+            $this->handler->getPlugin('Mock');
+        } catch (Phergie_Plugin_Exception $expected) {
+            $this->assertEquals(
+                Phergie_Plugin_Exception::ERR_PLUGIN_NOT_LOADED,
+                $expected->getCode()
+            );
+            return;
+        }
+
+        $this->fail('An expected exception has not been raised');
+    }
+
+    /**
+     * Tests addPlugins() with a plugin short name and no plugin constructor
+     * arguments.
+     *
+     * @depends testAddPluginByShortName
+     * @depends testAddPluginByInstance
+     * @return void
+     */
+    public function testAddPluginsWithoutArguments()
+    {
+        $prefix = 'Phergie_Plugin_';
+        $this->handler->addPath(dirname(__FILE__), $prefix);
+
+        $plugin = 'Mock';
+        $this->handler->addPlugins(array($plugin));
+        $returnedPlugin = $this->handler->getPlugin($plugin);
+        $this->assertContains(
+            get_class($returnedPlugin),
+            $prefix . $plugin,
+            'Short name plugin not of expected class'
+        );
+    }
+
+    /**
+     * Tests addPlugins() with a plugin short name and plugin constructor
+     * arguments.
+     *
+     * @depends testAddPluginByShortName
+     * @depends testAddPluginByInstance
+     * @return void
+     */
+    public function testAddPluginsWithArguments()
+    {
+        $prefix = 'Phergie_Plugin_';
+        $this->handler->addPath(dirname(__FILE__), $prefix);
+
+        $arguments = array(1, 2, 3);
+        $plugin = array('Mock', $arguments);
+        $this->handler->addPlugins(array($plugin));
+        $returnedPlugin = $this->handler->getPlugin('Mock');
+        $this->assertEquals(
+            $arguments,
+            $returnedPlugin->getArguments(),
+            'Constructor arguments for instance plugin do not match'
+        );
+    }
+
+    /**
+     * Tests removePlugin() with a plugin instance.
+     *
+     * @depends testAddPluginByInstance
+     * @return void
+     */
+    public function testRemovePluginByInstance()
+    {
+        $plugin = $this->getMockPlugin();
+        $this->handler->addPlugin($plugin);
+        $this->handler->removePlugin($plugin);
+        $this->assertFalse(
+            $this->handler->hasPlugin($plugin->getName()),
+            'Plugin was not removed'
+        );
+    }
+
+    /**
+     * Tests removePlugin() with a plugin short name.
+     *
+     * @depends testAddPluginByShortName
+     * @return void
+     */
+    public function testRemovePluginByShortName()
+    {
+        $plugin = 'Mock';
+        $this->handler->addPath(dirname(__FILE__), 'Phergie_Plugin_');
+
+        $this->handler->addPlugin($plugin);
+        $this->handler->removePlugin($plugin);
+        $this->assertFalse(
+            $this->handler->hasPlugin($plugin),
+            'Plugin was not removed'
+        );
+    }
+
+    /**
+     * Tests getPlugin() when the plugin is not already loaded and
+     * autoloading is disabled.
+     *
+     * @depends testSetAutoload
+     * @return void
+     */
+    public function testGetPluginWithAutoloadEnabled()
+    {
+        $this->handler->setAutoload(true);
+        $this->handler->addPath(dirname(__FILE__), 'Phergie_Plugin_');
+        $plugin = $this->handler->getPlugin('Mock');
+        $this->assertType(
+            'Phergie_Plugin_Mock',
+            $plugin,
+            'Retrieved plugin not of expected class'
+        );
+    }
+
+    /**
+     * Tests getPlugins().
+     *
+     * @depends testGetPluginWithAutoloadEnabled
+     * @return void
+     */
+    public function testGetPlugins()
+    {
+        $plugin1 = $this->getMockPlugin('TestPlugin1');
+        $this->handler->addPlugin($plugin1);
+
+        $plugin2 = $this->getMockPlugin('TestPlugin2');
+        $this->handler->addPlugin($plugin2);
+
+        $expected = array(
+            'testplugin1' => $plugin1,
+            'testplugin2' => $plugin2,
+        );
+
+        $actual = $this->handler->getPlugins();
+        $this->assertEquals($expected, $actual);
+
+        $actual = $this->handler->getPlugins(array('testplugin1', 'testplugin2'));
+        $this->assertEquals($expected, $actual);
+    }
+
+    /**
+     * Tests that multiple plugin iterators can be used concurrently.
+     *
+     * @return void
+     */
+    public function testUseMultiplePluginIteratorsConcurrently()
+    {
+        $plugin1 = $this->getMockPlugin('TestPlugin1');
+        $this->handler->addPlugin($plugin1);
+
+        $plugin2 = $this->getMockPlugin('TestPlugin2');
+        $this->handler->addPlugin($plugin2);
+
+        $iterator1 = $this->handler->getIterator();
+        $iterator1->next();
+        $this->assertSame($plugin2, $iterator1->current());
+
+        $iterator2 = $this->handler->getIterator();
+        $this->assertSame($plugin1, $iterator2->current());
+    }
+
+    /**
+     * Tests adding plugin paths via configuration.
+     *
+     * @return void
+     */
+    public function testAddPluginPathsViaConfiguration()
+    {
+        $dir = dirname(__FILE__);
+        $prefix = 'Phergie_Plugin_';
+        $paths = array($dir => $prefix);
+        $this->config
+            ->expects($this->any())
+            ->method('offsetExists')
+            ->will($this->returnValue(true));
+        $this->config
+            ->expects($this->any())
+            ->method('offsetGet')
+            ->will($this->returnValue($paths));
+
+        // Reinitialize the handler so the configuration change takes effect
+        // within the constructor
+        $this->handler = new Phergie_Plugin_Handler(
+            $this->config,
+            $this->events
+        );
+
+        $this->handler->setAutoload(true);
+        $this->handler->getPlugin('Mock');
+    }
+}
diff --git a/plugins/Irc/lib/ircmanager.php b/plugins/Irc/lib/ircmanager.php
new file mode 100644 (file)
index 0000000..11ba2bd
--- /dev/null
@@ -0,0 +1,357 @@
+<?php
+/*
+ * StatusNet - the 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/>.
+ */
+
+if (!defined('STATUSNET') && !defined('LACONICA')) { exit(1); }
+
+/**
+ * IRC background connection manager for IRC-using queue handlers,
+ * allowing them to send outgoing messages on the right connection.
+ *
+ * Input is handled during socket select loop, Any incoming messages will be handled.
+ *
+ * In a multi-site queuedaemon.php run, one connection will be instantiated
+ * for each site being handled by the current process that has IRC enabled.
+ */
+class IrcManager extends ImManager {
+    protected $conn = null;
+    protected $lastPing = null;
+    protected $messageWaiting = true;
+    protected $lastMessage = null;
+
+    protected $regChecks = array();
+    protected $regChecksLookup = array();
+
+    protected $connected = false;
+
+    /**
+     * Initialize connection to server.
+     *
+     * @return boolean true on success
+     */
+    public function start($master) {
+        if (parent::start($master)) {
+            $this->connect();
+            return true;
+        } else {
+            return false;
+        }
+    }
+
+    /**
+    * Return any open sockets that the run loop should listen
+    * for input on.
+    *
+    * @return array Array of socket resources
+    */
+    public function getSockets() {
+        $this->connect();
+        if ($this->conn) {
+            return $this->conn->getSockets();
+        } else {
+            return array();
+        }
+    }
+
+    /**
+     * Request a maximum timeout for listeners before the next idle period.
+     *
+     * @return integer Maximum timeout
+     */
+    public function timeout() {
+        if ($this->messageWaiting) {
+            return 1;
+        } else {
+            return $this->plugin->pinginterval;
+        }
+    }
+
+    /**
+     * Idle processing for io manager's execution loop.
+     *
+     * @return void
+     */
+    public function idle() {
+        // Send a ping if necessary
+        if (empty($this->lastPing) || time() - $this->lastPing > $this->plugin->pinginterval) {
+            $this->sendPing();
+        }
+
+        if ($this->connected) {
+            // Send a waiting message if appropriate
+            if ($this->messageWaiting && time() - $this->lastMessage > 1) {
+                $wm = Irc_waiting_message::top();
+                if ($wm === NULL) {
+                    $this->messageWaiting = false;
+                    return;
+                }
+
+                $data = unserialize($wm->data);
+                $wm->incAttempts();
+
+                if ($this->send_raw_message($data)) {
+                    $wm->delete();
+                } else {
+                    if ($wm->attempts <= common_config('queue', 'max_retries')) {
+                        // Try again next idle
+                        $wm->releaseClaim();
+                    } else {
+                        // Exceeded the maximum number of retries
+                        $wm->delete();
+                    }
+                }
+            }
+        }
+    }
+
+    /**
+     * Process IRC events that have come in over the wire.
+     *
+     * @param resource $socket Socket to handle input on
+     * @return void
+     */
+    public function handleInput($socket) {
+        common_debug('Servicing the IRC queue.');
+        $this->stats('irc_process');
+
+        try {
+            $this->conn->handleEvents();
+        } catch (Phergie_Driver_Exception $e) {
+            $this->connected = false;
+            $this->conn->reconnect();
+        }
+    }
+
+    /**
+    * Initiate connection
+    *
+    * @return void
+    */
+    public function connect() {
+        if (!$this->conn) {
+            $this->conn = new Phergie_StatusnetBot;
+
+            $config = new Phergie_Config;
+            $config->readArray(
+                array(
+                    'connections' => array(
+                        array(
+                            'host' => $this->plugin->host,
+                            'port' => $this->plugin->port,
+                            'username' => $this->plugin->username,
+                            'realname' => $this->plugin->realname,
+                            'nick' => $this->plugin->nick,
+                            'password' => $this->plugin->password,
+                            'transport' => $this->plugin->transporttype,
+                            'encoding' => $this->plugin->encoding
+                        )
+                    ),
+
+                    'driver' => 'statusnet',
+
+                    'processor' => 'async',
+                    'processor.options' => array('sec' => 0, 'usec' => 0),
+
+                    'plugins' => array(
+                        'Pong',
+                        'NickServ',
+                        'AutoJoin',
+                        'Statusnet',
+                    ),
+
+                    'plugins.autoload' => true,
+
+                    // Uncomment to enable debugging output
+                    //'ui.enabled' => true,
+
+                    'nickserv.password' => $this->plugin->nickservpassword,
+                    'nickserv.identify_message' => $this->plugin->nickservidentifyregexp,
+
+                    'autojoin.channels' => $this->plugin->channels,
+
+                    'statusnet.messagecallback' => array($this, 'handle_irc_message'),
+                    'statusnet.regcallback' => array($this, 'handle_reg_response'),
+                    'statusnet.connectedcallback' => array($this, 'handle_connected'),
+                    'statusnet.unregregexp' => $this->plugin->unregregexp,
+                    'statusnet.regregexp' => $this->plugin->regregexp
+                )
+            );
+
+            $this->conn->setConfig($config);
+            $this->conn->connect();
+            $this->lastPing = time();
+            $this->lastMessage = time();
+        }
+        return $this->conn;
+    }
+
+    /**
+    * Called via a callback when a message is received
+    * Passes it back to the queuing system
+    *
+    * @param array $data Data
+    * @return boolean
+    */
+    public function handle_irc_message($data) {
+        $this->plugin->enqueueIncomingRaw($data);
+        return true;
+    }
+
+    /**
+    * Called via a callback when NickServ responds to
+    * the bots query asking if a nick is registered
+    *
+    * @param array $data Data
+    * @return void
+    */
+    public function handle_reg_response($data) {
+        // Retrieve data
+        $screenname = $data['screenname'];
+        $nickdata = $this->regChecks[$screenname];
+        $usernick = $nickdata['user']->nickname;
+
+        if (isset($this->regChecksLookup[$usernick])) {
+            if ($data['registered']) {
+                // Send message
+                $this->plugin->sendConfirmationCode($screenname, $nickdata['code'], $nickdata['user'], true);
+            } else {
+                // TRANS: Message given when using an unregistered IRC nickname.
+                $this->plugin->sendMessage($screenname, _m('Your nickname is not registered so IRC connectivity cannot be enabled.'));
+
+                $confirm = new Confirm_address();
+
+                $confirm->user_id      = $user->id;
+                $confirm->address_type = $this->plugin->transport;
+
+                if ($confirm->find(true)) {
+                    $result = $confirm->delete();
+
+                    if (!$result) {
+                        common_log_db_error($confirm, 'DELETE', __FILE__);
+                        // TRANS: Server error thrown on database error when deleting IRC nickname confirmation.
+                        throw new ServerException(_m('Could not delete confirmation.'));
+                    }
+                }
+            }
+
+            // Unset lookup value
+            unset($this->regChecksLookup[$usernick]);
+
+            // Unset data
+            unset($this->regChecks[$screename]);
+        }
+    }
+
+    /**
+    * Called when the connection is established
+    *
+    * @return void
+    */
+    public function handle_connected() {
+        $this->connected = true;
+    }
+
+    /**
+    * Enters a message into the database for sending when ready
+    *
+    * @param string $command Command
+    * @param array $args Arguments
+    * @return boolean
+    */
+    protected function enqueue_waiting_message($data) {
+        $wm = new Irc_waiting_message();
+
+        $wm->data       = serialize($data);
+        $wm->prioritise = $data['prioritise'];
+        $wm->attempts   = 0;
+        $wm->created    = common_sql_now();
+        $result         = $wm->insert();
+
+        if (!$result) {
+            common_log_db_error($wm, 'INSERT', __FILE__);
+            // TRANS: Server exception thrown when an IRC waiting queue item could not be added to the database.
+            throw new ServerException(_m('Database error inserting IRC waiting queue item.'));
+        }
+
+        return true;
+    }
+
+    /**
+     * Send a message using the daemon
+     *
+     * @param $data Message data
+     * @return boolean true on success
+     */
+    public function send_raw_message($data) {
+        $this->connect();
+        if (!$this->conn) {
+            return false;
+        }
+
+        if ($data['type'] != 'delayedmessage') {
+            if ($data['type'] != 'message') {
+                // Nick checking
+                $nickdata = $data['nickdata'];
+                $usernick = $nickdata['user']->nickname;
+                $screenname = $nickdata['screenname'];
+
+                // Cancel any existing checks for this user
+                if (isset($this->regChecksLookup[$usernick])) {
+                    unset($this->regChecks[$this->regChecksLookup[$usernick]]);
+                }
+
+                $this->regChecks[$screenname] = $nickdata;
+                $this->regChecksLookup[$usernick] = $screenname;
+            }
+
+            // If there is a backlog or we need to wait, queue the message
+            if ($this->messageWaiting || time() - $this->lastMessage < 1) {
+                $this->enqueue_waiting_message(
+                    array(
+                        'type' => 'delayedmessage',
+                        'prioritise' => $data['prioritise'],
+                        'data' => $data['data']
+                    )
+                );
+                $this->messageWaiting = true;
+                return true;
+            }
+        }
+
+        try {
+            $this->conn->send($data['data']['command'], $data['data']['args']);
+        } catch (Phergie_Driver_Exception $e) {
+            $this->connected = false;
+            $this->conn->reconnect();
+            return false;
+        }
+
+        $this->lastMessage = time();
+        return true;
+    }
+
+    /**
+    * Sends a ping
+    *
+    * @return void
+    */
+    protected function sendPing() {
+        $this->lastPing = time();
+        $this->conn->send('PING', $this->lastPing);
+    }
+}
index 7d052d5b24ec84a0de0fe703b65787bcc195d24b..aea1b72ea4f409f4a641b3542721ed20102adcb2 100644 (file)
@@ -370,7 +370,7 @@ class LdapCommon
         mt_srand((double)microtime() * 1000000);
 
         while( strlen( $str ) < $length )
-            $str .= substr( $possible, ( rand() % strlen( $possible ) ), 1 );
+            $str .= substr( $possible, ( mt_rand() % strlen( $possible ) ), 1 );
 
         return $str;
     }
index 5edf66767d3715f3bb95f1c81bf32daadbde3f96..5e04d4d1546f10297642b019820956176307cd5c 100644 (file)
@@ -48,7 +48,7 @@ class LinkPreviewPlugin extends Plugin
      * @param Action $action
      * @return boolean hook result
      */
-    function onEndShowScripts($action)
+    function onEndShowScripts(Action $action)
     {
         $user = common_current_user();
         if ($user && common_config('attachments', 'process_links')) {
index 97b0942441e94a8a93bcb9663ae13c26294fed51..c0473fb597633a75929b96edc397e7153ed2039f 100644 (file)
@@ -46,7 +46,7 @@ if (!defined('STATUSNET') && !defined('LACONICA')) {
  */
 class OembedproxyAction extends OembedAction
 {
-    function handle($args)
+    function handle(array $args=array())
     {
         // Trigger short error responses; not a human-readable web page.
         GNUsocial::setApi(true);
index 941e7c4c4b9241705c02dbddefb3e35586973bfe..3a7de0d04558336f4166bc99211918d403e362a0 100644 (file)
@@ -140,7 +140,7 @@ class LinkbackPlugin extends Plugin
 
     // Based on https://github.com/indieweb/mention-client-php
     // which is licensed Apache 2.0
-    function getWebmention($result) {
+    function getWebmention(Auth_Yadis_HTTPFetcher $result) {
         if (isset($result->headers['Link'])) {
             // XXX: the fetcher only gives back one of each header, so this may fail on multiple Link headers
             if(preg_match('~<((?:https?://)?[^>]+)>; rel="webmention"~', $result->headers['Link'], $match)) {
@@ -188,7 +188,7 @@ class LinkbackPlugin extends Plugin
         }
     }
 
-    function getPingback($result) {
+    function getPingback(Auth_Yadis_HTTPFetcher $result) {
         if (array_key_exists('X-Pingback', $result->headers)) {
             return $result->headers['X-Pingback'];
         } else if(preg_match('/<(?:link|a)[ ]+href="([^"]+)"[ ]+rel="[^" ]* ?pingback ?[^" ]*"[ ]*\/?>/i', $result->body, $match)
@@ -233,7 +233,7 @@ class LinkbackPlugin extends Plugin
     // Largely cadged from trackback_cls.php by
     // Ran Aroussi <ran@blogish.org>, GPL2 or any later version
     // http://phptrackback.sourceforge.net/
-    function getTrackback($result)
+    function getTrackback(Auth_Yadis_HTTPFetcher $result)
     {
         $text = $result->body;
         $url = $result->final_url;
@@ -349,7 +349,7 @@ class LinkbackPlugin extends Plugin
         return true;
     }
 
-    function onEndAccountSettingsNav($action)
+    function onEndAccountSettingsNav(Action $action)
     {
         $action_name = $action->trimmed('action');
 
index fcc9d88e5661852d505ad5f678223dec7a6c5d8c..91e3edac406b3ef8ac79fae0f242d846f07af230 100644 (file)
@@ -63,7 +63,7 @@ class MapstractionPlugin extends Plugin
      *
      * @return boolean event handler return
      */
-    function onRouterInitialized($m)
+    function onRouterInitialized(URLMapper $m)
     {
         $m->connect(':nickname/all/map',
                     array('action' => 'allmap'),
@@ -83,7 +83,7 @@ class MapstractionPlugin extends Plugin
      *
      * @return boolean event handler return
      */
-    function onEndShowScripts($action)
+    function onEndShowScripts(Action $action)
     {
         $actionName = $action->trimmed('action');
 
index 21bdf62eaa94594a5c7615e3dcaa46ddcc61f09c..173629853cda442ce80a438461e45053823b649f 100644 (file)
@@ -44,7 +44,7 @@ if (!defined('STATUSNET')) {
  */
 class AllmapAction extends MapAction
 {
-    function prepare($args)
+    function prepare(array $args=array())
     {
         if (parent::prepare($args)) {
             $stream = new InboxNoticeStream($this->user->getProfile(), $this->scoped);
index 48861af9942605295b9b81bf775ed9c7032420c3..7e334cc9f3a053d90586c029045f8370beedd60c 100644 (file)
@@ -48,7 +48,7 @@ class MapAction extends Action
     var $page    = null;
     var $notices = null;
 
-    function prepare($args)
+    function prepare(array $args=array())
     {
         parent::prepare($args);
 
@@ -94,7 +94,7 @@ class MapAction extends Action
         return true;
     }
 
-    function handle($args)
+    function handle(array $args=array())
     {
         parent::handle($args);
         $this->showPage();
@@ -135,7 +135,7 @@ class MapAction extends Action
         return true;
     }
 
-    function noticeAsJson($notice)
+    function noticeAsJson(Notice $notice)
     {
         // FIXME: this code should be abstracted to a neutral third
         // party, like Notice::asJson(). I'm not sure of the ethics
index 99a43e538a5c81fb09ac551fec98b101450ba936..4aef1400abd363a74f3b7e465c87ac1d34958311 100644 (file)
@@ -44,7 +44,7 @@ if (!defined('STATUSNET')) {
  */
 class UsermapAction extends MapAction
 {
-    function prepare($args)
+    function prepare(array $args=array())
     {
         if(parent::prepare($args)) {
             $this->notice = empty($this->tag)
index 1dd3bdcf345fcd685cabdfe9ba3ad304d3e3ced0..cb51e980f3760c95e5345b16a77a032f8c72c877 100644 (file)
@@ -152,7 +152,7 @@ class MinifyPlugin extends Plugin
         return JSMin::minify($code);
     }
 
-    static function minifyCss($code, $options = array()) {
+    static function minifyCss($code, array $options = array()) {
         require_once('Minify/CSS.php');
         return Minify_CSS::minify($code,$options);
     }
index d7ec5d1392003cd0499584e169648e91424c836e..671e22f5a64889d3d98d658d5d4581a8b70d7917 100644 (file)
@@ -30,12 +30,12 @@ class MinifyAction extends Action
     var $file;
     var $v;
 
-    function isReadOnly($args)
+    function isReadOnly(array $args=array())
     {
         return true;
     }
 
-    function prepare($args)
+    function prepare(array $args=array())
     {
         parent::prepare($args);
         $this->v = $args['v'];
@@ -70,7 +70,7 @@ class MinifyAction extends Action
         return filemtime($this->file);
     }
 
-    function handle($args)
+    function handle(array $args=array())
     {
         parent::handle($args);
 
index 37f7169624c58b7d0ea1b6bbeff294a9d21b7b75..0d1555c9473cb6e47d24e8a258c09e1b5c9a8c97 100644 (file)
@@ -134,8 +134,8 @@ class Solar_Dir {
         if (! Solar_Dir::$_tmp) {
             
             // use the system if we can
-            if (function_exists('sys_get_temp_dir')) {
-                $tmp = sys_get_temp_dir();
+            if (function_exists('common_get_temp_dir')) {
+                $tmp = common_get_temp_dir();
             } else {
                 $tmp = Solar_Dir::_tmp();
             }
index 2752a2153947302d251aabf8374d381e32412f44..b37ea445788aa651a7172ec0dad28bcaebb62199 100644 (file)
@@ -42,7 +42,7 @@ class ModHelperPlugin extends Plugin
         return true;
     }
 
-    function onUserRightsCheck($profile, $right, &$result)
+    function onUserRightsCheck(Profile $profile, $right, &$result)
     {
         if (in_array($right, self::$rights)) {
             // Hrm.... really we should confirm that the *other* user isn't privleged. :)
index d1e01ca8496da938607e3d414ed2c2f734298121..aa275fd82abeab8abc570363d58f7492078e17eb 100644 (file)
@@ -71,7 +71,7 @@ class ModLogPlugin extends Plugin
         return true;
     }
 
-    function onEndGrantRole($profile, $role)
+    function onEndGrantRole(Profile $profile, $role)
     {
         $modlog = new ModLog();
 
@@ -79,7 +79,7 @@ class ModLogPlugin extends Plugin
         $modlog->profile_id = $profile->id;
 
         $cur = common_current_user();
-        
+
         if (!empty($cur)) {
             $modlog->moderator_id = $cur->id;
         }
@@ -93,7 +93,7 @@ class ModLogPlugin extends Plugin
         return true;
     }
 
-    function onEndRevokeRole($profile, $role)
+    function onEndRevokeRole(Profile $profile, $role)
     {
         $modlog = new ModLog();
 
@@ -102,7 +102,7 @@ class ModLogPlugin extends Plugin
         $modlog->profile_id = $profile->id;
 
         $scoped = Profile::current();
-        
+
         if ($scoped instanceof Profile) {
             $modlog->moderator_id = $scoped->getID();
         }
@@ -174,7 +174,7 @@ class ModLogPlugin extends Plugin
         }
     }
 
-    function onUserRightsCheck($profile, $right, &$result) {
+    function onUserRightsCheck(Profile $profile, $right, &$result) {
         switch ($right) {
         case self::VIEWMODLOG:
             $result = ($profile->hasRole(Profile_role::MODERATOR) || $profile->hasRole('modhelper'));
index 816034f83126a37fce7d82838f03d107c4981312..f0ef808eb55da4ecc68b32069b4fa316e2c3b39e 100644 (file)
@@ -74,7 +74,7 @@ class ModPlusPlugin extends Plugin
      *
      * @param ProfileListItem $item
      */
-    function onStartProfileListItemProfile($item)
+    function onStartProfileListItemProfile(ProfileListItem $item)
     {
         $this->showProfileOptions($item->out, $item->profile->getProfile());
         return true;
index 382ce2ee5bb782b2aa327004cd98952a618f0f85..b4c9c1cf69620357a90117ef1879284c6b593b5b 100644 (file)
@@ -70,7 +70,7 @@ class MollomPlugin extends Plugin
     public $private_key;
     public $servers;
 
-    function onStartNoticeSave($notice)
+    function onStartNoticeSave(Notice $notice)
     {
       if ( $this->public_key ) {
         //Check spam
index 960cb935f715ced90e5ec2102c353a2e8f619351..87e07d5a63fb75fdadf5d76e0adbec6cf5d4525d 100644 (file)
@@ -246,7 +246,7 @@ class NoticeTitlePlugin extends Plugin
      *
      * @return boolean hook value
      */
-    function onNoticeDeleteRelated($notice)
+    function onNoticeDeleteRelated(Notice $notice)
     {
         $nt = Notice_title::getKV('notice_id', $notice->id);
 
@@ -264,7 +264,7 @@ class NoticeTitlePlugin extends Plugin
      *
      * @return boolean hook value
      */
-    function onStartShowHeadTitle($action)
+    function onStartShowHeadTitle(Action $action)
     {
         $actionName = $action->trimmed('action');
 
index f88ab700874adfee8bbd847f8eee3aee92242151..d45864bd6c537b6137de6b0b797331ea2379daa2 100644 (file)
@@ -77,7 +77,7 @@ class Notice_title extends Managed_DataObject
      *
      * @return string title of the notice, or null if none
      */
-    static function fromNotice($notice)
+    static function fromNotice(Notice $notice)
     {
         $nt = Notice_title::getKV('notice_id', $notice->id);
         if (empty($nt)) {
index c3307f23cbcb021dec2378f4391a146ba59cbca5..03d63679d6500c50469a2d8718a5c6442bd23c88 100644 (file)
@@ -127,7 +127,7 @@ class OStatusPlugin extends Plugin
     /**
      * Put saved notices into the queue for pubsub distribution.
      */
-    function onStartEnqueueNotice($notice, &$transports)
+    function onStartEnqueueNotice(Notice $notice, array &$transports)
     {
         if ($notice->inScope(null)) {
             // put our transport first, in case there's any conflict (like OMB)
@@ -240,7 +240,7 @@ class OStatusPlugin extends Plugin
     /*
      * If the field being looked for is URI look for the profile
      */
-    function onStartProfileCompletionSearch($action, $profile, $search_engine) {
+    public function onStartProfileCompletionSearch(Action $action, Profile $profile, $search_engine) {
         if ($action->field == 'uri') {
             $profile->joinAdd(array('id', 'user:id'));
             $profile->whereAdd('uri LIKE "%' . $profile->escape($q) . '%"');
@@ -281,7 +281,7 @@ class OStatusPlugin extends Plugin
      * @param array &$mention in/out param: set of found mentions
      * @return boolean hook return value
      */
-    function onEndFindMentions(Profile $sender, $text, &$mentions)
+    function onEndFindMentions(Profile $sender, $text, array &$mentions)
     {
         $matches = array();
 
@@ -370,7 +370,7 @@ class OStatusPlugin extends Plugin
      * @param Profile &$profile
      * @return hook return code
      */
-    function onStartCommandGetProfile($command, $arg, &$profile)
+    public function onStartCommandGetProfile(Command $command, $arg, Profile &$profile = null)
     {
         $oprofile = $this->pullRemoteProfile($arg);
         if ($oprofile instanceof Ostatus_profile && !$oprofile->isGroup()) {
@@ -397,7 +397,7 @@ class OStatusPlugin extends Plugin
      * @param User_group &$group
      * @return hook return code
      */
-    function onStartCommandGetGroup($command, $arg, &$group)
+    function onStartCommandGetGroup(Command $command, $arg, User_group &$group = null)
     {
         $oprofile = $this->pullRemoteProfile($arg);
         if ($oprofile instanceof Ostatus_profile && $oprofile->isGroup()) {
@@ -473,7 +473,7 @@ class OStatusPlugin extends Plugin
         return true;
     }
 
-    function onEndShowStatusNetScripts($action) {
+    public function onEndShowStatusNetScripts(Action $action) {
         $action->script($this->path('js/ostatus.js'));
         return true;
     }
@@ -531,7 +531,7 @@ class OStatusPlugin extends Plugin
         if ($oprofile instanceof Ostatus_profile) {
             $oprofile->processFeed($feed, 'push');
         } else {
-            common_log(LOG_DEBUG, "No ostatus profile for incoming feed $feedsub->uri");
+            common_debug("No ostatus profile for incoming feed $feedsub->uri");
         }
     }
 
@@ -1139,7 +1139,7 @@ class OStatusPlugin extends Plugin
         $oprofile->query(sprintf($sql, $profile->id, $profile->id));
 
         if ($oprofile->N == 0) {
-            common_log(LOG_DEBUG, "No OStatus remote subscribees for $profile->nickname");
+            common_debug("No OStatus remote subscribees for $profile->nickname");
             return true;
         }
 
@@ -1375,7 +1375,7 @@ class OStatusPlugin extends Plugin
         return true;
     }
 
-    public function onProfileDeleteRelated($profile, &$related)
+    public function onProfileDeleteRelated(Profile $profile, array &$related)
     {
         // Ostatus_profile has a 'profile_id' property, which will be used to find the object
         $related[] = 'Ostatus_profile';
index 64b47df498eb956c278fe4c88c519d78fdc3b713..d1a4d24c8048c79299e7ce6f63298586f4335363 100644 (file)
@@ -211,7 +211,8 @@ class OStatusInitAction extends Action
     {
         if ($this->nickname) {
             $user = User::getKV('nickname', $this->nickname);
-            if ($user) {
+
+            if ($user instanceof User) {
                 return common_local_url('userbyid', array('id' => $user->id));
             } else {
                 // TRANS: Client error.
index fa999fe09a759b6b4d70d3fc5173e669d764bba9..d054c3e59f646e6cc89796cb143749f57d1aae48 100644 (file)
@@ -31,7 +31,7 @@ class OStatusTagAction extends OStatusInitAction
     var $profile;
     var $err;
 
-    function prepare($args)
+    function prepare(array $args=array())
     {
         parent::prepare($args);
 
index 0c7129e885a5983671dc7527110fe12f7c98d082..b0875c298865b86f70fa1d8c57c272368d73d25a 100644 (file)
@@ -487,7 +487,7 @@ class FeedSub extends Managed_DataObject
                     return true;
                 }
                 if (common_config('feedsub', 'debug')) {
-                    $tempfile = tempnam(sys_get_temp_dir(), 'feedsub-receive');
+                    $tempfile = tempnam(common_get_temp_dir(), 'feedsub-receive');
                     if ($tempfile) {
                         file_put_contents($tempfile, $post);
                     }
index 00c87bb004839838d9c9b7ae722a5625e0387cbd..ca1708282e9c392cff1a5b452033ffb4ff348de7 100644 (file)
@@ -371,9 +371,10 @@ class Ostatus_profile extends Managed_DataObject
      * send immediately but won't get the return value.
      *
      * @param mixed $entry XML string, Notice, or Activity
+     * @param Profile $actor Acting profile
      * @return boolean success
      */
-    public function notifyDeferred($entry, $actor)
+    public function notifyDeferred($entry, Profile $actor)
     {
         if ($this->salmonuri) {
             $data = array('salmonuri' => $this->salmonuri,
@@ -517,7 +518,7 @@ class Ostatus_profile extends Managed_DataObject
      * @param string $method 'push' or 'salmon'
      * @return mixed saved Notice or false
      */
-    public function processPost($activity, $method)
+    public function processPost(Activity $activity, $method)
     {
         $actor = ActivityUtils::checkAuthorship($activity, $this->localProfile());
 
@@ -541,7 +542,7 @@ class Ostatus_profile extends Managed_DataObject
      */
     static public function filterAttention(Profile $sender, array $attention)
     {
-        common_log(LOG_DEBUG, "Original reply recipients: " . implode(', ', array_keys($attention)));
+        common_debug("Original reply recipients: " . implode(', ', array_keys($attention)));
         $groups = array();
         $replies = array();
         foreach ($attention as $recipient=>$type) {
@@ -563,11 +564,11 @@ class Ostatus_profile extends Managed_DataObject
                     if ($sender->isMember($group)) {
                         $groups[] = $group->id;
                     } else {
-                        common_log(LOG_DEBUG, sprintf('Skipping reply to local group %s as sender %d is not a member', $group->getNickname(), $sender->id));
+                        common_debug(sprintf('Skipping reply to local group %s as sender %d is not a member', $group->getNickname(), $sender->id));
                     }
                     continue;
                 } else {
-                    common_log(LOG_DEBUG, "Skipping reply to bogus group $recipient");
+                    common_debug("Skipping reply to bogus group $recipient");
                 }
             }
 
@@ -585,12 +586,12 @@ class Ostatus_profile extends Managed_DataObject
                 continue;
             } catch (Exception $e) {
                 // Neither a recognizable local nor remote user!
-                common_log(LOG_DEBUG, "Skipping reply to unrecognized profile $recipient: " . $e->getMessage());
+                common_debug("Skipping reply to unrecognized profile $recipient: " . $e->getMessage());
             }
 
         }
-        common_log(LOG_DEBUG, "Local reply recipients: " . implode(', ', $replies));
-        common_log(LOG_DEBUG, "Local group recipients: " . implode(', ', $groups));
+        common_debug("Local reply recipients: " . implode(', ', $replies));
+        common_debug("Local group recipients: " . implode(', ', $groups));
         return array($groups, $replies);
     }
 
@@ -881,7 +882,7 @@ class Ostatus_profile extends Managed_DataObject
 
         // @todo FIXME: This should be better encapsulated
         // ripped from oauthstore.php (for old OMB client)
-        $temp_filename = tempnam(sys_get_temp_dir(), 'listener_avatar');
+        $temp_filename = tempnam(common_get_temp_dir(), 'listener_avatar');
         try {
             $imgData = HTTPClient::quickGet($url);
             // Make sure it's at least an image file. ImageFile can do the rest.
@@ -1106,7 +1107,7 @@ class Ostatus_profile extends Managed_DataObject
         $discover = false;
 
         if (!$homeuri) {
-            common_log(LOG_DEBUG, __METHOD__ . " empty actor profile URI: " . var_export($activity, true));
+            common_debug(__METHOD__ . " empty actor profile URI: " . var_export($activity, true));
             // TRANS: Exception.
             throw new Exception(_m('No profile URI.'));
         }
@@ -1348,7 +1349,7 @@ class Ostatus_profile extends Managed_DataObject
         // @todo tags from categories
 
         if ($profile->id) {
-            common_log(LOG_DEBUG, "Updating OStatus profile $profile->id from remote info $object->id: " . var_export($object, true) . var_export($hints, true));
+            common_debug("Updating OStatus profile $profile->id from remote info $object->id: " . var_export($object, true) . var_export($hints, true));
             $profile->update($orig);
         }
     }
@@ -1372,12 +1373,12 @@ class Ostatus_profile extends Managed_DataObject
         $group->homepage = self::getActivityObjectHomepage($object, $hints);
 
         if ($group->id) {   // If no id, we haven't called insert() yet, so don't run update()
-            common_log(LOG_DEBUG, "Updating OStatus group $group->id from remote info $object->id: " . var_export($object, true) . var_export($hints, true));
+            common_debug("Updating OStatus group $group->id from remote info $object->id: " . var_export($object, true) . var_export($hints, true));
             $group->update($orig);
         }
     }
 
-    protected static function updatePeopletag($tag, ActivityObject $object, array $hints=array()) {
+    protected static function updatePeopletag(Peopletag $tag, ActivityObject $object, array $hints=array()) {
         $orig = clone($tag);
 
         $tag->tag = $object->title;
@@ -1393,7 +1394,7 @@ class Ostatus_profile extends Managed_DataObject
         $tag->tagger = $tagger->profile_id;
 
         if ($tag->id) {
-            common_log(LOG_DEBUG, "Updating OStatus peopletag $tag->id from remote info $object->id: " . var_export($object, true) . var_export($hints, true));
+            common_debug("Updating OStatus peopletag $tag->id from remote info $object->id: " . var_export($object, true) . var_export($hints, true));
             $tag->update($orig);
         }
     }
@@ -1795,7 +1796,7 @@ class Ostatus_profile extends Managed_DataObject
         } else {
             $actor = $activity->actor;
 
-            if (empty($actor)) {
+            if (!$actor instanceof Profile) {
                 // OK here! assume the default
             } else if ($actor->id == $this->getUri() || $actor->link == $this->getUri()) {
                 $this->updateFromActivityObject($actor);
index 6786bfa298a650e34ef4e3e1fd6478ebe31a6190..a057da515bdd84529361d29d063f71a9a3f0c7a1 100644 (file)
@@ -340,19 +340,19 @@ class MagicEnvelope
     public function verify(Profile $profile)
     {
         if ($this->alg != 'RSA-SHA256') {
-            common_log(LOG_DEBUG, "Salmon error: bad algorithm");
+            common_debug("Salmon error: bad algorithm");
             return false;
         }
 
         if ($this->encoding != self::ENCODING) {
-            common_log(LOG_DEBUG, "Salmon error: bad encoding");
+            common_debug("Salmon error: bad encoding");
             return false;
         }
 
         try {
             $magicsig = $this->getKeyPair($profile, true);    // Do discovery too if necessary
         } catch (Exception $e) {
-            common_log(LOG_DEBUG, "Salmon error: ".$e->getMessage());
+            common_debug("Salmon error: ".$e->getMessage());
             return false;
         }
 
index 3e9c4828fb5584e3d077d6e6d5b4fd626bdb352c..964580cf49a208b8e2129857f8cc20a78587d468 100644 (file)
@@ -146,14 +146,14 @@ class OStatusQueueHandler extends QueueHandler
         $this->pushFeed($feed, array($this, 'peopletagFeedForNotice'), $ptag);
     }
 
-    function pingReply($oprofile)
+    function pingReply(OStatus_profile $oprofile)
     {
         if ($this->user) {
             // For local posts, send a Salmon ping to the mentioned
             // remote user or group.
             // @fixme as an optimization we can skip this if the
             // remote profile is subscribed to the author.
-            $oprofile->notifyDeferred($this->notice, $this->user);
+            $oprofile->notifyDeferred($this->notice, $this->user->getProfile());
         }
     }
 
index a2703f1647fbef952baa3f9b310bf9f35bb51f8d..2f48042820ba9add9c411afd7e761eac64a2ebeb 100644 (file)
@@ -93,7 +93,7 @@ class SalmonAction extends Action
     {
         parent::handle();
 
-        common_log(LOG_DEBUG, "Got a " . $this->activity->verb);
+        common_debug("Got a " . $this->activity->verb);
         try {
             if (Event::handle('StartHandleSalmonTarget', array($this->activity, $this->target)) &&
                     Event::handle('StartHandleSalmon', array($this->activity))) {
index ffaae5588d1eae757e07e15ac654f27056d168fc..817ef4eb166cc9f97225443fd57ac564e4a63bb2 100755 (executable)
@@ -31,7 +31,7 @@ for local users and groups.
 
 END_OF_USERROLE_HELP;
 
-require_once INSTALLDIR.'/scripts/commandline.inc';
+require_once INSTALLDIR.'/scripts/commandline.inc.php';
 
 $dry = have_option('dry-run');
 
@@ -156,7 +156,7 @@ while ($oprofile->fetch()) {
     if (preg_match('!/group/(\d+)/id!', $oprofile->getUri(), $matches)) {
         $id = intval($matches[1]);
         $group = Local_group::getKV('group_id', $id);
-        if ($group) {
+        if ($group instanceof Local_group) {
             $nick = $group->nickname;
         } else {
             $nick = '<deleted>';
@@ -165,11 +165,13 @@ while ($oprofile->fetch()) {
     } else if (preg_match('!/user/(\d+)!', $uri, $matches)) {
         $id = intval($matches[1]);
         $user = User::getKV('id', $id);
-        if ($user) {
+
+        if ($user instanceof User) {
             $nick = $user->nickname;
         } else {
             $nick = '<deleted>';
         }
+
         echo "user $id ($nick) hidden by $uri";
     } else {
         echo "$uri matched query, but we don't recognize it.\n";
index a95cd54dbc8d8b636106e598a4ddeca56b7bcc62..f1db4b358ff35b0497457ad75ef27086a411ee30 100755 (executable)
@@ -31,7 +31,7 @@ Clean up feeds that no longer have subscribers.
 
 END_OF_HELP;
 
-require_once INSTALLDIR.'/scripts/commandline.inc';
+require_once INSTALLDIR.'/scripts/commandline.inc.php';
 
 $delete_inactive = have_option('d', 'delete-inactive');
 $delcount = 0;
index 8f8ac3ee1d968416dacd8557e6e5fba7360181a4..01136de4173c5e04e871bc966d1b6deab49106fe 100755 (executable)
@@ -26,7 +26,7 @@ Resubscribe to any soon expiring feeds. Default time to expiration is 1 day.
 
 END_OF_HELP;
 
-require_once INSTALLDIR.'/scripts/commandline.inc';
+require_once INSTALLDIR.'/scripts/commandline.inc.php';
 
 try {
     $sub = FeedSub::renewalCheck();
index d5d0924fbfe3fe7330df4f49f543c20d175a8368..efad67dbb5005f1894b2289341992c1708134a60 100755 (executable)
@@ -34,7 +34,7 @@ Options:
 
 END_OF_HELP;
 
-require_once INSTALLDIR.'/scripts/commandline.inc';
+require_once INSTALLDIR.'/scripts/commandline.inc.php';
 
 $validate = new Validate();
 
index ce1698a60c2bff4751a228127965bf6422e176e4..1957f95cb368f3cafce9cf6b36ce25acbb156a25 100755 (executable)
@@ -41,7 +41,7 @@ the hub is probably either broken or doesn't exist.'
 
 END_OF_HELP;
 
-require_once INSTALLDIR . '/scripts/commandline.inc';
+require_once INSTALLDIR . '/scripts/commandline.inc.php';
 
 $dry = false;
 
index da1eee292ef8d5a3b439a7d0bb039ad167b39c4e..2a12069b5f5eeee7962d8b1014d42a42da9988e6 100755 (executable)
@@ -33,7 +33,7 @@ Mainly intended for testing funky feed formats.
 
 END_OF_HELP;
 
-require_once INSTALLDIR.'/scripts/commandline.inc';
+require_once INSTALLDIR.'/scripts/commandline.inc.php';
 
 $validate = new Validate();
 
index ca48dc34a7db1b7a57308da618f015c7b0a97cac..c56bedd05c6ce70fc29a07ff697523ea941740f6 100755 (executable)
@@ -37,7 +37,7 @@ Options:
 
 END_OF_HELP;
 
-require_once INSTALLDIR.'/scripts/commandline.inc';
+require_once INSTALLDIR.'/scripts/commandline.inc.php';
 
 function showProfileInfo(Ostatus_profile $oprofile) {
     if ($oprofile->isGroup()) {
index c5d9aa897c264549dac9a07a0da7c14d72a53699..40adda102ef8a6128c6403445abbd0f49459eed4 100755 (executable)
@@ -30,7 +30,7 @@ things restarted if the hub or feed URLs have changed for the profile.
 
 END_OF_HELP;
 
-require_once INSTALLDIR.'/scripts/commandline.inc';
+require_once INSTALLDIR.'/scripts/commandline.inc.php';
 
 $validate = new Validate();
 
index 3f54c83cda1ec3da4f121509d043d814f0e2cf5f..1f70bac897aecadd5581d9148d20ce2c8e7e125f 100755 (executable)
@@ -36,7 +36,7 @@ you have no backup.
 
 UPDATE_OSTATUS_PROFILES;
 
-require_once INSTALLDIR . '/scripts/commandline.inc';
+require_once INSTALLDIR . '/scripts/commandline.inc.php';
 
 /*
  * Hacky class to remove some checks and get public access to
@@ -54,7 +54,7 @@ class LooseOstatusProfile extends Ostatus_profile
      * @throws Exception on various error conditions
      * @throws OStatusShadowException if this reference would obscure a local user/group
      */
-    public static function updateProfileURL($profile_url, $hints=array())
+    public static function updateProfileURL($profile_url, array $hints=array())
     {
         $oprofile = null;
 
index 0584af8ef45669b789e08f8b9015825fe59e3683..52c8252c1394cf1058d42c738e9821a5097928a3 100644 (file)
@@ -9,7 +9,7 @@ define('INSTALLDIR', realpath(dirname(__FILE__) . '/../../..'));
 define('GNUSOCIAL', true);
 define('STATUSNET', true);  // compatibility
 
-require_once INSTALLDIR . '/scripts/commandline.inc';
+require_once INSTALLDIR . '/scripts/commandline.inc.php';
 require_once INSTALLDIR . '/extlib/php-gettext/gettext.inc';
 
 common_init_locale("en_US");
index e3f5439aed69bd239da22149538dfbbade619819..eaef76d8cdeb1f1e2e59b5cb568f1b0856395268 100755 (executable)
@@ -34,7 +34,7 @@ Test generation and sending of magic envelopes for Salmon slaps.
 
 END_OF_HELP;
 
-require_once INSTALLDIR.'/scripts/commandline.inc';
+require_once INSTALLDIR.'/scripts/commandline.inc.php';
 
 if (!have_option('--notice')) {
     print "$helptext";
index ccba4c42a585dfd8a77949598764a9cff09833a0..afaaa2ded5dea0f93c7fd1582aba19ce48733aa8 100644 (file)
@@ -230,7 +230,7 @@ class OembedAction extends Action
      *
      * @return boolean is read only action?
      */
-    function isReadOnly($args)
+    function isReadOnly(array $args=array())
     {
         return true;
     }
index 246a74fea03751960153134c1be880ea64c0037d..02f48f623e62a8600bdbd59e88524b2579b6887b 100644 (file)
@@ -100,6 +100,9 @@ class File_oembed extends Managed_DataObject
      * @param int $file_id
      */
     public static function saveNew($data, $file_id) {
+        // @TODO Must be an object
+        assert(is_object($data));
+
         $file_oembed = new File_oembed;
         $file_oembed->file_id = $file_id;
         if (!isset($data->version)) {
index 50ddc8a9943b2035885fc8ec88cf28de6f50ef4c..d2fb6b9ccb425e8ff6c1d8acc26120fecc6d3fe3 100755 (executable)
@@ -30,7 +30,7 @@ Patches up file entries with corrupted types and titles (the "h bug").
 
 END_OF_USERROLE_HELP;
 
-require_once INSTALLDIR.'/scripts/commandline.inc';
+require_once INSTALLDIR.'/scripts/commandline.inc.php';
 
 $dry = have_option('dry-run');
 
index 1d7a17ca2c87fff49e647f7345c7dcc53e62357a..2cc2ae00a0de811582bf08db86841009b59a46af 100644 (file)
@@ -50,7 +50,7 @@ if (!defined('STATUSNET')) {
 class OfflineBackupPlugin extends Plugin
 {
 
-    function onRouterInitialized($m)
+    function onRouterInitialized(URLMapper $m)
     {
         $m->connect('main/backupaccount',
                     array('action' => 'offlinebackup'));
@@ -65,7 +65,7 @@ class OfflineBackupPlugin extends Plugin
      * @return boolean hook value
      */
 
-    function onEndInitializeQueueManager($qm)
+    function onEndInitializeQueueManager(QueueManager $qm)
     {
         $qm->connect('backoff', 'OfflineBackupQueueHandler');
         return true;
index 9f96193d95758ed85c67db31bfd4a4c6216a42c2..82384f60bcc35765bb1df557e5c7be57ad9848ab 100644 (file)
@@ -73,7 +73,7 @@ class OfflineBackupQueueHandler extends QueueHandler
     {
         // XXX: this is pretty lose-y;  try another way
 
-        $tmpdir = sys_get_temp_dir() . '/offline-backup/' . $user->nickname . '/' . common_date_iso8601(common_sql_now());
+        $tmpdir = common_get_temp_dir() . '/offline-backup/' . $user->nickname . '/' . common_date_iso8601(common_sql_now());
 
         common_log(LOG_INFO, 'Writing backup data to ' . $tmpdir . ' for ' . $user->nickname);
 
index 06c75f7a930daee5b64ec3dd01f469a5d6f29b56..a597f829963ac4336874fae1d05628176171137a 100644 (file)
@@ -42,7 +42,7 @@ if (!defined('STATUSNET') && !defined('LACONICA')) {
  */
 class OpenExternalLinkTargetPlugin extends Plugin
 {
-    function onEndShowScripts($action)
+    function onEndShowScripts(Action $action)
     {
         $action->inlineScript('$(document).on("click", "a[rel~=external]:not([class~=attachment])", function () { window.open(this.href); return false; });');
 
index 2e9ada98064e3b36ae0d7457d98bfd3322c59488..d633b12f38a9edb085f906b00e7cb3dc15fce47d 100644 (file)
@@ -125,7 +125,7 @@ class OpenIDPlugin extends Plugin
      *
      * @return boolean hook return
      */
-    function onArgsInitialize($args)
+    function onArgsInitialize(array &$args)
     {
         if (common_config('site', 'openidonly')) {
             if (array_key_exists('action', $args)) {
@@ -566,7 +566,7 @@ class OpenIDPlugin extends Plugin
      *
      * @return boolean hook value
      */
-    function onEndAdminPanelNav($nav)
+    function onEndAdminPanelNav(Menu $nav)
     {
         if (AdminPanelAction::canAdmin('openid')) {
 
index 5182e50778736d2325f3e6a20de29bfcf8ae07df..0661f2acfa11887b440011c0da21f9113f675c21 100644 (file)
@@ -58,7 +58,7 @@ class FinishaddopenidAction extends Action
      *
      * @return void
      */
-    function handle($args)
+    function handle(array $args=array())
     {
         parent::handle($args);
         if (!common_logged_in()) {
index 3a99988fb59093fccf76e6b064ab35482abdae26..090ef8d45054963ba3de0019ff63c1047a4fe356 100644 (file)
@@ -29,7 +29,7 @@ class FinishopenidloginAction extends Action
     var $username = null;
     var $message = null;
 
-    function handle($args)
+    function handle(array $args=array())
     {
         parent::handle($args);
         if (common_is_real_login()) {
@@ -271,16 +271,18 @@ class FinishopenidloginAction extends Action
 
             $user = oid_get_user($canonical);
 
-            if ($user) {
+            if ($user instanceof User) {
                 oid_set_last($display);
                 // XXX: commented out at @edd's request until better
                 // control over how data flows from OpenID provider.
                 // oid_update_user($user, $sreg);
                 common_set_user($user);
                 common_real_login(true);
+
                 if (isset($_SESSION['openid_rememberme']) && $_SESSION['openid_rememberme']) {
                     common_rememberme($user);
                 }
+
                 unset($_SESSION['openid_rememberme']);
                 $this->goHome($user->nickname);
             } else {
index 86ebcae2e1d26335944938d1b1a20afb73d777a5..1728ff7d0120a6e904455518e0e36127a78f2c23 100644 (file)
@@ -25,7 +25,7 @@ require_once INSTALLDIR.'/plugins/OpenID/openid.php';
 
 class OpenidloginAction extends Action
 {
-    function handle($args)
+    function handle(array $args=array())
     {
         parent::handle($args);
         if (common_is_real_login()) {
index b50a9129d72cb1da03e0c8fe75f8b7d914f7a648..512dc37467c78bad44ed3da3c9c2275f5b983966 100644 (file)
@@ -50,14 +50,14 @@ class OpenidserverAction extends Action
 {
     var $oserver;
 
-    function prepare($args)
+    function prepare(array $args=array())
     {
         parent::prepare($args);
         $this->oserver = oid_server();
         return true;
     }
 
-    function handle($args)
+    function handle(array $args=array())
     {
         parent::handle($args);
         $request = $this->oserver->decodeRequest();
index 3f8a3a93b77afb73b0e6d3457684172cbda11b2f..1c09be85d9cef225f0e1f74f18c1eecce96fb96d 100644 (file)
@@ -35,7 +35,7 @@ class OpenidtrustAction extends Action
      *
      * @return boolean false
      */
-    function isReadOnly($args)
+    function isReadOnly(array $args=array())
     {
         return false;
     }
@@ -51,7 +51,7 @@ class OpenidtrustAction extends Action
         return _m('OpenID Identity Verification');
     }
 
-    function prepare($args)
+    function prepare(array $args=array())
     {
         parent::prepare($args);
         common_ensure_session();
@@ -71,7 +71,7 @@ class OpenidtrustAction extends Action
         return true;
     }
 
-    function handle($args)
+    function handle(array $args=array())
     {
         parent::handle($args);
         if($_SERVER['REQUEST_METHOD'] == 'POST'){
index 25801e7861cb1d3798f26141e6d5128890021100..eaeb84147db9474fe9a716e73a2150b7fa8e471b 100644 (file)
@@ -53,7 +53,7 @@ class PublicxrdsAction extends Action
      *
      * @return boolean true
      */
-    function isReadOnly($args)
+    function isReadOnly(array $args=array())
     {
         return true;
     }
index ee854e8140e274433b6decd6e08be0f15e576277..403bf7e9da2880912ea2d42979a4ea706240575b 100644 (file)
@@ -346,7 +346,7 @@ function oid_check_teams($response)
 
         $match = in_array($requiredTeam, $teams);
         $is = $match ? 'is' : 'is not';
-        common_log(LOG_DEBUG, "Remote user $is in required team $requiredTeam: [" . implode(', ', $teams) . "]");
+        common_debug("Remote user $is in required team $requiredTeam: [" . implode(', ', $teams) . "]");
 
         return $match;
     }
@@ -359,7 +359,7 @@ class AutosubmitAction extends Action
     var $form_html = null;
     var $form_id = null;
 
-    function handle($args)
+    function handle(array $args=array())
     {
         parent::handle($args);
         $this->showPage();
index 8d80197be35aeed6e7933a07ad5e244d2e232264..1d2b9d53e823be18b5aa64086f12caea2c957b3b 100644 (file)
@@ -173,7 +173,7 @@ ENDOFSCRIPT;
         return true;
     }
 
-    function onRouterInitialized($m)
+    function onRouterInitialized(URLMapper $m)
     {
         $m->connect('panel/openx',
                     array('action' => 'openxadminpanel'));
@@ -181,7 +181,7 @@ ENDOFSCRIPT;
         return true;
     }
 
-    function onEndAdminPanelNav($menu) {
+    function onEndAdminPanelNav(Menu $menu) {
         if (AdminPanelAction::canAdmin('openx')) {
             // TRANS: Menu item title.
             $menu_title = _m('OpenX configuration.');
index 0b57fb4ccc222e047f56a3644a3ed2c73e8be2fc..fdd484caefff0b5264c24940cb65b79ca9eb3bf9 100644 (file)
@@ -1,11 +1,37 @@
 <?php
+/**
+ * StatusNet - the distributed open-source microblogging tool
+ * Copyright (C) 2011, StatusNet, Inc.
+ *
+ * PHP version 5
+ *
+ * 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  OpportunisticQMPlugin
+ * @package   StatusNet
+ * @author    Brion Vibber <brion@status.net>
+ * @copyright 2011 StatusNet, Inc.
+ * @license   http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0
+ * @link      http://status.net/
+ */
 
 class OpportunisticQMPlugin extends Plugin {
     public $qmkey = false;
     public $secs_per_action = 1; // total seconds to run script per action
     public $rel_to_pageload = true;  // relative to pageload or queue start
 
-    public function onRouterInitialized($m)
+    public function onRouterInitialized(URLMapper $m)
     {
         $m->connect('main/runqueue', array('action' => 'runqueue'));
     }
index b2dc61e15fe8bf66ecf1741c00825bf7a50efe25..f29a4f7df73f5be0c5e7e606b6aff508cf18101f 100644 (file)
@@ -106,6 +106,7 @@ class OpportunisticQueueManager extends DBQueueManager
             try {
                 $this->poll();
             } catch (RunQueueOutOfWorkException $e) {
+                common_debug('Opportunistic queue manager finished: ' . $e->getMessage());
                 return true;
             }
         }
index fa5894a8f5386e6750675878b4967c84cdbe598f..59ef822cb26c1cae6fbc6e03db21d7afd4526d92 100644 (file)
@@ -76,7 +76,7 @@ class PiwikAnalyticsPlugin extends Plugin
      *
      * @return boolean ignored
      */
-    function onEndShowScripts($action)
+    function onEndShowScripts(Action $action)
     {
         // Slight modification to the default code.
         // Loading the piwik.js file from a <script> created in a document.write
index 53a491ef4776918d27ae6db14848bcc95d06c37e..64b254e41866793cbfded262c62d3c46644b083b 100644 (file)
@@ -77,7 +77,7 @@ class PollPlugin extends MicroAppPlugin
      *
      * @return boolean hook value
      */
-    function onEndShowStyles($action)
+    function onEndShowStyles(Action $action)
     {
         $action->cssLink($this->path('css/poll.css'));
         return true;
@@ -167,9 +167,9 @@ class PollPlugin extends MicroAppPlugin
     function saveNoticeFromActivity(Activity $activity, Profile $profile, array $options=array())
     {
         // @fixme
-        common_log(LOG_DEBUG, "XXX activity: " . var_export($activity, true));
-        common_log(LOG_DEBUG, "XXX profile: " . var_export($profile, true));
-        common_log(LOG_DEBUG, "XXX options: " . var_export($options, true));
+        common_debug("XXX activity: " . var_export($activity, true));
+        common_debug("XXX profile: " . var_export($profile, true));
+        common_debug("XXX options: " . var_export($options, true));
 
         // Ok for now, we can grab stuff from the XML entry directly.
         // This won't work when reading from JSON source
@@ -189,10 +189,10 @@ class PollPlugin extends MicroAppPlugin
                 }
                 try {
                     $notice = Poll::saveNew($profile, $question, $opts, $options);
-                    common_log(LOG_DEBUG, "Saved Poll from ActivityStream data ok: notice id " . $notice->id);
+                    common_debug("Saved Poll from ActivityStream data ok: notice id " . $notice->id);
                     return $notice;
                 } catch (Exception $e) {
-                    common_log(LOG_DEBUG, "Poll save from ActivityStream data failed: " . $e->getMessage());
+                    common_debug("Poll save from ActivityStream data failed: " . $e->getMessage());
                 }
             } else if ($responseElements->length) {
                 $data = $responseElements->item(0);
@@ -210,13 +210,13 @@ class PollPlugin extends MicroAppPlugin
                 }
                 try {
                     $notice = Poll_response::saveNew($profile, $poll, $selection, $options);
-                    common_log(LOG_DEBUG, "Saved Poll_response ok, notice id: " . $notice->id);
+                    common_debug("Saved Poll_response ok, notice id: " . $notice->id);
                     return $notice;
                 } catch (Exception $e) {
-                    common_log(LOG_DEBUG, "Poll response  save fail: " . $e->getMessage());
+                    common_debug("Poll response  save fail: " . $e->getMessage());
                 }
             } else {
-                common_log(LOG_DEBUG, "YYY no poll data");
+                common_debug("YYY no poll data");
             }
         }
     }
@@ -343,7 +343,7 @@ class PollPlugin extends MicroAppPlugin
      */
     public function activityObjectOutputJson(ActivityObject $obj, array &$out)
     {
-        common_log(LOG_DEBUG, 'QQQ: ' . var_export($obj, true));
+        common_debug('QQQ: ' . var_export($obj, true));
         if (isset($obj->pollQuestion)) {
             /**
              * "poll": {
index b097553498e449e15f8a57896ee577f027581edf..09d6765fbac74e62fbed816c477708e0f4a430e2 100644 (file)
@@ -217,7 +217,7 @@ class NewPollAction extends Action
      *
      * @return boolean is read only action?
      */
-    function isReadOnly($args)
+    function isReadOnly(array $args=array())
     {
         if ($_SERVER['REQUEST_METHOD'] == 'GET' ||
             $_SERVER['REQUEST_METHOD'] == 'HEAD') {
index 02aec678304b0de15d64b5868f76841d69c44664..c78038478daae2244a9d4a24852d49a9d5b1639d 100644 (file)
@@ -186,7 +186,7 @@ class RespondPollAction extends Action
      *
      * @return boolean is read only action?
      */
-    function isReadOnly($args)
+    function isReadOnly(array $args=array())
     {
         if ($_SERVER['REQUEST_METHOD'] == 'GET' ||
             $_SERVER['REQUEST_METHOD'] == 'HEAD') {
index 59161704a9dd1def3e7c8d88323bd98fbce636ed..1296733c99c9b1fa0f96291526dec3cbc305bdc2 100644 (file)
@@ -82,7 +82,7 @@ class Poll extends Managed_DataObject
      *
      * @return Poll found poll or null
      */
-    static function getByNotice($notice)
+    static function getByNotice(Notice $notice)
     {
         return self::getKV('uri', $notice->uri);
     }
@@ -167,12 +167,8 @@ class Poll extends Managed_DataObject
      *
      * @return Notice saved notice
      */
-    static function saveNew($profile, $question, $opts, $options=null)
+    static function saveNew(Profile $profile, $question, $opts, array $options = array())
     {
-        if (empty($options)) {
-            $options = array();
-        }
-
         $p = new Poll();
 
         $p->id          = UUID::gen();
@@ -193,7 +189,7 @@ class Poll extends Managed_DataObject
                                         array('id' => $p->id));
         }
 
-        common_log(LOG_DEBUG, "Saving poll: $p->id $p->uri");
+        common_debug("Saving poll: $p->id $p->uri");
         $p->insert();
 
         // TRANS: Notice content creating a poll.
index 78aec7ea0513c5818c6c0b570522edd1464a7805..0a828bf46908d29f570b6f21da9b2abe91f1e8cc 100644 (file)
@@ -85,7 +85,7 @@ class Poll_response extends Managed_DataObject
      *
      * @return Poll_response found response or null
      */
-    static function getByNotice($notice)
+    static function getByNotice(Notice $notice)
     {
         return self::getKV('uri', $notice->uri);
     }
@@ -123,12 +123,8 @@ class Poll_response extends Managed_DataObject
      *
      * @return Notice saved notice
      */
-    static function saveNew($profile, $poll, $selection, $options=null)
+    static function saveNew(Profile $profile, $poll, $selection, array $options=array())
     {
-        if (empty($options)) {
-            $options = array();
-        }
-
         if (!$poll->isValidSelection($selection)) {
             // TRANS: Client exception thrown when responding to a poll with an invalid option.
             throw new ClientException(_m('Invalid poll selection.'));
@@ -155,7 +151,7 @@ class Poll_response extends Managed_DataObject
                                         array('id' => $pr->id));
         }
 
-        common_log(LOG_DEBUG, "Saving poll response: $pr->id $pr->uri");
+        common_debug("Saving poll response: $pr->id $pr->uri");
         $pr->insert();
 
         // TRANS: Notice content voting for a poll.
index 120feee8fe0c88c92260d683ad44f3822a910cd3..72492deacac968b14b304d394a3a39211bba2ccb 100644 (file)
@@ -40,7 +40,7 @@ class PostDebugPlugin extends Plugin
      */
     public $dir=false;
 
-    public function onArgsInitialize(&$args)
+    public function onArgsInitialize(array &$args)
     {
         if (isset($_SERVER['REQUEST_METHOD']) &&
             $_SERVER['REQUEST_METHOD'] == 'POST') {
@@ -81,7 +81,7 @@ class PostDebugPlugin extends Plugin
             $file = $this->dir . DIRECTORY_SEPARATOR . $this->logFileName();
             file_put_contents($file, $output);
         } else {
-            common_log(LOG_DEBUG, "PostDebug: $output");
+            common_debug("PostDebug: $output");
         }
     }
 
index 0e23a5f64eeda27abc9813bd1492ddd47a75f508..3a3e767e43df2f58805eb4124a8cdc8a0818a876 100644 (file)
@@ -51,6 +51,7 @@ class PtitUrlPlugin extends UrlShortenerPlugin
         @$dom->loadHTML($response);
         $y = @simplexml_import_dom($dom);
         if (!isset($y->body)) return;
+        // @TODO Super-ugly style???
         $xml = $y->body->center->table->tr->td->pre->a->attributes();
         if (isset($xml['href'])) {
             return strval($xml['href']);
index e8c983eb9ae5d2c0bfae6c5433c43716703536ad..2c28bf6055483bef7e6468ba4e85e7ef3469b83a 100644 (file)
@@ -423,28 +423,28 @@ class QnAPlugin extends MicroAppPlugin
     {
         switch ($notice->object_type) {
         case QnA_Question::OBJECT_TYPE:
-            common_log(LOG_DEBUG, "Deleting question from notice...");
+            common_debug("Deleting question from notice...");
             $question = QnA_Question::fromNotice($notice);
             $question->delete();
             break;
         case QnA_Answer::OBJECT_TYPE:
-            common_log(LOG_DEBUG, "Deleting answer from notice...");
+            common_debug("Deleting answer from notice...");
             $answer = QnA_Answer::fromNotice($notice);
-            common_log(LOG_DEBUG, "to delete: $answer->id");
+            common_debug("to delete: $answer->id");
             $answer->delete();
             break;
         default:
-            common_log(LOG_DEBUG, "Not deleting related, wtf...");
+            common_debug("Not deleting related, wtf...");
         }
     }
 
-    function onEndShowScripts($action)
+    function onEndShowScripts(Action $action)
     {
         $action->script($this->path('js/qna.js'));
         return true;
     }
 
-    function onEndShowStyles($action)
+    function onEndShowStyles(Action $action)
     {
         $action->cssLink($this->path('css/qna.css'));
         return true;
index 5c5e0f846757b1a046404e870565fda533088cd1..2cafde91fc9f14939917010305a5eb43ed18b15a 100644 (file)
@@ -185,7 +185,7 @@ class QnaclosequestionAction extends Action
      *
      * @return boolean is read only action?
      */
-    function isReadOnly($args)
+    function isReadOnly(array $args=array())
     {
         if ($_SERVER['REQUEST_METHOD'] == 'GET' ||
             $_SERVER['REQUEST_METHOD'] == 'HEAD') {
index 0cdaa62f1935ac5c7e7f7d1fe466ffe89f9d748d..5543cba06c623dbff942744d3401abcff7b8e6b2 100644 (file)
@@ -197,7 +197,7 @@ class QnanewanswerAction extends Action
      *
      * @return boolean is read only action?
      */
-    function isReadOnly($args)
+    function isReadOnly(array $args=array())
     {
         if ($_SERVER['REQUEST_METHOD'] == 'GET' ||
             $_SERVER['REQUEST_METHOD'] == 'HEAD') {
index 79ef3a6eb05c99d334d169899f4fdc81d79550c6..24a91f69c957fc975bfb364c3781b1bbd691cf8d 100644 (file)
@@ -208,7 +208,7 @@ class QnanewquestionAction extends Action
      *
      * @return boolean is read only action?
      */
-    function isReadOnly($args)
+    function isReadOnly(array $args=array())
     {
         if ($_SERVER['REQUEST_METHOD'] == 'GET' ||
             $_SERVER['REQUEST_METHOD'] == 'HEAD') {
index ae9644a7e0a94454a12772247bdbf96297919324..92fcfd8c92997afbfc236caf650c284ab82daaa0 100644 (file)
@@ -256,7 +256,7 @@ class QnareviseanswerAction extends Action
      *
      * @return boolean is read only action?
      */
-    function isReadOnly($args)
+    function isReadOnly(array $args=array())
     {
         if ($_SERVER['REQUEST_METHOD'] == 'GET' ||
             $_SERVER['REQUEST_METHOD'] == 'HEAD') {
index 5531b3124bdfe4f8fd2d3dbc05e36cdf88ebcd81..00395d82e50f418528559537ce04ba61cbd97d2f 100644 (file)
@@ -184,7 +184,7 @@ class Qnavote extends Action
      *
      * @return boolean is read only action?
      */
-    function isReadOnly($args)
+    function isReadOnly(array $args=array())
     {
         if ($_SERVER['REQUEST_METHOD'] == 'GET' ||
             $_SERVER['REQUEST_METHOD'] == 'HEAD') {
index 2aa69cf5a301aab87e845402d7647cf8e040e804..d04159f9b9375e529240ffdb49d71ed331c7830c 100644 (file)
@@ -105,7 +105,7 @@ class QnA_Answer extends Managed_DataObject
      *
      * @return QnA_Answer found response or null
      */
-    static function getByNotice($notice)
+    static function getByNotice(Notice $notice)
     {
         $answer = self::getKV('uri', $notice->uri);
         if (empty($answer)) {
@@ -124,7 +124,7 @@ class QnA_Answer extends Managed_DataObject
         return Notice::getKV('uri', $this->uri);
     }
 
-    static function fromNotice($notice)
+    static function fromNotice(Notice $notice)
     {
         return QnA_Answer::getKV('uri', $notice->uri);
     }
@@ -179,7 +179,7 @@ class QnA_Answer extends Managed_DataObject
         );
     }
 
-    static function toHTML($profile, $question, $answer)
+    static function toHTML(Profile $profile, $question, $answer)
     {
         $notice = $question->getNotice();
 
@@ -237,12 +237,8 @@ class QnA_Answer extends Managed_DataObject
      *
      * @return Notice saved notice
      */
-    static function saveNew($profile, $question, $text, $options = null)
+    static function saveNew(Profile $profile, $question, $text, array $options = array())
     {
-        if (empty($options)) {
-            $options = array();
-        }
-
         $answer              = new QnA_Answer();
         $answer->id          = UUID::gen();
         $answer->profile_id  = $profile->id;
@@ -256,7 +252,7 @@ class QnA_Answer extends Managed_DataObject
             array('id' => $answer->id)
         );
 
-        common_log(LOG_DEBUG, "Saving answer: $answer->id, $answer->uri");
+        common_debug("Saving answer: $answer->id, $answer->uri");
         $answer->insert();
 
         $content  = sprintf(
index b5318386777b50dcd2569007bde40303565fa7ad..079f09fb6bf46143383d64a343a1f37ba93ba8e6 100644 (file)
@@ -97,7 +97,7 @@ class QnA_Question extends Managed_DataObject
      *
      * @return Question found question or null
      */
-    static function getByNotice($notice)
+    static function getByNotice(Notice $notice)
     {
         return self::getKV('uri', $notice->uri);
     }
@@ -164,7 +164,7 @@ class QnA_Question extends Managed_DataObject
         return $a->count();
     }
 
-    static function fromNotice($notice)
+    static function fromNotice(Notice $notice)
     {
         return QnA_Question::getKV('uri', $notice->uri);
     }
@@ -179,7 +179,7 @@ class QnA_Question extends Managed_DataObject
         return self::toString($this->getProfile(), $this);
     }
 
-    static function toHTML($profile, $question)
+    static function toHTML(Profile $profile, $question)
     {
         $notice = $question->getNotice();
 
@@ -237,7 +237,7 @@ class QnA_Question extends Managed_DataObject
      *
      * @return Notice saved notice
      */
-    static function saveNew($profile, $title, $description, $options = array())
+    static function saveNew(Profile $profile, $title, $description, array $options = array())
     {
         $q = new QnA_Question();
 
@@ -261,7 +261,7 @@ class QnA_Question extends Managed_DataObject
             );
         }
 
-        common_log(LOG_DEBUG, "Saving question: $q->id $q->uri");
+        common_debug("Saving question: $q->id $q->uri");
         $q->insert();
 
         if (Notice::contentTooLong($q->title . ' ' . $q->uri)) {
index 13679acd2c8c878aa3b6271108fbb12434e33f35..9bed5b15b3439e5742662bc1dd8aa5ba3c314fe0 100644 (file)
@@ -120,7 +120,7 @@ class QnA_Vote extends Managed_DataObject
         $v->vote        = $vote;
         $v->created     = common_sql_now();
 
-        common_log(LOG_DEBUG, "Saving vote: $v->id $v->vote");
+        common_debug("Saving vote: $v->id $v->vote");
 
         $v->insert();
     }
index eca01879822d2a03af8f282012ed0c684e3395ee..760c38905105542be66132cb5e843949dd032255 100644 (file)
@@ -56,7 +56,7 @@ class QnanewquestionForm extends Form
      *
      * @return void
      */
-    function __construct($out = null, $title = null, $description = null, $options = null)
+    function __construct($out = null, $title = null, $description = null, array $options = array())
     {
         parent::__construct($out);
         $this->title       = $title;
index 0fff0947a288020217dd4c9d56fd39013ed312e6..15a25c8d22a893d99a2a50f11803ddaa9277b7ba 100644 (file)
@@ -102,7 +102,7 @@ class RSSCloudPlugin extends Plugin
      *
      * @return boolean hook return
      */
-    function onRouterInitialized($m)
+    function onRouterInitialized(URLMapper $m)
     {
         $m->connect('/main/rsscloud/request_notify',
                     array('action' => 'RSSCloudRequestNotify'));
@@ -153,7 +153,7 @@ class RSSCloudPlugin extends Plugin
      * @return boolean hook return
      */
 
-    function onStartEnqueueNotice($notice, &$transports)
+    function onStartEnqueueNotice(Notice $notice, array &$transports)
     {
         if ($notice->isLocal()) {
             array_push($transports, 'rsscloud');
@@ -192,7 +192,7 @@ class RSSCloudPlugin extends Plugin
      *
      * @return boolean hook return
      */
-    function onEndInitializeQueueManager($manager)
+    function onEndInitializeQueueManager(QueueManager $manager)
     {
         $manager->connect('rsscloud', 'RSSCloudQueueHandler');
         return true;
index 824fa9ee9c7d678fe50f65b0d28a40209c282f4f..7dc6252af887cee5cc99c70cd466969b1659bdc7 100644 (file)
@@ -57,7 +57,7 @@ class LoggingAggregatorAction extends Action
      *
      * @return boolean false if user doesn't exist
      */
-    function prepare($args)
+    function prepare(array $args=array())
     {
         parent::prepare($args);
 
@@ -77,7 +77,7 @@ class LoggingAggregatorAction extends Action
      *
      * @return void
      */
-    function handle($args)
+    function handle(array $args=array())
     {
         parent::handle($args);
 
index 7fd6da05098bc401f9073812ca372dbcd6f0df76..91b01e21d9ee4eb6deba692053d7f16c71a88603 100644 (file)
@@ -50,7 +50,7 @@ class RSSCloudRequestNotifyAction extends Action
      *
      * @return boolean false if user doesn't exist
      */
-    function prepare($args)
+    function prepare(array $args=array())
     {
         parent::prepare($args);
 
@@ -82,7 +82,7 @@ class RSSCloudRequestNotifyAction extends Action
      *
      * @return void
      */
-    function handle($args)
+    function handle(array $args=array())
     {
         parent::handle($args);
 
index fbfb0aae306d3460878557e2004e1be6f0b902f5..bf847acca3ea487ca471a775c7c9b117a0bd62ab 100644 (file)
@@ -85,7 +85,7 @@ class RealtimePlugin extends Plugin
         return true;
     }
 
-    function onEndShowScripts($action)
+    function onEndShowScripts(Action $action)
     {
         $channel = $this->_getChannel($action);
 
@@ -311,7 +311,7 @@ class RealtimePlugin extends Plugin
         return false; // No default processing
     }
 
-    function noticeAsJson($notice)
+    function noticeAsJson(Notice $notice)
     {
         // FIXME: this code should be abstracted to a neutral third
         // party, like Notice::asJson(). I'm not sure of the ethics
@@ -347,7 +347,7 @@ class RealtimePlugin extends Plugin
         return $arr;
     }
 
-    function getNoticeTags($notice)
+    function getNoticeTags(Notice $notice)
     {
         $tags = null;
 
@@ -382,7 +382,7 @@ class RealtimePlugin extends Plugin
      *
      * @return boolean hook return value
      */
-    function onEndScriptMessages($action, &$messages)
+    function onEndScriptMessages(Action $action, &$messages)
     {
         // TRANS: Text label for realtime view "play" button, usually replaced by an icon.
         $messages['realtime_play'] = _m('BUTTON', 'Play');
index ee092ce2bc45e38674d47409b1d447397d2dac7c..5439db9ed65b4a9c6b8a796d2993896af5e4c927 100644 (file)
@@ -104,10 +104,9 @@ class ClosechannelAction extends Action
      * MAY override
      *
      * @param array $args other arguments
-     *
      * @return boolean is read only action?
      */
-    function isReadOnly($args)
+    function isReadOnly(array $args=array())
     {
         return false;
     }
index e9319ed916e5b99899e8b27a7477f10939a618bf..72618001f3c86842e3b89aecfc33ffaa546cebe2 100644 (file)
@@ -104,10 +104,9 @@ class KeepalivechannelAction extends Action
      * MAY override
      *
      * @param array $args other arguments
-     *
      * @return boolean is read only action?
      */
-    function isReadOnly($args)
+    function isReadOnly(array $args=array())
     {
         return false;
     }
index 37883b1da65d41f013273b5f8cdc355432b64baa..b6035bfac56227814ffb7d0e3b8945577b8a861c 100755 (executable)
@@ -33,7 +33,7 @@ Garbage-collects old realtime channels
 
 END_OF_CLEANUPCHANNELS_HELP;
 
-require_once INSTALLDIR.'/scripts/commandline.inc';
+require_once INSTALLDIR.'/scripts/commandline.inc.php';
 
 function cleanupChannels()
 {
index c039dd5350148f80ccc46b406bf6e58d6ab563ec..f205b4c15ac0ce8fc73f2c81d7a807fe38be4e7d 100644 (file)
@@ -67,7 +67,7 @@ class RecaptchaPlugin extends Plugin
         return true;
     }
 
-    function onEndShowScripts($action)
+    function onEndShowScripts(Action $action)
     {
         if (isset($action->recaptchaPluginNeedsOutput) && $action->recaptchaPluginNeedsOutput) {
             // Load the AJAX API
@@ -85,7 +85,17 @@ class RecaptchaPlugin extends Plugin
         return true;
     }
 
-    function onStartRegistrationTry($action)
+    /**
+     * Called when someone tries to register.
+     *
+     * We check the IP here to determine if it goes over any of our
+     * configured limits.
+     *
+     * @param Action $action Action that is being executed
+     *
+     * @return boolean hook value
+     */
+    function onStartRegistrationTry(Action $action)
     {
         $resp = recaptcha_check_answer ($this->private_key,
                                         $_SERVER["REMOTE_ADDR"],
index 9d3be3b8a26bdea267a036133e3cce4b0973e090..d09642a6330872d0206d5a00406674c87ae4a3ee 100644 (file)
@@ -91,7 +91,7 @@ class RegisterThrottlePlugin extends Plugin
      *
      * @return boolean hook value
      */
-    public function onStartRegistrationTry($action)
+    public function onStartRegistrationTry(Action $action)
     {
         $ipaddress = $this->_getIpAddress();
 
@@ -241,7 +241,7 @@ class RegisterThrottlePlugin extends Plugin
      *
      * @return boolean hook value
      */
-    public function onEndGrantRole($profile, $role)
+    public function onEndGrantRole(Profile $profile, $role)
     {
         if (!self::$enabled) {
             return true;
index 734cabbcd5182169b5eee61086637bb55e9e0f79..b3ae574f16e752fcae9d4bc1409529eff16e3997 100644 (file)
@@ -119,7 +119,7 @@ class RequireValidatedEmailPlugin extends Plugin
      *
      * @return bool hook result code
      */
-    function onStartRegisterUser(&$user, &$profile)
+    function onStartRegisterUser(User &$user, Profile &$profile)
     {
         $email = $user->email;
 
index 4d2000ab0fe714903549880f040c1f97dc77cad0..6935e00ee5ff192073faf1faf3c99ba6ed5a1a5e 100755 (executable)
@@ -30,7 +30,7 @@ Registers a new user by email address and sends a confirmation email
 
 END_OF_REGISTERBYEMAIL_HELP;
 
-require_once INSTALLDIR.'/scripts/commandline.inc';
+require_once INSTALLDIR.'/scripts/commandline.inc.php';
 
 $email = get_option_value('e', 'email');
 
index a7912844c2421436b9f413ecc1a9fad44ea90e5b..bacb1f2a95cf95c6f08ee6c6cd7f9d69bb5824e9 100644 (file)
@@ -58,7 +58,7 @@ class SQLProfilePlugin extends Plugin
                         (strpos($extra, 'Using temporary') !== false);
                 if ($evil) {
                     $xquery = $xobj->sanitizeQuery($query);
-                    common_log(LOG_DEBUG, "$extra | $xquery");
+                    common_debug("$extra | $xquery");
                 }
             }
         }
index da5682b332a0b4e6eadace042f393b725a049df5..70e8ec10a7ae56f89dd3350488167100509dcc26 100644 (file)
@@ -66,7 +66,7 @@ class HelloAction extends Action
      *
      * @return boolean success flag
      */
-    function prepare($args)
+    function prepare(array $args=array())
     {
         parent::prepare($args);
 
@@ -91,7 +91,7 @@ class HelloAction extends Action
      *
      * @return void
      */
-    function handle($args)
+    function handle(array $args=array())
     {
         parent::handle($args);
 
@@ -163,7 +163,7 @@ class HelloAction extends Action
      *
      * @return boolean is read only action?
      */
-    function isReadOnly($args)
+    function isReadOnly(array $args=array())
     {
         return false;
     }
diff --git a/plugins/Scroller b/plugins/Scroller
new file mode 120000 (symlink)
index 0000000..36eee26
--- /dev/null
@@ -0,0 +1 @@
+../scroller_plugin/
\ No newline at end of file
index 57984d0e01b03e2dea8ea000e6a1ae11890683cb..4c8d2121047fd528a8f6006dc8aaf8843d66067f 100644 (file)
@@ -165,7 +165,8 @@ class SearchSubPlugin extends Plugin
     function onStartNoticeSearchShowResults($action, $q, $notice)
     {
         $user = common_current_user();
-        if ($user) {
+
+        if ($user instanceof User) {
             $search = $q;
             $searchsub = SearchSub::pkeyGet(array('search' => $search,
                                                   'profile_id' => $user->id));
@@ -174,6 +175,7 @@ class SearchSubPlugin extends Plugin
             } else {
                 $form = new SearchSubForm($action, $search);
             }
+
             $action->elementStart('div', 'entity_actions');
             $action->elementStart('ul');
             $action->elementStart('li', 'entity_subscribe');
@@ -182,6 +184,7 @@ class SearchSubPlugin extends Plugin
             $action->elementEnd('ul');
             $action->elementEnd('div');
         }
+
         return true;
     }
 
index 586f2252f67a70bcdb269d9033da9675d377357d..de43da3aa7583a2a28ddfebfcc89b25ef820c8a6 100644 (file)
@@ -63,7 +63,7 @@ class SearchsubAction extends Action
      *
      * @return boolean success flag
      */
-    function prepare($args)
+    function prepare(array $args=array())
     {
         parent::prepare($args);
         if ($this->boolean('ajax')) {
@@ -118,7 +118,7 @@ class SearchsubAction extends Action
      *
      * @return void
      */
-    function handle($args)
+    function handle(array $args=array())
     {
         // Throws exception on error
 
index fd89075032eedbe862499e173baa5fd2a81e7c78..7e6aa1784e437022a600eb32330a8c437733aee9 100644 (file)
@@ -136,7 +136,7 @@ class SearchSubsAction extends GalleryAction
 
 class SearchSubscriptionsList extends SubscriptionList
 {
-    function newListItem($searchsub)
+    function newListItem(SearchSub $searchsub)
     {
         return new SearchSubscriptionsListItem($searchsub, $this->owner, $this->action);
     }
index a6ce0f07c5b9e0e681e0da9e39bc42c8b7cb03f3..8e135e62fa26adfad9fb7ca2386c082929ccc659 100644 (file)
@@ -62,7 +62,7 @@ class SearchunsubAction extends SearchsubAction
      *
      * @return void
      */
-    function handle($args)
+    function handle(array $args=array())
     {
         // Throws exception on error
 
index f3a44854b2730ed81870152772c5f73bea8cac32..0d5828695b18217b6ddcdaaddc3af168972def70 100644 (file)
@@ -91,6 +91,18 @@ class SearchSub extends Managed_DataObject
         return $ts;
     }
 
+    /**
+     * Getter for Profile instance
+     *
+     * @return $profile        Profile instance
+     */
+    public function getProfile () {
+        assert($this->profile_id > 0);
+        $profile = new Profile();
+        $profile->id = $this->profile_id;
+        return $profile;
+    }
+
     /**
      * End a search subscription!
      *
index 7af4cd3ec6649959832917de0019e43188df2ee0..82e86b9264689c453f6ddd56c8f3c050de8feaa3 100644 (file)
@@ -54,7 +54,7 @@ class ApiStatusesRetweetsAction extends ApiAuthAction
      *
      * @return boolean success flag
      */
-    function prepare($args)
+    function prepare(array $args=array())
     {
         parent::prepare($args);
 
@@ -89,7 +89,7 @@ class ApiStatusesRetweetsAction extends ApiAuthAction
      *
      * @return void
      */
-    function handle($args)
+    function handle(array $args=array())
     {
         parent::handle($args);
 
@@ -119,7 +119,7 @@ class ApiStatusesRetweetsAction extends ApiAuthAction
      * @return boolean is read only action?
      */
 
-    function isReadOnly($args)
+    function isReadOnly(array $args=array())
     {
         return true;
     }
index 01f3fe378b17bc948aadbaf587fa0774187e60e6..4ad4e269af5544bfa563e227f0547400eb979f41 100644 (file)
@@ -60,7 +60,7 @@ class ApiTimelineRetweetedByMeAction extends ApiAuthAction
      * @return boolean success flag
      *
      */
-    function prepare($args)
+    function prepare(array $args=array())
     {
         parent::prepare($args);
 
@@ -77,7 +77,7 @@ class ApiTimelineRetweetedByMeAction extends ApiAuthAction
      *
      * @return boolean is read only action?
      */
-    function isReadOnly($args)
+    function isReadOnly(array $args=array())
     {
         return true;
     }
index 92d4b358fe4168dbaf6b452c4de6b5547e16ebbe..14091eedee256cd66df8ab7b144f75e38b526a3e 100644 (file)
@@ -155,7 +155,7 @@ class ApiTimelineRetweetedToMeAction extends ApiAuthAction
      *
      * @return boolean is read only action?
      */
-    function isReadOnly($args)
+    function isReadOnly(array $args=array())
     {
         return true;
     }
index fe90213665074e7e6b4e430946c22200c4c6925e..49990a53358acf17a7f56bf5434a16d2c373135c 100644 (file)
@@ -59,7 +59,7 @@ class ApiTimelineRetweetsOfMeAction extends ApiAuthAction
      *
      * @return boolean success flag
      */
-    function prepare($args)
+    function prepare(array $args=array())
     {
         parent::prepare($args);
 
@@ -83,7 +83,7 @@ class ApiTimelineRetweetsOfMeAction extends ApiAuthAction
      *
      * @return void
      */
-    function handle($args)
+    function handle(array $args=array())
     {
         parent::handle($args);
 
@@ -165,7 +165,7 @@ class ApiTimelineRetweetsOfMeAction extends ApiAuthAction
      *
      * @return boolean is read only action?
      */
-    function isReadOnly($args)
+    function isReadOnly(array $args=array())
     {
         return true;
     }
index 7a6fd28feee10b5d9776611df46f3c2fc8957543..2c199efec09c2175369cc7e8a6e006171672365b 100644 (file)
@@ -37,7 +37,7 @@ class ShareNoticePlugin extends Plugin
         return true;
     }
 
-    function onStartShowNoticeItem($item)
+    function onStartShowNoticeItem(NoticeListItem $item)
     {
         $notice = $item->notice;
         $out = $item->out;
index 3131847349f80b9eb1f434001ab47b4bfa73c0d1..869a88dfc9278233485ce6ec9490a5cd9c9dd728 100644 (file)
@@ -55,7 +55,7 @@ class SiteNoticeInSidebarPlugin extends Plugin
      * @return
      */
 
-    function onStartShowSiteNotice($action)
+    function onStartShowSiteNotice(Action $action)
     {
         return false;
     }
@@ -70,7 +70,7 @@ class SiteNoticeInSidebarPlugin extends Plugin
         return true;
     }
 
-    function onEndShowStyles($action)
+    function onEndShowStyles(Action $action)
     {
         $action->element('style', null, '#site_notice { width: 100% }');
         return true;
index a1fe90b4b42e4313769735217e423b68b98f33e9..bab0d9fa9bb1ade283a28e72cc9296aca42cc0d7 100644 (file)
@@ -154,7 +154,7 @@ class SitemapPlugin extends Plugin
         return true;
     }
 
-    function onEndAdminPanelNav($menu) {
+    function onEndAdminPanelNav(Menu $menu) {
         if (AdminPanelAction::canAdmin('sitemap')) {
             // TRANS: Menu item title/tooltip
             $menu_title = _m('Sitemap configuration');
index efa23b94010e27589c92725faaa13f8083f9a789..d91dc4fc5689d2cdc15209d48fc04daa41b9d09f 100644 (file)
@@ -45,7 +45,7 @@ class NoticesitemapAction extends SitemapAction
     var $notices = null;
     var $j = 0;
 
-    function prepare($args)
+    function prepare(array $args=array())
     {
         parent::prepare($args);
 
index ef77645c3166133aeeff59eddfd43574d0a7c2e1..6401f8f311c2c597a31fdbb10d658fdbac5f1c65 100644 (file)
@@ -49,7 +49,7 @@ class SitemapAction extends Action
      *
      * @return void
      */
-    function handle($args)
+    function handle(array $args=array())
     {
         parent::handle($args);
 
index ab89c2156c936afd18b52f6ea5b64502bd6b80e0..e18c7d6ac5a446dcf1915035dbf1d16a80d5592c 100644 (file)
@@ -49,7 +49,7 @@ class SitemapindexAction extends Action
      *
      * @return void
      */
-    function handle($args)
+    function handle(array $args=array())
     {
         header('Content-Type: text/xml; charset=UTF-8');
         $this->startXML();
index c39165d0edb97bf34f6a628a1ca21aae0a2b2795..eea79d4b1d8f82eb271299829736b2f7e13850c9 100644 (file)
@@ -45,7 +45,7 @@ class UsersitemapAction extends SitemapAction
     var $users = null;
     var $j     = 0;
 
-    function prepare($args)
+    function prepare(array $args=array())
     {
         parent::prepare($args);
 
index 91bc0ac4e9720a23532973182c7bb749a06e1bb7..744dab82876e816f023fe1cd0878873eb7855bfe 100755 (executable)
@@ -26,7 +26,7 @@ Update the notice and user counts cached in the database.
 
 END_OF_UPDATECOUNTS_HELP;
 
-require_once INSTALLDIR.'/scripts/commandline.inc';
+require_once INSTALLDIR.'/scripts/commandline.inc.php';
 
 // Will fill the cache
 
index 4e1129536db36cbc8c6d422b6956ee8823eff0f5..e8435fa05a4c423b3ab17ea22dfc60557796a876 100644 (file)
@@ -65,7 +65,7 @@ class SlicedFavoritesPlugin extends Plugin
     }
 
     // Take over the default... :D
-    function onArgsInitialize($args)
+    function onArgsInitialize(array &$args)
     {
         if (array_key_exists('action', $args)) {
             $action = trim($args['action']);
index 5c9fb31f8f97a790364d872a996b2a11e13bba27..285bfbbc67cd06a4376cbd5ed90565f8565302ed 100644 (file)
@@ -45,7 +45,7 @@ class FavoritedSliceAction extends FavoritedAction
      *
      * @todo move queries from showContent() to here
      */
-    function prepare($args)
+    function prepare(array $args=array())
     {
         parent::prepare($args);
 
@@ -121,13 +121,13 @@ class FavoritedSliceAction extends FavoritedAction
         $exclude = $this->nicknamesToIds($this->excludeUsers);
 
         if (count($include) == 1) {
-            return "profile_id = " . intval($include[0]);
+            return '`profile_id` = ' . intval($include[0]);
         } else if (count($include) > 1) {
-            return "profile_id IN (" . implode(',', $include) . ")";
+            return '`profile_id` IN (' . implode(',', $include) . ')';
         } else if (count($exclude) == 1) {
-            return "profile_id != " . intval($exclude[0]);
+            return '`profile_id` != ' . intval($exclude[0]);
         } else if (count($exclude) > 1) {
-            return "profile_id NOT IN (" . implode(',', $exclude) . ")";
+            return '`profile_id` NOT IN (' . implode(',', $exclude) . ')';
         } else {
             return false;
         }
@@ -144,7 +144,8 @@ class FavoritedSliceAction extends FavoritedAction
         foreach ($nicks as $nick) {
             // not the most efficient way for a big list!
             $user = User::getKV('nickname', $nick);
-            if ($user) {
+
+            if ($user instanceof User) {
                 $ids[] = intval($user->id);
             }
         }
index e7f397747807755a169557d3ee77441da7eb3849..000a929243cf0469a436d8ce5ba3a3f76ac9834a 100755 (executable)
@@ -32,7 +32,7 @@ Generates sphinx.conf file based on StatusNet configuration.
 
 END_OF_TRIM_HELP;
 
-require_once INSTALLDIR . '/scripts/commandline.inc';
+require_once INSTALLDIR . '/scripts/commandline.inc.php';
 require dirname(__FILE__) . '/sphinx-utils.php';
 
 
index abac5434f7d33ba1946ba49bd075bc3a5e0b891c..79d9040e0e65bd4e3da5d554bbe4406de00bfdde 100755 (executable)
@@ -34,7 +34,7 @@ Runs Sphinx search indexer.
 
 END_OF_TRIM_HELP;
 
-require_once INSTALLDIR . '/scripts/commandline.inc';
+require_once INSTALLDIR . '/scripts/commandline.inc.php';
 require dirname(__FILE__) . '/sphinx-utils.php';
 
 sphinx_iterate_sites('sphinx_index_update');
diff --git a/plugins/Spotify/SpotifyPlugin.php b/plugins/Spotify/SpotifyPlugin.php
new file mode 100644 (file)
index 0000000..2754d18
--- /dev/null
@@ -0,0 +1,119 @@
+<?php
+/**
+ * StatusNet, the distributed open-source microblogging tool
+ *
+ * Plugin to create pretty Spotify URLs
+ *
+ * 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  Plugin
+ * @package   StatusNet
+ * @author    Nick Holliday <n.g.holliday@gmail.com>
+ * @copyright Nick Holliday
+ * @license   http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
+ * @link      http://status.net/
+ *
+ * @see      Event
+ */
+if (!defined('STATUSNET')) {
+    exit(1);
+}
+define('SPOTIFYPLUGIN_VERSION', '0.1');
+
+/**
+ * Plugin to create pretty Spotify URLs
+ *
+ * The Spotify API is called before the notice is saved to gather artist and track information.
+ *
+ * @category  Plugin
+ * @package   StatusNet
+ * @author    Nick Holliday <n.g.holliday@gmail.com>
+ * @copyright Nick Holliday
+ * @license   http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
+ * @link      http://status.net/
+ *
+ * @see       Event
+ */
+class SpotifyPlugin extends Plugin
+{
+    function __construct()
+    {
+        parent::__construct();
+    }
+
+    function onStartNoticeSave(Notice $notice)
+    {
+        $notice->rendered = preg_replace_callback('/spotify:[a-z]{5,6}:[a-z0-9]{22}/i',
+                                                  "renderSpotifyURILink",
+                                                  $notice->rendered);
+
+        $notice->rendered = preg_replace_callback('/<a href="http:\/\/open.spotify.com\/[a-z]{5,6}\/[a-z0-9]{22}" title="http:\/\/open.spotify.com\/[a-z]{5,6}\/[a-z0-9]{22}" rel="external">http:\/\/open.spotify.com\/[a-z]{5,6}\/[a-z0-9]{22}<\/a>/i',
+                                                  "renderSpotifyHTTPLink",
+                                                  $notice->rendered);
+
+        return true;
+    }
+
+    function onPluginVersion(array &$versions)
+    {
+        $versions[] = array('name' => 'Spotify',
+                            'version' => SPOTIFYPLUGIN_VERSION,
+                            'author' => 'Nick Holliday',
+                            'homepage' => 'http://status.net/wiki/Plugin:Spotify',
+                            'rawdescription' =>
+                            // TRANS: Plugin description.
+                            _m('Create pretty <a href="http://www.spotify.com">Spotify</a> URLs.'));
+
+        return true;
+    }
+}
+
+// @todo FIXME: This probably should not be global functions.
+function doSpotifyLookup($uri, $isArtist)
+{
+    $request = HTTPClient::start();
+    $response = $request->get('http://ws.spotify.com/lookup/1/?uri=' . $uri);
+    if ($response->isOk()) {
+        $xml = simplexml_load_string($response->getBody());
+
+        if($isArtist)
+            return $xml->name;
+        else
+            return $xml->artist->name . ' - ' . $xml->name;
+    }
+}
+
+function renderSpotifyURILink($match)
+{
+    $isArtist = false;
+    if(preg_match('/artist/', $match[0]) > 0) $isArtist = true;
+
+    $name = doSpotifyLookup($match[0], $isArtist);
+    return "<a href=\"{$match[0]}\">" . $name . "</a>";
+}
+
+function renderSpotifyHTTPLink($match)
+{
+    $match[0] = preg_replace('/<a href="http:\/\/open.spotify.com\/[a-z]{5,6}\/[a-z0-9]{22}" title="http:\/\/open.spotify.com\/[a-z]{5,6}\/[a-z0-9]{22}" rel="external">http:\/\/open.spotify.com\//i', 'spotify:', $match[0]);
+    $match[0] = preg_replace('/<\/a>/', '', $match[0]);
+    $match[0] = preg_replace('/\//', ':', $match[0]);
+
+    $isArtist = false;
+    if(preg_match('/artist/', $match[0]) > 0) $isArtist = true;
+
+    $name = doSpotifyLookup($match[0], $isArtist);
+    return "<a href=\"{$match[0]}\">" . $name . "</a>";
+}
diff --git a/plugins/Statistics/README.md b/plugins/Statistics/README.md
new file mode 120000 (symlink)
index 0000000..e98992b
--- /dev/null
@@ -0,0 +1 @@
+../../statistics_plugin/README.md
\ No newline at end of file
diff --git a/plugins/Statistics/StatisticsPlugin.php b/plugins/Statistics/StatisticsPlugin.php
new file mode 120000 (symlink)
index 0000000..41ced2e
--- /dev/null
@@ -0,0 +1 @@
+../../statistics_plugin/StatisticsPlugin-gnusocial.php
\ No newline at end of file
diff --git a/plugins/Statistics/actions b/plugins/Statistics/actions
new file mode 120000 (symlink)
index 0000000..dd018ab
--- /dev/null
@@ -0,0 +1 @@
+../../statistics_plugin/actions/
\ No newline at end of file
index 74a643d6d939c96200dfb16da19914f8864c35f2..3d7788c71163b37eab5ce33071cd9fe5219bac36 100644 (file)
@@ -40,7 +40,7 @@ class StrictTransportSecurityPlugin extends Plugin
         parent::__construct();
     }
 
-    function onArgsInitialize($args)
+    function onArgsInitialize(array &$args)
     {
         $path = common_config('site', 'path');
         if(common_config('site', 'ssl') == 'always' && ($path == '/' || ! $path )) {
index 27fc7c984d03e65ba680723261058f61e685f1d0..60560b4afc5bc4cef2d62174736ede7f382e0e7a 100644 (file)
@@ -115,7 +115,7 @@ class SubMirrorPlugin extends Plugin
         return true;
     }
 
-    function onStartEnqueueNotice($notice, &$transports)
+    function onStartEnqueueNotice(Notice $notice, array &$transports)
     {
         $transports[] = 'mirror';
     }
@@ -155,7 +155,7 @@ class SubMirrorPlugin extends Plugin
      * @param array $stats
      * @return boolean hook return value
      */
-    function onProfileStats($profile, &$stats)
+    function onProfileStats(Profile $profile, array &$stats)
     {
         $cur = common_current_user();
         if (!empty($cur) && $cur->id == $profile->id) {
index de63841e729e84f44f712d7efaa0c3bbb5f555ba..cdbbed6726e415c2ddcbd24d18cbef7ba7a36fe6 100644 (file)
@@ -188,10 +188,11 @@ class SubMirror extends Managed_DataObject
      * Kind of dirty, but if pulling an external data feed into an account
      * that may be what you want.
      *
-     * @param Notice $notice
-     * @return mixed Notice on successful repeat, true if already repeated, false on failure
+     * @param  Profile $profile
+     * @param  Notice  $notice
+     * @return mixed   Notice on successful repeat, true if already repeated, false on failure
      */
-    protected function copyNotice($profile, $notice)
+    protected function copyNotice(Profile $profile, Notice $notice)
     {
         $options = array('is_local' => Notice::LOCAL_PUBLIC,
                          'url' => $notice->getUrl(), // pass through the foreign link...
index df692988882d25a523bcadc9263d3577ff3c487a..4affc42c3f867bc94bdfda3bcbf2b80d7feed2c6 100644 (file)
@@ -39,7 +39,7 @@ class TabFocusPlugin extends Plugin
         parent::__construct();
     }
 
-    function onEndShowScripts($action)
+    function onEndShowScripts(Action $action)
     {
         $action->script($this->path('tabfocus.js'));
     }
index f1d1ab462229d1f3209d4f4b97c45e67959bf43f..ed65665ecc6c3f7dc0d6b4fbc6fd660c9dc763e4 100644 (file)
@@ -136,7 +136,8 @@ class TagSubPlugin extends Plugin
     function onStartTagShowContent(TagAction $action)
     {
         $user = common_current_user();
-        if ($user) {
+
+        if ($user instanceof User) {
             $tag = $action->trimmed('tag');
             $tagsub = TagSub::pkeyGet(array('tag' => $tag,
                                             'profile_id' => $user->id));
@@ -153,6 +154,7 @@ class TagSubPlugin extends Plugin
             $action->elementEnd('ul');
             $action->elementEnd('div');
         }
+
         return true;
     }
 
index de333c8f58971659805094cb475fe381532ca4e2..a87081bd4c85353398fcb17299e4580e6480d708 100644 (file)
@@ -63,7 +63,7 @@ class TagsubAction extends Action
      *
      * @return boolean success flag
      */
-    function prepare($args)
+    function prepare(array $args=array())
     {
         parent::prepare($args);
         if ($this->boolean('ajax')) {
@@ -118,7 +118,7 @@ class TagsubAction extends Action
      *
      * @return void
      */
-    function handle($args)
+    function handle(array $args=array())
     {
         // Throws exception on error
 
index 1e927b4fd175437133808b33fd04dd1885073366..90b73ee3d4062a53f29707c7ad1b85906d82405d 100644 (file)
@@ -136,7 +136,7 @@ class TagSubsAction extends GalleryAction
 
 class TagSubscriptionsList extends SubscriptionList
 {
-    function newListItem($tagsub)
+    function newListItem(TagSub $tagsub)
     {
         return new TagSubscriptionsListItem($tagsub, $this->owner, $this->action);
     }
index 43afab08e374c5e2b9dbbcf826b9f746887dcb27..58626d626da9e78968f17079b50bdd807d5126eb 100644 (file)
@@ -62,7 +62,7 @@ class TagunsubAction extends TagsubAction
      *
      * @return void
      */
-    function handle($args)
+    function handle(array $args=array())
     {
         // Throws exception on error
 
index 5bc0c436ee8f7d3639d273896c98ae4436b81545..43c573e7cbb58258dd97253ed8b2da1db3b70841 100644 (file)
@@ -132,4 +132,16 @@ class TagSub extends Managed_DataObject
 
         return $tags;
     }
+
+    /**
+     * Getter for Profile instance
+     *
+     * @return $profile        Profile instance
+     */
+    public function getProfile () {
+        assert($this->profile_id > 0);
+        $profile = new Profile();
+        $profile->id = $this->profile_id;
+        return $profile;
+    }
 }
diff --git a/plugins/TinyMCE/TinyMCEPlugin.php b/plugins/TinyMCE/TinyMCEPlugin.php
new file mode 100644 (file)
index 0000000..03d45e8
--- /dev/null
@@ -0,0 +1,348 @@
+<?php
+/**
+ * StatusNet - the distributed open-source microblogging tool
+ * Copyright (C) 2010, StatusNet, Inc.
+ *
+ * Use TinyMCE library to allow rich text editing in the browser
+ *
+ * PHP version 5
+ *
+ * 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  WYSIWYG
+ * @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);
+}
+
+/**
+ * Use TinyMCE library to allow rich text editing in the browser
+ *
+ * Converts the notice form in browser to a rich-text editor.
+ *
+ * FIXME: this plugin DOES NOT load its static files from the configured
+ * plugin server if one exists. There are cross-server permissions errors
+ * if you try to do that (something about window.tinymce).
+ *
+ * @category  WYSIWYG
+ * @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/
+ */
+class TinyMCEPlugin extends Plugin
+{
+    var $html;
+
+    // By default, TinyMCE editor will be available to all users.
+    // With restricted on, only users who have been granted the
+    // "richedit" role get it.
+    public $restricted = false;
+
+    function onEndShowScripts(Action $action)
+    {
+        if (common_logged_in() && $this->isAllowedRichEdit()) {
+            $action->script(common_path('plugins/TinyMCE/js/jquery.tinymce.js'));
+            $action->inlineScript($this->_inlineScript());
+        }
+
+        return true;
+    }
+
+    function onEndShowStyles(Action $action)
+    {
+        if ($this->isAllowedRichEdit()) {
+            $action->style('span#notice_data-text_container, span#notice_data-text_parent { float: left }');
+        }
+        return true;
+    }
+
+    function onPluginVersion(array &$versions)
+    {
+        $versions[] = array('name' => 'TinyMCE',
+            'version' => GNUSOCIAL_VERSION,
+            'author' => 'Evan Prodromou',
+            'homepage' => 'http://status.net/wiki/Plugin:TinyMCE',
+            'rawdescription' =>
+            // TRANS: Plugin description.
+            _m('Use TinyMCE library to allow rich text editing in the browser.'));
+        return true;
+    }
+
+    /**
+     * Sanitize HTML input and strip out potentially dangerous bits.
+     *
+     * @param string $raw HTML
+     * @return string HTML
+     */
+    private function sanitizeHtml($raw)
+    {
+        require_once INSTALLDIR . '/extlib/htmLawed/htmLawed.php';
+
+        $config = array('safe' => 1,
+            'deny_attribute' => 'id,style,on*');
+
+        return htmLawed($raw, $config);
+    }
+
+    /**
+     * Hook for new-notice form processing to take our HTML goodies;
+     * won't affect API posting etc.
+     *
+     * @param NewNoticeAction $action
+     * @param User $user
+     * @param string $content
+     * @param array $options
+     * @return boolean hook return
+     */
+    function onStartSaveNewNoticeWeb($action, $user, &$content, &$options)
+    {
+        if ($action->arg('richedit') && $this->isAllowedRichEdit()) {
+            $html = $this->sanitizeHtml($content);
+            $options['rendered'] = $html;
+            $content = common_strip_html($html);
+        }
+        return true;
+    }
+
+    /**
+     * Hook for new-notice form processing to process file upload appending...
+     *
+     * @param NewNoticeAction $action
+     * @param MediaFile $media
+     * @param string $content
+     * @param array $options
+     * @return boolean hook return
+     */
+    function onStartSaveNewNoticeAppendAttachment($action, $media, &$content, &$options)
+    {
+        if ($action->arg('richedit') && $this->isAllowedRichEdit()) {
+            // See if we've got a placeholder inline image; if so, fill it!
+            $dom = new DOMDocument();
+
+            if ($dom->loadHTML($options['rendered'])) {
+                $imgs = $dom->getElementsByTagName('img');
+                foreach ($imgs as $img) {
+                    if (preg_match('/(^| )placeholder( |$)/', $img->getAttribute('class'))) {
+                        // Create a link to the attachment page...
+                        $this->formatAttachment($img, $media);
+                    }
+                }
+                $options['rendered'] = $this->saveHtml($dom);
+            }
+
+            // The regular code will append the short URL to the plaintext content.
+            // Carry on and let it through...
+        }
+        return true;
+    }
+
+    /**
+     * Format the attachment placeholder img with the final version.
+     *
+     * @param DOMElement $img
+     * @param MediaFile $media
+     */
+    private function formatAttachment($img, $media)
+    {
+        $parent = $img->parentNode;
+        $dom = $img->ownerDocument;
+
+        $link = $dom->createElement('a');
+        $link->setAttribute('href', $media->fileurl);
+        $link->setAttribute('title', File::url($media->filename));
+
+        if ($this->isEmbeddable($media)) {
+            // Fix the the <img> attributes and wrap the link around it...
+            $this->insertImage($img, $media);
+            $parent->replaceChild($link, $img); //it dies in here?!
+            $link->appendChild($img);
+        } else {
+            // Not an image? Replace it with a text link.
+            $link->setAttribute('rel', 'external');
+            $link->setAttribute('class', 'attachment');
+            $link->setAttribute('id', 'attachment-' . $media->fileRecord->id);
+            $text = $dom->createTextNode($media->shortUrl());
+            $link->appendChild($text);
+            $parent->replaceChild($link, $img);
+        }
+    }
+
+    /**
+     * Is this media file a type we can display inline?
+     *
+     * @param MediaFile $media
+     * @return boolean
+     */
+    private function isEmbeddable($media)
+    {
+        $showable = array('image/png',
+                          'image/gif',
+                          'image/jpeg');
+        return in_array($media->mimetype, $showable);
+    }
+
+    /**
+     * Rewrite and resize a placeholder image element to match the uploaded
+     * file. If the holder is smaller than the file, the file is scaled to fit
+     * with correct aspect ratio (but will be loaded at full resolution).
+     *
+     * @param DOMElement $img
+     * @param MediaFile $media
+     */
+    private function insertImage($img, $media)
+    {
+        $img->setAttribute('src', $media->fileRecord->url);
+
+        $holderWidth = intval($img->getAttribute('width'));
+        $holderHeight = intval($img->getAttribute('height'));
+
+        $path = File::path($media->filename);
+        $imgInfo = getimagesize($path);
+
+        if ($imgInfo) {
+            $origWidth = $imgInfo[0];
+            $origHeight = $imgInfo[1];
+
+            list($width, $height) = $this->sizeBox(
+                    $origWidth, $origHeight,
+                    $holderWidth, $holderHeight);
+
+            $img->setAttribute('width', $width);
+            $img->setAttribute('height', $height);
+        }
+    }
+
+    /**
+     *
+     * @param int $origWidth
+     * @param int $origHeight
+     * @param int $holderWidth
+     * @param int $holderHeight
+     * @return array($width, $height)
+     */
+    private function sizeBox($origWidth, $origHeight, $holderWidth, $holderHeight)
+    {
+        $holderAspect = $holderWidth / $holderHeight;
+        $origAspect = $origWidth / $origHeight;
+        if ($origAspect >= 1.0) {
+            // wide image
+            if ($origWidth > $holderWidth) {
+                return array($holderWidth, intval($holderWidth / $origAspect));
+            } else {
+                return array($origWidth, $origHeight);
+            }
+        } else {
+            if ($origHeight > $holderHeight) {
+                return array(intval($holderWidth * $origAspect), $holderHeight);
+            } else {
+                return array($origWidth, $origHeight);
+            }
+        }
+    }
+
+    private function saveHtml($dom)
+    {
+        $html = $dom->saveHTML();
+        // hack to remove surrounding crap added to the dom
+        // all we wanted was a fragment
+        $stripped = preg_replace('/^.*<body[^>]*>(.*)<\/body.*$/is', '$1', $html);
+        return $stripped;
+    }
+
+    function _inlineScript()
+    {
+        $path = common_path('plugins/TinyMCE/js/tiny_mce.js');
+        $placeholder = common_path('plugins/TinyMCE/icons/placeholder.png');
+
+        // Note: the normal on-submit triggering to save data from
+        // the HTML editor into the textarea doesn't play well with
+        // our AJAX form submission. Manually moving it to trigger
+        // on our send button click.
+        $scr = <<<END_OF_SCRIPT
+        (function() {
+        var origInit = SN.Init.NoticeFormSetup;
+        SN.Init.NoticeFormSetup = function(form) {
+            origInit(form);
+            var noticeForm = form;
+            var textarea = form.find('.notice_data-text');
+            if (textarea.length == 0) return;
+            textarea.tinymce({
+                script_url : '{$path}',
+                // General options
+                theme : "advanced",
+                plugins : "paste,fullscreen,autoresize,inlinepopups,tabfocus,linkautodetect",
+                theme_advanced_buttons1 : "bold,italic,strikethrough,|,undo,redo,|,link,unlink,image,|,fullscreen",
+                theme_advanced_buttons2 : "",
+                theme_advanced_buttons3 : "",
+                add_form_submit_trigger : false,
+                theme_advanced_resizing : true,
+                tabfocus_elements: ":prev,:next",
+                setup: function(ed) {
+                    noticeForm.append('<input type="hidden" name="richedit" value="1">');
+
+                    form.find('.submit:first').click(function() {
+                        tinymce.triggerSave();
+                    });
+
+                    var origCounter = SN.U.CharacterCount;
+                    SN.U.CharacterCount = function(form) {
+                        var text = $(ed.getDoc()).text();
+                        return text.length;
+                    };
+                    ed.onKeyUp.add(function (ed, e) {
+                        SN.U.Counter(noticeForm);
+                    });
+
+                    form.find('input[type=file]').change(function() {
+                        var img = '<img src="{$placeholder}" class="placeholder" width="320" height="240">';
+                        var html = tinyMCE.activeEditor.getContent();
+                        ed.setContent(html + img);
+                    });
+                }
+            });
+        };
+        })();
+END_OF_SCRIPT;
+
+        return $scr;
+    }
+
+    /**
+     * Does the current user have permission to use the rich-text editor?
+     * Always true unless the plugin's "restricted" setting is on, in which
+     * case it's limited to users with the "richedit" role.
+     *
+     * @fixme make that more sanely configurable :)
+     *
+     * @return boolean
+     */
+    private function isAllowedRichEdit()
+    {
+        if ($this->restricted) {
+            $user = common_current_user();
+            return !empty($user) && $user->hasRole('richedit');
+        } else {
+            return true;
+        }
+    }
+}
index 72c28d4fa45eb4dfc4eefbaa1528cc357bf9055e..644cd8af75fbc7d22d39c18250d1337a46404736 100644 (file)
@@ -191,7 +191,7 @@ class TwitterBridgePlugin extends Plugin
      *
      * @return boolean hook return
      */
-    function onStartEnqueueNotice($notice, &$transports)
+    function onStartEnqueueNotice(Notice $notice, array &$transports)
     {
         if (self::hasKeys() && $notice->isLocal() && $notice->inScope(null)) {
             // Avoid a possible loop
@@ -209,7 +209,7 @@ class TwitterBridgePlugin extends Plugin
      *
      * @return boolean hook return
      */
-    function onGetValidDaemons(&$daemons)
+    function onGetValidDaemons(array &$daemons)
     {
         if (self::hasKeys()) {
             array_push(
@@ -236,7 +236,7 @@ class TwitterBridgePlugin extends Plugin
      *
      * @return boolean hook return
      */
-    function onEndInitializeQueueManager($manager)
+    function onEndInitializeQueueManager(QueueManager $manager)
     {
         if (self::hasKeys()) {
             // Outgoing notices -> twitter
@@ -268,7 +268,7 @@ class TwitterBridgePlugin extends Plugin
      * @return boolean hook value
      */
 
-    function onEndAdminPanelNav($nav)
+    function onEndAdminPanelNav(Menu $nav)
     {
         if (AdminPanelAction::canAdmin('twitter')) {
 
old mode 100755 (executable)
new mode 100644 (file)
index 9fa3b28..fd7f9c2
@@ -30,7 +30,7 @@ Batch script for synching local friends with Twitter friends.
 
 END_OF_TRIM_HELP;
 
-require_once INSTALLDIR . '/scripts/commandline.inc';
+require_once INSTALLDIR . '/scripts/commandline.inc.php';
 require_once dirname(__DIR__) . '/twitter.php';
 
 /**
index 8b774889d19722214cea7595862bd8e8eb48359e..e563f534934ce2a4ce09c8eeaa99079a95b53e51 100755 (executable)
@@ -33,7 +33,7 @@ Daemon script for receiving new notices from Twitter users.
 
 END_OF_TWITTERDAEMON_HELP;
 
-require_once INSTALLDIR.'/scripts/commandline.inc';
+require_once INSTALLDIR.'/scripts/commandline.inc.php';
 
 class TwitterDaemon extends SpawningDaemon
 {
old mode 100755 (executable)
new mode 100644 (file)
index 83e8a0d..fd3b576
@@ -36,7 +36,7 @@ Batch script for retrieving Twitter messages from foreign service.
 
 END_OF_TRIM_HELP;
 
-require_once INSTALLDIR . '/scripts/commandline.inc';
+require_once INSTALLDIR . '/scripts/commandline.inc.php';
 require_once INSTALLDIR . '/lib/common.php';
 require_once INSTALLDIR . '/lib/daemon.php';
 require_once dirname(__DIR__) . '/twitter.php';
@@ -160,7 +160,7 @@ class TwitterStatusFetcher extends ParallelizingDaemon
         if (TwitterOAuthClient::isPackedToken($flink->credentials)) {
             $token = TwitterOAuthClient::unpackToken($flink->credentials);
             $client = new TwitterOAuthClient($token->key, $token->secret);
-            common_log(LOG_DEBUG, $this->name() . ' - Grabbing ' . $timelineUri . ' timeline with OAuth.');
+            common_debug($this->name() . ' - Grabbing ' . $timelineUri . ' timeline with OAuth.');
         } else {
             common_log(LOG_ERR, "Skipping " . $timelineUri . " timeline for " .
                        $flink->foreign_id . " since not OAuth.");
@@ -170,7 +170,7 @@ class TwitterStatusFetcher extends ParallelizingDaemon
 
         $lastId = Twitter_synch_status::getLastId($flink->foreign_id, $timelineUri);
 
-        common_log(LOG_DEBUG, "Got lastId value '" . $lastId . "' for foreign id '" .
+        common_debug("Got lastId value '" . $lastId . "' for foreign id '" .
                      $flink->foreign_id . "' and timeline '" . $timelineUri. "'");
 
         try {
index f6ec1f3f5093495e09846e8cb6bf160350b2dda2..147f398da29e5705746f1c71d3e7cea97e4b3ec8 100644 (file)
@@ -55,7 +55,7 @@ abstract class JsonStreamReader
      */
     public function connect($url)
     {
-        common_log(LOG_DEBUG, "$this->id opening connection to $url");
+        common_debug("$this->id opening connection to $url");
 
         $scheme = parse_url($url, PHP_URL_SCHEME);
         if ($scheme == 'http') {
@@ -143,7 +143,7 @@ abstract class JsonStreamReader
     public function close()
     {
         if ($this->isConnected()) {
-            common_log(LOG_DEBUG, "$this->id closing connection.");
+            common_debug("$this->id closing connection.");
             fclose($this->socket);
             $this->socket = null;
         }
@@ -242,7 +242,7 @@ abstract class JsonStreamReader
             // TRANS: %1$s is the response code, %2$s is the line.
             throw new Exception(sprintf(_m('Bad HTTP response code %1$s: %2$s.'),$status,$line));
         }
-        common_log(LOG_DEBUG, "$this->id $line");
+        common_debug("$this->id $line");
         $this->state = 'headers';
     }
 
@@ -250,9 +250,9 @@ abstract class JsonStreamReader
     {
         if ($line == '') {
             $this->state = 'active';
-            common_log(LOG_DEBUG, "$this->id connection is active!");
+            common_debug("$this->id connection is active!");
         } else {
-            common_log(LOG_DEBUG, "$this->id read HTTP header: $line");
+            common_debug("$this->id read HTTP header: $line");
             $this->responseHeaders[] = $line;
         }
     }
index 5d965e7394f383df85867c267891b21a8ca6c3d2..7e192cf8b44623b59fc96b5081e7e8022a554b25 100644 (file)
@@ -42,7 +42,7 @@ data as it comes.
 
 ENDOFHELP;
 
-require_once INSTALLDIR.'/scripts/commandline.inc';
+require_once INSTALLDIR.'/scripts/commandline.inc.php';
 
 if (have_option('n')) {
     $nickname = get_option_value('n');
index f4a60c479d62498474f45710d7aae87535126b47..12fb2457482399bdacc8662b95d5c781f34dbd08 100755 (executable)
@@ -29,7 +29,7 @@ version 0.9.5.
 
 ENDOFHELP;
 
-require_once INSTALLDIR.'/scripts/commandline.inc';
+require_once INSTALLDIR.'/scripts/commandline.inc.php';
 
 // We update any notices that may have come in from
 // Twitter that we don't have a status_id for. Note that
index a642920cee908e09b0363c03a0c9cc52c4958dd2..d3acb41bed0cbc66d3423afb823ed1c24d8872a4 100644 (file)
@@ -43,7 +43,7 @@ data as it comes.
 
 ENDOFHELP;
 
-require_once INSTALLDIR.'/scripts/commandline.inc';
+require_once INSTALLDIR.'/scripts/commandline.inc.php';
 require_once dirname(dirname(__FILE__)) . '/lib/jsonstreamreader.php';
 require_once dirname(dirname(__FILE__)) . '/lib/twitterstreamreader.php';
 
index d2afeaced85346c4f6aae441db7466d6893e3438..986dd901a0f0a86ef828d001f7b16553fd3edac1 100644 (file)
@@ -152,6 +152,8 @@ class UserFlagPlugin extends Plugin
      * @param boolean &$result out, result of the check
      *
      * @return boolean hook result
+     * @TODO Other implementing classes expect Profile here!!!
+     * @WARNING
      */
     function onUserRightsCheck($user, $right, &$result)
     {
@@ -175,7 +177,7 @@ class UserFlagPlugin extends Plugin
      *
      * @return boolean hook result
      */
-    function onEndBlockProfile($user, $profile)
+    function onEndBlockProfile(User $user, Profile $profile)
     {
         if ($this->flagOnBlock && !User_flag_profile::exists($profile->id,
                                                              $user->id)) {
@@ -196,9 +198,9 @@ class UserFlagPlugin extends Plugin
      *
      * @return boolean hook result
      */
-    function onProfileDeleteRelated($profile, &$related)
+    public function onProfileDeleteRelated(Profile $profile, array &$related)
     {
-        $related[] = 'user_flag_profile';
+        $related[] = 'User_flag_profile';
         return true;
     }
 
index 9b5b4088bf0f2555c1bf619750fda7a85ea296e6..8a7d478631200deb6cba077df4a47698045721be 100644 (file)
@@ -52,7 +52,7 @@ class AdminprofileflagAction extends Action
      *
      * @return boolean success flag
      */
-    function prepare($args)
+    function prepare(array $args=array())
     {
         parent::prepare($args);
 
@@ -107,7 +107,7 @@ class AdminprofileflagAction extends Action
      *
      * @return void
      */
-    function handle($args)
+    function handle(array $args=array())
     {
         parent::handle($args);
 
@@ -200,7 +200,7 @@ class FlaggedProfileList extends ProfileList
      *
      * @return ProfileListItem newly-created item
      */
-    function newListItem($profile)
+    function newListItem(Profile $profile)
     {
         return new FlaggedProfileListItem($this->profile, $this->action);
     }
index c2443d6d58e76521199b1da01595b3d70a8bff36..4d17779322399ad158f5cc5e8c91d078787a23fe 100644 (file)
@@ -49,7 +49,7 @@ class ClearflagAction extends ProfileFormAction
      *
      * @return boolean success flag
      */
-    function prepare($args)
+    function prepare(array $args=array())
     {
         if (!parent::prepare($args)) {
             return false;
@@ -73,7 +73,7 @@ class ClearflagAction extends ProfileFormAction
      *
      * @return void
      */
-    function handle($args)
+    function handle(array $args=array())
     {
         if ($_SERVER['REQUEST_METHOD'] == 'POST') {
             $this->handlePost();
index 4c4dc46f60ffcb044a3a7e6e932fa7b6ea3df7fd..707b9ec0ed13dce8b579a366a747e474697ee396 100644 (file)
@@ -49,7 +49,7 @@ class FlagprofileAction extends ProfileFormAction
      *
      * @return boolean success flag
      */
-    function prepare($args)
+    function prepare(array $args=array())
     {
         if (!parent::prepare($args)) {
             return false;
@@ -73,7 +73,7 @@ class FlagprofileAction extends ProfileFormAction
      *
      * @return void
      */
-    function handle($args)
+    function handle(array $args=array())
     {
         if ($_SERVER['REQUEST_METHOD'] == 'POST') {
             $this->handlePost();
index ac4d503151d569d1d619c52776efe3bab3d31b14..ed4ff9df497267bda79f09ac6c5290a1e0467a47 100644 (file)
@@ -55,7 +55,17 @@ class UserLimitPlugin extends Plugin
         return true;
     }
 
-    function onStartRegistrationTry($action)
+    /**
+     * Called when someone tries to register.
+     *
+     * We check the IP here to determine if it goes over any of our
+     * configured limits.
+     *
+     * @param Action $action Action that is being executed
+     *
+     * @return boolean hook value
+     */
+    function onStartRegistrationTry(Action $action)
     {
         $this->_checkMaxUsers();
         return true;
index ce8c847aa799c2c744490f3b0e40779810a54f62..1edc3d8971351790ac70f9fc22418800814a6237 100644 (file)
@@ -42,7 +42,7 @@ class WebFingerPlugin extends Plugin
         common_config_set('webfinger', 'http_alias', $this->http_alias);
     }
 
-    public function onRouterInitialized($m)
+    public function onRouterInitialized(URLMapper $m)
     {
         $m->connect('.well-known/host-meta', array('action' => 'hostmeta'));
         $m->connect('.well-known/host-meta.:format',
@@ -141,7 +141,7 @@ class WebFingerPlugin extends Plugin
     /**
      * Add a link header for LRDD Discovery
      */
-    public function onStartShowHTML($action)
+    public function onStartShowHTML(Action $action)
     {
         if ($action instanceof ShowstreamAction) {
             $acct = 'acct:'. $action->getTarget()->getNickname() .'@'. common_config('site', 'server');
index 6d22631dc1aa4523cd93795852d48dcfdc2cf41d..1ac5764dc5e147eaa58909d5cc7aef55f1e4a910 100644 (file)
@@ -33,7 +33,7 @@ abstract class XrdAction extends ManagedAction
 
     protected $xrd      = null;
 
-    public function isReadOnly($args)
+    public function isReadOnly(array $args=array())
     {
         return true;
     }
index 8656272e48c85068be643d352295f9e9660ddfb1..1156ac933a4173a754c9ad573d99c62d1a5e19fb 100644 (file)
@@ -154,7 +154,7 @@ class WikiHowProfilePlugin extends Plugin
             $absolute = $base->resolve($src);
             $avatarUrl = strval($absolute);
 
-            common_log(LOG_DEBUG, "WikiHow avatar found for $profileUrl - $avatarUrl");
+            common_debug("WikiHow avatar found for $profileUrl - $avatarUrl");
             $data['avatar'] = $avatarUrl;
         }
 
@@ -178,7 +178,7 @@ class WikiHowProfilePlugin extends Plugin
 
         // @todo FIXME: This should be better encapsulated
         // ripped from OStatus via oauthstore.php (for old OMB client)
-        $temp_filename = tempnam(sys_get_temp_dir(), 'listener_avatar');
+        $temp_filename = tempnam(common_get_temp_dir(), 'listener_avatar');
         try {
             if (!copy($url, $temp_filename)) {
                 // TRANS: Exception thrown when fetching an avatar from a URL fails.
diff --git a/plugins/XCache/XCachePlugin.php b/plugins/XCache/XCachePlugin.php
new file mode 100644 (file)
index 0000000..66a3b88
--- /dev/null
@@ -0,0 +1,120 @@
+<?php
+/**
+ * StatusNet - the distributed open-source microblogging tool
+ * Copyright (C) 2009, StatusNet, Inc.
+ *
+ * Plugin to implement cache interface for XCache variable cache
+ *
+ * PHP version 5
+ *
+ * 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  Cache
+ * @package   StatusNet
+ * @author    Evan Prodromou <evan@status.net>
+ * @copyright 2009 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')) {
+    // This check helps protect against security problems;
+    // your code file can't be executed directly from the web.
+    exit(1);
+}
+
+/**
+ * A plugin to use XCache's variable cache for the cache interface
+ *
+ * New plugin interface lets us use alternative cache systems
+ * for caching. This one uses XCache's variable cache.
+ *
+ * @category  Cache
+ * @package   StatusNet
+ * @author    Evan Prodromou <evan@status.net>
+ * @copyright 2009 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/
+ */
+class XCachePlugin extends Plugin
+{
+    /**
+     * Get a value associated with a key
+     *
+     * The value should have been set previously.
+     *
+     * @param string &$key   in; Lookup key
+     * @param mixed  &$value out; value associated with key
+     *
+     * @return boolean hook success
+     */
+    function onStartCacheGet(&$key, &$value)
+    {
+        if (!xcache_isset($key)) {
+            $value = false;
+        } else {
+            $value = xcache_get($key);
+            $value = unserialize($value);
+        }
+        Event::handle('EndCacheGet', array($key, &$value));
+        return false;
+    }
+
+    /**
+     * Associate a value with a key
+     *
+     * @param string  &$key     in; Key to use for lookups
+     * @param mixed   &$value   in; Value to associate
+     * @param integer &$flag    in; Flag (passed through to Memcache)
+     * @param integer &$expiry  in; Expiry (passed through to Memcache)
+     * @param boolean &$success out; Whether the set was successful
+     *
+     * @return boolean hook success
+     */
+    function onStartCacheSet(&$key, &$value, &$flag, &$expiry, &$success)
+    {
+        $success = xcache_set($key, serialize($value));
+
+        Event::handle('EndCacheSet', array($key, $value, $flag,
+                                           $expiry));
+        return false;
+    }
+
+    /**
+     * Delete a value associated with a key
+     *
+     * @param string  &$key     in; Key to lookup
+     * @param boolean &$success out; whether it worked
+     *
+     * @return boolean hook success
+     */
+    function onStartCacheDelete(&$key, &$success)
+    {
+        $success = xcache_unset($key);
+        Event::handle('EndCacheDelete', array($key));
+        return false;
+    }
+
+    function onPluginVersion(array &$versions)
+    {
+        $versions[] = array('name' => 'XCache',
+                            'version' => GNUSOCIAL_VERSION,
+                            'author' => 'Craig Andrews',
+                            'homepage' => 'http://status.net/wiki/Plugin:XCache',
+                            'rawdescription' =>
+                            // TRANS: Plugin description.
+                            _m('Use the <a href="http://xcache.lighttpd.net/">XCache</a> variable cache to cache query results.'));
+        return true;
+    }
+}
index 6867eb093e73724739cd1bfffa96009c8c8fa02a..7112b8b63eaeb8013bf24be41ff05047ab8b1b33 100644 (file)
@@ -438,7 +438,7 @@ class XmppPlugin extends ImPlugin
      *
      * @return boolean hook return
      */
-    function onGetValidDaemons(&$daemons)
+    function onGetValidDaemons(array &$daemons)
     {
         if( isset($this->server) &&
             isset($this->port)   &&
index 372824ce54dc2f960958ad63af71fafdba55d40b..954639f18019ce82f4d238f7d53e7b32dc931e04 100644 (file)
@@ -81,7 +81,7 @@ class XmppManager extends ImManager
     {
         // Process the queue for as long as needed
         try {
-            common_log(LOG_DEBUG, "Servicing the XMPP queue.");
+            common_debug("Servicing the XMPP queue.");
             $this->stats('xmpp_process');
             $this->conn->processTime(0);
         } catch (XMPPHP_Exception $e) {
@@ -182,7 +182,7 @@ class XmppManager extends ImManager
             $this->pingid++;
         }
 
-        common_log(LOG_DEBUG, "Sending ping #{$this->pingid}");
+        common_debug("Sending ping #{$this->pingid}");
                $this->conn->send("<iq from='{" . $this->plugin->daemonScreenname() . "}' to='{$this->plugin->server}' id='ping_{$this->pingid}' type='get'><ping xmlns='urn:xmpp:ping'/></iq>");
         $this->lastping = $now;
         return true;
diff --git a/plugins/YammerImport/actions/yammeradminpanel.php b/plugins/YammerImport/actions/yammeradminpanel.php
new file mode 100644 (file)
index 0000000..83f3f19
--- /dev/null
@@ -0,0 +1,192 @@
+<?php
+/**
+ * StatusNet, the distributed open-source microblogging tool
+ *
+ * Yammer import administration panel
+ *
+ * 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  Settings
+ * @package   StatusNet
+ * @author    Zach Copley <zach@status.net>
+ * @copyright 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('STATUSNET')) {
+    exit(1);
+}
+
+class YammeradminpanelAction extends AdminPanelAction
+{
+    private $runner;
+
+    /**
+     * Returns the page title
+     *
+     * @return string page title
+     */
+    function title()
+    {
+        // TRANS: Page title for Yammer import administration panel.
+        return _m('Yammer Import');
+    }
+
+    /**
+     * Instructions for using this form.
+     *
+     * @return string instructions
+     */
+    function getInstructions()
+    {
+        // TRANS: Instructions for Yammer import administration panel.
+        return _m('This Yammer import tool is still undergoing testing, ' .
+                  'and is incomplete in some areas. ' .
+                'Currently user subscriptions and group memberships are not ' .
+                'transferred; in the future this may be supported for ' .
+                'imports done by verified administrators on the Yammer side.');
+    }
+
+    function prepare(array $args=array())
+    {
+        $ok = parent::prepare($args);
+
+        $this->subaction = $this->trimmed('subaction');
+        $this->runner = YammerRunner::init();
+
+        return $ok;
+    }
+
+    function handle(array $args=array())
+    {
+        // @fixme move this to saveSettings and friends?
+        if ($_SERVER['REQUEST_METHOD'] == 'POST') {
+            StatusNet::setApi(true); // short error pages :P
+            $this->checkSessionToken();
+            if ($this->subaction == 'change-apikey') {
+                $form = new YammerApiKeyForm($this);
+            } else if ($this->subaction == 'apikey') {
+                if ($this->saveKeys()) {
+                    $form = new YammerAuthInitForm($this, $this->runner);
+                } else {
+                    $form = new YammerApiKeyForm($this);
+                }
+            } else if ($this->subaction == 'authinit') {
+                // hack
+                if ($this->arg('change-apikey')) {
+                    $form = new YammerApiKeyForm($this);
+                } else {
+                    $url = $this->runner->requestAuth();
+                    $form = new YammerAuthVerifyForm($this, $this->runner);
+                }
+            } else if ($this->subaction == 'authverify') {
+                $this->runner->saveAuthToken($this->trimmed('verify_token'));
+
+                // Haho! Now we can make THE FUN HAPPEN
+                $this->runner->startBackgroundImport();
+
+                $form = new YammerProgressForm($this, $this->runner);
+            } else if ($this->subaction == 'pause-import') {
+                // TRANS: Error message about an import job being paused from the admin panel.
+                $this->runner->recordError(_m('Paused from admin panel.'));
+                $form = $this->statusForm();
+            } else if ($this->subaction == 'continue-import') {
+                $this->runner->clearError();
+                $this->runner->startBackgroundImport();
+                $form = $this->statusForm();
+            } else if ($this->subaction == 'abort-import') {
+                $this->runner->reset();
+                $form = $this->statusForm();
+            } else if ($this->subaction == 'progress') {
+                $form = $this->statusForm();
+            } else {
+                // TRANS: Client exception thrown when encountering an unhandled sub action.
+                throw new ClientException(_m('Invalid POST'));
+            }
+            return $this->showAjaxForm($form);
+        }
+        return parent::handle($args);
+    }
+
+    function saveKeys()
+    {
+        $key = $this->trimmed('consumer_key');
+        $secret = $this->trimmed('consumer_secret');
+        Config::save('yammer', 'consumer_key', $key);
+        Config::save('yammer', 'consumer_secret', $secret);
+
+        return !empty($key) && !empty($secret);
+    }
+
+    function showAjaxForm($form)
+    {
+        $this->startHTML('text/xml;charset=utf-8');
+        $this->elementStart('head');
+        // TRANS: Page title for Yammer import administration panel.
+        $this->element('title', null, _m('Yammer import'));
+        $this->elementEnd('head');
+        $this->elementStart('body');
+        $form->show();
+        $this->elementEnd('body');
+        $this->endHTML();
+    }
+
+    /**
+     * Fetch the appropriate form for our current state.
+     * @return Form
+     */
+    function statusForm()
+    {
+        if (!(common_config('yammer', 'consumer_key'))
+            || !(common_config('yammer', 'consumer_secret'))) {
+            return new YammerApiKeyForm($this);
+        }
+        switch($this->runner->state())
+        {
+            case 'init':
+                return new YammerAuthInitForm($this, $this->runner);
+            case 'requesting-auth':
+                return new YammerAuthVerifyForm($this, $this->runner);
+            default:
+                return new YammerProgressForm($this, $this->runner);
+        }
+    }
+
+    /**
+     * Show the Yammer admin panel form
+     *
+     * @return void
+     */
+    function showForm()
+    {
+        $this->elementStart('fieldset');
+        $this->statusForm()->show();
+        $this->elementEnd('fieldset');
+    }
+
+    function showStylesheets()
+    {
+        parent::showStylesheets();
+        $this->cssLink(Plugin::staticPath('YammerImport', 'css/admin.css'), null, 'screen, projection, tv');
+    }
+
+    function showScripts()
+    {
+        parent::showScripts();
+        $this->script(Plugin::staticPath('YammerImport', 'js/yammer-admin.js'));
+    }
+}
diff --git a/plugins/YammerImport/actions/yammerauth.php b/plugins/YammerImport/actions/yammerauth.php
new file mode 100644 (file)
index 0000000..cfd126f
--- /dev/null
@@ -0,0 +1,77 @@
+<?php
+/**
+ * StatusNet, the distributed open-source microblogging tool
+ *
+ * Yammer import administration panel
+ *
+ * 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  Settings
+ * @package   StatusNet
+ * @author    Zach Copley <zach@status.net>
+ * @copyright 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('STATUSNET')) {
+    exit(1);
+}
+
+class YammerauthAction extends AdminPanelAction
+{
+    /**
+     * Show the Yammer admin panel form
+     *
+     * @return void
+     */
+    function prepare(array $args=array())
+    {
+        parent::prepare($args);
+
+        $this->verify_token = $this->trim('verify_token');
+    }
+
+    /**
+     * Handle request
+     *
+     * Does the subscription and returns results.
+     *
+     * @param Array $args unused.
+     *
+     * @return void
+     */
+    function handle(array $args=array())
+    {
+        if ($this->verify_token) {
+            $runner->saveAuthToken($this->verify_token);
+            $form = new YammerAuthProgressForm();
+        } else {
+            $url = $runner->requestAuth();
+            $form = new YammerAuthVerifyForm($this, $url);
+        }
+
+        $this->startHTML('text/xml;charset=utf-8');
+        $this->elementStart('head');
+        // TRANS: Page title for Yammer administration panel.
+        $this->element('title', null, _m('Connect to Yammer'));
+        $this->elementEnd('head');
+        $this->elementStart('body');
+        $form->show();
+        $this->elementEnd('body');
+        $this->endHTML();
+    }
+}
diff --git a/plugins/YammerImport/lib/yammerimporter.php b/plugins/YammerImport/lib/yammerimporter.php
new file mode 100644 (file)
index 0000000..abd41dd
--- /dev/null
@@ -0,0 +1,512 @@
+<?php
+/*
+ * StatusNet - the distributed open-source microblogging tool
+ * Copyright (C) 2010, 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/>.
+ */
+
+/**
+ * Basic client class for Yammer's OAuth/JSON API.
+ *
+ * Depends on Favorite plugin
+ *
+ * @package YammerImportPlugin
+ * @author Brion Vibber <brion@status.net>
+ */
+class YammerImporter
+{
+    protected $client;
+
+    function __construct(SNYammerClient $client)
+    {
+        $this->client = $client;
+    }
+
+    /**
+     * Load or create an imported profile from Yammer data.
+     *
+     * @param object $item loaded JSON data for Yammer importer
+     * @return Profile
+     */
+    function importUser($item)
+    {
+        $data = $this->prepUser($item);
+        $nickname = $data['options']['nickname'];
+
+        $profileId = $this->findImportedUser($data['orig_id']);
+        if ($profileId) {
+            return Profile::getKV('id', $profileId);
+        } else {
+            $user = User::getKV('nickname', $nickname);
+
+            if ($user instanceof User) {
+                common_log(LOG_WARNING, "Copying Yammer profile info onto existing user $nickname");
+                $profile = $user->getProfile();
+                $this->savePropertiesOn($profile, $data['options'],
+                        array('fullname', 'homepage', 'bio', 'location'));
+            } else {
+                $user = User::register($data['options']);
+                $profile = $user->getProfile();
+            }
+
+            if ($data['avatar']) {
+                try {
+                    $this->saveAvatar($data['avatar'], $profile);
+                } catch (Exception $e) {
+                    common_log(LOG_ERR, "Error importing Yammer avatar: " . $e->getMessage());
+                }
+            }
+            $this->recordImportedUser($data['orig_id'], $profile->id);
+            return $profile;
+        }
+    }
+
+    /**
+     * Load or create an imported group from Yammer data.
+     *
+     * @param object $item loaded JSON data for Yammer importer
+     * @return User_group
+     */
+    function importGroup($item)
+    {
+        $data = $this->prepGroup($item);
+        $nickname = $data['options']['nickname'];
+
+        $groupId = $this->findImportedGroup($data['orig_id']);
+        if ($groupId) {
+            return User_group::getKV('id', $groupId);
+        } else {
+            $local = Local_group::getKV('nickname', $nickname);
+            if ($local) {
+                common_log(LOG_WARNING, "Copying Yammer group info onto existing group $nickname");
+                $group = User_group::getKV('id', $local->group_id);
+                $this->savePropertiesOn($group, $data['options'],
+                        array('fullname', 'description'));
+            } else {
+                $group = User_group::register($data['options']);
+            }
+            if ($data['avatar']) {
+                try {
+                    $this->saveAvatar($data['avatar'], $group);
+                } catch (Exception $e) {
+                    common_log(LOG_ERR, "Error importing Yammer avatar: " . $e->getMessage());
+                }
+            }
+            $this->recordImportedGroup($data['orig_id'], $group->id);
+            return $group;
+        }
+    }
+
+    private function savePropertiesOn($target, $options, $propList)
+    {
+        $changed = 0;
+        $orig = clone($target);
+        foreach ($propList as $prop) {
+            if (!empty($options[$prop]) && $target->$prop != $options[$prop]) {
+                $target->$prop = $options[$prop];
+                $changed++;
+            }
+        }
+        $target->update($orig);
+    }
+
+    /**
+     * Load or create an imported notice from Yammer data.
+     *
+     * @param object $item loaded JSON data for Yammer importer
+     * @return Notice
+     */
+    function importNotice($item)
+    {
+        $data = $this->prepNotice($item);
+
+        $noticeId = $this->findImportedNotice($data['orig_id']);
+        if ($noticeId) {
+            return Notice::getKV('id', $noticeId);
+        } else {
+            $notice = Notice::getKV('uri', $data['options']['uri']);
+            $content = $data['content'];
+            $user = User::getKV($data['profile']);
+
+            // Fetch file attachments and add the URLs...
+            $uploads = array();
+            foreach ($data['attachments'] as $url) {
+                try {
+                    $upload = $this->saveAttachment($url, $user);
+                    $content .= ' ' . $upload->shortUrl();
+                    $uploads[] = $upload;
+                } catch (Exception $e) {
+                    common_log(LOG_ERR, "Error importing Yammer attachment: " . $e->getMessage());
+                }
+            }
+
+            // Here's the meat! Actually save the dang ol' notice.
+            $notice = Notice::saveNew($user->id,
+                                      $content,
+                                      $data['source'],
+                                      $data['options']);
+
+            // Save "likes" as favorites...
+            foreach ($data['faves'] as $nickname) {
+                $user = User::getKV('nickname', $nickname);
+                if ($user instanceof User) {
+                    try {
+                        Fave::addNew($user->getProfile(), $notice);
+                    } catch (Exception $e) {
+                        // failed, let's move to the next
+                        common_debug('YammerImport failed favoriting a notice: '.$e->getMessage());
+                    }
+                }
+            }
+
+            // And finally attach the upload records...
+            foreach ($uploads as $upload) {
+                $upload->attachToNotice($notice);
+            }
+            $this->recordImportedNotice($data['orig_id'], $notice->id);
+            return $notice;
+        }
+    }
+
+    /**
+     * Pull relevant info out of a Yammer data record for a user import.
+     *
+     * @param array $item
+     * @return array
+     */
+    function prepUser($item)
+    {
+        if ($item['type'] != 'user') {
+            // TRANS: Exception thrown when a non-user item type is used, but expected.
+            throw new Exception(_m('Wrong item type sent to Yammer user import processing.'));
+        }
+
+        $origId = $item['id'];
+        $origUrl = $item['url'];
+
+        // @fixme check username rules?
+
+        $options['nickname'] = $item['name'];
+        $options['fullname'] = trim($item['full_name']);
+
+        // Avatar... this will be the "_small" variant.
+        // Remove that (pre-extension) suffix to get the orig-size image.
+        $avatar = $item['mugshot_url'];
+
+        // The following info is only available in full data, not in the reference version.
+
+        // There can be extensive contact info, but for now we'll only pull the primary email.
+        if (isset($item['contact'])) {
+            foreach ($item['contact']['email_addresses'] as $addr) {
+                if ($addr['type'] == 'primary') {
+                    $options['email'] = $addr['address'];
+                    $options['email_confirmed'] = true;
+                    break;
+                }
+            }
+        }
+
+        // There can be multiple external URLs; for now pull the first one as home page.
+        if (isset($item['external_urls'])) {
+            foreach ($item['external_urls'] as $url) {
+                if (common_valid_http_url($url)) {
+                    $options['homepage'] = $url;
+                    break;
+                }
+            }
+        }
+
+        // Combine a few bits into the bio...
+        $bio = array();
+        if (!empty($item['job_title'])) {
+            $bio[] = $item['job_title'];
+        }
+        if (!empty($item['summary'])) {
+            $bio[] = $item['summary'];
+        }
+        if (!empty($item['expertise'])) {
+            // TRANS: Used as a prefix for the Yammer expertise field contents.
+            $bio[] = _m('Expertise:') . ' ' . $item['expertise'];
+        }
+        $options['bio'] = implode("\n\n", $bio);
+
+        // Pull raw location string, may be lookupable
+        if (!empty($item['location'])) {
+            $options['location'] = $item['location'];
+        }
+
+        // Timezone is in format like 'Pacific Time (US & Canada)'
+        // We need to convert that to a zone id. :P
+        // @fixme timezone not yet supported at registration time :)
+        if (!empty($item['timezone'])) {
+            $tz = $this->timezone($item['timezone']);
+            if ($tz) {
+                $options['timezone'] = $tz;
+            }
+        }
+
+        return array('orig_id' => $origId,
+                     'orig_url' => $origUrl,
+                     'avatar' => $avatar,
+                     'options' => $options);
+
+    }
+
+    /**
+     * Pull relevant info out of a Yammer data record for a group import.
+     *
+     * @param array $item
+     * @return array
+     */
+    function prepGroup($item)
+    {
+        if ($item['type'] != 'group') {
+            // TRANS: Exception thrown when a non-group item type is used, but expected.
+            throw new Exception(_m('Wrong item type sent to Yammer group import processing.'));
+        }
+
+        $origId = $item['id'];
+        $origUrl = $item['url'];
+
+        $privacy = $item['privacy']; // Warning! only public groups in SN so far
+
+        $options['nickname'] = $item['name'];
+        $options['fullname'] = $item['full_name'];
+        $options['description'] = $item['description'];
+        $options['created'] = $this->timestamp($item['created_at']);
+
+        $avatar = $item['mugshot_url']; // as with user profiles...
+
+        $options['mainpage'] = common_local_url('showgroup',
+                                   array('nickname' => $options['nickname']));
+
+        // Set some default vals or User_group::register will whine
+        $options['homepage'] = '';
+        $options['location'] = '';
+        $options['aliases'] = array();
+        // @todo FIXME: What about admin user for the group?
+
+        $options['local'] = true;
+        return array('orig_id' => $origId,
+                     'orig_url' => $origUrl,
+                     'options' => $options,
+                     'avatar' => $avatar);
+    }
+
+    /**
+     * Pull relevant info out of a Yammer data record for a notice import.
+     *
+     * @param array $item
+     * @return array
+     */
+    function prepNotice($item)
+    {
+        if (isset($item['type']) && $item['type'] != 'message') {
+            // TRANS: Exception thrown when a non-message item type is used, but expected.
+            throw new Exception(_m('Wrong item type sent to Yammer message import processing.'));
+        }
+
+        $origId = $item['id'];
+        $origUrl = $item['url'];
+
+        $profile = $this->findImportedUser($item['sender_id']);
+        $content = $item['body']['plain'];
+        $source = 'yammer';
+        $options = array();
+
+        if ($item['replied_to_id']) {
+            $replyTo = $this->findImportedNotice($item['replied_to_id']);
+            if ($replyTo) {
+                $options['reply_to'] = $replyTo;
+            }
+        }
+        $options['created'] = $this->timestamp($item['created_at']);
+
+        if (!empty($item['group_id'])) {
+            $groupId = $this->findImportedGroup($item['group_id']);
+            if ($groupId) {
+                $options['groups'] = array($groupId);
+
+                // @fixme if we see a group link inline, don't add this?
+                $group = User_group::getKV('id', $groupId);
+                if ($group instanceof User_group) {
+                    $content .= ' !' . $group->nickname;
+                }
+            }
+        }
+
+        $faves = array();
+        foreach ($item['liked_by']['names'] as $liker) {
+            // "permalink" is the username. wtf?
+            $faves[] = $liker['permalink'];
+        }
+
+        $attachments = array();
+        foreach ($item['attachments'] as $attach) {
+            if ($attach['type'] == 'image' || $attach['type'] == 'file') {
+                $attachments[] = $attach[$attach['type']]['url'];
+            } else {
+                common_log(LOG_WARNING, "Unrecognized Yammer attachment type: " . $attach['type']);
+            }
+        }
+
+        return array('orig_id' => $origId,
+                     'orig_url' => $origUrl,
+                     'profile' => $profile,
+                     'content' => $content,
+                     'source' => $source,
+                     'options' => $options,
+                     'faves' => $faves,
+                     'attachments' => $attachments);
+    }
+
+    private function findImportedUser($origId)
+    {
+        $map = Yammer_user::getKV('id', $origId);
+        return $map ? $map->user_id : null;
+    }
+
+    private function findImportedGroup($origId)
+    {
+        $map = Yammer_group::getKV('id', $origId);
+        return $map ? $map->group_id : null;
+    }
+
+    private function findImportedNotice($origId)
+    {
+        $map = Yammer_notice::getKV('id', $origId);
+        return $map ? $map->notice_id : null;
+    }
+
+    private function recordImportedUser($origId, $userId)
+    {
+        Yammer_user::record($origId, $userId);
+    }
+
+    private function recordImportedGroup($origId, $groupId)
+    {
+        Yammer_group::record($origId, $groupId);
+    }
+
+    private function recordImportedNotice($origId, $noticeId)
+    {
+        Yammer_notice::record($origId, $noticeId);
+    }
+
+    /**
+     * Normalize timestamp format.
+     * @param string $ts
+     * @return string
+     */
+    private function timestamp($ts)
+    {
+        return common_sql_date(strtotime($ts));
+    }
+
+    private function timezone($tz)
+    {
+        // Blaaaaaarf!
+        $known = array('Pacific Time (US & Canada)' => 'America/Los_Angeles',
+                       'Eastern Time (US & Canada)' => 'America/New_York');
+        if (array_key_exists($tz, $known)) {
+            return $known[$tz];
+        } else {
+            return false;
+        }
+    }
+
+    /**
+     * Download and update given avatar image
+     *
+     * @param string $url
+     * @param mixed $dest either a Profile or User_group object
+     * @throws Exception in various failure cases
+     */
+    private function saveAvatar($url, $dest)
+    {
+        // Yammer API data mostly gives us the small variant.
+        // Try hitting the source image if we can!
+        // @fixme no guarantee of this URL scheme I think.
+        $url = preg_replace('/_small(\..*?)$/', '$1', $url);
+
+        if (!common_valid_http_url($url)) {
+            // TRANS: Server exception thrown when an avatar URL is invalid.
+            // TRANS: %s is the invalid avatar URL.
+            throw new ServerException(sprintf(_m('Invalid avatar URL %s.'), $url));
+        }
+
+        // @fixme this should be better encapsulated
+        // ripped from oauthstore.php (for old OMB client)
+        $temp_filename = tempnam(common_get_temp_dir(), 'listener_avatar');
+        try {
+            if (!copy($url, $temp_filename)) {
+                // TRANS: Server exception thrown when an avatar could not be fetched.
+                // TRANS: %s is the failed avatar URL.
+                throw new ServerException(sprintf(_m('Unable to fetch avatar from %s.'), $url));
+            }
+
+            $id = $dest->id;
+            // @fixme should we be using different ids?
+            $imagefile = new ImageFile($id, $temp_filename);
+            $filename = Avatar::filename($id,
+                                         image_type_to_extension($imagefile->type),
+                                         null,
+                                         common_timestamp());
+            rename($temp_filename, Avatar::path($filename));
+        } catch (Exception $e) {
+            unlink($temp_filename);
+            throw $e;
+        }
+        // @fixme hardcoded chmod is lame, but seems to be necessary to
+        // keep from accidentally saving images from command-line (queues)
+        // that can't be read from web server, which causes hard-to-notice
+        // problems later on:
+        //
+        // http://status.net/open-source/issues/2663
+        chmod(Avatar::path($filename), 0644);
+
+        $dest->setOriginal($filename);
+    }
+
+    /**
+     * Fetch an attachment from Yammer and save it into our system.
+     * Unlike avatars, the attachment URLs are guarded by authentication,
+     * so we need to run the HTTP hit through our OAuth API client.
+     *
+     * @param string $url
+     * @param User $user
+     * @return MediaFile
+     *
+     * @throws Exception on low-level network or HTTP error
+     */
+    private function saveAttachment($url, User $user)
+    {
+        // Fetch the attachment...
+        // WARNING: file must fit in memory here :(
+        $body = $this->client->fetchUrl($url);
+
+        // Save to a temporary file and shove it into our file-attachment space...
+        $temp = tmpfile();
+        fwrite($temp, $body);
+        try {
+            $upload = MediaFile::fromFilehandle($temp, $user->getProfile());
+            fclose($temp);
+            return $upload;
+        } catch (Exception $e) {
+            fclose($temp);
+            throw $e;
+        }
+    }
+}
index 211728c497fa9381bf53671738d1f2b8172768c7..59c4be2b912b93d82a87c53893f09f22946f24de 100755 (executable)
@@ -34,7 +34,7 @@ USAGE: allsites.php [OPTIONS]
 
 ENDOFHELP;
 
-require_once INSTALLDIR.'/scripts/commandline.inc';
+require_once INSTALLDIR.'/scripts/commandline.inc.php';
 
 function print_all_sites() {
 
index 740ae25d446bbd0210f9af4aa6945b57a9d41fa1..409c2737e28b9120b6d1b00d115b87c9711137aa 100644 (file)
@@ -33,7 +33,7 @@ Export a StatusNet user history to a file
 
 END_OF_EXPORTACTIVITYSTREAM_HELP;
 
-require_once INSTALLDIR.'/scripts/commandline.inc';
+require_once INSTALLDIR.'/scripts/commandline.inc.php';
 
 try {
     $user = getUser();
index cec5773683ef8ef52d7c7b13ab615fe896a2163c..6a4c8c972ce6f396b072e3f97b8076c65ba93f46 100755 (executable)
@@ -32,7 +32,7 @@ Gives plugins a chance to update the database schema.
 
 END_OF_CHECKSCHEMA_HELP;
 
-require_once INSTALLDIR.'/scripts/commandline.inc';
+require_once INSTALLDIR.'/scripts/commandline.inc.php';
 
 function tableDefs()
 {
index 573abf1ed0c8d246f92b04408acdba90256e2523..408141d847097a2a42cceac9f7f9f4d287e691e5 100755 (executable)
@@ -33,7 +33,7 @@ Will print '.' for each file, except for deleted ones which are marked as 'x'.
 
 END_OF_HELP;
 
-require_once INSTALLDIR.'/scripts/commandline.inc';
+require_once INSTALLDIR.'/scripts/commandline.inc.php';
 
 if (!have_option('y', 'yes')) {
     print "About to delete local file entries where the file cannot be found. Are you sure? [y/N] ";
index 470d6c1b91b2c422397139f950889711bf9949fb..ecb587d0c054491e04d4ae6081c04a830c851c56 100755 (executable)
@@ -34,7 +34,7 @@ WARNING: This has not been tested thoroughly. Maybe we've missed a table to comp
 
 END_OF_HELP;
 
-require_once INSTALLDIR.'/scripts/commandline.inc';
+require_once INSTALLDIR.'/scripts/commandline.inc.php';
 
 if (!have_option('y', 'yes')) {
     print "About to delete profiles that we think are useless to save. Are you sure? [y/N] ";
index aef3f54aff50e1e305e402bee73a6ed1d9522bfd..04bf1083eef8e65b4261657bbe6b41f684c2a3f8 100755 (executable)
@@ -35,7 +35,7 @@ If the script seems to stop, it is processing correct File_thumbnail entries.
 
 END_OF_HELP;
 
-require_once INSTALLDIR.'/scripts/commandline.inc';
+require_once INSTALLDIR.'/scripts/commandline.inc.php';
 
 if (!have_option('y', 'yes')) {
     print "About to delete locally generated thumbnails to allow regeneration. Are you sure? [y/N] ";
index 4ba24c275a37031ac0efe583cdde5affb0d376b0..c6756a5cd623865ab798e59d984c937fa76a408c 100755 (executable)
@@ -34,7 +34,7 @@ Deletes a user's confirmed Jabber/XMPP address from the database.
 
 END_OF_DELETEUSER_HELP;
 
-require_once INSTALLDIR.'/scripts/commandline.inc';
+require_once INSTALLDIR.'/scripts/commandline.inc.php';
 
 if (have_option('i', 'id')) {
     $id = get_option_value('i', 'id');
index c67d6275d89194cbcaf1641443e695a9ce14cd03..5904681edd8a7fbea0ad96b0e76373d37f09d6c4 100755 (executable)
@@ -33,7 +33,7 @@ clears the cached object based on the args
 
 END_OF_CLEARCACHE_HELP;
 
-require_once INSTALLDIR.'/scripts/commandline.inc';
+require_once INSTALLDIR.'/scripts/commandline.inc.php';
 
 $karg = get_option_value('k', 'key');
 
index 256743f5353bc43ff2c3a4c33957bd432d389223..5ffa5bda0de9e0611cc402d0c69da82869782828 100755 (executable)
@@ -33,7 +33,7 @@ Perform commands on behalf of a user, such as sub, unsub, join, drop
 
 END_OF_USERROLE_HELP;
 
-require_once INSTALLDIR.'/scripts/commandline.inc';
+require_once INSTALLDIR.'/scripts/commandline.inc.php';
 
 function interpretCommand($user, $body)
 {
diff --git a/scripts/commandline.inc b/scripts/commandline.inc
deleted file mode 100644 (file)
index 392166a..0000000
+++ /dev/null
@@ -1,249 +0,0 @@
-<?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/>.
- */
-
-// -*- mode: php -*-
-
-# Abort if called from a web server
-
-if (isset($_SERVER) && array_key_exists('REQUEST_METHOD', $_SERVER)) {
-    print "This script must be run from the command line\n";
-    exit();
-}
-
-define('GNUSOCIAL', true);
-define('STATUSNET', true); //compatibility
-
-define('GNUSOCIAL_CLI', true);  // to know we're in a CLI environment
-
-// Set various flags so we don't time out on long-running processes
-
-ini_set("max_execution_time", "0");
-ini_set("max_input_time", "0");
-set_time_limit(0);
-mb_internal_encoding('UTF-8');
-error_reporting(E_ALL & ~E_STRICT & ~E_DEPRECATED);
-
-// Add extlib to our path so we can get Console_Getopt
-
-$_extra_path = array(INSTALLDIR.'/extlib/');
-
-set_include_path(implode(PATH_SEPARATOR, $_extra_path) . PATH_SEPARATOR . get_include_path());
-
-require_once 'Console/Getopt.php';
-
-// Note: $shortoptions and $longoptions should be pre-defined!
-
-$_default_shortoptions = 'qvhc:s:p:';
-
-$_default_longoptions = array('quiet', 'verbose', 'help', 'conf=', 'server=', 'path=');
-
-if (isset($shortoptions)) {
-    $shortoptions .= $_default_shortoptions;
-} else {
-    $shortoptions = $_default_shortoptions;
-}
-
-if (isset($longoptions)) {
-    $longoptions = array_merge($longoptions, $_default_longoptions);
-} else {
-    $longoptions = $_default_longoptions;
-}
-
-$parser = new Console_Getopt();
-
-$result = $parser->getopt($argv, $shortoptions, $longoptions);
-
-if (PEAR::isError($result)) {
-    print $result->getMessage()."\n";
-    exit(1);
-} else {
-    list($options, $args) = $result;
-}
-
-function show_help()
-{
-    global $helptext;
-
-    $_default_help_text = <<<END_OF_DEFAULT
-      General options:
-
-    -q --quiet           Quiet (little output)
-    -v --verbose         Verbose (lots of output)
-    -c --conf=<filename> Use <filename> as config file
-    -s --server=<name>   Use <name> as server name
-    -p --path=<path>     Use <path> as path name
-    -h --help            Show this message and quit.
-
-END_OF_DEFAULT;
-    if (isset($helptext)) {
-        print $helptext;
-    }
-    print $_default_help_text;
-    exit(0);
-}
-
-foreach ($options as $option) {
-
-    switch ($option[0]) {
-     case '--server':
-     case 's':
-        $server = $option[1];
-        break;
-
-     case '--path':
-     case 'p':
-        $path = $option[1];
-        break;
-
-     case '--conf':
-     case 'c':
-        $conffile = $option[1];
-        break;
-
-     case '--help':
-     case 'h':
-        show_help();
-    }
-}
-
-require_once INSTALLDIR . '/lib/common.php';
-
-set_error_handler('common_error_handler');
-
-// Set up the language infrastructure so we can localize anything that
-// needs to be sent out to users, such as mail notifications.
-common_init_language();
-
-function _make_matches($opt, $alt)
-{
-    $matches = array();
-
-    if (strlen($opt) > 1 && 0 != strncmp($opt, '--', 2)) {
-        $matches[] = '--'.$opt;
-    } else {
-        $matches[] = $opt;
-    }
-
-    if (!empty($alt)) {
-        if (strlen($alt) > 1 && 0 != strncmp($alt, '--', 2)) {
-            $matches[] = '--'.$alt;
-        } else {
-            $matches[] = $alt;
-        }
-    }
-
-    return $matches;
-}
-
-function have_option($opt, $alt=null)
-{
-    global $options;
-
-    $matches = _make_matches($opt, $alt);
-
-    foreach ($options as $option) {
-        if (in_array($option[0], $matches)) {
-            return true;
-        }
-    }
-
-    return false;
-}
-
-function get_option_value($opt, $alt=null)
-{
-    global $options;
-
-    $matches = _make_matches($opt, $alt);
-
-    foreach ($options as $option) {
-        if (in_array($option[0], $matches)) {
-            return $option[1];
-        }
-    }
-
-    return null;
-}
-
-class NoUserArgumentException extends Exception
-{
-}
-
-function getUser()
-{
-    $user = null;
-
-    if (have_option('i', 'id')) {
-        $id = get_option_value('i', 'id');
-        $user = User::getKV('id', $id);
-        if (empty($user)) {
-            throw new Exception("Can't find user with id '$id'.");
-        }
-    } else if (have_option('n', 'nickname')) {
-        $nickname = get_option_value('n', 'nickname');
-        $user = User::getKV('nickname', $nickname);
-        if (empty($user)) {
-            throw new Exception("Can't find user with nickname '$nickname'");
-        }
-    } else {
-        throw new NoUserArgumentException("No user argument specified.");
-    }
-
-    return $user;
-}
-
-/** "Printf not quiet" */
-
-function printfnq()
-{
-    if (have_option('q', 'quiet')) {
-        return null;
-    }
-
-    $cargs  = func_num_args();
-
-    if ($cargs == 0) {
-        return 0;
-    }
-
-    $args   = func_get_args();
-    $format = array_shift($args);
-
-    return vprintf($format, $args);
-}
-
-/** "Print when verbose" */
-
-function printfv()
-{
-    if (!have_option('v', 'verbose')) {
-        return null;
-    }
-
-    $cargs  = func_num_args();
-
-    if ($cargs == 0) {
-        return 0;
-    }
-
-    $args   = func_get_args();
-    $format = array_shift($args);
-
-    return vprintf($format, $args);
-}
diff --git a/scripts/commandline.inc.php b/scripts/commandline.inc.php
new file mode 100644 (file)
index 0000000..5f2e1d8
--- /dev/null
@@ -0,0 +1,250 @@
+<?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/>.
+ */
+
+// -*- mode: php -*-
+
+# Abort if called from a web server
+
+if (isset($_SERVER) && array_key_exists('REQUEST_METHOD', $_SERVER)) {
+    print "This script must be run from the command line\n";
+    exit();
+}
+
+define('GNUSOCIAL', true);
+define('STATUSNET', true); //compatibility
+
+define('GNUSOCIAL_CLI', true);  // to know we're in a CLI environment
+
+// Set various flags so we don't time out on long-running processes
+
+ini_set("max_execution_time", "0");
+ini_set("max_input_time", "0");
+set_time_limit(0);
+mb_internal_encoding('UTF-8');
+error_reporting(0);
+# DEBUG: error_reporting(E_ALL & ~E_STRICT & ~E_DEPRECATED);
+
+// Add extlib to our path so we can get Console_Getopt
+
+$_extra_path = array(INSTALLDIR.'/extlib/');
+
+set_include_path(implode(PATH_SEPARATOR, $_extra_path) . PATH_SEPARATOR . get_include_path());
+
+require_once 'Console/Getopt.php';
+
+// Note: $shortoptions and $longoptions should be pre-defined!
+
+$_default_shortoptions = 'qvhc:s:p:';
+
+$_default_longoptions = array('quiet', 'verbose', 'help', 'conf=', 'server=', 'path=');
+
+if (isset($shortoptions)) {
+    $shortoptions .= $_default_shortoptions;
+} else {
+    $shortoptions = $_default_shortoptions;
+}
+
+if (isset($longoptions)) {
+    $longoptions = array_merge($longoptions, $_default_longoptions);
+} else {
+    $longoptions = $_default_longoptions;
+}
+
+$parser = new Console_Getopt();
+
+$result = $parser->getopt($argv, $shortoptions, $longoptions);
+
+if (PEAR::isError($result)) {
+    print $result->getMessage()."\n";
+    exit(1);
+} else {
+    list($options, $args) = $result;
+}
+
+function show_help()
+{
+    global $helptext;
+
+    $_default_help_text = <<<END_OF_DEFAULT
+      General options:
+
+    -q --quiet           Quiet (little output)
+    -v --verbose         Verbose (lots of output)
+    -c --conf=<filename> Use <filename> as config file
+    -s --server=<name>   Use <name> as server name
+    -p --path=<path>     Use <path> as path name
+    -h --help            Show this message and quit.
+
+END_OF_DEFAULT;
+    if (isset($helptext)) {
+        print $helptext;
+    }
+    print $_default_help_text;
+    exit(0);
+}
+
+foreach ($options as $option) {
+
+    switch ($option[0]) {
+     case '--server':
+     case 's':
+        $server = $option[1];
+        break;
+
+     case '--path':
+     case 'p':
+        $path = $option[1];
+        break;
+
+     case '--conf':
+     case 'c':
+        $conffile = $option[1];
+        break;
+
+     case '--help':
+     case 'h':
+        show_help();
+    }
+}
+
+require_once INSTALLDIR . '/lib/common.php';
+
+set_error_handler('common_error_handler');
+
+// Set up the language infrastructure so we can localize anything that
+// needs to be sent out to users, such as mail notifications.
+common_init_language();
+
+function _make_matches($opt, $alt)
+{
+    $matches = array();
+
+    if (strlen($opt) > 1 && 0 != strncmp($opt, '--', 2)) {
+        $matches[] = '--'.$opt;
+    } else {
+        $matches[] = $opt;
+    }
+
+    if (!empty($alt)) {
+        if (strlen($alt) > 1 && 0 != strncmp($alt, '--', 2)) {
+            $matches[] = '--'.$alt;
+        } else {
+            $matches[] = $alt;
+        }
+    }
+
+    return $matches;
+}
+
+function have_option($opt, $alt=null)
+{
+    global $options;
+
+    $matches = _make_matches($opt, $alt);
+
+    foreach ($options as $option) {
+        if (in_array($option[0], $matches)) {
+            return true;
+        }
+    }
+
+    return false;
+}
+
+function get_option_value($opt, $alt=null)
+{
+    global $options;
+
+    $matches = _make_matches($opt, $alt);
+
+    foreach ($options as $option) {
+        if (in_array($option[0], $matches)) {
+            return $option[1];
+        }
+    }
+
+    return null;
+}
+
+class NoUserArgumentException extends Exception
+{
+}
+
+function getUser()
+{
+    $user = null;
+
+    if (have_option('i', 'id')) {
+        $id = get_option_value('i', 'id');
+        $user = User::getKV('id', $id);
+        if (empty($user)) {
+            throw new Exception("Can't find user with id '$id'.");
+        }
+    } else if (have_option('n', 'nickname')) {
+        $nickname = get_option_value('n', 'nickname');
+        $user = User::getKV('nickname', $nickname);
+        if (empty($user)) {
+            throw new Exception("Can't find user with nickname '$nickname'");
+        }
+    } else {
+        throw new NoUserArgumentException("No user argument specified.");
+    }
+
+    return $user;
+}
+
+/** "Printf not quiet" */
+
+function printfnq()
+{
+    if (have_option('q', 'quiet')) {
+        return null;
+    }
+
+    $cargs  = func_num_args();
+
+    if ($cargs == 0) {
+        return 0;
+    }
+
+    $args   = func_get_args();
+    $format = array_shift($args);
+
+    return vprintf($format, $args);
+}
+
+/** "Print when verbose" */
+
+function printfv()
+{
+    if (!have_option('v', 'verbose')) {
+        return null;
+    }
+
+    $cargs  = func_num_args();
+
+    if ($cargs == 0) {
+        return 0;
+    }
+
+    $args   = func_get_args();
+    $format = array_shift($args);
+
+    return vprintf($format, $args);
+}
index 692cedf8d1e7396a267ea618cd1d89f7955d55c6..910c663b016141fed6cd44c3b3da17e801576b87 100755 (executable)
@@ -27,7 +27,7 @@ console.php - provide an interactive PHP interpreter for testing
 
 ENDOFHELP;
 
-require_once INSTALLDIR.'/scripts/commandline.inc';
+require_once INSTALLDIR.'/scripts/commandline.inc.php';
 
 // Assume we're on a terminal if on Windows, otherwise posix_isatty tells us.
 define('CONSOLE_INTERACTIVE', !function_exists('posix_isatty') || posix_isatty(0));
index 624043161da9f19fe0e3512e760e0f770e3f2ca4..e5b47df6dee7daf09c13f59de2c74ab82197c470 100755 (executable)
@@ -49,7 +49,7 @@ Creates a lot of test users and notices to (loosely) simulate a real server.
 
 END_OF_CREATESIM_HELP;
 
-require_once INSTALLDIR.'/scripts/commandline.inc';
+require_once INSTALLDIR.'/scripts/commandline.inc.php';
 
 // XXX: make these command-line options
 
@@ -71,7 +71,7 @@ function newGroup($i, $j)
 
     // Pick a random user to be the admin
 
-    $n = rand(0, max($j - 1, 0));
+    $n = mt_rand(0, max($j - 1, 0));
     $user = User::getKV('nickname', sprintf('%s%d', $userprefix, $n));
 
     $group = User_group::register(array('nickname' => sprintf('%s%d', $groupprefix, $i),
@@ -86,10 +86,10 @@ function newNotice($i, $tagmax)
 
     $options = array('scope' => Notice::defaultScope());
 
-    $n = rand(0, $i - 1);
+    $n = mt_rand(0, $i - 1);
     $user = User::getKV('nickname', sprintf('%s%d', $userprefix, $n));
 
-    $is_reply = rand(0, 1);
+    $is_reply = mt_rand(0, 1);
 
     $content = testNoticeContent();
 
@@ -97,30 +97,30 @@ function newNotice($i, $tagmax)
         $stream = new InboxNoticeStream($user->getProfile(), $user->getProfile());
         $notices = $stream->getNotices(0, 20);
         if ($notices->N > 0) {
-            $nval = rand(0, $notices->N - 1);
+            $nval = mt_rand(0, $notices->N - 1);
             $notices->fetch(); // go to 0th
             for ($i = 0; $i < $nval; $i++) {
                 $notices->fetch();
             }
             $options['reply_to'] = $notices->id;
-            $dont_use_nickname = rand(0, 2);
+            $dont_use_nickname = mt_rand(0, 2);
             if ($dont_use_nickname != 0) {
                 $rprofile = $notices->getProfile();
                 $content = "@".$rprofile->nickname." ".$content;
             }
-            $private_to_addressees = rand(0, 4);
+            $private_to_addressees = mt_rand(0, 4);
             if ($private_to_addressees == 0) {
                 $options['scope'] |= Notice::ADDRESSEE_SCOPE;
             }
         }
     } else {
-        $is_directed = rand(0, 4);
+        $is_directed = mt_rand(0, 4);
 
         if ($is_directed == 0) {
             $subs = $user->getSubscribed(0, 100)->fetchAll();
             if (count($subs) > 0) {
                 $seen = array();
-                $f = rand(0, 9);
+                $f = mt_rand(0, 9);
                 if ($f <= 6) {
                     $addrs = 1;
                 } else if ($f <= 8) {
@@ -129,7 +129,7 @@ function newNotice($i, $tagmax)
                     $addrs = 3;
                 }
                 for ($m = 0; $m < $addrs; $m++) {
-                    $x = rand(0, count($subs) - 1);
+                    $x = mt_rand(0, count($subs) - 1);
                     if ($seen[$x]) {
                         continue;
                     }
@@ -140,7 +140,7 @@ function newNotice($i, $tagmax)
                     $rprofile = $subs[$x];
                     $content = "@".$rprofile->nickname." ".$content;
                 }
-                $private_to_addressees = rand(0, 4);
+                $private_to_addressees = mt_rand(0, 4);
                 if ($private_to_addressees == 0) {
                     $options['scope'] |= Notice::ADDRESSEE_SCOPE;
                 }
@@ -148,36 +148,36 @@ function newNotice($i, $tagmax)
         }
     }
 
-    $has_hash = rand(0, 2);
+    $has_hash = mt_rand(0, 2);
 
     if ($has_hash == 0) {
-        $hashcount = rand(0, 2);
+        $hashcount = mt_rand(0, 2);
         for ($j = 0; $j < $hashcount; $j++) {
-            $h = rand(0, $tagmax);
+            $h = mt_rand(0, $tagmax);
             $content .= " #tag{$h}";
         }
     }
 
-    $in_group = rand(0, 5);
+    $in_group = mt_rand(0, 5);
 
     if ($in_group == 0) {
         $groups = $user->getGroups();
         if ($groups instanceof User_group) {
-            $gval = rand(0, $groups->N - 1);
+            $gval = mt_rand(0, $groups->N - 1);
             $groups->fetch(); // go to 0th
             for ($i = 0; $i < $gval; $i++) {
                 $groups->fetch();
             }
             $options['groups'] = array($groups->id);
             $content = "!".$groups->nickname." ".$content;
-            $private_to_group = rand(0, 2);
+            $private_to_group = mt_rand(0, 2);
             if ($private_to_group == 0) {
                 $options['scope'] |= Notice::GROUP_SCOPE;
             }
         }
     }
 
-    $private_to_site = rand(0, 4);
+    $private_to_site = mt_rand(0, 4);
 
     if ($private_to_site == 0) {
         $options['scope'] |= Notice::SITE_SCOPE;
@@ -191,7 +191,7 @@ function newMessage($i)
 {
     global $userprefix;
 
-    $n = rand(0, $i - 1);
+    $n = mt_rand(0, $i - 1);
     $user = User::getKV('nickname', sprintf('%s%d', $userprefix, $n));
 
     $content = testNoticeContent();
@@ -202,7 +202,7 @@ function newMessage($i)
         return;
     }
 
-    $j = rand(0, count($friends) - 1);
+    $j = mt_rand(0, count($friends) - 1);
     
     $other = $friends[$j];
 
@@ -212,7 +212,7 @@ function newMessage($i)
 function newSub($i)
 {
     global $userprefix;
-    $f = rand(0, $i - 1);
+    $f = mt_rand(0, $i - 1);
 
     $fromnick = sprintf('%s%d', $userprefix, $f);
 
@@ -222,7 +222,7 @@ function newSub($i)
         throw new Exception("Can't find user '$fromnick'.");
     }
 
-    $t = rand(0, $i - 1);
+    $t = mt_rand(0, $i - 1);
 
     if ($t == $f) {
         $t++;
@@ -250,7 +250,7 @@ function newJoin($u, $g)
     global $userprefix;
     global $groupprefix;
 
-    $userNumber = rand(0, $u - 1);
+    $userNumber = mt_rand(0, $u - 1);
 
     $userNick = sprintf('%s%d', $userprefix, $userNumber);
 
@@ -260,7 +260,7 @@ function newJoin($u, $g)
         throw new Exception("Can't find user '$fromnick'.");
     }
 
-    $groupNumber = rand(0, $g - 1);
+    $groupNumber = mt_rand(0, $g - 1);
 
     $groupNick = sprintf('%s%d', $groupprefix, $groupNumber);
 
@@ -281,7 +281,7 @@ function newFave($u)
     global $userprefix;
     global $groupprefix;
 
-    $userNumber = rand(0, $u - 1);
+    $userNumber = mt_rand(0, $u - 1);
 
     $userNick = sprintf('%s%d', $userprefix, $userNumber);
 
@@ -293,7 +293,7 @@ function newFave($u)
 
     // NB: it's OK to like your own stuff!
 
-    $otherNumber = rand(0, $u - 1);
+    $otherNumber = mt_rand(0, $u - 1);
 
     $otherNick = sprintf('%s%d', $userprefix, $otherNumber);
 
@@ -309,7 +309,7 @@ function newFave($u)
         return;
     }
 
-    $idx = rand(0, count($notices) - 1);
+    $idx = mt_rand(0, count($notices) - 1);
 
     $notice = $notices[$idx];
 
@@ -328,7 +328,7 @@ function testNoticeContent()
         return "test notice content";
     }
 
-    $cnt = rand(3, 8);
+    $cnt = mt_rand(3, 8);
 
     $ids = array_rand($words, $cnt);
 
@@ -393,7 +393,7 @@ function main($usercount, $groupcount, $noticeavg, $subsavg, $joinsavg, $tagmax)
 
     for ($i = 0; $i < $events; $i++)
     {
-        $e = rand(0, $events);
+        $e = mt_rand(0, $events);
 
         if ($e >= 0 && $e <= $ut) {
             printfv("$i Creating user $n\n");
index f76a3dedc780e2207a3446c226fd535027450adb..fc00e70b083b91f9d9d721c17bffc78e7044f116 100755 (executable)
@@ -33,7 +33,7 @@ deletes a group from the database
 
 END_OF_DELETEGROUP_HELP;
 
-require_once INSTALLDIR.'/scripts/commandline.inc';
+require_once INSTALLDIR.'/scripts/commandline.inc.php';
 
 if (have_option('i', 'id')) {
     $id = get_option_value('i', 'id');
index 8eed6ff97b718ce7ad77f6d00a2e60a4fdba785c..c1ef5a449a9869c3ffb06d1cce2d1c7e8c371561 100755 (executable)
@@ -34,7 +34,7 @@ deletes a profile from the database
 
 END_OF_DELETEUSER_HELP;
 
-require_once INSTALLDIR.'/scripts/commandline.inc';
+require_once INSTALLDIR.'/scripts/commandline.inc.php';
 
 if (have_option('i', 'id')) {
     $id = get_option_value('i', 'id');
index 6341b72706cc0b5e1878c8ce59265334d18029b5..9ca4d9dad5271640ca3a9b3975823451d72bc1d0 100755 (executable)
@@ -95,7 +95,7 @@ var_dump($replacements);
 $template = file_get_contents(dirname(__FILE__) . '/doxygen.tmpl');
 $template = strtr($template, $replacements);
 
-$templateFile = tempnam(sys_get_temp_dir(), 'statusnet-doxygen');
+$templateFile = tempnam(common_get_temp_dir(), 'statusnet-doxygen');
 file_put_contents($templateFile, $template);
 
 $cmd = "doxygen " . escapeshellarg($templateFile);
index 9c5e3cf8b38c2fd9808803ba9c2c8437fcddfb89..05638cda4cb22aed28c57fe79916a8c1b1814a49 100755 (executable)
@@ -34,7 +34,7 @@ Attempt to pull a schema definition for a given table.
 END_OF_CHECKSCHEMA_HELP;
 
 $longoptions = array('diff', 'all', 'create', 'update', 'raw', 'checksum');
-require_once INSTALLDIR.'/scripts/commandline.inc';
+require_once INSTALLDIR.'/scripts/commandline.inc.php';
 
 function indentOptions($indent)
 {
@@ -250,4 +250,4 @@ if (count($args)) {
     }
 } else {
     show_help($helptext);
-}
\ No newline at end of file
+}
index 07ada7f9d95c49089192243f430bcd7f6c39ebb4..c029b1e7d4a31359802e8459eb785b58f805e538 100755 (executable)
@@ -33,7 +33,7 @@ Stray incompletely deleted items cause various fun problems!
 
 END_OF_USERROLE_HELP;
 
-require_once INSTALLDIR.'/scripts/commandline.inc';
+require_once INSTALLDIR.'/scripts/commandline.inc.php';
 
 /**
  * Find the highest profile_id currently listed in the notice table;
diff --git a/scripts/fixup_group_profiles.php b/scripts/fixup_group_profiles.php
new file mode 100755 (executable)
index 0000000..43cdfd0
--- /dev/null
@@ -0,0 +1,98 @@
+#!/usr/bin/env php
+<?php
+/*
+ * StatusNet - the 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/>.
+ */
+
+// Abort if called from a web server
+if (isset($_SERVER) && array_key_exists('REQUEST_METHOD', $_SERVER)) {
+    print "This script must be run from the command line\n";
+    exit();
+}
+
+define('INSTALLDIR', realpath(dirname(__FILE__) . '/..'));
+
+require_once(INSTALLDIR . '/scripts/commandline.inc.php');
+error_reporting(E_ALL | E_STRICT);
+
+$relative = common_path('group/');
+print('Searching for profiles with relative=' . $relative . ' ...' . PHP_EOL);
+
+$profile = new Profile();
+$profile->whereAdd("`profileurl` LIKE '" . $relative . "%'");
+$cnt = $profile->find();
+
+print('Found ' . $cnt . ' profiles.' . PHP_EOL);
+
+if ($cnt == 0) {
+    // Nothing to do
+    print('All profiles are fixed. :-)' . PHP_EOL);
+    exit;
+}
+
+$profiles = array();
+
+while ($profile->fetch()) {
+    array_push($profiles, "'" . $profile->nickname . "'");
+}
+
+// Cleanup
+unset($profile);
+
+print('Have ' . count($profiles) . ' profiles found.' . PHP_EOL);
+
+// Make sure both are equal
+assert(count($profiles) == $cnt);
+
+print('Looking for matching user groups without local groups ...' . PHP_EOL);
+
+$group = new User_group();
+$group->whereAdd("`nickname` IN (" . implode(', ', $profiles) . ") AND `uri` NOT LIKE '" . $relative . "%'");
+$cnt = $group->find();
+
+print('Found ' . $cnt . ' groups.' . PHP_EOL);
+
+while ($group->fetch()) {
+    print('Fixing profile for group #' . $group->id . ',nickname=' . $group->nickname . ' to ' . $group->uri . ' ...' . PHP_EOL);
+
+    if ($group->profile_id < 1) {
+        print('INCONSISTENCY - Group ' . $group->nickname . ' has no profile_id set. Cannot fix!' . PHP_EOL);
+    }
+
+    $profile = new Profile();
+    $profile->id = $group->profile_id;
+    $cnt2 = $profile->find();
+
+    if ($cnt2 == 0) {
+        print('INCONSISTENCY - Cannot find profile ' . $group->nickname . ' - skipped!' . PHP_EOL);
+        continue;
+    } elseif ($cnt2 > 1) {
+        print('INCONSISTENCY - Group ' . $group->nickname . ' has more than one (' . $cnt2 . ') profiles - skipped!' . PHP_EOL);
+        continue;
+    } else {
+       // Dummy fetch
+       $profile->fetch();
+    }
+
+    $original = clone($profile);
+    $profile->profileurl = $group->uri;
+
+    $result = $profile->update($original);
+    if (!$result) {
+        common_log_db_error($profile, 'UPDATE', __FILE__);
+    }
+}
index 51178a725c6d5acfb369cfcbebcb81387c897b75..a9952b4304fc2d4f01dd5cd03a25eff1b9d70205 100755 (executable)
@@ -26,9 +26,9 @@ Flush the url router from cache.
 
 END_OF_FLUSHROUTER_HELP;
 
-require_once INSTALLDIR.'/scripts/commandline.inc';
+require_once INSTALLDIR.'/scripts/commandline.inc.php';
 
 $cache = Cache::instance();
 $cache->delete(Router::cacheKey());
 
-print "OK.\n";
\ No newline at end of file
+print "OK.\n";
index b7f385ac45f8652990f2849904845726814c470e..3950fb7cf71830b4b51b316bbf4606db130f8fca 100755 (executable)
@@ -29,7 +29,7 @@ Flush the site with the given name from memcached.
 
 END_OF_FLUSHSITE_HELP;
 
-require_once INSTALLDIR.'/scripts/commandline.inc';
+require_once INSTALLDIR.'/scripts/commandline.inc.php';
 
 $nickname = common_config('site', 'nickname');
 
@@ -42,4 +42,4 @@ if (empty($sn)) {
 
 print "Flushing cache for {$nickname}...";
 $sn->decache();
-print "OK.\n";
\ No newline at end of file
+print "OK.\n";
index 8274c37c0f89c01e4ce485bc8f04dec7e9bdbbcc..00e845f80db821a8ccd1a2008b2ff3a078cf4968 100755 (executable)
@@ -25,6 +25,6 @@ getpiddir.php - print out the currently configured PID directory
 
 ENDOFHELP;
 
-require_once INSTALLDIR.'/scripts/commandline.inc';
+require_once INSTALLDIR.'/scripts/commandline.inc.php';
 
 echo common_config('daemon', 'piddir');
index 448fbb6d32cceb9282804fa6a162a66893a23aa2..f7aa0f60f88088cf06857042cf424b3650263ccc 100755 (executable)
@@ -36,7 +36,7 @@ ENDOFHELP;
 // No unnecessary error reporting to avoid invalid daemon names
 error_reporting(E_ALL & ~E_STRICT & ~E_NOTICE);
 
-require_once INSTALLDIR.'/scripts/commandline.inc';
+require_once INSTALLDIR.'/scripts/commandline.inc.php';
 
 $daemons = array();
 
index dbe9c54c5ba9d838787dc2affbc3afe0265585f2..91c2dc7f646ec759ddac1bff7008876fbccee86c 100755 (executable)
@@ -28,6 +28,6 @@ prints out the current version of the software
 
 END_OF_HELP;
 
-require_once INSTALLDIR.'/scripts/commandline.inc';
+require_once INSTALLDIR.'/scripts/commandline.inc.php';
 
 print GNUSOCIAL_VERSION."\n";
index eb7d8297136cdb3dd461752d0ca8bc65439120c1..3b272868c0023753e45ed37b9e2b885db4b79dba 100755 (executable)
@@ -28,7 +28,7 @@ as if it were being run through the queue.
 
 END_OF_QUEUE_HELP;
 
-require_once INSTALLDIR.'/scripts/commandline.inc';
+require_once INSTALLDIR.'/scripts/commandline.inc.php';
 
 if (count($args) != 2) {
     show_help();
index 0298c00522b52b9d3d2d0dd3c4324a1fb7ae13bf..7d9ff1fe7dc7d1d65d0007c14e76219e713e196d 100755 (executable)
@@ -33,7 +33,7 @@ Daemon script for receiving new notices from IM users.
 
 END_OF_IM_HELP;
 
-require_once INSTALLDIR.'/scripts/commandline.inc';
+require_once INSTALLDIR.'/scripts/commandline.inc.php';
 
 class ImDaemon extends SpawningDaemon
 {
index a29526f27e1726f57f3679dcdab034fbf4350614..d121179f47a9e45e0fa1777d0d9f9c29c419b499 100755 (executable)
@@ -33,7 +33,7 @@ import an Atom feed from Twitter as notices by a user
 
 END_OF_IMPORTTWITTERATOM_HELP;
 
-require_once INSTALLDIR.'/scripts/commandline.inc';
+require_once INSTALLDIR.'/scripts/commandline.inc.php';
 require_once INSTALLDIR.'/extlib/htmLawed/htmLawed.php';
 
 function getAtomFeedDocument()
index bd73cbe79460b2c6788147237a7945367f4ebc98..df9aad10edd234c36991d48509b31bacbe32fc11 100644 (file)
@@ -34,7 +34,7 @@ Adds a local user to a local group.
 
 END_OF_HELP;
 
-require_once INSTALLDIR.'/scripts/commandline.inc';
+require_once INSTALLDIR.'/scripts/commandline.inc.php';
 
 try {
     $user = getUser();
index 8f9ef33e7edb2d33b2615d0023506e8479f489f5..fd1362ef5ea6672e45bef57d4d2b85003f172bc9 100644 (file)
@@ -34,7 +34,7 @@ Removes a local user from a local group.
 
 END_OF_HELP;
 
-require_once INSTALLDIR.'/scripts/commandline.inc';
+require_once INSTALLDIR.'/scripts/commandline.inc.php';
 
 try {
     $user = getUser();
index 3b1ef96a1e898617e86d56870f5c328106239bcc..5e9b6d22324b8b9844c843b431d3303b7b8b7046 100755 (executable)
@@ -26,7 +26,7 @@ as STDIN.
 
 END_OF_HELP;
 
-require_once INSTALLDIR.'/scripts/commandline.inc';
+require_once INSTALLDIR.'/scripts/commandline.inc.php';
 require_once INSTALLDIR.'/lib/mailhandler.php';
 
 if (common_config('emailpost', 'enabled')) {
index 157cae067db619a491c0ed9d8a07a8f8ae97f1a5..a3d9c70eb061bdb435826dfc78bead11b27e92b3 100755 (executable)
@@ -22,7 +22,7 @@
 
 define('INSTALLDIR', realpath(dirname(__FILE__) . '/..'));
 
-require_once INSTALLDIR.'/scripts/commandline.inc';
+require_once INSTALLDIR.'/scripts/commandline.inc.php';
 
 $base = INSTALLDIR;
 $encBase = escapeshellarg($base);
index 345d93c665745896d99c81e5d1623b56a2c3700f..3d3b1d3e841accdfaddcbe98d3af8d091ed8a787 100755 (executable)
@@ -32,7 +32,7 @@ makes a user the admin of a group
 
 END_OF_MAKEGROUPADMIN_HELP;
 
-require_once INSTALLDIR.'/scripts/commandline.inc';
+require_once INSTALLDIR.'/scripts/commandline.inc.php';
 
 $nickname = get_option_value('n', 'nickname');
 $groupname = get_option_value('g', 'group');
index 17b3e0fb678e5e06c207f95476d0929e3d169bd6..ff08ee24ce3ac60e8e03b03e7f3b2c543f394495 100644 (file)
@@ -37,7 +37,7 @@ an HTTP or HTTPS URL (http://example.com/social/site/user/nickname).
 
 END_OF_MOVEUSER_HELP;
 
-require_once INSTALLDIR.'/scripts/commandline.inc';
+require_once INSTALLDIR.'/scripts/commandline.inc.php';
 
 try {
 
index 4001833e8cf8a23d5ac15a2e6217a531b4eced2e..5e510d118fe74ab59bc93783b37e2d4a53e45a92 100755 (executable)
@@ -32,7 +32,7 @@ deletes a file and related notices from the database
 
 END_OF_HELP;
 
-require_once INSTALLDIR.'/scripts/commandline.inc';
+require_once INSTALLDIR.'/scripts/commandline.inc.php';
 
 if (have_option('i', 'id')) {
     $id = get_option_value('i', 'id');
index 1c9ea3353697b6f7d6e883efe100cceee94545d6..7524dabb15cfdf0cf2491e738cfccb62b54aa708 100755 (executable)
@@ -45,7 +45,7 @@ Global events:
 
 END_OF_QUEUECTL_HELP;
 
-require_once INSTALLDIR.'/scripts/commandline.inc';
+require_once INSTALLDIR.'/scripts/commandline.inc.php';
 
 function doSendControl($message, $event, $param='')
 {
index 582a3dd888f825ed0ff398a77629fffab9bf9628..bdd630f3d5a2e6ef54c8ff3982a5fe7d8a27977b 100755 (executable)
@@ -68,7 +68,7 @@ Daemon script for running queued items.
 
 END_OF_QUEUE_HELP;
 
-require_once INSTALLDIR.'/scripts/commandline.inc';
+require_once INSTALLDIR.'/scripts/commandline.inc.php';
 
 require_once(INSTALLDIR.'/lib/daemon.php');
 require_once(INSTALLDIR.'/classes/Queue_item.php');
index 97caf645cd6eb812904d9c68da110e958e30ca49..b7ee9f368ca32aee845c4f429f18a966f5a87199 100755 (executable)
@@ -34,7 +34,7 @@ registers a user in the database
 
 END_OF_REGISTERUSER_HELP;
 
-require_once INSTALLDIR.'/scripts/commandline.inc';
+require_once INSTALLDIR.'/scripts/commandline.inc.php';
 
 $nickname = get_option_value('n', 'nickname');
 $password = get_option_value('w', 'password');
index a4a7cd795b9afa9b487eeaa77c022666ee9d6341..8e718761d698a69412a3bc81c5be9156c7baf521 100755 (executable)
@@ -31,7 +31,7 @@ Remove duplicate URL entries in the file and file_redirection tables because the
 
 END_OF_HELP;
 
-require_once INSTALLDIR.'/scripts/commandline.inc';
+require_once INSTALLDIR.'/scripts/commandline.inc.php';
 
 if (!have_option('y', 'yes')) {
     print "About to remove duplicate URL entries in file and file_redirection tables. Are you sure? [y/N] ";
index 17f007b41206406c36d13e6711f7bda7d8535d71..c749b41a1253c4f51abe36e31be93a005bd88615 100644 (file)
@@ -33,7 +33,7 @@ neither ID or name provided, will create a new user.
 
 END_OF_RESTOREUSER_HELP;
 
-require_once INSTALLDIR.'/scripts/commandline.inc';
+require_once INSTALLDIR.'/scripts/commandline.inc.php';
 require_once INSTALLDIR.'/extlib/htmLawed/htmLawed.php';
 
 
index 0441bfe7ee9abef0ebc417ca31d2e4cb8bf9a8b9..9b89cbce7eccedaef96937a6536f4d29a2c852f9 100755 (executable)
@@ -33,7 +33,7 @@ Sends given email text to user.
 
 END_OF_USEREMAIL_HELP;
 
-require_once INSTALLDIR.'/scripts/commandline.inc';
+require_once INSTALLDIR.'/scripts/commandline.inc.php';
 
 if (have_option('i', 'id')) {
     $id = get_option_value('i', 'id');
index af55ddf3f0d971d9c8af92636104c9527ecf4cb9..ef452fdb064f61847689f811368abcfb4d4fba47 100755 (executable)
@@ -27,7 +27,7 @@ Delete old sessions from the server
 
 END_OF_GC_HELP;
 
-require_once INSTALLDIR.'/scripts/commandline.inc';
+require_once INSTALLDIR.'/scripts/commandline.inc.php';
 
 $maxlifetime = ini_get('session.gc_maxlifetime');
 
index 009c50dbf291061c4513c918341067780510fcd3..dc6843b92d3e16e56c2b46079061260f59a9aa35 100755 (executable)
@@ -39,7 +39,7 @@ With no args, lists all currently set values.
 
 END_OF_SETCONFIG_HELP;
 
-require_once INSTALLDIR.'/scripts/commandline.inc';
+require_once INSTALLDIR.'/scripts/commandline.inc.php';
 
 if (empty($args)) {
     if (have_option('a', 'all')) {
index 66964b2a088d58f252599646832ff17aaeec2bc8..b8feb207957ba3171714178c61e3975affa8bb30 100755 (executable)
@@ -27,7 +27,7 @@ Sets the password of user with name <username> to <password>
 
 END_OF_PASSWORD_HELP;
 
-require_once INSTALLDIR.'/scripts/commandline.inc';
+require_once INSTALLDIR.'/scripts/commandline.inc.php';
 
 if (count($args) < 2) {
     show_help();
index 19abce43c8018a5d1de97ca83e5740f730c2c294..3c234f2c31cdc430321c17d4abd082c94476a00c 100755 (executable)
@@ -31,7 +31,7 @@ With -d, delete the tag.
 
 END_OF_SETTAG_HELP;
 
-require_once INSTALLDIR.'/scripts/commandline.inc';
+require_once INSTALLDIR.'/scripts/commandline.inc.php';
 
 if (count($args) < 1) {
     show_help();
index 8ef08467d6be139dd2a50ee11670962cbeb30cf7..b4fe7b63ce9601b8c9d67648597a6bec63e1ce99 100755 (executable)
@@ -33,7 +33,7 @@ shows the cached object based on the args
 
 ENDOFHELP;
 
-require_once INSTALLDIR.'/scripts/commandline.inc';
+require_once INSTALLDIR.'/scripts/commandline.inc.php';
 
 $karg = get_option_value('k');
 
index e79b4e72242888f4661eedba444473e27caf6101..8b950eb0aa8e2d02e28da63f42ae4cbe9f35b3db 100755 (executable)
@@ -20,7 +20,7 @@
 
 define('INSTALLDIR', realpath(dirname(__FILE__) . '/..'));
 
-require_once INSTALLDIR.'/scripts/commandline.inc';
+require_once INSTALLDIR.'/scripts/commandline.inc.php';
 
 foreach (StatusNet::getActivePlugins() as $plugin=>$args) {
     echo "$plugin: ";
index eb18a98e20d510cb3dfd2d8feee39abbd341dfd7..986260e1d23bdf8d16ac5ad2b425fae4217325a2 100755 (executable)
@@ -26,7 +26,7 @@ Shows the structure of a table
 
 END_OF_SHOWTABLE_HELP;
 
-require_once INSTALLDIR.'/scripts/commandline.inc';
+require_once INSTALLDIR.'/scripts/commandline.inc.php';
 
 if (count($args) != 1) {
     show_help();
index 2ed3528c5e0d5b28338df53bb43a14d6a6d292f8..0fa72cea118cf0df81d69e9a83cf1806359abdc5 100755 (executable)
@@ -35,12 +35,14 @@ if [ $# -gt 1 ]; then
 fi
 
 DIR=`dirname $0`
-DAEMONS=`php $DIR/getvaliddaemons.php $ARGSG`
+DAEMONS=`$DIR/getvaliddaemons.php $ARGSG 2>/dev/null | grep -v "FUSE_EDEADLK"`
+
+echo "DAEMONS='${DAEMONS}'"
 
 for f in $DAEMONS; do
 
-    echo "Starting $f..."
-    php $f $ARGSD
+    echo "Starting '$f' ..."
+    php $f $ARGSD 2>/dev/null | grep -v "FUSE_EDEADLK"
     echo "DONE."
 
 done
index e725dd0bf0064588e490eecb90def35bc4d10ba9..e88fe26e22970c17ac944b188b41400f4c76908c 100755 (executable)
@@ -39,9 +39,9 @@ if [ $# -gt 1 ]; then
 fi
 
 SDIR=`dirname $0`
-DIR=`php $SDIR/getpiddir.php $SITE`
+DIR=`$SDIR/getpiddir.php $SITE 2>/dev/null | grep -v "FUSE_EDEADLK"`
 
-DAEMONS=`php $SDIR/getvaliddaemons.php $ARGSG`
+DAEMONS=`$SDIR/getvaliddaemons.php $ARGSG 2>/dev/null | grep -v "FUSE_EDEADLK"`
 
 for f in $DAEMONS; do
     f=$(basename $f .php)
@@ -52,7 +52,7 @@ for f in $DAEMONS; do
 
                PID=`cat $ff 2>/dev/null`
                if [ -n "$PID" ] ; then
-                       echo -n "Stopping $f ($PID)..."
+                       echo -n "Stopping '$f' ($PID)..."
                        if kill -3 $PID 2>/dev/null ; then
                                count=0
                                while kill -0 $PID 2>/dev/null ;  do
index 021b66885190dacbf944759738895272855256cc..165736816d8396c8d4d96bfb6cad1709d6a0cc63 100755 (executable)
@@ -36,7 +36,7 @@ Removes geolocation info from the given user's notices.
 
 END_OF_HELP;
 
-require_once INSTALLDIR.'/scripts/commandline.inc';
+require_once INSTALLDIR.'/scripts/commandline.inc.php';
 
 if (have_option('i', 'id')) {
     $id = get_option_value('i', 'id');
index b5955fd5aa9335a0ae259cdfb7baa24c3ea228bc..6cd2101ad7a4561378cf498456e99f569d3f25f3 100755 (executable)
@@ -26,7 +26,7 @@ Uncache users listed in an ID file, default 'ids.txt'.
 
 ENDOFHELP;
 
-require_once INSTALLDIR.'/scripts/commandline.inc';
+require_once INSTALLDIR.'/scripts/commandline.inc.php';
 
 $id_file = (count($args) > 1) ? $args[0] : 'ids.txt';
 
index abf9627cc71e6daffc61c3b26802b7a435bece14..c8024cb769a86fb6d868e52c483b6ef9b9084063 100755 (executable)
@@ -34,7 +34,7 @@ set the location for a profile
 
 END_OF_UPDATELOCATION_HELP;
 
-require_once INSTALLDIR.'/scripts/commandline.inc';
+require_once INSTALLDIR.'/scripts/commandline.inc.php';
 
 try {
     $user = null;
index 35b835e4944ac435ac24cf6dd43d5090efaa4932..c49187c299407c194b27cb669f75ac3d395b3206 100755 (executable)
@@ -29,7 +29,7 @@ update stored URLs in the system
 
 END_OF_UPDATEURLS_HELP;
 
-require_once INSTALLDIR.'/scripts/commandline.inc';
+require_once INSTALLDIR.'/scripts/commandline.inc.php';
 
 function main()
 {
index 977cb1b5bd037efcd9e603b47d62b34ee0035437..c6f3e28606a7fbd2c5ef03b229d6fb0f583beff1 100755 (executable)
@@ -29,7 +29,7 @@ Upgrade database schema and data to latest software
 
 END_OF_UPGRADE_HELP;
 
-require_once INSTALLDIR.'/scripts/commandline.inc';
+require_once INSTALLDIR.'/scripts/commandline.inc.php';
 
 function main()
 {
index 02c34678fb31eb1077a974a997f97c39c6e7ed56..91a9d3152bb7b72eb9abec81f43d730062b96a1b 100755 (executable)
@@ -33,7 +33,7 @@ Queries a user's registered email address, or queries the users with a given reg
 
 END_OF_USEREMAIL_HELP;
 
-require_once INSTALLDIR.'/scripts/commandline.inc';
+require_once INSTALLDIR.'/scripts/commandline.inc.php';
 
 if (have_option('i', 'id')) {
     $id = get_option_value('i', 'id');
index d1061b18322417a6afb9c18e634dd5c6c467a78e..a5eddeae5fc3dd5a1525ff6d12bdd2d1b4863b6e 100755 (executable)
@@ -34,7 +34,7 @@ modifies a role for the given user
 
 END_OF_USERROLE_HELP;
 
-require_once INSTALLDIR.'/scripts/commandline.inc';
+require_once INSTALLDIR.'/scripts/commandline.inc.php';
 
 if (have_option('i', 'id')) {
     $id = get_option_value('i', 'id');
index bd9124a91d38b1dd0cc6dcb793a9b7c12ff4d7d3..031be0cc4403919b92f225a41c222f6e5344860a 100644 (file)
@@ -18,13 +18,16 @@ class UserRightsTest extends PHPUnit_Framework_TestCase
     function setUp()
     {
         $user = User::getKV('nickname', 'userrightstestuser');
-        if ($user) {
+
+        if ($user instanceof User) {
             // Leftover from a broken test run?
             $profile = $user->getProfile();
             $user->delete();
             $profile->delete();
         }
+
         $this->user = User::register(array('nickname' => 'userrightstestuser'));
+
         if (!$this->user) {
             throw new Exception("Couldn't register userrightstestuser");
         }
index fb675c778e3c33754f7da53da80dd9c92806b973..4259c0cdc701dde222477542b0e59448e3395142 100755 (executable)
@@ -37,7 +37,7 @@ Options:
 
 END_OF_HELP;
 
-require_once INSTALLDIR.'/scripts/commandline.inc';
+require_once INSTALLDIR.'/scripts/commandline.inc.php';
 
 $user = get_option_value('n', 'nickname');
 $pass = get_option_value('p', 'password');
old mode 100755 (executable)
new mode 100644 (file)
index bea512a..3d8767a
@@ -20,7 +20,7 @@
 
 define('INSTALLDIR', realpath(dirname(__FILE__) . '/../..'));
 
-require_once INSTALLDIR . '/scripts/commandline.inc';
+require_once INSTALLDIR . '/scripts/commandline.inc.php';
 require_once INSTALLDIR . '/extlib/OAuth.php';
 
 $ini = parse_ini_file("oauth.ini");
old mode 100755 (executable)
new mode 100644 (file)
index a508c72..aac242d
@@ -52,7 +52,7 @@ $helptext = <<<END_OF_ETOKENS_HELP
 
 END_OF_ETOKENS_HELP;
 
-require_once INSTALLDIR . '/scripts/commandline.inc';
+require_once INSTALLDIR . '/scripts/commandline.inc.php';
 
 $token = $secret = $verifier = null;
 
index 23fc04b531567aedffc836627fc316eb7b563d88..6742ab1580b1dddd3c35772d70d878d6e2356bd8 100755 (executable)
@@ -40,7 +40,7 @@ $token        = null;
 $token_secret = null;
 $update       = null;
 
-require_once INSTALLDIR . '/scripts/commandline.inc';
+require_once INSTALLDIR . '/scripts/commandline.inc.php';
 
 if (have_option('t', 'oauth_token')) {
     $token = get_option_value('t', 'oauth_token');
old mode 100755 (executable)
new mode 100644 (file)
index a37538d..c20c7ee
@@ -37,7 +37,7 @@ END_OF_VERIFY_HELP;
 $token        = null;
 $token_secret = null;
 
-require_once INSTALLDIR . '/scripts/commandline.inc';
+require_once INSTALLDIR . '/scripts/commandline.inc.php';
 
 if (have_option('t', 'oauth_token')) {
     $token = get_option_value('t', 'oauth_token');