forked from GNUsocial/gnu-social
Merge branch '1.0.x' of git://gitorious.org/statusnet/mainline
Conflicts: lib/action.php plugins/OStatus/actions/ostatusinit.php
This commit is contained in:
commit
e36399974e
2
.gitignore
vendored
2
.gitignore
vendored
@ -25,3 +25,5 @@ good-config.php
|
||||
lac08.log
|
||||
php.log
|
||||
.DS_Store
|
||||
nbproject
|
||||
*.mo
|
||||
|
358
EVENTS.txt
358
EVENTS.txt
@ -118,16 +118,16 @@ EndShowHTML: Showing after the html element
|
||||
- $action: the current action
|
||||
|
||||
StartPublicGroupNav: Showing the public group nav menu
|
||||
- $action: the current action
|
||||
- $menu: the menu widget; use $menu->action for output
|
||||
|
||||
EndPublicGroupNav: At the end of the public group nav menu
|
||||
- $action: the current action
|
||||
- $menu: the menu widget; use $menu->action for output
|
||||
|
||||
StartSubGroupNav: Showing the subscriptions group nav menu
|
||||
- $action: the current action
|
||||
- $menu: the menu widget; use $menu->action for output
|
||||
|
||||
EndSubGroupNav: At the end of the subscriptions group nav menu
|
||||
- $action: the current action
|
||||
- $menu: the menu widget; use $menu->action for output
|
||||
|
||||
StartInitializeRouter: Before the router instance has been initialized; good place to add routes
|
||||
- $m: the Net_URL_Mapper that has just been set up
|
||||
@ -258,10 +258,28 @@ EndShowExportData: just after showing the <div> with export data (feeds)
|
||||
- $action: action object being shown
|
||||
|
||||
StartShowNoticeItem: just before showing the notice item
|
||||
- $action: action object being shown
|
||||
- $item: The NoticeListItem object being shown
|
||||
|
||||
EndShowNoticeItem: just after showing the notice item
|
||||
- $action: action object being shown
|
||||
- $item: the NoticeListItem object being shown
|
||||
|
||||
StartShowNoticeInfo: just before showing notice info
|
||||
- $item: The NoticeListItem object being shown
|
||||
|
||||
EndShowNoticeInfo: just after showing notice info
|
||||
- $item: The NoticeListItem object being shown
|
||||
|
||||
StartShowNoticeOptions: just before showing notice options like fave, repeat, etc.
|
||||
- $item: the NoticeListItem object being shown
|
||||
|
||||
EndShowNoticeOptions: just after showing notice options like fave, repeat, etc.
|
||||
- $item: the NoticeListItem object being shown
|
||||
|
||||
StartShowFaveForm: just before showing the fave form
|
||||
- $item: the NoticeListItem object being shown
|
||||
|
||||
EndShowFaveForm: just after showing the fave form
|
||||
- $item: the NoticeListItem object being shown
|
||||
|
||||
StartShowPageNotice: just before showing the page notice (instructions or error)
|
||||
- $action: action object being shown
|
||||
@ -284,6 +302,20 @@ StartProfileSaveForm: before starting to save a profile settings form
|
||||
EndProfileSaveForm: after saving a profile settings form (after commit, no profile or user object!)
|
||||
- $action: action object being shown
|
||||
|
||||
StartEmailFormData: just before showing text entry fields on email settings page
|
||||
- $action: action object being shown
|
||||
|
||||
EndEmailFormData: just after showing text entry fields on email settings page
|
||||
- $action: action object being shown
|
||||
|
||||
StartEmailSaveForm: before starting to save a email settings form
|
||||
- $action: action object being shown
|
||||
- &$user: user being saved
|
||||
|
||||
EndEmailSaveForm: after saving a email settings form (after commit)
|
||||
- $action: action object being shown
|
||||
- &$user: user being saved
|
||||
|
||||
StartRegistrationFormData: just before showing text entry fields on registration page
|
||||
- $action: action object being shown
|
||||
|
||||
@ -347,6 +379,14 @@ GetValidDaemons: Just before determining which daemons to run
|
||||
HandleQueuedNotice: Handle a queued notice at queue time (or immediately if no queue)
|
||||
- &$notice: notice to handle
|
||||
|
||||
StartHtmlElement: Reight before outputting the HTML element - allows plugins to add namespaces
|
||||
- $action: the current action
|
||||
- &$attrs: attributes for the HTML element
|
||||
|
||||
EndHtmlElement: Right after outputting the HTML element
|
||||
- $action: the current action
|
||||
- &$attrs: attributes for the HTML element
|
||||
|
||||
StartShowHeadElements: Right after the <head> tag
|
||||
- $action: the current action
|
||||
|
||||
@ -551,6 +591,12 @@ EndPublicXRDS: End XRDS output (right before the closing XRDS tag)
|
||||
- $action: the current action
|
||||
- &$xrdsoutputter - XRDSOutputter object to write to
|
||||
|
||||
StartHostMetaLinks: Start /.well-known/host-meta links
|
||||
- &links: array containing the links elements to be written
|
||||
|
||||
EndHostMetaLinks: End /.well-known/host-meta links
|
||||
- &links: array containing the links elements to be written
|
||||
|
||||
StartCheckPassword: Check a username/password
|
||||
- $nickname: The nickname to check
|
||||
- $password: The password to check
|
||||
@ -774,6 +820,22 @@ EndDisfavorNotice: After saving a notice as a favorite
|
||||
- $profile: profile of the person faving (can be remote!)
|
||||
- $notice: notice being faved
|
||||
|
||||
StartFavorNoticeForm: starting the data in the form for favoring a notice
|
||||
- $FavorForm: the favor form being shown
|
||||
- $notice: notice being favored
|
||||
|
||||
EndFavorNoticeForm: Ending the data in the form for favoring a notice
|
||||
- $FavorForm: the favor form being shown
|
||||
- $notice: notice being favored
|
||||
|
||||
StartDisFavorNoticeForm: starting the data in the form for disfavoring a notice
|
||||
- $DisfavorForm: the disfavor form being shown
|
||||
- $notice: notice being difavored
|
||||
|
||||
EndDisFavorNoticeForm: Ending the data in the form for disfavoring a notice
|
||||
- $DisfavorForm: the disfavor form being shown
|
||||
- $notice: notice being disfavored
|
||||
|
||||
StartFindMentions: start finding mentions in a block of text
|
||||
- $sender: sender profile
|
||||
- $text: plain text version of the notice
|
||||
@ -836,230 +898,122 @@ EndDeleteUser: handling the post for deleting a user
|
||||
- $action: action being shown
|
||||
- $user: user being deleted
|
||||
|
||||
StartActivityStart: starting the output for a notice activity <event>
|
||||
- &$notice: notice being output
|
||||
- &$xs: XMLStringer for output
|
||||
- &$attrs: <entry> attributes (mostly namespace declarations, if any)
|
||||
StartNoticeAsActivity: before converting a notice to an activity
|
||||
- $notice: notice being converted
|
||||
- &$activity: initially empty activity
|
||||
|
||||
EndActivityStart: end the opening tag for an activity <event>
|
||||
- &$notice: notice being output
|
||||
- &$xs: XMLStringer for output
|
||||
- $attrs: <entry> attributes (mostly namespace declarations, if any)
|
||||
EndNoticeAsActivity: after converting a notice to an activity (good time to customize!)
|
||||
- $notice: notice being converted
|
||||
- &$activity: activity, now more-or-less full
|
||||
|
||||
StartActivitySource: before outputting the <source> element for a notice activity
|
||||
- &$notice: notice being output
|
||||
- &$xs: XMLStringer for output
|
||||
StartNoticeSaveWeb: before saving a notice through the Web interface
|
||||
- $action: action being executed (instance of NewNoticeAction)
|
||||
- &$authorId: integer ID of the author
|
||||
- &$text: text of the notice
|
||||
- &$options: additional options (location, replies, etc.)
|
||||
|
||||
EndActivitySource: after outputting the <source> element for a notice activity
|
||||
- &$notice: notice being output
|
||||
- &$xs: XMLStringer for output
|
||||
EndNoticeSaveWeb: after saving a notice through the Web interface
|
||||
- $action: action being executed (instance of NewNoticeAction)
|
||||
- $notice: notice that was saved
|
||||
|
||||
StartActivityTitle: before outputting notice activity title
|
||||
- &$notice: notice being output
|
||||
- &$xs: XMLStringer for output
|
||||
- &$title: title of the notice, mutable
|
||||
StartRssEntryArray: at the start of copying a notice to an array
|
||||
- $notice: the notice being copied
|
||||
- &$entry: the entry (empty at beginning)
|
||||
|
||||
EndActivityTitle: after outputting notice activity title
|
||||
- $notice: notice being output
|
||||
- &$xs: XMLStringer for output
|
||||
- $title: title of the notice
|
||||
EndRssEntryArray: at the end of copying a notice to an array
|
||||
- $notice: the notice being copied
|
||||
- &$entry: the entry, with all the fields filled up
|
||||
|
||||
StartActivityAuthor: before outputting atom author
|
||||
- &$notice: notice being output
|
||||
- &$xs: XMLStringer for output
|
||||
- &$atomAuthor: string for XML representing atom author
|
||||
NoticeDeleteRelated: at the beginning of deleting related fields to a notice
|
||||
- $notice: notice being deleted
|
||||
|
||||
EndActivityAuthor: after outputting atom author
|
||||
- &$notice: notice being output
|
||||
- &$xs: XMLStringer for output
|
||||
- &$atomAuthor: string for XML representing atom author
|
||||
StartShowHeadTitle: when beginning to show the <title> element
|
||||
- $action: action being shown
|
||||
|
||||
StartActivityActor: before outputting activity actor element for a notice activity entry
|
||||
- &$notice: notice being output
|
||||
- &$xs: XMLStringer for output
|
||||
- &$actor: string for XML representing activity actor
|
||||
EndShowHeadTitle: when done showing the <title>
|
||||
- $action: action being shown
|
||||
|
||||
EndActivityActor: after outputting activity actor element for a notice activity entry
|
||||
- &$notice: notice being output
|
||||
- &$xs: XMLStringer for output
|
||||
- &$actor: string for XML representing activity actor
|
||||
StartShowPageTitle: when beginning to show the page title <h1>
|
||||
- $action: action being shown
|
||||
|
||||
StartActivityLink: before outputting activity HTML link element for a notice activity entry
|
||||
- &$notice: notice being output
|
||||
- &$xs: XMLStringer for output
|
||||
- &$url: URL for activity HTML link element for a notice activity entry
|
||||
EndShowPageTitle: when done showing the page title <h1>
|
||||
- $action: action being shown
|
||||
|
||||
EndActivityLink: before outputting activity HTML link element for a notice activity entry
|
||||
- &$notice: notice being output
|
||||
- &$xs: XMLStringer for output
|
||||
- $url: URL for activity HTML link element for a notice activity entry
|
||||
StartDeleteOwnNotice: when a user starts to delete their own notice
|
||||
- $user: the user doing the delete
|
||||
- $notice: the notice being deleted
|
||||
|
||||
StartActivityId: before outputting atom:id element for a notice activity entry
|
||||
- &$notice: notice being output
|
||||
- &$xs: XMLStringer for output
|
||||
- &$id: atom:id (notice URI by default)
|
||||
EndDeleteOwnNotice: when a user has deleted their own notice
|
||||
- $user: the user doing the delete
|
||||
- $notice: the notice being deleted
|
||||
|
||||
EndActivityId: after outputting atom:id element for a notice activity entry
|
||||
- &$notice: notice being output
|
||||
- &$xs: XMLStringer for output
|
||||
- $id: atom:id (notice URI by default)
|
||||
StartShowFeedLinkList: before showing the feed list in the sidebar
|
||||
- $action: action being executed
|
||||
- $feeds: list of feeds to show
|
||||
|
||||
StartActivityPublished: before outputting atom:published element for a notice activity entry
|
||||
- &$notice: notice being output
|
||||
- &$xs: XMLStringer for output
|
||||
- &$published: atom:published value (notice created by default)
|
||||
EndShowFeedLinkList: after showing the feed list in the sidebar
|
||||
- $action: action being executed
|
||||
- $feeds: list of feeds shown
|
||||
|
||||
EndActivityPublished: before outputting atom:published element for a notice activity entry
|
||||
- &$notice: notice being output
|
||||
- &$xs: XMLStringer for output
|
||||
- $published: atom:published value (notice created by default)
|
||||
StartShowFeedLink: before showing an individual feed item
|
||||
- $action: action being executed
|
||||
- $feed: feed to show
|
||||
|
||||
StartActivityUpdated: before outputting atom:updated element for a notice activity entry
|
||||
- &$notice: notice being output
|
||||
- &$xs: XMLStringer for output
|
||||
- &$updated: atom:updated value (same as atom:published by default)
|
||||
EndShowFeedLink: after showing an individual feed
|
||||
- $action: action being executed
|
||||
- $feed: feed to show
|
||||
|
||||
EndActivityUpdated: after outputting atom:updated element for a notice activity entry
|
||||
- &$notice: notice being output
|
||||
- &$xs: XMLStringer for output
|
||||
- $updated: atom:updated value (same as atom:published by default)
|
||||
StartShowNoticeForm: before showing the notice form (before <form>)
|
||||
- $action: action being executed
|
||||
|
||||
StartActivityContent: before outputting atom:content element for a notice activity entry
|
||||
- &$notice: notice being output
|
||||
- &$xs: XMLStringer for output
|
||||
- &$content: atom:content value (notice rendered HTML by default)
|
||||
EndShowNoticeForm: after showing the notice form (after <form>)
|
||||
- $action: action being executed
|
||||
|
||||
EndActivityContent: after outputting atom:content element for a notice activity entry
|
||||
- &$notice: notice being output
|
||||
- &$xs: XMLStringer for output
|
||||
- $content: atom:content value (notice rendered HTML by default)
|
||||
StartGrantRole: when a role is being assigned
|
||||
- $profile: profile that will have the role
|
||||
- $role: string name of the role
|
||||
|
||||
StartActivityVerb: before outputting activity:verb element for a notice activity entry
|
||||
- &$notice: notice being output
|
||||
- &$xs: XMLStringer for output
|
||||
- &$verb: activity:verb URI ('http://activitystrea.ms/schema/1.0/post' by default)
|
||||
EndGrantRole: when a role has been successfully assigned
|
||||
- $profile: profile that will have the role
|
||||
- $role: string name of the role
|
||||
|
||||
EndActivityVerb: after outputting activity:verb element for a notice activity entry
|
||||
- &$notice: notice being output
|
||||
- &$xs: XMLStringer for output
|
||||
- $verb: activity:verb URI ('http://activitystrea.ms/schema/1.0/post' by default)
|
||||
StartRevokeRole: when a role is being revoked
|
||||
- $profile: profile that will lose the role
|
||||
- $role: string name of the role
|
||||
|
||||
StartActivityDefaultObjectType: before outputting activity:object-type element for a notice activity entry
|
||||
- &$notice: notice being output
|
||||
- &$xs: XMLStringer for output
|
||||
- &$type: activity:object-type URI for default object ('http://activitystrea.ms/schema/1.0/note' by default)
|
||||
EndRevokeRole: when a role has been revoked
|
||||
- $profile: profile that lost the role
|
||||
- $role: string name of the role
|
||||
|
||||
EndActivityDefaultObjectType: after outputting activity:verb element for a notice activity entry
|
||||
- &$notice: notice being output
|
||||
- &$xs: XMLStringer for output
|
||||
- $type: activity:object-type URI for default object ('http://activitystrea.ms/schema/1.0/note' by default)
|
||||
StartAtomPubNewActivity: When a new activity comes in through Atom Pub API
|
||||
- &$activity: received activity
|
||||
|
||||
StartActivityObjects: before outputting activity:object elements for a notice activity entry
|
||||
- &$notice: notice being output
|
||||
- &$xs: XMLStringer for output
|
||||
- &$objects: array of ActivityObject objects to output (empty by default)
|
||||
EndAtomPubNewActivity: When a new activity comes in through Atom Pub API
|
||||
- $activity: received activity
|
||||
- $notice: notice that was created
|
||||
|
||||
EndActivityObjects: after outputting activity:object elements for a notice activity entry
|
||||
- &$notice: notice being output
|
||||
- &$xs: XMLStringer for output
|
||||
- $objects: array of ActivityObject objects to output (empty by default)
|
||||
StartXrdActionAliases: About to set aliases for the XRD object for a user
|
||||
- &$xrd: XRD object being shown
|
||||
- $user: User being shown
|
||||
|
||||
StartActivityNoticeInfo: before outputting statusnet:notice-info element for a notice activity entry
|
||||
- &$notice: notice being output
|
||||
- &$xs: XMLStringer for output
|
||||
- &$noticeInfoAttr: array of attributes for notice info element
|
||||
EndXrdActionAliases: Done with aliases for the XRD object for a user
|
||||
- &$xrd: XRD object being shown
|
||||
- $user: User being shown
|
||||
|
||||
EndActivityNoticeInfo: after outputting statusnet:notice-info element for a notice activity entry
|
||||
- &$notice: notice being output
|
||||
- &$xs: XMLStringer for output
|
||||
- $noticeInfoAttr: array of attributes for notice info element
|
||||
StartXrdActionLinks: About to set links for the XRD object for a user
|
||||
- &$xrd: XRD object being shown
|
||||
- $user: User being shown
|
||||
|
||||
StartActivityInReplyTo: before outputting thr:in-reply-to element for a notice activity entry
|
||||
- &$notice: notice being output
|
||||
- &$xs: XMLStringer for output
|
||||
- &$replyNotice: Notice object the main notice is in-reply-to
|
||||
EndXrdActionLinks: Done with links for the XRD object for a user
|
||||
- &$xrd: XRD object being shown
|
||||
- $user: User being shown
|
||||
|
||||
EndActivityInReplyTo: after outputting thr:in-reply-to element for a notice activity entry
|
||||
- &$notice: notice being output
|
||||
- &$xs: XMLStringer for output
|
||||
- $replyNotice: Notice object the main notice is in-reply-to
|
||||
AdminPanelCheck: When checking whether the current user can access a given admin panel
|
||||
- $name: Name of the admin panel
|
||||
- &$isOK: Boolean whether the user is allowed to use the panel
|
||||
|
||||
StartActivityConversation: before outputting ostatus:conversation link element for a notice activity entry
|
||||
- &$notice: notice being output
|
||||
- &$xs: XMLStringer for output
|
||||
- &$conv: Conversation object
|
||||
StartAdminPanelNav: Before displaying the first item in the list of admin panels
|
||||
- $nav The AdminPanelNav widget
|
||||
|
||||
EndActivityConversation: after outputting ostatus:conversation link element for a notice activity entry
|
||||
- &$notice: notice being output
|
||||
- &$xs: XMLStringer for output
|
||||
- $conv: Conversation object
|
||||
|
||||
StartActivityAttentionProfiles: before outputting ostatus:attention link element for people in a notice activity entry
|
||||
- &$notice: notice being output
|
||||
- &$xs: XMLStringer for output
|
||||
- &$replyProfiles: array of profiles of people being replied to
|
||||
|
||||
EndActivityAttentionProfiles: after outputting ostatus:attention link element for people in a notice activity entry
|
||||
- &$notice: notice being output
|
||||
- &$xs: XMLStringer for output
|
||||
- $replyProfiles: array of Profile object of people being replied to
|
||||
|
||||
StartActivityAttentionGroups: before outputting ostatus:attention link element for groups in a notice activity entry
|
||||
- &$notice: notice being output
|
||||
- &$xs: XMLStringer for output
|
||||
- &$groups: array of Group objects of groups being addressed
|
||||
|
||||
EndActivityAttentionGroups: after outputting ostatus:attention link element for groups in a notice activity entry
|
||||
- &$notice: notice being output
|
||||
- &$xs: XMLStringer for output
|
||||
- $groups: array of Group objects of groups being addressed
|
||||
|
||||
StartActivityForward: before outputting ostatus:forward link element in a notice activity entry
|
||||
- &$notice: notice being output
|
||||
- &$xs: XMLStringer for output
|
||||
- &$repeat: Notice that was repeated
|
||||
|
||||
EndActivityForward: after outputting ostatus:forward link element in a notice activity entry
|
||||
- &$notice: notice being output
|
||||
- &$xs: XMLStringer for output
|
||||
- $repeat: Notice that was repeated
|
||||
|
||||
StartActivityCategories: before outputting atom:category elements in a notice activity entry
|
||||
- &$notice: notice being output
|
||||
- &$xs: XMLStringer for output
|
||||
- &$tags: array of strings for tags on the notice (used for categories)
|
||||
|
||||
EndActivityCategories: after outputting atom:category elements in a notice activity entry
|
||||
- &$notice: notice being output
|
||||
- &$xs: XMLStringer for output
|
||||
- $tags: array of strings for tags on the notice (used for categories)
|
||||
|
||||
StartActivityEnclosures: before outputting enclosure link elements in a notice activity entry
|
||||
- &$notice: notice being output
|
||||
- &$xs: XMLStringer for output
|
||||
- &$enclosures: array of enclosure objects (see File::getEnclosure() for details)
|
||||
|
||||
EndActivityEnclosures: after outputting enclosure link elements in a notice activity entry
|
||||
- &$notice: notice being output
|
||||
- &$xs: XMLStringer for output
|
||||
- $enclosures: array of enclosure objects (see File::getEnclosure() for details)
|
||||
|
||||
StartActivityGeo: before outputting geo:rss element in a notice activity entry
|
||||
- &$notice: notice being output
|
||||
- &$xs: XMLStringer for output
|
||||
- &$lat: latitude
|
||||
- &$lon: longitude
|
||||
|
||||
EndActivityGeo: after outputting geo:rss element in a notice activity entry
|
||||
- &$notice: notice being output
|
||||
- &$xs: XMLStringer for output
|
||||
- $lat: latitude
|
||||
- $lon: longitude
|
||||
|
||||
StartActivityEnd: before the closing </entry> in a notice activity entry (last chance for data!)
|
||||
- &$notice: notice being output
|
||||
- &$xs: XMLStringer for output
|
||||
|
||||
EndActivityEnd: after the closing </entry> in a notice activity entry
|
||||
- &$notice: notice being output
|
||||
- &$xs: XMLStringer for output
|
||||
EndAdminPanelNav: After displaying the last item in the list of admin panels
|
||||
- $nav The AdminPanelNav widget
|
||||
|
157
README
157
README
@ -2,8 +2,8 @@
|
||||
README
|
||||
------
|
||||
|
||||
StatusNet 0.9.4beta2
|
||||
11 August 2010
|
||||
StatusNet 0.9.6 "Man on the Moon"
|
||||
29 October 2010
|
||||
|
||||
This is the README file for StatusNet, the Open Source microblogging
|
||||
platform. It includes installation instructions, descriptions of
|
||||
@ -38,7 +38,8 @@ more, please see the Open Software Service Definition 1.1:
|
||||
http://www.opendefinition.org/ossd
|
||||
|
||||
StatusNet, Inc. <http://status.net/> also offers this software as a
|
||||
Web service, requiring no installation on your part. The software run
|
||||
Web service, requiring no installation on your part. See
|
||||
<http://status.net/signup> for details. The software run
|
||||
on status.net is identical to the software available for download, so
|
||||
you can move back and forth between a hosted version or a version
|
||||
installed on your own servers.
|
||||
@ -72,6 +73,20 @@ License along with this program, in the file "COPYING". If not, see
|
||||
of using the software, and if you do not wish to share your
|
||||
modifications, *YOU MAY NOT INSTALL STATUSNET*.
|
||||
|
||||
Documentation in the /doc-src/ directory is available under the
|
||||
Creative Commons Attribution 3.0 Unported license, with attribution to
|
||||
"StatusNet". See http://creativecommons.org/licenses/by/3.0/ for details.
|
||||
|
||||
CSS and images in the /theme/ directory are available under the
|
||||
Creative Commons Attribution 3.0 Unported license, with attribution to
|
||||
"StatusNet". See http://creativecommons.org/licenses/by/3.0/ for details.
|
||||
|
||||
Our understanding and intention is that if you add your own theme that
|
||||
uses only CSS and images, those files are not subject to the copyleft
|
||||
requirements of the Affero General Public License 3.0. See
|
||||
http://wordpress.org/news/2009/07/themes-are-gpl-too/ . This is not
|
||||
legal advice; consult your lawyer.
|
||||
|
||||
Additional library software has been made available in the 'extlib'
|
||||
directory. All of it is Free Software and can be distributed under
|
||||
liberal terms, but those terms may differ in detail from the AGPL's
|
||||
@ -81,31 +96,43 @@ for additional terms.
|
||||
New this version
|
||||
================
|
||||
|
||||
This is a security, bug and feature release since version 0.9.3 released on
|
||||
29 June 2010.
|
||||
This is a security, bug and feature release since version 0.9.5 released on
|
||||
10 September 2010.
|
||||
|
||||
For best compatibility with client software and site federation, and a lot of
|
||||
bug fixes, it is highly recommended that all public sites upgrade to the new
|
||||
version.
|
||||
|
||||
Changes from 0.9.4beta1:
|
||||
- fix for daemon config switching on multi-site setup
|
||||
|
||||
Notable changes this version:
|
||||
|
||||
- OpenID and OAuth libraries patched for potential timing attack
|
||||
- OStatus feed i/o updated for Activity Streams
|
||||
- Correctness fixes on XRD, other discovery bits
|
||||
- Support for contacting SNI-based SSL virtual hosts when SSL
|
||||
certificate verification is enabled (requires PHP 5.3.2+ or
|
||||
enabling CURL backend with $config['http']['curl'] = true)
|
||||
- Experimental SubMirror plugin
|
||||
- Multi-site status_network table mode has been tweaked to support
|
||||
multiple tags better
|
||||
- Many updates to user interface translation from TranslateWiki
|
||||
- Many other bugfixes
|
||||
- Site moderators can now delete groups.
|
||||
- New themes: clean, shiny, mnml, victorian
|
||||
- New YammerImport plugin allows site admins to import non-private profiles and
|
||||
message from an authenticated Yammer site.
|
||||
- New experimental plugins: AnonFavorites, SlicedFavorites, GroupFavorited,
|
||||
ForceGroup, ShareNotice
|
||||
- OAuth upgraded to 1.0a
|
||||
- Localization updates now include plugins, thanks to translatewiki.net!
|
||||
- SSL link generation should be more consistent; alternate SSL URLs can be
|
||||
set in the admin UI for more parts of the system.
|
||||
- Experimental backupuser.php, restoreuser.php command-line scripts to
|
||||
dump/restore a user's complete activity stream. Can be used to transfer
|
||||
accounts manually between sites, or to save a backup before deleting.
|
||||
- Unicode fixes for OStatus notices
|
||||
- Header metadata on notice pages to aid in manual reposting on Facebook
|
||||
- Lots of little fixes...
|
||||
|
||||
A full changelog is available at http://status.net/wiki/StatusNet_0.9.4.
|
||||
Changes from 0.9.6 release candidate 1:
|
||||
- fix for broken group pages when logged out
|
||||
- fix for stuck ping queue entries when bad profile
|
||||
- fix for bogus single-user nickname config entry error
|
||||
- i18n updates
|
||||
- nofollow updates
|
||||
- SSL-only mode secure cookie fix
|
||||
- experimental ApiLogger plugin for usage data gathering
|
||||
- experimental follow-everyone plugin
|
||||
|
||||
A full changelog is available at http://status.net/wiki/StatusNet_0.9.6.
|
||||
|
||||
Prerequisites
|
||||
=============
|
||||
@ -193,14 +220,12 @@ and the URLs are listed here for your convenience.
|
||||
version may render your StatusNet site unable to send or receive XMPP
|
||||
messages.
|
||||
- Facebook library. Used for the Facebook application.
|
||||
- PEAR Services_oEmbed. Used for some multimedia integration.
|
||||
- PEAR HTTP_Request is an oEmbed dependency.
|
||||
- PEAR Validate is an oEmbed dependency.
|
||||
- PEAR Net_URL2 is an oEmbed dependency.
|
||||
- PEAR Validate is used for URL and email validation.
|
||||
- Console_GetOpt for parsing command-line options.
|
||||
- libomb. a library for implementing OpenMicroBlogging 0.1, the
|
||||
predecessor to OStatus.
|
||||
- HTTP_Request2, a library for making HTTP requests.
|
||||
- PEAR Net_URL2 is an HTTP_Request2 dependency.
|
||||
|
||||
A design goal of StatusNet is that the basic Web functionality should
|
||||
work on even the most restrictive commercial hosting services.
|
||||
@ -218,9 +243,9 @@ especially if you've previously installed PHP/MySQL packages.
|
||||
1. Unpack the tarball you downloaded on your Web server. Usually a
|
||||
command like this will work:
|
||||
|
||||
tar zxf statusnet-0.9.4.tar.gz
|
||||
tar zxf statusnet-0.9.6.tar.gz
|
||||
|
||||
...which will make a statusnet-0.9.2 subdirectory in your current
|
||||
...which will make a statusnet-0.9.6 subdirectory in your current
|
||||
directory. (If you don't have shell access on your Web server, you
|
||||
may have to unpack the tarball on your local computer and FTP the
|
||||
files to the server.)
|
||||
@ -228,7 +253,7 @@ especially if you've previously installed PHP/MySQL packages.
|
||||
2. Move the tarball to a directory of your choosing in your Web root
|
||||
directory. Usually something like this will work:
|
||||
|
||||
mv statusnet-0.9.4 /var/www/statusnet
|
||||
mv statusnet-0.9.6 /var/www/statusnet
|
||||
|
||||
This will make your StatusNet instance available in the statusnet path of
|
||||
your server, like "http://example.net/statusnet". "microblog" or
|
||||
@ -587,7 +612,7 @@ subdirectory to add a new language to your system. You'll need to
|
||||
compile the ".po" files into ".mo" files, however.
|
||||
|
||||
Contributions of translation information to StatusNet are very easy:
|
||||
you can use the Web interface at TranslateWiki.net to add one
|
||||
you can use the Web interface at translatewiki.net to add one
|
||||
or a few or lots of new translations -- or even new languages. You can
|
||||
also download more up-to-date .po files there, if you so desire.
|
||||
|
||||
@ -643,7 +668,7 @@ with this situation.
|
||||
If you've been using StatusNet 0.7, 0.6, 0.5 or lower, or if you've
|
||||
been tracking the "git" version of the software, you will probably
|
||||
want to upgrade and keep your existing data. There is no automated
|
||||
upgrade procedure in StatusNet 0.9.2. Try these step-by-step
|
||||
upgrade procedure in StatusNet 0.9.6. Try these step-by-step
|
||||
instructions; read to the end first before trying them.
|
||||
|
||||
0. Download StatusNet and set up all the prerequisites as if you were
|
||||
@ -664,10 +689,11 @@ instructions; read to the end first before trying them.
|
||||
5. Once all writing processes to your site are turned off, make a
|
||||
final backup of the Web directory and database.
|
||||
6. Move your StatusNet directory to a backup spot, like "statusnet.bak".
|
||||
7. Unpack your StatusNet 0.9.2 tarball and move it to "statusnet" or
|
||||
7. Unpack your StatusNet 0.9.6 tarball and move it to "statusnet" or
|
||||
wherever your code used to be.
|
||||
8. Copy the config.php file and avatar directory from your old
|
||||
directory to your new directory.
|
||||
8. Copy the config.php file and the contents of the avatar/, background/,
|
||||
file/, and local/ subdirectories from your old directory to your new
|
||||
directory.
|
||||
9. Copy htaccess.sample to .htaccess in the new directory. Change the
|
||||
RewriteBase to use the correct path.
|
||||
10. Rebuild the database. (You can safely skip this step and go to #12
|
||||
@ -835,6 +861,8 @@ notice: A plain string that will appear on every page. A good place
|
||||
be escaped.
|
||||
logo: URL of an image file to use as the logo for the site. Overrides
|
||||
the logo in the theme, if any.
|
||||
ssllogo: URL of an image file to use as the logo on SSL pages. If unset,
|
||||
theme logo is used instead.
|
||||
ssl: Whether to use SSL and https:// URLs for some or all pages.
|
||||
Possible values are 'always' (use it for all pages), 'never'
|
||||
(don't use it for any pages), or 'sometimes' (use it for
|
||||
@ -1092,6 +1120,9 @@ path: Path part of theme URLs, before the theme name. Relative to the
|
||||
which means to use the site path + '/theme'.
|
||||
ssl: Whether to use SSL for theme elements. Default is null, which means
|
||||
guess based on site SSL settings.
|
||||
sslserver: SSL server to use when page is HTTPS-encrypted. If
|
||||
unspecified, site ssl server and so on will be used.
|
||||
sslpath: If sslserver if defined, path to use when page is HTTPS-encrypted.
|
||||
|
||||
javascript
|
||||
----------
|
||||
@ -1103,6 +1134,9 @@ path: Path part of Javascript URLs. Defaults to null,
|
||||
which means to use the site path + '/js/'.
|
||||
ssl: Whether to use SSL for JavaScript files. Default is null, which means
|
||||
guess based on site SSL settings.
|
||||
sslserver: SSL server to use when page is HTTPS-encrypted. If
|
||||
unspecified, site ssl server and so on will be used.
|
||||
sslpath: If sslserver if defined, path to use when page is HTTPS-encrypted.
|
||||
|
||||
xmpp
|
||||
----
|
||||
@ -1330,6 +1364,11 @@ ssl: whether to use HTTPS for file URLs. Defaults to null, meaning to
|
||||
filecommand: command to use for determining the type of a file. May be
|
||||
skipped if fileinfo extension is installed. Defaults to
|
||||
'/usr/bin/file'.
|
||||
sslserver: if specified, this server will be used when creating HTTPS
|
||||
URLs. Otherwise, the site SSL server will be used, with /file/ path.
|
||||
sslpath: if this and the sslserver are specified, this path will be used
|
||||
when creating HTTPS URLs. Otherwise, the attachments|path value
|
||||
will be used.
|
||||
|
||||
group
|
||||
-----
|
||||
@ -1386,8 +1425,9 @@ dir: directory to write backgrounds too. Default is '/background/'
|
||||
subdir of install dir.
|
||||
path: path to backgrounds. Default is sub-path of install path; note
|
||||
that you may need to change this if you change site-path too.
|
||||
ssl: Whether or not to use HTTPS for background files. Defaults to
|
||||
null, meaning to guess from site-wide SSL settings.
|
||||
sslserver: SSL server to use when page is HTTPS-encrypted. If
|
||||
unspecified, site ssl server and so on will be used.
|
||||
sslpath: If sslserver if defined, path to use when page is HTTPS-encrypted.
|
||||
|
||||
ping
|
||||
----
|
||||
@ -1452,7 +1492,8 @@ If an installation has only one user, this can simplify a lot of the
|
||||
interface. It also makes the user's profile the root URL.
|
||||
|
||||
enabled: Whether to run in "single user mode". Default false.
|
||||
nickname: nickname of the single user.
|
||||
nickname: nickname of the single user. If no nickname is specified,
|
||||
the site owner account will be used (if present).
|
||||
|
||||
robotstxt
|
||||
---------
|
||||
@ -1468,6 +1509,33 @@ disallow: Array of (virtual) directories to disallow. Default is 'main',
|
||||
'search', 'message', 'settings', 'admin'. Ignored when site
|
||||
is private, in which case the entire site ('/') is disallowed.
|
||||
|
||||
api
|
||||
---
|
||||
|
||||
Options for the Twitter-like API.
|
||||
|
||||
realm: HTTP Basic Auth realm (see http://tools.ietf.org/html/rfc2617
|
||||
for details). Some third-party tools like ping.fm want this to be
|
||||
'Identi.ca API', so set it to that if you want to. default = null,
|
||||
meaning 'something based on the site name'.
|
||||
|
||||
nofollow
|
||||
--------
|
||||
|
||||
We optionally put 'rel="nofollow"' on some links in some pages. The
|
||||
following configuration settings let you fine-tune how or when things
|
||||
are nofollowed. See http://en.wikipedia.org/wiki/Nofollow for more
|
||||
information on what 'nofollow' means.
|
||||
|
||||
subscribers: whether to nofollow links to subscribers on the profile
|
||||
and personal pages. Default is true.
|
||||
members: links to members on the group page. Default true.
|
||||
peopletag: links to people listed in the peopletag page. Default true.
|
||||
external: external links in notices. One of three values: 'sometimes',
|
||||
'always', 'never'. If 'sometimes', then external links are not
|
||||
nofollowed on profile, notice, and favorites page. Default is
|
||||
'sometimes'.
|
||||
|
||||
url
|
||||
---
|
||||
|
||||
@ -1484,6 +1552,19 @@ maxnoticelength: If a notice is strictly longer than this limit, all
|
||||
URLs in the notice will be shortened. Users can override.
|
||||
-1 means the text limit for notices.
|
||||
|
||||
router
|
||||
------
|
||||
|
||||
We use a router class for mapping URLs to code. This section controls
|
||||
how that router works.
|
||||
|
||||
cache: whether to cache the router in memcache (or another caching
|
||||
mechanism). Defaults to true, but may be set to false for
|
||||
developers (who might be actively adding pages, so won't want the
|
||||
router cached) or others who see strange behavior. You're unlikely
|
||||
to need this unless you're a developer.
|
||||
|
||||
|
||||
Plugins
|
||||
=======
|
||||
|
||||
@ -1541,7 +1622,7 @@ repository (see below), and you get a compilation error ("unexpected
|
||||
T_STRING") in the browser, check to see that you don't have any
|
||||
conflicts in your code.
|
||||
|
||||
If you upgraded to StatusNet 0.9.2 without reading the "Notice
|
||||
If you upgraded to StatusNet 0.9.x without reading the "Notice
|
||||
inboxes" section above, and all your users' 'Personal' tabs are empty,
|
||||
read the "Notice inboxes" section above.
|
||||
|
||||
@ -1652,6 +1733,10 @@ if anyone's been overlooked in error.
|
||||
* mEDI
|
||||
* Brett Taylor
|
||||
* Brigitte Schuster
|
||||
* Siebrand Mazeland and the amazing volunteer translators at translatewiki.net
|
||||
* Brion Vibber, StatusNet, Inc.
|
||||
* James Walker, StatusNet, Inc.
|
||||
* Samantha Doherty, designer, StatusNet, Inc.
|
||||
|
||||
Thanks also to the developers of our upstream library code and to the
|
||||
thousands of people who have tried out Identi.ca, installed StatusNet,
|
||||
|
@ -40,7 +40,6 @@ if (!defined('STATUSNET')) {
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||
* @link http://status.net/
|
||||
*/
|
||||
|
||||
class AccessadminpanelAction extends AdminPanelAction
|
||||
{
|
||||
/**
|
||||
@ -48,10 +47,9 @@ class AccessadminpanelAction extends AdminPanelAction
|
||||
*
|
||||
* @return string page title
|
||||
*/
|
||||
|
||||
function title()
|
||||
{
|
||||
// TRANS: Page title
|
||||
// TRANS: Page title for Access admin panel that allows configuring site access.
|
||||
return _('Access');
|
||||
}
|
||||
|
||||
@ -60,10 +58,9 @@ class AccessadminpanelAction extends AdminPanelAction
|
||||
*
|
||||
* @return string instructions
|
||||
*/
|
||||
|
||||
function getInstructions()
|
||||
{
|
||||
// TRANS: Page notice
|
||||
// TRANS: Page notice.
|
||||
return _('Site access settings');
|
||||
}
|
||||
|
||||
@ -72,7 +69,6 @@ class AccessadminpanelAction extends AdminPanelAction
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
|
||||
function showForm()
|
||||
{
|
||||
$form = new AccessAdminPanelForm($this);
|
||||
@ -85,7 +81,6 @@ class AccessadminpanelAction extends AdminPanelAction
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
|
||||
function saveSettings()
|
||||
{
|
||||
static $booleans = array('site' => array('private', 'inviteonly', 'closed'));
|
||||
@ -110,7 +105,6 @@ class AccessadminpanelAction extends AdminPanelAction
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class AccessAdminPanelForm extends AdminForm
|
||||
@ -120,7 +114,6 @@ class AccessAdminPanelForm extends AdminForm
|
||||
*
|
||||
* @return int ID of the form
|
||||
*/
|
||||
|
||||
function id()
|
||||
{
|
||||
return 'form_site_admin_panel';
|
||||
@ -131,7 +124,6 @@ class AccessAdminPanelForm extends AdminForm
|
||||
*
|
||||
* @return string class of the form
|
||||
*/
|
||||
|
||||
function formClass()
|
||||
{
|
||||
return 'form_settings';
|
||||
@ -142,7 +134,6 @@ class AccessAdminPanelForm extends AdminForm
|
||||
*
|
||||
* @return string URL of the action
|
||||
*/
|
||||
|
||||
function action()
|
||||
{
|
||||
return common_local_url('accessadminpanel');
|
||||
@ -153,7 +144,6 @@ class AccessAdminPanelForm extends AdminForm
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
|
||||
function formData()
|
||||
{
|
||||
$this->out->elementStart('fieldset', array('id' => 'settings_admin_access'));
|
||||
@ -161,7 +151,7 @@ class AccessAdminPanelForm extends AdminForm
|
||||
$this->out->element('legend', null, _('Registration'));
|
||||
$this->out->elementStart('ul', 'form_data');
|
||||
$this->li();
|
||||
// TRANS: Checkbox instructions for admin setting "Private"
|
||||
// TRANS: Checkbox instructions for admin setting "Private".
|
||||
$instructions = _('Prohibit anonymous users (not logged in) from viewing site?');
|
||||
// TRANS: Checkbox label for prohibiting anonymous users from viewing site.
|
||||
$this->out->checkbox('private', _m('LABEL', 'Private'),
|
||||
@ -170,7 +160,7 @@ class AccessAdminPanelForm extends AdminForm
|
||||
$this->unli();
|
||||
|
||||
$this->li();
|
||||
// TRANS: Checkbox instructions for admin setting "Invite only"
|
||||
// TRANS: Checkbox instructions for admin setting "Invite only".
|
||||
$instructions = _('Make registration invitation only.');
|
||||
// TRANS: Checkbox label for configuring site as invite only.
|
||||
$this->out->checkbox('inviteonly', _('Invite only'),
|
||||
@ -179,7 +169,7 @@ class AccessAdminPanelForm extends AdminForm
|
||||
$this->unli();
|
||||
|
||||
$this->li();
|
||||
// TRANS: Checkbox instructions for admin setting "Closed" (no new registrations)
|
||||
// TRANS: Checkbox instructions for admin setting "Closed" (no new registrations).
|
||||
$instructions = _('Disable new registrations.');
|
||||
// TRANS: Checkbox label for disabling new user registrations.
|
||||
$this->out->checkbox('closed', _('Closed'),
|
||||
@ -195,12 +185,11 @@ class AccessAdminPanelForm extends AdminForm
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
|
||||
function formActions()
|
||||
{
|
||||
// TRANS: Title / tooltip for button to save access settings in site admin panel
|
||||
// TRANS: Title for button to save access settings in site admin panel.
|
||||
$title = _('Save access settings');
|
||||
// TRANS: Tooltip for button to save access settings in site admin panel.
|
||||
$this->out->submit('submit', _m('BUTTON', 'Save'), 'submit', null, $title);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -67,4 +67,3 @@ class AccesstokenAction extends Action
|
||||
}
|
||||
}
|
||||
}
|
||||
?>
|
||||
|
@ -64,7 +64,7 @@ class AllAction extends ProfileAction
|
||||
}
|
||||
|
||||
if ($this->page > 1 && $this->notice->N == 0) {
|
||||
// TRANS: Server error when page not found (404)
|
||||
// TRANS: Server error when page not found (404).
|
||||
$this->serverError(_('No such page.'), $code = 404);
|
||||
}
|
||||
|
||||
@ -76,6 +76,7 @@ class AllAction extends ProfileAction
|
||||
parent::handle($args);
|
||||
|
||||
if (!$this->user) {
|
||||
// TRANS: Client error when user not found for an action.
|
||||
$this->clientError(_('No such user.'));
|
||||
return;
|
||||
}
|
||||
@ -89,7 +90,7 @@ class AllAction extends ProfileAction
|
||||
// TRANS: Page title. %1$s is user nickname, %2$d is page number
|
||||
return sprintf(_('%1$s and friends, page %2$d'), $this->user->nickname, $this->page);
|
||||
} else {
|
||||
// TRANS: Page title. %1$s is user nickname
|
||||
// TRANS: Page title. %s is user nickname
|
||||
return sprintf(_("%s and friends"), $this->user->nickname);
|
||||
}
|
||||
}
|
||||
@ -103,7 +104,7 @@ class AllAction extends ProfileAction
|
||||
'nickname' =>
|
||||
$this->user->nickname)
|
||||
),
|
||||
// TRANS: %1$s is user nickname
|
||||
// TRANS: %s is user nickname.
|
||||
sprintf(_('Feed for friends of %s (RSS 1.0)'), $this->user->nickname)),
|
||||
new Feed(Feed::RSS2,
|
||||
common_local_url(
|
||||
@ -112,7 +113,7 @@ class AllAction extends ProfileAction
|
||||
'id' => $this->user->nickname
|
||||
)
|
||||
),
|
||||
// TRANS: %1$s is user nickname
|
||||
// TRANS: %s is user nickname.
|
||||
sprintf(_('Feed for friends of %s (RSS 2.0)'), $this->user->nickname)),
|
||||
new Feed(Feed::ATOM,
|
||||
common_local_url(
|
||||
@ -121,7 +122,7 @@ class AllAction extends ProfileAction
|
||||
'id' => $this->user->nickname
|
||||
)
|
||||
),
|
||||
// TRANS: %1$s is user nickname
|
||||
// TRANS: %s is user nickname.
|
||||
sprintf(_('Feed for friends of %s (Atom)'), $this->user->nickname))
|
||||
);
|
||||
}
|
||||
@ -134,18 +135,23 @@ class AllAction extends ProfileAction
|
||||
|
||||
function showEmptyListMessage()
|
||||
{
|
||||
// TRANS: %1$s is user nickname
|
||||
// TRANS: Empty list message. %s is a user nickname.
|
||||
$message = sprintf(_('This is the timeline for %s and friends but no one has posted anything yet.'), $this->user->nickname) . ' ';
|
||||
|
||||
if (common_logged_in()) {
|
||||
$current_user = common_current_user();
|
||||
if ($this->user->id === $current_user->id) {
|
||||
// TRANS: Encouragement displayed on logged in user's empty timeline.
|
||||
// TRANS: This message contains Markdown links. Keep "](" together.
|
||||
$message .= _('Try subscribing to more people, [join a group](%%action.groups%%) or post something yourself.');
|
||||
} else {
|
||||
// TRANS: %1$s is user nickname, %2$s is user nickname, %2$s is user nickname prefixed with "@"
|
||||
// TRANS: %1$s is user nickname, %2$s is user nickname, %2$s is user nickname prefixed with "@".
|
||||
// TRANS: This message contains Markdown links. Keep "](" together.
|
||||
$message .= sprintf(_('You can try to [nudge %1$s](../%2$s) from their profile or [post something to them](%%%%action.newnotice%%%%?status_textarea=%3$s).'), $this->user->nickname, $this->user->nickname, '@' . $this->user->nickname);
|
||||
}
|
||||
} else {
|
||||
// TRANS: Encoutagement displayed on empty timeline user pages for anonymous users.
|
||||
// TRANS: %s is a user nickname. This message contains Markdown links. Keep "](" together.
|
||||
$message .= sprintf(_('Why not [register an account](%%%%action.register%%%%) and then nudge %s or post a notice to them.'), $this->user->nickname);
|
||||
}
|
||||
|
||||
@ -178,10 +184,10 @@ class AllAction extends ProfileAction
|
||||
{
|
||||
$user = common_current_user();
|
||||
if ($user && ($user->id == $this->user->id)) {
|
||||
// TRANS: H1 text
|
||||
// TRANS: H1 text for page when viewing a list for self.
|
||||
$this->element('h1', null, _("You and friends"));
|
||||
} else {
|
||||
// TRANS: H1 text. %1$s is user nickname
|
||||
// TRANS: H1 text for page. %s is a user nickname.
|
||||
$this->element('h1', null, sprintf(_('%s and friends'), $this->user->nickname));
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,4 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* RSS feed for user and friends timeline action class.
|
||||
*
|
||||
@ -57,6 +56,7 @@ class AllrssAction extends Rss10Action
|
||||
* @param array $args Web and URL arguments
|
||||
*
|
||||
* @return boolean false if user doesn't exist
|
||||
*
|
||||
*/
|
||||
function prepare($args)
|
||||
{
|
||||
@ -65,6 +65,7 @@ class AllrssAction extends Rss10Action
|
||||
$this->user = User::staticGet('nickname', $nickname);
|
||||
|
||||
if (!$this->user) {
|
||||
// TRANS: Client error when user not found for an rss related action.
|
||||
$this->clientError(_('No such user.'));
|
||||
return false;
|
||||
} else {
|
||||
@ -127,7 +128,7 @@ class AllrssAction extends Rss10Action
|
||||
* Get image.
|
||||
*
|
||||
* @return string user avatar URL or null
|
||||
*/
|
||||
*/
|
||||
function getImage()
|
||||
{
|
||||
$user = $this->user;
|
||||
@ -139,4 +140,3 @@ class AllrssAction extends Rss10Action
|
||||
return $avatar ? $avatar->url : null;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -49,10 +49,8 @@ require_once INSTALLDIR . '/lib/apibareauth.php';
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||
* @link http://status.net/
|
||||
*/
|
||||
|
||||
class ApiAccountRateLimitStatusAction extends ApiBareAuthAction
|
||||
{
|
||||
|
||||
/**
|
||||
* Handle the request
|
||||
*
|
||||
@ -62,7 +60,6 @@ class ApiAccountRateLimitStatusAction extends ApiBareAuthAction
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
|
||||
function handle($args)
|
||||
{
|
||||
parent::handle($args);
|
||||
@ -119,11 +116,8 @@ class ApiAccountRateLimitStatusAction extends ApiBareAuthAction
|
||||
*
|
||||
* @return boolean is read only action?
|
||||
*/
|
||||
|
||||
function isReadOnly($args)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
@ -45,7 +45,6 @@ require_once INSTALLDIR . '/lib/apiauth.php';
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||
* @link http://status.net/
|
||||
*/
|
||||
|
||||
class ApiAccountUpdateDeliveryDeviceAction extends ApiAuthAction
|
||||
{
|
||||
/**
|
||||
@ -54,9 +53,7 @@ class ApiAccountUpdateDeliveryDeviceAction extends ApiAuthAction
|
||||
* @param array $args $_REQUEST args
|
||||
*
|
||||
* @return boolean success flag
|
||||
*
|
||||
*/
|
||||
|
||||
function prepare($args)
|
||||
{
|
||||
parent::prepare($args);
|
||||
@ -76,13 +73,13 @@ class ApiAccountUpdateDeliveryDeviceAction extends ApiAuthAction
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
|
||||
function handle($args)
|
||||
{
|
||||
parent::handle($args);
|
||||
|
||||
if ($_SERVER['REQUEST_METHOD'] != 'POST') {
|
||||
$this->clientError(
|
||||
// TRANS: Client error message. POST is a HTTP command. It should not be translated.
|
||||
_('This method requires a POST.'),
|
||||
400, $this->format
|
||||
);
|
||||
@ -91,6 +88,7 @@ class ApiAccountUpdateDeliveryDeviceAction extends ApiAuthAction
|
||||
|
||||
if (!in_array($this->format, array('xml', 'json'))) {
|
||||
$this->clientError(
|
||||
// TRANS: Client error displayed handling a non-existing API method.
|
||||
_('API method not found.'),
|
||||
404,
|
||||
$this->format
|
||||
@ -101,16 +99,14 @@ class ApiAccountUpdateDeliveryDeviceAction extends ApiAuthAction
|
||||
// Note: Twitter no longer supports IM
|
||||
|
||||
if (!in_array(strtolower($this->device), array('sms', 'im', 'none'))) {
|
||||
$this->clientError(
|
||||
_(
|
||||
'You must specify a parameter named ' .
|
||||
'\'device\' with a value of one of: sms, im, none.'
|
||||
)
|
||||
);
|
||||
// TRANS: Client error displayed when no valid device parameter is provided for a user's delivery device setting.
|
||||
$this->clientError(_( 'You must specify a parameter named ' .
|
||||
'\'device\' with a value of one of: sms, im, none.' ));
|
||||
return;
|
||||
}
|
||||
|
||||
if (empty($this->user)) {
|
||||
// TRANS: Client error displayed when no existing user is provided for a user's delivery device setting.
|
||||
$this->clientError(_('No such user.'), 404, $this->format);
|
||||
return;
|
||||
}
|
||||
@ -136,6 +132,7 @@ class ApiAccountUpdateDeliveryDeviceAction extends ApiAuthAction
|
||||
|
||||
if ($result === false) {
|
||||
common_log_db_error($this->user, 'UPDATE', __FILE__);
|
||||
// TRANS: Server error displayed when a user's delivery device cannot be updated.
|
||||
$this->serverError(_('Could not update user.'));
|
||||
return;
|
||||
}
|
||||
@ -160,5 +157,4 @@ class ApiAccountUpdateDeliveryDeviceAction extends ApiAuthAction
|
||||
$this->endDocument('json');
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -43,19 +43,15 @@ require_once INSTALLDIR . '/lib/apiauth.php';
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||
* @link http://status.net/
|
||||
*/
|
||||
|
||||
class ApiAccountUpdateProfileAction extends ApiAuthAction
|
||||
{
|
||||
|
||||
/**
|
||||
* Take arguments for running
|
||||
*
|
||||
* @param array $args $_REQUEST args
|
||||
*
|
||||
* @return boolean success flag
|
||||
*
|
||||
*/
|
||||
|
||||
function prepare($args)
|
||||
{
|
||||
parent::prepare($args);
|
||||
@ -79,13 +75,13 @@ class ApiAccountUpdateProfileAction extends ApiAuthAction
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
|
||||
function handle($args)
|
||||
{
|
||||
parent::handle($args);
|
||||
|
||||
if ($_SERVER['REQUEST_METHOD'] != 'POST') {
|
||||
$this->clientError(
|
||||
// TRANS: Client error. POST is a HTTP command. It should not be translated.
|
||||
_('This method requires a POST.'),
|
||||
400, $this->format
|
||||
);
|
||||
@ -94,6 +90,7 @@ class ApiAccountUpdateProfileAction extends ApiAuthAction
|
||||
|
||||
if (!in_array($this->format, array('xml', 'json'))) {
|
||||
$this->clientError(
|
||||
// TRANS: Client error displayed when trying to handle an unknown API method.
|
||||
_('API method not found.'),
|
||||
404,
|
||||
$this->format
|
||||
@ -102,6 +99,7 @@ class ApiAccountUpdateProfileAction extends ApiAuthAction
|
||||
}
|
||||
|
||||
if (empty($this->user)) {
|
||||
// TRANS: Client error displayed if a user could not be found.
|
||||
$this->clientError(_('No such user.'), 404, $this->format);
|
||||
return;
|
||||
}
|
||||
@ -109,6 +107,7 @@ class ApiAccountUpdateProfileAction extends ApiAuthAction
|
||||
$profile = $this->user->getProfile();
|
||||
|
||||
if (empty($profile)) {
|
||||
// TRANS: Client error displayed if a user profile could not be found.
|
||||
$this->clientError(_('User has no profile.'));
|
||||
return;
|
||||
}
|
||||
@ -144,6 +143,7 @@ class ApiAccountUpdateProfileAction extends ApiAuthAction
|
||||
|
||||
if (!$result) {
|
||||
common_log_db_error($profile, 'UPDATE', __FILE__);
|
||||
// TRANS: Server error displayed if a user profile could not be saved.
|
||||
$this->serverError(_('Could not save profile.'));
|
||||
return;
|
||||
}
|
||||
@ -162,5 +162,4 @@ class ApiAccountUpdateProfileAction extends ApiAuthAction
|
||||
$this->endDocument('json');
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -42,10 +42,8 @@ require_once INSTALLDIR . '/lib/apiauth.php';
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||
* @link http://status.net/
|
||||
*/
|
||||
|
||||
class ApiAccountUpdateProfileBackgroundImageAction extends ApiAuthAction
|
||||
{
|
||||
|
||||
var $tile = false;
|
||||
|
||||
/**
|
||||
@ -56,7 +54,6 @@ class ApiAccountUpdateProfileBackgroundImageAction extends ApiAuthAction
|
||||
* @return boolean success flag
|
||||
*
|
||||
*/
|
||||
|
||||
function prepare($args)
|
||||
{
|
||||
parent::prepare($args);
|
||||
@ -76,13 +73,13 @@ class ApiAccountUpdateProfileBackgroundImageAction extends ApiAuthAction
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
|
||||
function handle($args)
|
||||
{
|
||||
parent::handle($args);
|
||||
|
||||
if ($_SERVER['REQUEST_METHOD'] != 'POST') {
|
||||
$this->clientError(
|
||||
// TRANS: Client error. POST is a HTTP command. It should not be translated.
|
||||
_('This method requires a POST.'),
|
||||
400, $this->format
|
||||
);
|
||||
@ -91,6 +88,7 @@ class ApiAccountUpdateProfileBackgroundImageAction extends ApiAuthAction
|
||||
|
||||
if (!in_array($this->format, array('xml', 'json'))) {
|
||||
$this->clientError(
|
||||
// TRANS: Client error displayed when trying to handle an unknown API method.
|
||||
_('API method not found.'),
|
||||
404,
|
||||
$this->format
|
||||
@ -105,14 +103,18 @@ class ApiAccountUpdateProfileBackgroundImageAction extends ApiAuthAction
|
||||
&& empty($_POST)
|
||||
&& ($_SERVER['CONTENT_LENGTH'] > 0)
|
||||
) {
|
||||
$msg = _('The server was unable to handle that much POST ' .
|
||||
'data (%s bytes) due to its current configuration.');
|
||||
// TRANS: Client error displayed when the number of bytes in a POST request exceeds a limit.
|
||||
// TRANS: %s is the number of bytes of the CONTENT_LENGTH.
|
||||
$msg = _m('The server was unable to handle that much POST data (%s byte) due to its current configuration.',
|
||||
'The server was unable to handle that much POST data (%s bytes) due to its current configuration.',
|
||||
intval($_SERVER['CONTENT_LENGTH']));
|
||||
|
||||
$this->clientError(sprintf($msg, $_SERVER['CONTENT_LENGTH']));
|
||||
return;
|
||||
}
|
||||
|
||||
if (empty($this->user)) {
|
||||
// TRANS: Client error when user not found updating a profile background image.
|
||||
$this->clientError(_('No such user.'), 404, $this->format);
|
||||
return;
|
||||
}
|
||||
@ -124,7 +126,6 @@ class ApiAccountUpdateProfileBackgroundImageAction extends ApiAuthAction
|
||||
// is part of the img filename.
|
||||
|
||||
if (empty($design)) {
|
||||
|
||||
$this->user->query('BEGIN');
|
||||
|
||||
// save new design
|
||||
@ -133,6 +134,7 @@ class ApiAccountUpdateProfileBackgroundImageAction extends ApiAuthAction
|
||||
|
||||
if (empty($id)) {
|
||||
common_log_db_error($id, 'INSERT', __FILE__);
|
||||
// TRANS: Client error displayed when saving design settings fails because of an empty id.
|
||||
$this->clientError(_('Unable to save your design settings.'));
|
||||
return;
|
||||
}
|
||||
@ -143,6 +145,7 @@ class ApiAccountUpdateProfileBackgroundImageAction extends ApiAuthAction
|
||||
|
||||
if (empty($result)) {
|
||||
common_log_db_error($original, 'UPDATE', __FILE__);
|
||||
// TRANS: Client error displayed when saving design settings fails because of an empty result.
|
||||
$this->clientError(_('Unable to save your design settings.'));
|
||||
$this->user->query('ROLLBACK');
|
||||
return;
|
||||
@ -184,6 +187,7 @@ class ApiAccountUpdateProfileBackgroundImageAction extends ApiAuthAction
|
||||
|
||||
if ($result === false) {
|
||||
common_log_db_error($design, 'UPDATE', __FILE__);
|
||||
// TRANS: Error displayed when updating design settings fails.
|
||||
$this->showForm(_('Could not update your design.'));
|
||||
return;
|
||||
}
|
||||
@ -191,6 +195,7 @@ class ApiAccountUpdateProfileBackgroundImageAction extends ApiAuthAction
|
||||
$profile = $this->user->getProfile();
|
||||
|
||||
if (empty($profile)) {
|
||||
// TRANS: Client error displayed when a user has no profile.
|
||||
$this->clientError(_('User has no profile.'));
|
||||
return;
|
||||
}
|
||||
@ -207,5 +212,4 @@ class ApiAccountUpdateProfileBackgroundImageAction extends ApiAuthAction
|
||||
$this->endDocument('json');
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -43,10 +43,8 @@ require_once INSTALLDIR . '/lib/apiauth.php';
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||
* @link http://status.net/
|
||||
*/
|
||||
|
||||
class ApiAccountUpdateProfileColorsAction extends ApiAuthAction
|
||||
{
|
||||
|
||||
var $profile_background_color = null;
|
||||
var $profile_text_color = null;
|
||||
var $profile_link_color = null;
|
||||
@ -59,9 +57,7 @@ class ApiAccountUpdateProfileColorsAction extends ApiAuthAction
|
||||
* @param array $args $_REQUEST args
|
||||
*
|
||||
* @return boolean success flag
|
||||
*
|
||||
*/
|
||||
|
||||
function prepare($args)
|
||||
{
|
||||
parent::prepare($args);
|
||||
@ -100,13 +96,13 @@ class ApiAccountUpdateProfileColorsAction extends ApiAuthAction
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
|
||||
function handle($args)
|
||||
{
|
||||
parent::handle($args);
|
||||
|
||||
if ($_SERVER['REQUEST_METHOD'] != 'POST') {
|
||||
$this->clientError(
|
||||
// TRANS: Client error. POST is a HTTP command. It should not be translated.
|
||||
_('This method requires a POST.'),
|
||||
400, $this->format
|
||||
);
|
||||
@ -115,6 +111,7 @@ class ApiAccountUpdateProfileColorsAction extends ApiAuthAction
|
||||
|
||||
if (!in_array($this->format, array('xml', 'json'))) {
|
||||
$this->clientError(
|
||||
// TRANS: Client error displayed trying to execute an unknown API method updating profile colours.
|
||||
_('API method not found.'),
|
||||
404,
|
||||
$this->format
|
||||
@ -125,7 +122,6 @@ class ApiAccountUpdateProfileColorsAction extends ApiAuthAction
|
||||
$design = $this->user->getDesign();
|
||||
|
||||
if (!empty($design)) {
|
||||
|
||||
$original = clone($design);
|
||||
|
||||
try {
|
||||
@ -139,12 +135,11 @@ class ApiAccountUpdateProfileColorsAction extends ApiAuthAction
|
||||
|
||||
if ($result === false) {
|
||||
common_log_db_error($design, 'UPDATE', __FILE__);
|
||||
// TRANS: Client error displayed when a database error occurs updating profile colours.
|
||||
$this->clientError(_('Could not update your design.'));
|
||||
return;
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
$this->user->query('BEGIN');
|
||||
|
||||
// save new design
|
||||
@ -161,6 +156,7 @@ class ApiAccountUpdateProfileColorsAction extends ApiAuthAction
|
||||
|
||||
if (empty($id)) {
|
||||
common_log_db_error($id, 'INSERT', __FILE__);
|
||||
// TRANS: Client error displayed when a database error occurs inserting profile colours.
|
||||
$this->clientError(_('Unable to save your design settings.'));
|
||||
return;
|
||||
}
|
||||
@ -171,6 +167,7 @@ class ApiAccountUpdateProfileColorsAction extends ApiAuthAction
|
||||
|
||||
if (empty($result)) {
|
||||
common_log_db_error($original, 'UPDATE', __FILE__);
|
||||
// TRANS: Client error displayed when a database error occurs updating profile colours.
|
||||
$this->clientError(_('Unable to save your design settings.'));
|
||||
$this->user->query('ROLLBACK');
|
||||
return;
|
||||
@ -182,6 +179,7 @@ class ApiAccountUpdateProfileColorsAction extends ApiAuthAction
|
||||
$profile = $this->user->getProfile();
|
||||
|
||||
if (empty($profile)) {
|
||||
// TRANS: Client error displayed a user has no profile updating profile colours.
|
||||
$this->clientError(_('User has no profile.'));
|
||||
return;
|
||||
}
|
||||
@ -206,7 +204,6 @@ class ApiAccountUpdateProfileColorsAction extends ApiAuthAction
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
|
||||
function setColors($design)
|
||||
{
|
||||
$bgcolor = empty($this->profile_background_color) ?
|
||||
@ -242,5 +239,4 @@ class ApiAccountUpdateProfileColorsAction extends ApiAuthAction
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -43,19 +43,15 @@ require_once INSTALLDIR . '/lib/apiauth.php';
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||
* @link http://status.net/
|
||||
*/
|
||||
|
||||
class ApiAccountUpdateProfileImageAction extends ApiAuthAction
|
||||
{
|
||||
|
||||
/**
|
||||
* Take arguments for running
|
||||
*
|
||||
* @param array $args $_REQUEST args
|
||||
*
|
||||
* @return boolean success flag
|
||||
*
|
||||
*/
|
||||
|
||||
function prepare($args)
|
||||
{
|
||||
parent::prepare($args);
|
||||
@ -74,13 +70,13 @@ class ApiAccountUpdateProfileImageAction extends ApiAuthAction
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
|
||||
function handle($args)
|
||||
{
|
||||
parent::handle($args);
|
||||
|
||||
if ($_SERVER['REQUEST_METHOD'] != 'POST') {
|
||||
$this->clientError(
|
||||
// TRANS: Client error. POST is a HTTP command. It should not be translated.
|
||||
_('This method requires a POST.'),
|
||||
400, $this->format
|
||||
);
|
||||
@ -94,14 +90,17 @@ class ApiAccountUpdateProfileImageAction extends ApiAuthAction
|
||||
&& empty($_POST)
|
||||
&& ($_SERVER['CONTENT_LENGTH'] > 0)
|
||||
) {
|
||||
$msg = _('The server was unable to handle that much POST ' .
|
||||
'data (%s bytes) due to its current configuration.');
|
||||
|
||||
// TRANS: Client error displayed when the number of bytes in a POST request exceeds a limit.
|
||||
// TRANS: %s is the number of bytes of the CONTENT_LENGTH.
|
||||
$msg = _m('The server was unable to handle that much POST data (%s byte) due to its current configuration.',
|
||||
'The server was unable to handle that much POST data (%s bytes) due to its current configuration.',
|
||||
intval($_SERVER['CONTENT_LENGTH']));
|
||||
$this->clientError(sprintf($msg, $_SERVER['CONTENT_LENGTH']));
|
||||
return;
|
||||
}
|
||||
|
||||
if (empty($this->user)) {
|
||||
// TRANS: Client error displayed updating profile image without having a user object.
|
||||
$this->clientError(_('No such user.'), 404, $this->format);
|
||||
return;
|
||||
}
|
||||
@ -127,6 +126,7 @@ class ApiAccountUpdateProfileImageAction extends ApiAuthAction
|
||||
$profile = $this->user->getProfile();
|
||||
|
||||
if (empty($profile)) {
|
||||
// TRANS: Client error displayed if a user profile could not be found updating a profile image.
|
||||
$this->clientError(_('User has no profile.'));
|
||||
return;
|
||||
}
|
||||
@ -147,5 +147,4 @@ class ApiAccountUpdateProfileImageAction extends ApiAuthAction
|
||||
$this->endDocument('json');
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -48,10 +48,8 @@ require_once INSTALLDIR . '/lib/apiauth.php';
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||
* @link http://status.net/
|
||||
*/
|
||||
|
||||
class ApiAccountVerifyCredentialsAction extends ApiAuthAction
|
||||
{
|
||||
|
||||
/**
|
||||
* Handle the request
|
||||
*
|
||||
@ -61,12 +59,12 @@ class ApiAccountVerifyCredentialsAction extends ApiAuthAction
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
|
||||
function handle($args)
|
||||
{
|
||||
parent::handle($args);
|
||||
|
||||
if (!in_array($this->format, array('xml', 'json'))) {
|
||||
// TRANS: Client error displayed trying to execute an unknown API method verifying user credentials.
|
||||
$this->clientError(_('API method not found.'), $code = 404);
|
||||
return;
|
||||
}
|
||||
@ -91,12 +89,9 @@ class ApiAccountVerifyCredentialsAction extends ApiAuthAction
|
||||
* @param array $args other arguments
|
||||
*
|
||||
* @return boolean true
|
||||
*
|
||||
**/
|
||||
|
||||
*/
|
||||
function isReadOnly($args)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
132
actions/apiatomservice.php
Normal file
132
actions/apiatomservice.php
Normal file
@ -0,0 +1,132 @@
|
||||
<?php
|
||||
/**
|
||||
* StatusNet, the distributed open-source microblogging tool
|
||||
*
|
||||
* An AtomPub service document for a user
|
||||
*
|
||||
* 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 API
|
||||
* @package StatusNet
|
||||
* @author Evan Prodromou <evan@status.net>
|
||||
* @copyright 2010 StatusNet, Inc.
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPLv3
|
||||
* @link http://status.net/
|
||||
*/
|
||||
|
||||
require_once INSTALLDIR.'/lib/apibareauth.php';
|
||||
|
||||
/**
|
||||
* Shows an AtomPub service document for a user
|
||||
*
|
||||
* @category API
|
||||
* @package StatusNet
|
||||
* @author Evan Prodromou <evan@status.net>
|
||||
* @copyright 2010 StatusNet, Inc.
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPLv3
|
||||
* @link http://status.net/
|
||||
*/
|
||||
|
||||
class ApiAtomServiceAction extends ApiBareAuthAction
|
||||
{
|
||||
/**
|
||||
* Take arguments for running
|
||||
*
|
||||
* @param array $args $_REQUEST args
|
||||
*
|
||||
* @return boolean success flag
|
||||
*
|
||||
*/
|
||||
|
||||
function prepare($args)
|
||||
{
|
||||
parent::prepare($args);
|
||||
$this->user = $this->getTargetUser($this->arg('id'));
|
||||
|
||||
if (empty($this->user)) {
|
||||
$this->clientError(_('No such user.'), 404, $this->format);
|
||||
return;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle the arguments. In our case, show a service document.
|
||||
*
|
||||
* @param Array $args unused.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
|
||||
function handle($args)
|
||||
{
|
||||
parent::handle($args);
|
||||
|
||||
header('Content-Type: application/atomsvc+xml');
|
||||
|
||||
$this->startXML();
|
||||
$this->elementStart('service', array('xmlns' => 'http://www.w3.org/2007/app',
|
||||
'xmlns:atom' => 'http://www.w3.org/2005/Atom',
|
||||
'xmlns:activity' => 'http://activitystrea.ms/spec/1.0/'));
|
||||
$this->elementStart('workspace');
|
||||
$this->element('atom:title', null, _('Main'));
|
||||
$this->elementStart('collection',
|
||||
array('href' => common_local_url('ApiTimelineUser',
|
||||
array('id' => $this->user->id,
|
||||
'format' => 'atom'))));
|
||||
$this->element('atom:title',
|
||||
null,
|
||||
sprintf(_("%s timeline"),
|
||||
$this->user->nickname));
|
||||
$this->element('accept', null, 'application/atom+xml;type=entry');
|
||||
$this->element('activity:verb', null, ActivityVerb::POST);
|
||||
$this->elementEnd('collection');
|
||||
$this->elementStart('collection',
|
||||
array('href' => common_local_url('AtomPubSubscriptionFeed',
|
||||
array('subscriber' => $this->user->id))));
|
||||
$this->element('atom:title',
|
||||
null,
|
||||
sprintf(_("%s subscriptions"),
|
||||
$this->user->nickname));
|
||||
$this->element('accept', null, 'application/atom+xml;type=entry');
|
||||
$this->element('activity:verb', null, ActivityVerb::FOLLOW);
|
||||
$this->elementEnd('collection');
|
||||
$this->elementStart('collection',
|
||||
array('href' => common_local_url('AtomPubFavoriteFeed',
|
||||
array('profile' => $this->user->id))));
|
||||
$this->element('atom:title',
|
||||
null,
|
||||
sprintf(_("%s favorites"),
|
||||
$this->user->nickname));
|
||||
$this->element('accept', null, 'application/atom+xml;type=entry');
|
||||
$this->element('activity:verb', null, ActivityVerb::FAVORITE);
|
||||
$this->elementEnd('collection');
|
||||
$this->elementStart('collection',
|
||||
array('href' => common_local_url('AtomPubMembershipFeed',
|
||||
array('profile' => $this->user->id))));
|
||||
$this->element('atom:title',
|
||||
null,
|
||||
sprintf(_("%s memberships"),
|
||||
$this->user->nickname));
|
||||
$this->element('accept', null, 'application/atom+xml;type=entry');
|
||||
$this->element('activity:verb', null, ActivityVerb::JOIN);
|
||||
$this->elementEnd('collection');
|
||||
$this->elementEnd('workspace');
|
||||
$this->elementEnd('service');
|
||||
$this->endXML();
|
||||
}
|
||||
}
|
@ -46,7 +46,6 @@ require_once INSTALLDIR . '/lib/apiauth.php';
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||
* @link http://status.net/
|
||||
*/
|
||||
|
||||
class ApiBlockCreateAction extends ApiAuthAction
|
||||
{
|
||||
var $other = null;
|
||||
@ -59,7 +58,6 @@ class ApiBlockCreateAction extends ApiAuthAction
|
||||
* @return boolean success flag
|
||||
*
|
||||
*/
|
||||
|
||||
function prepare($args)
|
||||
{
|
||||
parent::prepare($args);
|
||||
@ -79,13 +77,13 @@ class ApiBlockCreateAction extends ApiAuthAction
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
|
||||
function handle($args)
|
||||
{
|
||||
parent::handle($args);
|
||||
|
||||
if ($_SERVER['REQUEST_METHOD'] != 'POST') {
|
||||
$this->clientError(
|
||||
// TRANS: Client error. POST is a HTTP command. It should not be translated.
|
||||
_('This method requires a POST.'),
|
||||
400,
|
||||
$this->format
|
||||
@ -102,6 +100,7 @@ class ApiBlockCreateAction extends ApiAuthAction
|
||||
|
||||
if ($this->user->id == $this->other->id) {
|
||||
$this->clientError(
|
||||
// TRANS: Client error displayed when users try to block themselves.
|
||||
_("You cannot block yourself!"),
|
||||
403,
|
||||
$this->format
|
||||
@ -123,10 +122,8 @@ class ApiBlockCreateAction extends ApiAuthAction
|
||||
$this->showProfile($this->other, $this->format);
|
||||
$this->endDocument($this->format);
|
||||
} else {
|
||||
// TRANS: Server error displayed when blocking a user has failed.
|
||||
$this->serverError(_('Block user failed.'), 500, $this->format);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
@ -45,7 +45,6 @@ require_once INSTALLDIR . '/lib/apiauth.php';
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||
* @link http://status.net/
|
||||
*/
|
||||
|
||||
class ApiBlockDestroyAction extends ApiAuthAction
|
||||
{
|
||||
var $other = null;
|
||||
@ -56,9 +55,7 @@ class ApiBlockDestroyAction extends ApiAuthAction
|
||||
* @param array $args $_REQUEST args
|
||||
*
|
||||
* @return boolean success flag
|
||||
*
|
||||
*/
|
||||
|
||||
function prepare($args)
|
||||
{
|
||||
parent::prepare($args);
|
||||
@ -78,13 +75,13 @@ class ApiBlockDestroyAction extends ApiAuthAction
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
|
||||
function handle($args)
|
||||
{
|
||||
parent::handle($args);
|
||||
|
||||
if ($_SERVER['REQUEST_METHOD'] != 'POST') {
|
||||
$this->clientError(
|
||||
// TRANS: Client error. POST is a HTTP command. It should not be translated.
|
||||
_('This method requires a POST.'),
|
||||
400,
|
||||
$this->format
|
||||
@ -93,6 +90,7 @@ class ApiBlockDestroyAction extends ApiAuthAction
|
||||
}
|
||||
|
||||
if (empty($this->user) || empty($this->other)) {
|
||||
// TRANS: Client error when user not found for an API action to remove a block for a user.
|
||||
$this->clientError(_('No such user.'), 404, $this->format);
|
||||
return;
|
||||
}
|
||||
@ -111,10 +109,8 @@ class ApiBlockDestroyAction extends ApiAuthAction
|
||||
$this->showProfile($this->other, $this->format);
|
||||
$this->endDocument($this->format);
|
||||
} else {
|
||||
// TRANS: Server error displayed when unblocking a user has failed.
|
||||
$this->serverError(_('Unblock user failed.'));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
@ -48,7 +48,6 @@ require_once INSTALLDIR . '/lib/apiauth.php';
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||
* @link http://status.net/
|
||||
*/
|
||||
|
||||
class ApiDirectMessageAction extends ApiAuthAction
|
||||
{
|
||||
var $messages = null;
|
||||
@ -64,9 +63,7 @@ class ApiDirectMessageAction extends ApiAuthAction
|
||||
* @param array $args $_REQUEST args
|
||||
*
|
||||
* @return boolean success flag
|
||||
*
|
||||
*/
|
||||
|
||||
function prepare($args)
|
||||
{
|
||||
parent::prepare($args);
|
||||
@ -74,6 +71,7 @@ class ApiDirectMessageAction extends ApiAuthAction
|
||||
$this->user = $this->auth_user;
|
||||
|
||||
if (empty($this->user)) {
|
||||
// TRANS: Client error given when a user was not found (404).
|
||||
$this->clientError(_('No such user.'), 404, $this->format);
|
||||
return;
|
||||
}
|
||||
@ -86,10 +84,12 @@ class ApiDirectMessageAction extends ApiAuthAction
|
||||
// Action was called by /api/direct_messages/sent.format
|
||||
|
||||
$this->title = sprintf(
|
||||
// TRANS: Title. %s is a user nickname.
|
||||
_("Direct messages from %s"),
|
||||
$this->user->nickname
|
||||
);
|
||||
$this->subtitle = sprintf(
|
||||
// TRANS: Subtitle. %s is a user nickname.
|
||||
_("All the direct messages sent from %s"),
|
||||
$this->user->nickname
|
||||
);
|
||||
@ -98,10 +98,12 @@ class ApiDirectMessageAction extends ApiAuthAction
|
||||
$this->id = "tag:$taguribase:SentDirectMessages:" . $this->user->id;
|
||||
} else {
|
||||
$this->title = sprintf(
|
||||
// TRANS: Title. %s is a user nickname.
|
||||
_("Direct messages to %s"),
|
||||
$this->user->nickname
|
||||
);
|
||||
$this->subtitle = sprintf(
|
||||
// TRANS: Subtitle. %s is a user nickname.
|
||||
_("All the direct messages sent to %s"),
|
||||
$this->user->nickname
|
||||
);
|
||||
@ -124,7 +126,6 @@ class ApiDirectMessageAction extends ApiAuthAction
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
|
||||
function handle($args)
|
||||
{
|
||||
parent::handle($args);
|
||||
@ -136,7 +137,6 @@ class ApiDirectMessageAction extends ApiAuthAction
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
|
||||
function showMessages()
|
||||
{
|
||||
switch($this->format) {
|
||||
@ -153,6 +153,7 @@ class ApiDirectMessageAction extends ApiAuthAction
|
||||
$this->showJsonDirectMessages();
|
||||
break;
|
||||
default:
|
||||
// TRANS: Client error given when an API method was not found (404).
|
||||
$this->clientError(_('API method not found.'), $code = 404);
|
||||
break;
|
||||
}
|
||||
@ -163,7 +164,6 @@ class ApiDirectMessageAction extends ApiAuthAction
|
||||
*
|
||||
* @return array notices
|
||||
*/
|
||||
|
||||
function getMessages()
|
||||
{
|
||||
$message = new Message();
|
||||
@ -202,7 +202,6 @@ class ApiDirectMessageAction extends ApiAuthAction
|
||||
*
|
||||
* @return boolean true
|
||||
*/
|
||||
|
||||
function isReadOnly($args)
|
||||
{
|
||||
return true;
|
||||
@ -213,7 +212,6 @@ class ApiDirectMessageAction extends ApiAuthAction
|
||||
*
|
||||
* @return string datestamp of the latest notice in the stream
|
||||
*/
|
||||
|
||||
function lastModified()
|
||||
{
|
||||
if (!empty($this->messages)) {
|
||||
@ -228,7 +226,6 @@ class ApiDirectMessageAction extends ApiAuthAction
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
|
||||
function showXmlDirectMessages()
|
||||
{
|
||||
$this->initDocument('xml');
|
||||
@ -249,7 +246,6 @@ class ApiDirectMessageAction extends ApiAuthAction
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
|
||||
function showJsonDirectMessages()
|
||||
{
|
||||
$this->initDocument('json');
|
||||
@ -270,7 +266,6 @@ class ApiDirectMessageAction extends ApiAuthAction
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
|
||||
function showRssDirectMessages()
|
||||
{
|
||||
$this->initDocument('rss');
|
||||
@ -305,7 +300,6 @@ class ApiDirectMessageAction extends ApiAuthAction
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
|
||||
function showAtomDirectMessages()
|
||||
{
|
||||
$this->initDocument('atom');
|
||||
@ -347,7 +341,6 @@ class ApiDirectMessageAction extends ApiAuthAction
|
||||
*
|
||||
* @return string etag
|
||||
*/
|
||||
|
||||
function etag()
|
||||
{
|
||||
if (!empty($this->messages)) {
|
||||
@ -357,6 +350,7 @@ class ApiDirectMessageAction extends ApiAuthAction
|
||||
return '"' . implode(
|
||||
':',
|
||||
array($this->arg('action'),
|
||||
common_user_cache_hash($this->auth_user),
|
||||
common_language(),
|
||||
strtotime($this->messages[0]->created),
|
||||
strtotime($this->messages[$last]->created)
|
||||
@ -367,5 +361,4 @@ class ApiDirectMessageAction extends ApiAuthAction
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -49,7 +49,6 @@ require_once INSTALLDIR . '/lib/apiauth.php';
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||
* @link http://status.net/
|
||||
*/
|
||||
|
||||
class ApiDirectMessageNewAction extends ApiAuthAction
|
||||
{
|
||||
var $other = null;
|
||||
@ -61,9 +60,7 @@ class ApiDirectMessageNewAction extends ApiAuthAction
|
||||
* @param array $args $_REQUEST args
|
||||
*
|
||||
* @return boolean success flag
|
||||
*
|
||||
*/
|
||||
|
||||
function prepare($args)
|
||||
{
|
||||
parent::prepare($args);
|
||||
@ -71,6 +68,7 @@ class ApiDirectMessageNewAction extends ApiAuthAction
|
||||
$this->user = $this->auth_user;
|
||||
|
||||
if (empty($this->user)) {
|
||||
// TRANS: Client error when user not found for an API direct message action.
|
||||
$this->clientError(_('No such user.'), 404, $this->format);
|
||||
return;
|
||||
}
|
||||
@ -99,13 +97,13 @@ class ApiDirectMessageNewAction extends ApiAuthAction
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
|
||||
function handle($args)
|
||||
{
|
||||
parent::handle($args);
|
||||
|
||||
if ($_SERVER['REQUEST_METHOD'] != 'POST') {
|
||||
$this->clientError(
|
||||
// TRANS: Client error. POST is a HTTP command. It should not be translated.
|
||||
_('This method requires a POST.'),
|
||||
400,
|
||||
$this->format
|
||||
@ -115,16 +113,18 @@ class ApiDirectMessageNewAction extends ApiAuthAction
|
||||
|
||||
if (empty($this->content)) {
|
||||
$this->clientError(
|
||||
// TRANS: Client error displayed when no message text was submitted (406).
|
||||
_('No message text!'),
|
||||
406,
|
||||
$this->format
|
||||
);
|
||||
} else {
|
||||
$content_shortened = common_shorten_links($this->content);
|
||||
$content_shortened = $this->auth_user->shortenLinks($this->content);
|
||||
if (Message::contentTooLong($content_shortened)) {
|
||||
$this->clientError(
|
||||
sprintf(
|
||||
_('That\'s too long. Max message size is %d chars.'),
|
||||
// TRANS: Client error displayed when message content is too long.
|
||||
// TRANS: %d is the maximum number of characters for a message.
|
||||
sprintf(_m('That\'s too long. Maximum message size is %d character.', 'That\'s too long. Maximum message size is %d characters.', Message::maxContent()),
|
||||
Message::maxContent()
|
||||
),
|
||||
406,
|
||||
@ -135,10 +135,12 @@ class ApiDirectMessageNewAction extends ApiAuthAction
|
||||
}
|
||||
|
||||
if (empty($this->other)) {
|
||||
// TRANS: Client error displayed if a recipient user could not be found (403).
|
||||
$this->clientError(_('Recipient user not found.'), 403, $this->format);
|
||||
return;
|
||||
} else if (!$this->user->mutuallySubscribed($this->other)) {
|
||||
$this->clientError(
|
||||
// TRANS: Client error displayed trying to direct message another user who's not a friend (403).
|
||||
_('Can\'t send direct messages to users who aren\'t your friend.'),
|
||||
403,
|
||||
$this->format
|
||||
@ -148,10 +150,9 @@ class ApiDirectMessageNewAction extends ApiAuthAction
|
||||
|
||||
// Note: sending msgs to yourself is allowed by Twitter
|
||||
|
||||
$errmsg = 'Don\'t send a message to yourself; ' .
|
||||
'just say it to yourself quietly instead.';
|
||||
|
||||
$this->clientError(_($errmsg), 403, $this->format);
|
||||
// TRANS: Client error displayed trying to direct message self (403).
|
||||
$this->clientError(_('Do not send a message to yourself; ' .
|
||||
'just say it to yourself quietly instead.'), 403, $this->format);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -175,6 +176,4 @@ class ApiDirectMessageNewAction extends ApiAuthAction
|
||||
$this->showSingleJsondirectMessage($message);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
@ -48,7 +48,6 @@ require_once INSTALLDIR . '/lib/apiauth.php';
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||
* @link http://status.net/
|
||||
*/
|
||||
|
||||
class ApiFavoriteCreateAction extends ApiAuthAction
|
||||
{
|
||||
var $notice = null;
|
||||
@ -59,9 +58,7 @@ class ApiFavoriteCreateAction extends ApiAuthAction
|
||||
* @param array $args $_REQUEST args
|
||||
*
|
||||
* @return boolean success flag
|
||||
*
|
||||
*/
|
||||
|
||||
function prepare($args)
|
||||
{
|
||||
parent::prepare($args);
|
||||
@ -81,13 +78,13 @@ class ApiFavoriteCreateAction extends ApiAuthAction
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
|
||||
function handle($args)
|
||||
{
|
||||
parent::handle($args);
|
||||
|
||||
if ($_SERVER['REQUEST_METHOD'] != 'POST') {
|
||||
$this->clientError(
|
||||
// TRANS: Client error. POST is a HTTP command. It should not be translated.
|
||||
_('This method requires a POST.'),
|
||||
400,
|
||||
$this->format
|
||||
@ -97,6 +94,7 @@ class ApiFavoriteCreateAction extends ApiAuthAction
|
||||
|
||||
if (!in_array($this->format, array('xml', 'json'))) {
|
||||
$this->clientError(
|
||||
// TRANS: Client error displayed when trying to handle an unknown API method.
|
||||
_('API method not found.'),
|
||||
404,
|
||||
$this->format
|
||||
@ -106,6 +104,7 @@ class ApiFavoriteCreateAction extends ApiAuthAction
|
||||
|
||||
if (empty($this->notice)) {
|
||||
$this->clientError(
|
||||
// TRANS: Client error displayed when requesting a status with a non-existing ID.
|
||||
_('No status found with that ID.'),
|
||||
404,
|
||||
$this->format
|
||||
@ -117,6 +116,7 @@ class ApiFavoriteCreateAction extends ApiAuthAction
|
||||
|
||||
if ($this->user->hasFave($this->notice)) {
|
||||
$this->clientError(
|
||||
// TRANS: Client error displayed when trying to mark a notice favourite that already is a favourite.
|
||||
_('This status is already a favorite.'),
|
||||
403,
|
||||
$this->format
|
||||
@ -128,6 +128,7 @@ class ApiFavoriteCreateAction extends ApiAuthAction
|
||||
|
||||
if (empty($fave)) {
|
||||
$this->clientError(
|
||||
// TRANS: Client error displayed when marking a notice as favourite fails.
|
||||
_('Could not create favorite.'),
|
||||
403,
|
||||
$this->format
|
||||
@ -165,5 +166,4 @@ class ApiFavoriteCreateAction extends ApiAuthAction
|
||||
// XXX: notify by SMS
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -48,10 +48,8 @@ require_once INSTALLDIR . '/lib/apiauth.php';
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||
* @link http://status.net/
|
||||
*/
|
||||
|
||||
class ApiFavoriteDestroyAction extends ApiAuthAction
|
||||
{
|
||||
|
||||
var $notice = null;
|
||||
|
||||
/**
|
||||
@ -60,9 +58,7 @@ class ApiFavoriteDestroyAction extends ApiAuthAction
|
||||
* @param array $args $_REQUEST args
|
||||
*
|
||||
* @return boolean success flag
|
||||
*
|
||||
*/
|
||||
|
||||
function prepare($args)
|
||||
{
|
||||
parent::prepare($args);
|
||||
@ -82,13 +78,13 @@ class ApiFavoriteDestroyAction extends ApiAuthAction
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
|
||||
function handle($args)
|
||||
{
|
||||
parent::handle($args);
|
||||
|
||||
if ($_SERVER['REQUEST_METHOD'] != 'POST') {
|
||||
$this->clientError(
|
||||
// TRANS: Client error. POST is a HTTP command. It should not be translated.
|
||||
_('This method requires a POST.'),
|
||||
400,
|
||||
$this->format
|
||||
@ -98,6 +94,7 @@ class ApiFavoriteDestroyAction extends ApiAuthAction
|
||||
|
||||
if (!in_array($this->format, array('xml', 'json'))) {
|
||||
$this->clientError(
|
||||
// TRANS: Client error displayed when trying to handle an unknown API method.
|
||||
_('API method not found.'),
|
||||
404,
|
||||
$this->format
|
||||
@ -107,6 +104,7 @@ class ApiFavoriteDestroyAction extends ApiAuthAction
|
||||
|
||||
if (empty($this->notice)) {
|
||||
$this->clientError(
|
||||
// TRANS: Client error displayed when trying to remove a favourite with an invalid ID.
|
||||
_('No status found with that ID.'),
|
||||
404,
|
||||
$this->format
|
||||
@ -120,6 +118,7 @@ class ApiFavoriteDestroyAction extends ApiAuthAction
|
||||
|
||||
if (!$fave->find(true)) {
|
||||
$this->clientError(
|
||||
// TRANS: Client error displayed when trying to remove a favourite that was not a favourite.
|
||||
_('That status is not a favorite.'),
|
||||
403,
|
||||
$this->favorite
|
||||
@ -132,6 +131,7 @@ class ApiFavoriteDestroyAction extends ApiAuthAction
|
||||
if (!$result) {
|
||||
common_log_db_error($fave, 'DELETE', __FILE__);
|
||||
$this->clientError(
|
||||
// TRANS: Client error displayed when removing a favourite has failed.
|
||||
_('Could not delete favorite.'),
|
||||
404,
|
||||
$this->format
|
||||
@ -147,5 +147,4 @@ class ApiFavoriteDestroyAction extends ApiAuthAction
|
||||
$this->show_single_json_status($this->notice);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -48,7 +48,6 @@ require_once INSTALLDIR . '/lib/apiauth.php';
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||
* @link http://status.net/
|
||||
*/
|
||||
|
||||
class ApiFriendshipsCreateAction extends ApiAuthAction
|
||||
{
|
||||
var $other = null;
|
||||
@ -61,7 +60,6 @@ class ApiFriendshipsCreateAction extends ApiAuthAction
|
||||
* @return boolean success flag
|
||||
*
|
||||
*/
|
||||
|
||||
function prepare($args)
|
||||
{
|
||||
parent::prepare($args);
|
||||
@ -81,13 +79,13 @@ class ApiFriendshipsCreateAction extends ApiAuthAction
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
|
||||
function handle($args)
|
||||
{
|
||||
parent::handle($args);
|
||||
|
||||
if ($_SERVER['REQUEST_METHOD'] != 'POST') {
|
||||
$this->clientError(
|
||||
// TRANS: Client error. POST is a HTTP command. It should not be translated.
|
||||
_('This method requires a POST.'),
|
||||
400,
|
||||
$this->format
|
||||
@ -97,6 +95,7 @@ class ApiFriendshipsCreateAction extends ApiAuthAction
|
||||
|
||||
if (!in_array($this->format, array('xml', 'json'))) {
|
||||
$this->clientError(
|
||||
// TRANS: Client error displayed when trying to handle an unknown API method.
|
||||
_('API method not found.'),
|
||||
404,
|
||||
$this->format
|
||||
@ -106,6 +105,7 @@ class ApiFriendshipsCreateAction extends ApiAuthAction
|
||||
|
||||
if (empty($this->other)) {
|
||||
$this->clientError(
|
||||
// TRANS: Client error displayed when trying follow who's profile could not be found.
|
||||
_('Could not follow user: profile not found.'),
|
||||
403,
|
||||
$this->format
|
||||
@ -115,6 +115,8 @@ class ApiFriendshipsCreateAction extends ApiAuthAction
|
||||
|
||||
if ($this->user->isSubscribed($this->other)) {
|
||||
$errmsg = sprintf(
|
||||
// TRANS: Client error displayed when trying to follow a user that's already being followed.
|
||||
// TRANS: %s is the nickname of the user that is already being followed.
|
||||
_('Could not follow user: %s is already on your list.'),
|
||||
$this->other->nickname
|
||||
);
|
||||
@ -133,5 +135,4 @@ class ApiFriendshipsCreateAction extends ApiAuthAction
|
||||
$this->showProfile($this->other, $this->format);
|
||||
$this->endDocument($this->format);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -48,7 +48,6 @@ require_once INSTALLDIR . '/lib/apiauth.php';
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||
* @link http://status.net/
|
||||
*/
|
||||
|
||||
class ApiFriendshipsDestroyAction extends ApiAuthAction
|
||||
{
|
||||
var $other = null;
|
||||
@ -61,7 +60,6 @@ class ApiFriendshipsDestroyAction extends ApiAuthAction
|
||||
* @return boolean success flag
|
||||
*
|
||||
*/
|
||||
|
||||
function prepare($args)
|
||||
{
|
||||
parent::prepare($args);
|
||||
@ -81,13 +79,13 @@ class ApiFriendshipsDestroyAction extends ApiAuthAction
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
|
||||
function handle($args)
|
||||
{
|
||||
parent::handle($args);
|
||||
|
||||
if ($_SERVER['REQUEST_METHOD'] != 'POST') {
|
||||
$this->clientError(
|
||||
// TRANS: Client error. POST is a HTTP command. It should not be translated.
|
||||
_('This method requires a POST.'),
|
||||
400,
|
||||
$this->format
|
||||
@ -97,6 +95,7 @@ class ApiFriendshipsDestroyAction extends ApiAuthAction
|
||||
|
||||
if (!in_array($this->format, array('xml', 'json'))) {
|
||||
$this->clientError(
|
||||
// TRANS: Client error displayed when trying to handle an unknown API method.
|
||||
_('API method not found.'),
|
||||
404,
|
||||
$this->format
|
||||
@ -106,6 +105,7 @@ class ApiFriendshipsDestroyAction extends ApiAuthAction
|
||||
|
||||
if (empty($this->other)) {
|
||||
$this->clientError(
|
||||
// TRANS: Client error displayed when trying to unfollow a user that cannot be found.
|
||||
_('Could not unfollow user: User not found.'),
|
||||
403,
|
||||
$this->format
|
||||
@ -117,6 +117,7 @@ class ApiFriendshipsDestroyAction extends ApiAuthAction
|
||||
|
||||
if ($this->user->id == $this->other->id) {
|
||||
$this->clientError(
|
||||
// TRANS: Client error displayed when trying to unfollow self.
|
||||
_("You cannot unfollow yourself."),
|
||||
403,
|
||||
$this->format
|
||||
@ -131,5 +132,4 @@ class ApiFriendshipsDestroyAction extends ApiAuthAction
|
||||
$this->showProfile($this->other, $this->format);
|
||||
$this->endDocument($this->format);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -47,7 +47,6 @@ require_once INSTALLDIR . '/lib/apiprivateauth.php';
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||
* @link http://status.net/
|
||||
*/
|
||||
|
||||
class ApiFriendshipsExistsAction extends ApiPrivateAuthAction
|
||||
{
|
||||
var $profile_a = null;
|
||||
@ -59,9 +58,7 @@ class ApiFriendshipsExistsAction extends ApiPrivateAuthAction
|
||||
* @param array $args $_REQUEST args
|
||||
*
|
||||
* @return boolean success flag
|
||||
*
|
||||
*/
|
||||
|
||||
function prepare($args)
|
||||
{
|
||||
parent::prepare($args);
|
||||
@ -81,14 +78,14 @@ class ApiFriendshipsExistsAction extends ApiPrivateAuthAction
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
|
||||
function handle($args)
|
||||
{
|
||||
parent::handle($args);
|
||||
|
||||
if (empty($this->profile_a) || empty($this->profile_b)) {
|
||||
$this->clientError(
|
||||
_('Two valid IDs or screen_names must be supplied.'),
|
||||
// TRANS: Client error displayed when supplying invalid parameters to an API call checking if a friendship exists.
|
||||
_('Two valid IDs or nick names must be supplied.'),
|
||||
400,
|
||||
$this->format
|
||||
);
|
||||
@ -122,10 +119,8 @@ class ApiFriendshipsExistsAction extends ApiPrivateAuthAction
|
||||
*
|
||||
* @return boolean is read only action?
|
||||
*/
|
||||
|
||||
function isReadOnly($args)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -46,7 +46,6 @@ require_once INSTALLDIR . '/lib/apibareauth.php';
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||
* @link http://status.net/
|
||||
*/
|
||||
|
||||
class ApiFriendshipsShowAction extends ApiBareAuthAction
|
||||
{
|
||||
var $source = null;
|
||||
@ -58,9 +57,7 @@ class ApiFriendshipsShowAction extends ApiBareAuthAction
|
||||
* @param array $args $_REQUEST args
|
||||
*
|
||||
* @return boolean success flag
|
||||
*
|
||||
*/
|
||||
|
||||
function prepare($args)
|
||||
{
|
||||
parent::prepare($args);
|
||||
@ -93,7 +90,6 @@ class ApiFriendshipsShowAction extends ApiBareAuthAction
|
||||
*
|
||||
* @return boolean true or false
|
||||
*/
|
||||
|
||||
function requiresAuth()
|
||||
{
|
||||
if (common_config('site', 'private')) {
|
||||
@ -119,18 +115,19 @@ class ApiFriendshipsShowAction extends ApiBareAuthAction
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
|
||||
function handle($args)
|
||||
{
|
||||
parent::handle($args);
|
||||
|
||||
if (!in_array($this->format, array('xml', 'json'))) {
|
||||
// TRANS: Client error displayed trying to execute an unknown API method showing friendship.
|
||||
$this->clientError(_('API method not found.'), 404);
|
||||
return;
|
||||
}
|
||||
|
||||
if (empty($this->source)) {
|
||||
$this->clientError(
|
||||
// TRANS: Client error displayed when a source user could not be determined showing friendship.
|
||||
_('Could not determine source user.'),
|
||||
404
|
||||
);
|
||||
@ -139,6 +136,7 @@ class ApiFriendshipsShowAction extends ApiBareAuthAction
|
||||
|
||||
if (empty($this->target)) {
|
||||
$this->clientError(
|
||||
// TRANS: Client error displayed when a target user could not be determined showing friendship.
|
||||
_('Could not find target user.'),
|
||||
404
|
||||
);
|
||||
@ -161,7 +159,6 @@ class ApiFriendshipsShowAction extends ApiBareAuthAction
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@ -178,5 +175,4 @@ class ApiFriendshipsShowAction extends ApiBareAuthAction
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -49,7 +49,6 @@ require_once INSTALLDIR . '/lib/apiauth.php';
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||
* @link http://status.net/
|
||||
*/
|
||||
|
||||
class ApiGroupCreateAction extends ApiAuthAction
|
||||
{
|
||||
var $group = null;
|
||||
@ -67,16 +66,14 @@ class ApiGroupCreateAction extends ApiAuthAction
|
||||
* @param array $args $_REQUEST args
|
||||
*
|
||||
* @return boolean success flag
|
||||
*
|
||||
*/
|
||||
|
||||
function prepare($args)
|
||||
{
|
||||
parent::prepare($args);
|
||||
|
||||
$this->user = $this->auth_user;
|
||||
|
||||
$this->nickname = $this->arg('nickname');
|
||||
$this->nickname = Nickname::normalize($this->arg('nickname'));
|
||||
$this->fullname = $this->arg('full_name');
|
||||
$this->homepage = $this->arg('homepage');
|
||||
$this->description = $this->arg('description');
|
||||
@ -95,13 +92,13 @@ class ApiGroupCreateAction extends ApiAuthAction
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
|
||||
function handle($args)
|
||||
{
|
||||
parent::handle($args);
|
||||
|
||||
if ($_SERVER['REQUEST_METHOD'] != 'POST') {
|
||||
$this->clientError(
|
||||
// TRANS: Client error. POST is a HTTP command. It should not be translated.
|
||||
_('This method requires a POST.'),
|
||||
400,
|
||||
$this->format
|
||||
@ -110,6 +107,7 @@ class ApiGroupCreateAction extends ApiAuthAction
|
||||
}
|
||||
|
||||
if (empty($this->user)) {
|
||||
// TRANS: Client error given when a user was not found (404).
|
||||
$this->clientError(_('No such user.'), 404, $this->format);
|
||||
return;
|
||||
}
|
||||
@ -136,13 +134,13 @@ class ApiGroupCreateAction extends ApiAuthAction
|
||||
break;
|
||||
default:
|
||||
$this->clientError(
|
||||
// TRANS: Client error given when an API method was not found (404).
|
||||
_('API method not found.'),
|
||||
404,
|
||||
$this->format
|
||||
);
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@ -150,29 +148,11 @@ class ApiGroupCreateAction extends ApiAuthAction
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
|
||||
function validateParams()
|
||||
{
|
||||
$valid = Validate::string(
|
||||
$this->nickname, array(
|
||||
'min_length' => 1,
|
||||
'max_length' => 64,
|
||||
'format' => NICKNAME_FMT
|
||||
)
|
||||
);
|
||||
|
||||
if (!$valid) {
|
||||
$this->clientError(
|
||||
_(
|
||||
'Nickname must have only lowercase letters ' .
|
||||
'and numbers and no spaces.'
|
||||
),
|
||||
403,
|
||||
$this->format
|
||||
);
|
||||
return false;
|
||||
} elseif ($this->groupNicknameExists($this->nickname)) {
|
||||
if ($this->groupNicknameExists($this->nickname)) {
|
||||
$this->clientError(
|
||||
// TRANS: Client error trying to create a group with a nickname this is already in use.
|
||||
_('Nickname already in use. Try another one.'),
|
||||
403,
|
||||
$this->format
|
||||
@ -180,6 +160,7 @@ class ApiGroupCreateAction extends ApiAuthAction
|
||||
return false;
|
||||
} else if (!User_group::allowedNickname($this->nickname)) {
|
||||
$this->clientError(
|
||||
// TRANS: Client error in form for group creation.
|
||||
_('Not a valid nickname.'),
|
||||
403,
|
||||
$this->format
|
||||
@ -196,6 +177,7 @@ class ApiGroupCreateAction extends ApiAuthAction
|
||||
)
|
||||
)) {
|
||||
$this->clientError(
|
||||
// TRANS: Client error in form for group creation.
|
||||
_('Homepage is not a valid URL.'),
|
||||
403,
|
||||
$this->format
|
||||
@ -205,7 +187,8 @@ class ApiGroupCreateAction extends ApiAuthAction
|
||||
!is_null($this->fullname)
|
||||
&& mb_strlen($this->fullname) > 255) {
|
||||
$this->clientError(
|
||||
_('Full name is too long (max 255 chars).'),
|
||||
// TRANS: Client error in form for group creation.
|
||||
_('Full name is too long (maximum 255 characters).'),
|
||||
403,
|
||||
$this->format
|
||||
);
|
||||
@ -213,7 +196,11 @@ class ApiGroupCreateAction extends ApiAuthAction
|
||||
} elseif (User_group::descriptionTooLong($this->description)) {
|
||||
$this->clientError(
|
||||
sprintf(
|
||||
_('Description is too long (max %d chars).'),
|
||||
// TRANS: Client error shown when providing too long a description during group creation.
|
||||
// TRANS: %d is the maximum number of allowed characters.
|
||||
_m('Description is too long (maximum %d character).',
|
||||
'Description is too long (maximum %d characters).',
|
||||
User_group::maxDescription()),
|
||||
User_group::maxDescription()
|
||||
),
|
||||
403,
|
||||
@ -224,7 +211,8 @@ class ApiGroupCreateAction extends ApiAuthAction
|
||||
!is_null($this->location)
|
||||
&& mb_strlen($this->location) > 255) {
|
||||
$this->clientError(
|
||||
_('Location is too long (max 255 chars).'),
|
||||
// TRANS: Client error shown when providing too long a location during group creation.
|
||||
_('Location is too long (maximum 255 characters).'),
|
||||
403,
|
||||
$this->format
|
||||
);
|
||||
@ -243,7 +231,11 @@ class ApiGroupCreateAction extends ApiAuthAction
|
||||
if (count($this->aliases) > common_config('group', 'maxaliases')) {
|
||||
$this->clientError(
|
||||
sprintf(
|
||||
_('Too many aliases! Maximum %d.'),
|
||||
// TRANS: Client error shown when providing too many aliases during group creation.
|
||||
// TRANS: %d is the maximum number of allowed aliases.
|
||||
_m('Too many aliases! Maximum %d allowed.',
|
||||
'Too many aliases! Maximum %d allowed.',
|
||||
common_config('group', 'maxaliases')),
|
||||
common_config('group', 'maxaliases')
|
||||
),
|
||||
403,
|
||||
@ -254,16 +246,10 @@ class ApiGroupCreateAction extends ApiAuthAction
|
||||
|
||||
foreach ($this->aliases as $alias) {
|
||||
|
||||
$valid = Validate::string(
|
||||
$alias, array(
|
||||
'min_length' => 1,
|
||||
'max_length' => 64,
|
||||
'format' => NICKNAME_FMT
|
||||
)
|
||||
);
|
||||
|
||||
if (!$valid) {
|
||||
if (!Nickname::isValid($alias)) {
|
||||
$this->clientError(
|
||||
// TRANS: Client error shown when providing an invalid alias during group creation.
|
||||
// TRANS: %s is the invalid alias.
|
||||
sprintf(_('Invalid alias: "%s".'), $alias),
|
||||
403,
|
||||
$this->format
|
||||
@ -273,6 +259,8 @@ class ApiGroupCreateAction extends ApiAuthAction
|
||||
if ($this->groupNicknameExists($alias)) {
|
||||
$this->clientError(
|
||||
sprintf(
|
||||
// TRANS: Client error displayed when trying to use an alias during group creation that is already in use.
|
||||
// TRANS: %s is the alias that is already in use.
|
||||
_('Alias "%s" already in use. Try another one.'),
|
||||
$alias
|
||||
),
|
||||
@ -286,6 +274,7 @@ class ApiGroupCreateAction extends ApiAuthAction
|
||||
|
||||
if (strcmp($alias, $this->nickname) == 0) {
|
||||
$this->clientError(
|
||||
// TRANS: Client error displayed when trying to use an alias during group creation that is the same as the group's nickname.
|
||||
_('Alias can\'t be the same as nickname.'),
|
||||
403,
|
||||
$this->format
|
||||
@ -294,7 +283,7 @@ class ApiGroupCreateAction extends ApiAuthAction
|
||||
}
|
||||
}
|
||||
|
||||
// Evarything looks OK
|
||||
// Everything looks OK
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -306,7 +295,6 @@ class ApiGroupCreateAction extends ApiAuthAction
|
||||
*
|
||||
* @return boolean true or false
|
||||
*/
|
||||
|
||||
function groupNicknameExists($nickname)
|
||||
{
|
||||
$local = Local_group::staticGet('nickname', $nickname);
|
||||
@ -323,5 +311,4 @@ class ApiGroupCreateAction extends ApiAuthAction
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -49,7 +49,6 @@ require_once INSTALLDIR . '/lib/apibareauth.php';
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||
* @link http://status.net/
|
||||
*/
|
||||
|
||||
class ApiGroupIsMemberAction extends ApiBareAuthAction
|
||||
{
|
||||
var $group = null;
|
||||
@ -60,7 +59,6 @@ class ApiGroupIsMemberAction extends ApiBareAuthAction
|
||||
* @param array $args $_REQUEST args
|
||||
*
|
||||
* @return boolean success flag
|
||||
*
|
||||
*/
|
||||
|
||||
function prepare($args)
|
||||
@ -82,17 +80,18 @@ class ApiGroupIsMemberAction extends ApiBareAuthAction
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
|
||||
function handle($args)
|
||||
{
|
||||
parent::handle($args);
|
||||
|
||||
if (empty($this->user)) {
|
||||
// TRANS: Client error displayed when checking group membership for a non-existing user.
|
||||
$this->clientError(_('No such user.'), 404, $this->format);
|
||||
return;
|
||||
}
|
||||
|
||||
if (empty($this->group)) {
|
||||
// TRANS: Client error displayed when checking group membership for a non-existing group.
|
||||
$this->clientError(_('Group not found.'), 404, $this->format);
|
||||
return false;
|
||||
}
|
||||
@ -112,6 +111,7 @@ class ApiGroupIsMemberAction extends ApiBareAuthAction
|
||||
break;
|
||||
default:
|
||||
$this->clientError(
|
||||
// TRANS: Client error displayed trying to execute an unknown API method showing group membership.
|
||||
_('API method not found.'),
|
||||
400,
|
||||
$this->format
|
||||
@ -129,10 +129,8 @@ class ApiGroupIsMemberAction extends ApiBareAuthAction
|
||||
*
|
||||
* @return boolean is read only action?
|
||||
*/
|
||||
|
||||
function isReadOnly($args)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -49,7 +49,6 @@ require_once INSTALLDIR . '/lib/apiauth.php';
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||
* @link http://status.net/
|
||||
*/
|
||||
|
||||
class ApiGroupJoinAction extends ApiAuthAction
|
||||
{
|
||||
var $group = null;
|
||||
@ -60,9 +59,7 @@ class ApiGroupJoinAction extends ApiAuthAction
|
||||
* @param array $args $_REQUEST args
|
||||
*
|
||||
* @return boolean success flag
|
||||
*
|
||||
*/
|
||||
|
||||
function prepare($args)
|
||||
{
|
||||
parent::prepare($args);
|
||||
@ -82,13 +79,13 @@ class ApiGroupJoinAction extends ApiAuthAction
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
|
||||
function handle($args)
|
||||
{
|
||||
parent::handle($args);
|
||||
|
||||
if ($_SERVER['REQUEST_METHOD'] != 'POST') {
|
||||
$this->clientError(
|
||||
// TRANS: Client error. POST is a HTTP command. It should not be translated.
|
||||
_('This method requires a POST.'),
|
||||
400,
|
||||
$this->format
|
||||
@ -97,17 +94,20 @@ class ApiGroupJoinAction extends ApiAuthAction
|
||||
}
|
||||
|
||||
if (empty($this->user)) {
|
||||
// TRANS: Client error displayed when trying to have a non-existing user join a group.
|
||||
$this->clientError(_('No such user.'), 404, $this->format);
|
||||
return;
|
||||
}
|
||||
|
||||
if (empty($this->group)) {
|
||||
// TRANS: Client error displayed when trying to join a group that does not exist.
|
||||
$this->clientError(_('Group not found.'), 404, $this->format);
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($this->user->isMember($this->group)) {
|
||||
$this->clientError(
|
||||
// TRANS: Server error displayed when trying to join a group the user is already a member of.
|
||||
_('You are already a member of that group.'),
|
||||
403,
|
||||
$this->format
|
||||
@ -117,6 +117,7 @@ class ApiGroupJoinAction extends ApiAuthAction
|
||||
|
||||
if (Group_block::isBlocked($this->group, $this->user->getProfile())) {
|
||||
$this->clientError(
|
||||
// TRANS: Server error displayed when trying to join a group the user is blocked from joining.
|
||||
_('You have been blocked from that group by the admin.'),
|
||||
403,
|
||||
$this->format
|
||||
@ -136,6 +137,8 @@ class ApiGroupJoinAction extends ApiAuthAction
|
||||
common_log_db_error($member, 'INSERT', __FILE__);
|
||||
$this->serverError(
|
||||
sprintf(
|
||||
// TRANS: Server error displayed when joining a group fails.
|
||||
// TRANS: %1$s is a user nickname, $2$s is a group nickname.
|
||||
_('Could not join user %1$s to group %2$s.'),
|
||||
$this->user->nickname,
|
||||
$this->group->nickname
|
||||
@ -153,6 +156,7 @@ class ApiGroupJoinAction extends ApiAuthAction
|
||||
break;
|
||||
default:
|
||||
$this->clientError(
|
||||
// TRANS: Client error displayed trying to execute an unknown API method joining a group.
|
||||
_('API method not found.'),
|
||||
404,
|
||||
$this->format
|
||||
@ -160,5 +164,4 @@ class ApiGroupJoinAction extends ApiAuthAction
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -49,7 +49,6 @@ require_once INSTALLDIR . '/lib/apiauth.php';
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||
* @link http://status.net/
|
||||
*/
|
||||
|
||||
class ApiGroupLeaveAction extends ApiAuthAction
|
||||
{
|
||||
var $group = null;
|
||||
@ -60,9 +59,7 @@ class ApiGroupLeaveAction extends ApiAuthAction
|
||||
* @param array $args $_REQUEST args
|
||||
*
|
||||
* @return boolean success flag
|
||||
*
|
||||
*/
|
||||
|
||||
function prepare($args)
|
||||
{
|
||||
parent::prepare($args);
|
||||
@ -82,13 +79,13 @@ class ApiGroupLeaveAction extends ApiAuthAction
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
|
||||
function handle($args)
|
||||
{
|
||||
parent::handle($args);
|
||||
|
||||
if ($_SERVER['REQUEST_METHOD'] != 'POST') {
|
||||
$this->clientError(
|
||||
// TRANS: Client error. POST is a HTTP command. It should not be translated.
|
||||
_('This method requires a POST.'),
|
||||
400,
|
||||
$this->format
|
||||
@ -97,11 +94,13 @@ class ApiGroupLeaveAction extends ApiAuthAction
|
||||
}
|
||||
|
||||
if (empty($this->user)) {
|
||||
// TRANS: Client error displayed when trying to have a non-existing user leave a group.
|
||||
$this->clientError(_('No such user.'), 404, $this->format);
|
||||
return;
|
||||
}
|
||||
|
||||
if (empty($this->group)) {
|
||||
// TRANS: Client error displayed when trying to leave a group that does not exist.
|
||||
$this->clientError(_('Group not found.'), 404, $this->format);
|
||||
return false;
|
||||
}
|
||||
@ -112,6 +111,7 @@ class ApiGroupLeaveAction extends ApiAuthAction
|
||||
$member->profile_id = $this->auth_user->id;
|
||||
|
||||
if (!$member->find(true)) {
|
||||
// TRANS: Server error displayed when trying to leave a group the user is not a member of.
|
||||
$this->serverError(_('You are not a member of this group.'));
|
||||
return;
|
||||
}
|
||||
@ -122,6 +122,8 @@ class ApiGroupLeaveAction extends ApiAuthAction
|
||||
common_log_db_error($member, 'DELETE', __FILE__);
|
||||
$this->serverError(
|
||||
sprintf(
|
||||
// TRANS: Server error displayed when leaving a group fails.
|
||||
// TRANS: %1$s is a user nickname, $2$s is a group nickname.
|
||||
_('Could not remove user %1$s from group %2$s.'),
|
||||
$this->user->nickname,
|
||||
$this->group->nickname
|
||||
@ -139,6 +141,7 @@ class ApiGroupLeaveAction extends ApiAuthAction
|
||||
break;
|
||||
default:
|
||||
$this->clientError(
|
||||
// TRANS: Client error displayed trying to execute an unknown API method leaving a group.
|
||||
_('API method not found.'),
|
||||
404,
|
||||
$this->format
|
||||
@ -146,5 +149,4 @@ class ApiGroupLeaveAction extends ApiAuthAction
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -49,7 +49,6 @@ require_once INSTALLDIR . '/lib/apibareauth.php';
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||
* @link http://status.net/
|
||||
*/
|
||||
|
||||
class ApiGroupListAction extends ApiBareAuthAction
|
||||
{
|
||||
var $groups = null;
|
||||
@ -60,9 +59,7 @@ class ApiGroupListAction extends ApiBareAuthAction
|
||||
* @param array $args $_REQUEST args
|
||||
*
|
||||
* @return boolean success flag
|
||||
*
|
||||
*/
|
||||
|
||||
function prepare($args)
|
||||
{
|
||||
parent::prepare($args);
|
||||
@ -88,13 +85,12 @@ class ApiGroupListAction extends ApiBareAuthAction
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
|
||||
function handle($args)
|
||||
{
|
||||
parent::handle($args);
|
||||
|
||||
$sitename = common_config('site', 'name');
|
||||
// TRANS: %s is a user name
|
||||
// TRANS: Used as title in check for group membership. %s is a user name.
|
||||
$title = sprintf(_("%s's groups"), $this->user->nickname);
|
||||
$taguribase = TagURI::base();
|
||||
$id = "tag:$taguribase:Groups";
|
||||
@ -104,8 +100,8 @@ class ApiGroupListAction extends ApiBareAuthAction
|
||||
);
|
||||
|
||||
$subtitle = sprintf(
|
||||
// TRANS: Meant to convey the user %2$s is a member of each of the groups listed on site %1$s
|
||||
_("%1\$s groups %2\$s is a member of."),
|
||||
// TRANS: Used as subtitle in check for group membership. %1$s is a user name, %2$s is the site name.
|
||||
_('%1$s groups %2$s is a member of.'),
|
||||
$sitename,
|
||||
$this->user->nickname
|
||||
);
|
||||
@ -134,13 +130,13 @@ class ApiGroupListAction extends ApiBareAuthAction
|
||||
break;
|
||||
default:
|
||||
$this->clientError(
|
||||
// TRANS: Client error displayed trying to execute an unknown API method checking group membership.
|
||||
_('API method not found.'),
|
||||
404,
|
||||
$this->format
|
||||
);
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@ -148,7 +144,6 @@ class ApiGroupListAction extends ApiBareAuthAction
|
||||
*
|
||||
* @return array groups
|
||||
*/
|
||||
|
||||
function getGroups()
|
||||
{
|
||||
$groups = array();
|
||||
@ -174,7 +169,6 @@ class ApiGroupListAction extends ApiBareAuthAction
|
||||
*
|
||||
* @return boolean true
|
||||
*/
|
||||
|
||||
function isReadOnly($args)
|
||||
{
|
||||
return true;
|
||||
@ -203,7 +197,6 @@ class ApiGroupListAction extends ApiBareAuthAction
|
||||
*
|
||||
* @return string etag
|
||||
*/
|
||||
|
||||
function etag()
|
||||
{
|
||||
if (!empty($this->groups) && (count($this->groups) > 0)) {
|
||||
@ -213,6 +206,7 @@ class ApiGroupListAction extends ApiBareAuthAction
|
||||
return '"' . implode(
|
||||
':',
|
||||
array($this->arg('action'),
|
||||
common_user_cache_hash($this->auth_user),
|
||||
common_language(),
|
||||
$this->user->id,
|
||||
strtotime($this->groups[0]->created),
|
||||
@ -223,5 +217,4 @@ class ApiGroupListAction extends ApiBareAuthAction
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -49,7 +49,6 @@ require_once INSTALLDIR . '/lib/apiprivateauth.php';
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||
* @link http://status.net/
|
||||
*/
|
||||
|
||||
class ApiGroupListAllAction extends ApiPrivateAuthAction
|
||||
{
|
||||
var $groups = null;
|
||||
@ -60,9 +59,7 @@ class ApiGroupListAllAction extends ApiPrivateAuthAction
|
||||
* @param array $args $_REQUEST args
|
||||
*
|
||||
* @return boolean success flag
|
||||
*
|
||||
*/
|
||||
|
||||
function prepare($args)
|
||||
{
|
||||
parent::prepare($args);
|
||||
@ -82,17 +79,17 @@ class ApiGroupListAllAction extends ApiPrivateAuthAction
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
|
||||
function handle($args)
|
||||
{
|
||||
parent::handle($args);
|
||||
|
||||
$sitename = common_config('site', 'name');
|
||||
// TRANS: Message is used as a title. %s is a site name.
|
||||
// TRANS: Message is used as a title when listing the lastest 20 groups. %s is a site name.
|
||||
$title = sprintf(_("%s groups"), $sitename);
|
||||
$taguribase = TagURI::base();
|
||||
$id = "tag:$taguribase:Groups";
|
||||
$link = common_local_url('groups');
|
||||
// TRANS: Message is used as a subtitle when listing the lastest 20 groups. %s is a site name.
|
||||
$subtitle = sprintf(_("groups on %s"), $sitename);
|
||||
|
||||
switch($this->format) {
|
||||
@ -119,13 +116,13 @@ class ApiGroupListAllAction extends ApiPrivateAuthAction
|
||||
break;
|
||||
default:
|
||||
$this->clientError(
|
||||
// TRANS: Client error displayed trying to execute an unknown API method listing the latest 20 groups.
|
||||
_('API method not found.'),
|
||||
404,
|
||||
$this->format
|
||||
);
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@ -133,7 +130,6 @@ class ApiGroupListAllAction extends ApiPrivateAuthAction
|
||||
*
|
||||
* @return array groups
|
||||
*/
|
||||
|
||||
function getGroups()
|
||||
{
|
||||
$qry = 'SELECT user_group.* '.
|
||||
@ -165,7 +161,6 @@ class ApiGroupListAllAction extends ApiPrivateAuthAction
|
||||
*
|
||||
* @return boolean true
|
||||
*/
|
||||
|
||||
function isReadOnly($args)
|
||||
{
|
||||
return true;
|
||||
@ -176,7 +171,6 @@ class ApiGroupListAllAction extends ApiPrivateAuthAction
|
||||
*
|
||||
* @return string datestamp of the site's latest group
|
||||
*/
|
||||
|
||||
function lastModified()
|
||||
{
|
||||
if (!empty($this->groups) && (count($this->groups) > 0)) {
|
||||
@ -194,7 +188,6 @@ class ApiGroupListAllAction extends ApiPrivateAuthAction
|
||||
*
|
||||
* @return string etag
|
||||
*/
|
||||
|
||||
function etag()
|
||||
{
|
||||
if (!empty($this->groups) && (count($this->groups) > 0)) {
|
||||
@ -204,6 +197,7 @@ class ApiGroupListAllAction extends ApiPrivateAuthAction
|
||||
return '"' . implode(
|
||||
':',
|
||||
array($this->arg('action'),
|
||||
common_user_cache_hash($this->auth_user),
|
||||
common_language(),
|
||||
strtotime($this->groups[0]->created),
|
||||
strtotime($this->groups[$last]->created))
|
||||
@ -213,5 +207,4 @@ class ApiGroupListAllAction extends ApiPrivateAuthAction
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -49,7 +49,6 @@ require_once INSTALLDIR . '/lib/apiprivateauth.php';
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||
* @link http://status.net/
|
||||
*/
|
||||
|
||||
class ApiGroupMembershipAction extends ApiPrivateAuthAction
|
||||
{
|
||||
var $group = null;
|
||||
@ -61,9 +60,7 @@ class ApiGroupMembershipAction extends ApiPrivateAuthAction
|
||||
* @param array $args $_REQUEST args
|
||||
*
|
||||
* @return boolean success flag
|
||||
*
|
||||
*/
|
||||
|
||||
function prepare($args)
|
||||
{
|
||||
parent::prepare($args);
|
||||
@ -83,12 +80,12 @@ class ApiGroupMembershipAction extends ApiPrivateAuthAction
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
|
||||
function handle($args)
|
||||
{
|
||||
parent::handle($args);
|
||||
|
||||
if (empty($this->group)) {
|
||||
// TRANS: Client error displayed trying to show group membership on a non-existing group.
|
||||
$this->clientError(_('Group not found.'), 404, $this->format);
|
||||
return false;
|
||||
}
|
||||
@ -104,6 +101,7 @@ class ApiGroupMembershipAction extends ApiPrivateAuthAction
|
||||
break;
|
||||
default:
|
||||
$this->clientError(
|
||||
// TRANS: Client error displayed trying to execute an unknown API method showing group membership.
|
||||
_('API method not found.'),
|
||||
404,
|
||||
$this->format
|
||||
@ -117,7 +115,6 @@ class ApiGroupMembershipAction extends ApiPrivateAuthAction
|
||||
*
|
||||
* @return array $profiles list of profiles
|
||||
*/
|
||||
|
||||
function getProfiles()
|
||||
{
|
||||
$profiles = array();
|
||||
@ -143,7 +140,6 @@ class ApiGroupMembershipAction extends ApiPrivateAuthAction
|
||||
*
|
||||
* @return boolean true
|
||||
*/
|
||||
|
||||
function isReadOnly($args)
|
||||
{
|
||||
return true;
|
||||
@ -154,7 +150,6 @@ class ApiGroupMembershipAction extends ApiPrivateAuthAction
|
||||
*
|
||||
* @return string datestamp of the lastest profile in the group
|
||||
*/
|
||||
|
||||
function lastModified()
|
||||
{
|
||||
if (!empty($this->profiles) && (count($this->profiles) > 0)) {
|
||||
@ -173,7 +168,6 @@ class ApiGroupMembershipAction extends ApiPrivateAuthAction
|
||||
*
|
||||
* @return string etag
|
||||
*/
|
||||
|
||||
function etag()
|
||||
{
|
||||
if (!empty($this->profiles) && (count($this->profiles) > 0)) {
|
||||
@ -183,6 +177,7 @@ class ApiGroupMembershipAction extends ApiPrivateAuthAction
|
||||
return '"' . implode(
|
||||
':',
|
||||
array($this->arg('action'),
|
||||
common_user_cache_hash($this->auth_user),
|
||||
common_language(),
|
||||
$this->group->id,
|
||||
strtotime($this->profiles[0]->created),
|
||||
@ -193,5 +188,4 @@ class ApiGroupMembershipAction extends ApiPrivateAuthAction
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -50,7 +50,6 @@ require_once INSTALLDIR . '/lib/apiprivateauth.php';
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||
* @link http://status.net/
|
||||
*/
|
||||
|
||||
class ApiGroupShowAction extends ApiPrivateAuthAction
|
||||
{
|
||||
var $group = null;
|
||||
@ -61,9 +60,7 @@ class ApiGroupShowAction extends ApiPrivateAuthAction
|
||||
* @param array $args $_REQUEST args
|
||||
*
|
||||
* @return boolean success flag
|
||||
*
|
||||
*/
|
||||
|
||||
function prepare($args)
|
||||
{
|
||||
parent::prepare($args);
|
||||
@ -80,6 +77,7 @@ class ApiGroupShowAction extends ApiPrivateAuthAction
|
||||
common_redirect(common_local_url('ApiGroupShow', $args), 301);
|
||||
} else {
|
||||
$this->clientError(
|
||||
// TRANS: Client error displayed when trying to show a group that could not be found.
|
||||
_('Group not found.'),
|
||||
404,
|
||||
$this->format
|
||||
@ -100,7 +98,6 @@ class ApiGroupShowAction extends ApiPrivateAuthAction
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
|
||||
function handle($args)
|
||||
{
|
||||
parent::handle($args);
|
||||
@ -113,6 +110,7 @@ class ApiGroupShowAction extends ApiPrivateAuthAction
|
||||
$this->showSingleJsonGroup($this->group);
|
||||
break;
|
||||
default:
|
||||
// TRANS: Client error displayed trying to execute an unknown API method showing a group.
|
||||
$this->clientError(_('API method not found.'), 404, $this->format);
|
||||
break;
|
||||
}
|
||||
@ -123,7 +121,6 @@ class ApiGroupShowAction extends ApiPrivateAuthAction
|
||||
*
|
||||
* @return string datestamp of the latest notice in the stream
|
||||
*/
|
||||
|
||||
function lastModified()
|
||||
{
|
||||
if (!empty($this->group)) {
|
||||
@ -141,7 +138,6 @@ class ApiGroupShowAction extends ApiPrivateAuthAction
|
||||
*
|
||||
* @return string etag
|
||||
*/
|
||||
|
||||
function etag()
|
||||
{
|
||||
if (!empty($this->group)) {
|
||||
@ -149,6 +145,7 @@ class ApiGroupShowAction extends ApiPrivateAuthAction
|
||||
return '"' . implode(
|
||||
':',
|
||||
array($this->arg('action'),
|
||||
common_user_cache_hash($this->auth_user),
|
||||
common_language(),
|
||||
$this->group->id,
|
||||
strtotime($this->group->modified))
|
||||
@ -168,10 +165,8 @@ class ApiGroupShowAction extends ApiPrivateAuthAction
|
||||
*
|
||||
* @return boolean is read only action?
|
||||
*/
|
||||
|
||||
function isReadOnly($args)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -44,19 +44,15 @@ require_once INSTALLDIR . '/lib/apiprivateauth.php';
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||
* @link http://status.net/
|
||||
*/
|
||||
|
||||
class ApiHelpTestAction extends ApiPrivateAuthAction
|
||||
{
|
||||
|
||||
/**
|
||||
* Take arguments for running
|
||||
*
|
||||
* @param array $args $_REQUEST args
|
||||
*
|
||||
* @return boolean success flag
|
||||
*
|
||||
*/
|
||||
|
||||
function prepare($args)
|
||||
{
|
||||
parent::prepare($args);
|
||||
@ -70,7 +66,6 @@ class ApiHelpTestAction extends ApiPrivateAuthAction
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
|
||||
function handle($args)
|
||||
{
|
||||
parent::handle($args);
|
||||
@ -85,6 +80,7 @@ class ApiHelpTestAction extends ApiPrivateAuthAction
|
||||
$this->endDocument('json');
|
||||
} else {
|
||||
$this->clientError(
|
||||
// TRANS: Client error displayed trying to execute an unknown API method testing API connectivity.
|
||||
_('API method not found.'),
|
||||
404,
|
||||
$this->format
|
||||
@ -101,11 +97,8 @@ class ApiHelpTestAction extends ApiPrivateAuthAction
|
||||
*
|
||||
* @return boolean is read only action?
|
||||
*/
|
||||
|
||||
function isReadOnly($args)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
@ -43,7 +43,6 @@ require_once INSTALLDIR . '/lib/mediafile.php';
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||
* @link http://status.net/
|
||||
*/
|
||||
|
||||
class ApiMediaUploadAction extends ApiAuthAction
|
||||
{
|
||||
/**
|
||||
@ -57,13 +56,13 @@ class ApiMediaUploadAction extends ApiAuthAction
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
|
||||
function handle($args)
|
||||
{
|
||||
parent::handle($args);
|
||||
|
||||
if ($_SERVER['REQUEST_METHOD'] != 'POST') {
|
||||
$this->clientError(
|
||||
// TRANS: Client error. POST is a HTTP command. It should not be translated.
|
||||
_('This method requires a POST.'),
|
||||
400, $this->format
|
||||
);
|
||||
@ -77,9 +76,11 @@ class ApiMediaUploadAction extends ApiAuthAction
|
||||
&& empty($_POST)
|
||||
&& ($_SERVER['CONTENT_LENGTH'] > 0)
|
||||
) {
|
||||
$msg = _('The server was unable to handle that much POST ' .
|
||||
'data (%s bytes) due to its current configuration.');
|
||||
|
||||
// TRANS: Client error displayed when the number of bytes in a POST request exceeds a limit.
|
||||
// TRANS: %s is the number of bytes of the CONTENT_LENGTH.
|
||||
$msg = _m('The server was unable to handle that much POST data (%s byte) due to its current configuration.',
|
||||
'The server was unable to handle that much POST data (%s bytes) due to its current configuration.',
|
||||
intval($_SERVER['CONTENT_LENGTH']));
|
||||
$this->clientError(sprintf($msg, $_SERVER['CONTENT_LENGTH']));
|
||||
return;
|
||||
}
|
||||
@ -96,6 +97,7 @@ class ApiMediaUploadAction extends ApiAuthAction
|
||||
if (isset($upload)) {
|
||||
$this->showResponse($upload);
|
||||
} else {
|
||||
// TRANS: Client error displayed when uploading a media file has failed.
|
||||
$this->clientError(_('Upload failed.'));
|
||||
return;
|
||||
}
|
||||
@ -123,7 +125,6 @@ class ApiMediaUploadAction extends ApiAuthAction
|
||||
* Overrided clientError to show a more Twitpic-like error
|
||||
*
|
||||
* @param String $msg an error message
|
||||
*
|
||||
*/
|
||||
function clientError($msg)
|
||||
{
|
||||
@ -137,5 +138,4 @@ class ApiMediaUploadAction extends ApiAuthAction
|
||||
$this->elementEnd('rsp');
|
||||
$this->endDocument();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -2,7 +2,8 @@
|
||||
/**
|
||||
* StatusNet, the distributed open-source microblogging tool
|
||||
*
|
||||
* Exchange an authorized OAuth request token for an access token
|
||||
* Action for getting OAuth token credentials (exchange an authorized
|
||||
* request token for an access token)
|
||||
*
|
||||
* PHP version 5
|
||||
*
|
||||
@ -34,7 +35,8 @@ if (!defined('STATUSNET')) {
|
||||
require_once INSTALLDIR . '/lib/apioauth.php';
|
||||
|
||||
/**
|
||||
* Exchange an authorized OAuth request token for an access token
|
||||
* Action for getting OAuth token credentials (exchange an authorized
|
||||
* request token for an access token)
|
||||
*
|
||||
* @category API
|
||||
* @package StatusNet
|
||||
@ -42,9 +44,10 @@ require_once INSTALLDIR . '/lib/apioauth.php';
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||
* @link http://status.net/
|
||||
*/
|
||||
|
||||
class ApiOauthAccessTokenAction extends ApiOauthAction
|
||||
{
|
||||
protected $reqToken = null;
|
||||
protected $verifier = null;
|
||||
|
||||
/**
|
||||
* Class handler.
|
||||
@ -63,32 +66,61 @@ class ApiOauthAccessTokenAction extends ApiOauthAction
|
||||
|
||||
$server->add_signature_method($hmac_method);
|
||||
|
||||
$atok = null;
|
||||
$atok = $app = null;
|
||||
|
||||
// XXX: Insist that oauth_token and oauth_verifier be populated?
|
||||
// Spec doesn't say they MUST be.
|
||||
|
||||
try {
|
||||
$req = OAuthRequest::from_request();
|
||||
$atok = $server->fetch_access_token($req);
|
||||
|
||||
} catch (OAuthException $e) {
|
||||
$this->reqToken = $req->get_parameter('oauth_token');
|
||||
$this->verifier = $req->get_parameter('oauth_verifier');
|
||||
|
||||
$app = $datastore->getAppByRequestToken($this->reqToken);
|
||||
$atok = $server->fetch_access_token($req);
|
||||
} catch (Exception $e) {
|
||||
common_log(LOG_WARNING, 'API OAuthException - ' . $e->getMessage());
|
||||
common_debug(var_export($req, true));
|
||||
$this->outputError($e->getMessage());
|
||||
return;
|
||||
$code = $e->getCode();
|
||||
$this->clientError($e->getMessage(), empty($code) ? 401 : $code, 'text');
|
||||
}
|
||||
|
||||
if (empty($atok)) {
|
||||
common_debug('couldn\'t get access token.');
|
||||
print "Token exchange failed. Has the request token been authorized?\n";
|
||||
// Token exchange failed -- log it
|
||||
|
||||
$msg = sprintf(
|
||||
'API OAuth - Failure exchanging OAuth request token for access token, '
|
||||
. 'request token = %s, verifier = %s',
|
||||
$this->reqToken,
|
||||
$this->verifier
|
||||
);
|
||||
|
||||
common_log(LOG_WARNING, $msg);
|
||||
// TRANS: Client error given from the OAuth API when the request token or verifier is invalid.
|
||||
$this->clientError(_("Invalid request token or verifier.", 400, 'text'));
|
||||
} else {
|
||||
print $atok;
|
||||
common_log(
|
||||
LOG_INFO,
|
||||
sprintf(
|
||||
"Issued access token '%s' for application %d (%s).",
|
||||
$atok->key,
|
||||
$app->id,
|
||||
$app->name
|
||||
)
|
||||
);
|
||||
$this->showAccessToken($atok);
|
||||
}
|
||||
}
|
||||
|
||||
function outputError($msg)
|
||||
/*
|
||||
* Display OAuth token credentials
|
||||
*
|
||||
* @param OAuthToken token the access token
|
||||
*/
|
||||
function showAccessToken($token)
|
||||
{
|
||||
header('HTTP/1.1 401 Unauthorized');
|
||||
header('Content-Type: text/html; charset=utf-8');
|
||||
print $msg . "\n";
|
||||
header('Content-Type: application/x-www-form-urlencoded');
|
||||
print $token;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -32,9 +32,10 @@ if (!defined('STATUSNET')) {
|
||||
}
|
||||
|
||||
require_once INSTALLDIR . '/lib/apioauth.php';
|
||||
require_once INSTALLDIR . '/lib/info.php';
|
||||
|
||||
/**
|
||||
* Authorize an OAuth request token
|
||||
* Authorize an Oputh request token
|
||||
*
|
||||
* @category API
|
||||
* @package StatusNet
|
||||
@ -42,10 +43,10 @@ require_once INSTALLDIR . '/lib/apioauth.php';
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||
* @link http://status.net/
|
||||
*/
|
||||
|
||||
class ApiOauthAuthorizeAction extends ApiOauthAction
|
||||
class ApiOauthAuthorizeAction extends Action
|
||||
{
|
||||
var $oauth_token;
|
||||
var $oauthTokenParam;
|
||||
var $reqToken;
|
||||
var $callback;
|
||||
var $app;
|
||||
var $nickname;
|
||||
@ -57,7 +58,6 @@ class ApiOauthAuthorizeAction extends ApiOauthAction
|
||||
*
|
||||
* @return boolean false
|
||||
*/
|
||||
|
||||
function isReadOnly($args)
|
||||
{
|
||||
return false;
|
||||
@ -67,12 +67,17 @@ class ApiOauthAuthorizeAction extends ApiOauthAction
|
||||
{
|
||||
parent::prepare($args);
|
||||
|
||||
$this->nickname = $this->trimmed('nickname');
|
||||
$this->password = $this->arg('password');
|
||||
$this->oauth_token = $this->arg('oauth_token');
|
||||
$this->callback = $this->arg('oauth_callback');
|
||||
$this->store = new ApiStatusNetOAuthDataStore();
|
||||
$this->app = $this->store->getAppByRequestToken($this->oauth_token);
|
||||
$this->nickname = $this->trimmed('nickname');
|
||||
$this->password = $this->arg('password');
|
||||
$this->oauthTokenParam = $this->arg('oauth_token');
|
||||
$this->mode = $this->arg('mode');
|
||||
$this->store = new ApiStatusNetOAuthDataStore();
|
||||
|
||||
try {
|
||||
$this->app = $this->store->getAppByRequestToken($this->oauthTokenParam);
|
||||
} catch (Exception $e) {
|
||||
$this->clientError($e->getMessage());
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -86,7 +91,6 @@ class ApiOauthAuthorizeAction extends ApiOauthAction
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
|
||||
function handle($args)
|
||||
{
|
||||
parent::handle($args);
|
||||
@ -97,14 +101,32 @@ class ApiOauthAuthorizeAction extends ApiOauthAction
|
||||
|
||||
} else {
|
||||
|
||||
if (empty($this->oauth_token)) {
|
||||
// Make sure a oauth_token parameter was provided
|
||||
if (empty($this->oauthTokenParam)) {
|
||||
// TRANS: Client error given when no oauth_token was passed to the OAuth API.
|
||||
$this->clientError(_('No oauth_token parameter provided.'));
|
||||
return;
|
||||
} else {
|
||||
|
||||
// Check to make sure the token exists
|
||||
$this->reqToken = $this->store->getTokenByKey($this->oauthTokenParam);
|
||||
|
||||
if (empty($this->reqToken)) {
|
||||
// TRANS: Client error given when an invalid request token was passed to the OAuth API.
|
||||
$this->clientError(_('Invalid request token.'));
|
||||
} else {
|
||||
|
||||
// Check to make sure we haven't already authorized the token
|
||||
if ($this->reqToken->state != 0) {
|
||||
// TRANS: Client error given when an invalid request token was passed to the OAuth API.
|
||||
$this->clientError(_('Request token already authorized.'));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// make sure there's an app associated with this token
|
||||
if (empty($this->app)) {
|
||||
$this->clientError(_('Invalid token.'));
|
||||
return;
|
||||
// TRANS: Client error given when an invalid request token was passed to the OAuth API.
|
||||
$this->clientError(_('Invalid request token.'));
|
||||
}
|
||||
|
||||
$name = $this->app->name;
|
||||
@ -120,8 +142,9 @@ class ApiOauthAuthorizeAction extends ApiOauthAction
|
||||
$token = $this->trimmed('token');
|
||||
|
||||
if (!$token || $token != common_session_token()) {
|
||||
$this->showForm(_('There was a problem with your session token. '.
|
||||
'Try again, please.'));
|
||||
$this->showForm(
|
||||
// TRANS: Form validation error in API OAuth authorisation because of an invalid session token.
|
||||
_('There was a problem with your session token. Try again, please.'));
|
||||
return;
|
||||
}
|
||||
|
||||
@ -130,8 +153,18 @@ class ApiOauthAuthorizeAction extends ApiOauthAction
|
||||
$user = null;
|
||||
|
||||
if (!common_logged_in()) {
|
||||
$user = common_check_user($this->nickname, $this->password);
|
||||
|
||||
// XXX Force credentials check?
|
||||
|
||||
// @fixme this should probably use a unified login form handler
|
||||
$user = null;
|
||||
if (Event::handle('StartOAuthLoginCheck', array($this, &$user))) {
|
||||
$user = common_check_user($this->nickname, $this->password);
|
||||
}
|
||||
Event::handle('EndOAuthLoginCheck', array($this, &$user));
|
||||
|
||||
if (empty($user)) {
|
||||
// TRANS: Form validation error given when an invalid username and/or password was passed to the OAuth API.
|
||||
$this->showForm(_("Invalid nickname / password!"));
|
||||
return;
|
||||
}
|
||||
@ -139,101 +172,196 @@ class ApiOauthAuthorizeAction extends ApiOauthAction
|
||||
$user = common_current_user();
|
||||
}
|
||||
|
||||
// fetch the token
|
||||
$this->reqToken = $this->store->getTokenByKey($this->oauthTokenParam);
|
||||
assert(!empty($this->reqToken));
|
||||
|
||||
if ($this->arg('allow')) {
|
||||
|
||||
// mark the req token as authorized
|
||||
|
||||
$this->store->authorize_token($this->oauth_token);
|
||||
|
||||
// Check to see if there was a previous token associated
|
||||
// with this user/app and kill it. If the user is doing this she
|
||||
// probably doesn't want any old tokens anyway.
|
||||
|
||||
$appUser = Oauth_application_user::getByKeys($user, $this->app);
|
||||
|
||||
if (!empty($appUser)) {
|
||||
$result = $appUser->delete();
|
||||
|
||||
if (!$result) {
|
||||
common_log_db_error($appUser, 'DELETE', __FILE__);
|
||||
throw new ServerException(_('Database error deleting OAuth application user.'));
|
||||
return;
|
||||
}
|
||||
try {
|
||||
$this->store->authorize_token($this->oauthTokenParam);
|
||||
} catch (Exception $e) {
|
||||
$this->serverError($e->getMessage());
|
||||
}
|
||||
|
||||
// associated the authorized req token with the user and the app
|
||||
common_log(
|
||||
LOG_INFO,
|
||||
sprintf(
|
||||
"API OAuth - User %d (%s) has authorized request token %s for OAuth application %d (%s).",
|
||||
$user->id,
|
||||
$user->nickname,
|
||||
$this->reqToken->tok,
|
||||
$this->app->id,
|
||||
$this->app->name
|
||||
)
|
||||
);
|
||||
|
||||
$appUser = new Oauth_application_user();
|
||||
// XXX: Make sure we have a oauth_token_association table. The table
|
||||
// is now in the main schema, but because it is being added with
|
||||
// a point release, it's unlikely to be there. This code can be
|
||||
// removed as of 1.0.
|
||||
$this->ensureOauthTokenAssociationTable();
|
||||
|
||||
$appUser->profile_id = $user->id;
|
||||
$appUser->application_id = $this->app->id;
|
||||
$tokenAssoc = new Oauth_token_association();
|
||||
|
||||
// Note: do not copy the access type from the application.
|
||||
// The access type should always be 0 when the OAuth app
|
||||
// user record has a request token associated with it.
|
||||
// Access type gets assigned once an access token has been
|
||||
// granted. The OAuth app user record then gets updated
|
||||
// with the new access token and access type.
|
||||
$tokenAssoc->profile_id = $user->id;
|
||||
$tokenAssoc->application_id = $this->app->id;
|
||||
$tokenAssoc->token = $this->oauthTokenParam;
|
||||
$tokenAssoc->created = common_sql_now();
|
||||
|
||||
$appUser->token = $this->oauth_token;
|
||||
$appUser->created = common_sql_now();
|
||||
|
||||
$result = $appUser->insert();
|
||||
$result = $tokenAssoc->insert();
|
||||
|
||||
if (!$result) {
|
||||
common_log_db_error($appUser, 'INSERT', __FILE__);
|
||||
throw new ServerException(_('Database error inserting OAuth application user.'));
|
||||
return;
|
||||
common_log_db_error($tokenAssoc, 'INSERT', __FILE__);
|
||||
// TRANS: Server error displayed when a database action fails.
|
||||
$this->serverError(_('Database error inserting oauth_token_association.'));
|
||||
}
|
||||
|
||||
// if we have a callback redirect and provide the token
|
||||
$callback = $this->getCallback();
|
||||
|
||||
// A callback specified in the app setup overrides whatever
|
||||
// is passed in with the request.
|
||||
if (!empty($callback) && $this->reqToken->verified_callback != 'oob') {
|
||||
$targetUrl = $this->buildCallbackUrl(
|
||||
$callback,
|
||||
array(
|
||||
'oauth_token' => $this->oauthTokenParam,
|
||||
'oauth_verifier' => $this->reqToken->verifier // 1.0a
|
||||
)
|
||||
);
|
||||
|
||||
if (!empty($this->app->callback_url)) {
|
||||
$this->callback = $this->app->callback_url;
|
||||
common_log(LOG_INFO, "Redirecting to callback: $targetUrl");
|
||||
|
||||
// Redirect the user to the provided OAuth callback
|
||||
common_redirect($targetUrl, 303);
|
||||
|
||||
} elseif ($this->app->type == 2) {
|
||||
// Strangely, a web application seems to want to do the OOB
|
||||
// workflow. Because no callback was specified anywhere.
|
||||
common_log(
|
||||
LOG_WARNING,
|
||||
sprintf(
|
||||
"API OAuth - No callback provided for OAuth web client ID %s (%s) "
|
||||
. "during authorization step. Falling back to OOB workflow.",
|
||||
$this->app->id,
|
||||
$this->app->name
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
if (!empty($this->callback)) {
|
||||
// Otherwise, inform the user that the rt was authorized
|
||||
$this->showAuthorized();
|
||||
} else if ($this->arg('cancel')) {
|
||||
common_log(
|
||||
LOG_INFO,
|
||||
sprintf(
|
||||
"API OAuth - User %d (%s) refused to authorize request token %s for OAuth application %d (%s).",
|
||||
$user->id,
|
||||
$user->nickname,
|
||||
$this->reqToken->tok,
|
||||
$this->app->id,
|
||||
$this->app->name
|
||||
)
|
||||
);
|
||||
|
||||
$target_url = $this->getCallback($this->callback,
|
||||
array('oauth_token' => $this->oauth_token));
|
||||
|
||||
common_redirect($target_url, 303);
|
||||
} else {
|
||||
common_debug("callback was empty!");
|
||||
try {
|
||||
$this->store->revoke_token($this->oauthTokenParam, 0);
|
||||
} catch (Exception $e) {
|
||||
$this->ServerError($e->getMessage());
|
||||
}
|
||||
|
||||
// otherwise inform the user that the rt was authorized
|
||||
$callback = $this->getCallback();
|
||||
|
||||
$this->elementStart('p');
|
||||
// If there's a callback available, inform the consumer the user
|
||||
// has refused authorization
|
||||
if (!empty($callback) && $this->reqToken->verified_callback != 'oob') {
|
||||
$targetUrl = $this->buildCallbackUrl(
|
||||
$callback,
|
||||
array(
|
||||
'oauth_problem' => 'user_refused',
|
||||
)
|
||||
);
|
||||
|
||||
// XXX: Do OAuth 1.0a verifier code
|
||||
common_log(LOG_INFO, "Redirecting to callback: $targetUrl");
|
||||
|
||||
$this->raw(sprintf(_("The request token %s has been authorized. " .
|
||||
'Please exchange it for an access token.'),
|
||||
$this->oauth_token));
|
||||
// Redirect the user to the provided OAuth callback
|
||||
common_redirect($targetUrl, 303);
|
||||
}
|
||||
|
||||
$this->elementEnd('p');
|
||||
// otherwise inform the user that authorization for the rt was declined
|
||||
$this->showCanceled();
|
||||
|
||||
} else if ($this->arg('deny')) {
|
||||
|
||||
$datastore = new ApiStatusNetOAuthDataStore();
|
||||
$datastore->revoke_token($this->oauth_token, 0);
|
||||
|
||||
$this->elementStart('p');
|
||||
|
||||
$this->raw(sprintf(_("The request token %s has been denied and revoked."),
|
||||
$this->oauth_token));
|
||||
|
||||
$this->elementEnd('p');
|
||||
} else {
|
||||
// TRANS: Client error given on when invalid data was passed through a form in the OAuth API.
|
||||
$this->clientError(_('Unexpected form submission.'));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// XXX Remove this function when we hit 1.0
|
||||
function ensureOauthTokenAssociationTable()
|
||||
{
|
||||
$schema = Schema::get();
|
||||
|
||||
$reqTokenCols = array(
|
||||
new ColumnDef('profile_id', 'integer', null, true, 'PRI'),
|
||||
new ColumnDef('application_id', 'integer', null, true, 'PRI'),
|
||||
new ColumnDef('token', 'varchar', 255, true, 'PRI'),
|
||||
new ColumnDef('created', 'datetime', null, false),
|
||||
new ColumnDef(
|
||||
'modified',
|
||||
'timestamp',
|
||||
null,
|
||||
false,
|
||||
null,
|
||||
'CURRENT_TIMESTAMP',
|
||||
'on update CURRENT_TIMESTAMP'
|
||||
)
|
||||
);
|
||||
|
||||
$schema->ensureTable('oauth_token_association', $reqTokenCols);
|
||||
}
|
||||
|
||||
/**
|
||||
* Show body - override to add a special CSS class for the authorize
|
||||
* page's "desktop mode" (minimal display)
|
||||
*
|
||||
* Calls template methods
|
||||
*
|
||||
* @return nothing
|
||||
*/
|
||||
function showBody()
|
||||
{
|
||||
$bodyClasses = array();
|
||||
|
||||
if ($this->desktopMode()) {
|
||||
$bodyClasses[] = 'oauth-desktop-mode';
|
||||
}
|
||||
|
||||
if (common_current_user()) {
|
||||
$bodyClasses[] = 'user_in';
|
||||
}
|
||||
|
||||
$attrs = array('id' => strtolower($this->trimmed('action')));
|
||||
|
||||
if (!empty($bodyClasses)) {
|
||||
$attrs['class'] = implode(' ', $bodyClasses);
|
||||
}
|
||||
|
||||
$this->elementStart('body', $attrs);
|
||||
|
||||
$this->elementStart('div', array('id' => 'wrap'));
|
||||
if (Event::handle('StartShowHeader', array($this))) {
|
||||
$this->showHeader();
|
||||
Event::handle('EndShowHeader', array($this));
|
||||
}
|
||||
$this->showCore();
|
||||
if (Event::handle('StartShowFooter', array($this))) {
|
||||
$this->showFooter();
|
||||
Event::handle('EndShowFooter', array($this));
|
||||
}
|
||||
$this->elementEnd('div');
|
||||
$this->showScripts();
|
||||
$this->elementEnd('body');
|
||||
}
|
||||
|
||||
function showForm($error=null)
|
||||
{
|
||||
$this->error = $error;
|
||||
@ -253,9 +381,9 @@ class ApiOauthAuthorizeAction extends ApiOauthAction
|
||||
*
|
||||
* @return string title of the page
|
||||
*/
|
||||
|
||||
function title()
|
||||
{
|
||||
// TRANS: Title for a page where a user can confirm/deny account access by an external application.
|
||||
return _('An application would like to connect to your account');
|
||||
}
|
||||
|
||||
@ -264,36 +392,50 @@ class ApiOauthAuthorizeAction extends ApiOauthAction
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
|
||||
function showContent()
|
||||
{
|
||||
$this->elementStart('form', array('method' => 'post',
|
||||
'id' => 'form_apioauthauthorize',
|
||||
'class' => 'form_settings',
|
||||
'action' => common_local_url('apioauthauthorize')));
|
||||
'action' => common_local_url('ApiOauthAuthorize')));
|
||||
$this->elementStart('fieldset');
|
||||
$this->element('legend', array('id' => 'apioauthauthorize_allowdeny'),
|
||||
// TRANS: Fieldset legend.
|
||||
_('Allow or deny access'));
|
||||
|
||||
$this->hidden('token', common_session_token());
|
||||
$this->hidden('oauth_token', $this->oauth_token);
|
||||
$this->hidden('mode', $this->mode);
|
||||
$this->hidden('oauth_token', $this->oauthTokenParam);
|
||||
$this->hidden('oauth_callback', $this->callback);
|
||||
|
||||
$this->elementStart('ul', 'form_data');
|
||||
$this->elementStart('li');
|
||||
$this->elementStart('p');
|
||||
if (!empty($this->app->icon)) {
|
||||
if (!empty($this->app->icon) && $this->app->name != 'anonymous') {
|
||||
$this->element('img', array('src' => $this->app->icon));
|
||||
}
|
||||
|
||||
$access = ($this->app->access_type & Oauth_application::$writeAccess) ?
|
||||
'access and update' : 'access';
|
||||
|
||||
$msg = _('The application <strong>%1$s</strong> by ' .
|
||||
'<strong>%2$s</strong> would like the ability ' .
|
||||
if ($this->app->name == 'anonymous') {
|
||||
// Special message for the anonymous app and consumer.
|
||||
// TRANS: User notification of external application requesting account access.
|
||||
// TRANS: %3$s is the access type requested (read-write or read-only), %4$s is the StatusNet sitename.
|
||||
$msg = _('An application would like the ability ' .
|
||||
'to <strong>%3$s</strong> your %4$s account data. ' .
|
||||
'You should only give access to your %4$s account ' .
|
||||
'to third parties you trust.');
|
||||
} else {
|
||||
// TRANS: User notification of external application requesting account access.
|
||||
// TRANS: %1$s is the application name requesting access, %2$s is the organisation behind the application,
|
||||
// TRANS: %3$s is the access type requested, %4$s is the StatusNet sitename.
|
||||
$msg = _('The application <strong>%1$s</strong> by ' .
|
||||
'<strong>%2$s</strong> would like the ability ' .
|
||||
'to <strong>%3$s</strong> your %4$s account data. ' .
|
||||
'You should only give access to your %4$s account ' .
|
||||
'to third parties you trust.');
|
||||
}
|
||||
|
||||
$this->raw(sprintf($msg,
|
||||
$this->app->name,
|
||||
@ -304,34 +446,43 @@ class ApiOauthAuthorizeAction extends ApiOauthAction
|
||||
$this->elementEnd('li');
|
||||
$this->elementEnd('ul');
|
||||
|
||||
// quickie hack
|
||||
$button = false;
|
||||
if (!common_logged_in()) {
|
||||
if (Event::handle('StartOAuthLoginForm', array($this, &$button))) {
|
||||
$this->elementStart('fieldset');
|
||||
// TRANS: Fieldset legend.
|
||||
$this->element('legend', null, _m('LEGEND','Account'));
|
||||
$this->elementStart('ul', 'form_data');
|
||||
$this->elementStart('li');
|
||||
// TRANS: Field label on OAuth API authorisation form.
|
||||
$this->input('nickname', _('Nickname'));
|
||||
$this->elementEnd('li');
|
||||
$this->elementStart('li');
|
||||
// TRANS: Field label on OAuth API authorisation form.
|
||||
$this->password('password', _('Password'));
|
||||
$this->elementEnd('li');
|
||||
$this->elementEnd('ul');
|
||||
|
||||
$this->elementStart('fieldset');
|
||||
$this->element('legend', null, _('Account'));
|
||||
$this->elementStart('ul', 'form_data');
|
||||
$this->elementStart('li');
|
||||
$this->input('nickname', _('Nickname'));
|
||||
$this->elementEnd('li');
|
||||
$this->elementStart('li');
|
||||
$this->password('password', _('Password'));
|
||||
$this->elementEnd('li');
|
||||
$this->elementEnd('ul');
|
||||
|
||||
$this->elementEnd('fieldset');
|
||||
|
||||
$this->elementEnd('fieldset');
|
||||
}
|
||||
Event::handle('EndOAuthLoginForm', array($this, &$button));
|
||||
}
|
||||
|
||||
$this->element('input', array('id' => 'deny_submit',
|
||||
$this->element('input', array('id' => 'cancel_submit',
|
||||
'class' => 'submit submit form_action-primary',
|
||||
'name' => 'deny',
|
||||
'name' => 'cancel',
|
||||
'type' => 'submit',
|
||||
'value' => _('Deny')));
|
||||
// TRANS: Button text that when clicked will cancel the process of allowing access to an account
|
||||
// TRANS: by an external application.
|
||||
'value' => _m('BUTTON','Cancel')));
|
||||
|
||||
$this->element('input', array('id' => 'allow_submit',
|
||||
'class' => 'submit submit form_action-secondary',
|
||||
'name' => 'allow',
|
||||
'type' => 'submit',
|
||||
'value' => _('Allow')));
|
||||
// TRANS: Button text that when clicked will allow access to an account by an external application.
|
||||
'value' => $button ? $button : _m('BUTTON','Allow')));
|
||||
|
||||
$this->elementEnd('fieldset');
|
||||
$this->elementEnd('form');
|
||||
@ -345,10 +496,10 @@ class ApiOauthAuthorizeAction extends ApiOauthAction
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
|
||||
function getInstructions()
|
||||
{
|
||||
return _('Allow or deny access to your account information.');
|
||||
// TRANS: Form instructions.
|
||||
return _('Authorize access to your account information.');
|
||||
}
|
||||
|
||||
/**
|
||||
@ -358,18 +509,61 @@ class ApiOauthAuthorizeAction extends ApiOauthAction
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
|
||||
function showLocalNav()
|
||||
{
|
||||
// NOP
|
||||
}
|
||||
|
||||
/*
|
||||
* Checks to see if a the "mode" parameter is present in the request
|
||||
* and set to "desktop". If it is, the page is meant to be displayed in
|
||||
* a small frame of another application, and we should suppress the
|
||||
* header, aside, and footer.
|
||||
*/
|
||||
function desktopMode()
|
||||
{
|
||||
if (isset($this->mode) && $this->mode == 'desktop') {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Override - suppress output in "desktop" mode
|
||||
*/
|
||||
function showHeader()
|
||||
{
|
||||
if ($this->desktopMode() == false) {
|
||||
parent::showHeader();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Override - suppress output in "desktop" mode
|
||||
*/
|
||||
function showAside()
|
||||
{
|
||||
if ($this->desktopMode() == false) {
|
||||
parent::showAside();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Override - suppress output in "desktop" mode
|
||||
*/
|
||||
function showFooter()
|
||||
{
|
||||
if ($this->desktopMode() == false) {
|
||||
parent::showFooter();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Show site notice.
|
||||
*
|
||||
* @return nothing
|
||||
*/
|
||||
|
||||
function showSiteNotice()
|
||||
{
|
||||
// NOP
|
||||
@ -382,10 +576,165 @@ class ApiOauthAuthorizeAction extends ApiOauthAction
|
||||
*
|
||||
* @return nothing
|
||||
*/
|
||||
|
||||
function showNoticeForm()
|
||||
{
|
||||
// NOP
|
||||
}
|
||||
|
||||
/*
|
||||
* Show a nice message confirming the authorization
|
||||
* operation was canceled.
|
||||
*
|
||||
* @return nothing
|
||||
*/
|
||||
function showCanceled()
|
||||
{
|
||||
$info = new InfoAction(
|
||||
// TRANS: Header for user notification after revoking OAuth access to an application.
|
||||
_('Authorization canceled.'),
|
||||
sprintf(
|
||||
// TRANS: User notification after revoking OAuth access to an application.
|
||||
// TRANS: %s is an OAuth token.
|
||||
_('The request token %s has been revoked.'),
|
||||
$this->oauthTokenParam
|
||||
)
|
||||
);
|
||||
|
||||
$info->showPage();
|
||||
}
|
||||
|
||||
/*
|
||||
* Show a nice message that the authorization was successful.
|
||||
* If the operation is out-of-band, show a pin.
|
||||
*
|
||||
* @return nothing
|
||||
*/
|
||||
function showAuthorized()
|
||||
{
|
||||
$title = null;
|
||||
$msg = null;
|
||||
|
||||
if ($this->app->name == 'anonymous') {
|
||||
|
||||
$title =
|
||||
// TRANS: Title of the page notifying the user that an anonymous client application was successfully authorized to access the user's account with OAuth.
|
||||
_('You have successfully authorized the application');
|
||||
|
||||
$msg =
|
||||
// TRANS: Message notifying the user that an anonymous client application was successfully authorized to access the user's account with OAuth.
|
||||
_('Please return to the application and enter the following security code to complete the process.');
|
||||
|
||||
} else {
|
||||
|
||||
$title = sprintf(
|
||||
// TRANS: Title of the page notifying the user that the client application was successfully authorized to access the user's account with OAuth.
|
||||
// TRANS: %s is the authorised application name.
|
||||
_('You have successfully authorized %s'),
|
||||
$this->app->name
|
||||
);
|
||||
|
||||
$msg = sprintf(
|
||||
// TRANS: Message notifying the user that the client application was successfully authorized to access the user's account with OAuth.
|
||||
// TRANS: %s is the authorised application name.
|
||||
_('Please return to %s and enter the following security code to complete the process.'),
|
||||
$this->app->name
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
if ($this->reqToken->verified_callback == 'oob') {
|
||||
$pin = new ApiOauthPinAction(
|
||||
$title,
|
||||
$msg,
|
||||
$this->reqToken->verifier,
|
||||
$this->desktopMode()
|
||||
);
|
||||
$pin->showPage();
|
||||
} else {
|
||||
// NOTE: This would only happen if an application registered as
|
||||
// a web application but sent in 'oob' for the oauth_callback
|
||||
// parameter. Usually web apps will send in a callback and
|
||||
// not use the pin-based workflow.
|
||||
|
||||
$info = new InfoAction(
|
||||
$title,
|
||||
$msg,
|
||||
$this->oauthTokenParam,
|
||||
$this->reqToken->verifier
|
||||
);
|
||||
|
||||
$info->showPage();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Figure out what the callback should be
|
||||
*/
|
||||
function getCallback()
|
||||
{
|
||||
$callback = null;
|
||||
|
||||
// Return the verified callback if we have one
|
||||
if ($this->reqToken->verified_callback != 'oob') {
|
||||
|
||||
$callback = $this->reqToken->verified_callback;
|
||||
|
||||
// Otherwise return the callback that was provided when
|
||||
// registering the app
|
||||
if (empty($callback)) {
|
||||
|
||||
common_debug(
|
||||
"No verified callback found for request token, using application callback: "
|
||||
. $this->app->callback_url,
|
||||
__FILE__
|
||||
);
|
||||
|
||||
$callback = $this->app->callback_url;
|
||||
}
|
||||
}
|
||||
|
||||
return $callback;
|
||||
}
|
||||
|
||||
/*
|
||||
* Properly format the callback URL and parameters so it's
|
||||
* suitable for a redirect in the OAuth dance
|
||||
*
|
||||
* @param string $url the URL
|
||||
* @param array $params an array of parameters
|
||||
*
|
||||
* @return string $url a URL to use for redirecting to
|
||||
*/
|
||||
function buildCallbackUrl($url, $params)
|
||||
{
|
||||
foreach ($params as $k => $v) {
|
||||
$url = $this->appendQueryVar(
|
||||
$url,
|
||||
OAuthUtil::urlencode_rfc3986($k),
|
||||
OAuthUtil::urlencode_rfc3986($v)
|
||||
);
|
||||
}
|
||||
|
||||
return $url;
|
||||
}
|
||||
|
||||
/*
|
||||
* Append a new query parameter after any existing query
|
||||
* parameters.
|
||||
*
|
||||
* @param string $url the URL
|
||||
* @prarm string $k the parameter name
|
||||
* @param string $v value of the paramter
|
||||
*
|
||||
* @return string $url the new URL with added parameter
|
||||
*/
|
||||
function appendQueryVar($url, $k, $v) {
|
||||
$url = preg_replace('/(.*)(\?|&)' . $k . '=[^&]+?(&)(.*)/i', '$1$2$4', $url . '&');
|
||||
$url = substr($url, 0, -1);
|
||||
if (strpos($url, '?') === false) {
|
||||
return ($url . '?' . $k . '=' . $v);
|
||||
} else {
|
||||
return ($url . '&' . $k . '=' . $v);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
172
actions/apioauthpin.php
Normal file
172
actions/apioauthpin.php
Normal file
@ -0,0 +1,172 @@
|
||||
<?php
|
||||
/**
|
||||
* StatusNet, the distributed open-source microblogging tool
|
||||
*
|
||||
* Action for displaying an OAuth verifier pin
|
||||
*
|
||||
* 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 Action
|
||||
* @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') && !defined('LACONICA')) {
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Class for displaying an OAuth verifier pin
|
||||
*
|
||||
* XXX: I'm pretty sure we don't need to check the logged in state here. -- Zach
|
||||
*
|
||||
* @category Action
|
||||
* @package StatusNet
|
||||
* @author Zach Copley <zach@status.net>
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||
* @link http://status.net/
|
||||
*/
|
||||
class ApiOauthPinAction extends InfoAction
|
||||
{
|
||||
function __construct($title, $message, $verifier, $desktopMode = false)
|
||||
{
|
||||
$this->verifier = $verifier;
|
||||
$this->title = $title;
|
||||
$this->desktopMode = $desktopMode;
|
||||
parent::__construct($title, $message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Show body - override to add a special CSS class for the pin pages's
|
||||
* "desktop mode" (minimal display)
|
||||
*
|
||||
* Calls template methods
|
||||
*
|
||||
* @return nothing
|
||||
*/
|
||||
function showBody()
|
||||
{
|
||||
$bodyClasses = array();
|
||||
|
||||
if ($this->desktopMode) {
|
||||
$bodyClasses[] = 'oauth-desktop-mode';
|
||||
}
|
||||
|
||||
if (common_current_user()) {
|
||||
$bodyClasses[] = 'user_in';
|
||||
}
|
||||
|
||||
$attrs = array('id' => strtolower($this->trimmed('action')));
|
||||
|
||||
if (!empty($bodyClasses)) {
|
||||
$attrs['class'] = implode(' ', $bodyClasses);
|
||||
}
|
||||
|
||||
$this->elementStart('body', $attrs);
|
||||
|
||||
$this->elementStart('div', array('id' => 'wrap'));
|
||||
if (Event::handle('StartShowHeader', array($this))) {
|
||||
$this->showHeader();
|
||||
Event::handle('EndShowHeader', array($this));
|
||||
}
|
||||
$this->showCore();
|
||||
if (Event::handle('StartShowFooter', array($this))) {
|
||||
$this->showFooter();
|
||||
Event::handle('EndShowFooter', array($this));
|
||||
}
|
||||
$this->elementEnd('div');
|
||||
$this->showScripts();
|
||||
$this->elementEnd('body');
|
||||
}
|
||||
|
||||
/**
|
||||
* A local menu
|
||||
*
|
||||
* Shows different login/register actions.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
function showLocalNav()
|
||||
{
|
||||
// NOP
|
||||
}
|
||||
|
||||
/*
|
||||
* Override - suppress output in "desktop" mode
|
||||
*/
|
||||
function showHeader()
|
||||
{
|
||||
if ($this->desktopMode == false) {
|
||||
parent::showHeader();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Override - suppress output in "desktop" mode
|
||||
*/
|
||||
function showAside()
|
||||
{
|
||||
if ($this->desktopMode == false) {
|
||||
parent::showAside();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Override - suppress output in "desktop" mode
|
||||
*/
|
||||
function showFooter()
|
||||
{
|
||||
if ($this->desktopMode == false) {
|
||||
parent::showFooter();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Show site notice.
|
||||
*
|
||||
* @return nothing
|
||||
*/
|
||||
function showSiteNotice()
|
||||
{
|
||||
// NOP
|
||||
}
|
||||
|
||||
/**
|
||||
* Show notice form.
|
||||
*
|
||||
* Show the form for posting a new notice
|
||||
*
|
||||
* @return nothing
|
||||
*/
|
||||
function showNoticeForm()
|
||||
{
|
||||
// NOP
|
||||
}
|
||||
|
||||
/**
|
||||
* Display content.
|
||||
*
|
||||
* @return nothing
|
||||
*/
|
||||
function showContent()
|
||||
{
|
||||
$this->element('div', array('class' => 'info'), $this->message);
|
||||
$this->element('div', array('id' => 'oauth_pin'), $this->verifier);
|
||||
}
|
||||
}
|
@ -2,7 +2,7 @@
|
||||
/**
|
||||
* StatusNet, the distributed open-source microblogging tool
|
||||
*
|
||||
* Get an OAuth request token
|
||||
* Issue temporary OAuth credentials (a request token)
|
||||
*
|
||||
* PHP version 5
|
||||
*
|
||||
@ -34,7 +34,7 @@ if (!defined('STATUSNET')) {
|
||||
require_once INSTALLDIR . '/lib/apioauth.php';
|
||||
|
||||
/**
|
||||
* Get an OAuth request token
|
||||
* Issue temporary OAuth credentials (a request token)
|
||||
*
|
||||
* @category API
|
||||
* @package StatusNet
|
||||
@ -42,7 +42,6 @@ require_once INSTALLDIR . '/lib/apioauth.php';
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||
* @link http://status.net/
|
||||
*/
|
||||
|
||||
class ApiOauthRequestTokenAction extends ApiOauthAction
|
||||
{
|
||||
/**
|
||||
@ -51,24 +50,22 @@ class ApiOauthRequestTokenAction extends ApiOauthAction
|
||||
* @param array $args $_REQUEST args
|
||||
*
|
||||
* @return boolean success flag
|
||||
*
|
||||
*/
|
||||
|
||||
function prepare($args)
|
||||
{
|
||||
parent::prepare($args);
|
||||
|
||||
$this->callback = $this->arg('oauth_callback');
|
||||
|
||||
if (!empty($this->callback)) {
|
||||
common_debug("callback: $this->callback");
|
||||
}
|
||||
// XXX: support "force_login" parameter like Twitter? (Forces the user to enter
|
||||
// their credentials to ensure the correct users account is authorized.)
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Class handler.
|
||||
* Handle a request for temporary OAuth credentials
|
||||
*
|
||||
* Make sure the request is kosher, then emit a set of temporary
|
||||
* credentials -- AKA an unauthorized request token.
|
||||
*
|
||||
* @param array $args array of arguments
|
||||
*
|
||||
@ -85,15 +82,73 @@ class ApiOauthRequestTokenAction extends ApiOauthAction
|
||||
$server->add_signature_method($hmac_method);
|
||||
|
||||
try {
|
||||
$req = OAuthRequest::from_request();
|
||||
|
||||
$req = OAuthRequest::from_request();
|
||||
|
||||
// verify callback
|
||||
if (!$this->verifyCallback($req->get_parameter('oauth_callback'))) {
|
||||
throw new OAuthException(
|
||||
"You must provide a valid URL or 'oob' in oauth_callback.",
|
||||
400
|
||||
);
|
||||
}
|
||||
|
||||
// check signature and issue a new request token
|
||||
$token = $server->fetch_request_token($req);
|
||||
print $token;
|
||||
|
||||
common_log(
|
||||
LOG_INFO,
|
||||
sprintf(
|
||||
"API OAuth - Issued request token %s for consumer %s with oauth_callback %s",
|
||||
$token->key,
|
||||
$req->get_parameter('oauth_consumer_key'),
|
||||
"'" . $req->get_parameter('oauth_callback') ."'"
|
||||
)
|
||||
);
|
||||
|
||||
// return token to the client
|
||||
$this->showRequestToken($token);
|
||||
|
||||
} catch (OAuthException $e) {
|
||||
common_log(LOG_WARNING, 'API OAuthException - ' . $e->getMessage());
|
||||
header('HTTP/1.1 401 Unauthorized');
|
||||
header('Content-Type: text/html; charset=utf-8');
|
||||
print $e->getMessage() . "\n";
|
||||
|
||||
// Return 401 for for bad credentials or signature problems,
|
||||
// and 400 for missing or unsupported parameters
|
||||
|
||||
$code = $e->getCode();
|
||||
$this->clientError($e->getMessage(), empty($code) ? 401 : $code, 'text');
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Display temporary OAuth credentials
|
||||
*/
|
||||
function showRequestToken($token)
|
||||
{
|
||||
header('Content-Type: application/x-www-form-urlencoded');
|
||||
print $token;
|
||||
print '&oauth_callback_confirmed=true';
|
||||
}
|
||||
|
||||
/* Make sure the callback parameter contains either a real URL
|
||||
* or the string 'oob'.
|
||||
*
|
||||
* @todo Check for evil/banned URLs here
|
||||
*
|
||||
* @return boolean true or false
|
||||
*/
|
||||
function verifyCallback($callback)
|
||||
{
|
||||
if ($callback == "oob") {
|
||||
common_debug("OAuth request token requested for out of band client.");
|
||||
|
||||
// XXX: Should we throw an error if a client is registered as a
|
||||
// web application but requests the pin based workflow? For now I'm
|
||||
// allowing the workflow to proceed and issuing a pin. --Zach
|
||||
|
||||
return true;
|
||||
} else {
|
||||
return Validate::uri($callback);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -48,10 +48,8 @@ require_once INSTALLDIR.'/lib/apiprivateauth.php';
|
||||
*
|
||||
* @see ApiPrivateAuthAction
|
||||
*/
|
||||
|
||||
class ApiSearchAtomAction extends ApiPrivateAuthAction
|
||||
{
|
||||
|
||||
var $cnt;
|
||||
var $query;
|
||||
var $lang;
|
||||
@ -70,7 +68,6 @@ class ApiSearchAtomAction extends ApiPrivateAuthAction
|
||||
*
|
||||
* @see Action::__construct
|
||||
*/
|
||||
|
||||
function __construct($output='php://output', $indent=null)
|
||||
{
|
||||
parent::__construct($output, $indent);
|
||||
@ -81,7 +78,6 @@ class ApiSearchAtomAction extends ApiPrivateAuthAction
|
||||
*
|
||||
* @return boolean true
|
||||
*/
|
||||
|
||||
function isReadonly()
|
||||
{
|
||||
return true;
|
||||
@ -93,16 +89,13 @@ class ApiSearchAtomAction extends ApiPrivateAuthAction
|
||||
* @param array $args Arguments from $_REQUEST
|
||||
*
|
||||
* @return boolean success
|
||||
*
|
||||
*/
|
||||
|
||||
function prepare($args)
|
||||
{
|
||||
common_debug("in apisearchatom prepare()");
|
||||
|
||||
parent::prepare($args);
|
||||
|
||||
|
||||
$this->query = $this->trimmed('q');
|
||||
$this->lang = $this->trimmed('lang');
|
||||
$this->rpp = $this->trimmed('rpp');
|
||||
@ -121,7 +114,7 @@ class ApiSearchAtomAction extends ApiPrivateAuthAction
|
||||
$this->page = 1;
|
||||
}
|
||||
|
||||
// TODO: Suppport since_id -- we need to tweak the backend
|
||||
// TODO: Suppport max_id -- we need to tweak the backend
|
||||
// Search classes to support it.
|
||||
|
||||
$this->since_id = $this->trimmed('since_id');
|
||||
@ -139,7 +132,6 @@ class ApiSearchAtomAction extends ApiPrivateAuthAction
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
|
||||
function handle($args)
|
||||
{
|
||||
parent::handle($args);
|
||||
@ -154,7 +146,6 @@ class ApiSearchAtomAction extends ApiPrivateAuthAction
|
||||
*
|
||||
* @return array an array of Notice objects sorted in reverse chron
|
||||
*/
|
||||
|
||||
function getNotices()
|
||||
{
|
||||
// TODO: Support search operators like from: and to:, boolean, etc.
|
||||
@ -180,13 +171,16 @@ class ApiSearchAtomAction extends ApiPrivateAuthAction
|
||||
|
||||
if ($this->cnt > 0) {
|
||||
while ($notice->fetch()) {
|
||||
|
||||
++$cnt;
|
||||
|
||||
if (!$this->max_id) {
|
||||
$this->max_id = $notice->id;
|
||||
}
|
||||
|
||||
if ($this->since_id && $notice->id <= $this->since_id) {
|
||||
break;
|
||||
}
|
||||
|
||||
if ($cnt > $this->rpp) {
|
||||
break;
|
||||
}
|
||||
@ -203,7 +197,6 @@ class ApiSearchAtomAction extends ApiPrivateAuthAction
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
|
||||
function showAtom()
|
||||
{
|
||||
$notices = $this->getNotices();
|
||||
@ -212,7 +205,6 @@ class ApiSearchAtomAction extends ApiPrivateAuthAction
|
||||
$this->showFeed();
|
||||
|
||||
foreach ($notices as $n) {
|
||||
|
||||
$profile = $n->getProfile();
|
||||
|
||||
// Don't show notices from deleted users
|
||||
@ -230,7 +222,6 @@ class ApiSearchAtomAction extends ApiPrivateAuthAction
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
|
||||
function showFeed()
|
||||
{
|
||||
// TODO: A9 OpenSearch stuff like search.twitter.com?
|
||||
@ -278,6 +269,7 @@ class ApiSearchAtomAction extends ApiPrivateAuthAction
|
||||
'rel' => 'self',
|
||||
'href' => $self_uri));
|
||||
|
||||
// @todo Needs i18n?
|
||||
$this->element('title', null, "$this->query - $sitename Search");
|
||||
$this->element('updated', null, common_date_iso8601('now'));
|
||||
|
||||
@ -313,7 +305,6 @@ class ApiSearchAtomAction extends ApiPrivateAuthAction
|
||||
'rel' => 'previous',
|
||||
'href' => $previous_uri));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@ -324,7 +315,6 @@ class ApiSearchAtomAction extends ApiPrivateAuthAction
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
|
||||
function showEntry($notice)
|
||||
{
|
||||
$server = common_config('site', 'server');
|
||||
@ -356,10 +346,10 @@ class ApiSearchAtomAction extends ApiPrivateAuthAction
|
||||
if ($ns) {
|
||||
if (!empty($ns->name) && !empty($ns->url)) {
|
||||
$source = '<a href="'
|
||||
. htmlspecialchars($ns->url)
|
||||
. '" rel="nofollow">'
|
||||
. htmlspecialchars($ns->name)
|
||||
. '</a>';
|
||||
. htmlspecialchars($ns->url)
|
||||
. '" rel="nofollow">'
|
||||
. htmlspecialchars($ns->name)
|
||||
. '</a>';
|
||||
} else {
|
||||
$source = $ns->code;
|
||||
}
|
||||
@ -372,6 +362,7 @@ class ApiSearchAtomAction extends ApiPrivateAuthAction
|
||||
$name = $profile->nickname;
|
||||
|
||||
if ($profile->fullname) {
|
||||
// @todo Needs proper i18n?
|
||||
$name .= ' (' . $profile->fullname . ')';
|
||||
}
|
||||
|
||||
@ -387,7 +378,6 @@ class ApiSearchAtomAction extends ApiPrivateAuthAction
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
|
||||
function initAtom()
|
||||
{
|
||||
header('Content-Type: application/atom+xml; charset=utf-8');
|
||||
@ -399,10 +389,8 @@ class ApiSearchAtomAction extends ApiPrivateAuthAction
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
|
||||
function endAtom()
|
||||
{
|
||||
$this->elementEnd('feed');
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -44,7 +44,6 @@ require_once INSTALLDIR.'/lib/jsonsearchresultslist.php';
|
||||
* @link http://status.net/
|
||||
* @see ApiAction
|
||||
*/
|
||||
|
||||
class ApiSearchJSONAction extends ApiPrivateAuthAction
|
||||
{
|
||||
var $query;
|
||||
@ -62,7 +61,6 @@ class ApiSearchJSONAction extends ApiPrivateAuthAction
|
||||
*
|
||||
* @return boolean true if nothing goes wrong
|
||||
*/
|
||||
|
||||
function prepare($args)
|
||||
{
|
||||
common_debug("apisearchjson prepare()");
|
||||
@ -87,6 +85,9 @@ class ApiSearchJSONAction extends ApiPrivateAuthAction
|
||||
$this->page = 1;
|
||||
}
|
||||
|
||||
// TODO: Suppport max_id -- we need to tweak the backend
|
||||
// Search classes to support it.
|
||||
|
||||
$this->since_id = $this->trimmed('since_id');
|
||||
$this->geocode = $this->trimmed('geocode');
|
||||
|
||||
@ -100,7 +101,6 @@ class ApiSearchJSONAction extends ApiPrivateAuthAction
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
|
||||
function handle($args)
|
||||
{
|
||||
parent::handle($args);
|
||||
@ -112,10 +112,8 @@ class ApiSearchJSONAction extends ApiPrivateAuthAction
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
|
||||
function showResults()
|
||||
{
|
||||
|
||||
// TODO: Support search operators like from: and to:, boolean, etc.
|
||||
|
||||
$notice = new Notice();
|
||||
@ -132,9 +130,9 @@ class ApiSearchJSONAction extends ApiPrivateAuthAction
|
||||
$cnt = $notice->find();
|
||||
}
|
||||
|
||||
// TODO: since_id, lang, geocode
|
||||
// TODO: max_id, lang, geocode
|
||||
|
||||
$results = new JSONSearchResultsList($notice, $q, $this->rpp, $this->page);
|
||||
$results = new JSONSearchResultsList($notice, $q, $this->rpp, $this->page, $this->since_id);
|
||||
|
||||
$this->initDocument('json');
|
||||
$results->show();
|
||||
@ -146,7 +144,6 @@ class ApiSearchJSONAction extends ApiPrivateAuthAction
|
||||
*
|
||||
* @return boolean true
|
||||
*/
|
||||
|
||||
function isReadOnly($args)
|
||||
{
|
||||
return true;
|
||||
|
@ -55,7 +55,6 @@ require_once INSTALLDIR . '/lib/apiauth.php';
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||
* @link http://status.net/
|
||||
*/
|
||||
|
||||
class ApiStatusesDestroyAction extends ApiAuthAction
|
||||
{
|
||||
var $status = null;
|
||||
@ -66,9 +65,7 @@ class ApiStatusesDestroyAction extends ApiAuthAction
|
||||
* @param array $args $_REQUEST args
|
||||
*
|
||||
* @return boolean success flag
|
||||
*
|
||||
*/
|
||||
|
||||
function prepare($args)
|
||||
{
|
||||
parent::prepare($args);
|
||||
@ -94,13 +91,13 @@ class ApiStatusesDestroyAction extends ApiAuthAction
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
|
||||
function handle($args)
|
||||
{
|
||||
parent::handle($args);
|
||||
|
||||
if (!in_array($this->format, array('xml', 'json'))) {
|
||||
$this->clientError(
|
||||
// TRANS: Client error displayed trying to execute an unknown API method deleting a status.
|
||||
_('API method not found.'),
|
||||
404
|
||||
);
|
||||
@ -109,6 +106,8 @@ class ApiStatusesDestroyAction extends ApiAuthAction
|
||||
|
||||
if (!in_array($_SERVER['REQUEST_METHOD'], array('POST', 'DELETE'))) {
|
||||
$this->clientError(
|
||||
// TRANS: Client error displayed trying to delete a status not using POST or DELETE.
|
||||
// TRANS: POST and DELETE should not be translated.
|
||||
_('This method requires a POST or DELETE.'),
|
||||
400,
|
||||
$this->format
|
||||
@ -118,6 +117,7 @@ class ApiStatusesDestroyAction extends ApiAuthAction
|
||||
|
||||
if (empty($this->notice)) {
|
||||
$this->clientError(
|
||||
// TRANS: Client error displayed trying to delete a status with an invalid ID.
|
||||
_('No status found with that ID.'),
|
||||
404, $this->format
|
||||
);
|
||||
@ -125,13 +125,14 @@ class ApiStatusesDestroyAction extends ApiAuthAction
|
||||
}
|
||||
|
||||
if ($this->user->id == $this->notice->profile_id) {
|
||||
$replies = new Reply;
|
||||
$replies->get('notice_id', $this->notice_id);
|
||||
$replies->delete();
|
||||
$this->notice->delete();
|
||||
if (Event::handle('StartDeleteOwnNotice', array($this->user, $this->notice))) {
|
||||
$this->notice->delete();
|
||||
Event::handle('EndDeleteOwnNotice', array($this->user, $this->notice));
|
||||
}
|
||||
$this->showNotice();
|
||||
} else {
|
||||
$this->clientError(
|
||||
// TRANS: Client error displayed trying to delete a status of another user.
|
||||
_('You may not delete another user\'s status.'),
|
||||
403,
|
||||
$this->format
|
||||
@ -144,7 +145,6 @@ class ApiStatusesDestroyAction extends ApiAuthAction
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
|
||||
function showNotice()
|
||||
{
|
||||
if (!empty($this->notice)) {
|
||||
@ -155,5 +155,4 @@ class ApiStatusesDestroyAction extends ApiAuthAction
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -43,7 +43,6 @@ require_once INSTALLDIR . '/lib/mediafile.php';
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||
* @link http://status.net/
|
||||
*/
|
||||
|
||||
class ApiStatusesRetweetAction extends ApiAuthAction
|
||||
{
|
||||
var $original = null;
|
||||
@ -54,14 +53,13 @@ class ApiStatusesRetweetAction extends ApiAuthAction
|
||||
* @param array $args $_REQUEST args
|
||||
*
|
||||
* @return boolean success flag
|
||||
*
|
||||
*/
|
||||
|
||||
function prepare($args)
|
||||
{
|
||||
parent::prepare($args);
|
||||
|
||||
if ($_SERVER['REQUEST_METHOD'] != 'POST') {
|
||||
// TRANS: Client error. POST is a HTTP command. It should not be translated.
|
||||
$this->clientError(_('This method requires a POST.'),
|
||||
400, $this->format);
|
||||
return false;
|
||||
@ -72,6 +70,7 @@ class ApiStatusesRetweetAction extends ApiAuthAction
|
||||
$this->original = Notice::staticGet('id', $id);
|
||||
|
||||
if (empty($this->original)) {
|
||||
// TRANS: Client error displayed trying to repeat a non-existing notice through the API.
|
||||
$this->clientError(_('No such notice.'),
|
||||
400, $this->format);
|
||||
return false;
|
||||
@ -80,6 +79,7 @@ class ApiStatusesRetweetAction extends ApiAuthAction
|
||||
$this->user = $this->auth_user;
|
||||
|
||||
if ($this->user->id == $this->original->profile_id) {
|
||||
// TRANS: Client error displayed trying to repeat an own notice through the API.
|
||||
$this->clientError(_('Cannot repeat your own notice.'),
|
||||
400, $this->format);
|
||||
return false;
|
||||
@ -88,6 +88,7 @@ class ApiStatusesRetweetAction extends ApiAuthAction
|
||||
$profile = $this->user->getProfile();
|
||||
|
||||
if ($profile->hasRepeated($id)) {
|
||||
// TRANS: Client error displayed trying to re-repeat a notice through the API.
|
||||
$this->clientError(_('Already repeated that notice.'),
|
||||
400, $this->format);
|
||||
return false;
|
||||
@ -105,15 +106,12 @@ class ApiStatusesRetweetAction extends ApiAuthAction
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
|
||||
function handle($args)
|
||||
{
|
||||
parent::handle($args);
|
||||
|
||||
$repeat = $this->original->repeat($this->user->id, $this->source);
|
||||
|
||||
|
||||
|
||||
$this->showNotice($repeat);
|
||||
}
|
||||
|
||||
@ -122,7 +120,6 @@ class ApiStatusesRetweetAction extends ApiAuthAction
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
|
||||
function showNotice($notice)
|
||||
{
|
||||
if (!empty($notice)) {
|
||||
|
@ -43,7 +43,6 @@ require_once INSTALLDIR . '/lib/mediafile.php';
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||
* @link http://status.net/
|
||||
*/
|
||||
|
||||
class ApiStatusesRetweetsAction extends ApiAuthAction
|
||||
{
|
||||
const MAXCOUNT = 100;
|
||||
@ -57,9 +56,7 @@ class ApiStatusesRetweetsAction extends ApiAuthAction
|
||||
* @param array $args $_REQUEST args
|
||||
*
|
||||
* @return boolean success flag
|
||||
*
|
||||
*/
|
||||
|
||||
function prepare($args)
|
||||
{
|
||||
parent::prepare($args);
|
||||
@ -69,6 +66,7 @@ class ApiStatusesRetweetsAction extends ApiAuthAction
|
||||
$this->original = Notice::staticGet('id', $id);
|
||||
|
||||
if (empty($this->original)) {
|
||||
// TRANS: Client error displayed trying to display redents of a non-exiting notice.
|
||||
$this->clientError(_('No such notice.'),
|
||||
400, $this->format);
|
||||
return false;
|
||||
@ -94,7 +92,6 @@ class ApiStatusesRetweetsAction extends ApiAuthAction
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
|
||||
function handle($args)
|
||||
{
|
||||
parent::handle($args);
|
||||
@ -109,6 +106,7 @@ class ApiStatusesRetweetsAction extends ApiAuthAction
|
||||
$this->showJsonTimeline($strm);
|
||||
break;
|
||||
default:
|
||||
// TRANS: Client error displayed when trying to handle an unknown API method.
|
||||
$this->clientError(_('API method not found.'), $code = 404);
|
||||
break;
|
||||
}
|
||||
|
@ -55,10 +55,8 @@ require_once INSTALLDIR . '/lib/apiprivateauth.php';
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||
* @link http://status.net/
|
||||
*/
|
||||
|
||||
class ApiStatusesShowAction extends ApiPrivateAuthAction
|
||||
{
|
||||
|
||||
var $notice_id = null;
|
||||
var $notice = null;
|
||||
|
||||
@ -68,9 +66,7 @@ class ApiStatusesShowAction extends ApiPrivateAuthAction
|
||||
* @param array $args $_REQUEST args
|
||||
*
|
||||
* @return boolean success flag
|
||||
*
|
||||
*/
|
||||
|
||||
function prepare($args)
|
||||
{
|
||||
parent::prepare($args);
|
||||
@ -100,17 +96,27 @@ class ApiStatusesShowAction extends ApiPrivateAuthAction
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
|
||||
function handle($args)
|
||||
{
|
||||
parent::handle($args);
|
||||
|
||||
if (!in_array($this->format, array('xml', 'json'))) {
|
||||
$this->clientError(_('API method not found.'), $code = 404);
|
||||
if (!in_array($this->format, array('xml', 'json', 'atom'))) {
|
||||
// TRANS: Client error displayed when trying to handle an unknown API method.
|
||||
$this->clientError(_('API method not found.'), 404);
|
||||
return;
|
||||
}
|
||||
|
||||
$this->showNotice();
|
||||
switch ($_SERVER['REQUEST_METHOD']) {
|
||||
case 'GET':
|
||||
$this->showNotice();
|
||||
break;
|
||||
case 'DELETE':
|
||||
$this->deleteNotice();
|
||||
break;
|
||||
default:
|
||||
$this->clientError(_('HTTP method not supported.'), 405);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -118,17 +124,23 @@ class ApiStatusesShowAction extends ApiPrivateAuthAction
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
|
||||
function showNotice()
|
||||
{
|
||||
if (!empty($this->notice)) {
|
||||
if ($this->format == 'xml') {
|
||||
switch ($this->format) {
|
||||
case 'xml':
|
||||
$this->showSingleXmlStatus($this->notice);
|
||||
} elseif ($this->format == 'json') {
|
||||
break;
|
||||
case 'json':
|
||||
$this->show_single_json_status($this->notice);
|
||||
break;
|
||||
case 'atom':
|
||||
$this->showSingleAtomStatus($this->notice);
|
||||
break;
|
||||
default:
|
||||
throw new Exception(sprintf(_("Unsupported format: %s"), $this->format));
|
||||
}
|
||||
} else {
|
||||
|
||||
// XXX: Twitter just sets a 404 header and doens't bother
|
||||
// to return an err msg
|
||||
|
||||
@ -136,12 +148,14 @@ class ApiStatusesShowAction extends ApiPrivateAuthAction
|
||||
|
||||
if (!empty($deleted)) {
|
||||
$this->clientError(
|
||||
// TRANS: Client error displayed requesting a deleted status.
|
||||
_('Status deleted.'),
|
||||
410,
|
||||
$this->format
|
||||
);
|
||||
} else {
|
||||
$this->clientError(
|
||||
// TRANS: Client error displayed requesting a status with an invalid ID.
|
||||
_('No status with that ID found.'),
|
||||
404,
|
||||
$this->format
|
||||
@ -151,16 +165,16 @@ class ApiStatusesShowAction extends ApiPrivateAuthAction
|
||||
}
|
||||
|
||||
/**
|
||||
* Is this action read only?
|
||||
* We expose AtomPub here, so non-GET/HEAD reqs must be read/write.
|
||||
*
|
||||
* @param array $args other arguments
|
||||
*
|
||||
* @return boolean true
|
||||
*/
|
||||
|
||||
|
||||
function isReadOnly($args)
|
||||
{
|
||||
return true;
|
||||
return ($_SERVER['REQUEST_METHOD'] == 'GET' || $_SERVER['REQUEST_METHOD'] == 'HEAD');
|
||||
}
|
||||
|
||||
/**
|
||||
@ -168,7 +182,6 @@ class ApiStatusesShowAction extends ApiPrivateAuthAction
|
||||
*
|
||||
* @return string datestamp of the latest notice in the stream
|
||||
*/
|
||||
|
||||
function lastModified()
|
||||
{
|
||||
if (!empty($this->notice)) {
|
||||
@ -186,7 +199,6 @@ class ApiStatusesShowAction extends ApiPrivateAuthAction
|
||||
*
|
||||
* @return string etag
|
||||
*/
|
||||
|
||||
function etag()
|
||||
{
|
||||
if (!empty($this->notice)) {
|
||||
@ -194,6 +206,7 @@ class ApiStatusesShowAction extends ApiPrivateAuthAction
|
||||
return '"' . implode(
|
||||
':',
|
||||
array($this->arg('action'),
|
||||
common_user_cache_hash($this->auth_user),
|
||||
common_language(),
|
||||
$this->notice->id,
|
||||
strtotime($this->notice->created))
|
||||
@ -204,4 +217,30 @@ class ApiStatusesShowAction extends ApiPrivateAuthAction
|
||||
return null;
|
||||
}
|
||||
|
||||
function deleteNotice()
|
||||
{
|
||||
if ($this->format != 'atom') {
|
||||
$this->clientError(_("Can only delete using the Atom format."));
|
||||
return;
|
||||
}
|
||||
|
||||
if (empty($this->auth_user) ||
|
||||
($this->notice->profile_id != $this->auth_user->id &&
|
||||
!$this->auth_user->hasRight(Right::DELETEOTHERSNOTICE))) {
|
||||
$this->clientError(_('Can\'t delete this notice.'), 403);
|
||||
return;
|
||||
}
|
||||
|
||||
if (Event::handle('StartDeleteOwnNotice', array($this->auth_user, $this->notice))) {
|
||||
$this->notice->delete();
|
||||
Event::handle('EndDeleteOwnNotice', array($this->auth_user, $this->notice));
|
||||
}
|
||||
|
||||
// @fixme is there better output we could do here?
|
||||
|
||||
header('HTTP/1.1 200 OK');
|
||||
header('Content-Type: text/plain');
|
||||
print(sprintf(_('Deleted notice %d'), $this->notice->id));
|
||||
print("\n");
|
||||
}
|
||||
}
|
||||
|
@ -55,7 +55,7 @@
|
||||
Yes
|
||||
|
||||
@param status (Required) The URL-encoded text of the status update.
|
||||
@param source (Optional) The source of the status.
|
||||
@param source (Optional) The source application name, if using HTTP authentication or an anonymous OAuth consumer.
|
||||
@param in_reply_to_status_id (Optional) The ID of an existing status that the update is in reply to.
|
||||
@param lat (Optional) The latitude the status refers to.
|
||||
@param long (Optional) The longitude the status refers to.
|
||||
@ -67,7 +67,7 @@
|
||||
@subsection usagenotes Usage notes
|
||||
|
||||
@li The URL pattern is relative to the @ref apiroot.
|
||||
@li If the @e source parameter is not supplied the source of the status will default to 'api'.
|
||||
@li If the @e source parameter is not supplied the source of the status will default to 'api'. When authenticated via a registered OAuth application, the application's registered name and URL will always override the source parameter.
|
||||
@li The XML response uses <a href="http://georss.org/Main_Page">GeoRSS</a>
|
||||
to encode the latitude and longitude (see example response below <georss:point>).
|
||||
@li Data uploaded via the @e media parameter should be multipart/form-data encoded.
|
||||
@ -147,10 +147,8 @@ require_once INSTALLDIR . '/lib/mediafile.php';
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||
* @link http://status.net/
|
||||
*/
|
||||
|
||||
class ApiStatusesUpdateAction extends ApiAuthAction
|
||||
{
|
||||
var $source = null;
|
||||
var $status = null;
|
||||
var $in_reply_to_status_id = null;
|
||||
var $lat = null;
|
||||
@ -162,9 +160,7 @@ class ApiStatusesUpdateAction extends ApiAuthAction
|
||||
* @param array $args $_REQUEST args
|
||||
*
|
||||
* @return boolean success flag
|
||||
*
|
||||
*/
|
||||
|
||||
function prepare($args)
|
||||
{
|
||||
parent::prepare($args);
|
||||
@ -188,13 +184,13 @@ class ApiStatusesUpdateAction extends ApiAuthAction
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
|
||||
function handle($args)
|
||||
{
|
||||
parent::handle($args);
|
||||
|
||||
if ($_SERVER['REQUEST_METHOD'] != 'POST') {
|
||||
$this->clientError(
|
||||
// TRANS: Client error. POST is a HTTP command. It should not be translated.
|
||||
_('This method requires a POST.'),
|
||||
400,
|
||||
$this->format
|
||||
@ -209,8 +205,11 @@ class ApiStatusesUpdateAction extends ApiAuthAction
|
||||
&& empty($_POST)
|
||||
&& ($_SERVER['CONTENT_LENGTH'] > 0)
|
||||
) {
|
||||
$msg = _('The server was unable to handle that much POST ' .
|
||||
'data (%s bytes) due to its current configuration.');
|
||||
// TRANS: Client error displayed when the number of bytes in a POST request exceeds a limit.
|
||||
// TRANS: %s is the number of bytes of the CONTENT_LENGTH.
|
||||
$msg = _m('The server was unable to handle that much POST data (%s byte) due to its current configuration.',
|
||||
'The server was unable to handle that much POST data (%s bytes) due to its current configuration.',
|
||||
intval($_SERVER['CONTENT_LENGTH']));
|
||||
|
||||
$this->clientError(sprintf($msg, $_SERVER['CONTENT_LENGTH']));
|
||||
return;
|
||||
@ -218,6 +217,7 @@ class ApiStatusesUpdateAction extends ApiAuthAction
|
||||
|
||||
if (empty($this->status)) {
|
||||
$this->clientError(
|
||||
// TRANS: Client error displayed when the parameter "status" is missing.
|
||||
_('Client must provide a \'status\' parameter with a value.'),
|
||||
400,
|
||||
$this->format
|
||||
@ -226,20 +226,24 @@ class ApiStatusesUpdateAction extends ApiAuthAction
|
||||
}
|
||||
|
||||
if (empty($this->auth_user)) {
|
||||
// TRANS: Client error displayed when updating a status for a non-existing user.
|
||||
$this->clientError(_('No such user.'), 404, $this->format);
|
||||
return;
|
||||
}
|
||||
|
||||
$status_shortened = common_shorten_links($this->status);
|
||||
$status_shortened = $this->auth_user->shortenlinks($this->status);
|
||||
|
||||
if (Notice::contentTooLong($status_shortened)) {
|
||||
|
||||
// Note: Twitter truncates anything over 140, flags the status
|
||||
// as "truncated."
|
||||
|
||||
$this->clientError(
|
||||
sprintf(
|
||||
_('That\'s too long. Max notice size is %d chars.'),
|
||||
// TRANS: Client error displayed when the parameter "status" is missing.
|
||||
// TRANS: %d is the maximum number of character for a notice.
|
||||
_m('That\'s too long. Maximum notice size is %d character.',
|
||||
'That\'s too long. Maximum notice size is %d characters.',
|
||||
Notice::maxContent()),
|
||||
Notice::maxContent()
|
||||
),
|
||||
406,
|
||||
@ -255,7 +259,6 @@ class ApiStatusesUpdateAction extends ApiAuthAction
|
||||
$cmd = $inter->handle_command($this->auth_user, $status_shortened);
|
||||
|
||||
if ($cmd) {
|
||||
|
||||
if ($this->supported($cmd)) {
|
||||
$cmd->execute(new Channel());
|
||||
}
|
||||
@ -265,13 +268,10 @@ class ApiStatusesUpdateAction extends ApiAuthAction
|
||||
// or not!
|
||||
|
||||
$this->notice = $this->auth_user->getCurrentNotice();
|
||||
|
||||
} else {
|
||||
|
||||
$reply_to = null;
|
||||
|
||||
if (!empty($this->in_reply_to_status_id)) {
|
||||
|
||||
// Check whether notice actually exists
|
||||
|
||||
$reply = Notice::staticGet($this->in_reply_to_status_id);
|
||||
@ -280,7 +280,8 @@ class ApiStatusesUpdateAction extends ApiAuthAction
|
||||
$reply_to = $this->in_reply_to_status_id;
|
||||
} else {
|
||||
$this->clientError(
|
||||
_('Not found.'),
|
||||
// TRANS: Client error displayed when replying to a non-existing notice.
|
||||
_('Parent notice not found.'),
|
||||
$code = 404,
|
||||
$this->format
|
||||
);
|
||||
@ -302,10 +303,11 @@ class ApiStatusesUpdateAction extends ApiAuthAction
|
||||
|
||||
if (Notice::contentTooLong($status_shortened)) {
|
||||
$upload->delete();
|
||||
$msg = _(
|
||||
'Max notice size is %d chars, ' .
|
||||
'including attachment URL.'
|
||||
);
|
||||
// TRANS: Client error displayed exceeding the maximum notice length.
|
||||
// TRANS: %d is the maximum lenth for a notice.
|
||||
$msg = _m('Maximum notice size is %d character, including attachment URL.',
|
||||
'Maximum notice size is %d characters, including attachment URL.',
|
||||
Notice::maxContent());
|
||||
$this->clientError(
|
||||
sprintf($msg, Notice::maxContent()),
|
||||
400,
|
||||
@ -344,7 +346,6 @@ class ApiStatusesUpdateAction extends ApiAuthAction
|
||||
if (isset($upload)) {
|
||||
$upload->attachToNotice($this->notice);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
$this->showNotice();
|
||||
@ -355,7 +356,6 @@ class ApiStatusesUpdateAction extends ApiAuthAction
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
|
||||
function showNotice()
|
||||
{
|
||||
if (!empty($this->notice)) {
|
||||
@ -374,7 +374,6 @@ class ApiStatusesUpdateAction extends ApiAuthAction
|
||||
*
|
||||
* @return boolean true or false
|
||||
*/
|
||||
|
||||
function supported($cmd)
|
||||
{
|
||||
static $cmdlist = array('MessageCommand', 'SubCommand', 'UnsubCommand',
|
||||
@ -386,5 +385,4 @@ class ApiStatusesUpdateAction extends ApiAuthAction
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -46,7 +46,6 @@ if (!defined('STATUSNET')) {
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||
* @link http://status.net/
|
||||
*/
|
||||
|
||||
class ApiStatusnetConfigAction extends ApiAction
|
||||
{
|
||||
var $keys = array(
|
||||
@ -69,9 +68,7 @@ class ApiStatusnetConfigAction extends ApiAction
|
||||
* @param array $args $_REQUEST args
|
||||
*
|
||||
* @return boolean success flag
|
||||
*
|
||||
*/
|
||||
|
||||
function prepare($args)
|
||||
{
|
||||
parent::prepare($args);
|
||||
@ -85,7 +82,6 @@ class ApiStatusnetConfigAction extends ApiAction
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
|
||||
function handle($args)
|
||||
{
|
||||
parent::handle($args);
|
||||
@ -138,6 +134,7 @@ class ApiStatusnetConfigAction extends ApiAction
|
||||
break;
|
||||
default:
|
||||
$this->clientError(
|
||||
// TRANS: Client error displayed when trying to handle an unknown API method.
|
||||
_('API method not found.'),
|
||||
404,
|
||||
$this->format
|
||||
@ -155,11 +152,8 @@ class ApiStatusnetConfigAction extends ApiAction
|
||||
*
|
||||
* @return boolean is read only action?
|
||||
*/
|
||||
|
||||
function isReadOnly($args)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
@ -47,7 +47,6 @@ require_once INSTALLDIR . '/lib/apiprivateauth.php';
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||
* @link http://status.net/
|
||||
*/
|
||||
|
||||
class ApiStatusnetVersionAction extends ApiPrivateAuthAction
|
||||
{
|
||||
/**
|
||||
@ -58,7 +57,6 @@ class ApiStatusnetVersionAction extends ApiPrivateAuthAction
|
||||
* @return boolean success flag
|
||||
*
|
||||
*/
|
||||
|
||||
function prepare($args)
|
||||
{
|
||||
parent::prepare($args);
|
||||
@ -72,7 +70,6 @@ class ApiStatusnetVersionAction extends ApiPrivateAuthAction
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
|
||||
function handle($args)
|
||||
{
|
||||
parent::handle($args);
|
||||
@ -90,6 +87,7 @@ class ApiStatusnetVersionAction extends ApiPrivateAuthAction
|
||||
break;
|
||||
default:
|
||||
$this->clientError(
|
||||
// TRANS: Client error displayed when trying to handle an unknown API method.
|
||||
_('API method not found.'),
|
||||
404,
|
||||
$this->format
|
||||
@ -107,11 +105,8 @@ class ApiStatusnetVersionAction extends ApiPrivateAuthAction
|
||||
*
|
||||
* @return boolean is read only action?
|
||||
*/
|
||||
|
||||
function isReadOnly($args)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
@ -48,7 +48,6 @@ require_once INSTALLDIR . '/lib/apibareauth.php';
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||
* @link http://status.net/
|
||||
*/
|
||||
|
||||
class ApiSubscriptionsAction extends ApiBareAuthAction
|
||||
{
|
||||
var $profiles = null;
|
||||
@ -62,9 +61,7 @@ class ApiSubscriptionsAction extends ApiBareAuthAction
|
||||
* @param array $args $_REQUEST args
|
||||
*
|
||||
* @return boolean success flag
|
||||
*
|
||||
*/
|
||||
|
||||
function prepare($args)
|
||||
{
|
||||
parent::prepare($args);
|
||||
@ -84,6 +81,7 @@ class ApiSubscriptionsAction extends ApiBareAuthAction
|
||||
$this->user = $this->getTargetUser($this->arg('id'));
|
||||
|
||||
if (empty($this->user)) {
|
||||
// TRANS: Client error displayed when requesting a list of followers for a non-existing user.
|
||||
$this->clientError(_('No such user.'), 404, $this->format);
|
||||
return false;
|
||||
}
|
||||
@ -102,12 +100,12 @@ class ApiSubscriptionsAction extends ApiBareAuthAction
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
|
||||
function handle($args)
|
||||
{
|
||||
parent::handle($args);
|
||||
|
||||
if (!in_array($this->format, array('xml', 'json'))) {
|
||||
// TRANS: Client error displayed when trying to handle an unknown API method.
|
||||
$this->clientError(_('API method not found.'), $code = 404);
|
||||
return;
|
||||
}
|
||||
@ -128,7 +126,6 @@ class ApiSubscriptionsAction extends ApiBareAuthAction
|
||||
*
|
||||
* @return array Profiles
|
||||
*/
|
||||
|
||||
function getProfiles()
|
||||
{
|
||||
}
|
||||
@ -140,7 +137,6 @@ class ApiSubscriptionsAction extends ApiBareAuthAction
|
||||
*
|
||||
* @return boolean true
|
||||
*/
|
||||
|
||||
function isReadOnly($args)
|
||||
{
|
||||
return true;
|
||||
@ -151,7 +147,6 @@ class ApiSubscriptionsAction extends ApiBareAuthAction
|
||||
*
|
||||
* @return string datestamp of the latest profile in the stream
|
||||
*/
|
||||
|
||||
function lastModified()
|
||||
{
|
||||
if (!empty($this->profiles) && (count($this->profiles) > 0)) {
|
||||
@ -171,7 +166,6 @@ class ApiSubscriptionsAction extends ApiBareAuthAction
|
||||
*
|
||||
* @return string etag
|
||||
*/
|
||||
|
||||
function etag()
|
||||
{
|
||||
if (!empty($this->profiles) && (count($this->profiles) > 0)) {
|
||||
@ -181,8 +175,10 @@ class ApiSubscriptionsAction extends ApiBareAuthAction
|
||||
return '"' . implode(
|
||||
':',
|
||||
array($this->arg('action'),
|
||||
common_user_cache_hash($this->auth_user),
|
||||
common_language(),
|
||||
$this->user->id,
|
||||
// Caching tags.
|
||||
isset($this->ids_only) ? 'IDs' : 'Profiles',
|
||||
strtotime($this->profiles[0]->created),
|
||||
strtotime($this->profiles[$last]->created))
|
||||
@ -201,7 +197,6 @@ class ApiSubscriptionsAction extends ApiBareAuthAction
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
|
||||
function showProfiles($include_statuses = true)
|
||||
{
|
||||
switch ($this->format) {
|
||||
@ -229,6 +224,7 @@ class ApiSubscriptionsAction extends ApiBareAuthAction
|
||||
print json_encode($arrays);
|
||||
break;
|
||||
default:
|
||||
// TRANS: Client error displayed when requesting profiles of followers in an unsupported format.
|
||||
$this->clientError(_('Unsupported format.'));
|
||||
break;
|
||||
}
|
||||
@ -240,7 +236,6 @@ class ApiSubscriptionsAction extends ApiBareAuthAction
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
|
||||
function showIds()
|
||||
{
|
||||
switch ($this->format) {
|
||||
@ -259,9 +254,9 @@ class ApiSubscriptionsAction extends ApiBareAuthAction
|
||||
print json_encode($ids);
|
||||
break;
|
||||
default:
|
||||
// TRANS: Client error displayed when requesting IDs of followers in an unsupported format.
|
||||
$this->clientError(_('Unsupported format.'));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -48,7 +48,6 @@ require_once INSTALLDIR.'/lib/apibareauth.php';
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||
* @link http://status.net/
|
||||
*/
|
||||
|
||||
class ApiTimelineFavoritesAction extends ApiBareAuthAction
|
||||
{
|
||||
var $notices = null;
|
||||
@ -59,9 +58,7 @@ class ApiTimelineFavoritesAction extends ApiBareAuthAction
|
||||
* @param array $args $_REQUEST args
|
||||
*
|
||||
* @return boolean success flag
|
||||
*
|
||||
*/
|
||||
|
||||
function prepare($args)
|
||||
{
|
||||
parent::prepare($args);
|
||||
@ -69,6 +66,7 @@ class ApiTimelineFavoritesAction extends ApiBareAuthAction
|
||||
$this->user = $this->getTargetUser($this->arg('id'));
|
||||
|
||||
if (empty($this->user)) {
|
||||
// TRANS: Client error displayed when requesting most recent favourite notices by a user for a non-existing user.
|
||||
$this->clientError(_('No such user.'), 404, $this->format);
|
||||
return;
|
||||
}
|
||||
@ -87,7 +85,6 @@ class ApiTimelineFavoritesAction extends ApiBareAuthAction
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
|
||||
function handle($args)
|
||||
{
|
||||
parent::handle($args);
|
||||
@ -99,7 +96,6 @@ class ApiTimelineFavoritesAction extends ApiBareAuthAction
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
|
||||
function showTimeline()
|
||||
{
|
||||
$profile = $this->user->getProfile();
|
||||
@ -107,6 +103,8 @@ class ApiTimelineFavoritesAction extends ApiBareAuthAction
|
||||
|
||||
$sitename = common_config('site', 'name');
|
||||
$title = sprintf(
|
||||
// TRANS: Title for timeline of most recent favourite notices by a user.
|
||||
// TRANS: %1$s is the StatusNet sitename, %2$s is a user nickname.
|
||||
_('%1$s / Favorites from %2$s'),
|
||||
$sitename,
|
||||
$this->user->nickname
|
||||
@ -116,7 +114,10 @@ class ApiTimelineFavoritesAction extends ApiBareAuthAction
|
||||
$id = "tag:$taguribase:Favorites:" . $this->user->id;
|
||||
|
||||
$subtitle = sprintf(
|
||||
_('%1$s updates favorited by %2$s / %2$s.'),
|
||||
// TRANS: Subtitle for timeline of most recent favourite notices by a user.
|
||||
// TRANS: %1$s is the StatusNet sitename, %2$s is a user's full name,
|
||||
// TRANS: %3$s is a user nickname.
|
||||
_('%1$s updates favorited by %2$s / %3$s.'),
|
||||
$sitename,
|
||||
$profile->getBestName(),
|
||||
$this->user->nickname
|
||||
@ -148,7 +149,6 @@ class ApiTimelineFavoritesAction extends ApiBareAuthAction
|
||||
);
|
||||
break;
|
||||
case 'atom':
|
||||
|
||||
header('Content-Type: application/atom+xml; charset=utf-8');
|
||||
|
||||
$atom = new AtomNoticeFeed($this->auth_user);
|
||||
@ -165,12 +165,12 @@ class ApiTimelineFavoritesAction extends ApiBareAuthAction
|
||||
$atom->addEntryFromNotices($this->notices);
|
||||
|
||||
$this->raw($atom->getString());
|
||||
|
||||
break;
|
||||
case 'json':
|
||||
$this->showJsonTimeline($this->notices);
|
||||
break;
|
||||
default:
|
||||
// TRANS: Client error displayed when trying to handle an unknown API method.
|
||||
$this->clientError(_('API method not found.'), $code = 404);
|
||||
break;
|
||||
}
|
||||
@ -181,7 +181,6 @@ class ApiTimelineFavoritesAction extends ApiBareAuthAction
|
||||
*
|
||||
* @return array notices
|
||||
*/
|
||||
|
||||
function getNotices()
|
||||
{
|
||||
$notices = array();
|
||||
@ -220,7 +219,6 @@ class ApiTimelineFavoritesAction extends ApiBareAuthAction
|
||||
*
|
||||
* @return boolean true
|
||||
*/
|
||||
|
||||
function isReadOnly($args)
|
||||
{
|
||||
return true;
|
||||
@ -231,7 +229,6 @@ class ApiTimelineFavoritesAction extends ApiBareAuthAction
|
||||
*
|
||||
* @return string datestamp of the latest notice in the stream
|
||||
*/
|
||||
|
||||
function lastModified()
|
||||
{
|
||||
if (!empty($this->notices) && (count($this->notices) > 0)) {
|
||||
@ -249,7 +246,6 @@ class ApiTimelineFavoritesAction extends ApiBareAuthAction
|
||||
*
|
||||
* @return string etag
|
||||
*/
|
||||
|
||||
function etag()
|
||||
{
|
||||
if (!empty($this->notices) && (count($this->notices) > 0)) {
|
||||
@ -259,6 +255,7 @@ class ApiTimelineFavoritesAction extends ApiBareAuthAction
|
||||
return '"' . implode(
|
||||
':',
|
||||
array($this->arg('action'),
|
||||
common_user_cache_hash($this->auth_user),
|
||||
common_language(),
|
||||
$this->user->id,
|
||||
strtotime($this->notices[0]->created),
|
||||
@ -269,5 +266,4 @@ class ApiTimelineFavoritesAction extends ApiBareAuthAction
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -151,7 +151,6 @@ require_once INSTALLDIR . '/lib/apibareauth.php';
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||
* @link http://status.net/
|
||||
*/
|
||||
|
||||
class ApiTimelineFriendsAction extends ApiBareAuthAction
|
||||
{
|
||||
var $notices = null;
|
||||
@ -164,13 +163,13 @@ class ApiTimelineFriendsAction extends ApiBareAuthAction
|
||||
* @return boolean success flag
|
||||
*
|
||||
*/
|
||||
|
||||
function prepare($args)
|
||||
{
|
||||
parent::prepare($args);
|
||||
$this->user = $this->getTargetUser($this->arg('id'));
|
||||
|
||||
if (empty($this->user)) {
|
||||
// TRANS: Client error displayed when requesting dents of a user and friends for a user that does not exist.
|
||||
$this->clientError(_('No such user.'), 404, $this->format);
|
||||
return;
|
||||
}
|
||||
@ -189,7 +188,6 @@ class ApiTimelineFriendsAction extends ApiBareAuthAction
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
|
||||
function handle($args)
|
||||
{
|
||||
parent::handle($args);
|
||||
@ -201,7 +199,6 @@ class ApiTimelineFriendsAction extends ApiBareAuthAction
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
|
||||
function showTimeline()
|
||||
{
|
||||
$profile = $this->user->getProfile();
|
||||
@ -246,7 +243,6 @@ class ApiTimelineFriendsAction extends ApiBareAuthAction
|
||||
);
|
||||
break;
|
||||
case 'atom':
|
||||
|
||||
header('Content-Type: application/atom+xml; charset=utf-8');
|
||||
|
||||
$atom = new AtomNoticeFeed($this->auth_user);
|
||||
@ -268,6 +264,7 @@ class ApiTimelineFriendsAction extends ApiBareAuthAction
|
||||
$this->showJsonTimeline($this->notices);
|
||||
break;
|
||||
default:
|
||||
// TRANS: Client error displayed when trying to handle an unknown API method.
|
||||
$this->clientError(_('API method not found.'), $code = 404);
|
||||
break;
|
||||
}
|
||||
@ -278,7 +275,6 @@ class ApiTimelineFriendsAction extends ApiBareAuthAction
|
||||
*
|
||||
* @return array notices
|
||||
*/
|
||||
|
||||
function getNotices()
|
||||
{
|
||||
$notices = array();
|
||||
@ -307,7 +303,6 @@ class ApiTimelineFriendsAction extends ApiBareAuthAction
|
||||
*
|
||||
* @return boolean true
|
||||
*/
|
||||
|
||||
function isReadOnly($args)
|
||||
{
|
||||
return true;
|
||||
@ -318,7 +313,6 @@ class ApiTimelineFriendsAction extends ApiBareAuthAction
|
||||
*
|
||||
* @return string datestamp of the latest notice in the stream
|
||||
*/
|
||||
|
||||
function lastModified()
|
||||
{
|
||||
if (!empty($this->notices) && (count($this->notices) > 0)) {
|
||||
@ -336,16 +330,15 @@ class ApiTimelineFriendsAction extends ApiBareAuthAction
|
||||
*
|
||||
* @return string etag
|
||||
*/
|
||||
|
||||
function etag()
|
||||
{
|
||||
if (!empty($this->notices) && (count($this->notices) > 0)) {
|
||||
|
||||
$last = count($this->notices) - 1;
|
||||
|
||||
return '"' . implode(
|
||||
':',
|
||||
array($this->arg('action'),
|
||||
common_user_cache_hash($this->auth_user),
|
||||
common_language(),
|
||||
$this->user->id,
|
||||
strtotime($this->notices[0]->created),
|
||||
@ -356,5 +349,4 @@ class ApiTimelineFriendsAction extends ApiBareAuthAction
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -49,10 +49,8 @@ require_once INSTALLDIR . '/lib/apiprivateauth.php';
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||
* @link http://status.net/
|
||||
*/
|
||||
|
||||
class ApiTimelineGroupAction extends ApiPrivateAuthAction
|
||||
{
|
||||
|
||||
var $group = null;
|
||||
var $notices = null;
|
||||
|
||||
@ -64,7 +62,6 @@ class ApiTimelineGroupAction extends ApiPrivateAuthAction
|
||||
* @return boolean success flag
|
||||
*
|
||||
*/
|
||||
|
||||
function prepare($args)
|
||||
{
|
||||
parent::prepare($args);
|
||||
@ -83,12 +80,12 @@ class ApiTimelineGroupAction extends ApiPrivateAuthAction
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
|
||||
function handle($args)
|
||||
{
|
||||
parent::handle($args);
|
||||
|
||||
if (empty($this->group)) {
|
||||
// TRANS: Client error displayed requesting most recent notices to a group for a non-existing group.
|
||||
$this->clientError(_('Group not found.'), 404, $this->format);
|
||||
return false;
|
||||
}
|
||||
@ -102,7 +99,6 @@ class ApiTimelineGroupAction extends ApiPrivateAuthAction
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
|
||||
function showTimeline()
|
||||
{
|
||||
// We'll pull common formatting out of this for other formats
|
||||
@ -126,7 +122,6 @@ class ApiTimelineGroupAction extends ApiPrivateAuthAction
|
||||
);
|
||||
break;
|
||||
case 'atom':
|
||||
|
||||
header('Content-Type: application/atom+xml; charset=utf-8');
|
||||
|
||||
try {
|
||||
@ -138,19 +133,21 @@ class ApiTimelineGroupAction extends ApiPrivateAuthAction
|
||||
$this->raw($atom->getString());
|
||||
} catch (Atom10FeedException $e) {
|
||||
$this->serverError(
|
||||
'Could not generate feed for group - ' . $e->getMessage(),
|
||||
// TRANS: Server error displayed when generating an Atom feed fails.
|
||||
// TRANS: %s is the error.
|
||||
sprintf(_('Could not generate feed for group - %s'),$e->getMessage()),
|
||||
400,
|
||||
$this->format
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
break;
|
||||
case 'json':
|
||||
$this->showJsonTimeline($this->notices);
|
||||
break;
|
||||
default:
|
||||
$this->clientError(
|
||||
// TRANS: Client error displayed when trying to handle an unknown API method.
|
||||
_('API method not found.'),
|
||||
404,
|
||||
$this->format
|
||||
@ -164,7 +161,6 @@ class ApiTimelineGroupAction extends ApiPrivateAuthAction
|
||||
*
|
||||
* @return array notices
|
||||
*/
|
||||
|
||||
function getNotices()
|
||||
{
|
||||
$notices = array();
|
||||
@ -190,7 +186,6 @@ class ApiTimelineGroupAction extends ApiPrivateAuthAction
|
||||
*
|
||||
* @return boolean true
|
||||
*/
|
||||
|
||||
function isReadOnly($args)
|
||||
{
|
||||
return true;
|
||||
@ -201,7 +196,6 @@ class ApiTimelineGroupAction extends ApiPrivateAuthAction
|
||||
*
|
||||
* @return string datestamp of the latest notice in the stream
|
||||
*/
|
||||
|
||||
function lastModified()
|
||||
{
|
||||
if (!empty($this->notices) && (count($this->notices) > 0)) {
|
||||
@ -219,7 +213,6 @@ class ApiTimelineGroupAction extends ApiPrivateAuthAction
|
||||
*
|
||||
* @return string etag
|
||||
*/
|
||||
|
||||
function etag()
|
||||
{
|
||||
if (!empty($this->notices) && (count($this->notices) > 0)) {
|
||||
@ -229,6 +222,7 @@ class ApiTimelineGroupAction extends ApiPrivateAuthAction
|
||||
return '"' . implode(
|
||||
':',
|
||||
array($this->arg('action'),
|
||||
common_user_cache_hash($this->auth_user),
|
||||
common_language(),
|
||||
$this->group->id,
|
||||
strtotime($this->notices[0]->created),
|
||||
@ -239,5 +233,4 @@ class ApiTimelineGroupAction extends ApiPrivateAuthAction
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -56,7 +56,6 @@ require_once INSTALLDIR . '/lib/apibareauth.php';
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||
* @link http://status.net/
|
||||
*/
|
||||
|
||||
class ApiTimelineHomeAction extends ApiBareAuthAction
|
||||
{
|
||||
var $notices = null;
|
||||
@ -67,9 +66,7 @@ class ApiTimelineHomeAction extends ApiBareAuthAction
|
||||
* @param array $args $_REQUEST args
|
||||
*
|
||||
* @return boolean success flag
|
||||
*
|
||||
*/
|
||||
|
||||
function prepare($args)
|
||||
{
|
||||
parent::prepare($args);
|
||||
@ -77,6 +74,7 @@ class ApiTimelineHomeAction extends ApiBareAuthAction
|
||||
$this->user = $this->getTargetUser($this->arg('id'));
|
||||
|
||||
if (empty($this->user)) {
|
||||
// TRANS: Client error displayed when requesting most recent dents by user and friends for a non-existing user.
|
||||
$this->clientError(_('No such user.'), 404, $this->format);
|
||||
return;
|
||||
}
|
||||
@ -95,7 +93,6 @@ class ApiTimelineHomeAction extends ApiBareAuthAction
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
|
||||
function handle($args)
|
||||
{
|
||||
parent::handle($args);
|
||||
@ -107,12 +104,12 @@ class ApiTimelineHomeAction extends ApiBareAuthAction
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
|
||||
function showTimeline()
|
||||
{
|
||||
$profile = $this->user->getProfile();
|
||||
$avatar = $profile->getAvatar(AVATAR_PROFILE_SIZE);
|
||||
$sitename = common_config('site', 'name');
|
||||
// TRANS: Timeline title for user and friends. %s is a user nickname.
|
||||
$title = sprintf(_("%s and friends"), $this->user->nickname);
|
||||
$taguribase = TagURI::base();
|
||||
$id = "tag:$taguribase:HomeTimeline:" . $this->user->id;
|
||||
@ -172,6 +169,7 @@ class ApiTimelineHomeAction extends ApiBareAuthAction
|
||||
$this->showJsonTimeline($this->notices);
|
||||
break;
|
||||
default:
|
||||
// TRANS: Client error displayed when trying to handle an unknown API method.
|
||||
$this->clientError(_('API method not found.'), $code = 404);
|
||||
break;
|
||||
}
|
||||
@ -182,7 +180,6 @@ class ApiTimelineHomeAction extends ApiBareAuthAction
|
||||
*
|
||||
* @return array notices
|
||||
*/
|
||||
|
||||
function getNotices()
|
||||
{
|
||||
$notices = array();
|
||||
@ -215,7 +212,6 @@ class ApiTimelineHomeAction extends ApiBareAuthAction
|
||||
*
|
||||
* @return boolean true
|
||||
*/
|
||||
|
||||
function isReadOnly($args)
|
||||
{
|
||||
return true;
|
||||
@ -226,7 +222,6 @@ class ApiTimelineHomeAction extends ApiBareAuthAction
|
||||
*
|
||||
* @return string datestamp of the latest notice in the stream
|
||||
*/
|
||||
|
||||
function lastModified()
|
||||
{
|
||||
if (!empty($this->notices) && (count($this->notices) > 0)) {
|
||||
@ -244,7 +239,6 @@ class ApiTimelineHomeAction extends ApiBareAuthAction
|
||||
*
|
||||
* @return string etag
|
||||
*/
|
||||
|
||||
function etag()
|
||||
{
|
||||
if (!empty($this->notices) && (count($this->notices) > 0)) {
|
||||
@ -254,6 +248,7 @@ class ApiTimelineHomeAction extends ApiBareAuthAction
|
||||
return '"' . implode(
|
||||
':',
|
||||
array($this->arg('action'),
|
||||
common_user_cache_hash($this->auth_user),
|
||||
common_language(),
|
||||
$this->user->id,
|
||||
strtotime($this->notices[0]->created),
|
||||
@ -264,5 +259,4 @@ class ApiTimelineHomeAction extends ApiBareAuthAction
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -55,10 +55,8 @@ require_once INSTALLDIR . '/lib/apibareauth.php';
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||
* @link http://status.net/
|
||||
*/
|
||||
|
||||
class ApiTimelineMentionsAction extends ApiBareAuthAction
|
||||
{
|
||||
|
||||
var $notices = null;
|
||||
|
||||
/**
|
||||
@ -67,9 +65,7 @@ class ApiTimelineMentionsAction extends ApiBareAuthAction
|
||||
* @param array $args $_REQUEST args
|
||||
*
|
||||
* @return boolean success flag
|
||||
*
|
||||
*/
|
||||
|
||||
function prepare($args)
|
||||
{
|
||||
parent::prepare($args);
|
||||
@ -77,6 +73,7 @@ class ApiTimelineMentionsAction extends ApiBareAuthAction
|
||||
$this->user = $this->getTargetUser($this->arg('id'));
|
||||
|
||||
if (empty($this->user)) {
|
||||
// TRANS: Client error displayed when requesting most recent mentions for a non-existing user.
|
||||
$this->clientError(_('No such user.'), 404, $this->format);
|
||||
return;
|
||||
}
|
||||
@ -95,7 +92,6 @@ class ApiTimelineMentionsAction extends ApiBareAuthAction
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
|
||||
function handle($args)
|
||||
{
|
||||
parent::handle($args);
|
||||
@ -107,7 +103,6 @@ class ApiTimelineMentionsAction extends ApiBareAuthAction
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
|
||||
function showTimeline()
|
||||
{
|
||||
$profile = $this->user->getProfile();
|
||||
@ -115,6 +110,8 @@ class ApiTimelineMentionsAction extends ApiBareAuthAction
|
||||
|
||||
$sitename = common_config('site', 'name');
|
||||
$title = sprintf(
|
||||
// TRANS: Title for timeline of most recent mentions of a user.
|
||||
// TRANS: %1$s is the StatusNet sitename, %2$s is a user nickname.
|
||||
_('%1$s / Updates mentioning %2$s'),
|
||||
$sitename, $this->user->nickname
|
||||
);
|
||||
@ -128,6 +125,9 @@ class ApiTimelineMentionsAction extends ApiBareAuthAction
|
||||
$self = $this->getSelfUri();
|
||||
|
||||
$subtitle = sprintf(
|
||||
// TRANS: Subtitle for timeline of most recent mentions of a user.
|
||||
// TRANS: %1$s is the StatusNet sitename, %2$s is a user nickname,
|
||||
// TRANS: %3$s is a user's full name.
|
||||
_('%1$s updates that reply to updates from %2$s / %3$s.'),
|
||||
$sitename, $this->user->nickname, $profile->getBestName()
|
||||
);
|
||||
@ -149,7 +149,6 @@ class ApiTimelineMentionsAction extends ApiBareAuthAction
|
||||
);
|
||||
break;
|
||||
case 'atom':
|
||||
|
||||
header('Content-Type: application/atom+xml; charset=utf-8');
|
||||
|
||||
$atom = new AtomNoticeFeed($this->auth_user);
|
||||
@ -171,6 +170,7 @@ class ApiTimelineMentionsAction extends ApiBareAuthAction
|
||||
$this->showJsonTimeline($this->notices);
|
||||
break;
|
||||
default:
|
||||
// TRANS: Client error displayed when trying to handle an unknown API method.
|
||||
$this->clientError(_('API method not found.'), $code = 404);
|
||||
break;
|
||||
}
|
||||
@ -181,7 +181,6 @@ class ApiTimelineMentionsAction extends ApiBareAuthAction
|
||||
*
|
||||
* @return array notices
|
||||
*/
|
||||
|
||||
function getNotices()
|
||||
{
|
||||
$notices = array();
|
||||
@ -205,7 +204,6 @@ class ApiTimelineMentionsAction extends ApiBareAuthAction
|
||||
*
|
||||
* @return boolean true
|
||||
*/
|
||||
|
||||
function isReadOnly($args)
|
||||
{
|
||||
return true;
|
||||
@ -216,7 +214,6 @@ class ApiTimelineMentionsAction extends ApiBareAuthAction
|
||||
*
|
||||
* @return string datestamp of the latest notice in the stream
|
||||
*/
|
||||
|
||||
function lastModified()
|
||||
{
|
||||
if (!empty($this->notices) && (count($this->notices) > 0)) {
|
||||
@ -234,7 +231,6 @@ class ApiTimelineMentionsAction extends ApiBareAuthAction
|
||||
*
|
||||
* @return string etag
|
||||
*/
|
||||
|
||||
function etag()
|
||||
{
|
||||
if (!empty($this->notices) && (count($this->notices) > 0)) {
|
||||
@ -244,6 +240,7 @@ class ApiTimelineMentionsAction extends ApiBareAuthAction
|
||||
return '"' . implode(
|
||||
':',
|
||||
array($this->arg('action'),
|
||||
common_user_cache_hash($this->auth_user),
|
||||
common_language(),
|
||||
$this->user->id,
|
||||
strtotime($this->notices[0]->created),
|
||||
@ -254,5 +251,4 @@ class ApiTimelineMentionsAction extends ApiBareAuthAction
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -144,10 +144,8 @@ require_once INSTALLDIR . '/lib/apiprivateauth.php';
|
||||
</statuses>
|
||||
@endverbatim
|
||||
*/
|
||||
|
||||
class ApiTimelinePublicAction extends ApiPrivateAuthAction
|
||||
{
|
||||
|
||||
var $notices = null;
|
||||
|
||||
/**
|
||||
@ -158,7 +156,6 @@ class ApiTimelinePublicAction extends ApiPrivateAuthAction
|
||||
* @return boolean success flag
|
||||
*
|
||||
*/
|
||||
|
||||
function prepare($args)
|
||||
{
|
||||
parent::prepare($args);
|
||||
@ -177,7 +174,6 @@ class ApiTimelinePublicAction extends ApiPrivateAuthAction
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
|
||||
function handle($args)
|
||||
{
|
||||
parent::handle($args);
|
||||
@ -189,16 +185,17 @@ class ApiTimelinePublicAction extends ApiPrivateAuthAction
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
|
||||
function showTimeline()
|
||||
{
|
||||
$sitename = common_config('site', 'name');
|
||||
$sitelogo = (common_config('site', 'logo')) ? common_config('site', 'logo') : Theme::path('logo.png');
|
||||
// TRANS: Title for site timeline. %s is the StatusNet sitename.
|
||||
$title = sprintf(_("%s public timeline"), $sitename);
|
||||
$taguribase = TagURI::base();
|
||||
$id = "tag:$taguribase:PublicTimeline";
|
||||
$link = common_local_url('public');
|
||||
$self = $this->getSelfUri();
|
||||
// TRANS: Subtitle for site timeline. %s is the StatusNet sitename.
|
||||
$subtitle = sprintf(_("%s updates from everyone!"), $sitename);
|
||||
|
||||
switch($this->format) {
|
||||
@ -238,6 +235,7 @@ class ApiTimelinePublicAction extends ApiPrivateAuthAction
|
||||
$this->showJsonTimeline($this->notices);
|
||||
break;
|
||||
default:
|
||||
// TRANS: Client error displayed when trying to handle an unknown API method.
|
||||
$this->clientError(_('API method not found.'), $code = 404);
|
||||
break;
|
||||
}
|
||||
@ -248,7 +246,6 @@ class ApiTimelinePublicAction extends ApiPrivateAuthAction
|
||||
*
|
||||
* @return array notices
|
||||
*/
|
||||
|
||||
function getNotices()
|
||||
{
|
||||
$notices = array();
|
||||
@ -272,7 +269,6 @@ class ApiTimelinePublicAction extends ApiPrivateAuthAction
|
||||
*
|
||||
* @return boolean true
|
||||
*/
|
||||
|
||||
function isReadOnly($args)
|
||||
{
|
||||
return true;
|
||||
@ -283,7 +279,6 @@ class ApiTimelinePublicAction extends ApiPrivateAuthAction
|
||||
*
|
||||
* @return string datestamp of the latest notice in the stream
|
||||
*/
|
||||
|
||||
function lastModified()
|
||||
{
|
||||
if (!empty($this->notices) && (count($this->notices) > 0)) {
|
||||
@ -301,7 +296,6 @@ class ApiTimelinePublicAction extends ApiPrivateAuthAction
|
||||
*
|
||||
* @return string etag
|
||||
*/
|
||||
|
||||
function etag()
|
||||
{
|
||||
if (!empty($this->notices) && (count($this->notices) > 0)) {
|
||||
@ -311,6 +305,7 @@ class ApiTimelinePublicAction extends ApiPrivateAuthAction
|
||||
return '"' . implode(
|
||||
':',
|
||||
array($this->arg('action'),
|
||||
common_user_cache_hash($this->auth_user),
|
||||
common_language(),
|
||||
strtotime($this->notices[0]->created),
|
||||
strtotime($this->notices[$last]->created))
|
||||
@ -320,5 +315,4 @@ class ApiTimelinePublicAction extends ApiPrivateAuthAction
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -43,7 +43,6 @@ require_once INSTALLDIR . '/lib/mediafile.php';
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||
* @link http://status.net/
|
||||
*/
|
||||
|
||||
class ApiTimelineRetweetedByMeAction extends ApiAuthAction
|
||||
{
|
||||
const DEFAULTCOUNT = 20;
|
||||
@ -64,12 +63,12 @@ class ApiTimelineRetweetedByMeAction extends ApiAuthAction
|
||||
* @return boolean success flag
|
||||
*
|
||||
*/
|
||||
|
||||
function prepare($args)
|
||||
{
|
||||
parent::prepare($args);
|
||||
|
||||
$this->serverError('Unimplemented.', 503);
|
||||
// TRANS: Server error displayed calling unimplemented API method for 'retweeted by me'.
|
||||
$this->serverError(_('Unimplemented.'), 503);
|
||||
|
||||
return false;
|
||||
}
|
||||
@ -81,7 +80,6 @@ class ApiTimelineRetweetedByMeAction extends ApiAuthAction
|
||||
*
|
||||
* @return boolean is read only action?
|
||||
*/
|
||||
|
||||
function isReadOnly($args)
|
||||
{
|
||||
return true;
|
||||
|
@ -42,7 +42,6 @@ require_once INSTALLDIR . '/lib/apiauth.php';
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||
* @link http://status.net/
|
||||
*/
|
||||
|
||||
class ApiTimelineRetweetedToMeAction extends ApiAuthAction
|
||||
{
|
||||
const DEFAULTCOUNT = 20;
|
||||
@ -61,9 +60,7 @@ class ApiTimelineRetweetedToMeAction extends ApiAuthAction
|
||||
* @param array $args $_REQUEST args
|
||||
*
|
||||
* @return boolean success flag
|
||||
*
|
||||
*/
|
||||
|
||||
function prepare($args)
|
||||
{
|
||||
parent::prepare($args);
|
||||
@ -88,7 +85,6 @@ class ApiTimelineRetweetedToMeAction extends ApiAuthAction
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
|
||||
function handle($args)
|
||||
{
|
||||
parent::handle($args);
|
||||
@ -108,6 +104,7 @@ class ApiTimelineRetweetedToMeAction extends ApiAuthAction
|
||||
case 'atom':
|
||||
$profile = $this->auth_user->getProfile();
|
||||
|
||||
// TRANS: Title for Atom feed "repeated to me". %s is the user nickname.
|
||||
$title = sprintf(_("Repeated to %s"), $this->auth_user->nickname);
|
||||
$taguribase = TagURI::base();
|
||||
$id = "tag:$taguribase:RepeatedToMe:" . $this->auth_user->id;
|
||||
@ -116,8 +113,8 @@ class ApiTimelineRetweetedToMeAction extends ApiAuthAction
|
||||
|
||||
$this->showAtomTimeline($strm, $title, $id, $link);
|
||||
break;
|
||||
|
||||
default:
|
||||
// TRANS: Client error displayed when trying to handle an unknown API method.
|
||||
$this->clientError(_('API method not found.'), $code = 404);
|
||||
break;
|
||||
}
|
||||
@ -132,7 +129,6 @@ class ApiTimelineRetweetedToMeAction extends ApiAuthAction
|
||||
*
|
||||
* @return boolean is read only action?
|
||||
*/
|
||||
|
||||
function isReadOnly($args)
|
||||
{
|
||||
return true;
|
||||
|
@ -43,7 +43,6 @@ require_once INSTALLDIR . '/lib/mediafile.php';
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||
* @link http://status.net/
|
||||
*/
|
||||
|
||||
class ApiTimelineRetweetsOfMeAction extends ApiAuthAction
|
||||
{
|
||||
const DEFAULTCOUNT = 20;
|
||||
@ -62,9 +61,7 @@ class ApiTimelineRetweetsOfMeAction extends ApiAuthAction
|
||||
* @param array $args $_REQUEST args
|
||||
*
|
||||
* @return boolean success flag
|
||||
*
|
||||
*/
|
||||
|
||||
function prepare($args)
|
||||
{
|
||||
parent::prepare($args);
|
||||
@ -89,7 +86,6 @@ class ApiTimelineRetweetsOfMeAction extends ApiAuthAction
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
|
||||
function handle($args)
|
||||
{
|
||||
parent::handle($args);
|
||||
@ -111,6 +107,8 @@ class ApiTimelineRetweetsOfMeAction extends ApiAuthAction
|
||||
case 'atom':
|
||||
$profile = $this->auth_user->getProfile();
|
||||
|
||||
// TRANS: Title of list of repeated notices of the logged in user.
|
||||
// TRANS: %s is the nickname of the logged in user.
|
||||
$title = sprintf(_("Repeats of %s"), $this->auth_user->nickname);
|
||||
$taguribase = TagURI::base();
|
||||
$id = "tag:$taguribase:RepeatsOfMe:" . $this->auth_user->id;
|
||||
@ -147,8 +145,8 @@ class ApiTimelineRetweetsOfMeAction extends ApiAuthAction
|
||||
$this->raw($atom->getString());
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
// TRANS: Client error displayed when trying to handle an unknown API method.
|
||||
$this->clientError(_('API method not found.'), $code = 404);
|
||||
break;
|
||||
}
|
||||
@ -163,7 +161,6 @@ class ApiTimelineRetweetsOfMeAction extends ApiAuthAction
|
||||
*
|
||||
* @return boolean is read only action?
|
||||
*/
|
||||
|
||||
function isReadOnly($args)
|
||||
{
|
||||
return true;
|
||||
|
@ -49,10 +49,8 @@ require_once INSTALLDIR . '/lib/apiprivateauth.php';
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||
* @link http://status.net/
|
||||
*/
|
||||
|
||||
class ApiTimelineTagAction extends ApiPrivateAuthAction
|
||||
{
|
||||
|
||||
var $notices = null;
|
||||
|
||||
/**
|
||||
@ -61,9 +59,7 @@ class ApiTimelineTagAction extends ApiPrivateAuthAction
|
||||
* @param array $args $_REQUEST args
|
||||
*
|
||||
* @return boolean success flag
|
||||
*
|
||||
*/
|
||||
|
||||
function prepare($args)
|
||||
{
|
||||
parent::prepare($args);
|
||||
@ -85,7 +81,6 @@ class ApiTimelineTagAction extends ApiPrivateAuthAction
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
|
||||
function handle($args)
|
||||
{
|
||||
parent::handle($args);
|
||||
@ -97,13 +92,16 @@ class ApiTimelineTagAction extends ApiPrivateAuthAction
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
|
||||
function showTimeline()
|
||||
{
|
||||
$sitename = common_config('site', 'name');
|
||||
$sitelogo = (common_config('site', 'logo')) ? common_config('site', 'logo') : Theme::path('logo.png');
|
||||
// TRANS: Title for timeline with lastest notices with a given tag.
|
||||
// TRANS: %s is the tag.
|
||||
$title = sprintf(_("Notices tagged with %s"), $this->tag);
|
||||
$subtitle = sprintf(
|
||||
// TRANS: Subtitle for timeline with lastest notices with a given tag.
|
||||
// TRANS: %1$s is the tag, $2$s is the StatusNet sitename.
|
||||
_('Updates tagged with %1$s on %2$s!'),
|
||||
$this->tag,
|
||||
$sitename
|
||||
@ -136,7 +134,6 @@ class ApiTimelineTagAction extends ApiPrivateAuthAction
|
||||
);
|
||||
break;
|
||||
case 'atom':
|
||||
|
||||
header('Content-Type: application/atom+xml; charset=utf-8');
|
||||
|
||||
$atom = new AtomNoticeFeed($this->auth_user);
|
||||
@ -158,6 +155,7 @@ class ApiTimelineTagAction extends ApiPrivateAuthAction
|
||||
$this->showJsonTimeline($this->notices);
|
||||
break;
|
||||
default:
|
||||
// TRANS: Client error displayed when trying to handle an unknown API method.
|
||||
$this->clientError(_('API method not found.'), $code = 404);
|
||||
break;
|
||||
}
|
||||
@ -168,7 +166,6 @@ class ApiTimelineTagAction extends ApiPrivateAuthAction
|
||||
*
|
||||
* @return array notices
|
||||
*/
|
||||
|
||||
function getNotices()
|
||||
{
|
||||
$notices = array();
|
||||
@ -193,7 +190,6 @@ class ApiTimelineTagAction extends ApiPrivateAuthAction
|
||||
*
|
||||
* @return boolean true
|
||||
*/
|
||||
|
||||
function isReadOnly($args)
|
||||
{
|
||||
return true;
|
||||
@ -204,7 +200,6 @@ class ApiTimelineTagAction extends ApiPrivateAuthAction
|
||||
*
|
||||
* @return string datestamp of the latest notice in the stream
|
||||
*/
|
||||
|
||||
function lastModified()
|
||||
{
|
||||
if (!empty($this->notices) && (count($this->notices) > 0)) {
|
||||
@ -222,7 +217,6 @@ class ApiTimelineTagAction extends ApiPrivateAuthAction
|
||||
*
|
||||
* @return string etag
|
||||
*/
|
||||
|
||||
function etag()
|
||||
{
|
||||
if (!empty($this->notices) && (count($this->notices) > 0)) {
|
||||
@ -232,6 +226,7 @@ class ApiTimelineTagAction extends ApiPrivateAuthAction
|
||||
return '"' . implode(
|
||||
':',
|
||||
array($this->arg('action'),
|
||||
common_user_cache_hash($this->auth_user),
|
||||
common_language(),
|
||||
$this->tag,
|
||||
strtotime($this->notices[0]->created),
|
||||
@ -242,5 +237,4 @@ class ApiTimelineTagAction extends ApiPrivateAuthAction
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -57,10 +57,8 @@ require_once INSTALLDIR . '/lib/apibareauth.php';
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||
* @link http://status.net/
|
||||
*/
|
||||
|
||||
class ApiTimelineUserAction extends ApiBareAuthAction
|
||||
{
|
||||
|
||||
var $notices = null;
|
||||
|
||||
/**
|
||||
@ -69,9 +67,7 @@ class ApiTimelineUserAction extends ApiBareAuthAction
|
||||
* @param array $args $_REQUEST args
|
||||
*
|
||||
* @return boolean success flag
|
||||
*
|
||||
*/
|
||||
|
||||
function prepare($args)
|
||||
{
|
||||
parent::prepare($args);
|
||||
@ -79,6 +75,7 @@ class ApiTimelineUserAction extends ApiBareAuthAction
|
||||
$this->user = $this->getTargetUser($this->arg('id'));
|
||||
|
||||
if (empty($this->user)) {
|
||||
// TRANS: Client error displayed requesting most recent notices for a non-existing user.
|
||||
$this->clientError(_('No such user.'), 404, $this->format);
|
||||
return;
|
||||
}
|
||||
@ -97,11 +94,15 @@ class ApiTimelineUserAction extends ApiBareAuthAction
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
|
||||
function handle($args)
|
||||
{
|
||||
parent::handle($args);
|
||||
$this->showTimeline();
|
||||
|
||||
if ($this->isPost()) {
|
||||
$this->handlePost();
|
||||
} else {
|
||||
$this->showTimeline();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -109,7 +110,6 @@ class ApiTimelineUserAction extends ApiBareAuthAction
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
|
||||
function showTimeline()
|
||||
{
|
||||
$profile = $this->user->getProfile();
|
||||
@ -119,9 +119,9 @@ class ApiTimelineUserAction extends ApiBareAuthAction
|
||||
$atom = new AtomUserNoticeFeed($this->user, $this->auth_user);
|
||||
|
||||
$link = common_local_url(
|
||||
'showstream',
|
||||
array('nickname' => $this->user->nickname)
|
||||
);
|
||||
'showstream',
|
||||
array('nickname' => $this->user->nickname)
|
||||
);
|
||||
|
||||
$self = $this->getSelfUri();
|
||||
|
||||
@ -137,21 +137,63 @@ class ApiTimelineUserAction extends ApiBareAuthAction
|
||||
break;
|
||||
case 'rss':
|
||||
$this->showRssTimeline(
|
||||
$this->notices,
|
||||
$atom->title,
|
||||
$link,
|
||||
$atom->subtitle,
|
||||
$suplink,
|
||||
$atom->logo,
|
||||
$self
|
||||
);
|
||||
$this->notices,
|
||||
$atom->title,
|
||||
$link,
|
||||
$atom->subtitle,
|
||||
$suplink,
|
||||
$atom->logo,
|
||||
$self
|
||||
);
|
||||
break;
|
||||
case 'atom':
|
||||
|
||||
header('Content-Type: application/atom+xml; charset=utf-8');
|
||||
|
||||
$atom->setId($self);
|
||||
$atom->setSelfLink($self);
|
||||
|
||||
// Add navigation links: next, prev, first
|
||||
// Note: we use IDs rather than pages for navigation; page boundaries
|
||||
// change too quickly!
|
||||
|
||||
if (!empty($this->next_id)) {
|
||||
$nextUrl = common_local_url('ApiTimelineUser',
|
||||
array('format' => 'atom',
|
||||
'id' => $this->user->id),
|
||||
array('max_id' => $this->next_id));
|
||||
|
||||
$atom->addLink($nextUrl,
|
||||
array('rel' => 'next',
|
||||
'type' => 'application/atom+xml'));
|
||||
}
|
||||
|
||||
if (($this->page > 1 || !empty($this->max_id)) && !empty($this->notices)) {
|
||||
|
||||
$lastNotice = $this->notices[0];
|
||||
$lastId = $lastNotice->id;
|
||||
|
||||
$prevUrl = common_local_url('ApiTimelineUser',
|
||||
array('format' => 'atom',
|
||||
'id' => $this->user->id),
|
||||
array('since_id' => $lastId));
|
||||
|
||||
$atom->addLink($prevUrl,
|
||||
array('rel' => 'prev',
|
||||
'type' => 'application/atom+xml'));
|
||||
}
|
||||
|
||||
if ($this->page > 1 || !empty($this->since_id) || !empty($this->max_id)) {
|
||||
|
||||
$firstUrl = common_local_url('ApiTimelineUser',
|
||||
array('format' => 'atom',
|
||||
'id' => $this->user->id));
|
||||
|
||||
$atom->addLink($firstUrl,
|
||||
array('rel' => 'first',
|
||||
'type' => 'application/atom+xml'));
|
||||
|
||||
}
|
||||
|
||||
$atom->addEntryFromNotices($this->notices);
|
||||
$this->raw($atom->getString());
|
||||
|
||||
@ -160,10 +202,10 @@ class ApiTimelineUserAction extends ApiBareAuthAction
|
||||
$this->showJsonTimeline($this->notices);
|
||||
break;
|
||||
default:
|
||||
// TRANS: Client error displayed when trying to handle an unknown API method.
|
||||
$this->clientError(_('API method not found.'), $code = 404);
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@ -171,34 +213,38 @@ class ApiTimelineUserAction extends ApiBareAuthAction
|
||||
*
|
||||
* @return array notices
|
||||
*/
|
||||
|
||||
function getNotices()
|
||||
{
|
||||
$notices = array();
|
||||
|
||||
$notice = $this->user->getNotices(
|
||||
($this->page-1) * $this->count, $this->count,
|
||||
$this->since_id, $this->max_id
|
||||
);
|
||||
$notice = $this->user->getNotices(($this->page-1) * $this->count,
|
||||
$this->count + 1,
|
||||
$this->since_id,
|
||||
$this->max_id);
|
||||
|
||||
while ($notice->fetch()) {
|
||||
$notices[] = clone($notice);
|
||||
if (count($notices) < $this->count) {
|
||||
$notices[] = clone($notice);
|
||||
} else {
|
||||
$this->next_id = $notice->id;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return $notices;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is this action read only?
|
||||
* We expose AtomPub here, so non-GET/HEAD reqs must be read/write.
|
||||
*
|
||||
* @param array $args other arguments
|
||||
*
|
||||
* @return boolean true
|
||||
*/
|
||||
|
||||
|
||||
function isReadOnly($args)
|
||||
{
|
||||
return true;
|
||||
return ($_SERVER['REQUEST_METHOD'] == 'GET' || $_SERVER['REQUEST_METHOD'] == 'HEAD');
|
||||
}
|
||||
|
||||
/**
|
||||
@ -206,7 +252,6 @@ class ApiTimelineUserAction extends ApiBareAuthAction
|
||||
*
|
||||
* @return string datestamp of the latest notice in the stream
|
||||
*/
|
||||
|
||||
function lastModified()
|
||||
{
|
||||
if (!empty($this->notices) && (count($this->notices) > 0)) {
|
||||
@ -224,25 +269,228 @@ class ApiTimelineUserAction extends ApiBareAuthAction
|
||||
*
|
||||
* @return string etag
|
||||
*/
|
||||
|
||||
function etag()
|
||||
{
|
||||
if (!empty($this->notices) && (count($this->notices) > 0)) {
|
||||
|
||||
$last = count($this->notices) - 1;
|
||||
|
||||
return '"' . implode(
|
||||
':',
|
||||
array($this->arg('action'),
|
||||
common_language(),
|
||||
$this->user->id,
|
||||
strtotime($this->notices[0]->created),
|
||||
strtotime($this->notices[$last]->created))
|
||||
)
|
||||
. '"';
|
||||
':',
|
||||
array($this->arg('action'),
|
||||
common_user_cache_hash($this->auth_user),
|
||||
common_language(),
|
||||
$this->user->id,
|
||||
strtotime($this->notices[0]->created),
|
||||
strtotime($this->notices[$last]->created))
|
||||
)
|
||||
. '"';
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
function handlePost()
|
||||
{
|
||||
if (empty($this->auth_user) ||
|
||||
$this->auth_user->id != $this->user->id) {
|
||||
// TRANS: Client error displayed trying to add a notice to another user's timeline.
|
||||
$this->clientError(_('Only the user can add to their own timeline.'));
|
||||
return;
|
||||
}
|
||||
|
||||
// Only handle posts for Atom
|
||||
if ($this->format != 'atom') {
|
||||
// TRANS: Client error displayed when using another format than AtomPub.
|
||||
$this->clientError(_('Only accept AtomPub for Atom feeds.'));
|
||||
return;
|
||||
}
|
||||
|
||||
$xml = trim(file_get_contents('php://input'));
|
||||
if (empty($xml)) {
|
||||
$this->clientError(_('Atom post must not be empty.'));
|
||||
}
|
||||
|
||||
$dom = DOMDocument::loadXML($xml);
|
||||
if (!$dom) {
|
||||
$this->clientError(_('Atom post must be well-formed XML.'));
|
||||
}
|
||||
|
||||
if ($dom->documentElement->namespaceURI != Activity::ATOM ||
|
||||
$dom->documentElement->localName != 'entry') {
|
||||
// TRANS: Client error displayed when not using an Atom entry.
|
||||
$this->clientError(_('Atom post must be an Atom entry.'));
|
||||
return;
|
||||
}
|
||||
|
||||
$activity = new Activity($dom->documentElement);
|
||||
|
||||
if (Event::handle('StartAtomPubNewActivity', array(&$activity))) {
|
||||
|
||||
if ($activity->verb != ActivityVerb::POST) {
|
||||
// TRANS: Client error displayed when not using the POST verb.
|
||||
// TRANS: Do not translate POST.
|
||||
$this->clientError(_('Can only handle POST activities.'));
|
||||
return;
|
||||
}
|
||||
|
||||
$note = $activity->objects[0];
|
||||
|
||||
if (!in_array($note->type, array(ActivityObject::NOTE,
|
||||
ActivityObject::BLOGENTRY,
|
||||
ActivityObject::STATUS))) {
|
||||
// TRANS: Client error displayed when using an unsupported activity object type.
|
||||
// TRANS: %s is the unsupported activity object type.
|
||||
$this->clientError(sprintf(_('Cannot handle activity object type "%s".'),
|
||||
$note->type));
|
||||
return;
|
||||
}
|
||||
|
||||
$saved = $this->postNote($activity);
|
||||
|
||||
Event::handle('EndAtomPubNewActivity', array($activity, $saved));
|
||||
}
|
||||
|
||||
if (!empty($saved)) {
|
||||
header('HTTP/1.1 201 Created');
|
||||
header("Location: " . common_local_url('ApiStatusesShow', array('id' => $saved->id,
|
||||
'format' => 'atom')));
|
||||
$this->showSingleAtomStatus($saved);
|
||||
}
|
||||
}
|
||||
|
||||
function postNote($activity)
|
||||
{
|
||||
$note = $activity->objects[0];
|
||||
|
||||
// Use summary as fallback for content
|
||||
|
||||
if (!empty($note->content)) {
|
||||
$sourceContent = $note->content;
|
||||
} else if (!empty($note->summary)) {
|
||||
$sourceContent = $note->summary;
|
||||
} else if (!empty($note->title)) {
|
||||
$sourceContent = $note->title;
|
||||
} else {
|
||||
// @fixme fetch from $sourceUrl?
|
||||
// TRANS: Client error displayed when posting a notice without content through the API.
|
||||
$this->clientError(sprintf(_('No content for notice %d.'),
|
||||
$note->id));
|
||||
return;
|
||||
}
|
||||
|
||||
// Get (safe!) HTML and text versions of the content
|
||||
|
||||
$rendered = $this->purify($sourceContent);
|
||||
$content = html_entity_decode(strip_tags($rendered), ENT_QUOTES, 'UTF-8');
|
||||
|
||||
$shortened = $this->auth_user->shortenLinks($content);
|
||||
|
||||
$options = array('is_local' => Notice::LOCAL_PUBLIC,
|
||||
'rendered' => $rendered,
|
||||
'replies' => array(),
|
||||
'groups' => array(),
|
||||
'tags' => array(),
|
||||
'urls' => array());
|
||||
|
||||
// accept remote URI (not necessarily a good idea)
|
||||
|
||||
common_debug("Note ID is {$note->id}");
|
||||
|
||||
if (!empty($note->id)) {
|
||||
$notice = Notice::staticGet('uri', trim($note->id));
|
||||
|
||||
if (!empty($notice)) {
|
||||
// TRANS: Client error displayed when using another format than AtomPub.
|
||||
$this->clientError(sprintf(_('Notice with URI "%s" already exists.'),
|
||||
$note->id));
|
||||
return;
|
||||
}
|
||||
common_log(LOG_NOTICE, "Saving client-supplied notice URI '$note->id'");
|
||||
$options['uri'] = $note->id;
|
||||
}
|
||||
|
||||
// accept remote create time (also maybe not such a good idea)
|
||||
|
||||
if (!empty($activity->time)) {
|
||||
common_log(LOG_NOTICE, "Saving client-supplied create time {$activity->time}");
|
||||
$options['created'] = common_sql_date($activity->time);
|
||||
}
|
||||
|
||||
// Check for optional attributes...
|
||||
|
||||
if (!empty($activity->context)) {
|
||||
|
||||
foreach ($activity->context->attention as $uri) {
|
||||
|
||||
$profile = Profile::fromURI($uri);
|
||||
|
||||
if (!empty($profile)) {
|
||||
$options['replies'] = $uri;
|
||||
} else {
|
||||
$group = User_group::staticGet('uri', $uri);
|
||||
if (!empty($group)) {
|
||||
$options['groups'] = $uri;
|
||||
} else {
|
||||
// @fixme: hook for discovery here
|
||||
common_log(LOG_WARNING, sprintf(_('AtomPub post with unknown attention URI %s'), $uri));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Maintain direct reply associations
|
||||
// @fixme what about conversation ID?
|
||||
|
||||
if (!empty($activity->context->replyToID)) {
|
||||
$orig = Notice::staticGet('uri',
|
||||
$activity->context->replyToID);
|
||||
if (!empty($orig)) {
|
||||
$options['reply_to'] = $orig->id;
|
||||
}
|
||||
}
|
||||
|
||||
$location = $activity->context->location;
|
||||
|
||||
if ($location) {
|
||||
$options['lat'] = $location->lat;
|
||||
$options['lon'] = $location->lon;
|
||||
if ($location->location_id) {
|
||||
$options['location_ns'] = $location->location_ns;
|
||||
$options['location_id'] = $location->location_id;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Atom categories <-> hashtags
|
||||
|
||||
foreach ($activity->categories as $cat) {
|
||||
if ($cat->term) {
|
||||
$term = common_canonical_tag($cat->term);
|
||||
if ($term) {
|
||||
$options['tags'][] = $term;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Atom enclosures -> attachment URLs
|
||||
foreach ($activity->enclosures as $href) {
|
||||
// @fixme save these locally or....?
|
||||
$options['urls'][] = $href;
|
||||
}
|
||||
|
||||
$saved = Notice::saveNew($this->user->id,
|
||||
$content,
|
||||
'atompub', // TODO: deal with this
|
||||
$options);
|
||||
|
||||
return $saved;
|
||||
}
|
||||
|
||||
function purify($content)
|
||||
{
|
||||
require_once INSTALLDIR.'/extlib/htmLawed/htmLawed.php';
|
||||
|
||||
$config = array('safe' => 1,
|
||||
'deny_attribute' => 'id,style,on*');
|
||||
return htmLawed($content, $config);
|
||||
}
|
||||
}
|
||||
|
@ -44,10 +44,8 @@ require_once INSTALLDIR.'/lib/apiprivateauth.php';
|
||||
*
|
||||
* @see ApiAction
|
||||
*/
|
||||
|
||||
class ApiTrendsAction extends ApiPrivateAuthAction
|
||||
{
|
||||
|
||||
var $callback;
|
||||
|
||||
/**
|
||||
@ -70,7 +68,6 @@ class ApiTrendsAction extends ApiPrivateAuthAction
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
|
||||
function handle($args)
|
||||
{
|
||||
parent::handle($args);
|
||||
@ -84,7 +81,7 @@ class ApiTrendsAction extends ApiPrivateAuthAction
|
||||
*/
|
||||
function showTrends()
|
||||
{
|
||||
// TRANS: Server error for unfinished API method showTrends.
|
||||
$this->serverError(_('API method under construction.'), 501);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -48,7 +48,6 @@ require_once INSTALLDIR . '/lib/apibareauth.php';
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||
* @link http://status.net/
|
||||
*/
|
||||
|
||||
class ApiUserFollowersAction extends ApiSubscriptionsAction
|
||||
{
|
||||
/**
|
||||
@ -56,7 +55,6 @@ class ApiUserFollowersAction extends ApiSubscriptionsAction
|
||||
*
|
||||
* @return array Profiles
|
||||
*/
|
||||
|
||||
function getProfiles()
|
||||
{
|
||||
$offset = ($this->page - 1) * $this->count;
|
||||
@ -85,5 +83,4 @@ class ApiUserFollowersAction extends ApiSubscriptionsAction
|
||||
|
||||
return $profiles;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -48,7 +48,6 @@ require_once INSTALLDIR . '/lib/apibareauth.php';
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||
* @link http://status.net/
|
||||
*/
|
||||
|
||||
class ApiUserFriendsAction extends ApiSubscriptionsAction
|
||||
{
|
||||
/**
|
||||
@ -56,7 +55,6 @@ class ApiUserFriendsAction extends ApiSubscriptionsAction
|
||||
*
|
||||
* @return array Profiles
|
||||
*/
|
||||
|
||||
function getProfiles()
|
||||
{
|
||||
$offset = ($this->page - 1) * $this->count;
|
||||
@ -85,5 +83,4 @@ class ApiUserFriendsAction extends ApiSubscriptionsAction
|
||||
|
||||
return $profiles;
|
||||
}
|
||||
|
||||
}
|
||||
|
135
actions/apiuserprofileimage.php
Normal file
135
actions/apiuserprofileimage.php
Normal file
@ -0,0 +1,135 @@
|
||||
<?php
|
||||
/**
|
||||
* StatusNet, the distributed open-source microblogging tool
|
||||
*
|
||||
* Return a user's avatar image
|
||||
*
|
||||
* 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 API
|
||||
* @package StatusNet
|
||||
* @author Brion Vibber <brion@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);
|
||||
}
|
||||
|
||||
require_once INSTALLDIR . '/lib/apiprivateauth.php';
|
||||
|
||||
/**
|
||||
* Ouputs avatar URL for a user, specified by screen name.
|
||||
* Unlike most API endpoints, this returns an HTTP redirect rather than direct data.
|
||||
*
|
||||
* @category API
|
||||
* @package StatusNet
|
||||
* @author Brion Vibber <brion@status.net>
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||
* @link http://status.net/
|
||||
*/
|
||||
class ApiUserProfileImageAction extends ApiPrivateAuthAction
|
||||
{
|
||||
/**
|
||||
* Take arguments for running
|
||||
*
|
||||
* @param array $args $_REQUEST args
|
||||
*
|
||||
* @return boolean success flag
|
||||
*
|
||||
*/
|
||||
function prepare($args)
|
||||
{
|
||||
parent::prepare($args);
|
||||
$this->user = User::staticGet('nickname', $this->arg('screen_name'));
|
||||
$this->size = $this->arg('size');
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle the request
|
||||
*
|
||||
* Check the format and show the user info
|
||||
*
|
||||
* @param array $args $_REQUEST data (unused)
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
function handle($args)
|
||||
{
|
||||
parent::handle($args);
|
||||
|
||||
if (empty($this->user)) {
|
||||
// TRANS: Client error displayed when requesting user information for a non-existing user.
|
||||
$this->clientError(_('User not found.'), 404, $this->format);
|
||||
return;
|
||||
}
|
||||
|
||||
$profile = $this->user->getProfile();
|
||||
|
||||
if (empty($profile)) {
|
||||
// TRANS: Client error displayed when requesting user information for a user without a profile.
|
||||
$this->clientError(_('User has no profile.'));
|
||||
return;
|
||||
}
|
||||
|
||||
$size = $this->avatarSize();
|
||||
$avatar = $profile->getAvatar($size);
|
||||
if ($avatar) {
|
||||
$url = $avatar->displayUrl();
|
||||
} else {
|
||||
$url = Avatar::defaultImage($size);
|
||||
}
|
||||
|
||||
// We don't actually output JSON or XML data -- redirect!
|
||||
common_redirect($url, 302);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the appropriate pixel size for an avatar based on the request...
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
private function avatarSize()
|
||||
{
|
||||
switch ($this->size) {
|
||||
case 'mini':
|
||||
return AVATAR_MINI_SIZE; // 24x24
|
||||
case 'bigger':
|
||||
return AVATAR_PROFILE_SIZE; // Twitter does 73x73, but we do 96x96
|
||||
case 'normal': // fall through
|
||||
default:
|
||||
return AVATAR_STREAM_SIZE; // 48x48
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if read only.
|
||||
*
|
||||
* MAY override
|
||||
*
|
||||
* @param array $args other arguments
|
||||
*
|
||||
* @return boolean is read only action?
|
||||
*/
|
||||
function isReadOnly($args)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
@ -49,7 +49,6 @@ require_once INSTALLDIR . '/lib/apiprivateauth.php';
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||
* @link http://status.net/
|
||||
*/
|
||||
|
||||
class ApiUserShowAction extends ApiPrivateAuthAction
|
||||
{
|
||||
/**
|
||||
@ -60,7 +59,6 @@ class ApiUserShowAction extends ApiPrivateAuthAction
|
||||
* @return boolean success flag
|
||||
*
|
||||
*/
|
||||
|
||||
function prepare($args)
|
||||
{
|
||||
parent::prepare($args);
|
||||
@ -87,17 +85,18 @@ class ApiUserShowAction extends ApiPrivateAuthAction
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
|
||||
function handle($args)
|
||||
{
|
||||
parent::handle($args);
|
||||
|
||||
if (empty($this->user)) {
|
||||
$this->clientError(_('Not found.'), 404, $this->format);
|
||||
// TRANS: Client error displayed when requesting user information for a non-existing user.
|
||||
$this->clientError(_('User not found.'), 404, $this->format);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!in_array($this->format, array('xml', 'json'))) {
|
||||
// TRANS: Client error displayed when trying to handle an unknown API method.
|
||||
$this->clientError(_('API method not found.'), $code = 404);
|
||||
return;
|
||||
}
|
||||
@ -105,6 +104,7 @@ class ApiUserShowAction extends ApiPrivateAuthAction
|
||||
$profile = $this->user->getProfile();
|
||||
|
||||
if (empty($profile)) {
|
||||
// TRANS: Client error displayed when requesting user information for a user without a profile.
|
||||
$this->clientError(_('User has no profile.'));
|
||||
return;
|
||||
}
|
||||
@ -120,7 +120,6 @@ class ApiUserShowAction extends ApiPrivateAuthAction
|
||||
$this->showJsonObjects($twitter_user);
|
||||
$this->endDocument('json');
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@ -132,10 +131,8 @@ class ApiUserShowAction extends ApiPrivateAuthAction
|
||||
*
|
||||
* @return boolean is read only action?
|
||||
*/
|
||||
|
||||
function isReadOnly($args)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
374
actions/atompubfavoritefeed.php
Normal file
374
actions/atompubfavoritefeed.php
Normal file
@ -0,0 +1,374 @@
|
||||
<?php
|
||||
/**
|
||||
* StatusNet - the distributed open-source microblogging tool
|
||||
* Copyright (C) 2010, StatusNet, Inc.
|
||||
*
|
||||
* Feed of ActivityStreams 'favorite' actions
|
||||
*
|
||||
* 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 AtomPub
|
||||
* @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);
|
||||
}
|
||||
|
||||
require_once INSTALLDIR . '/lib/apiauth.php';
|
||||
|
||||
/**
|
||||
* Feed of ActivityStreams 'favorite' actions
|
||||
*
|
||||
* @category AtomPub
|
||||
* @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 AtompubfavoritefeedAction extends ApiAuthAction
|
||||
{
|
||||
private $_profile = null;
|
||||
private $_faves = null;
|
||||
|
||||
/**
|
||||
* For initializing members of the class.
|
||||
*
|
||||
* @param array $argarray misc. arguments
|
||||
*
|
||||
* @return boolean true
|
||||
*/
|
||||
|
||||
function prepare($argarray)
|
||||
{
|
||||
parent::prepare($argarray);
|
||||
|
||||
$this->_profile = Profile::staticGet('id', $this->trimmed('profile'));
|
||||
|
||||
if (empty($this->_profile)) {
|
||||
throw new ClientException(_('No such profile'), 404);
|
||||
}
|
||||
|
||||
$offset = ($this->page-1) * $this->count;
|
||||
$limit = $this->count + 1;
|
||||
|
||||
$this->_faves = Fave::byProfile($this->_profile->id,
|
||||
$offset,
|
||||
$limit);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handler method
|
||||
*
|
||||
* @param array $argarray is ignored since it's now passed in in prepare()
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
|
||||
function handle($argarray=null)
|
||||
{
|
||||
parent::handle($argarray);
|
||||
|
||||
switch ($_SERVER['REQUEST_METHOD']) {
|
||||
case 'HEAD':
|
||||
case 'GET':
|
||||
$this->showFeed();
|
||||
break;
|
||||
case 'POST':
|
||||
$this->addFavorite();
|
||||
break;
|
||||
default:
|
||||
throw new ClientException(_('HTTP method not supported.'), 405);
|
||||
return;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Show a feed of favorite activity streams objects
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
|
||||
function showFeed()
|
||||
{
|
||||
header('Content-Type: application/atom+xml; charset=utf-8');
|
||||
|
||||
$url = common_local_url('AtomPubFavoriteFeed',
|
||||
array('profile' => $this->_profile->id));
|
||||
|
||||
$feed = new Atom10Feed(true);
|
||||
|
||||
$feed->addNamespace('activity',
|
||||
'http://activitystrea.ms/spec/1.0/');
|
||||
|
||||
$feed->addNamespace('poco',
|
||||
'http://portablecontacts.net/spec/1.0');
|
||||
|
||||
$feed->addNamespace('media',
|
||||
'http://purl.org/syndication/atommedia');
|
||||
|
||||
$feed->id = $url;
|
||||
|
||||
$feed->setUpdated('now');
|
||||
|
||||
$feed->addAuthor($this->_profile->getBestName(),
|
||||
$this->_profile->getURI());
|
||||
|
||||
$feed->setTitle(sprintf(_("%s favorites"),
|
||||
$this->_profile->getBestName()));
|
||||
|
||||
$feed->setSubtitle(sprintf(_("Notices %s has favorited to on %s"),
|
||||
$this->_profile->getBestName(),
|
||||
common_config('site', 'name')));
|
||||
|
||||
$feed->addLink(common_local_url('showfavorites',
|
||||
array('nickname' =>
|
||||
$this->_profile->nickname)));
|
||||
|
||||
$feed->addLink($url,
|
||||
array('rel' => 'self',
|
||||
'type' => 'application/atom+xml'));
|
||||
|
||||
// If there's more...
|
||||
|
||||
if ($this->page > 1) {
|
||||
$feed->addLink($url,
|
||||
array('rel' => 'first',
|
||||
'type' => 'application/atom+xml'));
|
||||
|
||||
$feed->addLink(common_local_url('AtomPubFavoriteFeed',
|
||||
array('profile' =>
|
||||
$this->_profile->id),
|
||||
array('page' =>
|
||||
$this->page - 1)),
|
||||
array('rel' => 'prev',
|
||||
'type' => 'application/atom+xml'));
|
||||
}
|
||||
|
||||
if ($this->_faves->N > $this->count) {
|
||||
|
||||
$feed->addLink(common_local_url('AtomPubFavoriteFeed',
|
||||
array('profile' =>
|
||||
$this->_profile->id),
|
||||
array('page' =>
|
||||
$this->page + 1)),
|
||||
array('rel' => 'next',
|
||||
'type' => 'application/atom+xml'));
|
||||
}
|
||||
|
||||
$i = 0;
|
||||
|
||||
while ($this->_faves->fetch()) {
|
||||
|
||||
// We get one more than needed; skip that one
|
||||
|
||||
$i++;
|
||||
|
||||
if ($i > $this->count) {
|
||||
break;
|
||||
}
|
||||
|
||||
$act = $this->_faves->asActivity();
|
||||
$feed->addEntryRaw($act->asString(false, false, false));
|
||||
}
|
||||
|
||||
$this->raw($feed->getString());
|
||||
}
|
||||
|
||||
/**
|
||||
* add a new favorite
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
|
||||
function addFavorite()
|
||||
{
|
||||
// XXX: Refactor this; all the same for atompub
|
||||
|
||||
if (empty($this->auth_user) ||
|
||||
$this->auth_user->id != $this->_profile->id) {
|
||||
throw new ClientException(_("Can't add someone else's".
|
||||
" subscription"), 403);
|
||||
}
|
||||
|
||||
$xml = file_get_contents('php://input');
|
||||
|
||||
$dom = DOMDocument::loadXML($xml);
|
||||
|
||||
if ($dom->documentElement->namespaceURI != Activity::ATOM ||
|
||||
$dom->documentElement->localName != 'entry') {
|
||||
// TRANS: Client error displayed when not using an Atom entry.
|
||||
throw new ClientException(_('Atom post must be an Atom entry.'));
|
||||
return;
|
||||
}
|
||||
|
||||
$activity = new Activity($dom->documentElement);
|
||||
|
||||
$fave = null;
|
||||
|
||||
if (Event::handle('StartAtomPubNewActivity', array(&$activity))) {
|
||||
|
||||
if ($activity->verb != ActivityVerb::FAVORITE) {
|
||||
// TRANS: Client error displayed when not using the POST verb.
|
||||
// TRANS: Do not translate POST.
|
||||
throw new ClientException(_('Can only handle Favorite activities.'));
|
||||
return;
|
||||
}
|
||||
|
||||
$note = $activity->objects[0];
|
||||
|
||||
if (!in_array($note->type, array(ActivityObject::NOTE,
|
||||
ActivityObject::BLOGENTRY,
|
||||
ActivityObject::STATUS))) {
|
||||
throw new ClientException(_('Can only fave notices.'));
|
||||
return;
|
||||
}
|
||||
|
||||
$notice = Notice::staticGet('uri', $note->id);
|
||||
|
||||
if (empty($notice)) {
|
||||
// XXX: import from listed URL or something
|
||||
throw new ClientException(_('Unknown note.'));
|
||||
}
|
||||
|
||||
$old = Fave::pkeyGet(array('user_id' => $this->auth_user->id,
|
||||
'notice_id' => $notice->id));
|
||||
|
||||
if (!empty($old)) {
|
||||
throw new ClientException(_('Already a favorite.'));
|
||||
}
|
||||
|
||||
$profile = $this->auth_user->getProfile();
|
||||
|
||||
$fave = Fave::addNew($profile, $notice);
|
||||
|
||||
if (!empty($fave)) {
|
||||
$this->_profile->blowFavesCache();
|
||||
$this->notify($fave, $notice, $this->auth_user);
|
||||
}
|
||||
|
||||
Event::handle('EndAtomPubNewActivity', array($activity, $fave));
|
||||
}
|
||||
|
||||
if (!empty($fave)) {
|
||||
$act = $fave->asActivity();
|
||||
|
||||
header('Content-Type: application/atom+xml; charset=utf-8');
|
||||
header('Content-Location: ' . $act->selfLink);
|
||||
|
||||
$this->startXML();
|
||||
$this->raw($act->asString(true, true, true));
|
||||
$this->endXML();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if read only.
|
||||
*
|
||||
* MAY override
|
||||
*
|
||||
* @param array $args other arguments
|
||||
*
|
||||
* @return boolean is read only action?
|
||||
*/
|
||||
|
||||
function isReadOnly($args)
|
||||
{
|
||||
if ($_SERVER['REQUEST_METHOD'] == 'GET' ||
|
||||
$_SERVER['REQUEST_METHOD'] == 'HEAD') {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return last modified, if applicable.
|
||||
*
|
||||
* MAY override
|
||||
*
|
||||
* @return string last modified http header
|
||||
*/
|
||||
function lastModified()
|
||||
{
|
||||
// For comparison with If-Last-Modified
|
||||
// If not applicable, return null
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return etag, if applicable.
|
||||
*
|
||||
* MAY override
|
||||
*
|
||||
* @return string etag http header
|
||||
*/
|
||||
|
||||
function etag()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Does this require authentication?
|
||||
*
|
||||
* @return boolean true if delete, else false
|
||||
*/
|
||||
|
||||
function requiresAuth()
|
||||
{
|
||||
if ($_SERVER['REQUEST_METHOD'] == 'GET' ||
|
||||
$_SERVER['REQUEST_METHOD'] == 'HEAD') {
|
||||
return false;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Notify the author of the favorite that the user likes their notice
|
||||
*
|
||||
* @param Favorite $fave the favorite in question
|
||||
* @param Notice $notice the notice that's been faved
|
||||
* @param User $user the user doing the favoriting
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
|
||||
function notify($fave, $notice, $user)
|
||||
{
|
||||
$other = User::staticGet('id', $notice->profile_id);
|
||||
if ($other && $other->id != $user->id) {
|
||||
if ($other->email && $other->emailnotifyfav) {
|
||||
mail_notify_fave($other, $user, $notice);
|
||||
}
|
||||
// XXX: notify by IM
|
||||
// XXX: notify by SMS
|
||||
}
|
||||
}
|
||||
}
|
355
actions/atompubmembershipfeed.php
Normal file
355
actions/atompubmembershipfeed.php
Normal file
@ -0,0 +1,355 @@
|
||||
<?php
|
||||
/**
|
||||
* StatusNet - the distributed open-source microblogging tool
|
||||
* Copyright (C) 2010, StatusNet, Inc.
|
||||
*
|
||||
* Feed of group memberships for a user, in ActivityStreams format
|
||||
*
|
||||
* 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 AtomPub
|
||||
* @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);
|
||||
}
|
||||
|
||||
require_once INSTALLDIR . '/lib/apiauth.php';
|
||||
|
||||
/**
|
||||
* Feed of group memberships for a user, in ActivityStreams format
|
||||
*
|
||||
* @category Action
|
||||
* @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 AtompubmembershipfeedAction extends ApiAuthAction
|
||||
{
|
||||
private $_profile = null;
|
||||
private $_memberships = null;
|
||||
|
||||
/**
|
||||
* For initializing members of the class.
|
||||
*
|
||||
* @param array $argarray misc. arguments
|
||||
*
|
||||
* @return boolean true
|
||||
*/
|
||||
|
||||
function prepare($argarray)
|
||||
{
|
||||
parent::prepare($argarray);
|
||||
|
||||
$profileId = $this->trimmed('profile');
|
||||
|
||||
$this->_profile = Profile::staticGet('id', $profileId);
|
||||
|
||||
if (empty($this->_profile)) {
|
||||
throw new ClientException(_('No such profile.'), 404);
|
||||
}
|
||||
|
||||
$offset = ($this->page-1) * $this->count;
|
||||
$limit = $this->count + 1;
|
||||
|
||||
$this->_memberships = Group_member::byMember($this->_profile->id,
|
||||
$offset,
|
||||
$limit);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handler method
|
||||
*
|
||||
* @param array $argarray is ignored since it's now passed in in prepare()
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
|
||||
function handle($argarray=null)
|
||||
{
|
||||
parent::handle($argarray);
|
||||
|
||||
switch ($_SERVER['REQUEST_METHOD']) {
|
||||
case 'HEAD':
|
||||
case 'GET':
|
||||
$this->showFeed();
|
||||
break;
|
||||
case 'POST':
|
||||
$this->addMembership();
|
||||
break;
|
||||
default:
|
||||
throw new ClientException(_('HTTP method not supported.'), 405);
|
||||
return;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Show a feed of favorite activity streams objects
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
|
||||
function showFeed()
|
||||
{
|
||||
header('Content-Type: application/atom+xml; charset=utf-8');
|
||||
|
||||
$url = common_local_url('AtomPubMembershipFeed',
|
||||
array('profile' => $this->_profile->id));
|
||||
|
||||
$feed = new Atom10Feed(true);
|
||||
|
||||
$feed->addNamespace('activity',
|
||||
'http://activitystrea.ms/spec/1.0/');
|
||||
|
||||
$feed->addNamespace('poco',
|
||||
'http://portablecontacts.net/spec/1.0');
|
||||
|
||||
$feed->addNamespace('media',
|
||||
'http://purl.org/syndication/atommedia');
|
||||
|
||||
$feed->id = $url;
|
||||
|
||||
$feed->setUpdated('now');
|
||||
|
||||
$feed->addAuthor($this->_profile->getBestName(),
|
||||
$this->_profile->getURI());
|
||||
|
||||
$feed->setTitle(sprintf(_("%s group memberships"),
|
||||
$this->_profile->getBestName()));
|
||||
|
||||
$feed->setSubtitle(sprintf(_("Groups %s is a member of on %s"),
|
||||
$this->_profile->getBestName(),
|
||||
common_config('site', 'name')));
|
||||
|
||||
$feed->addLink(common_local_url('usergroups',
|
||||
array('nickname' =>
|
||||
$this->_profile->nickname)));
|
||||
|
||||
$feed->addLink($url,
|
||||
array('rel' => 'self',
|
||||
'type' => 'application/atom+xml'));
|
||||
|
||||
// If there's more...
|
||||
|
||||
if ($this->page > 1) {
|
||||
$feed->addLink($url,
|
||||
array('rel' => 'first',
|
||||
'type' => 'application/atom+xml'));
|
||||
|
||||
$feed->addLink(common_local_url('AtomPubMembershipFeed',
|
||||
array('profile' =>
|
||||
$this->_profile->id),
|
||||
array('page' =>
|
||||
$this->page - 1)),
|
||||
array('rel' => 'prev',
|
||||
'type' => 'application/atom+xml'));
|
||||
}
|
||||
|
||||
if ($this->_memberships->N > $this->count) {
|
||||
|
||||
$feed->addLink(common_local_url('AtomPubMembershipFeed',
|
||||
array('profile' =>
|
||||
$this->_profile->id),
|
||||
array('page' =>
|
||||
$this->page + 1)),
|
||||
array('rel' => 'next',
|
||||
'type' => 'application/atom+xml'));
|
||||
}
|
||||
|
||||
$i = 0;
|
||||
|
||||
while ($this->_memberships->fetch()) {
|
||||
|
||||
// We get one more than needed; skip that one
|
||||
|
||||
$i++;
|
||||
|
||||
if ($i > $this->count) {
|
||||
break;
|
||||
}
|
||||
|
||||
$act = $this->_memberships->asActivity();
|
||||
$feed->addEntryRaw($act->asString(false, false, false));
|
||||
}
|
||||
|
||||
$this->raw($feed->getString());
|
||||
}
|
||||
|
||||
/**
|
||||
* add a new favorite
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
|
||||
function addMembership()
|
||||
{
|
||||
// XXX: Refactor this; all the same for atompub
|
||||
|
||||
if (empty($this->auth_user) ||
|
||||
$this->auth_user->id != $this->_profile->id) {
|
||||
throw new ClientException(_("Can't add someone else's".
|
||||
" membership"), 403);
|
||||
}
|
||||
|
||||
$xml = file_get_contents('php://input');
|
||||
|
||||
$dom = DOMDocument::loadXML($xml);
|
||||
|
||||
if ($dom->documentElement->namespaceURI != Activity::ATOM ||
|
||||
$dom->documentElement->localName != 'entry') {
|
||||
// TRANS: Client error displayed when not using an Atom entry.
|
||||
throw new ClientException(_('Atom post must be an Atom entry.'));
|
||||
return;
|
||||
}
|
||||
|
||||
$activity = new Activity($dom->documentElement);
|
||||
|
||||
$membership = null;
|
||||
|
||||
if (Event::handle('StartAtomPubNewActivity', array(&$activity))) {
|
||||
|
||||
if ($activity->verb != ActivityVerb::JOIN) {
|
||||
// TRANS: Client error displayed when not using the POST verb.
|
||||
// TRANS: Do not translate POST.
|
||||
throw new ClientException(_('Can only handle Join activities.'));
|
||||
return;
|
||||
}
|
||||
|
||||
$groupObj = $activity->objects[0];
|
||||
|
||||
if ($groupObj->type != ActivityObject::GROUP) {
|
||||
throw new ClientException(_('Can only fave notices.'));
|
||||
return;
|
||||
}
|
||||
|
||||
$group = User_group::staticGet('uri', $groupObj->id);
|
||||
|
||||
if (empty($group)) {
|
||||
// XXX: import from listed URL or something
|
||||
throw new ClientException(_('Unknown group.'));
|
||||
}
|
||||
|
||||
$old = Group_member::pkeyGet(array('profile_id' => $this->auth_user->id,
|
||||
'group_id' => $group->id));
|
||||
|
||||
if (!empty($old)) {
|
||||
throw new ClientException(_('Already a member.'));
|
||||
}
|
||||
|
||||
$profile = $this->auth_user->getProfile();
|
||||
|
||||
if (Group_block::isBlocked($group, $profile)) {
|
||||
// XXX: import from listed URL or something
|
||||
throw new ClientException(_('Blocked by admin.'));
|
||||
}
|
||||
|
||||
if (Event::handle('StartJoinGroup', array($group, $this->auth_user))) {
|
||||
$membership = Group_member::join($group->id, $this->auth_user->id);
|
||||
Event::handle('EndJoinGroup', array($group, $this->auth_user));
|
||||
}
|
||||
|
||||
Event::handle('EndAtomPubNewActivity', array($activity, $membership));
|
||||
}
|
||||
|
||||
if (!empty($membership)) {
|
||||
$act = $membership->asActivity();
|
||||
|
||||
header('Content-Type: application/atom+xml; charset=utf-8');
|
||||
header('Content-Location: ' . $act->selfLink);
|
||||
|
||||
$this->startXML();
|
||||
$this->raw($act->asString(true, true, true));
|
||||
$this->endXML();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if read only.
|
||||
*
|
||||
* MAY override
|
||||
*
|
||||
* @param array $args other arguments
|
||||
*
|
||||
* @return boolean is read only action?
|
||||
*/
|
||||
|
||||
function isReadOnly($args)
|
||||
{
|
||||
if ($_SERVER['REQUEST_METHOD'] == 'GET' ||
|
||||
$_SERVER['REQUEST_METHOD'] == 'HEAD') {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return last modified, if applicable.
|
||||
*
|
||||
* MAY override
|
||||
*
|
||||
* @return string last modified http header
|
||||
*/
|
||||
function lastModified()
|
||||
{
|
||||
// For comparison with If-Last-Modified
|
||||
// If not applicable, return null
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return etag, if applicable.
|
||||
*
|
||||
* MAY override
|
||||
*
|
||||
* @return string etag http header
|
||||
*/
|
||||
|
||||
function etag()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Does this require authentication?
|
||||
*
|
||||
* @return boolean true if delete, else false
|
||||
*/
|
||||
|
||||
function requiresAuth()
|
||||
{
|
||||
if ($_SERVER['REQUEST_METHOD'] == 'GET' ||
|
||||
$_SERVER['REQUEST_METHOD'] == 'HEAD') {
|
||||
return false;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
228
actions/atompubshowfavorite.php
Normal file
228
actions/atompubshowfavorite.php
Normal file
@ -0,0 +1,228 @@
|
||||
<?php
|
||||
/**
|
||||
* StatusNet - the distributed open-source microblogging tool
|
||||
* Copyright (C) 2010, StatusNet, Inc.
|
||||
*
|
||||
* Show a single favorite in Atom Activity Streams format
|
||||
*
|
||||
* 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 AtomPub
|
||||
* @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);
|
||||
}
|
||||
|
||||
require_once INSTALLDIR . '/lib/apiauth.php';
|
||||
|
||||
/**
|
||||
* Show a single favorite in Atom Activity Streams format.
|
||||
*
|
||||
* Can also be used to delete a favorite.
|
||||
*
|
||||
* @category Action
|
||||
* @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 AtompubshowfavoriteAction extends ApiAuthAction
|
||||
{
|
||||
private $_profile = null;
|
||||
private $_notice = null;
|
||||
private $_fave = null;
|
||||
|
||||
/**
|
||||
* For initializing members of the class.
|
||||
*
|
||||
* @param array $argarray misc. arguments
|
||||
*
|
||||
* @return boolean true
|
||||
*/
|
||||
|
||||
function prepare($argarray)
|
||||
{
|
||||
parent::prepare($argarray);
|
||||
|
||||
$profileId = $this->trimmed('profile');
|
||||
$noticeId = $this->trimmed('notice');
|
||||
|
||||
$this->_profile = Profile::staticGet('id', $profileId);
|
||||
|
||||
if (empty($this->_profile)) {
|
||||
throw new ClientException(_('No such profile.'), 404);
|
||||
}
|
||||
|
||||
$this->_notice = Notice::staticGet('id', $noticeId);
|
||||
|
||||
if (empty($this->_notice)) {
|
||||
throw new ClientException(_('No such notice.'), 404);
|
||||
}
|
||||
|
||||
$this->_fave = Fave::pkeyGet(array('user_id' => $profileId,
|
||||
'notice_id' => $noticeId));
|
||||
|
||||
if (empty($this->_fave)) {
|
||||
throw new ClientException(_('No such favorite.'), 404);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handler method
|
||||
*
|
||||
* @param array $argarray is ignored since it's now passed in in prepare()
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
|
||||
function handle($argarray=null)
|
||||
{
|
||||
parent::handle($argarray);
|
||||
|
||||
switch ($_SERVER['REQUEST_METHOD']) {
|
||||
case GET:
|
||||
case HEAD:
|
||||
$this->showFave();
|
||||
break;
|
||||
case DELETE:
|
||||
$this->deleteFave();
|
||||
break;
|
||||
default:
|
||||
throw new ClientException(_('HTTP method not supported.'),
|
||||
405);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Show a single favorite, in ActivityStreams format
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
|
||||
function showFave()
|
||||
{
|
||||
$activity = $this->_fave->asActivity();
|
||||
|
||||
header('Content-Type: application/atom+xml; charset=utf-8');
|
||||
|
||||
$this->startXML();
|
||||
$this->raw($activity->asString(true, true, true));
|
||||
$this->endXML();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete the favorite
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
|
||||
function deleteFave()
|
||||
{
|
||||
if (empty($this->auth_user) ||
|
||||
$this->auth_user->id != $this->_profile->id) {
|
||||
throw new ClientException(_("Can't delete someone else's".
|
||||
" favorite"), 403);
|
||||
}
|
||||
|
||||
$this->_fave->delete();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if read only.
|
||||
*
|
||||
* MAY override
|
||||
*
|
||||
* @param array $args other arguments
|
||||
*
|
||||
* @return boolean is read only action?
|
||||
*/
|
||||
|
||||
function isReadOnly($args)
|
||||
{
|
||||
if ($_SERVER['REQUEST_METHOD'] == 'GET' ||
|
||||
$_SERVER['REQUEST_METHOD'] == 'HEAD') {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return last modified, if applicable.
|
||||
*
|
||||
* MAY override
|
||||
*
|
||||
* @return string last modified http header
|
||||
*/
|
||||
|
||||
function lastModified()
|
||||
{
|
||||
return max(strtotime($this->_profile->modified),
|
||||
strtotime($this->_notice->modified),
|
||||
strtotime($this->_fave->modified));
|
||||
}
|
||||
|
||||
/**
|
||||
* Return etag, if applicable.
|
||||
*
|
||||
* MAY override
|
||||
*
|
||||
* @return string etag http header
|
||||
*/
|
||||
|
||||
function etag()
|
||||
{
|
||||
$mtime = strtotime($this->_fave->modified);
|
||||
|
||||
return 'W/"' . implode(':', array('AtomPubShowFavorite',
|
||||
$this->_profile->id,
|
||||
$this->_notice->id,
|
||||
$mtime)) . '"';
|
||||
}
|
||||
|
||||
/**
|
||||
* Does this require authentication?
|
||||
*
|
||||
* @return boolean true if delete, else false
|
||||
*/
|
||||
|
||||
function requiresAuth()
|
||||
{
|
||||
if ($_SERVER['REQUEST_METHOD'] == 'GET' ||
|
||||
$_SERVER['REQUEST_METHOD'] == 'HEAD') {
|
||||
return false;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
235
actions/atompubshowmembership.php
Normal file
235
actions/atompubshowmembership.php
Normal file
@ -0,0 +1,235 @@
|
||||
<?php
|
||||
/**
|
||||
* StatusNet - the distributed open-source microblogging tool
|
||||
* Copyright (C) 2010, StatusNet, Inc.
|
||||
*
|
||||
* Show a single membership as an Activity Streams entry
|
||||
*
|
||||
* 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 AtomPub
|
||||
* @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);
|
||||
}
|
||||
|
||||
require_once INSTALLDIR . '/lib/apiauth.php';
|
||||
|
||||
/**
|
||||
* Show (or delete) a single membership event as an ActivityStreams entry
|
||||
*
|
||||
* @category AtomPub
|
||||
* @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 AtompubshowmembershipAction extends ApiAuthAction
|
||||
{
|
||||
private $_profile = null;
|
||||
private $_group = null;
|
||||
private $_membership = null;
|
||||
|
||||
/**
|
||||
* For initializing members of the class.
|
||||
*
|
||||
* @param array $argarray misc. arguments
|
||||
*
|
||||
* @return boolean true
|
||||
*/
|
||||
|
||||
function prepare($argarray)
|
||||
{
|
||||
parent::prepare($argarray);
|
||||
|
||||
$profileId = $this->trimmed('profile');
|
||||
|
||||
$this->_profile = Profile::staticGet('id', $profileId);
|
||||
|
||||
if (empty($this->_profile)) {
|
||||
throw new ClientException(_('No such profile.'), 404);
|
||||
}
|
||||
|
||||
$groupId = $this->trimmed('group');
|
||||
|
||||
$this->_group = User_group::staticGet('id', $groupId);
|
||||
|
||||
if (empty($this->_group)) {
|
||||
throw new ClientException(_('No such group'), 404);
|
||||
}
|
||||
|
||||
$kv = array('group_id' => $groupId,
|
||||
'profile_id' => $profileId);
|
||||
|
||||
$this->_membership = Group_member::pkeyGet($kv);
|
||||
|
||||
if (empty($this->_membership)) {
|
||||
throw new ClientException(_('Not a member'), 404);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handler method
|
||||
*
|
||||
* @param array $argarray is ignored since it's now passed in in prepare()
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
|
||||
function handle($argarray=null)
|
||||
{
|
||||
switch ($_SERVER['REQUEST_METHOD']) {
|
||||
case 'GET':
|
||||
case 'HEAD':
|
||||
$this->showMembership();
|
||||
break;
|
||||
case 'DELETE':
|
||||
$this->deleteMembership();
|
||||
break;
|
||||
default:
|
||||
throw new ClientException(_('Method not supported'), 405);
|
||||
break;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* show a single membership
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
|
||||
function showMembership()
|
||||
{
|
||||
$activity = $this->_membership->asActivity();
|
||||
|
||||
header('Content-Type: application/atom+xml; charset=utf-8');
|
||||
|
||||
$this->startXML();
|
||||
$this->raw($activity->asString(true, true, true));
|
||||
$this->endXML();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete the membership (leave the group)
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
|
||||
function deleteMembership()
|
||||
{
|
||||
if (empty($this->auth_user) ||
|
||||
$this->auth_user->id != $this->_profile->id) {
|
||||
throw new ClientException(_("Can't delete someone else's".
|
||||
" membership"), 403);
|
||||
}
|
||||
|
||||
if (Event::handle('StartLeaveGroup', array($this->_group, $this->auth_user))) {
|
||||
Group_member::leave($this->_group->id, $this->auth_user->id);
|
||||
Event::handle('EndLeaveGroup', array($this->_group, $this->auth_user));
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if read only.
|
||||
*
|
||||
* MAY override
|
||||
*
|
||||
* @param array $args other arguments
|
||||
*
|
||||
* @return boolean is read only action?
|
||||
*/
|
||||
|
||||
function isReadOnly($args)
|
||||
{
|
||||
if ($_SERVER['REQUEST_METHOD'] == 'GET' ||
|
||||
$_SERVER['REQUEST_METHOD'] == 'HEAD') {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return last modified, if applicable.
|
||||
*
|
||||
* Because the representation depends on the profile and group,
|
||||
* our last modified value is the maximum of their mod time
|
||||
* with the actual membership's mod time.
|
||||
*
|
||||
* @return string last modified http header
|
||||
*/
|
||||
function lastModified()
|
||||
{
|
||||
return max(strtotime($this->_profile->modified),
|
||||
strtotime($this->_group->modified),
|
||||
strtotime($this->_membership->modified));
|
||||
}
|
||||
|
||||
/**
|
||||
* Return etag, if applicable.
|
||||
*
|
||||
* A "weak" Etag including the profile and group id as well as
|
||||
* the admin flag and ctime of the membership.
|
||||
*
|
||||
* @return string etag http header
|
||||
*/
|
||||
|
||||
function etag()
|
||||
{
|
||||
$ctime = strtotime($this->_membership->created);
|
||||
|
||||
$adminflag = ($this->_membership->is_admin) ? 't' : 'f';
|
||||
|
||||
return 'W/"' . implode(':', array('AtomPubShowMembership',
|
||||
$this->_profile->id,
|
||||
$this->_group->id,
|
||||
$adminflag,
|
||||
$ctime)) . '"';
|
||||
}
|
||||
|
||||
/**
|
||||
* Does this require authentication?
|
||||
*
|
||||
* @return boolean true if delete, else false
|
||||
*/
|
||||
|
||||
function requiresAuth()
|
||||
{
|
||||
if ($_SERVER['REQUEST_METHOD'] == 'GET' ||
|
||||
$_SERVER['REQUEST_METHOD'] == 'HEAD') {
|
||||
return false;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
224
actions/atompubshowsubscription.php
Normal file
224
actions/atompubshowsubscription.php
Normal file
@ -0,0 +1,224 @@
|
||||
<?php
|
||||
/**
|
||||
* StatusNet - the distributed open-source microblogging tool
|
||||
* Copyright (C) 2010, StatusNet, Inc.
|
||||
*
|
||||
* Single subscription
|
||||
*
|
||||
* 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 AtomPub
|
||||
* @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);
|
||||
}
|
||||
|
||||
require_once INSTALLDIR . '/lib/apiauth.php';
|
||||
|
||||
/**
|
||||
* Show a single subscription
|
||||
*
|
||||
* @category AtomPub
|
||||
* @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 AtompubshowsubscriptionAction extends ApiAuthAction
|
||||
{
|
||||
private $_subscriber = null;
|
||||
private $_subscribed = null;
|
||||
private $_subscription = null;
|
||||
|
||||
/**
|
||||
* For initializing members of the class.
|
||||
*
|
||||
* @param array $argarray misc. arguments
|
||||
*
|
||||
* @return boolean true
|
||||
*/
|
||||
|
||||
function prepare($argarray)
|
||||
{
|
||||
parent::prepare($argarray);
|
||||
$subscriberId = $this->trimmed('subscriber');
|
||||
|
||||
$this->_subscriber = Profile::staticGet('id', $subscriberId);
|
||||
|
||||
if (empty($this->_subscriber)) {
|
||||
throw new ClientException(sprintf(_('No such profile id: %d'),
|
||||
$subscriberId), 404);
|
||||
}
|
||||
|
||||
$subscribedId = $this->trimmed('subscribed');
|
||||
|
||||
$this->_subscribed = Profile::staticGet('id', $subscribedId);
|
||||
|
||||
if (empty($this->_subscribed)) {
|
||||
throw new ClientException(sprintf(_('No such profile id: %d'),
|
||||
$subscribedId), 404);
|
||||
}
|
||||
|
||||
$this->_subscription =
|
||||
Subscription::pkeyGet(array('subscriber' => $subscriberId,
|
||||
'subscribed' => $subscribedId));
|
||||
|
||||
if (empty($this->_subscription)) {
|
||||
$msg = sprintf(_('Profile %d not subscribed to profile %d'),
|
||||
$subscriberId, $subscribedId);
|
||||
throw new ClientException($msg, 404);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handler method
|
||||
*
|
||||
* @param array $argarray is ignored since it's now passed in in prepare()
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
|
||||
function handle($argarray=null)
|
||||
{
|
||||
parent::handle($argarray);
|
||||
switch ($_SERVER['REQUEST_METHOD']) {
|
||||
case 'HEAD':
|
||||
case 'GET':
|
||||
$this->showSubscription();
|
||||
break;
|
||||
case 'DELETE':
|
||||
$this->deleteSubscription();
|
||||
break;
|
||||
default:
|
||||
$this->clientError(_('HTTP method not supported.'), 405);
|
||||
return;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the subscription in ActivityStreams Atom format.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
|
||||
function showSubscription()
|
||||
{
|
||||
$activity = $this->_subscription->asActivity();
|
||||
|
||||
header('Content-Type: application/atom+xml; charset=utf-8');
|
||||
|
||||
$this->startXML();
|
||||
$this->raw($activity->asString(true, true, true));
|
||||
$this->endXML();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete the subscription
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
|
||||
function deleteSubscription()
|
||||
{
|
||||
if (empty($this->auth_user) ||
|
||||
$this->auth_user->id != $this->_subscriber->id) {
|
||||
throw new ClientException(_("Can't delete someone else's".
|
||||
" subscription"), 403);
|
||||
}
|
||||
|
||||
Subscription::cancel($this->_subscriber,
|
||||
$this->_subscribed);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is this action read only?
|
||||
*
|
||||
* @param array $args other arguments
|
||||
*
|
||||
* @return boolean true
|
||||
*/
|
||||
|
||||
function isReadOnly($args)
|
||||
{
|
||||
if ($_SERVER['REQUEST_METHOD'] == 'DELETE') {
|
||||
return false;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return last modified, if applicable.
|
||||
*
|
||||
* @return string last modified http header
|
||||
*/
|
||||
|
||||
function lastModified()
|
||||
{
|
||||
return max(strtotime($this->_subscriber->modified),
|
||||
strtotime($this->_subscribed->modified),
|
||||
strtotime($this->_subscription->modified));
|
||||
}
|
||||
|
||||
/**
|
||||
* Etag for this object
|
||||
*
|
||||
* @return string etag http header
|
||||
*/
|
||||
|
||||
function etag()
|
||||
{
|
||||
$mtime = strtotime($this->_subscription->modified);
|
||||
|
||||
return 'W/"' . implode(':', array('AtomPubShowSubscription',
|
||||
$this->_subscriber->id,
|
||||
$this->_subscribed->id,
|
||||
$mtime)) . '"';
|
||||
}
|
||||
|
||||
/**
|
||||
* Does this require authentication?
|
||||
*
|
||||
* @return boolean true if delete, else false
|
||||
*/
|
||||
|
||||
function requiresAuth()
|
||||
{
|
||||
if ($_SERVER['REQUEST_METHOD'] == 'DELETE') {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
335
actions/atompubsubscriptionfeed.php
Normal file
335
actions/atompubsubscriptionfeed.php
Normal file
@ -0,0 +1,335 @@
|
||||
<?php
|
||||
/**
|
||||
* StatusNet - the distributed open-source microblogging tool
|
||||
* Copyright (C) 2010, StatusNet, Inc.
|
||||
*
|
||||
* AtomPub subscription feed
|
||||
*
|
||||
* 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 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);
|
||||
}
|
||||
|
||||
require_once INSTALLDIR . '/lib/apiauth.php';
|
||||
|
||||
/**
|
||||
* Subscription feed class for AtomPub
|
||||
*
|
||||
* Generates a list of the user's subscriptions
|
||||
*
|
||||
* @category AtomPub
|
||||
* @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 AtompubsubscriptionfeedAction extends ApiAuthAction
|
||||
{
|
||||
private $_profile = null;
|
||||
private $_subscriptions = null;
|
||||
|
||||
/**
|
||||
* For initializing members of the class.
|
||||
*
|
||||
* @param array $argarray misc. arguments
|
||||
*
|
||||
* @return boolean true
|
||||
*/
|
||||
|
||||
function prepare($argarray)
|
||||
{
|
||||
parent::prepare($argarray);
|
||||
|
||||
$subscriber = $this->trimmed('subscriber');
|
||||
|
||||
$this->_profile = Profile::staticGet('id', $subscriber);
|
||||
|
||||
if (empty($this->_profile)) {
|
||||
throw new ClientException(sprintf(_('No such profile id: %d'),
|
||||
$subscriber), 404);
|
||||
}
|
||||
|
||||
// page and count from ApiAction
|
||||
|
||||
$offset = ($this->page-1) * $this->count;
|
||||
|
||||
$this->_subscriptions = Subscription::bySubscriber($subscriber,
|
||||
$offset,
|
||||
$this->count + 1);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handler method
|
||||
*
|
||||
* @param array $argarray is ignored since it's now passed in in prepare()
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
|
||||
function handle($argarray=null)
|
||||
{
|
||||
parent::handle($argarray);
|
||||
switch ($_SERVER['REQUEST_METHOD']) {
|
||||
case 'HEAD':
|
||||
case 'GET':
|
||||
$this->showFeed();
|
||||
break;
|
||||
case 'POST':
|
||||
$this->addSubscription();
|
||||
break;
|
||||
default:
|
||||
$this->clientError(_('HTTP method not supported.'), 405);
|
||||
return;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the feed of subscriptions
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
|
||||
function showFeed()
|
||||
{
|
||||
header('Content-Type: application/atom+xml; charset=utf-8');
|
||||
|
||||
$url = common_local_url('AtomPubSubscriptionFeed',
|
||||
array('subscriber' => $this->_profile->id));
|
||||
|
||||
$feed = new Atom10Feed(true);
|
||||
|
||||
$feed->addNamespace('activity',
|
||||
'http://activitystrea.ms/spec/1.0/');
|
||||
|
||||
$feed->addNamespace('poco',
|
||||
'http://portablecontacts.net/spec/1.0');
|
||||
|
||||
$feed->addNamespace('media',
|
||||
'http://purl.org/syndication/atommedia');
|
||||
|
||||
$feed->id = $url;
|
||||
|
||||
$feed->setUpdated('now');
|
||||
|
||||
$feed->addAuthor($this->_profile->getBestName(),
|
||||
$this->_profile->getURI());
|
||||
|
||||
$feed->setTitle(sprintf(_("%s subscriptions"),
|
||||
$this->_profile->getBestName()));
|
||||
|
||||
$feed->setSubtitle(sprintf(_("People %s has subscribed to on %s"),
|
||||
$this->_profile->getBestName(),
|
||||
common_config('site', 'name')));
|
||||
|
||||
$feed->addLink(common_local_url('subscriptions',
|
||||
array('nickname' =>
|
||||
$this->_profile->nickname)));
|
||||
|
||||
$feed->addLink($url,
|
||||
array('rel' => 'self',
|
||||
'type' => 'application/atom+xml'));
|
||||
|
||||
// If there's more...
|
||||
|
||||
if ($this->page > 1) {
|
||||
$feed->addLink($url,
|
||||
array('rel' => 'first',
|
||||
'type' => 'application/atom+xml'));
|
||||
|
||||
$feed->addLink(common_local_url('AtomPubSubscriptionFeed',
|
||||
array('subscriber' =>
|
||||
$this->_profile->id),
|
||||
array('page' =>
|
||||
$this->page - 1)),
|
||||
array('rel' => 'prev',
|
||||
'type' => 'application/atom+xml'));
|
||||
}
|
||||
|
||||
if ($this->_subscriptions->N > $this->count) {
|
||||
|
||||
$feed->addLink(common_local_url('AtomPubSubscriptionFeed',
|
||||
array('subscriber' =>
|
||||
$this->_profile->id),
|
||||
array('page' =>
|
||||
$this->page + 1)),
|
||||
array('rel' => 'next',
|
||||
'type' => 'application/atom+xml'));
|
||||
}
|
||||
|
||||
$i = 0;
|
||||
|
||||
// XXX: This is kind of inefficient
|
||||
|
||||
while ($this->_subscriptions->fetch()) {
|
||||
|
||||
// We get one more than needed; skip that one
|
||||
|
||||
$i++;
|
||||
|
||||
if ($i > $this->count) {
|
||||
break;
|
||||
}
|
||||
|
||||
$act = $this->_subscriptions->asActivity();
|
||||
$feed->addEntryRaw($act->asString(false, false, false));
|
||||
}
|
||||
|
||||
$this->raw($feed->getString());
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a new subscription
|
||||
*
|
||||
* Handling the POST method for AtomPub
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
|
||||
function addSubscription()
|
||||
{
|
||||
if (empty($this->auth_user) ||
|
||||
$this->auth_user->id != $this->_profile->id) {
|
||||
throw new ClientException(_("Can't add someone else's".
|
||||
" subscription"), 403);
|
||||
}
|
||||
|
||||
$xml = file_get_contents('php://input');
|
||||
|
||||
$dom = DOMDocument::loadXML($xml);
|
||||
|
||||
if ($dom->documentElement->namespaceURI != Activity::ATOM ||
|
||||
$dom->documentElement->localName != 'entry') {
|
||||
// TRANS: Client error displayed when not using an Atom entry.
|
||||
$this->clientError(_('Atom post must be an Atom entry.'));
|
||||
return;
|
||||
}
|
||||
|
||||
$activity = new Activity($dom->documentElement);
|
||||
|
||||
$sub = null;
|
||||
|
||||
if (Event::handle('StartAtomPubNewActivity', array(&$activity))) {
|
||||
|
||||
if ($activity->verb != ActivityVerb::FOLLOW) {
|
||||
// TRANS: Client error displayed when not using the POST verb.
|
||||
// TRANS: Do not translate POST.
|
||||
$this->clientError(_('Can only handle Follow activities.'));
|
||||
return;
|
||||
}
|
||||
|
||||
$person = $activity->objects[0];
|
||||
|
||||
if ($person->type != ActivityObject::PERSON) {
|
||||
$this->clientError(_('Can only follow people.'));
|
||||
return;
|
||||
}
|
||||
|
||||
// XXX: OStatus discovery (maybe)
|
||||
|
||||
$profile = Profile::fromURI($person->id);
|
||||
|
||||
if (empty($profile)) {
|
||||
$this->clientError(sprintf(_('Unknown profile %s'), $person->id));
|
||||
return;
|
||||
}
|
||||
|
||||
if (Subscription::start($this->_profile, $profile)) {
|
||||
$sub = Subscription::pkeyGet(array('subscriber' => $this->_profile->id,
|
||||
'subscribed' => $profile->id));
|
||||
}
|
||||
|
||||
Event::handle('EndAtomPubNewActivity', array($activity, $sub));
|
||||
}
|
||||
|
||||
if (!empty($sub)) {
|
||||
$act = $sub->asActivity();
|
||||
|
||||
header('Content-Type: application/atom+xml; charset=utf-8');
|
||||
header('Content-Location: ' . $act->selfLink);
|
||||
|
||||
$this->startXML();
|
||||
$this->raw($act->asString(true, true, true));
|
||||
$this->endXML();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if read only.
|
||||
*
|
||||
* @param array $args other arguments
|
||||
*
|
||||
* @return boolean is read only action?
|
||||
*/
|
||||
|
||||
function isReadOnly($args)
|
||||
{
|
||||
return $_SERVER['REQUEST_METHOD'] != 'POST';
|
||||
}
|
||||
|
||||
/**
|
||||
* Return last modified, if applicable.
|
||||
*
|
||||
* @return string last modified http header
|
||||
*/
|
||||
|
||||
function lastModified()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return etag, if applicable.
|
||||
*
|
||||
* @return string etag http header
|
||||
*/
|
||||
|
||||
function etag()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Does this require authentication?
|
||||
*
|
||||
* @return boolean true if delete, else false
|
||||
*/
|
||||
|
||||
function requiresAuth()
|
||||
{
|
||||
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
@ -42,7 +42,6 @@ require_once INSTALLDIR.'/lib/attachmentlist.php';
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||
* @link http://status.net/
|
||||
*/
|
||||
|
||||
class AttachmentAction extends Action
|
||||
{
|
||||
/**
|
||||
@ -70,6 +69,7 @@ class AttachmentAction extends Action
|
||||
}
|
||||
|
||||
if (empty($this->attachment)) {
|
||||
// TRANS: Client error displayed trying to get a non-existing attachment.
|
||||
$this->clientError(_('No such attachment.'), 404);
|
||||
return false;
|
||||
}
|
||||
@ -81,7 +81,6 @@ class AttachmentAction extends Action
|
||||
*
|
||||
* @return boolean true
|
||||
*/
|
||||
|
||||
function isReadOnly($args)
|
||||
{
|
||||
return true;
|
||||
@ -129,7 +128,6 @@ class AttachmentAction extends Action
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
|
||||
function handle($args)
|
||||
{
|
||||
parent::handle($args);
|
||||
@ -150,7 +148,6 @@ class AttachmentAction extends Action
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
|
||||
function showLocalNavBlock()
|
||||
{
|
||||
}
|
||||
@ -162,7 +159,6 @@ class AttachmentAction extends Action
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
|
||||
function showContent()
|
||||
{
|
||||
$ali = new Attachment($this->attachment, $this);
|
||||
@ -174,7 +170,6 @@ class AttachmentAction extends Action
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
|
||||
function showPageNoticeBlock()
|
||||
{
|
||||
}
|
||||
@ -191,4 +186,3 @@ class AttachmentAction extends Action
|
||||
$atcs->show();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -42,7 +42,6 @@ require_once INSTALLDIR.'/actions/attachment.php';
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||
* @link http://status.net/
|
||||
*/
|
||||
|
||||
class Attachment_ajaxAction extends AttachmentAction
|
||||
{
|
||||
/**
|
||||
@ -80,4 +79,3 @@ class Attachment_ajaxAction extends AttachmentAction
|
||||
$this->elementEnd('div');
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -42,10 +42,8 @@ require_once INSTALLDIR.'/actions/attachment.php';
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||
* @link http://status.net/
|
||||
*/
|
||||
|
||||
class Attachment_thumbnailAction extends AttachmentAction
|
||||
{
|
||||
|
||||
function handle($args)
|
||||
{
|
||||
$this->showPage();
|
||||
@ -79,6 +77,4 @@ class Attachment_thumbnailAction extends AttachmentAction
|
||||
}
|
||||
$this->element('img', array('src' => $file_thumbnail->url, 'alt' => 'Thumbnail'));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
@ -48,7 +48,7 @@ class AvatarbynicknameAction extends Action
|
||||
* Class handler.
|
||||
*
|
||||
* @param array $args query arguments
|
||||
*
|
||||
*
|
||||
* @return boolean false if nickname or user isn't found
|
||||
*/
|
||||
function handle($args)
|
||||
@ -56,27 +56,32 @@ class AvatarbynicknameAction extends Action
|
||||
parent::handle($args);
|
||||
$nickname = $this->trimmed('nickname');
|
||||
if (!$nickname) {
|
||||
// TRANS: Client error displayed trying to get an avatar without providing a nickname.
|
||||
$this->clientError(_('No nickname.'));
|
||||
return;
|
||||
}
|
||||
$size = $this->trimmed('size');
|
||||
if (!$size) {
|
||||
// TRANS: Client error displayed trying to get an avatar without providing an avatar size.
|
||||
$this->clientError(_('No size.'));
|
||||
return;
|
||||
}
|
||||
$size = strtolower($size);
|
||||
if (!in_array($size, array('original', '96', '48', '24'))) {
|
||||
// TRANS: Client error displayed trying to get an avatar providing an invalid avatar size.
|
||||
$this->clientError(_('Invalid size.'));
|
||||
return;
|
||||
}
|
||||
|
||||
$user = User::staticGet('nickname', $nickname);
|
||||
if (!$user) {
|
||||
// TRANS: Client error displayed trying to get an avatar for a non-existing user.
|
||||
$this->clientError(_('No such user.'));
|
||||
return;
|
||||
}
|
||||
$profile = $user->getProfile();
|
||||
if (!$profile) {
|
||||
// TRANS: Client error displayed trying to get an avatar for a user without a profile.
|
||||
$this->clientError(_('User has no profile.'));
|
||||
return;
|
||||
}
|
||||
@ -103,4 +108,3 @@ class AvatarbynicknameAction extends Action
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -49,7 +49,6 @@ define('MAX_ORIGINAL', 480);
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||
* @link http://status.net/
|
||||
*/
|
||||
|
||||
class AvatarsettingsAction extends AccountSettingsAction
|
||||
{
|
||||
var $mode = null;
|
||||
@ -61,9 +60,9 @@ class AvatarsettingsAction extends AccountSettingsAction
|
||||
*
|
||||
* @return string Title of the page
|
||||
*/
|
||||
|
||||
function title()
|
||||
{
|
||||
// TRANS: Title for avatar upload page.
|
||||
return _('Avatar');
|
||||
}
|
||||
|
||||
@ -72,10 +71,12 @@ class AvatarsettingsAction extends AccountSettingsAction
|
||||
*
|
||||
* @return instructions for use
|
||||
*/
|
||||
|
||||
function getInstructions()
|
||||
{
|
||||
return sprintf(_('You can upload your personal avatar. The maximum file size is %s.'), ImageFile::maxFileSize());
|
||||
// TRANS: Instruction for avatar upload page.
|
||||
// TRANS: %s is the maximum file size, for example "500b", "10kB" or "2MB".
|
||||
return sprintf(_('You can upload your personal avatar. The maximum file size is %s.'),
|
||||
ImageFile::maxFileSize());
|
||||
}
|
||||
|
||||
/**
|
||||
@ -103,6 +104,7 @@ class AvatarsettingsAction extends AccountSettingsAction
|
||||
|
||||
if (!$profile) {
|
||||
common_log_db_error($user, 'SELECT', __FILE__);
|
||||
// TRANS: Server error displayed in avatar upload page when no matching profile can be found for a user.
|
||||
$this->serverError(_('User without matching profile.'));
|
||||
return;
|
||||
}
|
||||
@ -116,14 +118,16 @@ class AvatarsettingsAction extends AccountSettingsAction
|
||||
'action' =>
|
||||
common_local_url('avatarsettings')));
|
||||
$this->elementStart('fieldset');
|
||||
// TRANS: Avatar upload page form legend.
|
||||
$this->element('legend', null, _('Avatar settings'));
|
||||
$this->hidden('token', common_session_token());
|
||||
|
||||
|
||||
if (Event::handle('StartAvatarFormData', array($this))) {
|
||||
$this->elementStart('ul', 'form_data');
|
||||
if ($original) {
|
||||
$this->elementStart('li', array('id' => 'avatar_original',
|
||||
'class' => 'avatar_view'));
|
||||
// TRANS: Header on avatar upload page for thumbnail of originally uploaded avatar (h2).
|
||||
$this->element('h2', null, _("Original"));
|
||||
$this->elementStart('div', array('id'=>'avatar_original_view'));
|
||||
$this->element('img', array('src' => $original->url,
|
||||
@ -139,6 +143,7 @@ class AvatarsettingsAction extends AccountSettingsAction
|
||||
if ($avatar) {
|
||||
$this->elementStart('li', array('id' => 'avatar_preview',
|
||||
'class' => 'avatar_view'));
|
||||
// TRANS: Header on avatar upload page for thumbnail of to be used rendition of uploaded avatar (h2).
|
||||
$this->element('h2', null, _("Preview"));
|
||||
$this->elementStart('div', array('id'=>'avatar_preview_view'));
|
||||
$this->element('img', array('src' => $original->url,
|
||||
@ -146,7 +151,8 @@ class AvatarsettingsAction extends AccountSettingsAction
|
||||
'height' => AVATAR_PROFILE_SIZE,
|
||||
'alt' => $user->nickname));
|
||||
$this->elementEnd('div');
|
||||
$this->submit('delete', _('Delete'));
|
||||
// TRANS: Button on avatar upload page to delete current avatar.
|
||||
$this->submit('delete', _m('BUTTON','Delete'));
|
||||
$this->elementEnd('li');
|
||||
}
|
||||
|
||||
@ -163,7 +169,8 @@ class AvatarsettingsAction extends AccountSettingsAction
|
||||
|
||||
$this->elementStart('ul', 'form_actions');
|
||||
$this->elementStart('li');
|
||||
$this->submit('upload', _('Upload'));
|
||||
// TRANS: Button on avatar upload page to upload an avatar.
|
||||
$this->submit('upload', _m('BUTTON','Upload'));
|
||||
$this->elementEnd('li');
|
||||
$this->elementEnd('ul');
|
||||
}
|
||||
@ -171,7 +178,6 @@ class AvatarsettingsAction extends AccountSettingsAction
|
||||
|
||||
$this->elementEnd('fieldset');
|
||||
$this->elementEnd('form');
|
||||
|
||||
}
|
||||
|
||||
function showCropForm()
|
||||
@ -182,6 +188,7 @@ class AvatarsettingsAction extends AccountSettingsAction
|
||||
|
||||
if (!$profile) {
|
||||
common_log_db_error($user, 'SELECT', __FILE__);
|
||||
// TRANS: Server error displayed in avatar upload page when no matching profile can be found for a user.
|
||||
$this->serverError(_('User without matching profile.'));
|
||||
return;
|
||||
}
|
||||
@ -194,6 +201,7 @@ class AvatarsettingsAction extends AccountSettingsAction
|
||||
'action' =>
|
||||
common_local_url('avatarsettings')));
|
||||
$this->elementStart('fieldset');
|
||||
// TRANS: Avatar upload page crop form legend.
|
||||
$this->element('legend', null, _('Avatar settings'));
|
||||
$this->hidden('token', common_session_token());
|
||||
|
||||
@ -202,6 +210,7 @@ class AvatarsettingsAction extends AccountSettingsAction
|
||||
$this->elementStart('li',
|
||||
array('id' => 'avatar_original',
|
||||
'class' => 'avatar_view'));
|
||||
// TRANS: Header on avatar upload crop form for thumbnail of originally uploaded avatar (h2).
|
||||
$this->element('h2', null, _("Original"));
|
||||
$this->elementStart('div', array('id'=>'avatar_original_view'));
|
||||
$this->element('img', array('src' => Avatar::url($this->filedata['filename']),
|
||||
@ -214,6 +223,7 @@ class AvatarsettingsAction extends AccountSettingsAction
|
||||
$this->elementStart('li',
|
||||
array('id' => 'avatar_preview',
|
||||
'class' => 'avatar_view'));
|
||||
// TRANS: Header on avatar upload crop form for thumbnail of to be used rendition of uploaded avatar (h2).
|
||||
$this->element('h2', null, _("Preview"));
|
||||
$this->elementStart('div', array('id'=>'avatar_preview_view'));
|
||||
$this->element('img', array('src' => Avatar::url($this->filedata['filename']),
|
||||
@ -228,13 +238,14 @@ class AvatarsettingsAction extends AccountSettingsAction
|
||||
'type' => 'hidden',
|
||||
'id' => $crop_info));
|
||||
}
|
||||
$this->submit('crop', _('Crop'));
|
||||
|
||||
// TRANS: Button on avatar upload crop form to confirm a selected crop as avatar.
|
||||
$this->submit('crop', _m('BUTTON','Crop'));
|
||||
|
||||
$this->elementEnd('li');
|
||||
$this->elementEnd('ul');
|
||||
$this->elementEnd('fieldset');
|
||||
$this->elementEnd('form');
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@ -244,7 +255,6 @@ class AvatarsettingsAction extends AccountSettingsAction
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
|
||||
function handlePost()
|
||||
{
|
||||
// Workaround for PHP returning empty $_POST and $_FILES when POST
|
||||
@ -254,9 +264,11 @@ class AvatarsettingsAction extends AccountSettingsAction
|
||||
&& empty($_POST)
|
||||
&& ($_SERVER['CONTENT_LENGTH'] > 0)
|
||||
) {
|
||||
$msg = _('The server was unable to handle that much POST ' .
|
||||
'data (%s bytes) due to its current configuration.');
|
||||
|
||||
// TRANS: Client error displayed when the number of bytes in a POST request exceeds a limit.
|
||||
// TRANS: %s is the number of bytes of the CONTENT_LENGTH.
|
||||
$msg = _m('The server was unable to handle that much POST data (%s byte) due to its current configuration.',
|
||||
'The server was unable to handle that much POST data (%s bytes) due to its current configuration.',
|
||||
intval($_SERVER['CONTENT_LENGTH']));
|
||||
$this->showForm(sprintf($msg, $_SERVER['CONTENT_LENGTH']));
|
||||
return;
|
||||
}
|
||||
@ -269,7 +281,7 @@ class AvatarsettingsAction extends AccountSettingsAction
|
||||
'Try again, please.'));
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (Event::handle('StartAvatarSaveForm', array($this))) {
|
||||
if ($this->arg('upload')) {
|
||||
$this->uploadAvatar();
|
||||
@ -278,6 +290,7 @@ class AvatarsettingsAction extends AccountSettingsAction
|
||||
} else if ($this->arg('delete')) {
|
||||
$this->deleteAvatar();
|
||||
} else {
|
||||
// TRANS: Unexpected validation error on avatar upload form.
|
||||
$this->showForm(_('Unexpected form submission.'));
|
||||
}
|
||||
Event::handle('EndAvatarSaveForm', array($this));
|
||||
@ -292,7 +305,6 @@ class AvatarsettingsAction extends AccountSettingsAction
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
|
||||
function uploadAvatar()
|
||||
{
|
||||
try {
|
||||
@ -302,6 +314,7 @@ class AvatarsettingsAction extends AccountSettingsAction
|
||||
return;
|
||||
}
|
||||
if ($imagefile === null) {
|
||||
// TRANS: Validation error on avatar upload form when no file was uploaded.
|
||||
$this->showForm(_('No file uploaded.'));
|
||||
return;
|
||||
}
|
||||
@ -329,6 +342,7 @@ class AvatarsettingsAction extends AccountSettingsAction
|
||||
|
||||
$this->mode = 'crop';
|
||||
|
||||
// TRANS: Avatar upload form unstruction after uploading a file.
|
||||
$this->showForm(_('Pick a square area of the image to be your avatar'),
|
||||
true);
|
||||
}
|
||||
@ -338,12 +352,12 @@ class AvatarsettingsAction extends AccountSettingsAction
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
|
||||
function cropAvatar()
|
||||
{
|
||||
$filedata = $_SESSION['FILEDATA'];
|
||||
|
||||
if (!$filedata) {
|
||||
// TRANS: Server error displayed if an avatar upload went wrong somehow server side.
|
||||
$this->serverError(_('Lost our file data.'));
|
||||
return;
|
||||
}
|
||||
@ -367,24 +381,25 @@ class AvatarsettingsAction extends AccountSettingsAction
|
||||
@unlink($filedata['filepath']);
|
||||
unset($_SESSION['FILEDATA']);
|
||||
$this->mode = 'upload';
|
||||
// TRANS: Success message for having updated a user avatar.
|
||||
$this->showForm(_('Avatar updated.'), true);
|
||||
common_broadcast_profile($profile);
|
||||
} else {
|
||||
// TRANS: Error displayed on the avatar upload page if the avatar could not be updated for an unknown reason.
|
||||
$this->showForm(_('Failed updating avatar.'));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get rid of the current avatar.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
|
||||
function deleteAvatar()
|
||||
{
|
||||
$user = common_current_user();
|
||||
$profile = $user->getProfile();
|
||||
|
||||
|
||||
$avatar = $profile->getOriginalAvatar();
|
||||
if($avatar) $avatar->delete();
|
||||
$avatar = $profile->getAvatar(AVATAR_PROFILE_SIZE);
|
||||
@ -394,6 +409,7 @@ class AvatarsettingsAction extends AccountSettingsAction
|
||||
$avatar = $profile->getAvatar(AVATAR_MINI_SIZE);
|
||||
if($avatar) $avatar->delete();
|
||||
|
||||
// TRANS: Success message for deleting a user avatar.
|
||||
$this->showForm(_('Avatar deleted.'), true);
|
||||
}
|
||||
|
||||
@ -414,7 +430,6 @@ class AvatarsettingsAction extends AccountSettingsAction
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
|
||||
function showScripts()
|
||||
{
|
||||
parent::showScripts();
|
||||
|
@ -42,7 +42,6 @@ if (!defined('STATUSNET') && !defined('LACONICA')) {
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl.html AGPLv3
|
||||
* @link http://status.net/
|
||||
*/
|
||||
|
||||
class BlockAction extends ProfileFormAction
|
||||
{
|
||||
var $profile = null;
|
||||
@ -54,7 +53,6 @@ class BlockAction extends ProfileFormAction
|
||||
*
|
||||
* @return boolean success flag
|
||||
*/
|
||||
|
||||
function prepare($args)
|
||||
{
|
||||
if (!parent::prepare($args)) {
|
||||
@ -66,6 +64,7 @@ class BlockAction extends ProfileFormAction
|
||||
assert(!empty($cur)); // checked by parent
|
||||
|
||||
if ($cur->hasBlocked($this->profile)) {
|
||||
// TRANS: Client error displayed when blocking a user that has already been blocked.
|
||||
$this->clientError(_('You already blocked that user.'));
|
||||
return false;
|
||||
}
|
||||
@ -82,7 +81,6 @@ class BlockAction extends ProfileFormAction
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
|
||||
function handle($args)
|
||||
{
|
||||
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
|
||||
@ -104,6 +102,7 @@ class BlockAction extends ProfileFormAction
|
||||
}
|
||||
|
||||
function title() {
|
||||
// TRANS: Title for block user page.
|
||||
return _('Block user');
|
||||
}
|
||||
|
||||
@ -133,8 +132,10 @@ class BlockAction extends ProfileFormAction
|
||||
'action' => common_local_url('block')));
|
||||
$this->elementStart('fieldset');
|
||||
$this->hidden('token', common_session_token());
|
||||
// TRANS: Legend for block user form.
|
||||
$this->element('legend', _('Block user'));
|
||||
$this->element('p', null,
|
||||
// TRANS: Explanation of consequences when blocking a user on the block user page.
|
||||
_('Are you sure you want to block this user? '.
|
||||
'Afterwards, they will be unsubscribed from you, '.
|
||||
'unable to subscribe to you in the future, and '.
|
||||
@ -184,6 +185,7 @@ class BlockAction extends ProfileFormAction
|
||||
}
|
||||
|
||||
if (!$result) {
|
||||
// TRANS: Server error displayed when blocking a user fails.
|
||||
$this->serverError(_('Failed to save block information.'));
|
||||
return;
|
||||
}
|
||||
@ -199,7 +201,7 @@ class BlockAction extends ProfileFormAction
|
||||
* Override for form session token checks; on our first hit we're just
|
||||
* requesting confirmation, which doesn't need a token. We need to be
|
||||
* able to take regular GET requests from email!
|
||||
*
|
||||
*
|
||||
* @throws ClientException if token is bad on POST request or if we have
|
||||
* confirmation parameters which could trigger something.
|
||||
*/
|
||||
@ -216,7 +218,7 @@ class BlockAction extends ProfileFormAction
|
||||
/**
|
||||
* If we reached this form without returnto arguments, return to the
|
||||
* current user's subscription list.
|
||||
*
|
||||
*
|
||||
* @return string URL
|
||||
*/
|
||||
function defaultReturnTo()
|
||||
|
@ -40,7 +40,6 @@ if (!defined('STATUSNET') && !defined('LACONICA')) {
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||
* @link http://status.net/
|
||||
*/
|
||||
|
||||
class BlockedfromgroupAction extends GroupDesignAction
|
||||
{
|
||||
var $page = null;
|
||||
@ -70,6 +69,7 @@ class BlockedfromgroupAction extends GroupDesignAction
|
||||
}
|
||||
|
||||
if (!$nickname) {
|
||||
// TRANS: Client error displayed when requesting a list of blocked users for a group without providing a group nickname.
|
||||
$this->clientError(_('No nickname.'), 404);
|
||||
return false;
|
||||
}
|
||||
@ -77,6 +77,7 @@ class BlockedfromgroupAction extends GroupDesignAction
|
||||
$local = Local_group::staticGet('nickname', $nickname);
|
||||
|
||||
if (!$local) {
|
||||
// TRANS: Client error displayed when requesting a list of blocked users for a non-local group.
|
||||
$this->clientError(_('No such group.'), 404);
|
||||
return false;
|
||||
}
|
||||
@ -84,6 +85,7 @@ class BlockedfromgroupAction extends GroupDesignAction
|
||||
$this->group = User_group::staticGet('id', $local->group_id);
|
||||
|
||||
if (!$this->group) {
|
||||
// TRANS: Client error displayed when requesting a list of blocked users for a non-existing group.
|
||||
$this->clientError(_('No such group.'), 404);
|
||||
return false;
|
||||
}
|
||||
@ -94,9 +96,13 @@ class BlockedfromgroupAction extends GroupDesignAction
|
||||
function title()
|
||||
{
|
||||
if ($this->page == 1) {
|
||||
// TRANS: Title for first page with list of users blocked from a group.
|
||||
// TRANS: %s is a group nickname.
|
||||
return sprintf(_('%s blocked profiles'),
|
||||
$this->group->nickname);
|
||||
} else {
|
||||
// TRANS: Title for any but the first page with list of users blocked from a group.
|
||||
// TRANS: %1$s is a group nickname, %2$d is a page number.
|
||||
return sprintf(_('%1$s blocked profiles, page %2$d'),
|
||||
$this->group->nickname,
|
||||
$this->page);
|
||||
@ -112,6 +118,7 @@ class BlockedfromgroupAction extends GroupDesignAction
|
||||
function showPageNotice()
|
||||
{
|
||||
$this->element('p', 'instructions',
|
||||
// TRANS: Instructions for list of users blocked from a group.
|
||||
_('A list of the users blocked from joining this group.'));
|
||||
}
|
||||
|
||||
@ -205,7 +212,6 @@ class GroupBlockListItem extends ProfileListItem
|
||||
*
|
||||
* @see UnblockForm
|
||||
*/
|
||||
|
||||
class GroupUnblockForm extends Form
|
||||
{
|
||||
/**
|
||||
@ -234,7 +240,6 @@ class GroupUnblockForm extends Form
|
||||
* @param User_group $group group to block user from
|
||||
* @param array $args return-to args
|
||||
*/
|
||||
|
||||
function __construct($out=null, $profile=null, $group=null, $args=null)
|
||||
{
|
||||
parent::__construct($out);
|
||||
@ -249,7 +254,6 @@ class GroupUnblockForm extends Form
|
||||
*
|
||||
* @return int ID of the form
|
||||
*/
|
||||
|
||||
function id()
|
||||
{
|
||||
// This should be unique for the page.
|
||||
@ -261,7 +265,6 @@ class GroupUnblockForm extends Form
|
||||
*
|
||||
* @return string class of the form
|
||||
*/
|
||||
|
||||
function formClass()
|
||||
{
|
||||
return 'form_group_unblock';
|
||||
@ -272,7 +275,6 @@ class GroupUnblockForm extends Form
|
||||
*
|
||||
* @return string URL of the action
|
||||
*/
|
||||
|
||||
function action()
|
||||
{
|
||||
return common_local_url('groupunblock');
|
||||
@ -285,6 +287,7 @@ class GroupUnblockForm extends Form
|
||||
*/
|
||||
function formLegend()
|
||||
{
|
||||
// TRANS: Form legend for unblocking a user from a group.
|
||||
$this->out->element('legend', null, _('Unblock user from group'));
|
||||
}
|
||||
|
||||
@ -293,7 +296,6 @@ class GroupUnblockForm extends Form
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
|
||||
function formData()
|
||||
{
|
||||
$this->out->hidden('unblockto-' . $this->profile->id,
|
||||
@ -314,9 +316,14 @@ class GroupUnblockForm extends Form
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
|
||||
function formActions()
|
||||
{
|
||||
$this->out->submit('submit', _('Unblock'), 'submit', null, _('Unblock this user'));
|
||||
$this->out->submit('submit',
|
||||
// TRANS: Button text for unblocking a user from a group.
|
||||
_m('BUTTON','Unblock'),
|
||||
'submit',
|
||||
null,
|
||||
// TRANS: Tooltip for button for unblocking a user from a group.
|
||||
_('Unblock this user'));
|
||||
}
|
||||
}
|
||||
|
@ -34,7 +34,7 @@ if (!defined('STATUSNET') && !defined('LACONICA')) {
|
||||
require_once INSTALLDIR . '/actions/newnotice.php';
|
||||
|
||||
/**
|
||||
* Action for posting a notice
|
||||
* Action for posting a notice
|
||||
*
|
||||
* @category Bookmarklet
|
||||
* @package StatusNet
|
||||
@ -42,12 +42,12 @@ require_once INSTALLDIR . '/actions/newnotice.php';
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||
* @link http://status.net/
|
||||
*/
|
||||
|
||||
class BookmarkletAction extends NewnoticeAction
|
||||
{
|
||||
function showTitle()
|
||||
{
|
||||
// TRANS: Title for mini-posting window loaded from bookmarklet.
|
||||
// TRANS: %s is the StatusNet site name.
|
||||
$this->element('title', null, sprintf(_('Post to %s'), common_config('site', 'name')));
|
||||
}
|
||||
|
||||
@ -73,4 +73,3 @@ class BookmarkletAction extends NewnoticeAction
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -44,7 +44,6 @@ if (!defined('STATUSNET') && !defined('LACONICA')) {
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||
* @link http://status.net/
|
||||
*/
|
||||
|
||||
class ConfirmaddressAction extends Action
|
||||
{
|
||||
/** type of confirmation. */
|
||||
@ -61,7 +60,6 @@ class ConfirmaddressAction extends Action
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
|
||||
function handle($args)
|
||||
{
|
||||
parent::handle($args);
|
||||
@ -72,16 +70,19 @@ class ConfirmaddressAction extends Action
|
||||
}
|
||||
$code = $this->trimmed('code');
|
||||
if (!$code) {
|
||||
// TRANS: Client error displayed when not providing a confirmation code in the contact address confirmation action.
|
||||
$this->clientError(_('No confirmation code.'));
|
||||
return;
|
||||
}
|
||||
$confirm = Confirm_address::staticGet('code', $code);
|
||||
if (!$confirm) {
|
||||
// TRANS: Client error displayed when providing a non-existing confirmation code in the contact address confirmation action.
|
||||
$this->clientError(_('Confirmation code not found.'));
|
||||
return;
|
||||
}
|
||||
$cur = common_current_user();
|
||||
if ($cur->id != $confirm->user_id) {
|
||||
// TRANS: Client error displayed when not providing a confirmation code for another user in the contact address confirmation action.
|
||||
$this->clientError(_('That confirmation code is not for you!'));
|
||||
return;
|
||||
}
|
||||
@ -98,6 +99,7 @@ class ConfirmaddressAction extends Action
|
||||
if (in_array($type, array('email', 'sms')))
|
||||
{
|
||||
if ($cur->$type == $confirm->address) {
|
||||
// TRANS: Client error for an already confirmed email/jabber/sms address.
|
||||
$this->clientError(_('That address has already been confirmed.'));
|
||||
return;
|
||||
}
|
||||
@ -162,7 +164,9 @@ class ConfirmaddressAction extends Action
|
||||
|
||||
if (!$result) {
|
||||
common_log_db_error($confirm, 'DELETE', __FILE__);
|
||||
$this->serverError(_('Couldn\'t delete email confirmation.'));
|
||||
// TRANS: Server error displayed when an address confirmation code deletion from the
|
||||
// TRANS: database fails in the contact address confirmation action.
|
||||
$this->serverError(_('Could not delete address confirmation.'));
|
||||
return;
|
||||
}
|
||||
|
||||
@ -175,9 +179,9 @@ class ConfirmaddressAction extends Action
|
||||
*
|
||||
* @return string title
|
||||
*/
|
||||
|
||||
function title()
|
||||
{
|
||||
// TRANS: Title for the contact address confirmation action.
|
||||
return _('Confirm address');
|
||||
}
|
||||
|
||||
@ -186,12 +190,13 @@ class ConfirmaddressAction extends Action
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
|
||||
function showContent()
|
||||
{
|
||||
$cur = common_current_user();
|
||||
|
||||
$this->element('p', null,
|
||||
// TRANS: Success message for the contact address confirmation action.
|
||||
// TRANS: %s can be 'email', 'jabber', or 'sms'.
|
||||
sprintf(_('The address "%s" has been '.
|
||||
'confirmed for your account.'),
|
||||
$this->address));
|
||||
|
@ -45,7 +45,6 @@ require_once INSTALLDIR.'/lib/noticelist.php';
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl.html AGPLv3
|
||||
* @link http://status.net/
|
||||
*/
|
||||
|
||||
class ConversationAction extends Action
|
||||
{
|
||||
var $id = null;
|
||||
@ -58,7 +57,6 @@ class ConversationAction extends Action
|
||||
*
|
||||
* @return boolean false if id not passed in
|
||||
*/
|
||||
|
||||
function prepare($args)
|
||||
{
|
||||
parent::prepare($args);
|
||||
@ -81,7 +79,6 @@ class ConversationAction extends Action
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
|
||||
function handle($args)
|
||||
{
|
||||
parent::handle($args);
|
||||
@ -93,10 +90,10 @@ class ConversationAction extends Action
|
||||
*
|
||||
* @return string page title
|
||||
*/
|
||||
|
||||
function title()
|
||||
{
|
||||
return _("Conversation");
|
||||
// TRANS: Title for page with a conversion (multiple notices in context).
|
||||
return _('Conversation');
|
||||
}
|
||||
|
||||
/**
|
||||
@ -107,7 +104,6 @@ class ConversationAction extends Action
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
|
||||
function showContent()
|
||||
{
|
||||
$notices = Notice::conversationStream($this->id, null, null);
|
||||
@ -134,7 +130,6 @@ class ConversationAction extends Action
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl.html AGPLv3
|
||||
* @link http://status.net/
|
||||
*/
|
||||
|
||||
class ConversationTree extends NoticeList
|
||||
{
|
||||
var $tree = null;
|
||||
@ -145,12 +140,12 @@ class ConversationTree extends NoticeList
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
|
||||
function show()
|
||||
{
|
||||
$cnt = $this->_buildTree();
|
||||
|
||||
$this->out->elementStart('div', array('id' =>'notices_primary'));
|
||||
// TRANS: Header on conversation page. Hidden by default (h2).
|
||||
$this->out->element('h2', null, _('Notices'));
|
||||
$this->out->elementStart('ol', array('class' => 'notices xoxo'));
|
||||
|
||||
@ -200,7 +195,6 @@ class ConversationTree extends NoticeList
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
|
||||
function showNoticePlus($id)
|
||||
{
|
||||
$notice = $this->table[$id];
|
||||
@ -237,7 +231,6 @@ class ConversationTree extends NoticeList
|
||||
*
|
||||
* @return NoticeListItem a list item to show
|
||||
*/
|
||||
|
||||
function newListItem($notice)
|
||||
{
|
||||
return new ConversationTreeItem($notice, $this->out);
|
||||
@ -255,7 +248,6 @@ class ConversationTree extends NoticeList
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl.html AGPLv3
|
||||
* @link http://status.net/
|
||||
*/
|
||||
|
||||
class ConversationTreeItem extends NoticeListItem
|
||||
{
|
||||
/**
|
||||
@ -266,7 +258,6 @@ class ConversationTreeItem extends NoticeListItem
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
|
||||
function showStart()
|
||||
{
|
||||
return;
|
||||
@ -280,7 +271,6 @@ class ConversationTreeItem extends NoticeListItem
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
|
||||
function showEnd()
|
||||
{
|
||||
return;
|
||||
@ -293,7 +283,6 @@ class ConversationTreeItem extends NoticeListItem
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
|
||||
function showContext()
|
||||
{
|
||||
return;
|
||||
|
@ -40,7 +40,6 @@ if (!defined('STATUSNET') && !defined('LACONICA')) {
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl.html AGPLv3
|
||||
* @link http://status.net/
|
||||
*/
|
||||
|
||||
class DeleteapplicationAction extends Action
|
||||
{
|
||||
var $app = null;
|
||||
@ -52,7 +51,6 @@ class DeleteapplicationAction extends Action
|
||||
*
|
||||
* @return boolean success flag
|
||||
*/
|
||||
|
||||
function prepare($args)
|
||||
{
|
||||
if (!parent::prepare($args)) {
|
||||
@ -60,6 +58,7 @@ class DeleteapplicationAction extends Action
|
||||
}
|
||||
|
||||
if (!common_logged_in()) {
|
||||
// TRANS: Client error displayed trying to delete an application while not logged in.
|
||||
$this->clientError(_('You must be logged in to delete an application.'));
|
||||
return false;
|
||||
}
|
||||
@ -68,6 +67,7 @@ class DeleteapplicationAction extends Action
|
||||
$this->app = Oauth_application::staticGet('id', $id);
|
||||
|
||||
if (empty($this->app)) {
|
||||
// TRANS: Client error displayed trying to delete an application that does not exist.
|
||||
$this->clientError(_('Application not found.'));
|
||||
return false;
|
||||
}
|
||||
@ -75,6 +75,7 @@ class DeleteapplicationAction extends Action
|
||||
$cur = common_current_user();
|
||||
|
||||
if ($cur->id != $this->app->owner) {
|
||||
// TRANS: Client error displayed trying to delete an application the current user does not own.
|
||||
$this->clientError(_('You are not the owner of this application.'), 401);
|
||||
return false;
|
||||
}
|
||||
@ -91,7 +92,6 @@ class DeleteapplicationAction extends Action
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
|
||||
function handle($args)
|
||||
{
|
||||
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
|
||||
@ -120,6 +120,7 @@ class DeleteapplicationAction extends Action
|
||||
}
|
||||
|
||||
function title() {
|
||||
// TRANS: Title for delete application page.
|
||||
return _('Delete application');
|
||||
}
|
||||
|
||||
@ -144,8 +145,10 @@ class DeleteapplicationAction extends Action
|
||||
array('id' => $this->app->id))));
|
||||
$this->elementStart('fieldset');
|
||||
$this->hidden('token', common_session_token());
|
||||
// TRANS: Fieldset legend on delete application page.
|
||||
$this->element('legend', _('Delete application'));
|
||||
$this->element('p', null,
|
||||
// TRANS: Confirmation text on delete application page.
|
||||
_('Are you sure you want to delete this application? '.
|
||||
'This will clear all data about the application from the '.
|
||||
'database, including all existing user connections.'));
|
||||
@ -171,10 +174,8 @@ class DeleteapplicationAction extends Action
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
|
||||
function handlePost()
|
||||
{
|
||||
$this->app->delete();
|
||||
}
|
||||
}
|
||||
|
||||
|
235
actions/deletegroup.php
Normal file
235
actions/deletegroup.php
Normal file
@ -0,0 +1,235 @@
|
||||
<?php
|
||||
/**
|
||||
* StatusNet, the distributed open-source microblogging tool
|
||||
*
|
||||
* Delete a group
|
||||
*
|
||||
* 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 Group
|
||||
* @package StatusNet
|
||||
* @author Evan Prodromou <evan@status.net>
|
||||
* @author Brion Vibber <brion@status.net>
|
||||
* @copyright 2008-2010 StatusNet, Inc.
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||
* @link http://status.net/
|
||||
*/
|
||||
|
||||
if (!defined('STATUSNET') && !defined('LACONICA')) {
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete a group
|
||||
*
|
||||
* This is the action for deleting a group.
|
||||
*
|
||||
* @category Group
|
||||
* @package StatusNet
|
||||
* @author Evan Prodromou <evan@status.net>
|
||||
* @author Brion Vibber <brion@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/
|
||||
* @fixme merge more of this code with related variants
|
||||
*/
|
||||
class DeletegroupAction extends RedirectingAction
|
||||
{
|
||||
var $group = null;
|
||||
|
||||
/**
|
||||
* Prepare to run
|
||||
*
|
||||
* @fixme merge common setup code with other group actions
|
||||
* @fixme allow group admins to delete their own groups
|
||||
*/
|
||||
function prepare($args)
|
||||
{
|
||||
parent::prepare($args);
|
||||
|
||||
if (!common_logged_in()) {
|
||||
// TRANS: Client error when trying to delete group while not logged in.
|
||||
$this->clientError(_('You must be logged in to delete a group.'));
|
||||
return false;
|
||||
}
|
||||
|
||||
$nickname_arg = $this->trimmed('nickname');
|
||||
$id = intval($this->arg('id'));
|
||||
if ($id) {
|
||||
$this->group = User_group::staticGet('id', $id);
|
||||
} else if ($nickname_arg) {
|
||||
$nickname = common_canonical_nickname($nickname_arg);
|
||||
|
||||
// Permanent redirect on non-canonical nickname
|
||||
|
||||
if ($nickname_arg != $nickname) {
|
||||
$args = array('nickname' => $nickname);
|
||||
common_redirect(common_local_url('leavegroup', $args), 301);
|
||||
return false;
|
||||
}
|
||||
|
||||
$local = Local_group::staticGet('nickname', $nickname);
|
||||
|
||||
if (!$local) {
|
||||
// TRANS: Client error when trying to delete a non-local group.
|
||||
$this->clientError(_('No such group.'), 404);
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->group = User_group::staticGet('id', $local->group_id);
|
||||
} else {
|
||||
// TRANS: Client error when trying to delete a group without providing a nickname or ID for the group.
|
||||
$this->clientError(_('No nickname or ID.'), 404);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!$this->group) {
|
||||
// TRANS: Client error when trying to delete a non-existing group.
|
||||
$this->clientError(_('No such group.'), 404);
|
||||
return false;
|
||||
}
|
||||
|
||||
$cur = common_current_user();
|
||||
if (!$cur->hasRight(Right::DELETEGROUP)) {
|
||||
// TRANS: Client error when trying to delete a group without having the rights to delete it.
|
||||
$this->clientError(_('You are not allowed to delete this group.'), 403);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle the request
|
||||
*
|
||||
* On POST, delete the group.
|
||||
*
|
||||
* @param array $args unused
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
function handle($args)
|
||||
{
|
||||
parent::handle($args);
|
||||
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
|
||||
if ($this->arg('no')) {
|
||||
$this->returnToPrevious();
|
||||
return;
|
||||
} elseif ($this->arg('yes')) {
|
||||
$this->handlePost();
|
||||
return;
|
||||
}
|
||||
}
|
||||
$this->showPage();
|
||||
}
|
||||
|
||||
function handlePost()
|
||||
{
|
||||
$cur = common_current_user();
|
||||
|
||||
try {
|
||||
if (Event::handle('StartDeleteGroup', array($this->group))) {
|
||||
$this->group->delete();
|
||||
Event::handle('EndDeleteGroup', array($this->group));
|
||||
}
|
||||
} catch (Exception $e) {
|
||||
// TRANS: Server error displayed if a group could not be deleted.
|
||||
// TRANS: %s is the name of the group that could not be deleted.
|
||||
$this->serverError(sprintf(_('Could not delete group %s.'),
|
||||
$this->group->nickname));
|
||||
}
|
||||
|
||||
if ($this->boolean('ajax')) {
|
||||
$this->startHTML('text/xml;charset=utf-8');
|
||||
$this->elementStart('head');
|
||||
// TRANS: Message given after deleting a group.
|
||||
// TRANS: %s is the deleted group's name.
|
||||
$this->element('title', null, sprintf(_('Deleted group %s'),
|
||||
$this->group->nickname));
|
||||
$this->elementEnd('head');
|
||||
$this->elementStart('body');
|
||||
// @fixme add a sensible AJAX response form!
|
||||
$this->elementEnd('body');
|
||||
$this->elementEnd('html');
|
||||
} else {
|
||||
// @fixme if we could direct to the page on which this group
|
||||
// would have shown... that would be awesome
|
||||
common_redirect(common_local_url('groups'),
|
||||
303);
|
||||
}
|
||||
}
|
||||
|
||||
function title() {
|
||||
// TRANS: Title of delete group page.
|
||||
return _('Delete group');
|
||||
}
|
||||
|
||||
function showContent() {
|
||||
$this->areYouSureForm();
|
||||
}
|
||||
|
||||
/**
|
||||
* Confirm with user.
|
||||
* Ripped from DeleteuserAction
|
||||
*
|
||||
* Shows a confirmation form.
|
||||
*
|
||||
* @fixme refactor common code for things like this
|
||||
* @return void
|
||||
*/
|
||||
function areYouSureForm()
|
||||
{
|
||||
$id = $this->group->id;
|
||||
$this->elementStart('form', array('id' => 'deletegroup-' . $id,
|
||||
'method' => 'post',
|
||||
'class' => 'form_settings form_entity_block',
|
||||
'action' => common_local_url('deletegroup', array('id' => $this->group->id))));
|
||||
$this->elementStart('fieldset');
|
||||
$this->hidden('token', common_session_token());
|
||||
// TRANS: Form legend for deleting a group.
|
||||
$this->element('legend', _('Delete group'));
|
||||
if (Event::handle('StartDeleteGroupForm', array($this, $this->group))) {
|
||||
$this->element('p', null,
|
||||
// TRANS: Warning in form for deleleting a group.
|
||||
_('Are you sure you want to delete this group? '.
|
||||
'This will clear all data about the group from the '.
|
||||
'database, without a backup. ' .
|
||||
'Public posts to this group will still appear in ' .
|
||||
'individual timelines.'));
|
||||
foreach ($this->args as $k => $v) {
|
||||
if (substr($k, 0, 9) == 'returnto-') {
|
||||
$this->hidden($k, $v);
|
||||
}
|
||||
}
|
||||
Event::handle('EndDeleteGroupForm', array($this, $this->group));
|
||||
}
|
||||
$this->submit('form_action-no',
|
||||
// TRANS: Button label on the delete group form.
|
||||
_m('BUTTON','No'),
|
||||
'submit form_action-primary',
|
||||
'no',
|
||||
// TRANS: Submit button title for 'No' when deleting a group.
|
||||
_('Do not delete this group'));
|
||||
$this->submit('form_action-yes',
|
||||
// TRANS: Button label on the delete group form.
|
||||
_m('BUTTON','Yes'),
|
||||
'submit form_action-secondary',
|
||||
'yes',
|
||||
// TRANS: Submit button title for 'Yes' when deleting a group.
|
||||
_('Delete this group'));
|
||||
$this->elementEnd('fieldset');
|
||||
$this->elementEnd('form');
|
||||
}
|
||||
}
|
@ -32,6 +32,7 @@ if (!defined('STATUSNET') && !defined('LACONICA')) {
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// @todo FIXME: documentation needed.
|
||||
class DeletenoticeAction extends Action
|
||||
{
|
||||
var $error = null;
|
||||
@ -45,10 +46,18 @@ class DeletenoticeAction extends Action
|
||||
parent::prepare($args);
|
||||
|
||||
$this->user = common_current_user();
|
||||
|
||||
if (!$this->user) {
|
||||
// TRANS: Error message displayed trying to delete a notice while not logged in.
|
||||
common_user_error(_('Not logged in.'));
|
||||
exit;
|
||||
}
|
||||
|
||||
$notice_id = $this->trimmed('notice');
|
||||
$this->notice = Notice::staticGet($notice_id);
|
||||
|
||||
if (!$this->notice) {
|
||||
// TRANS: Error message displayed trying to delete a non-existing notice.
|
||||
common_user_error(_('No such notice.'));
|
||||
exit;
|
||||
}
|
||||
@ -63,11 +72,9 @@ class DeletenoticeAction extends Action
|
||||
{
|
||||
parent::handle($args);
|
||||
|
||||
if (!common_logged_in()) {
|
||||
common_user_error(_('Not logged in.'));
|
||||
exit;
|
||||
} else if ($this->notice->profile_id != $this->user_profile->id &&
|
||||
if ($this->notice->profile_id != $this->user_profile->id &&
|
||||
!$this->user->hasRight(Right::DELETEOTHERSNOTICE)) {
|
||||
// TRANS: Error message displayed trying to delete a notice that was not made by the current user.
|
||||
common_user_error(_('Can\'t delete this notice.'));
|
||||
exit;
|
||||
}
|
||||
@ -87,7 +94,6 @@ class DeletenoticeAction extends Action
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
|
||||
function showPageNotice()
|
||||
{
|
||||
$instr = $this->getInstructions();
|
||||
@ -100,12 +106,14 @@ class DeletenoticeAction extends Action
|
||||
|
||||
function getInstructions()
|
||||
{
|
||||
// TRANS: Instructions for deleting a notice.
|
||||
return _('You are about to permanently delete a notice. ' .
|
||||
'Once this is done, it cannot be undone.');
|
||||
}
|
||||
|
||||
function title()
|
||||
{
|
||||
// TRANS: Page title when deleting a notice.
|
||||
return _('Delete notice');
|
||||
}
|
||||
|
||||
@ -118,7 +126,6 @@ class DeletenoticeAction extends Action
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
|
||||
function showForm($error = null)
|
||||
{
|
||||
$this->error = $error;
|
||||
@ -130,7 +137,6 @@ class DeletenoticeAction extends Action
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
|
||||
function showContent()
|
||||
{
|
||||
$this->elementStart('form', array('id' => 'form_notice_delete',
|
||||
@ -138,9 +144,11 @@ class DeletenoticeAction extends Action
|
||||
'method' => 'post',
|
||||
'action' => common_local_url('deletenotice')));
|
||||
$this->elementStart('fieldset');
|
||||
// TRANS: Fieldset legend for the delete notice form.
|
||||
$this->element('legend', null, _('Delete notice'));
|
||||
$this->hidden('token', common_session_token());
|
||||
$this->hidden('notice', $this->trimmed('notice'));
|
||||
// TRANS: Message for the delete notice form.
|
||||
$this->element('p', null, _('Are you sure you want to delete this notice?'));
|
||||
$this->submit('form_action-no',
|
||||
// TRANS: Button label on the delete notice form.
|
||||
@ -172,7 +180,10 @@ class DeletenoticeAction extends Action
|
||||
}
|
||||
|
||||
if ($this->arg('yes')) {
|
||||
$this->notice->delete();
|
||||
if (Event::handle('StartDeleteOwnNotice', array($this->user, $this->notice))) {
|
||||
$this->notice->delete();
|
||||
Event::handle('EndDeleteOwnNotice', array($this->user, $this->notice));
|
||||
}
|
||||
}
|
||||
|
||||
$url = common_get_returnto();
|
||||
|
@ -71,7 +71,7 @@ class DesignadminpanelAction extends AdminPanelAction
|
||||
|
||||
function getInstructions()
|
||||
{
|
||||
return _('Design settings for this StatusNet site.');
|
||||
return _('Design settings for this StatusNet site');
|
||||
}
|
||||
|
||||
/**
|
||||
@ -120,8 +120,11 @@ class DesignadminpanelAction extends AdminPanelAction
|
||||
&& empty($_POST)
|
||||
&& ($_SERVER['CONTENT_LENGTH'] > 0)
|
||||
) {
|
||||
$msg = _('The server was unable to handle that much POST ' .
|
||||
'data (%s bytes) due to its current configuration.');
|
||||
// TRANS: Client error displayed when the number of bytes in a POST request exceeds a limit.
|
||||
// TRANS: %s is the number of bytes of the CONTENT_LENGTH.
|
||||
$msg = _m('The server was unable to handle that much POST data (%s byte) due to its current configuration.',
|
||||
'The server was unable to handle that much POST data (%s bytes) due to its current configuration.',
|
||||
intval($_SERVER['CONTENT_LENGTH']));
|
||||
$this->clientException(sprintf($msg, $_SERVER['CONTENT_LENGTH']));
|
||||
return;
|
||||
}
|
||||
@ -140,7 +143,7 @@ class DesignadminpanelAction extends AdminPanelAction
|
||||
$themeChanged = ($this->trimmed('theme') != $oldtheme);
|
||||
}
|
||||
|
||||
static $settings = array('theme', 'logo');
|
||||
static $settings = array('theme', 'logo', 'ssllogo');
|
||||
|
||||
$values = array();
|
||||
|
||||
@ -154,9 +157,22 @@ class DesignadminpanelAction extends AdminPanelAction
|
||||
|
||||
$config->query('BEGIN');
|
||||
|
||||
// Only update colors if the theme has not changed.
|
||||
if ($themeChanged) {
|
||||
// If the theme has changed, reset custom colors and let them pick
|
||||
// up the new theme's defaults.
|
||||
$colors = array('background', 'content', 'sidebar', 'text', 'link');
|
||||
foreach ($colors as $colorKey) {
|
||||
// Clear from global config so we see defaults on this page...
|
||||
$GLOBALS['config']['design'][$colorKey . 'color'] = false;
|
||||
|
||||
if (!$themeChanged) {
|
||||
// And remove old settings from DB...
|
||||
$this->deleteSetting('design', $colorKey . 'color');
|
||||
}
|
||||
} else {
|
||||
// Only save colors from the form if the theme has not changed.
|
||||
//
|
||||
// @fixme a future more ajaxy form should allow theme switch
|
||||
// and color customization in one step.
|
||||
|
||||
$bgcolor = new WebColor($this->trimmed('design_background'));
|
||||
$ccolor = new WebColor($this->trimmed('design_content'));
|
||||
@ -217,6 +233,7 @@ class DesignadminpanelAction extends AdminPanelAction
|
||||
function restoreDefaults()
|
||||
{
|
||||
$this->deleteSetting('site', 'logo');
|
||||
$this->deleteSetting('site', 'ssllogo');
|
||||
$this->deleteSetting('site', 'theme');
|
||||
|
||||
$settings = array(
|
||||
@ -244,8 +261,8 @@ class DesignadminpanelAction extends AdminPanelAction
|
||||
function saveBackgroundImage()
|
||||
{
|
||||
$filename = null;
|
||||
|
||||
if ($_FILES['design_background-image_file']['error'] ==
|
||||
if (isset($_FILES['design_background-image_file']['error']) &&
|
||||
$_FILES['design_background-image_file']['error'] ==
|
||||
UPLOAD_ERR_OK) {
|
||||
|
||||
$filepath = null;
|
||||
@ -280,7 +297,7 @@ class DesignadminpanelAction extends AdminPanelAction
|
||||
|
||||
/**
|
||||
* Save the custom theme if the user uploaded one.
|
||||
*
|
||||
*
|
||||
* @return mixed custom theme name, if succesful, or null if no theme upload.
|
||||
* @throws ClientException for invalid theme archives
|
||||
* @throws ServerException if trouble saving the theme files
|
||||
@ -318,6 +335,11 @@ class DesignadminpanelAction extends AdminPanelAction
|
||||
$this->clientError(_('Invalid logo URL.'));
|
||||
}
|
||||
|
||||
if (!empty($values['ssllogo']) &&
|
||||
!Validate::uri($values['ssllogo'], array('allowed_schemes' => array('https')))) {
|
||||
$this->clientError(_('Invalid SSL logo URL.'));
|
||||
}
|
||||
|
||||
if (!in_array($values['theme'], Theme::listAvailable())) {
|
||||
$this->clientError(sprintf(_("Theme not available: %s."), $values['theme']));
|
||||
}
|
||||
@ -431,6 +453,10 @@ class DesignAdminPanelForm extends AdminForm
|
||||
$this->input('logo', _('Site logo'), 'Logo for the site (full URL)');
|
||||
$this->unli();
|
||||
|
||||
$this->li();
|
||||
$this->input('ssllogo', _('SSL logo'), 'Logo to show on SSL pages');
|
||||
$this->unli();
|
||||
|
||||
$this->out->elementEnd('ul');
|
||||
|
||||
$this->out->elementEnd('fieldset');
|
||||
|
@ -42,7 +42,6 @@ if (!defined('STATUSNET') && !defined('LACONICA')) {
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||
* @link http://status.net/
|
||||
*/
|
||||
|
||||
class EditApplicationAction extends OwnerDesignAction
|
||||
{
|
||||
var $msg = null;
|
||||
@ -51,18 +50,19 @@ class EditApplicationAction extends OwnerDesignAction
|
||||
|
||||
function title()
|
||||
{
|
||||
return _('Edit Application');
|
||||
// TRANS: Title for "Edit application" form.
|
||||
return _('Edit application');
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepare to run
|
||||
*/
|
||||
|
||||
function prepare($args)
|
||||
{
|
||||
parent::prepare($args);
|
||||
|
||||
if (!common_logged_in()) {
|
||||
// TRANS: Client error displayed trying to edit an application while not logged in.
|
||||
$this->clientError(_('You must be logged in to edit an application.'));
|
||||
return false;
|
||||
}
|
||||
@ -74,10 +74,12 @@ class EditApplicationAction extends OwnerDesignAction
|
||||
$cur = common_current_user();
|
||||
|
||||
if ($cur->id != $this->owner->id) {
|
||||
// TRANS: Client error displayed trying to edit an application while not being its owner.
|
||||
$this->clientError(_('You are not the owner of this application.'), 401);
|
||||
}
|
||||
|
||||
if (!$this->app) {
|
||||
// TRANS: Client error displayed trying to edit an application that does not exist.
|
||||
$this->clientError(_('No such application.'));
|
||||
return false;
|
||||
}
|
||||
@ -94,7 +96,6 @@ class EditApplicationAction extends OwnerDesignAction
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
|
||||
function handle($args)
|
||||
{
|
||||
parent::handle($args);
|
||||
@ -115,8 +116,11 @@ class EditApplicationAction extends OwnerDesignAction
|
||||
&& empty($_POST)
|
||||
&& ($_SERVER['CONTENT_LENGTH'] > 0)
|
||||
) {
|
||||
$msg = _('The server was unable to handle that much POST ' .
|
||||
'data (%s bytes) due to its current configuration.');
|
||||
// TRANS: Client error displayed when the number of bytes in a POST request exceeds a limit.
|
||||
// TRANS: %s is the number of bytes of the CONTENT_LENGTH.
|
||||
$msg = _m('The server was unable to handle that much POST data (%s byte) due to its current configuration.',
|
||||
'The server was unable to handle that much POST data (%s bytes) due to its current configuration.',
|
||||
intval($_SERVER['CONTENT_LENGTH']));
|
||||
$this->clientException(sprintf($msg, $_SERVER['CONTENT_LENGTH']));
|
||||
return;
|
||||
}
|
||||
@ -136,6 +140,7 @@ class EditApplicationAction extends OwnerDesignAction
|
||||
} elseif ($this->arg('save')) {
|
||||
$this->trySave();
|
||||
} else {
|
||||
// TRANS: Client error displayed submitting invalid form data for edit application.
|
||||
$this->clientError(_('Unexpected form submission.'));
|
||||
}
|
||||
}
|
||||
@ -158,6 +163,7 @@ class EditApplicationAction extends OwnerDesignAction
|
||||
$this->element('p', 'error', $this->msg);
|
||||
} else {
|
||||
$this->element('p', 'instructions',
|
||||
// TRANS: Instructions for "Edit application" form.
|
||||
_('Use this form to edit your application.'));
|
||||
}
|
||||
}
|
||||
@ -174,36 +180,47 @@ class EditApplicationAction extends OwnerDesignAction
|
||||
$access_type = $this->arg('default_access_type');
|
||||
|
||||
if (empty($name)) {
|
||||
// TRANS: Validation error shown when not providing a name in the "Edit application" form.
|
||||
$this->showForm(_('Name is required.'));
|
||||
return;
|
||||
} elseif (mb_strlen($name) > 255) {
|
||||
$this->showForm(_('Name is too long (max 255 chars).'));
|
||||
// TRANS: Validation error shown when providing too long a name in the "Edit application" form.
|
||||
$this->showForm(_('Name is too long (maximum 255 characters).'));
|
||||
return;
|
||||
} else if ($this->nameExists($name)) {
|
||||
// TRANS: Validation error shown when providing a name for an application that already exists in the "Edit application" form.
|
||||
$this->showForm(_('Name already in use. Try another one.'));
|
||||
return;
|
||||
} elseif (empty($description)) {
|
||||
// TRANS: Validation error shown when not providing a description in the "Edit application" form.
|
||||
$this->showForm(_('Description is required.'));
|
||||
return;
|
||||
} elseif (Oauth_application::descriptionTooLong($description)) {
|
||||
$this->showForm(sprintf(
|
||||
_('Description is too long (max %d chars).'),
|
||||
Oauth_application::maxDescription()));
|
||||
// TRANS: Validation error shown when providing too long a description in the "Edit application" form.
|
||||
_m('Description is too long (maximum %d character).',
|
||||
'Description is too long (maximum %d characters).',
|
||||
Oauth_application::maxDesc()),
|
||||
Oauth_application::maxDesc()));
|
||||
return;
|
||||
} elseif (mb_strlen($source_url) > 255) {
|
||||
// TRANS: Validation error shown when providing too long a source URL in the "Edit application" form.
|
||||
$this->showForm(_('Source URL is too long.'));
|
||||
return;
|
||||
} elseif ((mb_strlen($source_url) > 0)
|
||||
&& !Validate::uri($source_url,
|
||||
array('allowed_schemes' => array('http', 'https'))))
|
||||
{
|
||||
// TRANS: Validation error shown when providing an invalid source URL in the "Edit application" form.
|
||||
$this->showForm(_('Source URL is not valid.'));
|
||||
return;
|
||||
} elseif (empty($organization)) {
|
||||
// TRANS: Validation error shown when not providing an organisation in the "Edit application" form.
|
||||
$this->showForm(_('Organization is required.'));
|
||||
return;
|
||||
} elseif (mb_strlen($organization) > 255) {
|
||||
$this->showForm(_('Organization is too long (max 255 chars).'));
|
||||
// TRANS: Validation error shown when providing too long an arganisation name in the "Edit application" form.
|
||||
$this->showForm(_('Organization is too long (maximum 255 characters).'));
|
||||
return;
|
||||
} elseif (empty($homepage)) {
|
||||
$this->showForm(_('Organization homepage is required.'));
|
||||
@ -212,9 +229,11 @@ class EditApplicationAction extends OwnerDesignAction
|
||||
&& !Validate::uri($homepage,
|
||||
array('allowed_schemes' => array('http', 'https'))))
|
||||
{
|
||||
// TRANS: Validation error shown when providing an invalid homepage URL in the "Edit application" form.
|
||||
$this->showForm(_('Homepage is not a valid URL.'));
|
||||
return;
|
||||
} elseif (mb_strlen($callback_url) > 255) {
|
||||
// TRANS: Validation error shown when providing too long a callback URL in the "Edit application" form.
|
||||
$this->showForm(_('Callback is too long.'));
|
||||
return;
|
||||
} elseif (mb_strlen($callback_url) > 0
|
||||
@ -222,6 +241,7 @@ class EditApplicationAction extends OwnerDesignAction
|
||||
array('allowed_schemes' => array('http', 'https'))
|
||||
))
|
||||
{
|
||||
// TRANS: Validation error shown when providing an invalid callback URL in the "Edit application" form.
|
||||
$this->showForm(_('Callback URL is not valid.'));
|
||||
return;
|
||||
}
|
||||
@ -253,8 +273,12 @@ class EditApplicationAction extends OwnerDesignAction
|
||||
|
||||
$result = $this->app->update($orig);
|
||||
|
||||
if (!$result) {
|
||||
// Note: 0 means no rows changed, which can happen if the only
|
||||
// thing we changed was the icon, since it's not altered until
|
||||
// the next step.
|
||||
if ($result === false) {
|
||||
common_log_db_error($this->app, 'UPDATE', __FILE__);
|
||||
// TRANS: Server error occuring when an application could not be updated from the "Edit application" form.
|
||||
$this->serverError(_('Could not update application.'));
|
||||
}
|
||||
|
||||
@ -273,7 +297,6 @@ class EditApplicationAction extends OwnerDesignAction
|
||||
*
|
||||
* @return boolean true if the name already exists
|
||||
*/
|
||||
|
||||
function nameExists($name)
|
||||
{
|
||||
$newapp = Oauth_application::staticGet('name', $name);
|
||||
@ -283,6 +306,4 @@ class EditApplicationAction extends OwnerDesignAction
|
||||
return $newapp->id != $this->app->id;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
@ -45,14 +45,13 @@ if (!defined('STATUSNET') && !defined('LACONICA')) {
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||
* @link http://status.net/
|
||||
*/
|
||||
|
||||
class EditgroupAction extends GroupDesignAction
|
||||
{
|
||||
|
||||
var $msg;
|
||||
|
||||
function title()
|
||||
{
|
||||
// TRANS: Title for form to edit a group. %s is a group nickname.
|
||||
return sprintf(_('Edit %s group'), $this->group->nickname);
|
||||
}
|
||||
|
||||
@ -65,6 +64,7 @@ class EditgroupAction extends GroupDesignAction
|
||||
parent::prepare($args);
|
||||
|
||||
if (!common_logged_in()) {
|
||||
// TRANS: Client error displayed trying to edit a group while not logged in.
|
||||
$this->clientError(_('You must be logged in to create a group.'));
|
||||
return false;
|
||||
}
|
||||
@ -81,6 +81,7 @@ class EditgroupAction extends GroupDesignAction
|
||||
}
|
||||
|
||||
if (!$nickname) {
|
||||
// TRANS: Client error displayed trying to edit a group while not proving a nickname for the group to edit.
|
||||
$this->clientError(_('No nickname.'), 404);
|
||||
return false;
|
||||
}
|
||||
@ -97,6 +98,7 @@ class EditgroupAction extends GroupDesignAction
|
||||
}
|
||||
|
||||
if (!$this->group) {
|
||||
// TRANS: Client error displayed trying to edit a non-existing group.
|
||||
$this->clientError(_('No such group.'), 404);
|
||||
return false;
|
||||
}
|
||||
@ -104,6 +106,7 @@ class EditgroupAction extends GroupDesignAction
|
||||
$cur = common_current_user();
|
||||
|
||||
if (!$cur->isAdmin($this->group)) {
|
||||
// TRANS: Client error displayed trying to edit a group while not being a group admin.
|
||||
$this->clientError(_('You must be an admin to edit the group.'), 403);
|
||||
return false;
|
||||
}
|
||||
@ -120,7 +123,6 @@ class EditgroupAction extends GroupDesignAction
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
|
||||
function handle($args)
|
||||
{
|
||||
parent::handle($args);
|
||||
@ -155,6 +157,7 @@ class EditgroupAction extends GroupDesignAction
|
||||
$this->element('p', 'error', $this->msg);
|
||||
} else {
|
||||
$this->element('p', 'instructions',
|
||||
// TRANS: Form instructions for group edit form.
|
||||
_('Use this form to edit the group.'));
|
||||
}
|
||||
}
|
||||
@ -169,43 +172,48 @@ class EditgroupAction extends GroupDesignAction
|
||||
{
|
||||
$cur = common_current_user();
|
||||
if (!$cur->isAdmin($this->group)) {
|
||||
// TRANS: Client error displayed trying to edit a group while not being a group admin.
|
||||
$this->clientError(_('You must be an admin to edit the group.'), 403);
|
||||
return;
|
||||
}
|
||||
|
||||
$nickname = common_canonical_nickname($this->trimmed('nickname'));
|
||||
$nickname = Nickname::normalize($this->trimmed('nickname'));
|
||||
$fullname = $this->trimmed('fullname');
|
||||
$homepage = $this->trimmed('homepage');
|
||||
$description = $this->trimmed('description');
|
||||
$location = $this->trimmed('location');
|
||||
$aliasstring = $this->trimmed('aliases');
|
||||
|
||||
if (!Validate::string($nickname, array('min_length' => 1,
|
||||
'max_length' => 64,
|
||||
'format' => NICKNAME_FMT))) {
|
||||
$this->showForm(_('Nickname must have only lowercase letters '.
|
||||
'and numbers and no spaces.'));
|
||||
return;
|
||||
} else if ($this->nicknameExists($nickname)) {
|
||||
if ($this->nicknameExists($nickname)) {
|
||||
// TRANS: Group edit form validation error.
|
||||
$this->showForm(_('Nickname already in use. Try another one.'));
|
||||
return;
|
||||
} else if (!User_group::allowedNickname($nickname)) {
|
||||
// TRANS: Group edit form validation error.
|
||||
$this->showForm(_('Not a valid nickname.'));
|
||||
return;
|
||||
} else if (!is_null($homepage) && (strlen($homepage) > 0) &&
|
||||
!Validate::uri($homepage,
|
||||
array('allowed_schemes' =>
|
||||
array('http', 'https')))) {
|
||||
// TRANS: Group edit form validation error.
|
||||
$this->showForm(_('Homepage is not a valid URL.'));
|
||||
return;
|
||||
} else if (!is_null($fullname) && mb_strlen($fullname) > 255) {
|
||||
$this->showForm(_('Full name is too long (max 255 chars).'));
|
||||
// TRANS: Group edit form validation error.
|
||||
$this->showForm(_('Full name is too long (maximum 255 characters).'));
|
||||
return;
|
||||
} else if (User_group::descriptionTooLong($description)) {
|
||||
$this->showForm(sprintf(_('description is too long (max %d chars).'), User_group::maxDescription()));
|
||||
$this->showForm(sprintf(
|
||||
// TRANS: Group edit form validation error.
|
||||
_m('Description is too long (maximum %d character).',
|
||||
'Description is too long (maximum %d characters).',
|
||||
User_group::maxDescription()),
|
||||
User_group::maxDescription()));
|
||||
return;
|
||||
} else if (!is_null($location) && mb_strlen($location) > 255) {
|
||||
$this->showForm(_('Location is too long (max 255 chars).'));
|
||||
// TRANS: Group edit form validation error.
|
||||
$this->showForm(_('Location is too long (maximum 255 characters).'));
|
||||
return;
|
||||
}
|
||||
|
||||
@ -216,25 +224,30 @@ class EditgroupAction extends GroupDesignAction
|
||||
}
|
||||
|
||||
if (count($aliases) > common_config('group', 'maxaliases')) {
|
||||
$this->showForm(sprintf(_('Too many aliases! Maximum %d.'),
|
||||
// TRANS: Group edit form validation error.
|
||||
// TRANS: %d is the maximum number of allowed aliases.
|
||||
$this->showForm(sprintf(_m('Too many aliases! Maximum %d allowed.',
|
||||
'Too many aliases! Maximum %d allowed.',
|
||||
common_config('group', 'maxaliases')),
|
||||
common_config('group', 'maxaliases')));
|
||||
return;
|
||||
}
|
||||
|
||||
foreach ($aliases as $alias) {
|
||||
if (!Validate::string($alias, array('min_length' => 1,
|
||||
'max_length' => 64,
|
||||
'format' => NICKNAME_FMT))) {
|
||||
if (!Nickname::isValid($alias)) {
|
||||
// TRANS: Group edit form validation error.
|
||||
$this->showForm(sprintf(_('Invalid alias: "%s"'), $alias));
|
||||
return;
|
||||
}
|
||||
if ($this->nicknameExists($alias)) {
|
||||
// TRANS: Group edit form validation error.
|
||||
$this->showForm(sprintf(_('Alias "%s" already in use. Try another one.'),
|
||||
$alias));
|
||||
return;
|
||||
}
|
||||
// XXX assumes alphanum nicknames
|
||||
if (strcmp($alias, $nickname) == 0) {
|
||||
// TRANS: Group edit form validation error.
|
||||
$this->showForm(_('Alias can\'t be the same as nickname.'));
|
||||
return;
|
||||
}
|
||||
@ -255,12 +268,14 @@ class EditgroupAction extends GroupDesignAction
|
||||
|
||||
if (!$result) {
|
||||
common_log_db_error($this->group, 'UPDATE', __FILE__);
|
||||
// TRANS: Server error displayed when editing a group fails.
|
||||
$this->serverError(_('Could not update group.'));
|
||||
}
|
||||
|
||||
$result = $this->group->setAliases($aliases);
|
||||
|
||||
if (!$result) {
|
||||
// TRANS: Server error displayed when group aliases could not be added.
|
||||
$this->serverError(_('Could not create aliases.'));
|
||||
}
|
||||
|
||||
@ -277,6 +292,7 @@ class EditgroupAction extends GroupDesignAction
|
||||
array('nickname' => $nickname)),
|
||||
303);
|
||||
} else {
|
||||
// TRANS: Group edit form success message.
|
||||
$this->showForm(_('Options saved.'));
|
||||
}
|
||||
}
|
||||
@ -300,4 +316,3 @@ class EditgroupAction extends GroupDesignAction
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -79,6 +79,7 @@ class EmailsettingsAction extends AccountSettingsAction
|
||||
function showScripts()
|
||||
{
|
||||
parent::showScripts();
|
||||
$this->script('emailsettings.js');
|
||||
$this->autofocus('email');
|
||||
}
|
||||
|
||||
@ -131,7 +132,11 @@ class EmailsettingsAction extends AccountSettingsAction
|
||||
// TRANS: Field label for e-mail address input in e-mail settings form.
|
||||
$this->input('email', _('Email address'),
|
||||
($this->arg('email')) ? $this->arg('email') : null,
|
||||
// TRANS: Instructions for e-mail address input form.
|
||||
// TRANS: Instructions for e-mail address input form. Do not translate
|
||||
// TRANS: "example.org". It is one of the domain names reserved for
|
||||
// TRANS: use in examples by http://www.rfc-editor.org/rfc/rfc2606.txt.
|
||||
// TRANS: Any other domain may be owned by a legitimate person or
|
||||
// TRANS: organization.
|
||||
_('Email address, like "UserName@example.org"'));
|
||||
$this->elementEnd('li');
|
||||
$this->elementEnd('ul');
|
||||
@ -145,6 +150,26 @@ class EmailsettingsAction extends AccountSettingsAction
|
||||
$this->elementStart('fieldset', array('id' => 'settings_email_incoming'));
|
||||
// TRANS: Form legend for incoming e-mail settings form.
|
||||
$this->element('legend', null, _('Incoming email'));
|
||||
|
||||
$this->elementStart('ul', 'form_data');
|
||||
$this->elementStart('li');
|
||||
$this->checkbox('emailpost',
|
||||
// TRANS: Checkbox label in e-mail preferences form.
|
||||
_('I want to post notices by email.'),
|
||||
$user->emailpost);
|
||||
$this->elementEnd('li');
|
||||
$this->elementEnd('ul');
|
||||
|
||||
// Our stylesheets make the form_data list items all floats, which
|
||||
// creates lots of problems with trying to wrap divs around things.
|
||||
// This should force a break before the next section, which needs
|
||||
// to be separate so we can disable the things in it when the
|
||||
// checkbox is off.
|
||||
$this->elementStart('div', array('style' => 'clear: both'));
|
||||
$this->elementEnd('div');
|
||||
|
||||
$this->elementStart('div', array('id' => 'emailincoming'));
|
||||
|
||||
if ($user->incomingemail) {
|
||||
$this->elementStart('p');
|
||||
$this->element('span', 'address', $user->incomingemail);
|
||||
@ -159,13 +184,22 @@ class EmailsettingsAction extends AccountSettingsAction
|
||||
}
|
||||
|
||||
$this->elementStart('p');
|
||||
$this->element('span', 'input_instructions',
|
||||
// TRANS: Instructions for incoming e-mail address input form.
|
||||
_('Make a new email address for posting to; '.
|
||||
'cancels the old one.'));
|
||||
if ($user->incomingemail) {
|
||||
// TRANS: Instructions for incoming e-mail address input form, when an address has already been assigned.
|
||||
$msg = _('Make a new email address for posting to; '.
|
||||
'cancels the old one.');
|
||||
} else {
|
||||
// TRANS: Instructions for incoming e-mail address input form.
|
||||
$msg = _('To send notices via email, we need to create a unique email address for you on this server:');
|
||||
}
|
||||
$this->element('span', 'input_instructions', $msg);
|
||||
$this->elementEnd('p');
|
||||
|
||||
// TRANS: Button label for adding an e-mail address to send notices from.
|
||||
$this->submit('newincoming', _m('BUTTON','New'));
|
||||
|
||||
$this->elementEnd('div'); // div#emailincoming
|
||||
|
||||
$this->elementEnd('fieldset');
|
||||
}
|
||||
|
||||
@ -174,51 +208,47 @@ class EmailsettingsAction extends AccountSettingsAction
|
||||
$this->element('legend', null, _('Email preferences'));
|
||||
|
||||
$this->elementStart('ul', 'form_data');
|
||||
$this->elementStart('li');
|
||||
$this->checkbox('emailnotifysub',
|
||||
// TRANS: Checkbox label in e-mail preferences form.
|
||||
_('Send me notices of new subscriptions through email.'),
|
||||
$user->emailnotifysub);
|
||||
$this->elementEnd('li');
|
||||
$this->elementStart('li');
|
||||
$this->checkbox('emailnotifyfav',
|
||||
// TRANS: Checkbox label in e-mail preferences form.
|
||||
_('Send me email when someone '.
|
||||
'adds my notice as a favorite.'),
|
||||
$user->emailnotifyfav);
|
||||
$this->elementEnd('li');
|
||||
$this->elementStart('li');
|
||||
$this->checkbox('emailnotifymsg',
|
||||
// TRANS: Checkbox label in e-mail preferences form.
|
||||
_('Send me email when someone sends me a private message.'),
|
||||
$user->emailnotifymsg);
|
||||
$this->elementEnd('li');
|
||||
$this->elementStart('li');
|
||||
$this->checkbox('emailnotifyattn',
|
||||
// TRANS: Checkbox label in e-mail preferences form.
|
||||
_('Send me email when someone sends me an "@-reply".'),
|
||||
$user->emailnotifyattn);
|
||||
$this->elementEnd('li');
|
||||
$this->elementStart('li');
|
||||
$this->checkbox('emailnotifynudge',
|
||||
// TRANS: Checkbox label in e-mail preferences form.
|
||||
_('Allow friends to nudge me and send me an email.'),
|
||||
$user->emailnotifynudge);
|
||||
$this->elementEnd('li');
|
||||
if (common_config('emailpost', 'enabled')) {
|
||||
$this->elementStart('li');
|
||||
$this->checkbox('emailpost',
|
||||
// TRANS: Checkbox label in e-mail preferences form.
|
||||
_('I want to post notices by email.'),
|
||||
$user->emailpost);
|
||||
$this->elementEnd('li');
|
||||
}
|
||||
$this->elementStart('li');
|
||||
$this->checkbox('emailmicroid',
|
||||
// TRANS: Checkbox label in e-mail preferences form.
|
||||
_('Publish a MicroID for my email address.'),
|
||||
$user->emailmicroid);
|
||||
$this->elementEnd('li');
|
||||
|
||||
if (Event::handle('StartEmailFormData', array($this))) {
|
||||
$this->elementStart('li');
|
||||
$this->checkbox('emailnotifysub',
|
||||
// TRANS: Checkbox label in e-mail preferences form.
|
||||
_('Send me notices of new subscriptions through email.'),
|
||||
$user->emailnotifysub);
|
||||
$this->elementEnd('li');
|
||||
$this->elementStart('li');
|
||||
$this->checkbox('emailnotifyfav',
|
||||
// TRANS: Checkbox label in e-mail preferences form.
|
||||
_('Send me email when someone '.
|
||||
'adds my notice as a favorite.'),
|
||||
$user->emailnotifyfav);
|
||||
$this->elementEnd('li');
|
||||
$this->elementStart('li');
|
||||
$this->checkbox('emailnotifymsg',
|
||||
// TRANS: Checkbox label in e-mail preferences form.
|
||||
_('Send me email when someone sends me a private message.'),
|
||||
$user->emailnotifymsg);
|
||||
$this->elementEnd('li');
|
||||
$this->elementStart('li');
|
||||
$this->checkbox('emailnotifyattn',
|
||||
// TRANS: Checkbox label in e-mail preferences form.
|
||||
_('Send me email when someone sends me an "@-reply".'),
|
||||
$user->emailnotifyattn);
|
||||
$this->elementEnd('li');
|
||||
$this->elementStart('li');
|
||||
$this->checkbox('emailnotifynudge',
|
||||
// TRANS: Checkbox label in e-mail preferences form.
|
||||
_('Allow friends to nudge me and send me an email.'),
|
||||
$user->emailnotifynudge);
|
||||
$this->elementEnd('li');
|
||||
$this->elementStart('li');
|
||||
$this->checkbox('emailmicroid',
|
||||
// TRANS: Checkbox label in e-mail preferences form.
|
||||
_('Publish a MicroID for my email address.'),
|
||||
$user->emailmicroid);
|
||||
$this->elementEnd('li');
|
||||
Event::handle('EndEmailFormData', array($this));
|
||||
}
|
||||
$this->elementEnd('ul');
|
||||
// TRANS: Button label to save e-mail preferences.
|
||||
$this->submit('save', _m('BUTTON','Save'));
|
||||
@ -295,43 +325,48 @@ class EmailsettingsAction extends AccountSettingsAction
|
||||
|
||||
function savePreferences()
|
||||
{
|
||||
$emailnotifysub = $this->boolean('emailnotifysub');
|
||||
$emailnotifyfav = $this->boolean('emailnotifyfav');
|
||||
$emailnotifymsg = $this->boolean('emailnotifymsg');
|
||||
$emailnotifynudge = $this->boolean('emailnotifynudge');
|
||||
$emailnotifyattn = $this->boolean('emailnotifyattn');
|
||||
$emailmicroid = $this->boolean('emailmicroid');
|
||||
$emailpost = $this->boolean('emailpost');
|
||||
|
||||
$user = common_current_user();
|
||||
|
||||
assert(!is_null($user)); // should already be checked
|
||||
|
||||
$user->query('BEGIN');
|
||||
|
||||
$original = clone($user);
|
||||
|
||||
$user->emailnotifysub = $emailnotifysub;
|
||||
$user->emailnotifyfav = $emailnotifyfav;
|
||||
$user->emailnotifymsg = $emailnotifymsg;
|
||||
$user->emailnotifynudge = $emailnotifynudge;
|
||||
$user->emailnotifyattn = $emailnotifyattn;
|
||||
$user->emailmicroid = $emailmicroid;
|
||||
$user->emailpost = $emailpost;
|
||||
|
||||
$result = $user->update($original);
|
||||
|
||||
if ($result === false) {
|
||||
common_log_db_error($user, 'UPDATE', __FILE__);
|
||||
// TRANS: Server error thrown on database error updating e-mail preferences.
|
||||
$this->serverError(_('Couldn\'t update user.'));
|
||||
return;
|
||||
}
|
||||
|
||||
$user->query('COMMIT');
|
||||
|
||||
// TRANS: Confirmation message for successful e-mail preferences save.
|
||||
$this->showForm(_('Email preferences saved.'), true);
|
||||
$user = common_current_user();
|
||||
|
||||
if (Event::handle('StartEmailSaveForm', array($this, &$user))) {
|
||||
|
||||
$emailnotifysub = $this->boolean('emailnotifysub');
|
||||
$emailnotifyfav = $this->boolean('emailnotifyfav');
|
||||
$emailnotifymsg = $this->boolean('emailnotifymsg');
|
||||
$emailnotifynudge = $this->boolean('emailnotifynudge');
|
||||
$emailnotifyattn = $this->boolean('emailnotifyattn');
|
||||
$emailmicroid = $this->boolean('emailmicroid');
|
||||
$emailpost = $this->boolean('emailpost');
|
||||
|
||||
assert(!is_null($user)); // should already be checked
|
||||
|
||||
$user->query('BEGIN');
|
||||
|
||||
$original = clone($user);
|
||||
|
||||
$user->emailnotifysub = $emailnotifysub;
|
||||
$user->emailnotifyfav = $emailnotifyfav;
|
||||
$user->emailnotifymsg = $emailnotifymsg;
|
||||
$user->emailnotifynudge = $emailnotifynudge;
|
||||
$user->emailnotifyattn = $emailnotifyattn;
|
||||
$user->emailmicroid = $emailmicroid;
|
||||
$user->emailpost = $emailpost;
|
||||
|
||||
$result = $user->update($original);
|
||||
|
||||
if ($result === false) {
|
||||
common_log_db_error($user, 'UPDATE', __FILE__);
|
||||
// TRANS: Server error thrown on database error updating e-mail preferences.
|
||||
$this->serverError(_('Couldn\'t update user.'));
|
||||
return;
|
||||
}
|
||||
|
||||
$user->query('COMMIT');
|
||||
|
||||
Event::handle('EndEmailSaveForm', array($this));
|
||||
|
||||
// TRANS: Confirmation message for successful e-mail preferences save.
|
||||
$this->showForm(_('Email preferences saved.'), true);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -497,6 +532,7 @@ class EmailsettingsAction extends AccountSettingsAction
|
||||
$orig = clone($user);
|
||||
|
||||
$user->incomingemail = null;
|
||||
$user->emailpost = 0;
|
||||
|
||||
if (!$user->updateKeys($orig)) {
|
||||
common_log_db_error($user, 'UPDATE', __FILE__);
|
||||
@ -521,6 +557,7 @@ class EmailsettingsAction extends AccountSettingsAction
|
||||
$orig = clone($user);
|
||||
|
||||
$user->incomingemail = mail_new_incoming_address();
|
||||
$user->emailpost = 1;
|
||||
|
||||
if (!$user->updateKeys($orig)) {
|
||||
common_log_db_error($user, 'UPDATE', __FILE__);
|
||||
|
@ -185,29 +185,11 @@ class FavoritedAction extends Action
|
||||
|
||||
function showContent()
|
||||
{
|
||||
$weightexpr = common_sql_weight('fave.modified', common_config('popular', 'dropoff'));
|
||||
$cutoff = sprintf("fave.modified > '%s'",
|
||||
common_sql_date(time() - common_config('popular', 'cutoff')));
|
||||
|
||||
$qry = 'SELECT notice.*, '.
|
||||
$weightexpr . ' as weight ' .
|
||||
'FROM notice JOIN fave ON notice.id = fave.notice_id ' .
|
||||
"WHERE $cutoff " .
|
||||
'GROUP BY id,profile_id,uri,content,rendered,url,created,notice.modified,reply_to,is_local,source,notice.conversation ' .
|
||||
'ORDER BY weight DESC';
|
||||
|
||||
$offset = ($this->page - 1) * NOTICES_PER_PAGE;
|
||||
$limit = NOTICES_PER_PAGE + 1;
|
||||
|
||||
if (common_config('db', 'type') == 'pgsql') {
|
||||
$qry .= ' LIMIT ' . $limit . ' OFFSET ' . $offset;
|
||||
} else {
|
||||
$qry .= ' LIMIT ' . $offset . ', ' . $limit;
|
||||
}
|
||||
|
||||
$notice = Memcached_DataObject::cachedQuery('Notice',
|
||||
$qry,
|
||||
600);
|
||||
$pop = new Popularity();
|
||||
$pop->offset = ($this->page - 1) * NOTICES_PER_PAGE;
|
||||
$pop->limit = NOTICES_PER_PAGE;
|
||||
$pop->expiry = 600;
|
||||
$notice = $pop->getNotices();
|
||||
|
||||
$nl = new NoticeList($notice, $this);
|
||||
|
||||
|
@ -129,9 +129,9 @@ class GetfileAction extends Action
|
||||
return null;
|
||||
}
|
||||
|
||||
$cache = common_memcache();
|
||||
$cache = Cache::instance();
|
||||
if($cache) {
|
||||
$key = common_cache_key('attachments:etag:' . $this->path);
|
||||
$key = Cache::key('attachments:etag:' . $this->path);
|
||||
$etag = $cache->get($key);
|
||||
if($etag === false) {
|
||||
$etag = crc32(file_get_contents($this->path));
|
||||
|
@ -97,9 +97,13 @@ class GroupmembersAction extends GroupDesignAction
|
||||
function title()
|
||||
{
|
||||
if ($this->page == 1) {
|
||||
// TRANS: Title of the page showing group members.
|
||||
// TRANS: %s is the name of the group.
|
||||
return sprintf(_('%s group members'),
|
||||
$this->group->nickname);
|
||||
} else {
|
||||
// TRANS: Title of the page showing group members.
|
||||
// TRANS: %1$s is the name of the group, %2$d is the page number of the members list.
|
||||
return sprintf(_('%1$s group members, page %2$d'),
|
||||
$this->group->nickname,
|
||||
$this->page);
|
||||
@ -389,7 +393,14 @@ class GroupBlockForm extends Form
|
||||
|
||||
function formActions()
|
||||
{
|
||||
$this->out->submit('submit', _('Block'), 'submit', null, _('Block this user'));
|
||||
$this->out->submit(
|
||||
'submit',
|
||||
// TRANS: Button text for the form that will block a user from a group.
|
||||
_m('BUTTON','Block'),
|
||||
'submit',
|
||||
null,
|
||||
// TRANS: Submit button title.
|
||||
_m('TOOLTIP', 'Block this user'));
|
||||
}
|
||||
}
|
||||
|
||||
@ -516,6 +527,13 @@ class MakeAdminForm extends Form
|
||||
|
||||
function formActions()
|
||||
{
|
||||
$this->out->submit('submit', _('Make Admin'), 'submit', null, _('Make this user an admin'));
|
||||
$this->out->submit(
|
||||
'submit',
|
||||
// TRANS: Button text for the form that will make a user administrator.
|
||||
_m('BUTTON','Make Admin'),
|
||||
'submit',
|
||||
null,
|
||||
// TRANS: Submit button title.
|
||||
_m('TOOLTIP','Make this user an admin'));
|
||||
}
|
||||
}
|
||||
|
@ -32,7 +32,7 @@ if (!defined('STATUSNET') && !defined('LACONICA')) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Unlock a user from a group
|
||||
* Unblock a user from a group
|
||||
*
|
||||
* @category Action
|
||||
* @package StatusNet
|
||||
@ -40,7 +40,6 @@ if (!defined('STATUSNET') && !defined('LACONICA')) {
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl.html AGPLv3
|
||||
* @link http://status.net/
|
||||
*/
|
||||
|
||||
class GroupunblockAction extends Action
|
||||
{
|
||||
var $profile = null;
|
||||
@ -53,11 +52,11 @@ class GroupunblockAction extends Action
|
||||
*
|
||||
* @return boolean success flag
|
||||
*/
|
||||
|
||||
function prepare($args)
|
||||
{
|
||||
parent::prepare($args);
|
||||
if (!common_logged_in()) {
|
||||
// TRANS: Client error displayed when trying to unblock a user from a group while not logged in.
|
||||
$this->clientError(_('Not logged in.'));
|
||||
return false;
|
||||
}
|
||||
@ -68,11 +67,13 @@ class GroupunblockAction extends Action
|
||||
}
|
||||
$id = $this->trimmed('unblockto');
|
||||
if (empty($id)) {
|
||||
// TRANS: Client error displayed when trying to unblock a user from a group without providing a profile.
|
||||
$this->clientError(_('No profile specified.'));
|
||||
return false;
|
||||
}
|
||||
$this->profile = Profile::staticGet('id', $id);
|
||||
if (empty($this->profile)) {
|
||||
// TRANS: Client error displayed when trying to unblock a user from a group without providing an existing profile.
|
||||
$this->clientError(_('No profile with that ID.'));
|
||||
return false;
|
||||
}
|
||||
@ -83,15 +84,18 @@ class GroupunblockAction extends Action
|
||||
}
|
||||
$this->group = User_group::staticGet('id', $group_id);
|
||||
if (empty($this->group)) {
|
||||
// TRANS: Client error displayed when trying to unblock a user from a non-existing group.
|
||||
$this->clientError(_('No such group.'));
|
||||
return false;
|
||||
}
|
||||
$user = common_current_user();
|
||||
if (!$user->isAdmin($this->group)) {
|
||||
// TRANS: Client error displayed when trying to unblock a user from a group without being an administrator for the group.
|
||||
$this->clientError(_('Only an admin can unblock group members.'), 401);
|
||||
return false;
|
||||
}
|
||||
if (!Group_block::isBlocked($this->group, $this->profile)) {
|
||||
// TRANS: Client error displayed when trying to unblock a non-blocked user from a group.
|
||||
$this->clientError(_('User is not blocked from group.'));
|
||||
return false;
|
||||
}
|
||||
@ -105,7 +109,6 @@ class GroupunblockAction extends Action
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
|
||||
function handle($args)
|
||||
{
|
||||
parent::handle($args);
|
||||
@ -119,12 +122,12 @@ class GroupunblockAction extends Action
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
|
||||
function unblockProfile()
|
||||
{
|
||||
$result = Group_block::unblockProfile($this->group, $this->profile);
|
||||
|
||||
if (!$result) {
|
||||
// TRANS: Server error displayed when unblocking a user from a group fails because of an unknown error.
|
||||
$this->serverError(_('Error removing the block.'));
|
||||
return;
|
||||
}
|
||||
@ -146,4 +149,3 @@ class GroupunblockAction extends Action
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -18,28 +18,46 @@
|
||||
*/
|
||||
|
||||
/**
|
||||
* @package OStatusPlugin
|
||||
* @category Action
|
||||
* @package StatusNet
|
||||
* @maintainer James Walker <james@status.net>
|
||||
* @author Craig Andrews <candrews@integralblue.com>
|
||||
*/
|
||||
|
||||
if (!defined('STATUSNET') && !defined('LACONICA')) { exit(1); }
|
||||
if (!defined('STATUSNET')) {
|
||||
exit(1);
|
||||
}
|
||||
|
||||
class HostMetaAction extends Action
|
||||
{
|
||||
|
||||
/**
|
||||
* Is read only?
|
||||
*
|
||||
* @return boolean true
|
||||
*/
|
||||
function isReadOnly()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
function handle()
|
||||
{
|
||||
parent::handle();
|
||||
|
||||
$domain = common_config('site', 'server');
|
||||
$url = common_local_url('userxrd');
|
||||
$url.= '?uri={uri}';
|
||||
|
||||
$xrd = new XRD();
|
||||
$xrd->host = $domain;
|
||||
$xrd->links[] = array('rel' => Discovery::LRDD_REL,
|
||||
'template' => $url,
|
||||
'title' => array('Resource Descriptor'));
|
||||
|
||||
if(Event::handle('StartHostMetaLinks', array(&$xrd->links))) {
|
||||
$url = common_local_url('userxrd');
|
||||
$url.= '?uri={uri}';
|
||||
$xrd->links[] = array('rel' => Discovery::LRDD_REL,
|
||||
'template' => $url,
|
||||
'title' => array('Resource Descriptor'));
|
||||
Event::handle('EndHostMetaLinks', array(&$xrd->links));
|
||||
}
|
||||
|
||||
header('Content-type: application/xrd+xml');
|
||||
print $xrd->toXML();
|
@ -133,7 +133,7 @@ class ImsettingsAction extends ConnectSettingsAction
|
||||
'message with further instructions. '.
|
||||
'(Did you add %s to your buddy list?)'),
|
||||
$transport_info['display'],
|
||||
$transport_info['daemon_screenname']));
|
||||
$transport_info['daemonScreenname']));
|
||||
$this->hidden('screenname', $confirm->address);
|
||||
// TRANS: Button label to cancel an IM address confirmation procedure.
|
||||
$this->submit('cancel', _m('BUTTON','Cancel'));
|
||||
|
@ -36,8 +36,11 @@ class InviteAction extends CurrentUserDesignAction
|
||||
{
|
||||
parent::handle($args);
|
||||
if (!common_config('invite', 'enabled')) {
|
||||
// TRANS: Client error displayed when trying to sent invites while they have been disabled.
|
||||
$this->clientError(_('Invites have been disabled.'));
|
||||
} else if (!common_logged_in()) {
|
||||
// TRANS: Client error displayed when trying to sent invites while not logged in.
|
||||
// TRANS: %s is the StatusNet site name.
|
||||
$this->clientError(sprintf(_('You must be logged in to invite other users to use %s.'),
|
||||
common_config('site', 'name')));
|
||||
return;
|
||||
@ -69,7 +72,9 @@ class InviteAction extends CurrentUserDesignAction
|
||||
foreach ($addresses as $email) {
|
||||
$email = trim($email);
|
||||
if (!Validate::email($email, common_config('email', 'check_domain'))) {
|
||||
$this->showForm(sprintf(_('Invalid email address: %s'), $email));
|
||||
// TRANS: Form validation message when providing an e-mail address that does not validate.
|
||||
// TRANS: %s is an invalid e-mail address.
|
||||
$this->showForm(sprintf(_('Invalid email address: %s.'), $email));
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -107,8 +112,10 @@ class InviteAction extends CurrentUserDesignAction
|
||||
function title()
|
||||
{
|
||||
if ($this->mode == 'sent') {
|
||||
return _('Invitation(s) sent');
|
||||
// TRANS: Page title when invitations have been sent.
|
||||
return _('Invitations sent');
|
||||
} else {
|
||||
// TRANS: Page title when inviting potential users.
|
||||
return _('Invite new users');
|
||||
}
|
||||
}
|
||||
@ -125,28 +132,48 @@ class InviteAction extends CurrentUserDesignAction
|
||||
function showInvitationSuccess()
|
||||
{
|
||||
if ($this->already) {
|
||||
$this->element('p', null, _('You are already subscribed to these users:'));
|
||||
// TRANS: Message displayed inviting users to use a StatusNet site while the inviting user
|
||||
// TRANS: is already subscribed to one or more users with the given e-mail address(es).
|
||||
// TRANS: Plural form is based on the number of reported already subscribed e-mail addresses.
|
||||
// TRANS: Followed by a bullet list.
|
||||
$this->element('p', null, _m('You are already subscribed to this user:',
|
||||
'You are already subscribed to these users:',
|
||||
count($this->already)));
|
||||
$this->elementStart('ul');
|
||||
foreach ($this->already as $other) {
|
||||
$this->element('li', null, sprintf(_('%1$s (%2$s)'), $other->nickname, $other->email));
|
||||
// TRANS: Used as list item for already subscribed users (%1$s is nickname, %2$s is e-mail address).
|
||||
$this->element('li', null, sprintf(_m('INVITE','%1$s (%2$s)'), $other->nickname, $other->email));
|
||||
}
|
||||
$this->elementEnd('ul');
|
||||
}
|
||||
if ($this->subbed) {
|
||||
$this->element('p', null, _('These people are already users and you were automatically subscribed to them:'));
|
||||
// TRANS: Message displayed inviting users to use a StatusNet site while the invited user
|
||||
// TRANS: already uses a this StatusNet site. Plural form is based on the number of
|
||||
// TRANS: reported already present people. Followed by a bullet list.
|
||||
$this->element('p', null, _m('This person is already a user and you were automatically subscribed:',
|
||||
'These people are already users and you were automatically subscribed to them:',
|
||||
count($this->subbed)));
|
||||
$this->elementStart('ul');
|
||||
foreach ($this->subbed as $other) {
|
||||
$this->element('li', null, sprintf(_('%1$s (%2$s)'), $other->nickname, $other->email));
|
||||
// TRANS: Used as list item for already registered people (%1$s is nickname, %2$s is e-mail address).
|
||||
$this->element('li', null, sprintf(_m('INVITE','%1$s (%2$s)'), $other->nickname, $other->email));
|
||||
}
|
||||
$this->elementEnd('ul');
|
||||
}
|
||||
if ($this->sent) {
|
||||
$this->element('p', null, _('Invitation(s) sent to the following people:'));
|
||||
// TRANS: Message displayed inviting users to use a StatusNet site. Plural form is
|
||||
// TRANS: based on the number of invitations sent. Followed by a bullet list of
|
||||
// TRANS: e-mail addresses to which invitations were sent.
|
||||
$this->element('p', null, _m('Invitation sent to the following person:',
|
||||
'Invitations sent to the following people:',
|
||||
count($this->sent)));
|
||||
$this->elementStart('ul');
|
||||
foreach ($this->sent as $other) {
|
||||
$this->element('li', null, $other);
|
||||
}
|
||||
$this->elementEnd('ul');
|
||||
// TRANS: Generic message displayed after sending out one or more invitations to
|
||||
// TRANS: people to join a StatusNet site.
|
||||
$this->element('p', null, _('You will be notified when your invitees accept the invitation and register on the site. Thanks for growing the community!'));
|
||||
}
|
||||
}
|
||||
@ -159,6 +186,7 @@ class InviteAction extends CurrentUserDesignAction
|
||||
} else {
|
||||
$this->elementStart('div', 'instructions');
|
||||
$this->element('p', null,
|
||||
// TRANS: Form instructions.
|
||||
_('Use this form to invite your friends and colleagues to use this service.'));
|
||||
$this->elementEnd('div');
|
||||
}
|
||||
@ -179,18 +207,23 @@ class InviteAction extends CurrentUserDesignAction
|
||||
'class' => 'form_settings',
|
||||
'action' => common_local_url('invite')));
|
||||
$this->elementStart('fieldset');
|
||||
// TRANS: Form legend.
|
||||
$this->element('legend', null, 'Send an invitation');
|
||||
$this->hidden('token', common_session_token());
|
||||
|
||||
$this->elementStart('ul', 'form_data');
|
||||
$this->elementStart('li');
|
||||
// TRANS: Field label for a list of e-mail addresses.
|
||||
$this->textarea('addresses', _('Email addresses'),
|
||||
$this->trimmed('addresses'),
|
||||
// TRANS: Tooltip for field label for a list of e-mail addresses.
|
||||
_('Addresses of friends to invite (one per line)'));
|
||||
$this->elementEnd('li');
|
||||
$this->elementStart('li');
|
||||
// TRANS: Field label for a personal message to send to invitees.
|
||||
$this->textarea('personal', _('Personal message'),
|
||||
$this->trimmed('personal'),
|
||||
// TRANS: Tooltip for field label for a personal message to send to invitees.
|
||||
_('Optionally add a personal message to the invitation.'));
|
||||
$this->elementEnd('li');
|
||||
$this->elementEnd('ul');
|
||||
@ -224,10 +257,16 @@ class InviteAction extends CurrentUserDesignAction
|
||||
|
||||
$headers['From'] = mail_notify_from();
|
||||
$headers['To'] = trim($email);
|
||||
// TRANS: Subject for invitation email. Note that 'them' is correct as a gender-neutral singular 3rd-person pronoun in English.
|
||||
// TRANS: Subject for invitation email. Note that 'them' is correct as a gender-neutral
|
||||
// TRANS: singular 3rd-person pronoun in English. %1$s is the inviting user, $2$s is
|
||||
// TRANS: the StatusNet sitename.
|
||||
$headers['Subject'] = sprintf(_('%1$s has invited you to join them on %2$s'), $bestname, $sitename);
|
||||
|
||||
// TRANS: Body text for invitation email. Note that 'them' is correct as a gender-neutral singular 3rd-person pronoun in English.
|
||||
// TRANS: Body text for invitation email. Note that 'them' is correct as a gender-neutral
|
||||
// TRANS: singular 3rd-person pronoun in English. %1$s is the inviting user, %2$s is the
|
||||
// TRANS: StatusNet sitename, %3$s is the site URL, %4$s is the personal message from the
|
||||
// TRANS: inviting user, %s%5 a link to the timeline for the inviting user, %s$6 is a link
|
||||
// TRANS: to register with the StatusNet site.
|
||||
$body = sprintf(_("%1\$s has invited you to join them on %2\$s (%3\$s).\n\n".
|
||||
"%2\$s is a micro-blogging service that lets you keep up-to-date with people you know and people who interest you.\n\n".
|
||||
"You can also share news about yourself, your thoughts, or your life online with people who know about you. ".
|
||||
|
322
actions/licenseadminpanel.php
Normal file
322
actions/licenseadminpanel.php
Normal file
@ -0,0 +1,322 @@
|
||||
<?php
|
||||
/**
|
||||
* StatusNet, the distributed open-source microblogging tool
|
||||
*
|
||||
* License 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);
|
||||
}
|
||||
|
||||
/**
|
||||
* License settings
|
||||
*
|
||||
* @category Admin
|
||||
* @package StatusNet
|
||||
* @author Zach Copley <zach@status.net>
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||
* @link http://status.net/
|
||||
*/
|
||||
|
||||
class LicenseadminpanelAction extends AdminPanelAction
|
||||
{
|
||||
|
||||
/**
|
||||
* Returns the page title
|
||||
*
|
||||
* @return string page title
|
||||
*/
|
||||
|
||||
function title()
|
||||
{
|
||||
// TRANS: User admin panel title
|
||||
return _m('TITLE', 'License');
|
||||
}
|
||||
|
||||
/**
|
||||
* Instructions for using this form.
|
||||
*
|
||||
* @return string instructions
|
||||
*/
|
||||
|
||||
function getInstructions()
|
||||
{
|
||||
return _('License for this StatusNet site');
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the site admin panel form
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
|
||||
function showForm()
|
||||
{
|
||||
$form = new LicenseAdminPanelForm($this);
|
||||
$form->show();
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Save settings from the form
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
|
||||
function saveSettings()
|
||||
{
|
||||
static $settings = array(
|
||||
'license' => array('type', 'owner', 'url', 'title', 'image')
|
||||
);
|
||||
|
||||
$values = array();
|
||||
|
||||
foreach ($settings as $section => $parts) {
|
||||
foreach ($parts as $setting) {
|
||||
$values[$section][$setting] = $this->trimmed($setting);
|
||||
}
|
||||
}
|
||||
|
||||
// This throws an exception on validation errors
|
||||
|
||||
$this->validate($values);
|
||||
|
||||
// assert(all values are valid);
|
||||
|
||||
$config = new Config();
|
||||
|
||||
$config->query('BEGIN');
|
||||
|
||||
foreach ($settings as $section => $parts) {
|
||||
foreach ($parts as $setting) {
|
||||
Config::save($section, $setting, $values[$section][$setting]);
|
||||
}
|
||||
}
|
||||
|
||||
$config->query('COMMIT');
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate License admin form values
|
||||
*
|
||||
* @param array &$values from the form
|
||||
*
|
||||
* @return nothing
|
||||
*/
|
||||
|
||||
function validate(&$values)
|
||||
{
|
||||
// Validate license type (shouldn't have to do it, but just in case)
|
||||
|
||||
$types = array('private', 'allrightsreserved', 'cc');
|
||||
|
||||
if (!in_array($values['license']['type'], $types)) {
|
||||
$this->clientError(_("Invalid license selection."));
|
||||
}
|
||||
|
||||
// Make sure the user has set an owner if the site has a private
|
||||
// license
|
||||
|
||||
if ($values['license']['type'] == 'allrightsreserved'
|
||||
&& empty($values['license']['owner'])
|
||||
) {
|
||||
$this->clientError(
|
||||
_("You must specify the owner of the content when using the All Rights Reserved license.")
|
||||
);
|
||||
}
|
||||
|
||||
// Make sure the license title is not too long
|
||||
if (mb_strlen($values['license']['type']) > 255) {
|
||||
$this->clientError(
|
||||
_('Invalid license title. Maximum length is 255 characters.')
|
||||
);
|
||||
}
|
||||
|
||||
// make sure the license URL and license image URL are valid URLs
|
||||
|
||||
$options = array('allowed_schemes' => array('http', 'https'));
|
||||
|
||||
// URLs should be set for cc license
|
||||
|
||||
if ($values['license']['type'] == 'cc') {
|
||||
if (!Validate::uri($values['license']['url'], $options)) {
|
||||
$this->clientError(_("Invalid license URL."));
|
||||
}
|
||||
if (!Validate::uri($values['license']['image'], $options)) {
|
||||
$this->clientError(_("Invalid license image URL."));
|
||||
}
|
||||
}
|
||||
|
||||
// can be either blank or a valid URL for private & allrightsreserved
|
||||
|
||||
if (!empty($values['license']['url'])) {
|
||||
if (!Validate::uri($values['license']['url'], $options)) {
|
||||
$this->clientError(_("License URL must be blank or a valid URL."));
|
||||
}
|
||||
}
|
||||
|
||||
// can be either blank or a valid URL for private & allrightsreserved
|
||||
|
||||
if (!empty($values['license']['image'])) {
|
||||
if (!Validate::uri($values['license']['image'], $options)) {
|
||||
$this->clientError(_("License image must be blank or valid URL."));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class LicenseAdminPanelForm extends AdminForm
|
||||
{
|
||||
/**
|
||||
* ID of the form
|
||||
*
|
||||
* @return int ID of the form
|
||||
*/
|
||||
|
||||
function id()
|
||||
{
|
||||
return 'licenseadminpanel';
|
||||
}
|
||||
|
||||
/**
|
||||
* class of the form
|
||||
*
|
||||
* @return string class of the form
|
||||
*/
|
||||
|
||||
function formClass()
|
||||
{
|
||||
return 'form_settings';
|
||||
}
|
||||
|
||||
/**
|
||||
* Action of the form
|
||||
*
|
||||
* @return string URL of the action
|
||||
*/
|
||||
|
||||
function action()
|
||||
{
|
||||
return common_local_url('licenseadminpanel');
|
||||
}
|
||||
|
||||
/**
|
||||
* Data elements of the form
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
|
||||
function formData()
|
||||
{
|
||||
$this->out->elementStart(
|
||||
'fieldset', array('id' => 'settings_license-selection')
|
||||
);
|
||||
$this->out->element('legend', null, _('License selection'));
|
||||
$this->out->elementStart('ul', 'form_data');
|
||||
|
||||
$this->li();
|
||||
|
||||
$types = array(
|
||||
'private' => _('Private'),
|
||||
'allrightsreserved' => _('All Rights Reserved'),
|
||||
'cc' => _('Creative Commons')
|
||||
);
|
||||
|
||||
$this->out->dropdown(
|
||||
'type',
|
||||
_('Type'),
|
||||
$types,
|
||||
_('Select license'),
|
||||
false,
|
||||
$this->value('type', 'license')
|
||||
);
|
||||
|
||||
$this->unli();
|
||||
|
||||
$this->out->elementEnd('ul');
|
||||
$this->out->elementEnd('fieldset');
|
||||
|
||||
$this->out->elementStart(
|
||||
'fieldset',
|
||||
array('id' => 'settings_license-details')
|
||||
);
|
||||
$this->out->element('legend', null, _('License details'));
|
||||
$this->out->elementStart('ul', 'form_data');
|
||||
|
||||
$this->li();
|
||||
$this->input(
|
||||
'owner',
|
||||
_('Owner'),
|
||||
_('Name of the owner of the site\'s content (if applicable).'),
|
||||
'license'
|
||||
);
|
||||
$this->unli();
|
||||
|
||||
$this->li();
|
||||
$this->input(
|
||||
'title',
|
||||
_('License Title'),
|
||||
_('The title of the license.'),
|
||||
'license'
|
||||
);
|
||||
$this->unli();
|
||||
|
||||
$this->li();
|
||||
$this->input(
|
||||
'url',
|
||||
_('License URL'),
|
||||
_('URL for more information about the license.'),
|
||||
'license'
|
||||
);
|
||||
$this->unli();
|
||||
|
||||
$this->li();
|
||||
$this->input(
|
||||
'image', _('License Image URL'),
|
||||
_('URL for an image to display with the license.'),
|
||||
'license'
|
||||
);
|
||||
$this->unli();
|
||||
|
||||
$this->out->elementEnd('ul');
|
||||
$this->out->elementEnd('fieldset');
|
||||
}
|
||||
|
||||
/**
|
||||
* Action elements
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
|
||||
function formActions()
|
||||
{
|
||||
$this->out->submit(
|
||||
'submit', _('Save'), 'submit', null, _('Save license settings')
|
||||
);
|
||||
}
|
||||
}
|
@ -62,28 +62,6 @@ class LoginAction extends Action
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepare page to run
|
||||
*
|
||||
*
|
||||
* @param $args
|
||||
* @return string title
|
||||
*/
|
||||
|
||||
function prepare($args)
|
||||
{
|
||||
parent::prepare($args);
|
||||
|
||||
// @todo this check should really be in index.php for all sensitive actions
|
||||
$ssl = common_config('site', 'ssl');
|
||||
if (empty($_SERVER['HTTPS']) && ($ssl == 'always' || $ssl == 'sometimes')) {
|
||||
common_redirect(common_local_url('login'));
|
||||
// exit
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle input, produce output
|
||||
*
|
||||
@ -118,27 +96,10 @@ class LoginAction extends Action
|
||||
* @return void
|
||||
*/
|
||||
|
||||
function checkLogin($user_id=null, $token=null)
|
||||
function checkLogin($user_id=null)
|
||||
{
|
||||
// XXX: login throttle
|
||||
|
||||
// CSRF protection - token set in NoticeForm
|
||||
$token = $this->trimmed('token');
|
||||
if (!$token || $token != common_session_token()) {
|
||||
$st = common_session_token();
|
||||
if (empty($token)) {
|
||||
common_log(LOG_WARNING, 'No token provided by client.');
|
||||
} else if (empty($st)) {
|
||||
common_log(LOG_WARNING, 'No session token stored.');
|
||||
} else {
|
||||
common_log(LOG_WARNING, 'Token = ' . $token . ' and session token = ' . $st);
|
||||
}
|
||||
|
||||
$this->clientError(_('There was a problem with your session token. '.
|
||||
'Try again, please.'));
|
||||
return;
|
||||
}
|
||||
|
||||
$nickname = $this->trimmed('nickname');
|
||||
$password = $this->arg('password');
|
||||
|
||||
@ -261,7 +222,6 @@ class LoginAction extends Action
|
||||
$this->elementEnd('li');
|
||||
$this->elementEnd('ul');
|
||||
$this->submit('submit', _('Login'));
|
||||
$this->hidden('token', common_session_token());
|
||||
$this->elementEnd('fieldset');
|
||||
$this->elementEnd('form');
|
||||
$this->elementStart('p');
|
||||
|
@ -148,7 +148,7 @@ class MakeadminAction extends RedirectingAction
|
||||
$this->group->getBestName());
|
||||
}
|
||||
|
||||
$this->returnToArgs();
|
||||
$this->returnToPrevious();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -42,14 +42,14 @@ if (!defined('STATUSNET') && !defined('LACONICA')) {
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||
* @link http://status.net/
|
||||
*/
|
||||
|
||||
class NewApplicationAction extends OwnerDesignAction
|
||||
{
|
||||
var $msg;
|
||||
|
||||
function title()
|
||||
{
|
||||
return _('New Application');
|
||||
// TRANS: This is the title of the form for adding a new application.
|
||||
return _('New application');
|
||||
}
|
||||
|
||||
/**
|
||||
@ -61,6 +61,7 @@ class NewApplicationAction extends OwnerDesignAction
|
||||
parent::prepare($args);
|
||||
|
||||
if (!common_logged_in()) {
|
||||
// TRANS: Client error displayed trying to add a new application while not logged in.
|
||||
$this->clientError(_('You must be logged in to register an application.'));
|
||||
return false;
|
||||
}
|
||||
@ -91,35 +92,38 @@ class NewApplicationAction extends OwnerDesignAction
|
||||
|
||||
function handlePost($args)
|
||||
{
|
||||
// Workaround for PHP returning empty $_POST and $_FILES when POST
|
||||
// Workaround for PHP returning empty $_POST and $_FILES when POST
|
||||
// length > post_max_size in php.ini
|
||||
|
||||
if (empty($_FILES)
|
||||
&& empty($_POST)
|
||||
&& ($_SERVER['CONTENT_LENGTH'] > 0)
|
||||
) {
|
||||
$msg = _('The server was unable to handle that much POST ' .
|
||||
'data (%s bytes) due to its current configuration.');
|
||||
// TRANS: Client error displayed when the number of bytes in a POST request exceeds a limit.
|
||||
// TRANS: %s is the number of bytes of the CONTENT_LENGTH.
|
||||
$msg = _m('The server was unable to handle that much POST data (%s byte) due to its current configuration.',
|
||||
'The server was unable to handle that much POST data (%s bytes) due to its current configuration.',
|
||||
intval($_SERVER['CONTENT_LENGTH']));
|
||||
$this->clientException(sprintf($msg, $_SERVER['CONTENT_LENGTH']));
|
||||
return;
|
||||
}
|
||||
|
||||
// CSRF protection
|
||||
$token = $this->trimmed('token');
|
||||
if (!$token || $token != common_session_token()) {
|
||||
$this->clientError(_('There was a problem with your session token.'));
|
||||
return;
|
||||
}
|
||||
// CSRF protection
|
||||
$token = $this->trimmed('token');
|
||||
if (!$token || $token != common_session_token()) {
|
||||
$this->clientError(_('There was a problem with your session token.'));
|
||||
return;
|
||||
}
|
||||
|
||||
$cur = common_current_user();
|
||||
$cur = common_current_user();
|
||||
|
||||
if ($this->arg('cancel')) {
|
||||
common_redirect(common_local_url('oauthappssettings'), 303);
|
||||
} elseif ($this->arg('save')) {
|
||||
$this->trySave();
|
||||
} else {
|
||||
$this->clientError(_('Unexpected form submission.'));
|
||||
}
|
||||
if ($this->arg('cancel')) {
|
||||
common_redirect(common_local_url('oauthappssettings'), 303);
|
||||
} elseif ($this->arg('save')) {
|
||||
$this->trySave();
|
||||
} else {
|
||||
$this->clientError(_('Unexpected form submission.'));
|
||||
}
|
||||
}
|
||||
|
||||
function showForm($msg=null)
|
||||
@ -162,15 +166,19 @@ class NewApplicationAction extends OwnerDesignAction
|
||||
$this->showForm(_('Name already in use. Try another one.'));
|
||||
return;
|
||||
} elseif (mb_strlen($name) > 255) {
|
||||
$this->showForm(_('Name is too long (max 255 chars).'));
|
||||
$this->showForm(_('Name is too long (maximum 255 characters).'));
|
||||
return;
|
||||
} elseif (empty($description)) {
|
||||
$this->showForm(_('Description is required.'));
|
||||
return;
|
||||
} elseif (Oauth_application::descriptionTooLong($description)) {
|
||||
$this->showForm(sprintf(
|
||||
_('Description is too long (max %d chars).'),
|
||||
Oauth_application::maxDescription()));
|
||||
// TRANS: Form validation error in New application form.
|
||||
// TRANS: %d is the maximum number of characters for the description.
|
||||
_m('Description is too long (maximum %d character).',
|
||||
'Description is too long (maximum %d characters).',
|
||||
Oauth_application::maxDesc()),
|
||||
Oauth_application::maxDesc()));
|
||||
return;
|
||||
} elseif (empty($source_url)) {
|
||||
$this->showForm(_('Source URL is required.'));
|
||||
@ -188,7 +196,7 @@ class NewApplicationAction extends OwnerDesignAction
|
||||
$this->showForm(_('Organization is required.'));
|
||||
return;
|
||||
} elseif (mb_strlen($organization) > 255) {
|
||||
$this->showForm(_('Organization is too long (max 255 chars).'));
|
||||
$this->showForm(_('Organization is too long (maximum 255 characters).'));
|
||||
return;
|
||||
} elseif (empty($homepage)) {
|
||||
$this->showForm(_('Organization homepage is required.'));
|
||||
|
@ -43,25 +43,25 @@ if (!defined('STATUSNET') && !defined('LACONICA')) {
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||
* @link http://status.net/
|
||||
*/
|
||||
|
||||
class NewgroupAction extends Action
|
||||
{
|
||||
var $msg;
|
||||
|
||||
function title()
|
||||
{
|
||||
// TRANS: Title for form to create a group.
|
||||
return _('New group');
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepare to run
|
||||
*/
|
||||
|
||||
function prepare($args)
|
||||
{
|
||||
parent::prepare($args);
|
||||
|
||||
if (!common_logged_in()) {
|
||||
// TRANS: Client error displayed trying to create a group while not logged in.
|
||||
$this->clientError(_('You must be logged in to create a group.'));
|
||||
return false;
|
||||
}
|
||||
@ -78,7 +78,6 @@ class NewgroupAction extends Action
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
|
||||
function handle($args)
|
||||
{
|
||||
parent::handle($args);
|
||||
@ -107,45 +106,54 @@ class NewgroupAction extends Action
|
||||
$this->element('p', 'error', $this->msg);
|
||||
} else {
|
||||
$this->element('p', 'instructions',
|
||||
// TRANS: Form instructions for group create form.
|
||||
_('Use this form to create a new group.'));
|
||||
}
|
||||
}
|
||||
|
||||
function trySave()
|
||||
{
|
||||
$nickname = $this->trimmed('nickname');
|
||||
try {
|
||||
$nickname = Nickname::normalize($this->trimmed('nickname'));
|
||||
} catch (NicknameException $e) {
|
||||
$this->showForm($e->getMessage());
|
||||
}
|
||||
$fullname = $this->trimmed('fullname');
|
||||
$homepage = $this->trimmed('homepage');
|
||||
$description = $this->trimmed('description');
|
||||
$location = $this->trimmed('location');
|
||||
$aliasstring = $this->trimmed('aliases');
|
||||
|
||||
if (!Validate::string($nickname, array('min_length' => 1,
|
||||
'max_length' => 64,
|
||||
'format' => NICKNAME_FMT))) {
|
||||
$this->showForm(_('Nickname must have only lowercase letters '.
|
||||
'and numbers and no spaces.'));
|
||||
return;
|
||||
} else if ($this->nicknameExists($nickname)) {
|
||||
if ($this->nicknameExists($nickname)) {
|
||||
// TRANS: Group create form validation error.
|
||||
$this->showForm(_('Nickname already in use. Try another one.'));
|
||||
return;
|
||||
} else if (!User_group::allowedNickname($nickname)) {
|
||||
// TRANS: Group create form validation error.
|
||||
$this->showForm(_('Not a valid nickname.'));
|
||||
return;
|
||||
} else if (!is_null($homepage) && (strlen($homepage) > 0) &&
|
||||
!Validate::uri($homepage,
|
||||
array('allowed_schemes' =>
|
||||
array('http', 'https')))) {
|
||||
// TRANS: Group create form validation error.
|
||||
$this->showForm(_('Homepage is not a valid URL.'));
|
||||
return;
|
||||
} else if (!is_null($fullname) && mb_strlen($fullname) > 255) {
|
||||
$this->showForm(_('Full name is too long (max 255 chars).'));
|
||||
// TRANS: Group create form validation error.
|
||||
$this->showForm(_('Full name is too long (maximum 255 characters).'));
|
||||
return;
|
||||
} else if (User_group::descriptionTooLong($description)) {
|
||||
$this->showForm(sprintf(_('description is too long (max %d chars).'), User_group::maxDescription()));
|
||||
// TRANS: Group create form validation error.
|
||||
// TRANS: %d is the maximum number of allowed characters.
|
||||
$this->showForm(sprintf(_m('Description is too long (maximum %d character).',
|
||||
'Description is too long (maximum %d characters).',
|
||||
User_group::maxDescription()),
|
||||
User_group::maxDescription()));
|
||||
return;
|
||||
} else if (!is_null($location) && mb_strlen($location) > 255) {
|
||||
$this->showForm(_('Location is too long (max 255 chars).'));
|
||||
// TRANS: Group create form validation error.
|
||||
$this->showForm(_('Location is too long (maximum 255 characters).'));
|
||||
return;
|
||||
}
|
||||
|
||||
@ -156,25 +164,30 @@ class NewgroupAction extends Action
|
||||
}
|
||||
|
||||
if (count($aliases) > common_config('group', 'maxaliases')) {
|
||||
$this->showForm(sprintf(_('Too many aliases! Maximum %d.'),
|
||||
// TRANS: Group create form validation error.
|
||||
// TRANS: %d is the maximum number of allowed aliases.
|
||||
$this->showForm(sprintf(_m('Too many aliases! Maximum %d allowed.',
|
||||
'Too many aliases! Maximum %d allowed.',
|
||||
common_config('group', 'maxaliases')),
|
||||
common_config('group', 'maxaliases')));
|
||||
return;
|
||||
}
|
||||
|
||||
foreach ($aliases as $alias) {
|
||||
if (!Validate::string($alias, array('min_length' => 1,
|
||||
'max_length' => 64,
|
||||
'format' => NICKNAME_FMT))) {
|
||||
if (!Nickname::isValid($alias)) {
|
||||
// TRANS: Group create form validation error.
|
||||
$this->showForm(sprintf(_('Invalid alias: "%s"'), $alias));
|
||||
return;
|
||||
}
|
||||
if ($this->nicknameExists($alias)) {
|
||||
// TRANS: Group create form validation error.
|
||||
$this->showForm(sprintf(_('Alias "%s" already in use. Try another one.'),
|
||||
$alias));
|
||||
return;
|
||||
}
|
||||
// XXX assumes alphanum nicknames
|
||||
if (strcmp($alias, $nickname) == 0) {
|
||||
// TRANS: Group create form validation error.
|
||||
$this->showForm(_('Alias can\'t be the same as nickname.'));
|
||||
return;
|
||||
}
|
||||
@ -218,4 +231,3 @@ class NewgroupAction extends Action
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user