Merge branch '0.9-release'
* 0.9-release: (874 commits) Removed call to NewDirectMessage() until IE return is fixed i.e., Don't show flag user button your own profile Fixed HXR response for flag user Using the right form class name Using common_redirect Left a form_data class of a <ul> in the user admin panel Added validation to fields in user admin panel Added a user admin panel Added mobile logos for default and identica themes Changed gif to png Changed this to action. THANKS zach! Doing content negotiation only once Add execute bit to pingqueuehandler Localisation updates for !StatusNet from !translatewiki.net Use the browser's geolocation API to set the location on the notice form Add geometa library, and include it. Add location form elements to the noticeform, and save their values on submission Use the $user object nickname, as login name doesnt have to == nickname anymore with plugins such as ldap/etc Revert "Re added NICKNAME_FMT constant to router.php." Moved most path and server settings to a new paths admin panel ... Conflicts: js/util.js locale/it_IT/LC_MESSAGES/statusnet.mo locale/mk_MK/LC_MESSAGES/statusnet.mo locale/mk_MK/LC_MESSAGES/statusnet.po locale/pt_BR/LC_MESSAGES/statusnet.mo locale/vi_VN/LC_MESSAGES/statusnet.mo plugins/InfiniteScroll/infinitescroll.js plugins/Realtime/realtimeupdate.js
This commit is contained in:
commit
4b98edf75f
2
.gitignore
vendored
2
.gitignore
vendored
@ -24,4 +24,4 @@ config-*.php
|
|||||||
good-config.php
|
good-config.php
|
||||||
lac08.log
|
lac08.log
|
||||||
php.log
|
php.log
|
||||||
|
.DS_Store
|
||||||
|
444
EVENTS.txt
444
EVENTS.txt
@ -32,10 +32,10 @@ StartShowLaconicaStyles: backwards compatibility; deprecated
|
|||||||
EndShowLaconicaStyles: backwards compatibility; deprecated
|
EndShowLaconicaStyles: backwards compatibility; deprecated
|
||||||
- $action: the current action
|
- $action: the current action
|
||||||
|
|
||||||
StartShowUAStyles: Showing custom UA Style links
|
StartShowUAStyles: Showing custom User-Agent style links
|
||||||
- $action: the current action
|
- $action: the current action
|
||||||
|
|
||||||
EndShowUAStyles: End showing custom UA Style links; good place to add user-agent (e.g., filter, -webkit, -moz) specific styles
|
EndShowUAStyles: End showing custom User-Agent links; good place to add user-agent (e.g., filter, -webkit, -moz) specific styles
|
||||||
- $action: the current action
|
- $action: the current action
|
||||||
|
|
||||||
StartShowScripts: Showing JavaScript links
|
StartShowScripts: Showing JavaScript links
|
||||||
@ -87,6 +87,18 @@ StartShowContentBlock: Showing before the content container
|
|||||||
EndShowContentBlock: Showing after the content container
|
EndShowContentBlock: Showing after the content container
|
||||||
- $action: the current action
|
- $action: the current action
|
||||||
|
|
||||||
|
StartShowAside: Showing before the Aside container
|
||||||
|
- $action: the current action
|
||||||
|
|
||||||
|
EndShowAside: Showing after the Aside container
|
||||||
|
- $action: the current action
|
||||||
|
|
||||||
|
StartShowNoticeFormData: Showing before the notice form data
|
||||||
|
- $action: the current action
|
||||||
|
|
||||||
|
EndShowNoticeFormData: Showing after the notice form data
|
||||||
|
- $action: the current action
|
||||||
|
|
||||||
StartNoticeSave: before inserting a notice (good place for content filters)
|
StartNoticeSave: before inserting a notice (good place for content filters)
|
||||||
- $notice: notice being saved (no ID or URI)
|
- $notice: notice being saved (no ID or URI)
|
||||||
|
|
||||||
@ -117,6 +129,9 @@ StartSubGroupNav: Showing the subscriptions group nav menu
|
|||||||
EndSubGroupNav: At the end of the subscriptions group nav menu
|
EndSubGroupNav: At the end of the subscriptions group nav menu
|
||||||
- $action: the current action
|
- $action: the current action
|
||||||
|
|
||||||
|
StartInitializeRouter: Before the router instance has been initialized; good place to add routes
|
||||||
|
- $m: the Net_URL_Mapper that has just been set up
|
||||||
|
|
||||||
RouterInitialized: After the router instance has been initialized
|
RouterInitialized: After the router instance has been initialized
|
||||||
- $m: the Net_URL_Mapper that has just been set up
|
- $m: the Net_URL_Mapper that has just been set up
|
||||||
|
|
||||||
@ -134,3 +149,428 @@ StartAddressData: Allows the site owner to provide additional information about
|
|||||||
|
|
||||||
EndAddressData: At the end of <address>
|
EndAddressData: At the end of <address>
|
||||||
- $action: the current action
|
- $action: the current action
|
||||||
|
|
||||||
|
StartLoginGroupNav: Before showing the login and register navigation menu
|
||||||
|
- $action: the current action
|
||||||
|
|
||||||
|
EndLoginGroupNav: After showing the login and register navigation menu
|
||||||
|
- $action: the current action
|
||||||
|
|
||||||
|
StartAccountSettingsNav: Before showing the account settings menu
|
||||||
|
- $action: the current action
|
||||||
|
|
||||||
|
EndAccountSettingsNav: After showing the account settings menu
|
||||||
|
- $action: the current action
|
||||||
|
|
||||||
|
StartAccountSettingsProfileMenuItem: Before showing the Profile menu item
|
||||||
|
- $widget: AccountSettingsNav instance being shown
|
||||||
|
|
||||||
|
EndAccountSettingsProfileMenuItem: After showing the Profile menu item
|
||||||
|
- $widget: AccountSettingsNav instance being shown
|
||||||
|
|
||||||
|
StartAccountSettingsAvatarMenuItem: Before showing the Avatar menu item
|
||||||
|
- $widget: AccountSettingsNav instance being shown
|
||||||
|
|
||||||
|
EndAccountSettingsAvatarMenuItem: After showing the Avatar menu item
|
||||||
|
- $widget: AccountSettingsNav instance being shown
|
||||||
|
|
||||||
|
StartAccountSettingsPasswordMenuItem: Before showing the Password menu item
|
||||||
|
- $widget: AccountSettingsNav instance being shown
|
||||||
|
|
||||||
|
EndAccountSettingsPasswordMenuItem: After showing the Password menu item
|
||||||
|
- $widget: AccountSettingsNav instance being shown
|
||||||
|
|
||||||
|
StartAccountSettingsEmailMenuItem: Before showing the Email menu item
|
||||||
|
- $widget: AccountSettingsNav instance being shown
|
||||||
|
|
||||||
|
EndAccountSettingsEmailMenuItem: After showing the Email menu item
|
||||||
|
- $widget: AccountSettingsNav instance being shown
|
||||||
|
|
||||||
|
StartAccountSettingsDesignMenuItem: Before showing the Design menu item
|
||||||
|
- $widget: AccountSettingsNav instance being shown
|
||||||
|
|
||||||
|
EndAccountSettingsDesignMenuItem: After showing the Design menu item
|
||||||
|
- $widget: AccountSettingsNav instance being shown
|
||||||
|
|
||||||
|
StartAccountSettingsOtherMenuItem: Before showing the Other menu item
|
||||||
|
- $widget: AccountSettingsNav instance being shown
|
||||||
|
|
||||||
|
EndAccountSettingsOtherMenuItem: After showing the Other menu item
|
||||||
|
- $widget: AccountSettingsNav instance being shown
|
||||||
|
|
||||||
|
Autoload: When trying to autoload a class
|
||||||
|
- $cls: the class being sought. A plugin might require_once the file for the class.
|
||||||
|
|
||||||
|
SensitiveAction: determines if an action is 'sensitive' and should use SSL
|
||||||
|
- $action: name of the action, like 'login'
|
||||||
|
- $sensitive: flag for whether this is a sensitive action
|
||||||
|
|
||||||
|
LoginAction: determines if an action is a 'login' action (OK for public view in private mode)
|
||||||
|
- $action: name of the action, like 'register'
|
||||||
|
- $login: flag for whether this is a login action
|
||||||
|
|
||||||
|
StartShowHead: called before showing the <head> element and children
|
||||||
|
- $action: action object being show
|
||||||
|
|
||||||
|
EndShowHead: called after showing the <head> element (and </head>)
|
||||||
|
- $action: action object being shown
|
||||||
|
|
||||||
|
StartShowBody: called before showing the <body> element and children
|
||||||
|
- $action: action object being shown
|
||||||
|
|
||||||
|
EndShowBody: called after showing the <body> element (and </body>)
|
||||||
|
- $action: action object being shown
|
||||||
|
|
||||||
|
StartPersonalGroupNav: beginning of personal group nav menu
|
||||||
|
- $action: action object being shown
|
||||||
|
|
||||||
|
EndPersonalGroupNav: end of personal group nav menu (good place to add a menu item)
|
||||||
|
- $action: action object being shown
|
||||||
|
|
||||||
|
StartGroupGroupNav: Showing the group nav menu
|
||||||
|
- $action: the current action
|
||||||
|
|
||||||
|
EndGroupGroupNav: At the end of the group nav menu
|
||||||
|
- $action: the current action
|
||||||
|
|
||||||
|
StartEndHTML: just before the </html> tag
|
||||||
|
- $action: action object being shown
|
||||||
|
|
||||||
|
EndEndHTML: just after the </html> tag
|
||||||
|
- $action: action object being shown
|
||||||
|
|
||||||
|
StartShowDesign: just before showing a site, user, or group design
|
||||||
|
- $action: action object being shown
|
||||||
|
|
||||||
|
EndShowDesign: just after showing a site, user, or group design
|
||||||
|
- $action: action object being shown
|
||||||
|
|
||||||
|
StartShowExportData: just before showing the <div> with export data (feeds)
|
||||||
|
- $action: action object being shown
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
EndShowNoticeItem: just after showing the notice item
|
||||||
|
- $action: action object being shown
|
||||||
|
|
||||||
|
StartShowPageNotice: just before showing the page notice (instructions or error)
|
||||||
|
- $action: action object being shown
|
||||||
|
|
||||||
|
EndShowPageNotice: just after showing the page notice (instructions or error)
|
||||||
|
- $action: action object being shown
|
||||||
|
|
||||||
|
StartShowPageTitle: just before showing the main h1 title of a page (only for registration)
|
||||||
|
- $action: action object being shown
|
||||||
|
|
||||||
|
StartProfileFormData: just before showing text entry fields on profile settings page
|
||||||
|
- $action: action object being shown
|
||||||
|
|
||||||
|
EndProfileFormData: just after showing text entry fields on profile settings page
|
||||||
|
- $action: action object being shown
|
||||||
|
|
||||||
|
StartProfileSaveForm: before starting to save a profile settings form
|
||||||
|
- $action: action object being shown
|
||||||
|
|
||||||
|
EndProfileSaveForm: after saving a profile settings form (after commit, no profile or user object!)
|
||||||
|
- $action: action object being shown
|
||||||
|
|
||||||
|
StartRegistrationFormData: just before showing text entry fields on registration page
|
||||||
|
- $action: action object being shown
|
||||||
|
|
||||||
|
EndRegistrationFormData: just after showing text entry fields on registration page
|
||||||
|
- $action: action object being shown
|
||||||
|
|
||||||
|
StartRegistrationTry: before validating and saving a new user
|
||||||
|
- $action: action object being shown
|
||||||
|
|
||||||
|
EndRegistrationTry: after saving a new user (note: no profile or user object!)
|
||||||
|
- $action: action object being shown
|
||||||
|
|
||||||
|
StartNewQueueManager: before trying to start a new queue manager; good for plugins implementing new queue manager classes
|
||||||
|
- $qm: empty queue manager to set
|
||||||
|
|
||||||
|
RedirectToLogin: event when we force a redirect to login (like when going to a settings page on a remembered login)
|
||||||
|
- $action: action object being shown
|
||||||
|
- $user: current user
|
||||||
|
|
||||||
|
StartLoadDoc: before loading a help doc (hook this to show your own documentation)
|
||||||
|
- $title: title of the document
|
||||||
|
- $output: HTML output to show
|
||||||
|
|
||||||
|
EndLoadDoc: after loading a help doc (hook this to modify other documentation)
|
||||||
|
- $title: title of the document
|
||||||
|
- $output: HTML output to show
|
||||||
|
|
||||||
|
StartApiRss: after the rss <channel> element is started
|
||||||
|
- $action: action object being shown
|
||||||
|
|
||||||
|
StartApiAtom: after the <feed> element is started
|
||||||
|
- $action: action object being shown
|
||||||
|
|
||||||
|
StartEnqueueNotice: about to add a notice to the queues (good place to add a new transport)
|
||||||
|
- $notice: the notice being added
|
||||||
|
- &$transports: modifiable list of transports (as strings) to queue for
|
||||||
|
|
||||||
|
EndEnqueueNotice: after adding a notice to the queues
|
||||||
|
- $notice: the notice being added
|
||||||
|
- $transports: modifiable list of transports to use
|
||||||
|
|
||||||
|
UnqueueHandleNotice: Handle a notice when no queue manager is available
|
||||||
|
- $notice: the notice to handle
|
||||||
|
- $queue: the "queue" that is being executed
|
||||||
|
|
||||||
|
GetValidDaemons: Just before determining which daemons to run
|
||||||
|
- &$daemons: modifiable list of daemon scripts to run, filenames relative to scripts/
|
||||||
|
|
||||||
|
HandleQueuedNotice: Handle a queued notice at queue time (or immediately if no queue)
|
||||||
|
- &$notice: notice to handle
|
||||||
|
|
||||||
|
StartShowHeadElements: Right after the <head> tag
|
||||||
|
- $action: the current action
|
||||||
|
|
||||||
|
EndShowHeadElements: Right before the </head> tag; put <script>s here if you need them in <head>
|
||||||
|
- $action: the current action
|
||||||
|
|
||||||
|
CheckSchema: chance to check the schema
|
||||||
|
|
||||||
|
StartProfilePageProfileSection: Starting to show the section of the
|
||||||
|
profile page with the actual profile data;
|
||||||
|
hook to prevent showing the profile (e.g.)
|
||||||
|
- $userprofile: UserProfile widget
|
||||||
|
- &$profile: the profile being shown
|
||||||
|
|
||||||
|
StartProfilePageProfileElements: inside the section, before the first
|
||||||
|
element; prepend elements here
|
||||||
|
- $userprofile: UserProfile widget
|
||||||
|
- &$profile: the profile being shown
|
||||||
|
|
||||||
|
EndProfilePageProfileElements: inside the section, after the last element;
|
||||||
|
append elements here
|
||||||
|
- $userprofile: UserProfile widget
|
||||||
|
- &$profile: the profile being shown
|
||||||
|
|
||||||
|
EndProfilePageProfileSection: After showing the section of the profile
|
||||||
|
page with the profile elements
|
||||||
|
- $userprofile: UserProfile widget
|
||||||
|
- &$profile: the profile being shown
|
||||||
|
|
||||||
|
StartProfilePageActionsSection: Starting to show the section of the
|
||||||
|
profile page with action links; hook
|
||||||
|
to hide them (for example)
|
||||||
|
- $userprofile: UserProfile widget
|
||||||
|
- &$profile: the profile being shown
|
||||||
|
|
||||||
|
StartProfilePageActionsElements: inside the list, before the first
|
||||||
|
element; prepend elements here
|
||||||
|
- $userprofile: UserProfile widget
|
||||||
|
- &$profile: the profile being shown
|
||||||
|
|
||||||
|
EndProfilePageActionsElements: inside the list, after the last element;
|
||||||
|
append elements here
|
||||||
|
- $userprofile: UserProfile widget
|
||||||
|
- &$profile: the profile being shown
|
||||||
|
|
||||||
|
EndProfilePageActionsSection: After showing the section of the profile
|
||||||
|
page with the entity actions
|
||||||
|
- $userprofile: UserProfile widget
|
||||||
|
- &$profile: the profile being shown
|
||||||
|
|
||||||
|
StartProfilePageAvatar: before showing the avatar on the profile page
|
||||||
|
- $userprofile: UserProfile widget
|
||||||
|
- &$profile: the profile being shown
|
||||||
|
|
||||||
|
EndProfilePageAvatar: after showing the avatar on the profile page
|
||||||
|
- $userprofile: UserProfile widget
|
||||||
|
- &$profile: the profile being shown
|
||||||
|
|
||||||
|
StartProfilePageNickname: before showing the nickname on the profile page
|
||||||
|
- $userprofile: UserProfile widget
|
||||||
|
- &$profile: the profile being shown
|
||||||
|
|
||||||
|
EndProfilePageNickname: after showing the nickname on the profile page
|
||||||
|
- $userprofile: UserProfile widget
|
||||||
|
- &$profile: the profile being shown
|
||||||
|
|
||||||
|
StartProfilePageFullName: before showing the fullname on the profile page
|
||||||
|
- $userprofile: UserProfile widget
|
||||||
|
- &$profile: the profile being shown
|
||||||
|
|
||||||
|
EndProfilePageFullName: after showing the fullname on the profile page
|
||||||
|
- $userprofile: UserProfile widget
|
||||||
|
- &$profile: the profile being shown
|
||||||
|
|
||||||
|
StartProfilePageLocation: before showing the location on the profile page
|
||||||
|
- $userprofile: UserProfile widget
|
||||||
|
- &$profile: the profile being shown
|
||||||
|
|
||||||
|
EndProfilePageLocation: after showing the location on the profile page
|
||||||
|
- $userprofile: UserProfile widget
|
||||||
|
- &$profile: the profile being shown
|
||||||
|
|
||||||
|
StartProfilePageHomepage: before showing the homepage link on the profile page
|
||||||
|
- $userprofile: UserProfile widget
|
||||||
|
- &$profile: the profile being shown
|
||||||
|
|
||||||
|
EndProfilePageHomepage: after showing the homepage on the profile page
|
||||||
|
- $userprofile: UserProfile widget
|
||||||
|
- &$profile: the profile being shown
|
||||||
|
|
||||||
|
StartProfilePageBio: before showing the bio on the profile page
|
||||||
|
- $userprofile: UserProfile widget
|
||||||
|
- &$profile: the profile being shown
|
||||||
|
|
||||||
|
EndProfilePageBio: after showing the bio on the profile page
|
||||||
|
- $userprofile: UserProfile widget
|
||||||
|
- &$profile: the profile being shown
|
||||||
|
|
||||||
|
StartProfilePageProfileTags: before showing the tags on the profile page
|
||||||
|
- $userprofile: UserProfile widget
|
||||||
|
- &$profile: the profile being shown
|
||||||
|
|
||||||
|
EndProfilePageProfileTags: after showing the tags on the profile page
|
||||||
|
- $userprofile: UserProfile widget
|
||||||
|
- &$profile: the profile being shown
|
||||||
|
|
||||||
|
StartProfileList: when starting a list of profiles (before <ul>)
|
||||||
|
- $profilelist: ProfileList widget, with $profile, $action, and $out
|
||||||
|
|
||||||
|
EndProfileList: when ending a list of profiles (after </ul>)
|
||||||
|
- $profilelist: ProfileList widget
|
||||||
|
|
||||||
|
StartProfileListItem: when starting to show a profile list item
|
||||||
|
- $item: ProfileListItem widget
|
||||||
|
|
||||||
|
EndProfileListItem: after showing a profile list item
|
||||||
|
- $item: ProfileListItem widget
|
||||||
|
|
||||||
|
StartProfileListItemProfile: the profile data part of the item
|
||||||
|
- $item: ProfileListItem widget
|
||||||
|
|
||||||
|
EndProfileListItemProfile: the profile data part of the item
|
||||||
|
- $item: ProfileListItem widget
|
||||||
|
|
||||||
|
StartProfileListItemActions: the actions (buttons) for an item
|
||||||
|
- $item: ProfileListItem widget
|
||||||
|
|
||||||
|
EndProfileListItemActions: the actions (buttons) for an item
|
||||||
|
- $item: ProfileListItem widget
|
||||||
|
|
||||||
|
StartProfileListItemProfileElements: inside the <div>
|
||||||
|
- $item: ProfileListItem widget
|
||||||
|
|
||||||
|
EndProfileListItemProfileElements: inside the <div>
|
||||||
|
- $item: ProfileListItem widget
|
||||||
|
|
||||||
|
StartProfileListItemAvatar: Showing a profile list avatar
|
||||||
|
- $item: ProfileListItem widget
|
||||||
|
|
||||||
|
EndProfileListItemAvatar: Showing a profile list avatar
|
||||||
|
- $item: ProfileListItem widget
|
||||||
|
|
||||||
|
StartProfileListItemFullName: Showing the profile list full name
|
||||||
|
- $item: ProfileListItem widget
|
||||||
|
|
||||||
|
EndProfileListItemFullName: Showing the profile list full name
|
||||||
|
- $item: ProfileListItem widget
|
||||||
|
|
||||||
|
StartProfileListItemLocation: Showing the profile list location
|
||||||
|
- $item: ProfileListItem widget
|
||||||
|
|
||||||
|
EndProfileListItemLocation: Showing the profile list location
|
||||||
|
- $item: ProfileListItem widget
|
||||||
|
|
||||||
|
StartProfileListItemHomepage: Showing the profile list homepage
|
||||||
|
- $item: ProfileListItem widget
|
||||||
|
|
||||||
|
EndProfileListItemHomepage: Showing the profile list homepage
|
||||||
|
- $item: ProfileListItem widget
|
||||||
|
|
||||||
|
StartProfileListItemBio: Showing the profile list bio
|
||||||
|
- $item: ProfileListItem widget
|
||||||
|
|
||||||
|
EndProfileListItemBio: Showing the profile list bio
|
||||||
|
- $item: ProfileListItem widget
|
||||||
|
|
||||||
|
StartProfileListItemActionElements: Showing the profile list actions (prepend a button here, or replace all buttons)
|
||||||
|
- $item: ProfileListItem widget
|
||||||
|
|
||||||
|
EndProfileListItemActionElements: Showing profile list actions (append a button here)
|
||||||
|
- $item: ProfileListItem widget
|
||||||
|
|
||||||
|
StartUserXRDS: Start XRDS output (right after the opening XRDS tag)
|
||||||
|
- $action: the current action
|
||||||
|
- &$xrdsoutputter - XRDSOutputter object to write to
|
||||||
|
|
||||||
|
EndUserXRDS: End XRDS output (right before the closing XRDS tag)
|
||||||
|
- $action: the current action
|
||||||
|
- &$xrdsoutputter - XRDSOutputter object to write to
|
||||||
|
|
||||||
|
StartPublicXRDS: Start XRDS output (right after the opening XRDS tag)
|
||||||
|
- $action: the current action
|
||||||
|
- &$xrdsoutputter - XRDSOutputter object to write to
|
||||||
|
|
||||||
|
EndPublicXRDS: End XRDS output (right before the closing XRDS tag)
|
||||||
|
- $action: the current action
|
||||||
|
- &$xrdsoutputter - XRDSOutputter object to write to
|
||||||
|
|
||||||
|
StartCheckPassword: Check a username/password
|
||||||
|
- $nickname: The nickname to check
|
||||||
|
- $password: The password to check
|
||||||
|
- &$authenticatedUser: set to User object if credentials match a user.
|
||||||
|
|
||||||
|
EndCheckPassword: After checking a username/password pair
|
||||||
|
- $nickname: The nickname that was checked
|
||||||
|
- $password: The password that was checked
|
||||||
|
- $authenticatedUser: User object if credentials match a user, else null.
|
||||||
|
|
||||||
|
StartChangePassword: Before changing a password
|
||||||
|
- $user: user
|
||||||
|
- $oldpassword: the user's old password
|
||||||
|
- $newpassword: the desired new password
|
||||||
|
|
||||||
|
EndChangePassword: After changing a password
|
||||||
|
- $user: user
|
||||||
|
|
||||||
|
StartSetUser: Before setting the currently logged in user
|
||||||
|
- $user: user
|
||||||
|
|
||||||
|
EndSetUser: After setting the currently logged in user
|
||||||
|
- $user: user
|
||||||
|
|
||||||
|
StartSetApiUser: Before setting the current API user
|
||||||
|
- $user: user
|
||||||
|
|
||||||
|
EndSetApiUser: After setting the current API user
|
||||||
|
- $user: user
|
||||||
|
|
||||||
|
StartHasRole: Before determing if the a profile has a given role
|
||||||
|
- $profile: profile in question
|
||||||
|
- $name: name of the role in question
|
||||||
|
- &$has_role: does this profile have the named role?
|
||||||
|
|
||||||
|
EndHasRole: Before determing if the a profile has a given role
|
||||||
|
- $profile: profile in question
|
||||||
|
- $name: name of the role in question
|
||||||
|
- $has_role: does this profile have the named role?
|
||||||
|
|
||||||
|
UserDeleteRelated: Specify additional tables to delete entries from when deleting users
|
||||||
|
- $user: User object
|
||||||
|
- &$related: array of DB_DataObject class names to delete entries on matching user_id.
|
||||||
|
|
||||||
|
GetUrlShorteners: Specify URL shorteners that are available for use
|
||||||
|
- &$shorteners: append your shortener to this array like so: $shorteners[shortenerName]=array('display'=>display, 'freeService'=>boolean)
|
||||||
|
|
||||||
|
StartShortenUrl: About to shorten a URL
|
||||||
|
- $url: url to be shortened
|
||||||
|
- $shortenerName: name of the requested shortener
|
||||||
|
- &$shortenedUrl: short version of the url
|
||||||
|
|
||||||
|
EndShortenUrl: After a URL has been shortened
|
||||||
|
- $url: url to be shortened
|
||||||
|
- $shortenerName: name of the requested shortener
|
||||||
|
- $shortenedUrl: short version of the url
|
||||||
|
|
||||||
|
254
README
254
README
@ -150,6 +150,7 @@ released Aug 26 2009. Notable changes this version:
|
|||||||
- Use the NICKNAME_FMT constant for detecting nicknames.
|
- Use the NICKNAME_FMT constant for detecting nicknames.
|
||||||
- Check for site servername config'd.
|
- Check for site servername config'd.
|
||||||
- Compatibility fix for empty status updates with Twitter API.
|
- Compatibility fix for empty status updates with Twitter API.
|
||||||
|
- Option to show files privately (EXPERIMENTAL! Use with caution.)
|
||||||
- a script to register a new user.
|
- a script to register a new user.
|
||||||
- a script to make a user admin of a group.
|
- a script to make a user admin of a group.
|
||||||
|
|
||||||
@ -388,20 +389,16 @@ the server first.
|
|||||||
Sphinx
|
Sphinx
|
||||||
------
|
------
|
||||||
|
|
||||||
To use a Sphinx server to search users and notices, you also need
|
To use a Sphinx server to search users and notices, you'll need to
|
||||||
to install, compile and enable the sphinx pecl extension for php on the
|
enable the SphinxSearch plugin. Add to your config.php:
|
||||||
client side, which itself depends on the sphinx development files.
|
|
||||||
"pecl install sphinx" should take care of that. Add "extension=sphinx.so"
|
|
||||||
to your php.ini and reload apache to enable it.
|
|
||||||
|
|
||||||
You can update your MySQL or Postgresql databases to drop their fulltext
|
addPlugin('SphinxSearch');
|
||||||
search indexes, since they're now provided by sphinx.
|
$config['sphinx']['server'] = 'searchhost.local';
|
||||||
|
|
||||||
On the sphinx server side, a script reads the main database and build
|
You also need to install, compile and enable the sphinx pecl extension for
|
||||||
the keyword index. A cron job reads the database and keeps the sphinx
|
php on the client side, which itself depends on the sphinx development files.
|
||||||
indexes up to date. scripts/sphinx-cron.sh should be called by cron
|
|
||||||
every 5 minutes, for example. scripts/sphinx.sh is an init.d script
|
See plugins/SphinxSearch/README for more details and server setup.
|
||||||
to start and stop the sphinx search daemon.
|
|
||||||
|
|
||||||
SMS
|
SMS
|
||||||
---
|
---
|
||||||
@ -558,10 +555,6 @@ This will run eight (for now) queue handlers:
|
|||||||
of registered users.
|
of registered users.
|
||||||
* xmppconfirmhandler.php - sends confirmation messages to registered
|
* xmppconfirmhandler.php - sends confirmation messages to registered
|
||||||
users.
|
users.
|
||||||
* twitterqueuehandler.php - sends queued notices to Twitter for user
|
|
||||||
who have opted to set up Twitter bridging.
|
|
||||||
* facebookqueuehandler.php - sends queued notices to Facebook for users
|
|
||||||
of the built-in Facebook application.
|
|
||||||
|
|
||||||
Note that these queue daemons are pretty raw, and need your care. In
|
Note that these queue daemons are pretty raw, and need your care. In
|
||||||
particular, they leak memory, and you may want to restart them on a
|
particular, they leak memory, and you may want to restart them on a
|
||||||
@ -579,101 +572,6 @@ our kind of hacky home-grown DB-based queue solution. See the "queues"
|
|||||||
config section below for how to configure to use STOMP. As of this
|
config section below for how to configure to use STOMP. As of this
|
||||||
writing, the software has been tested with ActiveMQ (
|
writing, the software has been tested with ActiveMQ (
|
||||||
|
|
||||||
Twitter Bridge
|
|
||||||
--------------
|
|
||||||
|
|
||||||
* OAuth
|
|
||||||
|
|
||||||
As of 0.8.1, OAuth is used to to access protected resources on Twitter
|
|
||||||
instead of HTTP Basic Auth. To use Twitter bridging you will need
|
|
||||||
to register your instance of StatusNet as an application on Twitter
|
|
||||||
(http://twitter.com/apps), and update the following variables in your
|
|
||||||
config.php with the consumer key and secret Twitter generates for you:
|
|
||||||
|
|
||||||
$config['twitter']['consumer_key'] = 'YOURKEY';
|
|
||||||
$config['twitter']['consumer_secret'] = 'YOURSECRET';
|
|
||||||
|
|
||||||
When registering your application with Twitter set the type to "Browser"
|
|
||||||
and your Callback URL to:
|
|
||||||
|
|
||||||
http://example.org/mublog/twitter/authorization
|
|
||||||
|
|
||||||
The default access type should be, "Read & Write".
|
|
||||||
|
|
||||||
* Importing statuses from Twitter
|
|
||||||
|
|
||||||
To allow your users to import their friends' Twitter statuses, you will
|
|
||||||
need to enable the bidirectional Twitter bridge in config.php:
|
|
||||||
|
|
||||||
$config['twitterbridge']['enabled'] = true;
|
|
||||||
|
|
||||||
and run the TwitterStatusFetcher daemon (scripts/twitterstatusfetcher.php).
|
|
||||||
Additionally, you will want to set the integration source variable,
|
|
||||||
which will keep notices posted to Twitter via StatusNet from looping
|
|
||||||
back. The integration source should be set to the name of your
|
|
||||||
application, exactly as you specified it on the settings page for your
|
|
||||||
StatusNet application on Twitter, e.g.:
|
|
||||||
|
|
||||||
$config['integration']['source'] = 'YourApp';
|
|
||||||
|
|
||||||
* Twitter Friends Syncing
|
|
||||||
|
|
||||||
Users may set a flag in their settings ("Subscribe to my Twitter friends
|
|
||||||
here" under the Twitter tab) to have StatusNet attempt to locate and
|
|
||||||
subscribe to "friends" (people they "follow") on Twitter who also have
|
|
||||||
accounts on your StatusNet system, and who have previously set up a link
|
|
||||||
for automatically posting notices to Twitter.
|
|
||||||
|
|
||||||
As of 0.8.0, this is no longer accomplished via a cron job. Instead you
|
|
||||||
must run the SyncTwitterFriends daemon (scripts/synctwitterfreinds.php).
|
|
||||||
|
|
||||||
Built-in Facebook Application
|
|
||||||
-----------------------------
|
|
||||||
|
|
||||||
StatusNet's Facebook application allows your users to automatically
|
|
||||||
update their Facebook statuses with their latest notices, invite
|
|
||||||
their friends to use the app (and thus your site), view their notice
|
|
||||||
timelines, and post notices -- all from within Facebook. The application
|
|
||||||
is built into StatusNet and runs on your host. For automatic Facebook
|
|
||||||
status updating to work you will need to enable queuing and run the
|
|
||||||
facebookqueuehandler.php daemon (see the "Queues and daemons" section
|
|
||||||
above).
|
|
||||||
|
|
||||||
Quick setup instructions*:
|
|
||||||
|
|
||||||
Install the Facebook Developer application on Facebook:
|
|
||||||
|
|
||||||
http://www.facebook.com/developers/
|
|
||||||
|
|
||||||
Use it to create a new application and generate an API key and secret.
|
|
||||||
Uncomment the Facebook app section of your config.php and copy in the
|
|
||||||
key and secret, e.g.:
|
|
||||||
|
|
||||||
# Config section for the built-in Facebook application
|
|
||||||
$config['facebook']['apikey'] = 'APIKEY';
|
|
||||||
$config['facebook']['secret'] = 'SECRET';
|
|
||||||
|
|
||||||
In Facebook's application editor, specify the following URLs for your app:
|
|
||||||
|
|
||||||
- Canvas Callback URL: http://example.net/mublog/facebook/
|
|
||||||
- Post-Remove Callback URL: http://example.net/mublog/facebook/remove
|
|
||||||
- Post-Add Redirect URL: http://apps.facebook.com/yourapp/
|
|
||||||
- Canvas Page URL: http://apps.facebook.com/yourapp/
|
|
||||||
|
|
||||||
(Replace 'example.net' with your host's URL, 'mublog' with the path
|
|
||||||
to your StatusNet installation, and 'yourapp' with the name of the
|
|
||||||
Facebook application you created.)
|
|
||||||
|
|
||||||
Additionally, Choose "Web" for Application type in the Advanced tab.
|
|
||||||
In the "Canvas setting" section, choose the "FBML" for Render Method,
|
|
||||||
"Smart Size" for IFrame size, and "Full width (760px)" for Canvas Width.
|
|
||||||
Everything else can be left with default values.
|
|
||||||
|
|
||||||
*For more detailed instructions please see the installation guide on the
|
|
||||||
StatusNet wiki:
|
|
||||||
|
|
||||||
http://status.net/trac/wiki/FacebookApplication
|
|
||||||
|
|
||||||
Sitemaps
|
Sitemaps
|
||||||
--------
|
--------
|
||||||
|
|
||||||
@ -787,6 +685,16 @@ private site, but users of the private site may be able to subscribe
|
|||||||
to users on a remote site. (Or not... it's not well tested.) The
|
to users on a remote site. (Or not... it's not well tested.) The
|
||||||
"proper behaviour" hasn't been defined here, so handle with care.
|
"proper behaviour" hasn't been defined here, so handle with care.
|
||||||
|
|
||||||
|
If fancy URLs is enabled, access to file attachments can also be
|
||||||
|
restricted to logged-in users only. Uncomment the appropriate rewrite
|
||||||
|
<<<<<<< HEAD:README
|
||||||
|
rule in .htaccess or your server's httpd.conf. (This most likely will
|
||||||
|
not work if you are using a virtual server for attachments, so consider
|
||||||
|
the performance/security tradeoff.)
|
||||||
|
=======
|
||||||
|
rule in .htaccess or your server's httpd.conf.
|
||||||
|
>>>>>>> 446de62... Revert "Added some explanatory text to README":README
|
||||||
|
|
||||||
Upgrading
|
Upgrading
|
||||||
=========
|
=========
|
||||||
|
|
||||||
@ -871,40 +779,8 @@ to update it.
|
|||||||
Notice inboxes
|
Notice inboxes
|
||||||
--------------
|
--------------
|
||||||
|
|
||||||
Before version 0.6.2, the page showing all notices from people the
|
Notice inboxes are now required. If you don't have inboxes enabled,
|
||||||
user is subscribed to ("so-and-so with friends") was calculated at run
|
StatusNet will no longer run.
|
||||||
time. Starting with 0.6.2, we have a new data structure for holding a
|
|
||||||
user's "notice inbox". (Note: distinct from the "message inbox", which
|
|
||||||
is the "inbox" tab in the UI. The notice inbox appears under the
|
|
||||||
"Personal" tab.)
|
|
||||||
|
|
||||||
Notices are added to the inbox when they're created. This speeds up
|
|
||||||
the query considerably, and also allows us the opportunity, in the
|
|
||||||
future, to add different kind of notices to an inbox -- like @-replies
|
|
||||||
or subscriptions to search terms or hashtags.
|
|
||||||
|
|
||||||
Notice inboxes are enabled by default for new installations. If you
|
|
||||||
are upgrading an existing site, this means that your users will see
|
|
||||||
empty "Personal" pages. The following steps will help you fix the
|
|
||||||
problem.
|
|
||||||
|
|
||||||
0. $config['inboxes']['enabled'] can be set to one of three values. If
|
|
||||||
you set it to 'false', the site will work as before. Support for this
|
|
||||||
will probably be dropped in future versions.
|
|
||||||
1. Setting the flag to 'transitional' means that you're in transition.
|
|
||||||
In this mode, the code will run the "new query" or the "old query"
|
|
||||||
based on whether the user's inbox has been updated.
|
|
||||||
2. After setting the flag to "transitional", you can run the
|
|
||||||
fixup_inboxes.php script to create the inboxes. You may want to set
|
|
||||||
the memory limit high. You can re-run it without ill effect.
|
|
||||||
3. When fixup_inboxes is finished, you can set the enabled flag to
|
|
||||||
'true'.
|
|
||||||
|
|
||||||
NOTE: As of version 0.8.1 notice inboxes are automatically trimmed back
|
|
||||||
to ~1000 notices every once in a while.
|
|
||||||
|
|
||||||
NOTE: we will drop support for non-inboxed sites in the 0.9.x version
|
|
||||||
of StatusNet. It's time to switch now!
|
|
||||||
|
|
||||||
UTF-8 Database
|
UTF-8 Database
|
||||||
--------------
|
--------------
|
||||||
@ -976,6 +852,12 @@ locale_path: full path to the directory for locale data. Unless you
|
|||||||
store all your locale data in one place, you probably
|
store all your locale data in one place, you probably
|
||||||
don't need to use this.
|
don't need to use this.
|
||||||
language: default language for your site. Defaults to US English.
|
language: default language for your site. Defaults to US English.
|
||||||
|
Note that this is overridden if a user is logged in and has
|
||||||
|
selected a different language. It is also overridden if the
|
||||||
|
user is NOT logged in, but their browser requests a different
|
||||||
|
langauge. Since pretty much everybody's browser requests a
|
||||||
|
language, that means that changing this setting has little or
|
||||||
|
no effect in practice.
|
||||||
languages: A list of languages supported on your site. Typically you'd
|
languages: A list of languages supported on your site. Typically you'd
|
||||||
only change this if you wanted to disable support for one
|
only change this if you wanted to disable support for one
|
||||||
or another language:
|
or another language:
|
||||||
@ -1000,8 +882,6 @@ closed: If set to 'true', will disallow registration on your site.
|
|||||||
the service, *then* set this variable to 'true'.
|
the service, *then* set this variable to 'true'.
|
||||||
inviteonly: If set to 'true', will only allow registration if the user
|
inviteonly: If set to 'true', will only allow registration if the user
|
||||||
was invited by an existing user.
|
was invited by an existing user.
|
||||||
openidonly: If set to 'true', will only allow registrations and logins
|
|
||||||
through OpenID.
|
|
||||||
private: If set to 'true', anonymous users will be redirected to the
|
private: If set to 'true', anonymous users will be redirected to the
|
||||||
'login' page. Also, API methods that normally require no
|
'login' page. Also, API methods that normally require no
|
||||||
authentication will require it. Note that this does not turn
|
authentication will require it. Note that this does not turn
|
||||||
@ -1029,6 +909,9 @@ shorturllength: Length of URL at which URLs in a message exceeding 140
|
|||||||
dupelimit: minimum time allowed for one person to say the same thing
|
dupelimit: minimum time allowed for one person to say the same thing
|
||||||
twice. Default 60s. Anything lower is considered a user
|
twice. Default 60s. Anything lower is considered a user
|
||||||
or UI error.
|
or UI error.
|
||||||
|
textlimit: default max size for texts in the site. Defaults to 140.
|
||||||
|
0 means no limit. Can be fine-tuned for notices, messages,
|
||||||
|
profile bios and group descriptions.
|
||||||
|
|
||||||
db
|
db
|
||||||
--
|
--
|
||||||
@ -1068,6 +951,14 @@ utf8: whether to talk to the database in UTF-8 mode. This is the default
|
|||||||
with new installations, but older sites may want to turn it off
|
with new installations, but older sites may want to turn it off
|
||||||
until they get their databases fixed up. See "UTF-8 database"
|
until they get their databases fixed up. See "UTF-8 database"
|
||||||
above for details.
|
above for details.
|
||||||
|
schemacheck: when to let plugins check the database schema to add
|
||||||
|
tables or update them. Values can be 'runtime' (default)
|
||||||
|
or 'script'. 'runtime' can be costly (plugins check the
|
||||||
|
schema on every hit, adding potentially several db
|
||||||
|
queries, some quite long), but not everyone knows how to
|
||||||
|
run a script. If you can, set this to 'script' and run
|
||||||
|
scripts/checkschema.php whenever you install or upgrade a
|
||||||
|
plugin.
|
||||||
|
|
||||||
syslog
|
syslog
|
||||||
------
|
------
|
||||||
@ -1229,14 +1120,6 @@ For configuring invites.
|
|||||||
|
|
||||||
enabled: Whether to allow users to send invites. Default true.
|
enabled: Whether to allow users to send invites. Default true.
|
||||||
|
|
||||||
openid
|
|
||||||
------
|
|
||||||
|
|
||||||
For configuring OpenID.
|
|
||||||
|
|
||||||
enabled: Whether to allow users to register and login using OpenID. Default
|
|
||||||
true.
|
|
||||||
|
|
||||||
tag
|
tag
|
||||||
---
|
---
|
||||||
|
|
||||||
@ -1287,17 +1170,6 @@ base: memcached uses key-value pairs to store data. We build long,
|
|||||||
StatusNet site using your memcached server.
|
StatusNet site using your memcached server.
|
||||||
port: Port to connect to; defaults to 11211.
|
port: Port to connect to; defaults to 11211.
|
||||||
|
|
||||||
sphinx
|
|
||||||
------
|
|
||||||
|
|
||||||
You can get a significant boost in performance using Sphinx Search
|
|
||||||
instead of your database server to search for users and notices.
|
|
||||||
<http://sphinxsearch.com/>.
|
|
||||||
|
|
||||||
enabled: Set to true to enable. Default false.
|
|
||||||
server: a string with the hostname of the sphinx server.
|
|
||||||
port: an integer with the port number of the sphinx server.
|
|
||||||
|
|
||||||
emailpost
|
emailpost
|
||||||
---------
|
---------
|
||||||
|
|
||||||
@ -1314,24 +1186,11 @@ For SMS integration.
|
|||||||
enabled: Whether to enable SMS integration. Defaults to true. Queues
|
enabled: Whether to enable SMS integration. Defaults to true. Queues
|
||||||
should also be enabled.
|
should also be enabled.
|
||||||
|
|
||||||
twitter
|
|
||||||
-------
|
|
||||||
|
|
||||||
For Twitter integration
|
|
||||||
|
|
||||||
enabled: Whether to enable Twitter integration. Defaults to true.
|
|
||||||
Queues should also be enabled.
|
|
||||||
|
|
||||||
integration
|
integration
|
||||||
-----------
|
-----------
|
||||||
|
|
||||||
A catch-all for integration with other systems.
|
A catch-all for integration with other systems.
|
||||||
|
|
||||||
source: The name to use for the source of posts to Twitter. Defaults
|
|
||||||
to 'statusnet', but if you request your own source name from
|
|
||||||
Twitter <http://twitter.com/help/request_source>, you can use
|
|
||||||
that here instead. Status updates on Twitter will then have
|
|
||||||
links to your site.
|
|
||||||
taguri: base for tag:// URIs. Defaults to site-server + ',2009'.
|
taguri: base for tag:// URIs. Defaults to site-server + ',2009'.
|
||||||
|
|
||||||
inboxes
|
inboxes
|
||||||
@ -1339,9 +1198,8 @@ inboxes
|
|||||||
|
|
||||||
For notice inboxes.
|
For notice inboxes.
|
||||||
|
|
||||||
enabled: A three-valued flag for whether to use notice inboxes (see
|
enabled: No longer used. If you set this to something other than true,
|
||||||
upgrading info above for notes about this change). Can be
|
StatusNet will no longer run.
|
||||||
'false', 'true', or '"transitional"'.
|
|
||||||
|
|
||||||
throttle
|
throttle
|
||||||
--------
|
--------
|
||||||
@ -1363,6 +1221,8 @@ banned: an array of usernames and/or profile IDs of 'banned' profiles.
|
|||||||
The site will reject any notices by these users -- they will
|
The site will reject any notices by these users -- they will
|
||||||
not be accepted at all. (Compare with blacklisted users above,
|
not be accepted at all. (Compare with blacklisted users above,
|
||||||
whose posts just won't show up in the public stream.)
|
whose posts just won't show up in the public stream.)
|
||||||
|
biolimit: max character length of bio; 0 means no limit; null means to use
|
||||||
|
the site text limit default.
|
||||||
|
|
||||||
newuser
|
newuser
|
||||||
-------
|
-------
|
||||||
@ -1459,6 +1319,9 @@ Options for group functionality.
|
|||||||
|
|
||||||
maxaliases: maximum number of aliases a group can have. Default 3. Set
|
maxaliases: maximum number of aliases a group can have. Default 3. Set
|
||||||
to 0 or less to prevent aliases in a group.
|
to 0 or less to prevent aliases in a group.
|
||||||
|
desclimit: maximum number of characters to allow in group descriptions.
|
||||||
|
null (default) means to use the site-wide text limits. 0
|
||||||
|
means no limit.
|
||||||
|
|
||||||
oohembed
|
oohembed
|
||||||
--------
|
--------
|
||||||
@ -1505,15 +1368,6 @@ dir: directory to write backgrounds too. Default is '/background/'
|
|||||||
path: path to backgrounds. Default is sub-path of install path; note
|
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.
|
that you may need to change this if you change site-path too.
|
||||||
|
|
||||||
twitterbridge
|
|
||||||
-------------
|
|
||||||
|
|
||||||
A bi-direction bridge to Twitter (http://twitter.com/).
|
|
||||||
|
|
||||||
enabled: default false. If true, will show user's Twitter friends'
|
|
||||||
notices in their inbox and faves pages, only to the user. You
|
|
||||||
must also run the twitterstatusfetcher.php script.
|
|
||||||
|
|
||||||
ping
|
ping
|
||||||
----
|
----
|
||||||
|
|
||||||
@ -1537,6 +1391,24 @@ linkcolor: Hex color of all links.
|
|||||||
backgroundimage: Image to use for the background.
|
backgroundimage: Image to use for the background.
|
||||||
disposition: Flags for whether or not to tile the background image.
|
disposition: Flags for whether or not to tile the background image.
|
||||||
|
|
||||||
|
notice
|
||||||
|
------
|
||||||
|
|
||||||
|
Configuration options specific to notices.
|
||||||
|
|
||||||
|
contentlimit: max length of the plain-text content of a notice.
|
||||||
|
Default is null, meaning to use the site-wide text limit.
|
||||||
|
0 means no limit.
|
||||||
|
|
||||||
|
message
|
||||||
|
-------
|
||||||
|
|
||||||
|
Configuration options specific to messages.
|
||||||
|
|
||||||
|
contentlimit: max length of the plain-text content of a message.
|
||||||
|
Default is null, meaning to use the site-wide text limit.
|
||||||
|
0 means no limit.
|
||||||
|
|
||||||
Plugins
|
Plugins
|
||||||
=======
|
=======
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
/**
|
/**
|
||||||
* Access token class.
|
* Access token class
|
||||||
*
|
*
|
||||||
* PHP version 5
|
* PHP version 5
|
||||||
*
|
*
|
||||||
@ -32,10 +32,11 @@ if (!defined('STATUSNET') && !defined('LACONICA')) {
|
|||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
require_once INSTALLDIR.'/extlib/libomb/service_provider.php';
|
||||||
require_once INSTALLDIR.'/lib/omb.php';
|
require_once INSTALLDIR.'/lib/omb.php';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Access token class.
|
* Access token class
|
||||||
*
|
*
|
||||||
* @category Action
|
* @category Action
|
||||||
* @package StatusNet
|
* @package StatusNet
|
||||||
@ -47,28 +48,23 @@ require_once INSTALLDIR.'/lib/omb.php';
|
|||||||
class AccesstokenAction extends Action
|
class AccesstokenAction extends Action
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* Class handler.
|
* Class handler
|
||||||
*
|
*
|
||||||
* @param array $args query arguments
|
* @param array $args query arguments
|
||||||
*
|
*
|
||||||
* @return boolean false if user doesn't exist
|
* @return nothing
|
||||||
*/
|
*
|
||||||
|
**/
|
||||||
function handle($args)
|
function handle($args)
|
||||||
{
|
{
|
||||||
parent::handle($args);
|
parent::handle($args);
|
||||||
try {
|
try {
|
||||||
common_debug('getting request from env variables', __FILE__);
|
$srv = new OMB_Service_Provider(null, omb_oauth_datastore(),
|
||||||
common_remove_magic_from_request();
|
omb_oauth_server());
|
||||||
$req = OAuthRequest::from_request('POST', common_local_url('accesstoken'));
|
$srv->writeAccessToken();
|
||||||
common_debug('getting a server', __FILE__);
|
} catch (Exception $e) {
|
||||||
$server = omb_oauth_server();
|
|
||||||
common_debug('fetching the access token', __FILE__);
|
|
||||||
$token = $server->fetch_access_token($req);
|
|
||||||
common_debug('got this token: "'.print_r($token, true).'"', __FILE__);
|
|
||||||
common_debug('printing the access token', __FILE__);
|
|
||||||
print $token;
|
|
||||||
} catch (OAuthException $e) {
|
|
||||||
$this->serverError($e->getMessage());
|
$this->serverError($e->getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
?>
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
/*
|
/**
|
||||||
* StatusNet - the distributed open-source microblogging tool
|
* StatusNet - the distributed open-source microblogging tool
|
||||||
* Copyright (C) 2008, 2009, StatusNet, Inc.
|
* Copyright (C) 2008, 2009, StatusNet, Inc.
|
||||||
*
|
*
|
||||||
@ -15,9 +15,25 @@
|
|||||||
*
|
*
|
||||||
* You should have received a copy of the GNU Affero General Public License
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* @category Actions
|
||||||
|
* @package Actions
|
||||||
|
* @author Evan Prodromou <evan@status.net>
|
||||||
|
* @author Mike Cochrane <mikec@mikenz.geek.nz>
|
||||||
|
* @author Robin Millette <millette@controlyourself.ca>
|
||||||
|
* @author Adrian Lang <mail@adrianlang.de>
|
||||||
|
* @author Meitar Moscovitz <meitarm@gmail.com>
|
||||||
|
* @author Sarven Capadisli <csarven@status.net>
|
||||||
|
* @author Craig Andrews <candrews@integralblue.com>
|
||||||
|
* @author Jeffery To <jeffery.to@gmail.com>
|
||||||
|
* @author Zach Copley <zach@controlyourself.ca>
|
||||||
|
* @license GNU Affero General Public License http://www.gnu.org/licenses/
|
||||||
|
* @link http://status.net
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (!defined('STATUSNET') && !defined('LACONICA')) { exit(1); }
|
if (!defined('STATUSNET') && !defined('LACONICA')) {
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
require_once INSTALLDIR.'/lib/personalgroupnav.php';
|
require_once INSTALLDIR.'/lib/personalgroupnav.php';
|
||||||
require_once INSTALLDIR.'/lib/noticelist.php';
|
require_once INSTALLDIR.'/lib/noticelist.php';
|
||||||
@ -43,8 +59,8 @@ class AllAction extends ProfileAction
|
|||||||
$this->notice = $this->user->noticesWithFriends(($this->page-1)*NOTICES_PER_PAGE, NOTICES_PER_PAGE + 1);
|
$this->notice = $this->user->noticesWithFriends(($this->page-1)*NOTICES_PER_PAGE, NOTICES_PER_PAGE + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if($this->page > 1 && $this->notice->N == 0){
|
if ($this->page > 1 && $this->notice->N == 0) {
|
||||||
$this->serverError(_('No such page'),$code=404);
|
$this->serverError(_('No such page'), $code = 404);
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@ -73,20 +89,31 @@ class AllAction extends ProfileAction
|
|||||||
|
|
||||||
function getFeeds()
|
function getFeeds()
|
||||||
{
|
{
|
||||||
return array(new Feed(Feed::RSS1,
|
return array(
|
||||||
common_local_url('allrss', array('nickname' =>
|
new Feed(Feed::RSS1,
|
||||||
$this->user->nickname)),
|
common_local_url(
|
||||||
sprintf(_('Feed for friends of %s (RSS 1.0)'), $this->user->nickname)),
|
'allrss', array(
|
||||||
new Feed(Feed::RSS2,
|
'nickname' =>
|
||||||
common_local_url('api', array('apiaction' => 'statuses',
|
$this->user->nickname)
|
||||||
'method' => 'friends_timeline',
|
),
|
||||||
'argument' => $this->user->nickname.'.rss')),
|
sprintf(_('Feed for friends of %s (RSS 1.0)'), $this->user->nickname)),
|
||||||
sprintf(_('Feed for friends of %s (RSS 2.0)'), $this->user->nickname)),
|
new Feed(Feed::RSS2,
|
||||||
new Feed(Feed::ATOM,
|
common_local_url(
|
||||||
common_local_url('api', array('apiaction' => 'statuses',
|
'ApiTimelineFriends', array(
|
||||||
'method' => 'friends_timeline',
|
'format' => 'rss',
|
||||||
'argument' => $this->user->nickname.'.atom')),
|
'id' => $this->user->nickname
|
||||||
sprintf(_('Feed for friends of %s (Atom)'), $this->user->nickname)));
|
)
|
||||||
|
),
|
||||||
|
sprintf(_('Feed for friends of %s (RSS 2.0)'), $this->user->nickname)),
|
||||||
|
new Feed(Feed::ATOM,
|
||||||
|
common_local_url(
|
||||||
|
'ApiTimelineFriends', array(
|
||||||
|
'format' => 'atom',
|
||||||
|
'id' => $this->user->nickname
|
||||||
|
)
|
||||||
|
),
|
||||||
|
sprintf(_('Feed for friends of %s (Atom)'), $this->user->nickname))
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function showLocalNav()
|
function showLocalNav()
|
||||||
@ -106,11 +133,8 @@ class AllAction extends ProfileAction
|
|||||||
} else {
|
} else {
|
||||||
$message .= sprintf(_('You can try to [nudge %s](../%s) from his profile or [post something to his or her attention](%%%%action.newnotice%%%%?status_textarea=%s).'), $this->user->nickname, $this->user->nickname, '@' . $this->user->nickname);
|
$message .= sprintf(_('You can try to [nudge %s](../%s) from his profile or [post something to his or her attention](%%%%action.newnotice%%%%?status_textarea=%s).'), $this->user->nickname, $this->user->nickname, '@' . $this->user->nickname);
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else {
|
$message .= sprintf(_('Why not [register an account](%%%%action.register%%%%) and then nudge %s or post a notice to his or her attention.'), $this->user->nickname);
|
||||||
$message .= sprintf(_('Why not [register an account](%%%%action.%s%%%%) and then nudge %s or post a notice to his or her attention.'),
|
|
||||||
(!common_config('site','openidonly')) ? 'register' : 'openidlogin',
|
|
||||||
$this->user->nickname);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->elementStart('div', 'guide');
|
$this->elementStart('div', 'guide');
|
||||||
@ -128,17 +152,19 @@ class AllAction extends ProfileAction
|
|||||||
$this->showEmptyListMessage();
|
$this->showEmptyListMessage();
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->pagination($this->page > 1, $cnt > NOTICES_PER_PAGE,
|
$this->pagination(
|
||||||
$this->page, 'all', array('nickname' => $this->user->nickname));
|
$this->page > 1, $cnt > NOTICES_PER_PAGE,
|
||||||
|
$this->page, 'all', array('nickname' => $this->user->nickname)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function showPageTitle()
|
function showPageTitle()
|
||||||
{
|
{
|
||||||
$user =& common_current_user();
|
$user =& common_current_user();
|
||||||
if ($user && ($user->id == $this->user->id)) {
|
if ($user && ($user->id == $this->user->id)) {
|
||||||
$this->element('h1', NULL, _("You and friends"));
|
$this->element('h1', null, _("You and friends"));
|
||||||
} else {
|
} else {
|
||||||
$this->element('h1', NULL, sprintf(_('%s and friends'), $this->user->nickname));
|
$this->element('h1', null, sprintf(_('%s and friends'), $this->user->nickname));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -68,6 +68,7 @@ class AllrssAction extends Rss10Action
|
|||||||
$this->clientError(_('No such user.'));
|
$this->clientError(_('No such user.'));
|
||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
|
$this->notices = $this->getNotices($this->limit);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
293
actions/api.php
293
actions/api.php
@ -1,293 +0,0 @@
|
|||||||
<?php
|
|
||||||
/*
|
|
||||||
* StatusNet - the distributed open-source microblogging tool
|
|
||||||
* Copyright (C) 2008, 2009, StatusNet, Inc.
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU Affero General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU Affero General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Affero General Public License
|
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (!defined('STATUSNET') && !defined('LACONICA')) { exit(1); }
|
|
||||||
|
|
||||||
class ApiAction extends Action
|
|
||||||
{
|
|
||||||
|
|
||||||
var $user;
|
|
||||||
var $content_type;
|
|
||||||
var $api_arg;
|
|
||||||
var $api_method;
|
|
||||||
var $api_action;
|
|
||||||
var $auth_user;
|
|
||||||
var $auth_pw;
|
|
||||||
|
|
||||||
function handle($args)
|
|
||||||
{
|
|
||||||
parent::handle($args);
|
|
||||||
|
|
||||||
$this->api_action = $this->arg('apiaction');
|
|
||||||
$method = $this->arg('method');
|
|
||||||
$argument = $this->arg('argument');
|
|
||||||
$this->basic_auth_process_header();
|
|
||||||
|
|
||||||
if (isset($argument)) {
|
|
||||||
$cmdext = explode('.', $argument);
|
|
||||||
$this->api_arg = $cmdext[0];
|
|
||||||
$this->api_method = $method;
|
|
||||||
$this->content_type = strtolower($cmdext[1]);
|
|
||||||
} else {
|
|
||||||
|
|
||||||
# Requested format / content-type will be an extension on the method
|
|
||||||
$cmdext = explode('.', $method);
|
|
||||||
$this->api_method = $cmdext[0];
|
|
||||||
$this->content_type = strtolower($cmdext[1]);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($this->requires_auth()) {
|
|
||||||
if (!isset($this->auth_user)) {
|
|
||||||
|
|
||||||
# This header makes basic auth go
|
|
||||||
header('WWW-Authenticate: Basic realm="StatusNet API"');
|
|
||||||
|
|
||||||
# If the user hits cancel -- bam!
|
|
||||||
$this->show_basic_auth_error();
|
|
||||||
} else {
|
|
||||||
$nickname = $this->auth_user;
|
|
||||||
$password = $this->auth_pw;
|
|
||||||
$user = common_check_user($nickname, $password);
|
|
||||||
|
|
||||||
if ($user) {
|
|
||||||
$this->user = $user;
|
|
||||||
$this->process_command();
|
|
||||||
} else {
|
|
||||||
# basic authentication failed
|
|
||||||
list($proxy, $ip) = common_client_ip();
|
|
||||||
|
|
||||||
common_log(LOG_WARNING, "Failed API auth attempt, nickname = $nickname, proxy = $proxy, ip = $ip.");
|
|
||||||
$this->show_basic_auth_error();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
|
|
||||||
// Caller might give us a username even if not required
|
|
||||||
if (isset($this->auth_user)) {
|
|
||||||
$user = User::staticGet('nickname', $this->auth_user);
|
|
||||||
if ($user) {
|
|
||||||
$this->user = $user;
|
|
||||||
}
|
|
||||||
# Twitter doesn't throw an error if the user isn't found
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->process_command();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function process_command()
|
|
||||||
{
|
|
||||||
$action = "twitapi$this->api_action";
|
|
||||||
$actionfile = INSTALLDIR."/actions/$action.php";
|
|
||||||
|
|
||||||
if (file_exists($actionfile)) {
|
|
||||||
require_once($actionfile);
|
|
||||||
$action_class = ucfirst($action)."Action";
|
|
||||||
$action_obj = new $action_class();
|
|
||||||
|
|
||||||
if (!$action_obj->prepare($this->args)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (method_exists($action_obj, $this->api_method)) {
|
|
||||||
$apidata = array( 'content-type' => $this->content_type,
|
|
||||||
'api_method' => $this->api_method,
|
|
||||||
'api_arg' => $this->api_arg,
|
|
||||||
'user' => $this->user);
|
|
||||||
|
|
||||||
call_user_func(array($action_obj, $this->api_method), $_REQUEST, $apidata);
|
|
||||||
} else {
|
|
||||||
$this->clientError("API method not found!", $code=404);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
$this->clientError("API method not found!", $code=404);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Whitelist of API methods that don't need authentication
|
|
||||||
function requires_auth()
|
|
||||||
{
|
|
||||||
static $noauth = array( 'statuses/public_timeline',
|
|
||||||
'statuses/show',
|
|
||||||
'users/show',
|
|
||||||
'help/test',
|
|
||||||
'help/downtime_schedule',
|
|
||||||
'statusnet/version',
|
|
||||||
'statusnet/config',
|
|
||||||
'statusnet/wadl',
|
|
||||||
'tags/timeline',
|
|
||||||
'oembed/oembed',
|
|
||||||
'groups/show',
|
|
||||||
'groups/timeline',
|
|
||||||
'groups/list_all',
|
|
||||||
'groups/membership',
|
|
||||||
'groups/is_member',
|
|
||||||
'groups/timeline');
|
|
||||||
|
|
||||||
static $bareauth = array('statuses/user_timeline',
|
|
||||||
'statuses/friends_timeline',
|
|
||||||
'statuses/home_timeline',
|
|
||||||
'statuses/friends',
|
|
||||||
'statuses/replies',
|
|
||||||
'statuses/mentions',
|
|
||||||
'statuses/followers',
|
|
||||||
'favorites/favorites',
|
|
||||||
'friendships/show',
|
|
||||||
'groups/list_groups');
|
|
||||||
|
|
||||||
$fullname = "$this->api_action/$this->api_method";
|
|
||||||
|
|
||||||
// If the site is "private", all API methods except statusnet/config
|
|
||||||
// need authentication
|
|
||||||
|
|
||||||
if (common_config('site', 'private')) {
|
|
||||||
return $fullname != 'statusnet/config' || false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// bareauth: only needs auth if without an argument or query param specifying user
|
|
||||||
|
|
||||||
if (in_array($fullname, $bareauth)) {
|
|
||||||
|
|
||||||
// Special case: friendships/show only needs auth if source_id or
|
|
||||||
// source_screen_name is not specified as a param
|
|
||||||
|
|
||||||
if ($fullname == 'friendships/show') {
|
|
||||||
|
|
||||||
$source_id = $this->arg('source_id');
|
|
||||||
$source_screen_name = $this->arg('source_screen_name');
|
|
||||||
|
|
||||||
if (empty($source_id) && empty($source_screen_name)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// if all of these are empty, auth is required
|
|
||||||
|
|
||||||
$id = $this->arg('id');
|
|
||||||
$user_id = $this->arg('user_id');
|
|
||||||
$screen_name = $this->arg('screen_name');
|
|
||||||
|
|
||||||
if (empty($this->api_arg) &&
|
|
||||||
empty($id) &&
|
|
||||||
empty($user_id) &&
|
|
||||||
empty($screen_name)) {
|
|
||||||
return true;
|
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
} else if (in_array($fullname, $noauth)) {
|
|
||||||
|
|
||||||
// noauth: never needs auth
|
|
||||||
|
|
||||||
return false;
|
|
||||||
} else {
|
|
||||||
|
|
||||||
// everybody else needs auth
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function basic_auth_process_header()
|
|
||||||
{
|
|
||||||
if(isset($_SERVER['AUTHORIZATION']) || isset($_SERVER['HTTP_AUTHORIZATION']))
|
|
||||||
{
|
|
||||||
$authorization_header = isset($_SERVER['HTTP_AUTHORIZATION'])?$_SERVER['HTTP_AUTHORIZATION']:$_SERVER['AUTHORIZATION'];
|
|
||||||
}
|
|
||||||
|
|
||||||
if(isset($_SERVER['PHP_AUTH_USER']))
|
|
||||||
{
|
|
||||||
$this->auth_user = $_SERVER['PHP_AUTH_USER'];
|
|
||||||
$this->auth_pw = $_SERVER['PHP_AUTH_PW'];
|
|
||||||
}
|
|
||||||
elseif ( isset($authorization_header) && strstr(substr($authorization_header, 0,5),'Basic') )
|
|
||||||
{
|
|
||||||
// decode the HTTP_AUTHORIZATION header on php-cgi server self
|
|
||||||
// on fcgid server the header name is AUTHORIZATION
|
|
||||||
|
|
||||||
$auth_hash = base64_decode( substr($authorization_header, 6) );
|
|
||||||
list($this->auth_user, $this->auth_pw) = explode(':', $auth_hash);
|
|
||||||
|
|
||||||
// set all to NULL on a empty basic auth request
|
|
||||||
if($this->auth_user == "") {
|
|
||||||
$this->auth_user = NULL;
|
|
||||||
$this->auth_pw = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
$this->auth_user = NULL;
|
|
||||||
$this->auth_pw = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function show_basic_auth_error()
|
|
||||||
{
|
|
||||||
header('HTTP/1.1 401 Unauthorized');
|
|
||||||
$msg = 'Could not authenticate you.';
|
|
||||||
|
|
||||||
if ($this->content_type == 'xml') {
|
|
||||||
header('Content-Type: application/xml; charset=utf-8');
|
|
||||||
$this->startXML();
|
|
||||||
$this->elementStart('hash');
|
|
||||||
$this->element('error', null, $msg);
|
|
||||||
$this->element('request', null, $_SERVER['REQUEST_URI']);
|
|
||||||
$this->elementEnd('hash');
|
|
||||||
$this->endXML();
|
|
||||||
} else if ($this->content_type == 'json') {
|
|
||||||
header('Content-Type: application/json; charset=utf-8');
|
|
||||||
$error_array = array('error' => $msg, 'request' => $_SERVER['REQUEST_URI']);
|
|
||||||
print(json_encode($error_array));
|
|
||||||
} else {
|
|
||||||
header('Content-type: text/plain');
|
|
||||||
print "$msg\n";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function isReadOnly($args)
|
|
||||||
{
|
|
||||||
$apiaction = $args['apiaction'];
|
|
||||||
$method = $args['method'];
|
|
||||||
|
|
||||||
list($cmdtext, $fmt) = explode('.', $method);
|
|
||||||
|
|
||||||
static $write_methods = array(
|
|
||||||
'account' => array('update_location', 'update_delivery_device', 'end_session'),
|
|
||||||
'blocks' => array('create', 'destroy'),
|
|
||||||
'direct_messages' => array('create', 'destroy'),
|
|
||||||
'favorites' => array('create', 'destroy'),
|
|
||||||
'friendships' => array('create', 'destroy'),
|
|
||||||
'help' => array(),
|
|
||||||
'notifications' => array('follow', 'leave'),
|
|
||||||
'statuses' => array('update', 'destroy'),
|
|
||||||
'users' => array()
|
|
||||||
);
|
|
||||||
|
|
||||||
if (array_key_exists($apiaction, $write_methods)) {
|
|
||||||
if (!in_array($cmdtext, $write_methods[$apiaction])) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
112
actions/apiaccountratelimitstatus.php
Normal file
112
actions/apiaccountratelimitstatus.php
Normal file
@ -0,0 +1,112 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* StatusNet, the distributed open-source microblogging tool
|
||||||
|
*
|
||||||
|
* Dummy action that emulates Twitter's rate limit status API resource
|
||||||
|
*
|
||||||
|
* 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>
|
||||||
|
* @author Robin Millette <robin@millette.info>
|
||||||
|
* @author Zach Copley <zach@status.net>
|
||||||
|
* @copyright 2009 StatusNet, Inc.
|
||||||
|
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||||
|
* @link http://status.net/
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (!defined('STATUSNET')) {
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
require_once INSTALLDIR . '/lib/apibareauth.php';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* We don't have a rate limit, but some clients check this method.
|
||||||
|
* It always returns the same thing: 150 hits left.
|
||||||
|
*
|
||||||
|
* @category API
|
||||||
|
* @package StatusNet
|
||||||
|
* @author Evan Prodromou <evan@status.net>
|
||||||
|
* @author Robin Millette <robin@millette.info>
|
||||||
|
* @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 ApiAccountRateLimitStatusAction extends ApiBareAuthAction
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle the request
|
||||||
|
*
|
||||||
|
* Return some Twitter-ish data about API limits
|
||||||
|
*
|
||||||
|
* @param array $args $_REQUEST data (unused)
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
|
||||||
|
function handle($args)
|
||||||
|
{
|
||||||
|
parent::handle($args);
|
||||||
|
|
||||||
|
if (!in_array($this->format, array('xml', 'json'))) {
|
||||||
|
$this->clientError(
|
||||||
|
_('API method not found.'),
|
||||||
|
404,
|
||||||
|
$this->format
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$reset = new DateTime();
|
||||||
|
$reset->modify('+1 hour');
|
||||||
|
|
||||||
|
$this->initDocument($this->format);
|
||||||
|
|
||||||
|
if ($this->format == 'xml') {
|
||||||
|
$this->elementStart('hash');
|
||||||
|
$this->element('remaining-hits', array('type' => 'integer'), 150);
|
||||||
|
$this->element('hourly-limit', array('type' => 'integer'), 150);
|
||||||
|
$this->element(
|
||||||
|
'reset-time', array('type' => 'datetime'),
|
||||||
|
common_date_iso8601($reset->format('r'))
|
||||||
|
);
|
||||||
|
$this->element(
|
||||||
|
'reset_time_in_seconds',
|
||||||
|
array('type' => 'integer'),
|
||||||
|
strtotime('+1 hour')
|
||||||
|
);
|
||||||
|
$this->elementEnd('hash');
|
||||||
|
} elseif ($this->format == 'json') {
|
||||||
|
$out = array(
|
||||||
|
'reset_time_in_seconds' => strtotime('+1 hour'),
|
||||||
|
'remaining_hits' => 150,
|
||||||
|
'hourly_limit' => 150,
|
||||||
|
'reset_time' => common_date_rfc2822(
|
||||||
|
$reset->format('r')
|
||||||
|
)
|
||||||
|
);
|
||||||
|
print json_encode($out);
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->endDocument($this->format);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
157
actions/apiaccountupdatedeliverydevice.php
Normal file
157
actions/apiaccountupdatedeliverydevice.php
Normal file
@ -0,0 +1,157 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* StatusNet, the distributed open-source microblogging tool
|
||||||
|
*
|
||||||
|
* Update the authenticating user notification channels
|
||||||
|
*
|
||||||
|
* 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 Zach Copley <zach@status.net>
|
||||||
|
* @copyright 2009 StatusNet, Inc.
|
||||||
|
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||||
|
* @link http://status.net/
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (!defined('STATUSNET')) {
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
require_once INSTALLDIR . '/lib/apiauth.php';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets which channel (device) StatusNet delivers updates to for
|
||||||
|
* the authenticating user. Sending none as the device parameter
|
||||||
|
* will disable IM and/or SMS updates.
|
||||||
|
*
|
||||||
|
* @category API
|
||||||
|
* @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 ApiAccountUpdateDeliveryDeviceAction extends ApiAuthAction
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Take arguments for running
|
||||||
|
*
|
||||||
|
* @param array $args $_REQUEST args
|
||||||
|
*
|
||||||
|
* @return boolean success flag
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
function prepare($args)
|
||||||
|
{
|
||||||
|
parent::prepare($args);
|
||||||
|
|
||||||
|
$this->user = $this->auth_user;
|
||||||
|
$this->device = $this->trimmed('device');
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle the request
|
||||||
|
*
|
||||||
|
* See which request params have been set, and update the user settings
|
||||||
|
*
|
||||||
|
* @param array $args $_REQUEST data (unused)
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
|
||||||
|
function handle($args)
|
||||||
|
{
|
||||||
|
parent::handle($args);
|
||||||
|
|
||||||
|
if ($_SERVER['REQUEST_METHOD'] != 'POST') {
|
||||||
|
$this->clientError(
|
||||||
|
_('This method requires a POST.'),
|
||||||
|
400, $this->format
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!in_array($this->format, array('xml', 'json'))) {
|
||||||
|
$this->clientError(
|
||||||
|
_('API method not found.'),
|
||||||
|
404,
|
||||||
|
$this->format
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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'
|
||||||
|
)
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (empty($this->user)) {
|
||||||
|
$this->clientError(_('No such user.'), 404, $this->format);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$original = clone($this->user);
|
||||||
|
|
||||||
|
if (strtolower($this->device) == 'sms') {
|
||||||
|
$this->user->smsnotify = true;
|
||||||
|
} elseif (strtolower($this->device) == 'im') {
|
||||||
|
$this->user->jabbernotify = true;
|
||||||
|
} elseif (strtolower($this->device == 'none')) {
|
||||||
|
$this->user->smsnotify = false;
|
||||||
|
$this->user->jabbernotify = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$result = $this->user->update($original);
|
||||||
|
|
||||||
|
if ($result === false) {
|
||||||
|
common_log_db_error($this->user, 'UPDATE', __FILE__);
|
||||||
|
$this->serverError(_('Could not update user.'));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$profile = $this->user->getProfile();
|
||||||
|
|
||||||
|
$twitter_user = $this->twitterUserArray($profile, true);
|
||||||
|
|
||||||
|
// Note: this Twitter API method is retarded because it doesn't give
|
||||||
|
// any success/failure information. Twitter's docs claim that the
|
||||||
|
// notification field will change to reflect notification choice,
|
||||||
|
// but that's not true; notification> is used to indicate
|
||||||
|
// whether the auth user is following the user in question.
|
||||||
|
|
||||||
|
if ($this->format == 'xml') {
|
||||||
|
$this->initDocument('xml');
|
||||||
|
$this->showTwitterXmlUser($twitter_user);
|
||||||
|
$this->endDocument('xml');
|
||||||
|
} elseif ($this->format == 'json') {
|
||||||
|
$this->initDocument('json');
|
||||||
|
$this->showJsonObjects($twitter_user);
|
||||||
|
$this->endDocument('json');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
166
actions/apiaccountupdateprofile.php
Normal file
166
actions/apiaccountupdateprofile.php
Normal file
@ -0,0 +1,166 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* StatusNet, the distributed open-source microblogging tool
|
||||||
|
*
|
||||||
|
* Update the authenticating user's profile
|
||||||
|
*
|
||||||
|
* 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 Zach Copley <zach@status.net>
|
||||||
|
* @copyright 2009 StatusNet, Inc.
|
||||||
|
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||||
|
* @link http://status.net/
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (!defined('STATUSNET')) {
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
require_once INSTALLDIR . '/lib/apiauth.php';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* API analog to the profile settings page
|
||||||
|
* Only the parameters specified will be updated.
|
||||||
|
*
|
||||||
|
* @category API
|
||||||
|
* @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 ApiAccountUpdateProfileAction extends ApiAuthAction
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Take arguments for running
|
||||||
|
*
|
||||||
|
* @param array $args $_REQUEST args
|
||||||
|
*
|
||||||
|
* @return boolean success flag
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
function prepare($args)
|
||||||
|
{
|
||||||
|
parent::prepare($args);
|
||||||
|
|
||||||
|
$this->user = $this->auth_user;
|
||||||
|
|
||||||
|
$this->name = $this->trimmed('name');
|
||||||
|
$this->url = $this->trimmed('url');
|
||||||
|
$this->location = $this->trimmed('location');
|
||||||
|
$this->description = $this->trimmed('description');
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle the request
|
||||||
|
*
|
||||||
|
* See which request params have been set, and update the profile
|
||||||
|
*
|
||||||
|
* @param array $args $_REQUEST data (unused)
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
|
||||||
|
function handle($args)
|
||||||
|
{
|
||||||
|
parent::handle($args);
|
||||||
|
|
||||||
|
if ($_SERVER['REQUEST_METHOD'] != 'POST') {
|
||||||
|
$this->clientError(
|
||||||
|
_('This method requires a POST.'),
|
||||||
|
400, $this->format
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!in_array($this->format, array('xml', 'json'))) {
|
||||||
|
$this->clientError(
|
||||||
|
_('API method not found.'),
|
||||||
|
404,
|
||||||
|
$this->format
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (empty($this->user)) {
|
||||||
|
$this->clientError(_('No such user.'), 404, $this->format);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$profile = $this->user->getProfile();
|
||||||
|
|
||||||
|
if (empty($profile)) {
|
||||||
|
$this->clientError(_('User has no profile.'));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$original = clone($profile);
|
||||||
|
|
||||||
|
if (empty($this->name)) {
|
||||||
|
$profile->fullname = $this->name;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (empty($this->url)) {
|
||||||
|
$profile->homepage = $this->url;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!empty($this->description)) {
|
||||||
|
$profile->bio = $this->description;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!empty($this->location)) {
|
||||||
|
$profile->location = $this->location;
|
||||||
|
|
||||||
|
$loc = Location::fromName($location);
|
||||||
|
|
||||||
|
if (!empty($loc)) {
|
||||||
|
$profile->lat = $loc->lat;
|
||||||
|
$profile->lon = $loc->lon;
|
||||||
|
$profile->location_id = $loc->location_id;
|
||||||
|
$profile->location_ns = $loc->location_ns;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$result = $profile->update($original);
|
||||||
|
|
||||||
|
if (!$result) {
|
||||||
|
common_log_db_error($profile, 'UPDATE', __FILE__);
|
||||||
|
$this->serverError(_('Could not save profile.'));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
common_broadcast_profile($profile);
|
||||||
|
|
||||||
|
$twitter_user = $this->twitterUserArray($profile, true);
|
||||||
|
|
||||||
|
if ($this->format == 'xml') {
|
||||||
|
$this->initDocument('xml');
|
||||||
|
$this->showTwitterXmlUser($twitter_user);
|
||||||
|
$this->endDocument('xml');
|
||||||
|
} elseif ($this->format == 'json') {
|
||||||
|
$this->initDocument('json');
|
||||||
|
$this->showJsonObjects($twitter_user);
|
||||||
|
$this->endDocument('json');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
211
actions/apiaccountupdateprofilebackgroundimage.php
Normal file
211
actions/apiaccountupdateprofilebackgroundimage.php
Normal file
@ -0,0 +1,211 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* StatusNet, the distributed open-source microblogging tool
|
||||||
|
*
|
||||||
|
* Update the authenticating user's profile background 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 Zach Copley <zach@status.net>
|
||||||
|
* @copyright 2009 StatusNet, Inc.
|
||||||
|
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||||
|
* @link http://status.net/
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (!defined('STATUSNET')) {
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
require_once INSTALLDIR . '/lib/apiauth.php';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update the authenticating user's profile background image
|
||||||
|
*
|
||||||
|
* @category API
|
||||||
|
* @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 ApiAccountUpdateProfileBackgroundImageAction extends ApiAuthAction
|
||||||
|
{
|
||||||
|
|
||||||
|
var $tile = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Take arguments for running
|
||||||
|
*
|
||||||
|
* @param array $args $_REQUEST args
|
||||||
|
*
|
||||||
|
* @return boolean success flag
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
function prepare($args)
|
||||||
|
{
|
||||||
|
parent::prepare($args);
|
||||||
|
|
||||||
|
$this->user = $this->auth_user;
|
||||||
|
$this->tile = $this->arg('tile');
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle the request
|
||||||
|
*
|
||||||
|
* Check whether the credentials are valid and output the result
|
||||||
|
*
|
||||||
|
* @param array $args $_REQUEST data (unused)
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
|
||||||
|
function handle($args)
|
||||||
|
{
|
||||||
|
parent::handle($args);
|
||||||
|
|
||||||
|
if ($_SERVER['REQUEST_METHOD'] != 'POST') {
|
||||||
|
$this->clientError(
|
||||||
|
_('This method requires a POST.'),
|
||||||
|
400, $this->format
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!in_array($this->format, array('xml', 'json'))) {
|
||||||
|
$this->clientError(
|
||||||
|
_('API method not found.'),
|
||||||
|
404,
|
||||||
|
$this->format
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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.');
|
||||||
|
|
||||||
|
$this->clientError(sprintf($msg, $_SERVER['CONTENT_LENGTH']));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (empty($this->user)) {
|
||||||
|
$this->clientError(_('No such user.'), 404, $this->format);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$design = $this->user->getDesign();
|
||||||
|
|
||||||
|
// XXX: This is kinda gross, but before we can add a background
|
||||||
|
// img we have to make sure there's a Design because design ID
|
||||||
|
// is part of the img filename.
|
||||||
|
|
||||||
|
if (empty($design)) {
|
||||||
|
|
||||||
|
$this->user->query('BEGIN');
|
||||||
|
|
||||||
|
// save new design
|
||||||
|
$design = new Design();
|
||||||
|
$id = $design->insert();
|
||||||
|
|
||||||
|
if (empty($id)) {
|
||||||
|
common_log_db_error($id, 'INSERT', __FILE__);
|
||||||
|
$this->clientError(_('Unable to save your design settings.'));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$original = clone($this->user);
|
||||||
|
$this->user->design_id = $id;
|
||||||
|
$result = $this->user->update($original);
|
||||||
|
|
||||||
|
if (empty($result)) {
|
||||||
|
common_log_db_error($original, 'UPDATE', __FILE__);
|
||||||
|
$this->clientError(_('Unable to save your design settings.'));
|
||||||
|
$this->user->query('ROLLBACK');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->user->query('COMMIT');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Okay, now get the image and add it to the design
|
||||||
|
|
||||||
|
try {
|
||||||
|
$imagefile = ImageFile::fromUpload('image');
|
||||||
|
} catch (Exception $e) {
|
||||||
|
$this->clientError($e->getMessage(), 400, $this->format);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$filename = Design::filename(
|
||||||
|
$design->id,
|
||||||
|
image_type_to_extension($imagefile->type),
|
||||||
|
common_timestamp()
|
||||||
|
);
|
||||||
|
|
||||||
|
$filepath = Design::path($filename);
|
||||||
|
|
||||||
|
move_uploaded_file($imagefile->filepath, $filepath);
|
||||||
|
|
||||||
|
// delete any old backround img laying around
|
||||||
|
|
||||||
|
if (isset($design->backgroundimage)) {
|
||||||
|
@unlink(Design::path($design->backgroundimage));
|
||||||
|
}
|
||||||
|
|
||||||
|
$original = clone($design);
|
||||||
|
$design->backgroundimage = $filename;
|
||||||
|
$design->setDisposition(true, false, ($this->tile == 'true'));
|
||||||
|
|
||||||
|
$result = $design->update($original);
|
||||||
|
|
||||||
|
if ($result === false) {
|
||||||
|
common_log_db_error($design, 'UPDATE', __FILE__);
|
||||||
|
$this->showForm(_('Could not update your design.'));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$profile = $this->user->getProfile();
|
||||||
|
|
||||||
|
if (empty($profile)) {
|
||||||
|
$this->clientError(_('User has no profile.'));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$twitter_user = $this->twitterUserArray($profile, true);
|
||||||
|
|
||||||
|
if ($this->format == 'xml') {
|
||||||
|
$this->initDocument('xml');
|
||||||
|
$this->showTwitterXmlUser($twitter_user);
|
||||||
|
$this->endDocument('xml');
|
||||||
|
} elseif ($this->format == 'json') {
|
||||||
|
$this->initDocument('json');
|
||||||
|
$this->showJsonObjects($twitter_user);
|
||||||
|
$this->endDocument('json');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
246
actions/apiaccountupdateprofilecolors.php
Normal file
246
actions/apiaccountupdateprofilecolors.php
Normal file
@ -0,0 +1,246 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* StatusNet, the distributed open-source microblogging tool
|
||||||
|
*
|
||||||
|
* Update a user's design colors
|
||||||
|
*
|
||||||
|
* 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 Zach Copley <zach@status.net>
|
||||||
|
* @copyright 2009 StatusNet, Inc.
|
||||||
|
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||||
|
* @link http://status.net/
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (!defined('STATUSNET')) {
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
require_once INSTALLDIR . '/lib/apiauth.php';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets one or more hex values that control the color scheme of the
|
||||||
|
* authenticating user's design
|
||||||
|
*
|
||||||
|
* @category API
|
||||||
|
* @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 ApiAccountUpdateProfileColorsAction extends ApiAuthAction
|
||||||
|
{
|
||||||
|
|
||||||
|
var $profile_background_color = null;
|
||||||
|
var $profile_text_color = null;
|
||||||
|
var $profile_link_color = null;
|
||||||
|
var $profile_sidebar_fill_color = null;
|
||||||
|
var $profile_sidebar_border_color = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Take arguments for running
|
||||||
|
*
|
||||||
|
* @param array $args $_REQUEST args
|
||||||
|
*
|
||||||
|
* @return boolean success flag
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
function prepare($args)
|
||||||
|
{
|
||||||
|
parent::prepare($args);
|
||||||
|
|
||||||
|
$this->user = $this->auth_user;
|
||||||
|
|
||||||
|
$this->profile_background_color
|
||||||
|
= $this->trimmed('profile_background_color');
|
||||||
|
$this->profile_text_color
|
||||||
|
= $this->trimmed('profile_text_color');
|
||||||
|
$this->profile_link_color
|
||||||
|
= $this->trimmed('profile_link_color');
|
||||||
|
$this->profile_sidebar_fill_color
|
||||||
|
= $this->trimmed('profile_sidebar_fill_color');
|
||||||
|
|
||||||
|
// XXX: we don't support changing the sidebar border color
|
||||||
|
// in our designs.
|
||||||
|
|
||||||
|
$this->profile_sidebar_border_color
|
||||||
|
= $this->trimmed('profile_sidebar_border_color');
|
||||||
|
|
||||||
|
// XXX: Unlike Twitter, we do allow people to change the 'content color'
|
||||||
|
|
||||||
|
$this->profile_content_color = $this->trimmed('profile_content_color');
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle the request
|
||||||
|
*
|
||||||
|
* Try to save the user's colors in her design. Create a new design
|
||||||
|
* if the user doesn't already have one.
|
||||||
|
*
|
||||||
|
* @param array $args $_REQUEST data (unused)
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
|
||||||
|
function handle($args)
|
||||||
|
{
|
||||||
|
parent::handle($args);
|
||||||
|
|
||||||
|
if ($_SERVER['REQUEST_METHOD'] != 'POST') {
|
||||||
|
$this->clientError(
|
||||||
|
_('This method requires a POST.'),
|
||||||
|
400, $this->format
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!in_array($this->format, array('xml', 'json'))) {
|
||||||
|
$this->clientError(
|
||||||
|
_('API method not found.'),
|
||||||
|
404,
|
||||||
|
$this->format
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$design = $this->user->getDesign();
|
||||||
|
|
||||||
|
if (!empty($design)) {
|
||||||
|
|
||||||
|
$original = clone($design);
|
||||||
|
|
||||||
|
try {
|
||||||
|
$this->setColors($design);
|
||||||
|
} catch (WebColorException $e) {
|
||||||
|
$this->clientError($e->getMessage());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$result = $design->update($original);
|
||||||
|
|
||||||
|
if ($result === false) {
|
||||||
|
common_log_db_error($design, 'UPDATE', __FILE__);
|
||||||
|
$this->clientError(_('Could not update your design.'));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
$this->user->query('BEGIN');
|
||||||
|
|
||||||
|
// save new design
|
||||||
|
$design = new Design();
|
||||||
|
|
||||||
|
try {
|
||||||
|
$this->setColors($design);
|
||||||
|
} catch (WebColorException $e) {
|
||||||
|
$this->clientError($e->getMessage());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$id = $design->insert();
|
||||||
|
|
||||||
|
if (empty($id)) {
|
||||||
|
common_log_db_error($id, 'INSERT', __FILE__);
|
||||||
|
$this->clientError(_('Unable to save your design settings.'));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$original = clone($this->user);
|
||||||
|
$this->user->design_id = $id;
|
||||||
|
$result = $this->user->update($original);
|
||||||
|
|
||||||
|
if (empty($result)) {
|
||||||
|
common_log_db_error($original, 'UPDATE', __FILE__);
|
||||||
|
$this->clientError(_('Unable to save your design settings.'));
|
||||||
|
$this->user->query('ROLLBACK');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->user->query('COMMIT');
|
||||||
|
}
|
||||||
|
|
||||||
|
$profile = $this->user->getProfile();
|
||||||
|
|
||||||
|
if (empty($profile)) {
|
||||||
|
$this->clientError(_('User has no profile.'));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$twitter_user = $this->twitterUserArray($profile, true);
|
||||||
|
|
||||||
|
if ($this->format == 'xml') {
|
||||||
|
$this->initDocument('xml');
|
||||||
|
$this->showTwitterXmlUser($twitter_user);
|
||||||
|
$this->endDocument('xml');
|
||||||
|
} elseif ($this->format == 'json') {
|
||||||
|
$this->initDocument('json');
|
||||||
|
$this->showJsonObjects($twitter_user);
|
||||||
|
$this->endDocument('json');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the user's design colors based on the request parameters
|
||||||
|
*
|
||||||
|
* @param Design $design the user's Design
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
|
||||||
|
function setColors($design)
|
||||||
|
{
|
||||||
|
$bgcolor = empty($this->profile_background_color) ?
|
||||||
|
null : new WebColor($this->profile_background_color);
|
||||||
|
$tcolor = empty($this->profile_text_color) ?
|
||||||
|
null : new WebColor($this->profile_text_color);
|
||||||
|
$sbcolor = empty($this->profile_sidebar_fill_color) ?
|
||||||
|
null : new WebColor($this->profile_sidebar_fill_color);
|
||||||
|
$lcolor = empty($this->profile_link_color) ?
|
||||||
|
null : new WebColor($this->profile_link_color);
|
||||||
|
$ccolor = empty($this->profile_content_color) ?
|
||||||
|
null : new WebColor($this->profile_content_color);
|
||||||
|
|
||||||
|
if (!empty($bgcolor)) {
|
||||||
|
$design->backgroundcolor = $bgcolor->intValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!empty($ccolor)) {
|
||||||
|
$design->contentcolor = $ccolor->intValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!empty($sbcolor)) {
|
||||||
|
$design->sidebarcolor = $sbcolor->intValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!empty($tcolor)) {
|
||||||
|
$design->textcolor = $tcolor->intValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!empty($lcolor)) {
|
||||||
|
$design->linkcolor = $lcolor->intValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
151
actions/apiaccountupdateprofileimage.php
Normal file
151
actions/apiaccountupdateprofileimage.php
Normal file
@ -0,0 +1,151 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* StatusNet, the distributed open-source microblogging tool
|
||||||
|
*
|
||||||
|
* Update the authenticating user's profile 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 Zach Copley <zach@status.net>
|
||||||
|
* @copyright 2009 StatusNet, Inc.
|
||||||
|
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||||
|
* @link http://status.net/
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (!defined('STATUSNET')) {
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
require_once INSTALLDIR . '/lib/apiauth.php';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates the authenticating user's profile image. Note that this API method
|
||||||
|
* expects raw multipart data, not a URL to an image.
|
||||||
|
*
|
||||||
|
* @category API
|
||||||
|
* @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 ApiAccountUpdateProfileImageAction extends ApiAuthAction
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Take arguments for running
|
||||||
|
*
|
||||||
|
* @param array $args $_REQUEST args
|
||||||
|
*
|
||||||
|
* @return boolean success flag
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
function prepare($args)
|
||||||
|
{
|
||||||
|
parent::prepare($args);
|
||||||
|
|
||||||
|
$this->user = $this->auth_user;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle the request
|
||||||
|
*
|
||||||
|
* Check whether the credentials are valid and output the result
|
||||||
|
*
|
||||||
|
* @param array $args $_REQUEST data (unused)
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
|
||||||
|
function handle($args)
|
||||||
|
{
|
||||||
|
parent::handle($args);
|
||||||
|
|
||||||
|
if ($_SERVER['REQUEST_METHOD'] != 'POST') {
|
||||||
|
$this->clientError(
|
||||||
|
_('This method requires a POST.'),
|
||||||
|
400, $this->format
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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.');
|
||||||
|
|
||||||
|
$this->clientError(sprintf($msg, $_SERVER['CONTENT_LENGTH']));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (empty($this->user)) {
|
||||||
|
$this->clientError(_('No such user.'), 404, $this->format);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
$imagefile = ImageFile::fromUpload('image');
|
||||||
|
} catch (Exception $e) {
|
||||||
|
$this->clientError($e->getMessage(), 400, $this->format);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$filename = Avatar::filename(
|
||||||
|
$user->id,
|
||||||
|
image_type_to_extension($imagefile->type),
|
||||||
|
null,
|
||||||
|
'tmp'.common_timestamp()
|
||||||
|
);
|
||||||
|
|
||||||
|
$filepath = Avatar::path($filename);
|
||||||
|
|
||||||
|
move_uploaded_file($imagefile->filepath, $filepath);
|
||||||
|
|
||||||
|
$profile = $this->user->getProfile();
|
||||||
|
|
||||||
|
if (empty($profile)) {
|
||||||
|
$this->clientError(_('User has no profile.'));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$profile->setOriginal($filename);
|
||||||
|
|
||||||
|
common_broadcast_profile($profile);
|
||||||
|
|
||||||
|
$twitter_user = $this->twitterUserArray($profile, true);
|
||||||
|
|
||||||
|
if ($this->format == 'xml') {
|
||||||
|
$this->initDocument('xml');
|
||||||
|
$this->showTwitterXmlUser($twitter_user);
|
||||||
|
$this->endDocument('xml');
|
||||||
|
} elseif ($this->format == 'json') {
|
||||||
|
$this->initDocument('json');
|
||||||
|
$this->showJsonObjects($twitter_user);
|
||||||
|
$this->endDocument('json');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
85
actions/apiaccountverifycredentials.php
Normal file
85
actions/apiaccountverifycredentials.php
Normal file
@ -0,0 +1,85 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* StatusNet, the distributed open-source microblogging tool
|
||||||
|
*
|
||||||
|
* Test if supplied user credentials are valid.
|
||||||
|
*
|
||||||
|
* 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>
|
||||||
|
* @author Robin Millette <robin@millette.info>
|
||||||
|
* @author Zach Copley <zach@status.net>
|
||||||
|
* @copyright 2009 StatusNet, Inc.
|
||||||
|
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||||
|
* @link http://status.net/
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (!defined('STATUSNET')) {
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
require_once INSTALLDIR . '/lib/apiauth.php';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check a user's credentials. Returns an HTTP 200 OK response code and a
|
||||||
|
* representation of the requesting user if authentication was successful;
|
||||||
|
* returns a 401 status code and an error message if not.
|
||||||
|
*
|
||||||
|
* @category API
|
||||||
|
* @package StatusNet
|
||||||
|
* @author Evan Prodromou <evan@status.net>
|
||||||
|
* @author Robin Millette <robin@millette.info>
|
||||||
|
* @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 ApiAccountVerifyCredentialsAction extends ApiAuthAction
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle the request
|
||||||
|
*
|
||||||
|
* Check whether the credentials are valid and output the result
|
||||||
|
*
|
||||||
|
* @param array $args $_REQUEST data (unused)
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
|
||||||
|
function handle($args)
|
||||||
|
{
|
||||||
|
parent::handle($args);
|
||||||
|
|
||||||
|
switch ($this->format) {
|
||||||
|
case 'xml':
|
||||||
|
case 'json':
|
||||||
|
$args['id'] = $this->auth_user->id;
|
||||||
|
$action_obj = new ApiUserShowAction();
|
||||||
|
if ($action_obj->prepare($args)) {
|
||||||
|
$action_obj->handle($args);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
header('Content-Type: text/html; charset=utf-8');
|
||||||
|
print 'Authorized';
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
114
actions/apiblockcreate.php
Normal file
114
actions/apiblockcreate.php
Normal file
@ -0,0 +1,114 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* StatusNet, the distributed open-source microblogging tool
|
||||||
|
*
|
||||||
|
* Block a user via the API
|
||||||
|
*
|
||||||
|
* PHP version 5
|
||||||
|
*
|
||||||
|
* LICENCE: This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* @category API
|
||||||
|
* @package StatusNet
|
||||||
|
* @author Evan Prodromou <evan@status.net>
|
||||||
|
* @author Zach Copley <zach@status.net>
|
||||||
|
* @copyright 2009 StatusNet, Inc.
|
||||||
|
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||||
|
* @link http://status.net/
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (!defined('STATUSNET')) {
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
require_once INSTALLDIR . '/lib/apiauth.php';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Blocks the user specified in the ID parameter as the authenticating user.
|
||||||
|
* Destroys a friendship to the blocked user if it exists. Returns the
|
||||||
|
* blocked user in the requested format when successful.
|
||||||
|
*
|
||||||
|
* @category API
|
||||||
|
* @package StatusNet
|
||||||
|
* @author Evan Prodromou <evan@status.net>
|
||||||
|
* @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 ApiBlockCreateAction extends ApiAuthAction
|
||||||
|
{
|
||||||
|
var $other = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Take arguments for running
|
||||||
|
*
|
||||||
|
* @param array $args $_REQUEST args
|
||||||
|
*
|
||||||
|
* @return boolean success flag
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
function prepare($args)
|
||||||
|
{
|
||||||
|
parent::prepare($args);
|
||||||
|
|
||||||
|
$this->user = $this->auth_user;
|
||||||
|
$this->other = $this->getTargetUser($this->arg('id'));
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle the request
|
||||||
|
*
|
||||||
|
* Save the new message
|
||||||
|
*
|
||||||
|
* @param array $args $_REQUEST data (unused)
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
|
||||||
|
function handle($args)
|
||||||
|
{
|
||||||
|
parent::handle($args);
|
||||||
|
|
||||||
|
if ($_SERVER['REQUEST_METHOD'] != 'POST') {
|
||||||
|
$this->clientError(
|
||||||
|
_('This method requires a POST.'),
|
||||||
|
400,
|
||||||
|
$this->format
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (empty($this->user) || empty($this->other)) {
|
||||||
|
$this->clientError(_('No such user.'), 404, $this->format);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($this->user->hasBlocked($this->other)
|
||||||
|
|| $this->user->block($this->other)
|
||||||
|
) {
|
||||||
|
$this->initDocument($this->format);
|
||||||
|
$this->showProfile($this->other, $this->format);
|
||||||
|
$this->endDocument($this->format);
|
||||||
|
} else {
|
||||||
|
$this->serverError(_('Block user failed.'), 500, $this->format);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
113
actions/apiblockdestroy.php
Normal file
113
actions/apiblockdestroy.php
Normal file
@ -0,0 +1,113 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* StatusNet, the distributed open-source microblogging tool
|
||||||
|
*
|
||||||
|
* Un-block a user via the API
|
||||||
|
*
|
||||||
|
* PHP version 5
|
||||||
|
*
|
||||||
|
* LICENCE: This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* @category API
|
||||||
|
* @package StatusNet
|
||||||
|
* @author Evan Prodromou <evan@status.net>
|
||||||
|
* @author Zach Copley <zach@status.net>
|
||||||
|
* @copyright 2009 StatusNet, Inc.
|
||||||
|
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||||
|
* @link http://status.net/
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (!defined('STATUSNET')) {
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
require_once INSTALLDIR . '/lib/apiauth.php';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Un-blocks the user specified in the ID parameter for the authenticating user.
|
||||||
|
* Returns the un-blocked user in the requested format when successful.
|
||||||
|
*
|
||||||
|
* @category API
|
||||||
|
* @package StatusNet
|
||||||
|
* @author Evan Prodromou <evan@status.net>
|
||||||
|
* @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 ApiBlockDestroyAction extends ApiAuthAction
|
||||||
|
{
|
||||||
|
var $other = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Take arguments for running
|
||||||
|
*
|
||||||
|
* @param array $args $_REQUEST args
|
||||||
|
*
|
||||||
|
* @return boolean success flag
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
function prepare($args)
|
||||||
|
{
|
||||||
|
parent::prepare($args);
|
||||||
|
|
||||||
|
$this->user = $this->auth_user;
|
||||||
|
$this->other = $this->getTargetUser($this->arg('id'));
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle the request
|
||||||
|
*
|
||||||
|
* Save the new message
|
||||||
|
*
|
||||||
|
* @param array $args $_REQUEST data (unused)
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
|
||||||
|
function handle($args)
|
||||||
|
{
|
||||||
|
parent::handle($args);
|
||||||
|
|
||||||
|
if ($_SERVER['REQUEST_METHOD'] != 'POST') {
|
||||||
|
$this->clientError(
|
||||||
|
_('This method requires a POST.'),
|
||||||
|
400,
|
||||||
|
$this->format
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (empty($this->user) || empty($this->other)) {
|
||||||
|
$this->clientError(_('No such user.'), 404, $this->format);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$this->user->hasBlocked($this->other)
|
||||||
|
|| $this->user->unblock($this->other)
|
||||||
|
) {
|
||||||
|
$this->initDocument($this->format);
|
||||||
|
$this->showProfile($this->other, $this->format);
|
||||||
|
$this->endDocument($this->format);
|
||||||
|
} else {
|
||||||
|
$this->serverError(_('Unblock user failed.'));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
375
actions/apidirectmessage.php
Normal file
375
actions/apidirectmessage.php
Normal file
@ -0,0 +1,375 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* StatusNet, the distributed open-source microblogging tool
|
||||||
|
*
|
||||||
|
* Show a the direct messages from or to 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 Adrian Lang <mail@adrianlang.de>
|
||||||
|
* @author Evan Prodromou <evan@status.net>
|
||||||
|
* @author Robin Millette <robin@millette.info>
|
||||||
|
* @author Zach Copley <zach@status.net>
|
||||||
|
* @copyright 2009 StatusNet, Inc.
|
||||||
|
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||||
|
* @link http://status.net/
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (!defined('STATUSNET')) {
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
require_once INSTALLDIR . '/lib/apiauth.php';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Show a list of direct messages from or to the authenticating user
|
||||||
|
*
|
||||||
|
* @category API
|
||||||
|
* @package StatusNet
|
||||||
|
* @author Adrian Lang <mail@adrianlang.de>
|
||||||
|
* @author Evan Prodromou <evan@status.net>
|
||||||
|
* @author Robin Millette <robin@millette.info>
|
||||||
|
* @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 ApiDirectMessageAction extends ApiAuthAction
|
||||||
|
{
|
||||||
|
var $messages = null;
|
||||||
|
var $title = null;
|
||||||
|
var $subtitle = null;
|
||||||
|
var $link = null;
|
||||||
|
var $selfuri_base = null;
|
||||||
|
var $id = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Take arguments for running
|
||||||
|
*
|
||||||
|
* @param array $args $_REQUEST args
|
||||||
|
*
|
||||||
|
* @return boolean success flag
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
function prepare($args)
|
||||||
|
{
|
||||||
|
parent::prepare($args);
|
||||||
|
|
||||||
|
$this->user = $this->auth_user;
|
||||||
|
|
||||||
|
if (empty($this->user)) {
|
||||||
|
$this->clientError(_('No such user.'), 404, $this->format);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$server = common_root_url();
|
||||||
|
$taguribase = common_config('integration', 'taguri');
|
||||||
|
|
||||||
|
if ($this->arg('sent')) {
|
||||||
|
|
||||||
|
// Action was called by /api/direct_messages/sent.format
|
||||||
|
|
||||||
|
$this->title = sprintf(
|
||||||
|
_("Direct messages from %s"),
|
||||||
|
$this->user->nickname
|
||||||
|
);
|
||||||
|
$this->subtitle = sprintf(
|
||||||
|
_("All the direct messages sent from %s"),
|
||||||
|
$this->user->nickname
|
||||||
|
);
|
||||||
|
$this->link = $server . $this->user->nickname . '/outbox';
|
||||||
|
$this->selfuri_base = common_root_url() . 'api/direct_messages/sent';
|
||||||
|
$this->id = "tag:$taguribase:SentDirectMessages:" . $this->user->id;
|
||||||
|
} else {
|
||||||
|
$this->title = sprintf(
|
||||||
|
_("Direct messages to %s"),
|
||||||
|
$this->user->nickname
|
||||||
|
);
|
||||||
|
$this->subtitle = sprintf(
|
||||||
|
_("All the direct messages sent to %s"),
|
||||||
|
$this->user->nickname
|
||||||
|
);
|
||||||
|
$this->link = $server . $this->user->nickname . '/inbox';
|
||||||
|
$this->selfuri_base = common_root_url() . 'api/direct_messages';
|
||||||
|
$this->id = "tag:$taguribase:DirectMessages:" . $this->user->id;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->messages = $this->getMessages();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle the request
|
||||||
|
*
|
||||||
|
* Show the messages
|
||||||
|
*
|
||||||
|
* @param array $args $_REQUEST data (unused)
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
|
||||||
|
function handle($args)
|
||||||
|
{
|
||||||
|
parent::handle($args);
|
||||||
|
$this->showMessages();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Show the messages
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
|
||||||
|
function showMessages()
|
||||||
|
{
|
||||||
|
switch($this->format) {
|
||||||
|
case 'xml':
|
||||||
|
$this->showXmlDirectMessages();
|
||||||
|
break;
|
||||||
|
case 'rss':
|
||||||
|
$this->showRssDirectMessages();
|
||||||
|
break;
|
||||||
|
case 'atom':
|
||||||
|
$this->showAtomDirectMessages();
|
||||||
|
break;
|
||||||
|
case 'json':
|
||||||
|
$this->showJsonDirectMessages();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
$this->clientError(_('API method not found!'), $code = 404);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get notices
|
||||||
|
*
|
||||||
|
* @return array notices
|
||||||
|
*/
|
||||||
|
|
||||||
|
function getMessages()
|
||||||
|
{
|
||||||
|
$message = new Message();
|
||||||
|
|
||||||
|
if ($this->arg('sent')) {
|
||||||
|
$message->from_profile = $this->user->id;
|
||||||
|
} else {
|
||||||
|
$message->to_profile = $this->user->id;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!empty($this->max_id)) {
|
||||||
|
$message->whereAdd('id <= ' . $this->max_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!empty($this->since_id)) {
|
||||||
|
$message->whereAdd('id > ' . $this->since_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!empty($since)) {
|
||||||
|
$d = date('Y-m-d H:i:s', $this->since);
|
||||||
|
$message->whereAdd("created > '$d'");
|
||||||
|
}
|
||||||
|
|
||||||
|
$message->orderBy('created DESC, id DESC');
|
||||||
|
$message->limit((($this->page - 1) * $this->count), $this->count);
|
||||||
|
$message->find();
|
||||||
|
|
||||||
|
$messages = array();
|
||||||
|
|
||||||
|
while ($message->fetch()) {
|
||||||
|
$messages[] = clone($message);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $messages;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Is this action read only?
|
||||||
|
*
|
||||||
|
* @param array $args other arguments
|
||||||
|
*
|
||||||
|
* @return boolean true
|
||||||
|
*/
|
||||||
|
|
||||||
|
function isReadOnly($args)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* When was this notice last modified?
|
||||||
|
*
|
||||||
|
* @return string datestamp of the latest notice in the stream
|
||||||
|
*/
|
||||||
|
|
||||||
|
function lastModified()
|
||||||
|
{
|
||||||
|
if (!empty($this->messages)) {
|
||||||
|
return strtotime($this->messages[0]->created);
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Shows a list of direct messages as Twitter-style XML array
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
|
||||||
|
function showXmlDirectMessages()
|
||||||
|
{
|
||||||
|
$this->initDocument('xml');
|
||||||
|
$this->elementStart('direct-messages', array('type' => 'array'));
|
||||||
|
|
||||||
|
foreach ($this->messages as $m) {
|
||||||
|
$dm_array = $this->directMessageArray($m);
|
||||||
|
$this->showXmlDirectMessage($dm_array);
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->elementEnd('direct-messages');
|
||||||
|
$this->endDocument('xml');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Shows a list of direct messages as a JSON encoded array
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
|
||||||
|
function showJsonDirectMessages()
|
||||||
|
{
|
||||||
|
$this->initDocument('json');
|
||||||
|
|
||||||
|
$dmsgs = array();
|
||||||
|
|
||||||
|
foreach ($this->messages as $m) {
|
||||||
|
$dm_array = $this->directMessageArray($m);
|
||||||
|
array_push($dmsgs, $dm_array);
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->showJsonObjects($dmsgs);
|
||||||
|
$this->endDocument('json');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Shows a list of direct messages as RSS items
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
|
||||||
|
function showRssDirectMessages()
|
||||||
|
{
|
||||||
|
$this->initDocument('rss');
|
||||||
|
|
||||||
|
$this->element('title', null, $this->title);
|
||||||
|
|
||||||
|
$this->element('link', null, $this->link);
|
||||||
|
$this->element('description', null, $this->subtitle);
|
||||||
|
$this->element('language', null, 'en-us');
|
||||||
|
|
||||||
|
$this->element(
|
||||||
|
'atom:link',
|
||||||
|
array(
|
||||||
|
'type' => 'application/rss+xml',
|
||||||
|
'href' => $this->selfuri_base . '.rss',
|
||||||
|
'rel' => self
|
||||||
|
),
|
||||||
|
null
|
||||||
|
);
|
||||||
|
$this->element('ttl', null, '40');
|
||||||
|
|
||||||
|
foreach ($this->messages as $m) {
|
||||||
|
$entry = $this->rssDirectMessageArray($m);
|
||||||
|
$this->showTwitterRssItem($entry);
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->endTwitterRss();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Shows a list of direct messages as Atom entries
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
|
||||||
|
function showAtomDirectMessages()
|
||||||
|
{
|
||||||
|
$this->initDocument('atom');
|
||||||
|
|
||||||
|
$this->element('title', null, $this->title);
|
||||||
|
$this->element('id', null, $this->id);
|
||||||
|
|
||||||
|
$selfuri = common_root_url() . 'api/direct_messages.atom';
|
||||||
|
|
||||||
|
$this->element(
|
||||||
|
'link', array(
|
||||||
|
'href' => $this->link,
|
||||||
|
'rel' => 'alternate',
|
||||||
|
'type' => 'text/html'),
|
||||||
|
null
|
||||||
|
);
|
||||||
|
$this->element(
|
||||||
|
'link', array(
|
||||||
|
'href' => $this->selfuri_base . '.atom', 'rel' => 'self',
|
||||||
|
'type' => 'application/atom+xml'),
|
||||||
|
null
|
||||||
|
);
|
||||||
|
$this->element('updated', null, common_date_iso8601('now'));
|
||||||
|
$this->element('subtitle', null, $this->subtitle);
|
||||||
|
|
||||||
|
foreach ($this->messages as $m) {
|
||||||
|
$entry = $this->rssDirectMessageArray($m);
|
||||||
|
$this->showTwitterAtomEntry($entry);
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->endDocument('atom');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An entity tag for this notice
|
||||||
|
*
|
||||||
|
* Returns an Etag based on the action name, language, and
|
||||||
|
* timestamps of the notice
|
||||||
|
*
|
||||||
|
* @return string etag
|
||||||
|
*/
|
||||||
|
|
||||||
|
function etag()
|
||||||
|
{
|
||||||
|
if (!empty($this->messages)) {
|
||||||
|
|
||||||
|
$last = count($this->messages) - 1;
|
||||||
|
|
||||||
|
return '"' . implode(
|
||||||
|
':',
|
||||||
|
array($this->arg('action'),
|
||||||
|
common_language(),
|
||||||
|
strtotime($this->messages[0]->created),
|
||||||
|
strtotime($this->messages[$last]->created)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
. '"';
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
188
actions/apidirectmessagenew.php
Normal file
188
actions/apidirectmessagenew.php
Normal file
@ -0,0 +1,188 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* StatusNet, the distributed open-source microblogging tool
|
||||||
|
*
|
||||||
|
* Send a direct message via the API
|
||||||
|
*
|
||||||
|
* PHP version 5
|
||||||
|
*
|
||||||
|
* LICENCE: This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* @category API
|
||||||
|
* @package StatusNet
|
||||||
|
* @author Adrian Lang <mail@adrianlang.de>
|
||||||
|
* @author Evan Prodromou <evan@status.net>
|
||||||
|
* @author Robin Millette <robin@millette.info>
|
||||||
|
* @author Zach Copley <zach@status.net>
|
||||||
|
* @copyright 2009 StatusNet, Inc.
|
||||||
|
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||||
|
* @link http://status.net/
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (!defined('STATUSNET')) {
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
require_once INSTALLDIR . '/lib/apiauth.php';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new direct message from the authenticating user to
|
||||||
|
* the user specified by id.
|
||||||
|
*
|
||||||
|
* @category API
|
||||||
|
* @package StatusNet
|
||||||
|
* @author Adrian Lang <mail@adrianlang.de>
|
||||||
|
* @author Evan Prodromou <evan@status.net>
|
||||||
|
* @author Robin Millette <robin@millette.info>
|
||||||
|
* @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 ApiDirectMessageNewAction extends ApiAuthAction
|
||||||
|
{
|
||||||
|
var $source = null;
|
||||||
|
var $other = null;
|
||||||
|
var $content = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Take arguments for running
|
||||||
|
*
|
||||||
|
* @param array $args $_REQUEST args
|
||||||
|
*
|
||||||
|
* @return boolean success flag
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
function prepare($args)
|
||||||
|
{
|
||||||
|
parent::prepare($args);
|
||||||
|
|
||||||
|
$this->user = $this->auth_user;
|
||||||
|
|
||||||
|
if (empty($this->user)) {
|
||||||
|
$this->clientError(_('No such user.'), 404, $this->format);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->source = $this->trimmed('source'); // Not supported by Twitter.
|
||||||
|
|
||||||
|
$reserved_sources = array('web', 'omb', 'mail', 'xmpp', 'api');
|
||||||
|
if (empty($thtis->source) || in_array($this->source, $reserved_sources)) {
|
||||||
|
$source = 'api';
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->content = $this->trimmed('text');
|
||||||
|
|
||||||
|
$this->user = $this->auth_user;
|
||||||
|
|
||||||
|
$user_param = $this->trimmed('user');
|
||||||
|
$user_id = $this->arg('user_id');
|
||||||
|
$screen_name = $this->trimmed('screen_name');
|
||||||
|
|
||||||
|
if (isset($user_param) || isset($user_id) || isset($screen_name)) {
|
||||||
|
$this->other = $this->getTargetUser($user_param);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle the request
|
||||||
|
*
|
||||||
|
* Save the new message
|
||||||
|
*
|
||||||
|
* @param array $args $_REQUEST data (unused)
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
|
||||||
|
function handle($args)
|
||||||
|
{
|
||||||
|
parent::handle($args);
|
||||||
|
|
||||||
|
if ($_SERVER['REQUEST_METHOD'] != 'POST') {
|
||||||
|
$this->clientError(
|
||||||
|
_('This method requires a POST.'),
|
||||||
|
400,
|
||||||
|
$this->format
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (empty($this->content)) {
|
||||||
|
$this->clientError(
|
||||||
|
_('No message text!'),
|
||||||
|
406,
|
||||||
|
$this->format
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
$content_shortened = common_shorten_links($this->content);
|
||||||
|
if (Message::contentTooLong($content_shortened)) {
|
||||||
|
$this->clientError(
|
||||||
|
sprintf(
|
||||||
|
_('That\'s too long. Max message size is %d chars.'),
|
||||||
|
Message::maxContent()
|
||||||
|
),
|
||||||
|
406,
|
||||||
|
$this->format
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (empty($this->other)) {
|
||||||
|
$this->clientError(_('Recipient user not found.'), 403, $this->format);
|
||||||
|
return;
|
||||||
|
} else if (!$this->user->mutuallySubscribed($this->other)) {
|
||||||
|
$this->clientError(
|
||||||
|
_('Can\'t send direct messages to users who aren\'t your friend.'),
|
||||||
|
403,
|
||||||
|
$this->format
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
} else if ($this->user->id == $this->other->id) {
|
||||||
|
|
||||||
|
// 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);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$message = Message::saveNew(
|
||||||
|
$this->user->id,
|
||||||
|
$this->other->id,
|
||||||
|
html_entity_decode($this->content, ENT_NOQUOTES, 'UTF-8'),
|
||||||
|
$this->source
|
||||||
|
);
|
||||||
|
|
||||||
|
if (is_string($message)) {
|
||||||
|
$this->serverError($message);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
mail_notify_message($message, $this->user, $this->other);
|
||||||
|
|
||||||
|
if ($this->format == 'xml') {
|
||||||
|
$this->showSingleXmlDirectMessage($message);
|
||||||
|
} elseif ($this->format == 'json') {
|
||||||
|
$this->showSingleJsondirectMessage($message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
168
actions/apifavoritecreate.php
Normal file
168
actions/apifavoritecreate.php
Normal file
@ -0,0 +1,168 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* StatusNet, the distributed open-source microblogging tool
|
||||||
|
*
|
||||||
|
* Add a notice to a user's list of favorite notices via the API
|
||||||
|
*
|
||||||
|
* PHP version 5
|
||||||
|
*
|
||||||
|
* LICENCE: This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* @category API
|
||||||
|
* @package StatusNet
|
||||||
|
* @author Craig Andrews <candrews@integralblue.com>
|
||||||
|
* @author Evan Prodromou <evan@status.net>
|
||||||
|
* @author Zach Copley <zach@status.net>
|
||||||
|
* @copyright 2009 StatusNet, Inc.
|
||||||
|
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||||
|
* @link http://status.net/
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (!defined('STATUSNET')) {
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
require_once INSTALLDIR . '/lib/apiauth.php';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Favorites the status specified in the ID parameter as the authenticating user.
|
||||||
|
* Returns the favorite status when successful.
|
||||||
|
*
|
||||||
|
* @category API
|
||||||
|
* @package StatusNet
|
||||||
|
* @author Craig Andrews <candrews@integralblue.com>
|
||||||
|
* @author Evan Prodromou <evan@status.net>
|
||||||
|
* @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 ApiFavoriteCreateAction extends ApiAuthAction
|
||||||
|
{
|
||||||
|
var $notice = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Take arguments for running
|
||||||
|
*
|
||||||
|
* @param array $args $_REQUEST args
|
||||||
|
*
|
||||||
|
* @return boolean success flag
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
function prepare($args)
|
||||||
|
{
|
||||||
|
parent::prepare($args);
|
||||||
|
|
||||||
|
$this->user = $this->auth_user;
|
||||||
|
$this->notice = Notice::staticGet($this->arg('id'));
|
||||||
|
|
||||||
|
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 ($_SERVER['REQUEST_METHOD'] != 'POST') {
|
||||||
|
$this->clientError(
|
||||||
|
_('This method requires a POST.'),
|
||||||
|
400,
|
||||||
|
$this->format
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!in_array($this->format, array('xml', 'json'))) {
|
||||||
|
$this->clientError(
|
||||||
|
_('API method not found!'),
|
||||||
|
404,
|
||||||
|
$this->format
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (empty($this->notice)) {
|
||||||
|
$this->clientError(
|
||||||
|
_('No status found with that ID.'),
|
||||||
|
404,
|
||||||
|
$this->format
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Note: Twitter lets you fave things repeatedly via API.
|
||||||
|
|
||||||
|
if ($this->user->hasFave($this->notice)) {
|
||||||
|
$this->clientError(
|
||||||
|
_('This status is already a favorite!'),
|
||||||
|
403,
|
||||||
|
$this->format
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$fave = Fave::addNew($this->user, $this->notice);
|
||||||
|
|
||||||
|
if (empty($fave)) {
|
||||||
|
$this->clientError(
|
||||||
|
_('Could not create favorite.'),
|
||||||
|
403,
|
||||||
|
$this->format
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->notify($fave, $this->notice, $this->user);
|
||||||
|
$this->user->blowFavesCache();
|
||||||
|
|
||||||
|
if ($this->format == 'xml') {
|
||||||
|
$this->showSingleXmlStatus($this->notice);
|
||||||
|
} elseif ($this->format == 'json') {
|
||||||
|
$this->show_single_json_status($this->notice);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
150
actions/apifavoritedestroy.php
Normal file
150
actions/apifavoritedestroy.php
Normal file
@ -0,0 +1,150 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* StatusNet, the distributed open-source microblogging tool
|
||||||
|
*
|
||||||
|
* Remote a notice from a user's list of favorite notices via the API
|
||||||
|
*
|
||||||
|
* PHP version 5
|
||||||
|
*
|
||||||
|
* LICENCE: This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* @category API
|
||||||
|
* @package StatusNet
|
||||||
|
* @author Craig Andrews <candrews@integralblue.com>
|
||||||
|
* @author Evan Prodromou <evan@status.net>
|
||||||
|
* @author Zach Copley <zach@status.net>
|
||||||
|
* @copyright 2009 StatusNet, Inc.
|
||||||
|
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||||
|
* @link http://status.net/
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (!defined('STATUSNET')) {
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
require_once INSTALLDIR . '/lib/apiauth.php';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Un-favorites the status specified in the ID parameter as the authenticating user.
|
||||||
|
* Returns the un-favorited status in the requested format when successful.
|
||||||
|
*
|
||||||
|
* @category API
|
||||||
|
* @package StatusNet
|
||||||
|
* @author Craig Andrews <candrews@integralblue.com>
|
||||||
|
* @author Evan Prodromou <evan@status.net>
|
||||||
|
* @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 ApiFavoriteDestroyAction extends ApiAuthAction
|
||||||
|
{
|
||||||
|
|
||||||
|
var $notice = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Take arguments for running
|
||||||
|
*
|
||||||
|
* @param array $args $_REQUEST args
|
||||||
|
*
|
||||||
|
* @return boolean success flag
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
function prepare($args)
|
||||||
|
{
|
||||||
|
parent::prepare($args);
|
||||||
|
|
||||||
|
$this->user = $this->auth_user;
|
||||||
|
$this->notice = Notice::staticGet($this->arg('id'));
|
||||||
|
|
||||||
|
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 ($_SERVER['REQUEST_METHOD'] != 'POST') {
|
||||||
|
$this->clientError(
|
||||||
|
_('This method requires a POST.'),
|
||||||
|
400,
|
||||||
|
$this->format
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!in_array($this->format, array('xml', 'json'))) {
|
||||||
|
$this->clientError(
|
||||||
|
_('API method not found!'),
|
||||||
|
404,
|
||||||
|
$this->format
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (empty($this->notice)) {
|
||||||
|
$this->clientError(
|
||||||
|
_('No status found with that ID.'),
|
||||||
|
404,
|
||||||
|
$this->format
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$fave = new Fave();
|
||||||
|
$fave->user_id = $this->user->id;
|
||||||
|
$fave->notice_id = $this->notice->id;
|
||||||
|
|
||||||
|
if (!$fave->find(true)) {
|
||||||
|
$this->clientError(
|
||||||
|
_('That status is not a favorite!'),
|
||||||
|
403,
|
||||||
|
$this->favorite
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$result = $fave->delete();
|
||||||
|
|
||||||
|
if (!$result) {
|
||||||
|
common_log_db_error($fave, 'DELETE', __FILE__);
|
||||||
|
$this->clientError(
|
||||||
|
_('Could not delete favorite.'),
|
||||||
|
404,
|
||||||
|
$this->format
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->user->blowFavesCache();
|
||||||
|
|
||||||
|
if ($this->format == 'xml') {
|
||||||
|
$this->showSingleXmlStatus($this->notice);
|
||||||
|
} elseif ($this->format == 'json') {
|
||||||
|
$this->show_single_json_status($this->notice);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
137
actions/apifriendshipscreate.php
Normal file
137
actions/apifriendshipscreate.php
Normal file
@ -0,0 +1,137 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* StatusNet, the distributed open-source microblogging tool
|
||||||
|
*
|
||||||
|
* Subscribe to a user via the API
|
||||||
|
*
|
||||||
|
* PHP version 5
|
||||||
|
*
|
||||||
|
* LICENCE: This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* @category API
|
||||||
|
* @package StatusNet
|
||||||
|
* @author Dan Moore <dan@moore.cx>
|
||||||
|
* @author Evan Prodromou <evan@status.net>
|
||||||
|
* @author Zach Copley <zach@status.net>
|
||||||
|
* @copyright 2009 StatusNet, Inc.
|
||||||
|
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||||
|
* @link http://status.net/
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (!defined('STATUSNET')) {
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
require_once INSTALLDIR . '/lib/apiauth.php';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Allows the authenticating users to follow (subscribe) the user specified in
|
||||||
|
* the ID parameter. Returns the befriended user in the requested format when
|
||||||
|
* successful. Returns a string describing the failure condition when unsuccessful.
|
||||||
|
*
|
||||||
|
* @category API
|
||||||
|
* @package StatusNet
|
||||||
|
* @author Dan Moore <dan@moore.cx>
|
||||||
|
* @author Evan Prodromou <evan@status.net>
|
||||||
|
* @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 ApiFriendshipsCreateAction extends ApiAuthAction
|
||||||
|
{
|
||||||
|
var $other = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Take arguments for running
|
||||||
|
*
|
||||||
|
* @param array $args $_REQUEST args
|
||||||
|
*
|
||||||
|
* @return boolean success flag
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
function prepare($args)
|
||||||
|
{
|
||||||
|
parent::prepare($args);
|
||||||
|
|
||||||
|
$this->user = $this->auth_user;
|
||||||
|
$this->other = $this->getTargetUser($id);
|
||||||
|
|
||||||
|
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 ($_SERVER['REQUEST_METHOD'] != 'POST') {
|
||||||
|
$this->clientError(
|
||||||
|
_('This method requires a POST.'),
|
||||||
|
400,
|
||||||
|
$this->format
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!in_array($this->format, array('xml', 'json'))) {
|
||||||
|
$this->clientError(
|
||||||
|
_('API method not found!'),
|
||||||
|
404,
|
||||||
|
$this->format
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (empty($this->other)) {
|
||||||
|
$this->clientError(
|
||||||
|
_('Could not follow user: User not found.'),
|
||||||
|
403,
|
||||||
|
$this->format
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($this->user->isSubscribed($this->other)) {
|
||||||
|
$errmsg = sprintf(
|
||||||
|
_('Could not follow user: %s is already on your list.'),
|
||||||
|
$this->other->nickname
|
||||||
|
);
|
||||||
|
$this->clientError($errmsg, 403, $this->format);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$result = subs_subscribe_to($this->user, $this->other);
|
||||||
|
|
||||||
|
if (is_string($result)) {
|
||||||
|
$this->clientError($result, 403, $this->format);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->initDocument($this->format);
|
||||||
|
$this->showProfile($this->other, $this->format);
|
||||||
|
$this->endDocument($this->format);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
139
actions/apifriendshipsdestroy.php
Normal file
139
actions/apifriendshipsdestroy.php
Normal file
@ -0,0 +1,139 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* StatusNet, the distributed open-source microblogging tool
|
||||||
|
*
|
||||||
|
* Unsubscribe to a user via API
|
||||||
|
*
|
||||||
|
* PHP version 5
|
||||||
|
*
|
||||||
|
* LICENCE: This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* @category API
|
||||||
|
* @package StatusNet
|
||||||
|
* @author Dan Moore <dan@moore.cx>
|
||||||
|
* @author Evan Prodromou <evan@status.net>
|
||||||
|
* @author Zach Copley <zach@status.net>
|
||||||
|
* @copyright 2009 StatusNet, Inc.
|
||||||
|
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||||
|
* @link http://status.net/
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (!defined('STATUSNET')) {
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
require_once INSTALLDIR . '/lib/apiauth.php';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Allows the authenticating users to unfollow (unsubscribe) the user specified in
|
||||||
|
* the ID parameter. Returns the unfollowed user in the requested format when
|
||||||
|
* successful. Returns a string describing the failure condition when unsuccessful.
|
||||||
|
*
|
||||||
|
* @category API
|
||||||
|
* @package StatusNet
|
||||||
|
* @author Dan Moore <dan@moore.cx>
|
||||||
|
* @author Evan Prodromou <evan@status.net>
|
||||||
|
* @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 ApiFriendshipsDestroyAction extends ApiAuthAction
|
||||||
|
{
|
||||||
|
var $other = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Take arguments for running
|
||||||
|
*
|
||||||
|
* @param array $args $_REQUEST args
|
||||||
|
*
|
||||||
|
* @return boolean success flag
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
function prepare($args)
|
||||||
|
{
|
||||||
|
parent::prepare($args);
|
||||||
|
|
||||||
|
$this->user = $this->auth_user;
|
||||||
|
$this->other = $this->getTargetUser($id);
|
||||||
|
|
||||||
|
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 ($_SERVER['REQUEST_METHOD'] != 'POST') {
|
||||||
|
$this->clientError(
|
||||||
|
_('This method requires a POST.'),
|
||||||
|
400,
|
||||||
|
$this->format
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!in_array($this->format, array('xml', 'json'))) {
|
||||||
|
$this->clientError(
|
||||||
|
_('API method not found!'),
|
||||||
|
404,
|
||||||
|
$this->format
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (empty($this->other)) {
|
||||||
|
$this->clientError(
|
||||||
|
_('Could not unfollow user: User not found.'),
|
||||||
|
403,
|
||||||
|
$this->format
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Don't allow unsubscribing from yourself!
|
||||||
|
|
||||||
|
if ($this->user->id == $this->other->id) {
|
||||||
|
$this->clientError(
|
||||||
|
_("You cannot unfollow yourself!"),
|
||||||
|
403,
|
||||||
|
$this->format
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$result = subs_unsubscribe_user($this->user, $this->other->nickname);
|
||||||
|
|
||||||
|
if (is_string($result)) {
|
||||||
|
$this->clientError($result, 403, $this->format);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->initDocument($this->format);
|
||||||
|
$this->showProfile($this->other, $this->format);
|
||||||
|
$this->endDocument($this->format);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
119
actions/apifriendshipsexists.php
Normal file
119
actions/apifriendshipsexists.php
Normal file
@ -0,0 +1,119 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* StatusNet, the distributed open-source microblogging tool
|
||||||
|
*
|
||||||
|
* Show whether there is a friendship between two users
|
||||||
|
*
|
||||||
|
* 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 Dan Moore <dan@moore.cx>
|
||||||
|
* @author Evan Prodromou <evan@status.net>
|
||||||
|
* @author Zach Copley <zach@status.net>
|
||||||
|
* @copyright 2009 StatusNet, Inc.
|
||||||
|
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||||
|
* @link http://status.net/
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (!defined('STATUSNET')) {
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
require_once INSTALLDIR . '/lib/apiprivateauth.php';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests for the existence of friendship between two users. Will return true if
|
||||||
|
* user_a follows user_b, otherwise will return false.
|
||||||
|
*
|
||||||
|
* @category API
|
||||||
|
* @package StatusNet
|
||||||
|
* @author Dan Moore <dan@moore.cx>
|
||||||
|
* @author Evan Prodromou <evan@status.net>
|
||||||
|
* @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 ApiFriendshipsExistsAction extends ApiPrivateAuthAction
|
||||||
|
{
|
||||||
|
var $user_a = null;
|
||||||
|
var $user_b = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Take arguments for running
|
||||||
|
*
|
||||||
|
* @param array $args $_REQUEST args
|
||||||
|
*
|
||||||
|
* @return boolean success flag
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
function prepare($args)
|
||||||
|
{
|
||||||
|
parent::prepare($args);
|
||||||
|
|
||||||
|
$user_a_id = $this->trimmed('user_a');
|
||||||
|
$user_b_id = $this->trimmed('user_b');
|
||||||
|
|
||||||
|
$this->user_a = $this->getTargetUser($user_a_id);
|
||||||
|
$this->user_b = $this->getTargetUser($user_b_id);
|
||||||
|
|
||||||
|
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_a) || empty($this->user_b)) {
|
||||||
|
$this->clientError(
|
||||||
|
_('Two user ids or screen_names must be supplied.'),
|
||||||
|
400,
|
||||||
|
$this->format
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$result = $this->user_a->isSubscribed($this->user_b);
|
||||||
|
|
||||||
|
switch ($this->format) {
|
||||||
|
case 'xml':
|
||||||
|
$this->initDocument('xml');
|
||||||
|
$this->element('friends', null, $result);
|
||||||
|
$this->endDocument('xml');
|
||||||
|
break;
|
||||||
|
case 'json':
|
||||||
|
$this->initDocument('json');
|
||||||
|
print json_encode($result);
|
||||||
|
$this->endDocument('json');
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
168
actions/apifriendshipsshow.php
Normal file
168
actions/apifriendshipsshow.php
Normal file
@ -0,0 +1,168 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* StatusNet, the distributed open-source microblogging tool
|
||||||
|
*
|
||||||
|
* Show information about the relationship between two users
|
||||||
|
*
|
||||||
|
* 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 Dan Moore <dan@moore.cx>
|
||||||
|
* @author Evan Prodromou <evan@status.net>
|
||||||
|
* @author Zach Copley <zach@status.net>
|
||||||
|
* @copyright 2009 StatusNet, Inc.
|
||||||
|
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||||
|
* @link http://status.net/
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (!defined('STATUSNET')) {
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
require_once INSTALLDIR . '/lib/apibareauth.php';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Outputs detailed information about the relationship between two users
|
||||||
|
*
|
||||||
|
* @category API
|
||||||
|
* @package StatusNet
|
||||||
|
* @author Dan Moore <dan@moore.cx>
|
||||||
|
* @author Evan Prodromou <evan@status.net>
|
||||||
|
* @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 ApiFriendshipsShowAction extends ApiBareAuthAction
|
||||||
|
{
|
||||||
|
var $source = null;
|
||||||
|
var $target = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Take arguments for running
|
||||||
|
*
|
||||||
|
* @param array $args $_REQUEST args
|
||||||
|
*
|
||||||
|
* @return boolean success flag
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
function prepare($args)
|
||||||
|
{
|
||||||
|
parent::prepare($args);
|
||||||
|
|
||||||
|
$source_id = (int)$this->trimmed('source_id');
|
||||||
|
$source_screen_name = $this->trimmed('source_screen_name');
|
||||||
|
$target_id = (int)$this->trimmed('target_id');
|
||||||
|
$target_screen_name = $this->trimmed('target_screen_name');
|
||||||
|
|
||||||
|
if (!empty($source_id)) {
|
||||||
|
$this->source = User::staticGet($source_id);
|
||||||
|
} elseif (!empty($source_screen_name)) {
|
||||||
|
$this->source = User::staticGet('nickname', $source_screen_name);
|
||||||
|
} else {
|
||||||
|
$this->source = $this->auth_user;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!empty($target_id)) {
|
||||||
|
$this->target = User::staticGet($target_id);
|
||||||
|
} elseif (!empty($target_screen_name)) {
|
||||||
|
$this->target = User::staticGet('nickname', $target_screen_name);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determines whether this API resource requires auth. Overloaded to look
|
||||||
|
* return true in case source_id and source_screen_name are both empty
|
||||||
|
*
|
||||||
|
* @return boolean true or false
|
||||||
|
*/
|
||||||
|
|
||||||
|
function requiresAuth()
|
||||||
|
{
|
||||||
|
if (common_config('site', 'private')) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
$source_id = $this->trimmed('source_id');
|
||||||
|
$source_screen_name = $this->trimmed('source_screen_name');
|
||||||
|
|
||||||
|
if (empty($source_id) && empty($source_screen_name)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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 (!in_array($this->format, array('xml', 'json'))) {
|
||||||
|
$this->clientError(_('API method not found!'), 404);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (empty($this->source)) {
|
||||||
|
$this->clientError(
|
||||||
|
_('Could not determine source user.'),
|
||||||
|
404
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (empty($this->target)) {
|
||||||
|
$this->clientError(
|
||||||
|
_('Could not find target user.'),
|
||||||
|
404
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$result = $this->twitterRelationshipArray($this->source, $this->target);
|
||||||
|
|
||||||
|
switch ($this->format) {
|
||||||
|
case 'xml':
|
||||||
|
$this->initDocument('xml');
|
||||||
|
$this->showTwitterXmlRelationship($result[relationship]);
|
||||||
|
$this->endDocument('xml');
|
||||||
|
break;
|
||||||
|
case 'json':
|
||||||
|
$this->initDocument('json');
|
||||||
|
print json_encode($result);
|
||||||
|
$this->endDocument('json');
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
324
actions/apigroupcreate.php
Normal file
324
actions/apigroupcreate.php
Normal file
@ -0,0 +1,324 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* StatusNet, the distributed open-source microblogging tool
|
||||||
|
*
|
||||||
|
* Create a group via the API
|
||||||
|
*
|
||||||
|
* PHP version 5
|
||||||
|
*
|
||||||
|
* LICENCE: This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* @category API
|
||||||
|
* @package StatusNet
|
||||||
|
* @author Craig Andrews <candrews@integralblue.com>
|
||||||
|
* @author Evan Prodromou <evan@status.net>
|
||||||
|
* @author Jeffery To <jeffery.to@gmail.com>
|
||||||
|
* @author Zach Copley <zach@status.net>
|
||||||
|
* @copyright 2009 StatusNet, Inc.
|
||||||
|
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||||
|
* @link http://status.net/
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (!defined('STATUSNET')) {
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
require_once INSTALLDIR . '/lib/apiauth.php';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Make a new group. Sets the authenticated user as the administrator of the group.
|
||||||
|
*
|
||||||
|
* @category API
|
||||||
|
* @package StatusNet
|
||||||
|
* @author Craig Andrews <candrews@integralblue.com>
|
||||||
|
* @author Evan Prodromou <evan@status.net>
|
||||||
|
* @author Jeffery To <jeffery.to@gmail.com>
|
||||||
|
* @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 ApiGroupCreateAction extends ApiAuthAction
|
||||||
|
{
|
||||||
|
var $group = null;
|
||||||
|
var $nickname = null;
|
||||||
|
var $fullname = null;
|
||||||
|
var $homepage = null;
|
||||||
|
var $description = null;
|
||||||
|
var $location = null;
|
||||||
|
var $aliasstring = null;
|
||||||
|
var $aliases = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Take arguments for running
|
||||||
|
*
|
||||||
|
* @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->fullname = $this->arg('full_name');
|
||||||
|
$this->homepage = $this->arg('homepage');
|
||||||
|
$this->description = $this->arg('description');
|
||||||
|
$this->location = $this->arg('location');
|
||||||
|
$this->aliasstring = $this->arg('aliases');
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle the request
|
||||||
|
*
|
||||||
|
* Save the new group
|
||||||
|
*
|
||||||
|
* @param array $args $_REQUEST data (unused)
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
|
||||||
|
function handle($args)
|
||||||
|
{
|
||||||
|
parent::handle($args);
|
||||||
|
|
||||||
|
if ($_SERVER['REQUEST_METHOD'] != 'POST') {
|
||||||
|
$this->clientError(
|
||||||
|
_('This method requires a POST.'),
|
||||||
|
400,
|
||||||
|
$this->format
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (empty($this->user)) {
|
||||||
|
$this->clientError(_('No such user.'), 404, $this->format);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($this->validateParams() == false) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$group = User_group::register(array('nickname' => $this->nickname,
|
||||||
|
'fullname' => $this->fullname,
|
||||||
|
'homepage' => $this->homepage,
|
||||||
|
'description' => $this->description,
|
||||||
|
'location' => $this->location,
|
||||||
|
'aliases' => $this->aliases,
|
||||||
|
'userid' => $this->user->id));
|
||||||
|
switch($this->format) {
|
||||||
|
case 'xml':
|
||||||
|
$this->showSingleXmlGroup($group);
|
||||||
|
break;
|
||||||
|
case 'json':
|
||||||
|
$this->showSingleJsonGroup($group);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
$this->clientError(
|
||||||
|
_('API method not found!'),
|
||||||
|
404,
|
||||||
|
$this->format
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validate params for the new group
|
||||||
|
*
|
||||||
|
* @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)) {
|
||||||
|
$this->clientError(
|
||||||
|
_('Nickname already in use. Try another one.'),
|
||||||
|
403,
|
||||||
|
$this->format
|
||||||
|
);
|
||||||
|
return false;
|
||||||
|
} else if (!User_group::allowedNickname($this->nickname)) {
|
||||||
|
$this->clientError(
|
||||||
|
_('Not a valid nickname.'),
|
||||||
|
403,
|
||||||
|
$this->format
|
||||||
|
);
|
||||||
|
return false;
|
||||||
|
|
||||||
|
} elseif (
|
||||||
|
!is_null($this->homepage)
|
||||||
|
&& strlen($this->homepage) > 0
|
||||||
|
&& !Validate::uri(
|
||||||
|
$this->homepage, array(
|
||||||
|
'allowed_schemes' =>
|
||||||
|
array('http', 'https')
|
||||||
|
)
|
||||||
|
)) {
|
||||||
|
$this->clientError(
|
||||||
|
_('Homepage is not a valid URL.'),
|
||||||
|
403,
|
||||||
|
$this->format
|
||||||
|
);
|
||||||
|
return false;
|
||||||
|
} elseif (
|
||||||
|
!is_null($this->fullname)
|
||||||
|
&& mb_strlen($this->fullname) > 255) {
|
||||||
|
$this->clientError(
|
||||||
|
_('Full name is too long (max 255 chars).'),
|
||||||
|
403,
|
||||||
|
$this->format
|
||||||
|
);
|
||||||
|
return false;
|
||||||
|
} elseif (User_group::descriptionTooLong($this->description)) {
|
||||||
|
$this->clientError(
|
||||||
|
sprintf(
|
||||||
|
_('Description is too long (max %d chars).'),
|
||||||
|
User_group::maxDescription()
|
||||||
|
),
|
||||||
|
403,
|
||||||
|
$this->format
|
||||||
|
);
|
||||||
|
return false;
|
||||||
|
} elseif (
|
||||||
|
!is_null($this->location)
|
||||||
|
&& mb_strlen($this->location) > 255) {
|
||||||
|
$this->clientError(
|
||||||
|
_('Location is too long (max 255 chars).'),
|
||||||
|
403,
|
||||||
|
$this->format
|
||||||
|
);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!empty($this->aliasstring)) {
|
||||||
|
$this->aliases = array_map(
|
||||||
|
'common_canonical_nickname',
|
||||||
|
array_unique(preg_split('/[\s,]+/', $this->aliasstring))
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
$this->aliases = array();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (count($this->aliases) > common_config('group', 'maxaliases')) {
|
||||||
|
$this->clientError(
|
||||||
|
sprintf(
|
||||||
|
_('Too many aliases! Maximum %d.'),
|
||||||
|
common_config('group', 'maxaliases')
|
||||||
|
),
|
||||||
|
403,
|
||||||
|
$this->format
|
||||||
|
);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($this->aliases as $alias) {
|
||||||
|
|
||||||
|
$valid = Validate::string(
|
||||||
|
$alias, array(
|
||||||
|
'min_length' => 1,
|
||||||
|
'max_length' => 64,
|
||||||
|
'format' => NICKNAME_FMT
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!$valid) {
|
||||||
|
$this->clientError(
|
||||||
|
sprintf(_('Invalid alias: "%s"'), $alias),
|
||||||
|
403,
|
||||||
|
$this->format
|
||||||
|
);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if ($this->groupNicknameExists($alias)) {
|
||||||
|
$this->clientError(
|
||||||
|
sprintf(
|
||||||
|
_('Alias "%s" already in use. Try another one.'),
|
||||||
|
$alias
|
||||||
|
),
|
||||||
|
403,
|
||||||
|
$this->format
|
||||||
|
);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// XXX assumes alphanum nicknames
|
||||||
|
|
||||||
|
if (strcmp($alias, $this->nickname) == 0) {
|
||||||
|
$this->clientError(
|
||||||
|
_('Alias can\'t be the same as nickname.'),
|
||||||
|
403,
|
||||||
|
$this->format
|
||||||
|
);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Evarything looks OK
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check to see whether a nickname is already in use by a group
|
||||||
|
*
|
||||||
|
* @param String $nickname The nickname in question
|
||||||
|
*
|
||||||
|
* @return boolean true or false
|
||||||
|
*/
|
||||||
|
|
||||||
|
function groupNicknameExists($nickname)
|
||||||
|
{
|
||||||
|
$group = User_group::staticGet('nickname', $nickname);
|
||||||
|
|
||||||
|
if (!empty($group)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
$alias = Group_alias::staticGet('alias', $nickname);
|
||||||
|
|
||||||
|
if (!empty($alias)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
122
actions/apigroupismember.php
Normal file
122
actions/apigroupismember.php
Normal file
@ -0,0 +1,122 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* StatusNet, the distributed open-source microblogging tool
|
||||||
|
*
|
||||||
|
* Check to see whether a user a member of 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 API
|
||||||
|
* @package StatusNet
|
||||||
|
* @author Craig Andrews <candrews@integralblue.com>
|
||||||
|
* @author Evan Prodromou <evan@status.net>
|
||||||
|
* @author Jeffery To <jeffery.to@gmail.com>
|
||||||
|
* @author Zach Copley <zach@status.net>
|
||||||
|
* @copyright 2009 StatusNet, Inc.
|
||||||
|
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||||
|
* @link http://status.net/
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (!defined('STATUSNET')) {
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
require_once INSTALLDIR . '/lib/apibareauth.php';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns whether a user is a member of a specified group.
|
||||||
|
*
|
||||||
|
* @category API
|
||||||
|
* @package StatusNet
|
||||||
|
* @author Craig Andrews <candrews@integralblue.com>
|
||||||
|
* @author Evan Prodromou <evan@status.net>
|
||||||
|
* @author Jeffery To <jeffery.to@gmail.com>
|
||||||
|
* @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 ApiGroupIsMemberAction extends ApiBareAuthAction
|
||||||
|
{
|
||||||
|
var $group = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Take arguments for running
|
||||||
|
*
|
||||||
|
* @param array $args $_REQUEST args
|
||||||
|
*
|
||||||
|
* @return boolean success flag
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
function prepare($args)
|
||||||
|
{
|
||||||
|
parent::prepare($args);
|
||||||
|
|
||||||
|
$this->user = $this->getTargetUser(null);
|
||||||
|
$this->group = $this->getTargetGroup(null);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle the request
|
||||||
|
*
|
||||||
|
* Save the new message
|
||||||
|
*
|
||||||
|
* @param array $args $_REQUEST data (unused)
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
|
||||||
|
function handle($args)
|
||||||
|
{
|
||||||
|
parent::handle($args);
|
||||||
|
|
||||||
|
if (empty($this->user)) {
|
||||||
|
$this->clientError(_('No such user.'), 404, $this->format);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (empty($this->group)) {
|
||||||
|
$this->clientError(_('Group not found!'), 404, $this->format);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$is_member = $this->user->isMember($this->group);
|
||||||
|
|
||||||
|
switch($this->format) {
|
||||||
|
case 'xml':
|
||||||
|
$this->initDocument('xml');
|
||||||
|
$this->element('is_member', null, $is_member);
|
||||||
|
$this->endDocument('xml');
|
||||||
|
break;
|
||||||
|
case 'json':
|
||||||
|
$this->initDocument('json');
|
||||||
|
$this->showJsonObjects(array('is_member' => $is_member));
|
||||||
|
$this->endDocument('json');
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
$this->clientError(
|
||||||
|
_('API method not found!'),
|
||||||
|
400,
|
||||||
|
$this->format
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
163
actions/apigroupjoin.php
Normal file
163
actions/apigroupjoin.php
Normal file
@ -0,0 +1,163 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* StatusNet, the distributed open-source microblogging tool
|
||||||
|
*
|
||||||
|
* Join a group via the API
|
||||||
|
*
|
||||||
|
* PHP version 5
|
||||||
|
*
|
||||||
|
* LICENCE: This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* @category API
|
||||||
|
* @package StatusNet
|
||||||
|
* @author Craig Andrews <candrews@integralblue.com>
|
||||||
|
* @author Evan Prodromou <evan@status.net>
|
||||||
|
* @author Jeffery To <jeffery.to@gmail.com>
|
||||||
|
* @author Zach Copley <zach@status.net>
|
||||||
|
* @copyright 2009 StatusNet, Inc.
|
||||||
|
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||||
|
* @link http://status.net/
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (!defined('STATUSNET')) {
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
require_once INSTALLDIR . '/lib/apiauth.php';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Joins the authenticated user to the group speicified by ID
|
||||||
|
*
|
||||||
|
* @category API
|
||||||
|
* @package StatusNet
|
||||||
|
* @author Craig Andrews <candrews@integralblue.com>
|
||||||
|
* @author Evan Prodromou <evan@status.net>
|
||||||
|
* @author Jeffery To <jeffery.to@gmail.com>
|
||||||
|
* @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 ApiGroupJoinAction extends ApiAuthAction
|
||||||
|
{
|
||||||
|
var $group = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Take arguments for running
|
||||||
|
*
|
||||||
|
* @param array $args $_REQUEST args
|
||||||
|
*
|
||||||
|
* @return boolean success flag
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
function prepare($args)
|
||||||
|
{
|
||||||
|
parent::prepare($args);
|
||||||
|
|
||||||
|
$this->user = $this->auth_user;
|
||||||
|
$this->group = $this->getTargetGroup($this->arg('id'));
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle the request
|
||||||
|
*
|
||||||
|
* Save the new message
|
||||||
|
*
|
||||||
|
* @param array $args $_REQUEST data (unused)
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
|
||||||
|
function handle($args)
|
||||||
|
{
|
||||||
|
parent::handle($args);
|
||||||
|
|
||||||
|
if ($_SERVER['REQUEST_METHOD'] != 'POST') {
|
||||||
|
$this->clientError(
|
||||||
|
_('This method requires a POST.'),
|
||||||
|
400,
|
||||||
|
$this->format
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (empty($this->user)) {
|
||||||
|
$this->clientError(_('No such user.'), 404, $this->format);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (empty($this->group)) {
|
||||||
|
$this->clientError(_('Group not found!'), 404, $this->format);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($this->user->isMember($this->group)) {
|
||||||
|
$this->clientError(
|
||||||
|
_('You are already a member of that group.'),
|
||||||
|
403,
|
||||||
|
$this->format
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Group_block::isBlocked($this->group, $this->user->getProfile())) {
|
||||||
|
$this->clientError(
|
||||||
|
_('You have been blocked from that group by the admin.'),
|
||||||
|
403,
|
||||||
|
$this->format
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$member = new Group_member();
|
||||||
|
|
||||||
|
$member->group_id = $this->group->id;
|
||||||
|
$member->profile_id = $this->user->id;
|
||||||
|
$member->created = common_sql_now();
|
||||||
|
|
||||||
|
$result = $member->insert();
|
||||||
|
|
||||||
|
if (!$result) {
|
||||||
|
common_log_db_error($member, 'INSERT', __FILE__);
|
||||||
|
$this->serverError(
|
||||||
|
sprintf(
|
||||||
|
_('Could not join user %s to group %s.'),
|
||||||
|
$this->user->nickname,
|
||||||
|
$this->group->nickname
|
||||||
|
)
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch($this->format) {
|
||||||
|
case 'xml':
|
||||||
|
$this->show_single_xml_group($this->group);
|
||||||
|
break;
|
||||||
|
case 'json':
|
||||||
|
$this->showSingleJsonGroup($this->group);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
$this->clientError(
|
||||||
|
_('API method not found!'),
|
||||||
|
404,
|
||||||
|
$this->format
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
149
actions/apigroupleave.php
Normal file
149
actions/apigroupleave.php
Normal file
@ -0,0 +1,149 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* StatusNet, the distributed open-source microblogging tool
|
||||||
|
*
|
||||||
|
* Leave a group via the API
|
||||||
|
*
|
||||||
|
* PHP version 5
|
||||||
|
*
|
||||||
|
* LICENCE: This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* @category API
|
||||||
|
* @package StatusNet
|
||||||
|
* @author Craig Andrews <candrews@integralblue.com>
|
||||||
|
* @author Evan Prodromou <evan@status.net>
|
||||||
|
* @author Jeffery To <jeffery.to@gmail.com>
|
||||||
|
* @author Zach Copley <zach@status.net>
|
||||||
|
* @copyright 2009 StatusNet, Inc.
|
||||||
|
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||||
|
* @link http://status.net/
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (!defined('STATUSNET')) {
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
require_once INSTALLDIR . '/lib/apiauth.php';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes the authenticated user from the group specified by ID
|
||||||
|
*
|
||||||
|
* @category API
|
||||||
|
* @package StatusNet
|
||||||
|
* @author Craig Andrews <candrews@integralblue.com>
|
||||||
|
* @author Evan Prodromou <evan@status.net>
|
||||||
|
* @author Jeffery To <jeffery.to@gmail.com>
|
||||||
|
* @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 ApiGroupLeaveAction extends ApiAuthAction
|
||||||
|
{
|
||||||
|
var $group = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Take arguments for running
|
||||||
|
*
|
||||||
|
* @param array $args $_REQUEST args
|
||||||
|
*
|
||||||
|
* @return boolean success flag
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
function prepare($args)
|
||||||
|
{
|
||||||
|
parent::prepare($args);
|
||||||
|
|
||||||
|
$this->user = $this->auth_user;
|
||||||
|
$this->group = $this->getTargetGroup($this->arg('id'));
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle the request
|
||||||
|
*
|
||||||
|
* Save the new message
|
||||||
|
*
|
||||||
|
* @param array $args $_REQUEST data (unused)
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
|
||||||
|
function handle($args)
|
||||||
|
{
|
||||||
|
parent::handle($args);
|
||||||
|
|
||||||
|
if ($_SERVER['REQUEST_METHOD'] != 'POST') {
|
||||||
|
$this->clientError(
|
||||||
|
_('This method requires a POST.'),
|
||||||
|
400,
|
||||||
|
$this->format
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (empty($this->user)) {
|
||||||
|
$this->clientError(_('No such user.'), 404, $this->format);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (empty($this->group)) {
|
||||||
|
$this->clientError(_('Group not found!'), 404, $this->format);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$member = new Group_member();
|
||||||
|
|
||||||
|
$member->group_id = $this->group->id;
|
||||||
|
$member->profile_id = $this->auth->id;
|
||||||
|
|
||||||
|
if (!$member->find(true)) {
|
||||||
|
$this->serverError(_('You are not a member of this group.'));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$result = $member->delete();
|
||||||
|
|
||||||
|
if (!$result) {
|
||||||
|
common_log_db_error($member, 'INSERT', __FILE__);
|
||||||
|
$this->serverError(
|
||||||
|
sprintf(
|
||||||
|
_('Could not remove user %s to group %s.'),
|
||||||
|
$this->user->nickname,
|
||||||
|
$this->$group->nickname
|
||||||
|
)
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch($this->format) {
|
||||||
|
case 'xml':
|
||||||
|
$this->show_single_xml_group($this->group);
|
||||||
|
break;
|
||||||
|
case 'json':
|
||||||
|
$this->showSingleJsonGroup($this->group);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
$this->clientError(
|
||||||
|
_('API method not found!'),
|
||||||
|
404,
|
||||||
|
$this->format
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
223
actions/apigrouplist.php
Normal file
223
actions/apigrouplist.php
Normal file
@ -0,0 +1,223 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* StatusNet, the distributed open-source microblogging tool
|
||||||
|
*
|
||||||
|
* Check to see whether a user a member of 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 API
|
||||||
|
* @package StatusNet
|
||||||
|
* @author Craig Andrews <candrews@integralblue.com>
|
||||||
|
* @author Evan Prodromou <evan@status.net>
|
||||||
|
* @author Jeffery To <jeffery.to@gmail.com>
|
||||||
|
* @author Zach Copley <zach@status.net>
|
||||||
|
* @copyright 2009 StatusNet, Inc.
|
||||||
|
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||||
|
* @link http://status.net/
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (!defined('STATUSNET')) {
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
require_once INSTALLDIR . '/lib/apibareauth.php';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns whether a user is a member of a specified group.
|
||||||
|
*
|
||||||
|
* @category API
|
||||||
|
* @package StatusNet
|
||||||
|
* @author Craig Andrews <candrews@integralblue.com>
|
||||||
|
* @author Evan Prodromou <evan@status.net>
|
||||||
|
* @author Jeffery To <jeffery.to@gmail.com>
|
||||||
|
* @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 ApiGroupListAction extends ApiBareAuthAction
|
||||||
|
{
|
||||||
|
var $groups = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Take arguments for running
|
||||||
|
*
|
||||||
|
* @param array $args $_REQUEST args
|
||||||
|
*
|
||||||
|
* @return boolean success flag
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
function prepare($args)
|
||||||
|
{
|
||||||
|
parent::prepare($args);
|
||||||
|
|
||||||
|
$this->user = $this->getTargetUser($id);
|
||||||
|
$this->groups = $this->getGroups();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle the request
|
||||||
|
*
|
||||||
|
* Show the user's groups
|
||||||
|
*
|
||||||
|
* @param array $args $_REQUEST data (unused)
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
|
||||||
|
function handle($args)
|
||||||
|
{
|
||||||
|
parent::handle($args);
|
||||||
|
|
||||||
|
if (empty($this->user)) {
|
||||||
|
$this->clientError(_('No such user.'), 404, $this->format);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$sitename = common_config('site', 'name');
|
||||||
|
$title = sprintf(_("%s's groups"), $this->user->nickname);
|
||||||
|
$taguribase = common_config('integration', 'taguri');
|
||||||
|
$id = "tag:$taguribase:Groups";
|
||||||
|
$link = common_local_url(
|
||||||
|
'usergroups',
|
||||||
|
array('nickname' => $this->user->nickname)
|
||||||
|
);
|
||||||
|
$subtitle = sprintf(
|
||||||
|
_("Groups %s is a member of on %s."),
|
||||||
|
$this->user->nickname,
|
||||||
|
$sitename
|
||||||
|
);
|
||||||
|
|
||||||
|
switch($this->format) {
|
||||||
|
case 'xml':
|
||||||
|
$this->showXmlGroups($this->groups);
|
||||||
|
break;
|
||||||
|
case 'rss':
|
||||||
|
$this->showRssGroups($this->groups, $title, $link, $subtitle);
|
||||||
|
break;
|
||||||
|
case 'atom':
|
||||||
|
$selfuri = common_root_url() . 'api/statusnet/groups/list/' .
|
||||||
|
$this->user->id . '.atom';
|
||||||
|
$this->showAtomGroups(
|
||||||
|
$this->groups,
|
||||||
|
$title,
|
||||||
|
$id,
|
||||||
|
$link,
|
||||||
|
$subtitle,
|
||||||
|
$selfuri
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
case 'json':
|
||||||
|
$this->showJsonGroups($this->groups);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
$this->clientError(
|
||||||
|
_('API method not found!'),
|
||||||
|
404,
|
||||||
|
$this->format
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get groups
|
||||||
|
*
|
||||||
|
* @return array groups
|
||||||
|
*/
|
||||||
|
|
||||||
|
function getGroups()
|
||||||
|
{
|
||||||
|
$groups = array();
|
||||||
|
|
||||||
|
$group = $this->user->getGroups(
|
||||||
|
($this->page - 1) * $this->count,
|
||||||
|
$this->count,
|
||||||
|
$this->since_id,
|
||||||
|
$this->max_id,
|
||||||
|
$this->since
|
||||||
|
);
|
||||||
|
|
||||||
|
while ($group->fetch()) {
|
||||||
|
$groups[] = clone($group);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $groups;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Is this action read only?
|
||||||
|
*
|
||||||
|
* @param array $args other arguments
|
||||||
|
*
|
||||||
|
* @return boolean true
|
||||||
|
*/
|
||||||
|
|
||||||
|
function isReadOnly($args)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* When was this feed last modified?
|
||||||
|
*
|
||||||
|
* @return string datestamp of the latest group the user has joined
|
||||||
|
*/
|
||||||
|
|
||||||
|
function lastModified()
|
||||||
|
{
|
||||||
|
if (!empty($this->groups) && (count($this->groups) > 0)) {
|
||||||
|
return strtotime($this->groups[0]->created);
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An entity tag for this list of groups
|
||||||
|
*
|
||||||
|
* Returns an Etag based on the action name, language, user ID and
|
||||||
|
* timestamps of the first and last group the user has joined
|
||||||
|
*
|
||||||
|
* @return string etag
|
||||||
|
*/
|
||||||
|
|
||||||
|
function etag()
|
||||||
|
{
|
||||||
|
if (!empty($this->groups) && (count($this->groups) > 0)) {
|
||||||
|
|
||||||
|
$last = count($this->groups) - 1;
|
||||||
|
|
||||||
|
return '"' . implode(
|
||||||
|
':',
|
||||||
|
array($this->arg('action'),
|
||||||
|
common_language(),
|
||||||
|
$this->user->id,
|
||||||
|
strtotime($this->groups[0]->created),
|
||||||
|
strtotime($this->groups[$last]->created))
|
||||||
|
)
|
||||||
|
. '"';
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
208
actions/apigrouplistall.php
Normal file
208
actions/apigrouplistall.php
Normal file
@ -0,0 +1,208 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* StatusNet, the distributed open-source microblogging tool
|
||||||
|
*
|
||||||
|
* Show the newest groups
|
||||||
|
*
|
||||||
|
* 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 Craig Andrews <candrews@integralblue.com>
|
||||||
|
* @author Evan Prodromou <evan@status.net>
|
||||||
|
* @author Jeffery To <jeffery.to@gmail.com>
|
||||||
|
* @author Zach Copley <zach@status.net>
|
||||||
|
* @copyright 2009 StatusNet, Inc.
|
||||||
|
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||||
|
* @link http://status.net/
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (!defined('STATUSNET')) {
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
require_once INSTALLDIR . '/lib/apiprivateauth.php';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns of the lastest 20 groups for the site
|
||||||
|
*
|
||||||
|
* @category API
|
||||||
|
* @package StatusNet
|
||||||
|
* @author Craig Andrews <candrews@integralblue.com>
|
||||||
|
* @author Evan Prodromou <evan@status.net>
|
||||||
|
* @author Jeffery To <jeffery.to@gmail.com>
|
||||||
|
* @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 ApiGroupListAllAction extends ApiPrivateAuthAction
|
||||||
|
{
|
||||||
|
var $groups = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Take arguments for running
|
||||||
|
*
|
||||||
|
* @param array $args $_REQUEST args
|
||||||
|
*
|
||||||
|
* @return boolean success flag
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
function prepare($args)
|
||||||
|
{
|
||||||
|
parent::prepare($args);
|
||||||
|
|
||||||
|
$this->user = $this->getTargetUser($id);
|
||||||
|
$this->groups = $this->getGroups();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle the request
|
||||||
|
*
|
||||||
|
* Show the user's groups
|
||||||
|
*
|
||||||
|
* @param array $args $_REQUEST data (unused)
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
|
||||||
|
function handle($args)
|
||||||
|
{
|
||||||
|
parent::handle($args);
|
||||||
|
|
||||||
|
$sitename = common_config('site', 'name');
|
||||||
|
$title = sprintf(_("%s groups"), $sitename);
|
||||||
|
$taguribase = common_config('integration', 'taguri');
|
||||||
|
$id = "tag:$taguribase:Groups";
|
||||||
|
$link = common_local_url('groups');
|
||||||
|
$subtitle = sprintf(_("groups on %s"), $sitename);
|
||||||
|
|
||||||
|
switch($this->format) {
|
||||||
|
case 'xml':
|
||||||
|
$this->showXmlGroups($this->groups);
|
||||||
|
break;
|
||||||
|
case 'rss':
|
||||||
|
$this->showRssGroups($this->groups, $title, $link, $subtitle);
|
||||||
|
break;
|
||||||
|
case 'atom':
|
||||||
|
$selfuri = common_root_url() .
|
||||||
|
'api/statusnet/groups/list_all.atom';
|
||||||
|
$this->showAtomGroups(
|
||||||
|
$this->groups,
|
||||||
|
$title,
|
||||||
|
$id,
|
||||||
|
$link,
|
||||||
|
$subtitle,
|
||||||
|
$selfuri
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
case 'json':
|
||||||
|
$this->showJsonGroups($this->groups);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
$this->clientError(
|
||||||
|
_('API method not found!'),
|
||||||
|
404,
|
||||||
|
$this->format
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get groups
|
||||||
|
*
|
||||||
|
* @return array groups
|
||||||
|
*/
|
||||||
|
|
||||||
|
function getGroups()
|
||||||
|
{
|
||||||
|
$groups = array();
|
||||||
|
|
||||||
|
// XXX: Use the $page, $count, $max_id, $since_id, and $since parameters
|
||||||
|
|
||||||
|
$group = new User_group();
|
||||||
|
$group->orderBy('created DESC');
|
||||||
|
$group->find();
|
||||||
|
|
||||||
|
while ($group->fetch()) {
|
||||||
|
$groups[] = clone($group);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $groups;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Is this action read only?
|
||||||
|
*
|
||||||
|
* @param array $args other arguments
|
||||||
|
*
|
||||||
|
* @return boolean true
|
||||||
|
*/
|
||||||
|
|
||||||
|
function isReadOnly($args)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* When was this feed last modified?
|
||||||
|
*
|
||||||
|
* @return string datestamp of the site's latest group
|
||||||
|
*/
|
||||||
|
|
||||||
|
function lastModified()
|
||||||
|
{
|
||||||
|
if (!empty($this->groups) && (count($this->groups) > 0)) {
|
||||||
|
return strtotime($this->groups[0]->created);
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An entity tag for this list of groups
|
||||||
|
*
|
||||||
|
* Returns an Etag based on the action name, language, and
|
||||||
|
* timestamps of the first and last group the user has joined
|
||||||
|
*
|
||||||
|
* @return string etag
|
||||||
|
*/
|
||||||
|
|
||||||
|
function etag()
|
||||||
|
{
|
||||||
|
if (!empty($this->groups) && (count($this->groups) > 0)) {
|
||||||
|
|
||||||
|
$last = count($this->groups) - 1;
|
||||||
|
|
||||||
|
return '"' . implode(
|
||||||
|
':',
|
||||||
|
array($this->arg('action'),
|
||||||
|
common_language(),
|
||||||
|
strtotime($this->groups[0]->created),
|
||||||
|
strtotime($this->groups[$last]->created))
|
||||||
|
)
|
||||||
|
. '"';
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
197
actions/apigroupmembership.php
Normal file
197
actions/apigroupmembership.php
Normal file
@ -0,0 +1,197 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* StatusNet, the distributed open-source microblogging tool
|
||||||
|
*
|
||||||
|
* List a group's members
|
||||||
|
*
|
||||||
|
* 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 Craig Andrews <candrews@integralblue.com>
|
||||||
|
* @author Evan Prodromou <evan@status.net>
|
||||||
|
* @author Jeffery To <jeffery.to@gmail.com>
|
||||||
|
* @author Zach Copley <zach@status.net>
|
||||||
|
* @copyright 2009 StatusNet, Inc.
|
||||||
|
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||||
|
* @link http://status.net/
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (!defined('STATUSNET')) {
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
require_once INSTALLDIR . '/lib/apiprivateauth.php';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* List 20 newest members of the group specified by name or ID.
|
||||||
|
*
|
||||||
|
* @category API
|
||||||
|
* @package StatusNet
|
||||||
|
* @author Craig Andrews <candrews@integralblue.com>
|
||||||
|
* @author Evan Prodromou <evan@status.net>
|
||||||
|
* @author Jeffery To <jeffery.to@gmail.com>
|
||||||
|
* @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 ApiGroupMembershipAction extends ApiPrivateAuthAction
|
||||||
|
{
|
||||||
|
var $group = null;
|
||||||
|
var $profiles = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Take arguments for running
|
||||||
|
*
|
||||||
|
* @param array $args $_REQUEST args
|
||||||
|
*
|
||||||
|
* @return boolean success flag
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
function prepare($args)
|
||||||
|
{
|
||||||
|
parent::prepare($args);
|
||||||
|
|
||||||
|
$this->group = $this->getTargetGroup($this->arg('id'));
|
||||||
|
$this->profiles = $this->getProfiles();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle the request
|
||||||
|
*
|
||||||
|
* Show the members of the group
|
||||||
|
*
|
||||||
|
* @param array $args $_REQUEST data (unused)
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
|
||||||
|
function handle($args)
|
||||||
|
{
|
||||||
|
parent::handle($args);
|
||||||
|
|
||||||
|
if (empty($this->group)) {
|
||||||
|
$this->clientError(_('Group not found!'), 404, $this->format);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// XXX: RSS and Atom
|
||||||
|
|
||||||
|
switch($this->format) {
|
||||||
|
case 'xml':
|
||||||
|
$this->showTwitterXmlUsers($this->profiles);
|
||||||
|
break;
|
||||||
|
case 'json':
|
||||||
|
$this->showJsonUsers($this->profiles);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
$this->clientError(
|
||||||
|
_('API method not found!'),
|
||||||
|
404,
|
||||||
|
$this->format
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fetch the members of a group
|
||||||
|
*
|
||||||
|
* @return array $profiles list of profiles
|
||||||
|
*/
|
||||||
|
|
||||||
|
function getProfiles()
|
||||||
|
{
|
||||||
|
$profiles = array();
|
||||||
|
|
||||||
|
$profile = $this->group->getMembers(
|
||||||
|
($this->page - 1) * $this->count,
|
||||||
|
$this->count,
|
||||||
|
$this->since_id,
|
||||||
|
$this->max_id,
|
||||||
|
$this->since
|
||||||
|
);
|
||||||
|
|
||||||
|
while ($profile->fetch()) {
|
||||||
|
$profiles[] = clone($profile);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $profiles;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Is this action read only?
|
||||||
|
*
|
||||||
|
* @param array $args other arguments
|
||||||
|
*
|
||||||
|
* @return boolean true
|
||||||
|
*/
|
||||||
|
|
||||||
|
function isReadOnly($args)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* When was this list of profiles last modified?
|
||||||
|
*
|
||||||
|
* @return string datestamp of the lastest profile in the group
|
||||||
|
*/
|
||||||
|
|
||||||
|
function lastModified()
|
||||||
|
{
|
||||||
|
if (!empty($this->profiles) && (count($this->profiles) > 0)) {
|
||||||
|
return strtotime($this->profiles[0]->created);
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An entity tag for this list of groups
|
||||||
|
*
|
||||||
|
* Returns an Etag based on the action name, language
|
||||||
|
* the group id, and timestamps of the first and last
|
||||||
|
* user who has joined the group
|
||||||
|
*
|
||||||
|
* @return string etag
|
||||||
|
*/
|
||||||
|
|
||||||
|
function etag()
|
||||||
|
{
|
||||||
|
if (!empty($this->profiles) && (count($this->profiles) > 0)) {
|
||||||
|
|
||||||
|
$last = count($this->profiles) - 1;
|
||||||
|
|
||||||
|
return '"' . implode(
|
||||||
|
':',
|
||||||
|
array($this->arg('action'),
|
||||||
|
common_language(),
|
||||||
|
$this->group->id,
|
||||||
|
strtotime($this->profiles[0]->created),
|
||||||
|
strtotime($this->profiles[$last]->created))
|
||||||
|
)
|
||||||
|
. '"';
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
152
actions/apigroupshow.php
Normal file
152
actions/apigroupshow.php
Normal file
@ -0,0 +1,152 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* StatusNet, the distributed open-source microblogging tool
|
||||||
|
*
|
||||||
|
* Show information about 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 API
|
||||||
|
* @package StatusNet
|
||||||
|
* @author Craig Andrews <candrews@integralblue.com>
|
||||||
|
* @author Evan Prodromou <evan@status.net>
|
||||||
|
* @author Jeffery To <jeffery.to@gmail.com>
|
||||||
|
* @author Zach Copley <zach@status.net>
|
||||||
|
* @copyright 2009 StatusNet, Inc.
|
||||||
|
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||||
|
* @link http://status.net/
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (!defined('STATUSNET')) {
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
require_once INSTALLDIR . '/lib/apiprivateauth.php';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Outputs detailed information about the group specified by ID
|
||||||
|
*
|
||||||
|
* @category API
|
||||||
|
* @package StatusNet
|
||||||
|
* @author Craig Andrews <candrews@integralblue.com>
|
||||||
|
* @author Evan Prodromou <evan@status.net>
|
||||||
|
* @author Jeffery To <jeffery.to@gmail.com>
|
||||||
|
* @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 ApiGroupShowAction extends ApiPrivateAuthAction
|
||||||
|
{
|
||||||
|
var $group = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Take arguments for running
|
||||||
|
*
|
||||||
|
* @param array $args $_REQUEST args
|
||||||
|
*
|
||||||
|
* @return boolean success flag
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
function prepare($args)
|
||||||
|
{
|
||||||
|
parent::prepare($args);
|
||||||
|
|
||||||
|
$this->group = $this->getTargetGroup($this->arg('id'));
|
||||||
|
|
||||||
|
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->group)) {
|
||||||
|
$this->clientError(
|
||||||
|
_('Group not found!'),
|
||||||
|
404,
|
||||||
|
$this->format
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch($this->format) {
|
||||||
|
case 'xml':
|
||||||
|
$this->show_single_xml_group($this->group);
|
||||||
|
break;
|
||||||
|
case 'json':
|
||||||
|
$this->showSingleJsonGroup($this->group);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
$this->clientError(_('API method not found!'), 404, $this->format);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* When was this group last modified?
|
||||||
|
*
|
||||||
|
* @return string datestamp of the latest notice in the stream
|
||||||
|
*/
|
||||||
|
|
||||||
|
function lastModified()
|
||||||
|
{
|
||||||
|
if (!empty($this->group)) {
|
||||||
|
return strtotime($this->group->modified);
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An entity tag for this group
|
||||||
|
*
|
||||||
|
* Returns an Etag based on the action name, language, and
|
||||||
|
* timestamps of the notice
|
||||||
|
*
|
||||||
|
* @return string etag
|
||||||
|
*/
|
||||||
|
|
||||||
|
function etag()
|
||||||
|
{
|
||||||
|
if (!empty($this->group)) {
|
||||||
|
|
||||||
|
return '"' . implode(
|
||||||
|
':',
|
||||||
|
array($this->arg('action'),
|
||||||
|
common_language(),
|
||||||
|
$this->group->id,
|
||||||
|
strtotime($this->group->modified))
|
||||||
|
)
|
||||||
|
. '"';
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
96
actions/apihelptest.php
Normal file
96
actions/apihelptest.php
Normal file
@ -0,0 +1,96 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* StatusNet, the distributed open-source microblogging tool
|
||||||
|
*
|
||||||
|
* Test that you can connect to the API
|
||||||
|
*
|
||||||
|
* PHP version 5
|
||||||
|
*
|
||||||
|
* LICENCE: This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* @category API
|
||||||
|
* @package StatusNet
|
||||||
|
* @author Evan Prodromou <evan@status.net>
|
||||||
|
* @author Zach Copley <zach@status.net>
|
||||||
|
* @copyright 2009 StatusNet, Inc.
|
||||||
|
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||||
|
* @link http://status.net/
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (!defined('STATUSNET')) {
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
require_once INSTALLDIR . '/lib/apiprivateauth.php';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the string "ok" in the requested format with a 200 OK HTTP status code.
|
||||||
|
*
|
||||||
|
* @category API
|
||||||
|
* @package StatusNet
|
||||||
|
* @author Evan Prodromou <evan@status.net>
|
||||||
|
* @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 ApiHelpTestAction extends ApiPrivateAuthAction
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Take arguments for running
|
||||||
|
*
|
||||||
|
* @param array $args $_REQUEST args
|
||||||
|
*
|
||||||
|
* @return boolean success flag
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
function prepare($args)
|
||||||
|
{
|
||||||
|
parent::prepare($args);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle the request
|
||||||
|
*
|
||||||
|
* @param array $args $_REQUEST data (unused)
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
|
||||||
|
function handle($args)
|
||||||
|
{
|
||||||
|
parent::handle($args);
|
||||||
|
|
||||||
|
if ($this->format == 'xml') {
|
||||||
|
$this->initDocument('xml');
|
||||||
|
$this->element('ok', null, 'true');
|
||||||
|
$this->endDocument('xml');
|
||||||
|
} elseif ($this->format == 'json') {
|
||||||
|
$this->initDocument('json');
|
||||||
|
print '"ok"';
|
||||||
|
$this->endDocument('json');
|
||||||
|
} else {
|
||||||
|
$this->clientError(
|
||||||
|
_('API method not found!'),
|
||||||
|
404,
|
||||||
|
$this->format
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
154
actions/apistatusesdestroy.php
Normal file
154
actions/apistatusesdestroy.php
Normal file
@ -0,0 +1,154 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* StatusNet, the distributed open-source microblogging tool
|
||||||
|
*
|
||||||
|
* Destroy a notice through the API
|
||||||
|
*
|
||||||
|
* PHP version 5
|
||||||
|
*
|
||||||
|
* LICENCE: This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* @category API
|
||||||
|
* @package StatusNet
|
||||||
|
* @author Craig Andrews <candrews@integralblue.com>
|
||||||
|
* @author Evan Prodromou <evan@status.net>
|
||||||
|
* @author Jeffery To <jeffery.to@gmail.com>
|
||||||
|
* @author Tom Blankenship <mac65@mac65.com>
|
||||||
|
* @author Mike Cochrane <mikec@mikenz.geek.nz>
|
||||||
|
* @author Robin Millette <robin@millette.info>
|
||||||
|
* @author Zach Copley <zach@status.net>
|
||||||
|
* @copyright 2009 StatusNet, Inc.
|
||||||
|
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||||
|
* @link http://status.net/
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (!defined('STATUSNET')) {
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
require_once INSTALLDIR . '/lib/apiauth.php';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deletes one of the authenticating user's statuses (notices).
|
||||||
|
*
|
||||||
|
* @category API
|
||||||
|
* @package StatusNet
|
||||||
|
* @author Craig Andrews <candrews@integralblue.com>
|
||||||
|
* @author Evan Prodromou <evan@status.net>
|
||||||
|
* @author Jeffery To <jeffery.to@gmail.com>
|
||||||
|
* @author Tom Blankenship <mac65@mac65.com>
|
||||||
|
* @author Mike Cochrane <mikec@mikenz.geek.nz>
|
||||||
|
* @author Robin Millette <robin@millette.info>
|
||||||
|
* @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 ApiStatusesDestroyAction extends ApiAuthAction
|
||||||
|
{
|
||||||
|
var $status = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Take arguments for running
|
||||||
|
*
|
||||||
|
* @param array $args $_REQUEST args
|
||||||
|
*
|
||||||
|
* @return boolean success flag
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
function prepare($args)
|
||||||
|
{
|
||||||
|
parent::prepare($args);
|
||||||
|
|
||||||
|
$this->user = $this->auth_user;
|
||||||
|
$this->notice_id = (int)$this->trimmed('id');
|
||||||
|
|
||||||
|
if (empty($notice_id)) {
|
||||||
|
$this->notice_id = (int)$this->arg('id');
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->notice = Notice::staticGet((int)$this->notice_id);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle the request
|
||||||
|
*
|
||||||
|
* Delete the notice and all related replies
|
||||||
|
*
|
||||||
|
* @param array $args $_REQUEST data (unused)
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
|
||||||
|
function handle($args)
|
||||||
|
{
|
||||||
|
parent::handle($args);
|
||||||
|
|
||||||
|
if (!in_array($this->format, array('xml', 'json'))) {
|
||||||
|
$this->clientError(_('API method not found!'), $code = 404);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!in_array($_SERVER['REQUEST_METHOD'], array('POST', 'DELETE'))) {
|
||||||
|
$this->clientError(_('This method requires a POST or DELETE.'),
|
||||||
|
400, $this->format);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (empty($this->notice)) {
|
||||||
|
$this->clientError(_('No status found with that ID.'),
|
||||||
|
404, $this->format);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($this->user->id == $this->notice->profile_id) {
|
||||||
|
$replies = new Reply;
|
||||||
|
$replies->get('notice_id', $this->notice_id);
|
||||||
|
$replies->delete();
|
||||||
|
$this->notice->delete();
|
||||||
|
|
||||||
|
if ($this->format == 'xml') {
|
||||||
|
$this->showSingleXmlStatus($this->notice);
|
||||||
|
} elseif ($this->format == 'json') {
|
||||||
|
$this->show_single_json_status($this->notice);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$this->clientError(_('You may not delete another user\'s status.'),
|
||||||
|
403, $this->format);
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->showNotice();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Show the deleted notice
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
|
||||||
|
function showNotice()
|
||||||
|
{
|
||||||
|
if (!empty($this->notice)) {
|
||||||
|
if ($this->format == 'xml') {
|
||||||
|
$this->showSingleXmlStatus($this->notice);
|
||||||
|
} elseif ($this->format == 'json') {
|
||||||
|
$this->show_single_json_status($this->notice);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
206
actions/apistatusesshow.php
Normal file
206
actions/apistatusesshow.php
Normal file
@ -0,0 +1,206 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* StatusNet, the distributed open-source microblogging tool
|
||||||
|
*
|
||||||
|
* Show a notice (as a Twitter-style status)
|
||||||
|
*
|
||||||
|
* 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 Craig Andrews <candrews@integralblue.com>
|
||||||
|
* @author Evan Prodromou <evan@status.net>
|
||||||
|
* @author Jeffery To <jeffery.to@gmail.com>
|
||||||
|
* @author Tom Blankenship <mac65@mac65.com>
|
||||||
|
* @author Mike Cochrane <mikec@mikenz.geek.nz>
|
||||||
|
* @author Robin Millette <robin@millette.info>
|
||||||
|
* @author Zach Copley <zach@status.net>
|
||||||
|
* @copyright 2009 StatusNet, Inc.
|
||||||
|
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||||
|
* @link http://status.net/
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (!defined('STATUSNET')) {
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
require_once INSTALLDIR . '/lib/apiprivateauth.php';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the notice specified by id as a Twitter-style status and inline user
|
||||||
|
*
|
||||||
|
* @category API
|
||||||
|
* @package StatusNet
|
||||||
|
* @author Craig Andrews <candrews@integralblue.com>
|
||||||
|
* @author Evan Prodromou <evan@status.net>
|
||||||
|
* @author Jeffery To <jeffery.to@gmail.com>
|
||||||
|
* @author Tom Blankenship <mac65@mac65.com>
|
||||||
|
* @author Mike Cochrane <mikec@mikenz.geek.nz>
|
||||||
|
* @author Robin Millette <robin@millette.info>
|
||||||
|
* @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 ApiStatusesShowAction extends ApiPrivateAuthAction
|
||||||
|
{
|
||||||
|
|
||||||
|
var $notice_id = null;
|
||||||
|
var $notice = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Take arguments for running
|
||||||
|
*
|
||||||
|
* @param array $args $_REQUEST args
|
||||||
|
*
|
||||||
|
* @return boolean success flag
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
function prepare($args)
|
||||||
|
{
|
||||||
|
parent::prepare($args);
|
||||||
|
|
||||||
|
// 'id' is an undocumented parameter in Twitter's API. Several
|
||||||
|
// clients make use of it, so we support it too.
|
||||||
|
|
||||||
|
// show.json?id=12345 takes precedence over /show/12345.json
|
||||||
|
|
||||||
|
$this->notice_id = (int)$this->trimmed('id');
|
||||||
|
|
||||||
|
if (empty($notice_id)) {
|
||||||
|
$this->notice_id = (int)$this->arg('id');
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->notice = Notice::staticGet((int)$this->notice_id);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle the request
|
||||||
|
*
|
||||||
|
* Check the format and show the notice
|
||||||
|
*
|
||||||
|
* @param array $args $_REQUEST data (unused)
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
|
||||||
|
function handle($args)
|
||||||
|
{
|
||||||
|
parent::handle($args);
|
||||||
|
|
||||||
|
if (!in_array($this->format, array('xml', 'json'))) {
|
||||||
|
$this->clientError(_('API method not found!'), $code = 404);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->showNotice();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Show the notice
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
|
||||||
|
function showNotice()
|
||||||
|
{
|
||||||
|
if (!empty($this->notice)) {
|
||||||
|
if ($this->format == 'xml') {
|
||||||
|
$this->showSingleXmlStatus($this->notice);
|
||||||
|
} elseif ($this->format == 'json') {
|
||||||
|
$this->show_single_json_status($this->notice);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
|
||||||
|
// XXX: Twitter just sets a 404 header and doens't bother
|
||||||
|
// to return an err msg
|
||||||
|
|
||||||
|
$deleted = Deleted_notice::staticGet($this->notice_id);
|
||||||
|
|
||||||
|
if (!empty($deleted)) {
|
||||||
|
$this->clientError(
|
||||||
|
_('Status deleted.'),
|
||||||
|
410,
|
||||||
|
$this->format
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
$this->clientError(
|
||||||
|
_('No status with that ID found.'),
|
||||||
|
404,
|
||||||
|
$this->format
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Is this action read only?
|
||||||
|
*
|
||||||
|
* @param array $args other arguments
|
||||||
|
*
|
||||||
|
* @return boolean true
|
||||||
|
*/
|
||||||
|
|
||||||
|
function isReadOnly($args)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* When was this notice last modified?
|
||||||
|
*
|
||||||
|
* @return string datestamp of the latest notice in the stream
|
||||||
|
*/
|
||||||
|
|
||||||
|
function lastModified()
|
||||||
|
{
|
||||||
|
if (!empty($this->notice)) {
|
||||||
|
return strtotime($this->notice->created);
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An entity tag for this notice
|
||||||
|
*
|
||||||
|
* Returns an Etag based on the action name, language, and
|
||||||
|
* timestamps of the notice
|
||||||
|
*
|
||||||
|
* @return string etag
|
||||||
|
*/
|
||||||
|
|
||||||
|
function etag()
|
||||||
|
{
|
||||||
|
if (!empty($this->notice)) {
|
||||||
|
|
||||||
|
return '"' . implode(
|
||||||
|
':',
|
||||||
|
array($this->arg('action'),
|
||||||
|
common_language(),
|
||||||
|
$this->notice->id,
|
||||||
|
strtotime($this->notice->created))
|
||||||
|
)
|
||||||
|
. '"';
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
295
actions/apistatusesupdate.php
Normal file
295
actions/apistatusesupdate.php
Normal file
@ -0,0 +1,295 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* StatusNet, the distributed open-source microblogging tool
|
||||||
|
*
|
||||||
|
* Post a notice (update your status) through the API
|
||||||
|
*
|
||||||
|
* PHP version 5
|
||||||
|
*
|
||||||
|
* LICENCE: This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* @category API
|
||||||
|
* @package StatusNet
|
||||||
|
* @author Craig Andrews <candrews@integralblue.com>
|
||||||
|
* @author Evan Prodromou <evan@status.net>
|
||||||
|
* @author Jeffery To <jeffery.to@gmail.com>
|
||||||
|
* @author Tom Blankenship <mac65@mac65.com>
|
||||||
|
* @author Mike Cochrane <mikec@mikenz.geek.nz>
|
||||||
|
* @author Robin Millette <robin@millette.info>
|
||||||
|
* @author Zach Copley <zach@status.net>
|
||||||
|
* @copyright 2009 StatusNet, Inc.
|
||||||
|
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||||
|
* @link http://status.net/
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (!defined('STATUSNET')) {
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
require_once INSTALLDIR . '/lib/apiauth.php';
|
||||||
|
require_once INSTALLDIR . '/lib/mediafile.php';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates the authenticating user's status (posts a notice).
|
||||||
|
*
|
||||||
|
* @category API
|
||||||
|
* @package StatusNet
|
||||||
|
* @author Craig Andrews <candrews@integralblue.com>
|
||||||
|
* @author Evan Prodromou <evan@status.net>
|
||||||
|
* @author Jeffery To <jeffery.to@gmail.com>
|
||||||
|
* @author Tom Blankenship <mac65@mac65.com>
|
||||||
|
* @author Mike Cochrane <mikec@mikenz.geek.nz>
|
||||||
|
* @author Robin Millette <robin@millette.info>
|
||||||
|
* @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 ApiStatusesUpdateAction extends ApiAuthAction
|
||||||
|
{
|
||||||
|
var $source = null;
|
||||||
|
var $status = null;
|
||||||
|
var $in_reply_to_status_id = null;
|
||||||
|
var $lat = null;
|
||||||
|
var $lon = null;
|
||||||
|
|
||||||
|
static $reserved_sources = array('web', 'omb', 'mail', 'xmpp', 'api');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Take arguments for running
|
||||||
|
*
|
||||||
|
* @param array $args $_REQUEST args
|
||||||
|
*
|
||||||
|
* @return boolean success flag
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
function prepare($args)
|
||||||
|
{
|
||||||
|
parent::prepare($args);
|
||||||
|
|
||||||
|
$this->user = $this->auth_user;
|
||||||
|
$this->status = $this->trimmed('status');
|
||||||
|
$this->source = $this->trimmed('source');
|
||||||
|
$this->lat = $this->trimmed('lat');
|
||||||
|
$this->lon = $this->trimmed('long');
|
||||||
|
|
||||||
|
if (empty($this->source) || in_array($this->source, self::$reserved_sources)) {
|
||||||
|
$this->source = 'api';
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->in_reply_to_status_id
|
||||||
|
= intval($this->trimmed('in_reply_to_status_id'));
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle the request
|
||||||
|
*
|
||||||
|
* Make a new notice for the update, save it, and show it
|
||||||
|
*
|
||||||
|
* @param array $args $_REQUEST data (unused)
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
|
||||||
|
function handle($args)
|
||||||
|
{
|
||||||
|
parent::handle($args);
|
||||||
|
|
||||||
|
if ($_SERVER['REQUEST_METHOD'] != 'POST') {
|
||||||
|
$this->clientError(
|
||||||
|
_('This method requires a POST.'),
|
||||||
|
400, $this->format
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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.');
|
||||||
|
|
||||||
|
$this->clientError(sprintf($msg, $_SERVER['CONTENT_LENGTH']));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (empty($this->status)) {
|
||||||
|
$this->clientError(
|
||||||
|
'Client must provide a \'status\' parameter with a value.',
|
||||||
|
400,
|
||||||
|
$this->format
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (empty($this->user)) {
|
||||||
|
$this->clientError(_('No such user.'), 404, $this->format);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$status_shortened = common_shorten_links($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.'),
|
||||||
|
Notice::maxContent()
|
||||||
|
),
|
||||||
|
406,
|
||||||
|
$this->format
|
||||||
|
);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check for commands
|
||||||
|
|
||||||
|
$inter = new CommandInterpreter();
|
||||||
|
$cmd = $inter->handle_command($this->user, $status_shortened);
|
||||||
|
|
||||||
|
if ($cmd) {
|
||||||
|
|
||||||
|
if ($this->supported($cmd)) {
|
||||||
|
$cmd->execute(new Channel());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Cmd not supported? Twitter just returns your latest status.
|
||||||
|
// And, it returns your last status whether the cmd was successful
|
||||||
|
// or not!
|
||||||
|
|
||||||
|
$this->notice = $this->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);
|
||||||
|
|
||||||
|
if ($reply) {
|
||||||
|
$reply_to = $this->in_reply_to_status_id;
|
||||||
|
} else {
|
||||||
|
$this->clientError(
|
||||||
|
_('Not found'),
|
||||||
|
$code = 404,
|
||||||
|
$this->format
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$location = null;
|
||||||
|
|
||||||
|
if (!empty($this->lat) && !empty($this->lon)) {
|
||||||
|
$location = Location::fromLatLon($this->lat, $this->lon);
|
||||||
|
}
|
||||||
|
|
||||||
|
$upload = null;
|
||||||
|
|
||||||
|
try {
|
||||||
|
$upload = MediaFile::fromUpload('media', $this->user);
|
||||||
|
} catch (ClientException $ce) {
|
||||||
|
$this->clientError($ce->getMessage());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isset($upload)) {
|
||||||
|
$status_shortened .= ' ' . $upload->shortUrl();
|
||||||
|
|
||||||
|
if (Notice::contentTooLong($status_shortened)) {
|
||||||
|
$upload->delete();
|
||||||
|
$msg = _(
|
||||||
|
'Max notice size is %d chars, ' .
|
||||||
|
'including attachment URL.'
|
||||||
|
);
|
||||||
|
$this->clientError(sprintf($msg, Notice::maxContent()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->notice = Notice::saveNew(
|
||||||
|
$this->user->id,
|
||||||
|
html_entity_decode($status_shortened, ENT_NOQUOTES, 'UTF-8'),
|
||||||
|
$this->source,
|
||||||
|
1,
|
||||||
|
$reply_to,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
empty($location) ? null : $location->lat,
|
||||||
|
empty($location) ? null : $location->lon,
|
||||||
|
empty($location) ? null : $location->location_id,
|
||||||
|
empty($location) ? null : $location->location_ns
|
||||||
|
);
|
||||||
|
|
||||||
|
if (isset($upload)) {
|
||||||
|
$upload->attachToNotice($this->notice);
|
||||||
|
}
|
||||||
|
|
||||||
|
common_broadcast_notice($this->notice);
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->showNotice();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Show the resulting notice
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
|
||||||
|
function showNotice()
|
||||||
|
{
|
||||||
|
if (!empty($this->notice)) {
|
||||||
|
if ($this->format == 'xml') {
|
||||||
|
$this->showSingleXmlStatus($this->notice);
|
||||||
|
} elseif ($this->format == 'json') {
|
||||||
|
$this->show_single_json_status($this->notice);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Is this command supported when doing an update from the API?
|
||||||
|
*
|
||||||
|
* @param string $cmd the command to check for
|
||||||
|
*
|
||||||
|
* @return boolean true or false
|
||||||
|
*/
|
||||||
|
|
||||||
|
function supported($cmd)
|
||||||
|
{
|
||||||
|
static $cmdlist = array('MessageCommand', 'SubCommand', 'UnsubCommand',
|
||||||
|
'FavCommand', 'OnCommand', 'OffCommand');
|
||||||
|
|
||||||
|
if (in_array(get_class($cmd), $cmdlist)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
142
actions/apistatusnetconfig.php
Normal file
142
actions/apistatusnetconfig.php
Normal file
@ -0,0 +1,142 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* StatusNet, the distributed open-source microblogging tool
|
||||||
|
*
|
||||||
|
* Dump of configuration variables
|
||||||
|
*
|
||||||
|
* 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>
|
||||||
|
* @author Zach Copley <zach@status.net>
|
||||||
|
* @copyright 2009 StatusNet, Inc.
|
||||||
|
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||||
|
* @link http://status.net/
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (!defined('STATUSNET')) {
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
require_once INSTALLDIR . '/lib/api.php';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gives a full dump of configuration variables for this instance
|
||||||
|
* of StatusNet, minus variables that may be security-sensitive (like
|
||||||
|
* passwords).
|
||||||
|
* URL: http://identi.ca/api/statusnet/config.(xml|json)
|
||||||
|
* Formats: xml, json
|
||||||
|
*
|
||||||
|
* @category API
|
||||||
|
* @package StatusNet
|
||||||
|
* @author Evan Prodromou <evan@status.net>
|
||||||
|
* @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 ApiStatusnetConfigAction extends ApiAction
|
||||||
|
{
|
||||||
|
var $keys = array(
|
||||||
|
'site' => array('name', 'server', 'theme', 'path', 'fancy', 'language',
|
||||||
|
'email', 'broughtby', 'broughtbyurl', 'closed',
|
||||||
|
'inviteonly', 'private'),
|
||||||
|
'license' => array('url', 'title', 'image'),
|
||||||
|
'nickname' => array('featured'),
|
||||||
|
'throttle' => array('enabled', 'count', 'timespan'),
|
||||||
|
'xmpp' => array('enabled', 'server', 'user')
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Take arguments for running
|
||||||
|
*
|
||||||
|
* @param array $args $_REQUEST args
|
||||||
|
*
|
||||||
|
* @return boolean success flag
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
function prepare($args)
|
||||||
|
{
|
||||||
|
parent::prepare($args);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle the request
|
||||||
|
*
|
||||||
|
* @param array $args $_REQUEST data (unused)
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
|
||||||
|
function handle($args)
|
||||||
|
{
|
||||||
|
parent::handle($args);
|
||||||
|
|
||||||
|
switch ($this->format) {
|
||||||
|
case 'xml':
|
||||||
|
$this->initDocument('xml');
|
||||||
|
$this->elementStart('config');
|
||||||
|
|
||||||
|
// XXX: check that all sections and settings are legal XML elements
|
||||||
|
|
||||||
|
common_debug(var_export($this->keys, true));
|
||||||
|
|
||||||
|
foreach ($this->keys as $section => $settings) {
|
||||||
|
$this->elementStart($section);
|
||||||
|
foreach ($settings as $setting) {
|
||||||
|
$value = common_config($section, $setting);
|
||||||
|
if (is_array($value)) {
|
||||||
|
$value = implode(',', $value);
|
||||||
|
} else if ($value === false) {
|
||||||
|
$value = 'false';
|
||||||
|
} else if ($value === true) {
|
||||||
|
$value = 'true';
|
||||||
|
}
|
||||||
|
$this->element($setting, null, $value);
|
||||||
|
}
|
||||||
|
$this->elementEnd($section);
|
||||||
|
}
|
||||||
|
$this->elementEnd('config');
|
||||||
|
$this->endDocument('xml');
|
||||||
|
break;
|
||||||
|
case 'json':
|
||||||
|
$result = array();
|
||||||
|
foreach ($this->keys as $section => $settings) {
|
||||||
|
$result[$section] = array();
|
||||||
|
foreach ($settings as $setting) {
|
||||||
|
$result[$section][$setting]
|
||||||
|
= common_config($section, $setting);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$this->initDocument('json');
|
||||||
|
$this->showJsonObjects($result);
|
||||||
|
$this->endDocument('json');
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
$this->clientError(
|
||||||
|
_('API method not found!'),
|
||||||
|
404,
|
||||||
|
$this->format
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
102
actions/apistatusnetversion.php
Normal file
102
actions/apistatusnetversion.php
Normal file
@ -0,0 +1,102 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* StatusNet, the distributed open-source microblogging tool
|
||||||
|
*
|
||||||
|
* A version stamp for the API
|
||||||
|
*
|
||||||
|
* PHP version 5
|
||||||
|
*
|
||||||
|
* LICENCE: This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* @category API
|
||||||
|
* @package StatusNet
|
||||||
|
* @author Evan Prodromou <evan@status.net>
|
||||||
|
* @author Zach Copley <zach@status.net>
|
||||||
|
* @copyright 2009 StatusNet, Inc.
|
||||||
|
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||||
|
* @link http://status.net/
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (!defined('STATUSNET')) {
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
require_once INSTALLDIR . '/lib/apiprivateauth.php';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a version number for this version of StatusNet, which
|
||||||
|
* should make things a bit easier for upgrades.
|
||||||
|
* URL: http://identi.ca/api/statusnet/version.(xml|json)
|
||||||
|
* Formats: xml, js
|
||||||
|
*
|
||||||
|
* @category API
|
||||||
|
* @package StatusNet
|
||||||
|
* @author Evan Prodromou <evan@status.net>
|
||||||
|
* @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 ApiStatusnetVersionAction extends ApiPrivateAuthAction
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Take arguments for running
|
||||||
|
*
|
||||||
|
* @param array $args $_REQUEST args
|
||||||
|
*
|
||||||
|
* @return boolean success flag
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
function prepare($args)
|
||||||
|
{
|
||||||
|
parent::prepare($args);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle the request
|
||||||
|
*
|
||||||
|
* @param array $args $_REQUEST data (unused)
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
|
||||||
|
function handle($args)
|
||||||
|
{
|
||||||
|
parent::handle($args);
|
||||||
|
|
||||||
|
switch ($this->format) {
|
||||||
|
case 'xml':
|
||||||
|
$this->initDocument('xml');
|
||||||
|
$this->element('version', null, STATUSNET_VERSION);
|
||||||
|
$this->endDocument('xml');
|
||||||
|
break;
|
||||||
|
case 'json':
|
||||||
|
$this->initDocument('json');
|
||||||
|
print '"'.STATUSNET_VERSION.'"';
|
||||||
|
$this->endDocument('json');
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
$this->clientError(
|
||||||
|
_('API method not found!'),
|
||||||
|
404,
|
||||||
|
$this->format
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
266
actions/apisubscriptions.php
Normal file
266
actions/apisubscriptions.php
Normal file
@ -0,0 +1,266 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* StatusNet, the distributed open-source microblogging tool
|
||||||
|
*
|
||||||
|
* Base class for showing subscription information in the API
|
||||||
|
*
|
||||||
|
* PHP version 5
|
||||||
|
*
|
||||||
|
* LICENCE: This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* @category API
|
||||||
|
* @package StatusNet
|
||||||
|
* @author Dan Moore <dan@moore.cx>
|
||||||
|
* @author Evan Prodromou <evan@status.net>
|
||||||
|
* @author Zach Copley <zach@status.net>
|
||||||
|
* @copyright 2009 StatusNet, Inc.
|
||||||
|
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||||
|
* @link http://status.net/
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (!defined('STATUSNET')) {
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
require_once INSTALLDIR . '/lib/apibareauth.php';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class outputs a list of profiles as Twitter-style user and status objects.
|
||||||
|
* It is used by the API methods /api/statuses/(friends|followers). To support the
|
||||||
|
* social graph methods it also can output a simple list of IDs.
|
||||||
|
*
|
||||||
|
* @category API
|
||||||
|
* @package StatusNet
|
||||||
|
* @author Dan Moore <dan@moore.cx>
|
||||||
|
* @author Evan Prodromou <evan@status.net>
|
||||||
|
* @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 ApiSubscriptionsAction extends ApiBareAuthAction
|
||||||
|
{
|
||||||
|
var $profiles = null;
|
||||||
|
var $tag = null;
|
||||||
|
var $lite = null;
|
||||||
|
var $ids_only = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Take arguments for running
|
||||||
|
*
|
||||||
|
* @param array $args $_REQUEST args
|
||||||
|
*
|
||||||
|
* @return boolean success flag
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
function prepare($args)
|
||||||
|
{
|
||||||
|
parent::prepare($args);
|
||||||
|
|
||||||
|
$this->tag = $this->arg('tag');
|
||||||
|
|
||||||
|
// Note: Twitter no longer supports 'lite'
|
||||||
|
$this->lite = $this->arg('lite');
|
||||||
|
|
||||||
|
$this->ids_only = $this->arg('ids_only');
|
||||||
|
|
||||||
|
// If called as a social graph method, show 5000 per page, otherwise 100
|
||||||
|
|
||||||
|
$this->count = isset($this->ids_only) ?
|
||||||
|
5000 : (int)$this->arg('count', 100);
|
||||||
|
|
||||||
|
$this->user = $this->getTargetUser($this->arg('id'));
|
||||||
|
|
||||||
|
if (empty($this->user)) {
|
||||||
|
$this->clientError(_('No such user.'), 404, $this->format);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->profiles = $this->getProfiles();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle the request
|
||||||
|
*
|
||||||
|
* Show the profiles
|
||||||
|
*
|
||||||
|
* @param array $args $_REQUEST data (unused)
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
|
||||||
|
function handle($args)
|
||||||
|
{
|
||||||
|
parent::handle($args);
|
||||||
|
|
||||||
|
if (!in_array($this->format, array('xml', 'json'))) {
|
||||||
|
$this->clientError(_('API method not found!'), $code = 404);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->initDocument($this->format);
|
||||||
|
|
||||||
|
if (isset($this->ids_only)) {
|
||||||
|
$this->showIds();
|
||||||
|
} else {
|
||||||
|
$this->showProfiles(isset($this->lite) ? false : true);
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->endDocument($this->format);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get profiles - should get overrrided
|
||||||
|
*
|
||||||
|
* @return array Profiles
|
||||||
|
*/
|
||||||
|
|
||||||
|
function getProfiles()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Is this action read only?
|
||||||
|
*
|
||||||
|
* @param array $args other arguments
|
||||||
|
*
|
||||||
|
* @return boolean true
|
||||||
|
*/
|
||||||
|
|
||||||
|
function isReadOnly($args)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* When was this feed last modified?
|
||||||
|
*
|
||||||
|
* @return string datestamp of the latest profile in the stream
|
||||||
|
*/
|
||||||
|
|
||||||
|
function lastModified()
|
||||||
|
{
|
||||||
|
if (!empty($this->profiles) && (count($this->profiles) > 0)) {
|
||||||
|
return strtotime($this->profiles[0]->created);
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An entity tag for this action
|
||||||
|
*
|
||||||
|
* Returns an Etag based on the action name, language, user ID, and
|
||||||
|
* timestamps of the first and last profiles in the subscriptions list
|
||||||
|
* There's also an indicator to show whether this action is being called
|
||||||
|
* as /api/statuses/(friends|followers) or /api/(friends|followers)/ids
|
||||||
|
*
|
||||||
|
* @return string etag
|
||||||
|
*/
|
||||||
|
|
||||||
|
function etag()
|
||||||
|
{
|
||||||
|
if (!empty($this->profiles) && (count($this->profiles) > 0)) {
|
||||||
|
|
||||||
|
$last = count($this->profiles) - 1;
|
||||||
|
|
||||||
|
return '"' . implode(
|
||||||
|
':',
|
||||||
|
array($this->arg('action'),
|
||||||
|
common_language(),
|
||||||
|
$this->user->id,
|
||||||
|
isset($this->ids_only) ? 'IDs' : 'Profiles',
|
||||||
|
strtotime($this->profiles[0]->created),
|
||||||
|
strtotime($this->profiles[$last]->created))
|
||||||
|
)
|
||||||
|
. '"';
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Show the profiles as Twitter-style useres and statuses
|
||||||
|
*
|
||||||
|
* @param boolean $include_statuses Whether to include the latest status
|
||||||
|
* with each user. Default true.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
|
||||||
|
function showProfiles($include_statuses = true)
|
||||||
|
{
|
||||||
|
switch ($this->format) {
|
||||||
|
case 'xml':
|
||||||
|
$this->elementStart('users', array('type' => 'array'));
|
||||||
|
foreach ($this->profiles as $profile) {
|
||||||
|
$this->showProfile(
|
||||||
|
$profile,
|
||||||
|
$this->format,
|
||||||
|
null,
|
||||||
|
$include_statuses
|
||||||
|
);
|
||||||
|
}
|
||||||
|
$this->elementEnd('users');
|
||||||
|
break;
|
||||||
|
case 'json':
|
||||||
|
$arrays = array();
|
||||||
|
foreach ($this->profiles as $profile) {
|
||||||
|
$arrays[] = $this->twitterUserArray(
|
||||||
|
$profile,
|
||||||
|
$include_statuses
|
||||||
|
);
|
||||||
|
}
|
||||||
|
print json_encode($arrays);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
$this->clientError(_('Unsupported format.'));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Show the IDs of the profiles only. 5000 per page. To support
|
||||||
|
* the 'social graph' methods: /api/(friends|followers)/ids
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
|
||||||
|
function showIds()
|
||||||
|
{
|
||||||
|
switch ($this->format) {
|
||||||
|
case 'xml':
|
||||||
|
$this->elementStart('ids');
|
||||||
|
foreach ($this->profiles as $profile) {
|
||||||
|
$this->element('id', null, $profile->id);
|
||||||
|
}
|
||||||
|
$this->elementEnd('ids');
|
||||||
|
break;
|
||||||
|
case 'json':
|
||||||
|
$ids = array();
|
||||||
|
foreach ($this->profiles as $profile) {
|
||||||
|
$ids[] = (int)$profile->id;
|
||||||
|
}
|
||||||
|
print json_encode($ids);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
$this->clientError(_('Unsupported format.'));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
237
actions/apitimelinefavorites.php
Normal file
237
actions/apitimelinefavorites.php
Normal file
@ -0,0 +1,237 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* StatusNet, the distributed open-source microblogging tool
|
||||||
|
*
|
||||||
|
* Show a user's favorite notices
|
||||||
|
*
|
||||||
|
* PHP version 5
|
||||||
|
*
|
||||||
|
* LICENCE: This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* 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 Craig Andrews <candrews@integralblue.com>
|
||||||
|
* @author Evan Prodromou <evan@status.net>
|
||||||
|
* @author Zach Copley <zach@status.net> * @copyright 2009 StatusNet, Inc.
|
||||||
|
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||||
|
* @link http://status.net/
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (!defined('STATUSNET')) {
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
require_once INSTALLDIR.'/lib/apibareauth.php';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the 20 most recent favorite notices for the authenticating user or user
|
||||||
|
* specified by the ID parameter in the requested format.
|
||||||
|
*
|
||||||
|
* @category API
|
||||||
|
* @package StatusNet
|
||||||
|
* @author Craig Andrews <candrews@integralblue.com>
|
||||||
|
* @author Evan Prodromou <evan@status.net>
|
||||||
|
* @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 ApiTimelineFavoritesAction extends ApiBareAuthAction
|
||||||
|
{
|
||||||
|
var $notices = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->notices = $this->getNotices();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle the request
|
||||||
|
*
|
||||||
|
* Just show the notices
|
||||||
|
*
|
||||||
|
* @param array $args $_REQUEST data (unused)
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
|
||||||
|
function handle($args)
|
||||||
|
{
|
||||||
|
parent::handle($args);
|
||||||
|
$this->showTimeline();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Show the timeline of notices
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
|
||||||
|
function showTimeline()
|
||||||
|
{
|
||||||
|
$profile = $this->user->getProfile();
|
||||||
|
|
||||||
|
$sitename = common_config('site', 'name');
|
||||||
|
$title = sprintf(
|
||||||
|
_('%s / Favorites from %s'),
|
||||||
|
$sitename,
|
||||||
|
$this->user->nickname
|
||||||
|
);
|
||||||
|
|
||||||
|
$taguribase = common_config('integration', 'taguri');
|
||||||
|
$id = "tag:$taguribase:Favorites:" . $this->user->id;
|
||||||
|
$link = common_local_url(
|
||||||
|
'favorites',
|
||||||
|
array('nickname' => $this->user->nickname)
|
||||||
|
);
|
||||||
|
$subtitle = sprintf(
|
||||||
|
_('%s updates favorited by %s / %s.'),
|
||||||
|
$sitename,
|
||||||
|
$profile->getBestName(),
|
||||||
|
$this->user->nickname
|
||||||
|
);
|
||||||
|
|
||||||
|
switch($this->format) {
|
||||||
|
case 'xml':
|
||||||
|
$this->showXmlTimeline($this->notices);
|
||||||
|
break;
|
||||||
|
case 'rss':
|
||||||
|
$this->showRssTimeline($this->notices, $title, $link, $subtitle);
|
||||||
|
break;
|
||||||
|
case 'atom':
|
||||||
|
$selfuri = common_root_url() .
|
||||||
|
ltrim($_SERVER['QUERY_STRING'], 'p=');
|
||||||
|
$this->showAtomTimeline(
|
||||||
|
$this->notices, $title, $id, $link, $subtitle,
|
||||||
|
null, $selfuri
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
case 'json':
|
||||||
|
$this->showJsonTimeline($this->notices);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
$this->clientError(_('API method not found!'), $code = 404);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get notices
|
||||||
|
*
|
||||||
|
* @return array notices
|
||||||
|
*/
|
||||||
|
|
||||||
|
function getNotices()
|
||||||
|
{
|
||||||
|
$notices = array();
|
||||||
|
|
||||||
|
if (!empty($this->auth_user) && $this->auth_user->id == $this->user->id) {
|
||||||
|
$notice = $this->user->favoriteNotices(
|
||||||
|
($this->page-1) * $this->count,
|
||||||
|
$this->count,
|
||||||
|
true
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
$notice = $this->user->favoriteNotices(
|
||||||
|
($this->page-1) * $this->count,
|
||||||
|
$this->count,
|
||||||
|
false
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
while ($notice->fetch()) {
|
||||||
|
$notices[] = clone($notice);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $notices;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Is this action read only?
|
||||||
|
*
|
||||||
|
* @param array $args other arguments
|
||||||
|
*
|
||||||
|
* @return boolean true
|
||||||
|
*/
|
||||||
|
|
||||||
|
function isReadOnly($args)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* When was this feed last modified?
|
||||||
|
*
|
||||||
|
* @return string datestamp of the latest notice in the stream
|
||||||
|
*/
|
||||||
|
|
||||||
|
function lastModified()
|
||||||
|
{
|
||||||
|
if (!empty($this->notices) && (count($this->notices) > 0)) {
|
||||||
|
return strtotime($this->notices[0]->created);
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An entity tag for this stream
|
||||||
|
*
|
||||||
|
* Returns an Etag based on the action name, language, user ID, and
|
||||||
|
* timestamps of the first and last notice in the timeline
|
||||||
|
*
|
||||||
|
* @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))
|
||||||
|
)
|
||||||
|
. '"';
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
247
actions/apitimelinefriends.php
Normal file
247
actions/apitimelinefriends.php
Normal file
@ -0,0 +1,247 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* StatusNet, the distributed open-source microblogging tool
|
||||||
|
*
|
||||||
|
* Show the friends timeline
|
||||||
|
*
|
||||||
|
* 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 Craig Andrews <candrews@integralblue.com>
|
||||||
|
* @author Evan Prodromou <evan@status.net>
|
||||||
|
* @author Jeffery To <jeffery.to@gmail.com>
|
||||||
|
* @author mac65 <mac65@mac65.com>
|
||||||
|
* @author Mike Cochrane <mikec@mikenz.geek.nz>
|
||||||
|
* @author Robin Millette <robin@millette.info>
|
||||||
|
* @author Zach Copley <zach@status.net>
|
||||||
|
* @copyright 2009 StatusNet, Inc.
|
||||||
|
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||||
|
* @link http://status.net/
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (!defined('STATUSNET')) {
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
require_once INSTALLDIR . '/lib/apibareauth.php';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the most recent notices (default 20) posted by the target user.
|
||||||
|
* This is the equivalent of 'You and friends' page accessed via Web.
|
||||||
|
*
|
||||||
|
* @category API
|
||||||
|
* @package StatusNet
|
||||||
|
* @author Craig Andrews <candrews@integralblue.com>
|
||||||
|
* @author Evan Prodromou <evan@status.net>
|
||||||
|
* @author Jeffery To <jeffery.to@gmail.com>
|
||||||
|
* @author mac65 <mac65@mac65.com>
|
||||||
|
* @author Mike Cochrane <mikec@mikenz.geek.nz>
|
||||||
|
* @author Robin Millette <robin@millette.info>
|
||||||
|
* @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 ApiTimelineFriendsAction extends ApiBareAuthAction
|
||||||
|
{
|
||||||
|
var $notices = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Take arguments for running
|
||||||
|
*
|
||||||
|
* @param array $args $_REQUEST args
|
||||||
|
*
|
||||||
|
* @return boolean success flag
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
function prepare($args)
|
||||||
|
{
|
||||||
|
parent::prepare($args);
|
||||||
|
common_debug("api friends_timeline");
|
||||||
|
$this->user = $this->getTargetUser($this->arg('id'));
|
||||||
|
|
||||||
|
if (empty($this->user)) {
|
||||||
|
$this->clientError(_('No such user.'), 404, $this->format);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->notices = $this->getNotices();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle the request
|
||||||
|
*
|
||||||
|
* Just show the notices
|
||||||
|
*
|
||||||
|
* @param array $args $_REQUEST data (unused)
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
|
||||||
|
function handle($args)
|
||||||
|
{
|
||||||
|
parent::handle($args);
|
||||||
|
$this->showTimeline();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Show the timeline of notices
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
|
||||||
|
function showTimeline()
|
||||||
|
{
|
||||||
|
$profile = $this->user->getProfile();
|
||||||
|
$sitename = common_config('site', 'name');
|
||||||
|
$title = sprintf(_("%s and friends"), $this->user->nickname);
|
||||||
|
$taguribase = common_config('integration', 'taguri');
|
||||||
|
$id = "tag:$taguribase:FriendsTimeline:" . $this->user->id;
|
||||||
|
$link = common_local_url(
|
||||||
|
'all', array('nickname' => $this->user->nickname)
|
||||||
|
);
|
||||||
|
$subtitle = sprintf(
|
||||||
|
_('Updates from %1$s and friends on %2$s!'),
|
||||||
|
$this->user->nickname, $sitename
|
||||||
|
);
|
||||||
|
|
||||||
|
switch($this->format) {
|
||||||
|
case 'xml':
|
||||||
|
$this->showXmlTimeline($this->notices);
|
||||||
|
break;
|
||||||
|
case 'rss':
|
||||||
|
$this->showRssTimeline($this->notices, $title, $link, $subtitle);
|
||||||
|
break;
|
||||||
|
case 'atom':
|
||||||
|
|
||||||
|
$target_id = $this->arg('id');
|
||||||
|
|
||||||
|
if (isset($target_id)) {
|
||||||
|
$selfuri = common_root_url() .
|
||||||
|
'api/statuses/friends_timeline/' .
|
||||||
|
$target_id . '.atom';
|
||||||
|
} else {
|
||||||
|
$selfuri = common_root_url() .
|
||||||
|
'api/statuses/friends_timeline.atom';
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->showAtomTimeline(
|
||||||
|
$this->notices, $title, $id, $link,
|
||||||
|
$subtitle, null, $selfuri
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
case 'json':
|
||||||
|
$this->showJsonTimeline($this->notices);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
$this->clientError(_('API method not found!'), $code = 404);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get notices
|
||||||
|
*
|
||||||
|
* @return array notices
|
||||||
|
*/
|
||||||
|
|
||||||
|
function getNotices()
|
||||||
|
{
|
||||||
|
$notices = array();
|
||||||
|
|
||||||
|
if (!empty($this->auth_user) && $this->auth_user->id == $this->user->id) {
|
||||||
|
$notice = $this->user->noticeInbox(
|
||||||
|
($this->page-1) * $this->count,
|
||||||
|
$this->count, $this->since_id,
|
||||||
|
$this->max_id, $this->since
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
$notice = $this->user->noticesWithFriends(
|
||||||
|
($this->page-1) * $this->count,
|
||||||
|
$this->count, $this->since_id,
|
||||||
|
$this->max_id, $this->since
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
while ($notice->fetch()) {
|
||||||
|
$notices[] = clone($notice);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $notices;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Is this action read only?
|
||||||
|
*
|
||||||
|
* @param array $args other arguments
|
||||||
|
*
|
||||||
|
* @return boolean true
|
||||||
|
*/
|
||||||
|
|
||||||
|
function isReadOnly($args)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* When was this feed last modified?
|
||||||
|
*
|
||||||
|
* @return string datestamp of the latest notice in the stream
|
||||||
|
*/
|
||||||
|
|
||||||
|
function lastModified()
|
||||||
|
{
|
||||||
|
if (!empty($this->notices) && (count($this->notices) > 0)) {
|
||||||
|
return strtotime($this->notices[0]->created);
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An entity tag for this stream
|
||||||
|
*
|
||||||
|
* Returns an Etag based on the action name, language, user ID, and
|
||||||
|
* timestamps of the first and last notice in the timeline
|
||||||
|
*
|
||||||
|
* @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))
|
||||||
|
)
|
||||||
|
. '"';
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
237
actions/apitimelinegroup.php
Normal file
237
actions/apitimelinegroup.php
Normal file
@ -0,0 +1,237 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* StatusNet, the distributed open-source microblogging tool
|
||||||
|
*
|
||||||
|
* Show a group's notices
|
||||||
|
*
|
||||||
|
* PHP version 5
|
||||||
|
*
|
||||||
|
* LICENCE: This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* 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 Craig Andrews <candrews@integralblue.com>
|
||||||
|
* @author Evan Prodromou <evan@status.net>
|
||||||
|
* @author Jeffery To <jeffery.to@gmail.com>
|
||||||
|
* @author Zach Copley <zach@status.net>
|
||||||
|
* @copyright 2009 StatusNet, Inc.
|
||||||
|
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||||
|
* @link http://status.net/
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (!defined('STATUSNET')) {
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
require_once INSTALLDIR . '/lib/apiprivateauth.php';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the most recent notices (default 20) posted to the group specified by ID
|
||||||
|
*
|
||||||
|
* @category API
|
||||||
|
* @package StatusNet
|
||||||
|
* @author Craig Andrews <candrews@integralblue.com>
|
||||||
|
* @author Evan Prodromou <evan@status.net>
|
||||||
|
* @author Jeffery To <jeffery.to@gmail.com>
|
||||||
|
* @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 ApiTimelineGroupAction extends ApiPrivateAuthAction
|
||||||
|
{
|
||||||
|
|
||||||
|
var $group = null;
|
||||||
|
var $notices = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Take arguments for running
|
||||||
|
*
|
||||||
|
* @param array $args $_REQUEST args
|
||||||
|
*
|
||||||
|
* @return boolean success flag
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
function prepare($args)
|
||||||
|
{
|
||||||
|
parent::prepare($args);
|
||||||
|
|
||||||
|
$this->group = $this->getTargetGroup($this->arg('id'));
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle the request
|
||||||
|
*
|
||||||
|
* Just show the notices
|
||||||
|
*
|
||||||
|
* @param array $args $_REQUEST data (unused)
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
|
||||||
|
function handle($args)
|
||||||
|
{
|
||||||
|
parent::handle($args);
|
||||||
|
|
||||||
|
if (empty($this->group)) {
|
||||||
|
$this->clientError(_('Group not found!'), 404, $this->format);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->notices = $this->getNotices();
|
||||||
|
$this->showTimeline();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Show the timeline of notices
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
|
||||||
|
function showTimeline()
|
||||||
|
{
|
||||||
|
$sitename = common_config('site', 'name');
|
||||||
|
$title = sprintf(_("%s timeline"), $this->group->nickname);
|
||||||
|
$taguribase = common_config('integration', 'taguri');
|
||||||
|
$id = "tag:$taguribase:GroupTimeline:" . $this->group->id;
|
||||||
|
$link = common_local_url(
|
||||||
|
'showgroup',
|
||||||
|
array('nickname' => $this->group->nickname)
|
||||||
|
);
|
||||||
|
$subtitle = sprintf(
|
||||||
|
_('Updates from %1$s on %2$s!'),
|
||||||
|
$this->group->nickname,
|
||||||
|
$sitename
|
||||||
|
);
|
||||||
|
|
||||||
|
switch($this->format) {
|
||||||
|
case 'xml':
|
||||||
|
$this->showXmlTimeline($this->notices);
|
||||||
|
break;
|
||||||
|
case 'rss':
|
||||||
|
$this->showRssTimeline($this->notices, $title, $link, $subtitle);
|
||||||
|
break;
|
||||||
|
case 'atom':
|
||||||
|
$selfuri = common_root_url() .
|
||||||
|
'api/statusnet/groups/timeline/' .
|
||||||
|
$this->group->nickname . '.atom';
|
||||||
|
$this->showAtomTimeline(
|
||||||
|
$this->notices,
|
||||||
|
$title,
|
||||||
|
$id,
|
||||||
|
$link,
|
||||||
|
$subtitle,
|
||||||
|
null,
|
||||||
|
$selfuri
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
case 'json':
|
||||||
|
$this->showJsonTimeline($this->notices);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
$this->clientError(
|
||||||
|
_('API method not found!'),
|
||||||
|
404,
|
||||||
|
$this->format
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get notices
|
||||||
|
*
|
||||||
|
* @return array notices
|
||||||
|
*/
|
||||||
|
|
||||||
|
function getNotices()
|
||||||
|
{
|
||||||
|
$notices = array();
|
||||||
|
|
||||||
|
$notice = $this->group->getNotices(
|
||||||
|
($this->page-1) * $this->count,
|
||||||
|
$this->count,
|
||||||
|
$this->since_id,
|
||||||
|
$this->max_id,
|
||||||
|
$this->since
|
||||||
|
);
|
||||||
|
|
||||||
|
while ($notice->fetch()) {
|
||||||
|
$notices[] = clone($notice);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $notices;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Is this action read only?
|
||||||
|
*
|
||||||
|
* @param array $args other arguments
|
||||||
|
*
|
||||||
|
* @return boolean true
|
||||||
|
*/
|
||||||
|
|
||||||
|
function isReadOnly($args)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* When was this feed last modified?
|
||||||
|
*
|
||||||
|
* @return string datestamp of the latest notice in the stream
|
||||||
|
*/
|
||||||
|
|
||||||
|
function lastModified()
|
||||||
|
{
|
||||||
|
if (!empty($this->notices) && (count($this->notices) > 0)) {
|
||||||
|
return strtotime($this->notices[0]->created);
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An entity tag for this stream
|
||||||
|
*
|
||||||
|
* Returns an Etag based on the action name, language, group ID and
|
||||||
|
* timestamps of the first and last notice in the timeline
|
||||||
|
*
|
||||||
|
* @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->group->id,
|
||||||
|
strtotime($this->notices[0]->created),
|
||||||
|
strtotime($this->notices[$last]->created))
|
||||||
|
)
|
||||||
|
. '"';
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
233
actions/apitimelinementions.php
Normal file
233
actions/apitimelinementions.php
Normal file
@ -0,0 +1,233 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* StatusNet, the distributed open-source microblogging tool
|
||||||
|
*
|
||||||
|
* Show notices mentioning a user (@nickname)
|
||||||
|
*
|
||||||
|
* 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 Craig Andrews <candrews@integralblue.com>
|
||||||
|
* @author Evan Prodromou <evan@status.net>
|
||||||
|
* @author Jeffery To <jeffery.to@gmail.com>
|
||||||
|
* @author mac65 <mac65@mac65.com>
|
||||||
|
* @author Mike Cochrane <mikec@mikenz.geek.nz>
|
||||||
|
* @author Robin Millette <robin@millette.info>
|
||||||
|
* @author Zach Copley <zach@status.net>
|
||||||
|
* @copyright 2009 StatusNet, Inc.
|
||||||
|
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||||
|
* @link http://status.net/
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (!defined('STATUSNET')) {
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
require_once INSTALLDIR . '/lib/apibareauth.php';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the most recent (default 20) mentions (status containing @nickname)
|
||||||
|
*
|
||||||
|
* @category API
|
||||||
|
* @package StatusNet
|
||||||
|
* @author Craig Andrews <candrews@integralblue.com>
|
||||||
|
* @author Evan Prodromou <evan@status.net>
|
||||||
|
* @author Jeffery To <jeffery.to@gmail.com>
|
||||||
|
* @author mac65 <mac65@mac65.com>
|
||||||
|
* @author Mike Cochrane <mikec@mikenz.geek.nz>
|
||||||
|
* @author Robin Millette <robin@millette.info>
|
||||||
|
* @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 ApiTimelineMentionsAction extends ApiBareAuthAction
|
||||||
|
{
|
||||||
|
|
||||||
|
var $notices = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->notices = $this->getNotices();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle the request
|
||||||
|
*
|
||||||
|
* Just show the notices
|
||||||
|
*
|
||||||
|
* @param array $args $_REQUEST data (unused)
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
|
||||||
|
function handle($args)
|
||||||
|
{
|
||||||
|
parent::handle($args);
|
||||||
|
$this->showTimeline();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Show the timeline of notices
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
|
||||||
|
function showTimeline()
|
||||||
|
{
|
||||||
|
$profile = $this->user->getProfile();
|
||||||
|
|
||||||
|
$sitename = common_config('site', 'name');
|
||||||
|
$title = sprintf(
|
||||||
|
_('%1$s / Updates mentioning %2$s'),
|
||||||
|
$sitename, $this->user->nickname
|
||||||
|
);
|
||||||
|
$taguribase = common_config('integration', 'taguri');
|
||||||
|
$id = "tag:$taguribase:Mentions:" . $this->user->id;
|
||||||
|
$link = common_local_url(
|
||||||
|
'replies',
|
||||||
|
array('nickname' => $this->user->nickname)
|
||||||
|
);
|
||||||
|
$subtitle = sprintf(
|
||||||
|
_('%1$s updates that reply to updates from %2$s / %3$s.'),
|
||||||
|
$sitename, $this->user->nickname, $profile->getBestName()
|
||||||
|
);
|
||||||
|
|
||||||
|
switch($this->format) {
|
||||||
|
case 'xml':
|
||||||
|
$this->showXmlTimeline($this->notices);
|
||||||
|
break;
|
||||||
|
case 'rss':
|
||||||
|
$this->showRssTimeline($this->notices, $title, $link, $subtitle);
|
||||||
|
break;
|
||||||
|
case 'atom':
|
||||||
|
$selfuri = common_root_url() .
|
||||||
|
ltrim($_SERVER['QUERY_STRING'], 'p=');
|
||||||
|
$this->showAtomTimeline(
|
||||||
|
$this->notices, $title, $id, $link, $subtitle,
|
||||||
|
null, $selfuri
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
case 'json':
|
||||||
|
$this->showJsonTimeline($this->notices);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
$this->clientError(_('API method not found!'), $code = 404);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get notices
|
||||||
|
*
|
||||||
|
* @return array notices
|
||||||
|
*/
|
||||||
|
|
||||||
|
function getNotices()
|
||||||
|
{
|
||||||
|
$notices = array();
|
||||||
|
|
||||||
|
$notice = $this->user->getReplies(
|
||||||
|
($this->page - 1) * $this->count, $this->count,
|
||||||
|
$this->since_id, $this->max_id, $this->since
|
||||||
|
);
|
||||||
|
|
||||||
|
while ($notice->fetch()) {
|
||||||
|
$notices[] = clone($notice);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $notices;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Is this action read only?
|
||||||
|
*
|
||||||
|
* @param array $args other arguments
|
||||||
|
*
|
||||||
|
* @return boolean true
|
||||||
|
*/
|
||||||
|
|
||||||
|
function isReadOnly($args)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* When was this feed last modified?
|
||||||
|
*
|
||||||
|
* @return string datestamp of the latest notice in the stream
|
||||||
|
*/
|
||||||
|
|
||||||
|
function lastModified()
|
||||||
|
{
|
||||||
|
if (!empty($this->notices) && (count($this->notices) > 0)) {
|
||||||
|
return strtotime($this->notices[0]->created);
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An entity tag for this stream
|
||||||
|
*
|
||||||
|
* Returns an Etag based on the action name, language, user ID, and
|
||||||
|
* timestamps of the first and last notice in the timeline
|
||||||
|
*
|
||||||
|
* @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))
|
||||||
|
)
|
||||||
|
. '"';
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
213
actions/apitimelinepublic.php
Normal file
213
actions/apitimelinepublic.php
Normal file
@ -0,0 +1,213 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* StatusNet, the distributed open-source microblogging tool
|
||||||
|
*
|
||||||
|
* Show the public timeline
|
||||||
|
*
|
||||||
|
* 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 Craig Andrews <candrews@integralblue.com>
|
||||||
|
* @author Evan Prodromou <evan@status.net>
|
||||||
|
* @author Jeffery To <jeffery.to@gmail.com>
|
||||||
|
* @author mac65 <mac65@mac65.com>
|
||||||
|
* @author Mike Cochrane <mikec@mikenz.geek.nz>
|
||||||
|
* @author Robin Millette <robin@millette.info>
|
||||||
|
* @author Zach Copley <zach@status.net>
|
||||||
|
* @copyright 2009 StatusNet, Inc.
|
||||||
|
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||||
|
* @link http://status.net/
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (!defined('STATUSNET')) {
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
require_once INSTALLDIR . '/lib/apiprivateauth.php';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the most recent notices (default 20) posted by everybody
|
||||||
|
*
|
||||||
|
* @category API
|
||||||
|
* @package StatusNet
|
||||||
|
* @author Craig Andrews <candrews@integralblue.com>
|
||||||
|
* @author Evan Prodromou <evan@status.net>
|
||||||
|
* @author Jeffery To <jeffery.to@gmail.com>
|
||||||
|
* @author mac65 <mac65@mac65.com>
|
||||||
|
* @author Mike Cochrane <mikec@mikenz.geek.nz>
|
||||||
|
* @author Robin Millette <robin@millette.info>
|
||||||
|
* @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 ApiTimelinePublicAction extends ApiPrivateAuthAction
|
||||||
|
{
|
||||||
|
|
||||||
|
var $notices = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Take arguments for running
|
||||||
|
*
|
||||||
|
* @param array $args $_REQUEST args
|
||||||
|
*
|
||||||
|
* @return boolean success flag
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
function prepare($args)
|
||||||
|
{
|
||||||
|
parent::prepare($args);
|
||||||
|
|
||||||
|
$this->notices = $this->getNotices();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle the request
|
||||||
|
*
|
||||||
|
* Just show the notices
|
||||||
|
*
|
||||||
|
* @param array $args $_REQUEST data (unused)
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
|
||||||
|
function handle($args)
|
||||||
|
{
|
||||||
|
parent::handle($args);
|
||||||
|
$this->showTimeline();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Show the timeline of notices
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
|
||||||
|
function showTimeline()
|
||||||
|
{
|
||||||
|
$sitename = common_config('site', 'name');
|
||||||
|
$title = sprintf(_("%s public timeline"), $sitename);
|
||||||
|
$taguribase = common_config('integration', 'taguri');
|
||||||
|
$id = "tag:$taguribase:PublicTimeline";
|
||||||
|
$link = common_root_url();
|
||||||
|
$subtitle = sprintf(_("%s updates from everyone!"), $sitename);
|
||||||
|
|
||||||
|
switch($this->format) {
|
||||||
|
case 'xml':
|
||||||
|
$this->showXmlTimeline($this->notices);
|
||||||
|
break;
|
||||||
|
case 'rss':
|
||||||
|
$this->showRssTimeline($this->notices, $title, $link, $subtitle);
|
||||||
|
break;
|
||||||
|
case 'atom':
|
||||||
|
$selfuri = common_root_url() . 'api/statuses/public_timeline.atom';
|
||||||
|
$this->showAtomTimeline(
|
||||||
|
$this->notices, $title, $id, $link,
|
||||||
|
$subtitle, null, $selfuri
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
case 'json':
|
||||||
|
$this->showJsonTimeline($this->notices);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
$this->clientError(_('API method not found!'), $code = 404);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get notices
|
||||||
|
*
|
||||||
|
* @return array notices
|
||||||
|
*/
|
||||||
|
|
||||||
|
function getNotices()
|
||||||
|
{
|
||||||
|
$notices = array();
|
||||||
|
|
||||||
|
$notice = Notice::publicStream(
|
||||||
|
($this->page - 1) * $this->count, $this->count, $this->since_id,
|
||||||
|
$this->max_id, $this->since
|
||||||
|
);
|
||||||
|
|
||||||
|
while ($notice->fetch()) {
|
||||||
|
$notices[] = clone($notice);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $notices;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Is this action read only?
|
||||||
|
*
|
||||||
|
* @param array $args other arguments
|
||||||
|
*
|
||||||
|
* @return boolean true
|
||||||
|
*/
|
||||||
|
|
||||||
|
function isReadOnly($args)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* When was this feed last modified?
|
||||||
|
*
|
||||||
|
* @return string datestamp of the latest notice in the stream
|
||||||
|
*/
|
||||||
|
|
||||||
|
function lastModified()
|
||||||
|
{
|
||||||
|
if (!empty($this->notices) && (count($this->notices) > 0)) {
|
||||||
|
return strtotime($this->notices[0]->created);
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An entity tag for this stream
|
||||||
|
*
|
||||||
|
* Returns an Etag based on the action name, language, and
|
||||||
|
* timestamps of the first and last notice in the timeline
|
||||||
|
*
|
||||||
|
* @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(),
|
||||||
|
strtotime($this->notices[0]->created),
|
||||||
|
strtotime($this->notices[$last]->created))
|
||||||
|
)
|
||||||
|
. '"';
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
224
actions/apitimelinetag.php
Normal file
224
actions/apitimelinetag.php
Normal file
@ -0,0 +1,224 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* StatusNet, the distributed open-source microblogging tool
|
||||||
|
*
|
||||||
|
* Show the latest notices for a given tag
|
||||||
|
*
|
||||||
|
* 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 Craig Andrews <candrews@integralblue.com>
|
||||||
|
* @author Evan Prodromou <evan@status.net>
|
||||||
|
* @author Jeffery To <jeffery.to@gmail.com>
|
||||||
|
* @author Zach Copley <zach@status.net>
|
||||||
|
* @copyright 2009 StatusNet, Inc.
|
||||||
|
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||||
|
* @link http://status.net/
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (!defined('STATUSNET')) {
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
require_once INSTALLDIR . '/lib/apiprivateauth.php';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the 20 most recent notices tagged by a given tag
|
||||||
|
*
|
||||||
|
* @category API
|
||||||
|
* @package StatusNet
|
||||||
|
* @author Craig Andrews <candrews@integralblue.com>
|
||||||
|
* @author Evan Prodromou <evan@status.net>
|
||||||
|
* @author Jeffery To <jeffery.to@gmail.com>
|
||||||
|
* @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 ApiTimelineTagAction extends ApiPrivateAuthAction
|
||||||
|
{
|
||||||
|
|
||||||
|
var $notices = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Take arguments for running
|
||||||
|
*
|
||||||
|
* @param array $args $_REQUEST args
|
||||||
|
*
|
||||||
|
* @return boolean success flag
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
function prepare($args)
|
||||||
|
{
|
||||||
|
parent::prepare($args);
|
||||||
|
|
||||||
|
$this->tag = $this->arg('tag');
|
||||||
|
$this->notices = $this->getNotices();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle the request
|
||||||
|
*
|
||||||
|
* Just show the notices
|
||||||
|
*
|
||||||
|
* @param array $args $_REQUEST data (unused)
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
|
||||||
|
function handle($args)
|
||||||
|
{
|
||||||
|
parent::handle($args);
|
||||||
|
$this->showTimeline();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Show the timeline of notices
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
|
||||||
|
function showTimeline()
|
||||||
|
{
|
||||||
|
$sitename = common_config('site', 'name');
|
||||||
|
$title = sprintf(_("Notices tagged with %s"), $this->tag);
|
||||||
|
$link = common_local_url(
|
||||||
|
'tag',
|
||||||
|
array('tag' => $this->tag)
|
||||||
|
);
|
||||||
|
$subtitle = sprintf(
|
||||||
|
_('Updates tagged with %1$s on %2$s!'),
|
||||||
|
$this->tag,
|
||||||
|
$sitename
|
||||||
|
);
|
||||||
|
$taguribase = common_config('integration', 'taguri');
|
||||||
|
$id = "tag:$taguribase:TagTimeline:".$tag;
|
||||||
|
|
||||||
|
switch($this->format) {
|
||||||
|
case 'xml':
|
||||||
|
$this->showXmlTimeline($this->notices);
|
||||||
|
break;
|
||||||
|
case 'rss':
|
||||||
|
$this->showRssTimeline($this->notices, $title, $link, $subtitle);
|
||||||
|
break;
|
||||||
|
case 'atom':
|
||||||
|
$selfuri = common_root_url() .
|
||||||
|
'api/statusnet/tags/timeline/' .
|
||||||
|
$this->tag . '.atom';
|
||||||
|
$this->showAtomTimeline(
|
||||||
|
$this->notices,
|
||||||
|
$title,
|
||||||
|
$id,
|
||||||
|
$link,
|
||||||
|
$subtitle,
|
||||||
|
null,
|
||||||
|
$selfuri
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
case 'json':
|
||||||
|
$this->showJsonTimeline($this->notices);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
$this->clientError(_('API method not found!'), $code = 404);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get notices
|
||||||
|
*
|
||||||
|
* @return array notices
|
||||||
|
*/
|
||||||
|
|
||||||
|
function getNotices()
|
||||||
|
{
|
||||||
|
$notices = array();
|
||||||
|
|
||||||
|
$notice = Notice_tag::getStream(
|
||||||
|
$this->tag,
|
||||||
|
($this->page - 1) * $this->count,
|
||||||
|
$this->count + 1
|
||||||
|
);
|
||||||
|
|
||||||
|
while ($notice->fetch()) {
|
||||||
|
$notices[] = clone($notice);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $notices;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Is this action read only?
|
||||||
|
*
|
||||||
|
* @param array $args other arguments
|
||||||
|
*
|
||||||
|
* @return boolean true
|
||||||
|
*/
|
||||||
|
|
||||||
|
function isReadOnly($args)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* When was this feed last modified?
|
||||||
|
*
|
||||||
|
* @return string datestamp of the latest notice in the stream
|
||||||
|
*/
|
||||||
|
|
||||||
|
function lastModified()
|
||||||
|
{
|
||||||
|
if (!empty($this->notices) && (count($this->notices) > 0)) {
|
||||||
|
return strtotime($this->notices[0]->created);
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An entity tag for this stream
|
||||||
|
*
|
||||||
|
* Returns an Etag based on the action name, language, and
|
||||||
|
* timestamps of the first and last notice in the timeline
|
||||||
|
*
|
||||||
|
* @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->tag,
|
||||||
|
strtotime($this->notices[0]->created),
|
||||||
|
strtotime($this->notices[$last]->created))
|
||||||
|
)
|
||||||
|
. '"';
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
248
actions/apitimelineuser.php
Normal file
248
actions/apitimelineuser.php
Normal file
@ -0,0 +1,248 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* StatusNet, the distributed open-source microblogging tool
|
||||||
|
*
|
||||||
|
* Show a user's timeline
|
||||||
|
*
|
||||||
|
* 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 Craig Andrews <candrews@integralblue.com>
|
||||||
|
* @author Evan Prodromou <evan@status.net>
|
||||||
|
* @author Jeffery To <jeffery.to@gmail.com>
|
||||||
|
* @author mac65 <mac65@mac65.com>
|
||||||
|
* @author Mike Cochrane <mikec@mikenz.geek.nz>
|
||||||
|
* @author Robin Millette <robin@millette.info>
|
||||||
|
* @author Zach Copley <zach@status.net>
|
||||||
|
* @copyright 2009 StatusNet, Inc.
|
||||||
|
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||||
|
* @link http://status.net/
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (!defined('STATUSNET')) {
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
require_once INSTALLDIR . '/lib/apibareauth.php';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the most recent notices (default 20) posted by the authenticating
|
||||||
|
* user. Another user's timeline can be requested via the id parameter. This
|
||||||
|
* is the API equivalent of the user profile web page.
|
||||||
|
*
|
||||||
|
* @category API
|
||||||
|
* @package StatusNet
|
||||||
|
* @author Craig Andrews <candrews@integralblue.com>
|
||||||
|
* @author Evan Prodromou <evan@status.net>
|
||||||
|
* @author Jeffery To <jeffery.to@gmail.com>
|
||||||
|
* @author mac65 <mac65@mac65.com>
|
||||||
|
* @author Mike Cochrane <mikec@mikenz.geek.nz>
|
||||||
|
* @author Robin Millette <robin@millette.info>
|
||||||
|
* @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 ApiTimelineUserAction extends ApiBareAuthAction
|
||||||
|
{
|
||||||
|
|
||||||
|
var $notices = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->notices = $this->getNotices();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle the request
|
||||||
|
*
|
||||||
|
* Just show the notices
|
||||||
|
*
|
||||||
|
* @param array $args $_REQUEST data (unused)
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
|
||||||
|
function handle($args)
|
||||||
|
{
|
||||||
|
parent::handle($args);
|
||||||
|
$this->showTimeline();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Show the timeline of notices
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
|
||||||
|
function showTimeline()
|
||||||
|
{
|
||||||
|
$profile = $this->user->getProfile();
|
||||||
|
|
||||||
|
$sitename = common_config('site', 'name');
|
||||||
|
$title = sprintf(_("%s timeline"), $this->user->nickname);
|
||||||
|
$taguribase = common_config('integration', 'taguri');
|
||||||
|
$id = "tag:$taguribase:UserTimeline:" . $this->user->id;
|
||||||
|
$link = common_local_url(
|
||||||
|
'showstream',
|
||||||
|
array('nickname' => $this->user->nickname)
|
||||||
|
);
|
||||||
|
$subtitle = sprintf(
|
||||||
|
_('Updates from %1$s on %2$s!'),
|
||||||
|
$this->user->nickname, $sitename
|
||||||
|
);
|
||||||
|
|
||||||
|
// FriendFeed's SUP protocol
|
||||||
|
// Also added RSS and Atom feeds
|
||||||
|
|
||||||
|
$suplink = common_local_url('sup', null, null, $this->user->id);
|
||||||
|
header('X-SUP-ID: ' . $suplink);
|
||||||
|
|
||||||
|
switch($this->format) {
|
||||||
|
case 'xml':
|
||||||
|
$this->showXmlTimeline($this->notices);
|
||||||
|
break;
|
||||||
|
case 'rss':
|
||||||
|
$this->showRssTimeline(
|
||||||
|
$this->notices, $title, $link,
|
||||||
|
$subtitle, $suplink
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
case 'atom':
|
||||||
|
if (isset($apidata['api_arg'])) {
|
||||||
|
$selfuri = common_root_url() .
|
||||||
|
'api/statuses/user_timeline/' .
|
||||||
|
$apidata['api_arg'] . '.atom';
|
||||||
|
} else {
|
||||||
|
$selfuri = common_root_url() .
|
||||||
|
'api/statuses/user_timeline.atom';
|
||||||
|
}
|
||||||
|
$this->showAtomTimeline(
|
||||||
|
$this->notices, $title, $id, $link,
|
||||||
|
$subtitle, $suplink, $selfuri
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
case 'json':
|
||||||
|
$this->showJsonTimeline($this->notices);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
$this->clientError(_('API method not found!'), $code = 404);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get notices
|
||||||
|
*
|
||||||
|
* @return array notices
|
||||||
|
*/
|
||||||
|
|
||||||
|
function getNotices()
|
||||||
|
{
|
||||||
|
$notices = array();
|
||||||
|
|
||||||
|
$notice = $this->user->getNotices(
|
||||||
|
($this->page-1) * $this->count, $this->count,
|
||||||
|
$this->since_id, $this->max_id, $this->since
|
||||||
|
);
|
||||||
|
|
||||||
|
while ($notice->fetch()) {
|
||||||
|
$notices[] = clone($notice);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $notices;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Is this action read only?
|
||||||
|
*
|
||||||
|
* @param array $args other arguments
|
||||||
|
*
|
||||||
|
* @return boolean true
|
||||||
|
*/
|
||||||
|
|
||||||
|
function isReadOnly($args)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* When was this feed last modified?
|
||||||
|
*
|
||||||
|
* @return string datestamp of the latest notice in the stream
|
||||||
|
*/
|
||||||
|
|
||||||
|
function lastModified()
|
||||||
|
{
|
||||||
|
if (!empty($this->notices) && (count($this->notices) > 0)) {
|
||||||
|
return strtotime($this->notices[0]->created);
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An entity tag for this stream
|
||||||
|
*
|
||||||
|
* Returns an Etag based on the action name, language, user ID, and
|
||||||
|
* timestamps of the first and last notice in the timeline
|
||||||
|
*
|
||||||
|
* @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))
|
||||||
|
)
|
||||||
|
. '"';
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
89
actions/apiuserfollowers.php
Normal file
89
actions/apiuserfollowers.php
Normal file
@ -0,0 +1,89 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* StatusNet, the distributed open-source microblogging tool
|
||||||
|
*
|
||||||
|
* Show a user's followers (subscribers)
|
||||||
|
*
|
||||||
|
* 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 Dan Moore <dan@moore.cx>
|
||||||
|
* @author Evan Prodromou <evan@status.net>
|
||||||
|
* @author Zach Copley <zach@status.net>
|
||||||
|
* @copyright 2009 StatusNet, Inc.
|
||||||
|
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||||
|
* @link http://status.net/
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (!defined('STATUSNET')) {
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
require_once INSTALLDIR . '/lib/apibareauth.php';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Ouputs the authenticating user's followers (subscribers), each with
|
||||||
|
* current Twitter-style status inline. They are ordered by the order
|
||||||
|
* in which they subscribed to the user, 100 at a time.
|
||||||
|
*
|
||||||
|
* @category API
|
||||||
|
* @package StatusNet
|
||||||
|
* @author Dan Moore <dan@moore.cx>
|
||||||
|
* @author Evan Prodromou <evan@status.net>
|
||||||
|
* @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 ApiUserFollowersAction extends ApiSubscriptionsAction
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Get the user's subscribers (followers) as an array of profiles
|
||||||
|
*
|
||||||
|
* @return array Profiles
|
||||||
|
*/
|
||||||
|
|
||||||
|
function getProfiles()
|
||||||
|
{
|
||||||
|
$offset = ($this->page - 1) * $this->count;
|
||||||
|
$limit = $this->count + 1;
|
||||||
|
|
||||||
|
$subs = null;
|
||||||
|
|
||||||
|
if (isset($this->tag)) {
|
||||||
|
$subs = $this->user->getTaggedSubscribers(
|
||||||
|
$this->tag, $offset, $limit
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
$subs = $this->user->getSubscribers(
|
||||||
|
$offset,
|
||||||
|
$limit
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
$profiles = array();
|
||||||
|
|
||||||
|
if (!empty($subs)) {
|
||||||
|
while ($subs->fetch()) {
|
||||||
|
$profiles[] = clone($subs);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $profiles;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
89
actions/apiuserfriends.php
Normal file
89
actions/apiuserfriends.php
Normal file
@ -0,0 +1,89 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* StatusNet, the distributed open-source microblogging tool
|
||||||
|
*
|
||||||
|
* Show a user's friends (subscriptions)
|
||||||
|
*
|
||||||
|
* 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 Dan Moore <dan@moore.cx>
|
||||||
|
* @author Evan Prodromou <evan@status.net>
|
||||||
|
* @author Zach Copley <zach@status.net>
|
||||||
|
* @copyright 2009 StatusNet, Inc.
|
||||||
|
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||||
|
* @link http://status.net/
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (!defined('STATUSNET')) {
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
require_once INSTALLDIR . '/lib/apibareauth.php';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Ouputs the authenticating user's friends (subscriptions), each with
|
||||||
|
* current Twitter-style status inline. They are ordered by the date
|
||||||
|
* in which the user subscribed to them, 100 at a time.
|
||||||
|
*
|
||||||
|
* @category API
|
||||||
|
* @package StatusNet
|
||||||
|
* @author Dan Moore <dan@moore.cx>
|
||||||
|
* @author Evan Prodromou <evan@status.net>
|
||||||
|
* @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 ApiUserFriendsAction extends ApiSubscriptionsAction
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Get the user's subscriptions (friends) as an array of profiles
|
||||||
|
*
|
||||||
|
* @return array Profiles
|
||||||
|
*/
|
||||||
|
|
||||||
|
function getProfiles()
|
||||||
|
{
|
||||||
|
$offset = ($this->page - 1) * $this->count;
|
||||||
|
$limit = $this->count + 1;
|
||||||
|
|
||||||
|
$subs = null;
|
||||||
|
|
||||||
|
if (isset($this->tag)) {
|
||||||
|
$subs = $this->user->getTaggedSubscriptions(
|
||||||
|
$this->tag, $offset, $limit
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
$subs = $this->user->getSubscriptions(
|
||||||
|
$offset,
|
||||||
|
$limit
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
$profiles = array();
|
||||||
|
|
||||||
|
if (!empty($subs)) {
|
||||||
|
while ($subs->fetch()) {
|
||||||
|
$profiles[] = clone($subs);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $profiles;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
126
actions/apiusershow.php
Normal file
126
actions/apiusershow.php
Normal file
@ -0,0 +1,126 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* StatusNet, the distributed open-source microblogging tool
|
||||||
|
*
|
||||||
|
* Show a user's profile information
|
||||||
|
*
|
||||||
|
* 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 Dan Moore <dan@moore.cx>
|
||||||
|
* @author Evan Prodromou <evan@status.net>
|
||||||
|
* @author mac65 <mac65@mac65.com>
|
||||||
|
* @author Zach Copley <zach@status.net>
|
||||||
|
* @copyright 2009 StatusNet, Inc.
|
||||||
|
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||||
|
* @link http://status.net/
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (!defined('STATUSNET')) {
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
require_once INSTALLDIR . '/lib/apiprivateauth.php';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Ouputs information for a user, specified by ID or screen name.
|
||||||
|
* The user's most recent status will be returned inline.
|
||||||
|
*
|
||||||
|
* @category API
|
||||||
|
* @package StatusNet
|
||||||
|
* @author Dan Moore <dan@moore.cx>
|
||||||
|
* @author Evan Prodromou <evan@status.net>
|
||||||
|
* @author mac65 <mac65@mac65.com>
|
||||||
|
* @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 ApiUserShowAction extends ApiPrivateAuthAction
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Take arguments for running
|
||||||
|
*
|
||||||
|
* @param array $args $_REQUEST args
|
||||||
|
*
|
||||||
|
* @return boolean success flag
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
function prepare($args)
|
||||||
|
{
|
||||||
|
parent::prepare($args);
|
||||||
|
|
||||||
|
$email = $this->arg('email');
|
||||||
|
|
||||||
|
// XXX: email field deprecated in Twitter's API
|
||||||
|
|
||||||
|
if (!empty($email)) {
|
||||||
|
$this->user = User::staticGet('email', $email);
|
||||||
|
} else {
|
||||||
|
$this->user = $this->getTargetUser($this->arg('id'));
|
||||||
|
}
|
||||||
|
|
||||||
|
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)) {
|
||||||
|
$this->clientError(_('Not found.'), 404, $this->format);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!in_array($this->format, array('xml', 'json'))) {
|
||||||
|
$this->clientError(_('API method not found!'), $code = 404);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$profile = $this->user->getProfile();
|
||||||
|
|
||||||
|
if (empty($profile)) {
|
||||||
|
$this->clientError(_('User has no profile.'));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$twitter_user = $this->twitterUserArray($this->user->getProfile(), true);
|
||||||
|
|
||||||
|
if ($this->format == 'xml') {
|
||||||
|
$this->initDocument('xml');
|
||||||
|
$this->showTwitterXmlUser($twitter_user);
|
||||||
|
$this->endDocument('xml');
|
||||||
|
} elseif ($this->format == 'json') {
|
||||||
|
$this->initDocument('json');
|
||||||
|
$this->showJsonObjects($twitter_user);
|
||||||
|
$this->endDocument('json');
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -244,11 +244,25 @@ class AvatarsettingsAction extends AccountSettingsAction
|
|||||||
|
|
||||||
function handlePost()
|
function handlePost()
|
||||||
{
|
{
|
||||||
|
// 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.');
|
||||||
|
|
||||||
|
$this->showForm(sprintf($msg, $_SERVER['CONTENT_LENGTH']));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// CSRF protection
|
// CSRF protection
|
||||||
|
|
||||||
$token = $this->trimmed('token');
|
$token = $this->trimmed('token');
|
||||||
if (!$token || $token != common_session_token()) {
|
if (!$token || $token != common_session_token()) {
|
||||||
$this->show_form(_('There was a problem with your session token. '.
|
$this->showForm(_('There was a problem with your session token. '.
|
||||||
'Try again, please.'));
|
'Try again, please.'));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -42,9 +42,11 @@ if (!defined('STATUSNET') && !defined('LACONICA')) {
|
|||||||
* @license http://www.fsf.org/licensing/licenses/agpl.html AGPLv3
|
* @license http://www.fsf.org/licensing/licenses/agpl.html AGPLv3
|
||||||
* @link http://status.net/
|
* @link http://status.net/
|
||||||
*/
|
*/
|
||||||
class BlockAction extends Action
|
|
||||||
|
class BlockAction extends ProfileFormAction
|
||||||
{
|
{
|
||||||
var $profile = null;
|
var $profile = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Take arguments for running
|
* Take arguments for running
|
||||||
*
|
*
|
||||||
@ -52,28 +54,22 @@ class BlockAction extends Action
|
|||||||
*
|
*
|
||||||
* @return boolean success flag
|
* @return boolean success flag
|
||||||
*/
|
*/
|
||||||
|
|
||||||
function prepare($args)
|
function prepare($args)
|
||||||
{
|
{
|
||||||
parent::prepare($args);
|
if (!parent::prepare($args)) {
|
||||||
if (!common_logged_in()) {
|
|
||||||
$this->clientError(_('Not logged in.'));
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
$token = $this->trimmed('token');
|
|
||||||
if (!$token || $token != common_session_token()) {
|
$cur = common_current_user();
|
||||||
$this->clientError(_('There was a problem with your session token. Try again, please.'));
|
|
||||||
return;
|
assert(!empty($cur)); // checked by parent
|
||||||
}
|
|
||||||
$id = $this->trimmed('blockto');
|
if ($cur->hasBlocked($this->profile)) {
|
||||||
if (!$id) {
|
$this->clientError(_("You already blocked that user."));
|
||||||
$this->clientError(_('No profile specified.'));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
$this->profile = Profile::staticGet('id', $id);
|
|
||||||
if (!$this->profile) {
|
|
||||||
$this->clientError(_('No profile with that ID.'));
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -86,18 +82,16 @@ class BlockAction extends Action
|
|||||||
*
|
*
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
|
|
||||||
function handle($args)
|
function handle($args)
|
||||||
{
|
{
|
||||||
parent::handle($args);
|
|
||||||
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
|
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
|
||||||
if ($this->arg('no')) {
|
if ($this->arg('no')) {
|
||||||
$cur = common_current_user();
|
$this->returnToArgs();
|
||||||
$other = Profile::staticGet('id', $this->arg('blockto'));
|
|
||||||
common_redirect(common_local_url('showstream', array('nickname' => $other->nickname)),
|
|
||||||
303);
|
|
||||||
} elseif ($this->arg('yes')) {
|
} elseif ($this->arg('yes')) {
|
||||||
$this->blockProfile();
|
$this->handlePost();
|
||||||
} elseif ($this->arg('blockto')) {
|
$this->returnToArgs();
|
||||||
|
} else {
|
||||||
$this->showPage();
|
$this->showPage();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -138,7 +132,7 @@ class BlockAction extends Action
|
|||||||
'unable to subscribe to you in the future, and '.
|
'unable to subscribe to you in the future, and '.
|
||||||
'you will not be notified of any @-replies from them.'));
|
'you will not be notified of any @-replies from them.'));
|
||||||
$this->element('input', array('id' => 'blockto-' . $id,
|
$this->element('input', array('id' => 'blockto-' . $id,
|
||||||
'name' => 'blockto',
|
'name' => 'profileid',
|
||||||
'type' => 'hidden',
|
'type' => 'hidden',
|
||||||
'value' => $id));
|
'value' => $id));
|
||||||
foreach ($this->args as $k => $v) {
|
foreach ($this->args as $k => $v) {
|
||||||
@ -146,8 +140,8 @@ class BlockAction extends Action
|
|||||||
$this->hidden($k, $v);
|
$this->hidden($k, $v);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$this->submit('form_action-no', _('No'), 'submit form_action-primary', 'no', _("Do not block this user from this group"));
|
$this->submit('form_action-no', _('No'), 'submit form_action-primary', 'no', _("Do not block this user"));
|
||||||
$this->submit('form_action-yes', _('Yes'), 'submit form_action-secondary', 'yes', _('Block this user from this group'));
|
$this->submit('form_action-yes', _('Yes'), 'submit form_action-secondary', 'yes', _('Block this user'));
|
||||||
$this->elementEnd('fieldset');
|
$this->elementEnd('fieldset');
|
||||||
$this->elementEnd('form');
|
$this->elementEnd('form');
|
||||||
}
|
}
|
||||||
@ -157,36 +151,17 @@ class BlockAction extends Action
|
|||||||
*
|
*
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
function blockProfile()
|
|
||||||
|
function handlePost()
|
||||||
{
|
{
|
||||||
$cur = common_current_user();
|
$cur = common_current_user();
|
||||||
|
|
||||||
if ($cur->hasBlocked($this->profile)) {
|
|
||||||
$this->clientError(_('You have already blocked this user.'));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
$result = $cur->block($this->profile);
|
$result = $cur->block($this->profile);
|
||||||
|
|
||||||
if (!$result) {
|
if (!$result) {
|
||||||
$this->serverError(_('Failed to save block information.'));
|
$this->serverError(_('Failed to save block information.'));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Now, gotta figure where we go back to
|
|
||||||
foreach ($this->args as $k => $v) {
|
|
||||||
if ($k == 'returnto-action') {
|
|
||||||
$action = $v;
|
|
||||||
} elseif (substr($k, 0, 9) == 'returnto-') {
|
|
||||||
$args[substr($k, 9)] = $v;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($action) {
|
|
||||||
common_redirect(common_local_url($action, $args), 303);
|
|
||||||
} else {
|
|
||||||
common_redirect(common_local_url('subscribers',
|
|
||||||
array('nickname' => $cur->nickname)),
|
|
||||||
303);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
75
actions/bookmarklet.php
Normal file
75
actions/bookmarklet.php
Normal file
@ -0,0 +1,75 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* StatusNet, the distributed open-source microblogging tool
|
||||||
|
*
|
||||||
|
* Handler for posting new notices
|
||||||
|
*
|
||||||
|
* PHP version 5
|
||||||
|
*
|
||||||
|
* LICENCE: This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* 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 Bookmarklet
|
||||||
|
* @package StatusNet
|
||||||
|
* @author Sarven Capadisli <csarven@status.net>
|
||||||
|
* @copyright 2008-2009 StatusNet, Inc.
|
||||||
|
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||||
|
* @link http://status.net/
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (!defined('STATUSNET') && !defined('LACONICA')) {
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
require_once INSTALLDIR . '/actions/newnotice.php';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Action for posting a notice
|
||||||
|
*
|
||||||
|
* @category Bookmarklet
|
||||||
|
* @package StatusNet
|
||||||
|
* @author Sarven Capadisli <csarven@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 BookmarkletAction extends NewnoticeAction
|
||||||
|
{
|
||||||
|
function showTitle()
|
||||||
|
{
|
||||||
|
$this->element('title', null, _('Post to ').common_config('site', 'name'));
|
||||||
|
}
|
||||||
|
|
||||||
|
function showHeader()
|
||||||
|
{
|
||||||
|
$this->elementStart('div', array('id' => 'header'));
|
||||||
|
$this->elementStart('address');
|
||||||
|
$this->element('a', array('class' => 'url',
|
||||||
|
'href' => common_local_url('public')),
|
||||||
|
'');
|
||||||
|
$this->elementEnd('address');
|
||||||
|
if (common_logged_in()) {
|
||||||
|
$this->showNoticeForm();
|
||||||
|
}
|
||||||
|
$this->elementEnd('div');
|
||||||
|
}
|
||||||
|
|
||||||
|
function showCore()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
function showFooter()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -67,11 +67,7 @@ class ConfirmaddressAction extends Action
|
|||||||
parent::handle($args);
|
parent::handle($args);
|
||||||
if (!common_logged_in()) {
|
if (!common_logged_in()) {
|
||||||
common_set_returnto($this->selfUrl());
|
common_set_returnto($this->selfUrl());
|
||||||
if (!common_config('site', 'openidonly')) {
|
common_redirect(common_local_url('login'));
|
||||||
common_redirect(common_local_url('login'));
|
|
||||||
} else {
|
|
||||||
common_redirect(common_local_url('openidlogin'));
|
|
||||||
}
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
$code = $this->trimmed('code');
|
$code = $this->trimmed('code');
|
||||||
|
@ -32,15 +32,45 @@ if (!defined('STATUSNET') && !defined('LACONICA')) {
|
|||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
require_once INSTALLDIR.'/lib/deleteaction.php';
|
class DeletenoticeAction extends Action
|
||||||
|
|
||||||
class DeletenoticeAction extends DeleteAction
|
|
||||||
{
|
{
|
||||||
var $error = null;
|
var $error = null;
|
||||||
|
var $user = null;
|
||||||
|
var $notice = null;
|
||||||
|
var $profile = null;
|
||||||
|
var $user_profile = null;
|
||||||
|
|
||||||
|
function prepare($args)
|
||||||
|
{
|
||||||
|
parent::prepare($args);
|
||||||
|
|
||||||
|
$this->user = common_current_user();
|
||||||
|
$notice_id = $this->trimmed('notice');
|
||||||
|
$this->notice = Notice::staticGet($notice_id);
|
||||||
|
|
||||||
|
if (!$this->notice) {
|
||||||
|
common_user_error(_('No such notice.'));
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->profile = $this->notice->getProfile();
|
||||||
|
$this->user_profile = $this->user->getProfile();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
function handle($args)
|
function handle($args)
|
||||||
{
|
{
|
||||||
parent::handle($args);
|
parent::handle($args);
|
||||||
|
|
||||||
|
if (!common_logged_in()) {
|
||||||
|
common_user_error(_('Not logged in.'));
|
||||||
|
exit;
|
||||||
|
} else if ($this->notice->profile_id != $this->user_profile->id &&
|
||||||
|
!$this->user->hasRight(Right::DELETEOTHERSNOTICE)) {
|
||||||
|
common_user_error(_('Can\'t delete this notice.'));
|
||||||
|
exit;
|
||||||
|
}
|
||||||
// XXX: Ajax!
|
// XXX: Ajax!
|
||||||
|
|
||||||
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
|
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
|
||||||
|
164
actions/deleteuser.php
Normal file
164
actions/deleteuser.php
Normal file
@ -0,0 +1,164 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* StatusNet, the distributed open-source microblogging tool
|
||||||
|
*
|
||||||
|
* Action class to delete 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 Action
|
||||||
|
* @package StatusNet
|
||||||
|
* @author Evan Prodromou <evan@status.net>
|
||||||
|
* @copyright 2009 StatusNet, Inc.
|
||||||
|
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||||
|
* @link http://status.net/
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (!defined('STATUSNET') && !defined('LACONICA')) {
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delete a user
|
||||||
|
*
|
||||||
|
* @category Action
|
||||||
|
* @package StatusNet
|
||||||
|
* @author Evan Prodromou <evan@status.net>
|
||||||
|
* @license http://www.fsf.org/licensing/licenses/agpl.html AGPLv3
|
||||||
|
* @link http://status.net/
|
||||||
|
*/
|
||||||
|
|
||||||
|
class DeleteuserAction extends ProfileFormAction
|
||||||
|
{
|
||||||
|
var $user = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Take arguments for running
|
||||||
|
*
|
||||||
|
* @param array $args $_REQUEST args
|
||||||
|
*
|
||||||
|
* @return boolean success flag
|
||||||
|
*/
|
||||||
|
|
||||||
|
function prepare($args)
|
||||||
|
{
|
||||||
|
if (!parent::prepare($args)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$cur = common_current_user();
|
||||||
|
|
||||||
|
assert(!empty($cur)); // checked by parent
|
||||||
|
|
||||||
|
if (!$cur->hasRight(Right::DELETEUSER)) {
|
||||||
|
$this->clientError(_("You cannot delete users."));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->user = User::staticGet('id', $this->profile->id);
|
||||||
|
|
||||||
|
if (empty($this->user)) {
|
||||||
|
$this->clientError(_("You can only delete local users."));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle request
|
||||||
|
*
|
||||||
|
* Shows a page with list of favorite notices
|
||||||
|
*
|
||||||
|
* @param array $args $_REQUEST args; handled in prepare()
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
|
||||||
|
function handle($args)
|
||||||
|
{
|
||||||
|
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
|
||||||
|
if ($this->arg('no')) {
|
||||||
|
$this->returnToArgs();
|
||||||
|
} elseif ($this->arg('yes')) {
|
||||||
|
$this->handlePost();
|
||||||
|
$this->returnToArgs();
|
||||||
|
} else {
|
||||||
|
$this->showPage();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function showContent() {
|
||||||
|
$this->areYouSureForm();
|
||||||
|
}
|
||||||
|
|
||||||
|
function title() {
|
||||||
|
return _('Delete user');
|
||||||
|
}
|
||||||
|
|
||||||
|
function showNoticeForm() {
|
||||||
|
// nop
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Confirm with user.
|
||||||
|
*
|
||||||
|
* Shows a confirmation form.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
function areYouSureForm()
|
||||||
|
{
|
||||||
|
$id = $this->profile->id;
|
||||||
|
$this->elementStart('form', array('id' => 'deleteuser-' . $id,
|
||||||
|
'method' => 'post',
|
||||||
|
'class' => 'form_settings form_entity_block',
|
||||||
|
'action' => common_local_url('deleteuser')));
|
||||||
|
$this->elementStart('fieldset');
|
||||||
|
$this->hidden('token', common_session_token());
|
||||||
|
$this->element('legend', _('Delete user'));
|
||||||
|
$this->element('p', null,
|
||||||
|
_('Are you sure you want to delete this user? '.
|
||||||
|
'This will clear all data about the user from the '.
|
||||||
|
'database, without a backup.'));
|
||||||
|
$this->element('input', array('id' => 'deleteuserto-' . $id,
|
||||||
|
'name' => 'profileid',
|
||||||
|
'type' => 'hidden',
|
||||||
|
'value' => $id));
|
||||||
|
foreach ($this->args as $k => $v) {
|
||||||
|
if (substr($k, 0, 9) == 'returnto-') {
|
||||||
|
$this->hidden($k, $v);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$this->submit('form_action-no', _('No'), 'submit form_action-primary', 'no', _("Do not block this user"));
|
||||||
|
$this->submit('form_action-yes', _('Yes'), 'submit form_action-secondary', 'yes', _('Delete this user'));
|
||||||
|
$this->elementEnd('fieldset');
|
||||||
|
$this->elementEnd('form');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Actually delete a user.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
|
||||||
|
function handlePost()
|
||||||
|
{
|
||||||
|
$this->user->delete();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
585
actions/designadminpanel.php
Normal file
585
actions/designadminpanel.php
Normal file
@ -0,0 +1,585 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* StatusNet, the distributed open-source microblogging tool
|
||||||
|
*
|
||||||
|
* Design 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 Evan Prodromou <evan@status.net>
|
||||||
|
* @author Zach Copley <zach@status.net>
|
||||||
|
* @author Sarven Capadisli <csarven@status.net>
|
||||||
|
* @copyright 2008-2009 StatusNet, Inc.
|
||||||
|
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||||
|
* @link http://status.net/
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (!defined('STATUSNET')) {
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Administer design settings
|
||||||
|
*
|
||||||
|
* @category Admin
|
||||||
|
* @package StatusNet
|
||||||
|
* @author Evan Prodromou <evan@status.net>
|
||||||
|
* @author Zach Copley <zach@status.net>
|
||||||
|
* @author Sarven Capadisli <csarven@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 DesignadminpanelAction extends AdminPanelAction
|
||||||
|
{
|
||||||
|
|
||||||
|
/* The default site design */
|
||||||
|
var $design = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the page title
|
||||||
|
*
|
||||||
|
* @return string page title
|
||||||
|
*/
|
||||||
|
|
||||||
|
function title()
|
||||||
|
{
|
||||||
|
return _('Design');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Instructions for using this form.
|
||||||
|
*
|
||||||
|
* @return string instructions
|
||||||
|
*/
|
||||||
|
|
||||||
|
function getInstructions()
|
||||||
|
{
|
||||||
|
return _('Design settings for this StatusNet site.');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the default design and show the design admin panel form
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
|
||||||
|
function showForm()
|
||||||
|
{
|
||||||
|
$this->design = Design::siteDesign();
|
||||||
|
$form = new DesignAdminPanelForm($this);
|
||||||
|
$form->show();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Save settings from the form
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
|
||||||
|
function saveSettings()
|
||||||
|
{
|
||||||
|
if ($this->arg('save')) {
|
||||||
|
$this->saveDesignSettings();
|
||||||
|
} else if ($this->arg('defaults')) {
|
||||||
|
$this->restoreDefaults();
|
||||||
|
} else {
|
||||||
|
$this->clientError(_('Unexpected form submission.'));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Save the new design settings
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
|
||||||
|
function saveDesignSettings()
|
||||||
|
{
|
||||||
|
// 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.');
|
||||||
|
$this->clientException(sprintf($msg, $_SERVER['CONTENT_LENGTH']));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// check for an image upload
|
||||||
|
|
||||||
|
$bgimage = $this->saveBackgroundImage();
|
||||||
|
|
||||||
|
common_debug("background image: $bgimage");
|
||||||
|
|
||||||
|
static $settings = array('theme', 'logo');
|
||||||
|
|
||||||
|
$values = array();
|
||||||
|
|
||||||
|
foreach ($settings as $setting) {
|
||||||
|
$values[$setting] = $this->trimmed($setting);
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->validate($values);
|
||||||
|
|
||||||
|
// assert(all values are valid);
|
||||||
|
|
||||||
|
$bgcolor = new WebColor($this->trimmed('design_background'));
|
||||||
|
$ccolor = new WebColor($this->trimmed('design_content'));
|
||||||
|
$sbcolor = new WebColor($this->trimmed('design_sidebar'));
|
||||||
|
$tcolor = new WebColor($this->trimmed('design_text'));
|
||||||
|
$lcolor = new WebColor($this->trimmed('design_links'));
|
||||||
|
|
||||||
|
$onoff = $this->arg('design_background-image_onoff');
|
||||||
|
|
||||||
|
$on = false;
|
||||||
|
$off = false;
|
||||||
|
|
||||||
|
if ($onoff == 'on') {
|
||||||
|
$on = true;
|
||||||
|
} else {
|
||||||
|
$off = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
$tile = $this->boolean('design_background-image_repeat');
|
||||||
|
|
||||||
|
$config = new Config();
|
||||||
|
|
||||||
|
$config->query('BEGIN');
|
||||||
|
|
||||||
|
foreach ($settings as $setting) {
|
||||||
|
Config::save('site', $setting, $values[$setting]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isset($bgimage)) {
|
||||||
|
Config::save('design', 'backgroundimage', $bgimage);
|
||||||
|
}
|
||||||
|
|
||||||
|
Config::save('design', 'backgroundcolor', $bgcolor->intValue());
|
||||||
|
Config::save('design', 'contentcolor', $ccolor->intValue());
|
||||||
|
Config::save('design', 'sidebarcolor', $sbcolor->intValue());
|
||||||
|
Config::save('design', 'textcolor', $tcolor->intValue());
|
||||||
|
Config::save('design', 'linkcolor', $lcolor->intValue());
|
||||||
|
|
||||||
|
// Hack to use Design's bit setter
|
||||||
|
$scratch = new Design();
|
||||||
|
$scratch->setDisposition($on, $off, $tile);
|
||||||
|
|
||||||
|
Config::save('design', 'disposition', $scratch->disposition);
|
||||||
|
|
||||||
|
$config->query('COMMIT');
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Restore the default design
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
|
||||||
|
function restoreDefaults()
|
||||||
|
{
|
||||||
|
$this->deleteSetting('site', 'logo');
|
||||||
|
$this->deleteSetting('site', 'theme');
|
||||||
|
|
||||||
|
$settings = array(
|
||||||
|
'theme', 'backgroundimage', 'backgroundcolor', 'contentcolor',
|
||||||
|
'sidebarcolor', 'textcolor', 'linkcolor', 'disposition'
|
||||||
|
);
|
||||||
|
|
||||||
|
foreach ($settings as $setting) {
|
||||||
|
$this->deleteSetting('design', $setting);
|
||||||
|
}
|
||||||
|
|
||||||
|
// XXX: Should we restore the default dir settings, etc.? --Z
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Save the background image if the user uploaded one
|
||||||
|
*
|
||||||
|
* @return string $filename the filename of the image
|
||||||
|
*/
|
||||||
|
|
||||||
|
function saveBackgroundImage()
|
||||||
|
{
|
||||||
|
$filename = null;
|
||||||
|
|
||||||
|
if ($_FILES['design_background-image_file']['error'] ==
|
||||||
|
UPLOAD_ERR_OK) {
|
||||||
|
|
||||||
|
$filepath = null;
|
||||||
|
|
||||||
|
try {
|
||||||
|
$imagefile =
|
||||||
|
ImageFile::fromUpload('design_background-image_file');
|
||||||
|
} catch (Exception $e) {
|
||||||
|
$this->clientError('Unable to save background image.');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Note: site design background image has a special filename
|
||||||
|
|
||||||
|
$filename = Design::filename('site-design-background',
|
||||||
|
image_type_to_extension($imagefile->type),
|
||||||
|
common_timestamp());
|
||||||
|
|
||||||
|
$filepath = Design::path($filename);
|
||||||
|
|
||||||
|
move_uploaded_file($imagefile->filepath, $filepath);
|
||||||
|
|
||||||
|
// delete any old backround img laying around
|
||||||
|
|
||||||
|
if (isset($this->design->backgroundimage)) {
|
||||||
|
@unlink(Design::path($design->backgroundimage));
|
||||||
|
}
|
||||||
|
|
||||||
|
return $filename;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Attempt to validate setting values
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
|
||||||
|
function validate(&$values)
|
||||||
|
{
|
||||||
|
if (!empty($values['logo']) &&
|
||||||
|
!Validate::uri($values['logo'], array('allowed_schemes' => array('http', 'https')))) {
|
||||||
|
$this->clientError(_("Invalid logo URL."));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!in_array($values['theme'], Theme::listAvailable())) {
|
||||||
|
$this->clientError(sprintf(_("Theme not available: %s"), $values['theme']));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add the Farbtastic stylesheet
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
|
||||||
|
function showStylesheets()
|
||||||
|
{
|
||||||
|
parent::showStylesheets();
|
||||||
|
$this->cssLink('css/farbtastic.css','base','screen, projection, tv');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add the Farbtastic scripts
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
|
||||||
|
function showScripts()
|
||||||
|
{
|
||||||
|
parent::showScripts();
|
||||||
|
|
||||||
|
$this->script('js/farbtastic/farbtastic.js');
|
||||||
|
$this->script('js/userdesign.go.js');
|
||||||
|
|
||||||
|
$this->autofocus('design_background-image_file');
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
class DesignAdminPanelForm extends AdminForm
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ID of the form
|
||||||
|
*
|
||||||
|
* @return int ID of the form
|
||||||
|
*/
|
||||||
|
|
||||||
|
function id()
|
||||||
|
{
|
||||||
|
return 'form_design_admin_panel';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* class of the form
|
||||||
|
*
|
||||||
|
* @return string class of the form
|
||||||
|
*/
|
||||||
|
|
||||||
|
function formClass()
|
||||||
|
{
|
||||||
|
return 'form_settings';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* HTTP method used to submit the form
|
||||||
|
*
|
||||||
|
* For image data we need to send multipart/form-data
|
||||||
|
* so we set that here too
|
||||||
|
*
|
||||||
|
* @return string the method to use for submitting
|
||||||
|
*/
|
||||||
|
|
||||||
|
function method()
|
||||||
|
{
|
||||||
|
$this->enctype = 'multipart/form-data';
|
||||||
|
|
||||||
|
return 'post';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Action of the form
|
||||||
|
*
|
||||||
|
* @return string URL of the action
|
||||||
|
*/
|
||||||
|
|
||||||
|
function action()
|
||||||
|
{
|
||||||
|
return common_local_url('designadminpanel');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Data elements of the form
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
|
||||||
|
function formData()
|
||||||
|
{
|
||||||
|
|
||||||
|
$this->out->elementStart('fieldset', array('id' => 'settings_design_logo'));
|
||||||
|
$this->out->element('legend', null, _('Change logo'));
|
||||||
|
|
||||||
|
$this->out->elementStart('ul', 'form_data');
|
||||||
|
|
||||||
|
$this->li();
|
||||||
|
$this->input('logo', _('Site logo'), 'Logo for the site (full URL)');
|
||||||
|
$this->unli();
|
||||||
|
|
||||||
|
$this->out->elementEnd('ul');
|
||||||
|
|
||||||
|
$this->out->elementEnd('fieldset');
|
||||||
|
$this->out->elementStart('fieldset', array('id' => 'settings_design_theme'));
|
||||||
|
$this->out->element('legend', null, _('Change theme'));
|
||||||
|
|
||||||
|
$this->out->elementStart('ul', 'form_data');
|
||||||
|
|
||||||
|
$themes = Theme::listAvailable();
|
||||||
|
|
||||||
|
// XXX: listAvailable() can return an empty list if you
|
||||||
|
// screw up your settings, so just in case:
|
||||||
|
|
||||||
|
if (empty($themes)) {
|
||||||
|
$themes = array('default', 'default');
|
||||||
|
}
|
||||||
|
|
||||||
|
asort($themes);
|
||||||
|
$themes = array_combine($themes, $themes);
|
||||||
|
|
||||||
|
$this->li();
|
||||||
|
$this->out->dropdown('theme', _('Site theme'),
|
||||||
|
$themes, _('Theme for the site.'),
|
||||||
|
false, $this->value('theme'));
|
||||||
|
$this->unli();
|
||||||
|
|
||||||
|
$this->out->elementEnd('ul');
|
||||||
|
|
||||||
|
$this->out->elementEnd('fieldset');
|
||||||
|
|
||||||
|
$design = $this->out->design;
|
||||||
|
|
||||||
|
$this->out->elementStart('fieldset', array('id' =>
|
||||||
|
'settings_design_background-image'));
|
||||||
|
$this->out->element('legend', null, _('Change background image'));
|
||||||
|
$this->out->elementStart('ul', 'form_data');
|
||||||
|
|
||||||
|
$this->li();
|
||||||
|
$this->out->element('label', array('for' => 'design_background-image_file'),
|
||||||
|
_('Background'));
|
||||||
|
$this->out->element('input', array('name' => 'design_background-image_file',
|
||||||
|
'type' => 'file',
|
||||||
|
'id' => 'design_background-image_file'));
|
||||||
|
$this->out->element('p', 'form_guide',
|
||||||
|
sprintf(_('You can upload a background image for the site. ' .
|
||||||
|
'The maximum file size is %1$s.'), ImageFile::maxFileSize()));
|
||||||
|
$this->out->element('input', array('name' => 'MAX_FILE_SIZE',
|
||||||
|
'type' => 'hidden',
|
||||||
|
'id' => 'MAX_FILE_SIZE',
|
||||||
|
'value' => ImageFile::maxFileSizeInt()));
|
||||||
|
$this->unli();
|
||||||
|
|
||||||
|
if (!empty($design->backgroundimage)) {
|
||||||
|
|
||||||
|
$this->out->elementStart('li', array('id' =>
|
||||||
|
'design_background-image_onoff'));
|
||||||
|
|
||||||
|
$this->out->element('img', array('src' =>
|
||||||
|
Design::url($design->backgroundimage)));
|
||||||
|
|
||||||
|
$attrs = array('name' => 'design_background-image_onoff',
|
||||||
|
'type' => 'radio',
|
||||||
|
'id' => 'design_background-image_on',
|
||||||
|
'class' => 'radio',
|
||||||
|
'value' => 'on');
|
||||||
|
|
||||||
|
if ($design->disposition & BACKGROUND_ON) {
|
||||||
|
$attrs['checked'] = 'checked';
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->out->element('input', $attrs);
|
||||||
|
|
||||||
|
$this->out->element('label', array('for' => 'design_background-image_on',
|
||||||
|
'class' => 'radio'),
|
||||||
|
_('On'));
|
||||||
|
|
||||||
|
$attrs = array('name' => 'design_background-image_onoff',
|
||||||
|
'type' => 'radio',
|
||||||
|
'id' => 'design_background-image_off',
|
||||||
|
'class' => 'radio',
|
||||||
|
'value' => 'off');
|
||||||
|
|
||||||
|
if ($design->disposition & BACKGROUND_OFF) {
|
||||||
|
$attrs['checked'] = 'checked';
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->out->element('input', $attrs);
|
||||||
|
|
||||||
|
$this->out->element('label', array('for' => 'design_background-image_off',
|
||||||
|
'class' => 'radio'),
|
||||||
|
_('Off'));
|
||||||
|
$this->out->element('p', 'form_guide', _('Turn background image on or off.'));
|
||||||
|
$this->unli();
|
||||||
|
|
||||||
|
$this->li();
|
||||||
|
$this->out->checkbox('design_background-image_repeat',
|
||||||
|
_('Tile background image'),
|
||||||
|
($design->disposition & BACKGROUND_TILE) ? true : false);
|
||||||
|
$this->unli();
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->out->elementEnd('ul');
|
||||||
|
$this->out->elementEnd('fieldset');
|
||||||
|
|
||||||
|
$this->out->elementStart('fieldset', array('id' => 'settings_design_color'));
|
||||||
|
$this->out->element('legend', null, _('Change colours'));
|
||||||
|
|
||||||
|
$this->out->elementStart('ul', 'form_data');
|
||||||
|
|
||||||
|
try {
|
||||||
|
|
||||||
|
$bgcolor = new WebColor($design->backgroundcolor);
|
||||||
|
|
||||||
|
$this->li();
|
||||||
|
$this->out->element('label', array('for' => 'swatch-1'), _('Background'));
|
||||||
|
$this->out->element('input', array('name' => 'design_background',
|
||||||
|
'type' => 'text',
|
||||||
|
'id' => 'swatch-1',
|
||||||
|
'class' => 'swatch',
|
||||||
|
'maxlength' => '7',
|
||||||
|
'size' => '7',
|
||||||
|
'value' => ''));
|
||||||
|
$this->unli();
|
||||||
|
|
||||||
|
$ccolor = new WebColor($design->contentcolor);
|
||||||
|
|
||||||
|
$this->li();
|
||||||
|
$this->out->element('label', array('for' => 'swatch-2'), _('Content'));
|
||||||
|
$this->out->element('input', array('name' => 'design_content',
|
||||||
|
'type' => 'text',
|
||||||
|
'id' => 'swatch-2',
|
||||||
|
'class' => 'swatch',
|
||||||
|
'maxlength' => '7',
|
||||||
|
'size' => '7',
|
||||||
|
'value' => ''));
|
||||||
|
$this->unli();
|
||||||
|
|
||||||
|
$sbcolor = new WebColor($design->sidebarcolor);
|
||||||
|
|
||||||
|
$this->li();
|
||||||
|
$this->out->element('label', array('for' => 'swatch-3'), _('Sidebar'));
|
||||||
|
$this->out->element('input', array('name' => 'design_sidebar',
|
||||||
|
'type' => 'text',
|
||||||
|
'id' => 'swatch-3',
|
||||||
|
'class' => 'swatch',
|
||||||
|
'maxlength' => '7',
|
||||||
|
'size' => '7',
|
||||||
|
'value' => ''));
|
||||||
|
$this->unli();
|
||||||
|
|
||||||
|
$tcolor = new WebColor($design->textcolor);
|
||||||
|
|
||||||
|
$this->li();
|
||||||
|
$this->out->element('label', array('for' => 'swatch-4'), _('Text'));
|
||||||
|
$this->out->element('input', array('name' => 'design_text',
|
||||||
|
'type' => 'text',
|
||||||
|
'id' => 'swatch-4',
|
||||||
|
'class' => 'swatch',
|
||||||
|
'maxlength' => '7',
|
||||||
|
'size' => '7',
|
||||||
|
'value' => ''));
|
||||||
|
$this->unli();
|
||||||
|
|
||||||
|
$lcolor = new WebColor($design->linkcolor);
|
||||||
|
|
||||||
|
$this->li();
|
||||||
|
$this->out->element('label', array('for' => 'swatch-5'), _('Links'));
|
||||||
|
$this->out->element('input', array('name' => 'design_links',
|
||||||
|
'type' => 'text',
|
||||||
|
'id' => 'swatch-5',
|
||||||
|
'class' => 'swatch',
|
||||||
|
'maxlength' => '7',
|
||||||
|
'size' => '7',
|
||||||
|
'value' => ''));
|
||||||
|
$this->unli();
|
||||||
|
|
||||||
|
} catch (WebColorException $e) {
|
||||||
|
common_log(LOG_ERR, 'Bad color values in site design: ' .
|
||||||
|
$e->getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->out->elementEnd('fieldset');
|
||||||
|
|
||||||
|
$this->out->elementEnd('ul');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Action elements
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
|
||||||
|
function formActions()
|
||||||
|
{
|
||||||
|
$this->out->submit('defaults', _('Use defaults'), 'submit form_action-default',
|
||||||
|
'defaults', _('Restore default designs'));
|
||||||
|
|
||||||
|
$this->out->element('input', array('id' => 'settings_design_reset',
|
||||||
|
'type' => 'reset',
|
||||||
|
'value' => 'Reset',
|
||||||
|
'class' => 'submit form_action-primary',
|
||||||
|
'title' => _('Reset back to default')));
|
||||||
|
|
||||||
|
$this->out->submit('save', _('Save'), 'submit form_action-secondary',
|
||||||
|
'save', _('Save design'));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -58,12 +58,24 @@ class DocAction extends Action
|
|||||||
function handle($args)
|
function handle($args)
|
||||||
{
|
{
|
||||||
parent::handle($args);
|
parent::handle($args);
|
||||||
$this->title = $this->trimmed('title');
|
|
||||||
$this->filename = INSTALLDIR.'/doc-src/'.$this->title;
|
$this->title = $this->trimmed('title');
|
||||||
if (!file_exists($this->filename)) {
|
$this->output = null;
|
||||||
$this->clientError(_('No such document.'));
|
|
||||||
return;
|
if (Event::handle('StartLoadDoc', array(&$this->title, &$this->output))) {
|
||||||
|
|
||||||
|
$this->filename = INSTALLDIR.'/doc-src/'.$this->title;
|
||||||
|
if (!file_exists($this->filename)) {
|
||||||
|
$this->clientError(_('No such document.'));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$c = file_get_contents($this->filename);
|
||||||
|
$this->output = common_markup_to_html($c);
|
||||||
|
|
||||||
|
Event::handle('EndLoadDoc', array($this->title, &$this->output));
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->showPage();
|
$this->showPage();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -93,9 +105,7 @@ class DocAction extends Action
|
|||||||
*/
|
*/
|
||||||
function showContent()
|
function showContent()
|
||||||
{
|
{
|
||||||
$c = file_get_contents($this->filename);
|
$this->raw($this->output);
|
||||||
$output = common_markup_to_html($c);
|
|
||||||
$this->raw($output);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -64,11 +64,6 @@ class EditgroupAction extends GroupDesignAction
|
|||||||
{
|
{
|
||||||
parent::prepare($args);
|
parent::prepare($args);
|
||||||
|
|
||||||
if (!common_config('inboxes','enabled')) {
|
|
||||||
$this->serverError(_('Inboxes must be enabled for groups to work'));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!common_logged_in()) {
|
if (!common_logged_in()) {
|
||||||
$this->clientError(_('You must be logged in to create a group.'));
|
$this->clientError(_('You must be logged in to create a group.'));
|
||||||
return false;
|
return false;
|
||||||
@ -202,8 +197,8 @@ class EditgroupAction extends GroupDesignAction
|
|||||||
} else if (!is_null($fullname) && mb_strlen($fullname) > 255) {
|
} else if (!is_null($fullname) && mb_strlen($fullname) > 255) {
|
||||||
$this->showForm(_('Full name is too long (max 255 chars).'));
|
$this->showForm(_('Full name is too long (max 255 chars).'));
|
||||||
return;
|
return;
|
||||||
} else if (!is_null($description) && mb_strlen($description) > 140) {
|
} else if (User_group::descriptionTooLong($description)) {
|
||||||
$this->showForm(_('description is too long (max 140 chars).'));
|
$this->showForm(sprintf(_('description is too long (max %d chars).'), User_group::maxDescription()));
|
||||||
return;
|
return;
|
||||||
} else if (!is_null($location) && mb_strlen($location) > 255) {
|
} else if (!is_null($location) && mb_strlen($location) > 255) {
|
||||||
$this->showForm(_('Location is too long (max 255 chars).'));
|
$this->showForm(_('Location is too long (max 255 chars).'));
|
||||||
|
@ -95,7 +95,7 @@ class EmailsettingsAction extends AccountSettingsAction
|
|||||||
'class' => 'form_settings',
|
'class' => 'form_settings',
|
||||||
'action' =>
|
'action' =>
|
||||||
common_local_url('emailsettings')));
|
common_local_url('emailsettings')));
|
||||||
|
$this->elementStart('fieldset');
|
||||||
$this->elementStart('fieldset', array('id' => 'settings_email_address'));
|
$this->elementStart('fieldset', array('id' => 'settings_email_address'));
|
||||||
$this->element('legend', null, _('Address'));
|
$this->element('legend', null, _('Address'));
|
||||||
$this->hidden('token', common_session_token());
|
$this->hidden('token', common_session_token());
|
||||||
@ -194,6 +194,7 @@ class EmailsettingsAction extends AccountSettingsAction
|
|||||||
$this->elementEnd('ul');
|
$this->elementEnd('ul');
|
||||||
$this->submit('save', _('Save'));
|
$this->submit('save', _('Save'));
|
||||||
$this->elementEnd('fieldset');
|
$this->elementEnd('fieldset');
|
||||||
|
$this->elementEnd('fieldset');
|
||||||
$this->elementEnd('form');
|
$this->elementEnd('form');
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -326,7 +327,7 @@ class EmailsettingsAction extends AccountSettingsAction
|
|||||||
$this->showForm(_('Cannot normalize that email address'));
|
$this->showForm(_('Cannot normalize that email address'));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!Validate::email($email, true)) {
|
if (!Validate::email($email, common_config('email', 'check_domain'))) {
|
||||||
$this->showForm(_('Not a valid email address'));
|
$this->showForm(_('Not a valid email address'));
|
||||||
return;
|
return;
|
||||||
} else if ($user->email == $email) {
|
} else if ($user->email == $email) {
|
||||||
|
@ -153,8 +153,7 @@ class FavoritedAction extends Action
|
|||||||
$message .= _('Be the first to add a notice to your favorites by clicking the fave button next to any notice you like.');
|
$message .= _('Be the first to add a notice to your favorites by clicking the fave button next to any notice you like.');
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
$message .= sprintf(_('Why not [register an account](%%%%action.%s%%%%) and be the first to add a notice to your favorites!'),
|
$message .= _('Why not [register an account](%%action.register%%) and be the first to add a notice to your favorites!');
|
||||||
(!common_config('site','openidonly')) ? 'register' : 'openidlogin');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->elementStart('div', 'guide');
|
$this->elementStart('div', 'guide');
|
||||||
|
@ -50,11 +50,11 @@ require_once INSTALLDIR.'/lib/rssaction.php';
|
|||||||
*/
|
*/
|
||||||
class FavoritesrssAction extends Rss10Action
|
class FavoritesrssAction extends Rss10Action
|
||||||
{
|
{
|
||||||
|
|
||||||
/** The user whose favorites to display */
|
/** The user whose favorites to display */
|
||||||
|
|
||||||
var $user = null;
|
var $user = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Find the user to display by supplied nickname
|
* Find the user to display by supplied nickname
|
||||||
*
|
*
|
||||||
@ -66,7 +66,7 @@ class FavoritesrssAction extends Rss10Action
|
|||||||
function prepare($args)
|
function prepare($args)
|
||||||
{
|
{
|
||||||
parent::prepare($args);
|
parent::prepare($args);
|
||||||
|
|
||||||
$nickname = $this->trimmed('nickname');
|
$nickname = $this->trimmed('nickname');
|
||||||
$this->user = User::staticGet('nickname', $nickname);
|
$this->user = User::staticGet('nickname', $nickname);
|
||||||
|
|
||||||
@ -74,10 +74,11 @@ class FavoritesrssAction extends Rss10Action
|
|||||||
$this->clientError(_('No such user.'));
|
$this->clientError(_('No such user.'));
|
||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
|
$this->notices = $this->getNotices($this->limit);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get notices
|
* Get notices
|
||||||
*
|
*
|
||||||
|
@ -1,5 +1,16 @@
|
|||||||
<?php
|
<?php
|
||||||
/*
|
/**
|
||||||
|
* Handler for remote subscription finish callback
|
||||||
|
*
|
||||||
|
* PHP version 5
|
||||||
|
*
|
||||||
|
* @category Action
|
||||||
|
* @package StatusNet
|
||||||
|
* @author Evan Prodromou <evan@status.net>
|
||||||
|
* @author Robin Millette <millette@status.net>
|
||||||
|
* @license http://www.fsf.org/licensing/licenses/agpl.html AGPLv3
|
||||||
|
* @link http://status.net/
|
||||||
|
*
|
||||||
* StatusNet - the distributed open-source microblogging tool
|
* StatusNet - the distributed open-source microblogging tool
|
||||||
* Copyright (C) 2008, 2009, StatusNet, Inc.
|
* Copyright (C) 2008, 2009, StatusNet, Inc.
|
||||||
*
|
*
|
||||||
@ -15,285 +26,121 @@
|
|||||||
*
|
*
|
||||||
* You should have received a copy of the GNU Affero General Public License
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
**/
|
||||||
|
|
||||||
if (!defined('STATUSNET') && !defined('LACONICA')) { exit(1); }
|
if (!defined('STATUSNET') && !defined('LACONICA')) { exit(1); }
|
||||||
|
|
||||||
require_once(INSTALLDIR.'/lib/omb.php');
|
require_once INSTALLDIR.'/extlib/libomb/service_consumer.php';
|
||||||
|
require_once INSTALLDIR.'/lib/omb.php';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handler for remote subscription finish callback
|
||||||
|
*
|
||||||
|
* When a remote user subscribes a local user, a redirect to this action is
|
||||||
|
* issued after the remote user authorized his service to subscribe.
|
||||||
|
*
|
||||||
|
* @category Action
|
||||||
|
* @package Laconica
|
||||||
|
* @author Evan Prodromou <evan@status.net>
|
||||||
|
* @author Robin Millette <millette@controlyourself.ca>
|
||||||
|
* @license http://www.fsf.org/licensing/licenses/agpl.html AGPLv3
|
||||||
|
* @link http://laconi.ca/
|
||||||
|
*/
|
||||||
class FinishremotesubscribeAction extends Action
|
class FinishremotesubscribeAction extends Action
|
||||||
{
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class handler.
|
||||||
|
*
|
||||||
|
* @param array $args query arguments
|
||||||
|
*
|
||||||
|
* @return nothing
|
||||||
|
*
|
||||||
|
**/
|
||||||
function handle($args)
|
function handle($args)
|
||||||
{
|
{
|
||||||
|
|
||||||
parent::handle($args);
|
parent::handle($args);
|
||||||
|
|
||||||
if (common_logged_in()) {
|
/* Restore session data. RemotesubscribeAction should have stored
|
||||||
$this->clientError(_('You can use the local subscription!'));
|
this entry. */
|
||||||
return;
|
$service = unserialize($_SESSION['oauth_authorization_request']);
|
||||||
}
|
|
||||||
|
|
||||||
$omb = $_SESSION['oauth_authorization_request'];
|
if (!$service) {
|
||||||
|
|
||||||
if (!$omb) {
|
|
||||||
$this->clientError(_('Not expecting this response!'));
|
$this->clientError(_('Not expecting this response!'));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
common_debug('stored request: '.print_r($omb,true), __FILE__);
|
common_debug('stored request: '. print_r($service, true), __FILE__);
|
||||||
|
|
||||||
common_remove_magic_from_request();
|
/* Create user objects for both users. Do it early for request
|
||||||
$req = OAuthRequest::from_request('POST', common_local_url('finishuserauthorization'));
|
validation. */
|
||||||
|
$user = User::staticGet('uri', $service->getListeneeURI());
|
||||||
$token = $req->get_parameter('oauth_token');
|
|
||||||
|
|
||||||
# I think this is the success metric
|
|
||||||
|
|
||||||
if ($token != $omb['token']) {
|
|
||||||
$this->clientError(_('Not authorized.'));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
$version = $req->get_parameter('omb_version');
|
|
||||||
|
|
||||||
if ($version != OMB_VERSION_01) {
|
|
||||||
$this->clientError(_('Unknown version of OMB protocol.'));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
$nickname = $req->get_parameter('omb_listener_nickname');
|
|
||||||
|
|
||||||
if (!$nickname) {
|
|
||||||
$this->clientError(_('No nickname provided by remote server.'));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
$profile_url = $req->get_parameter('omb_listener_profile');
|
|
||||||
|
|
||||||
if (!$profile_url) {
|
|
||||||
$this->clientError(_('No profile URL returned by server.'));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!Validate::uri($profile_url, array('allowed_schemes' => array('http', 'https')))) {
|
|
||||||
$this->clientError(_('Invalid profile URL returned by server.'));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($profile_url == common_local_url('showstream', array('nickname' => $nickname))) {
|
|
||||||
$this->clientError(_('You can use the local subscription!'));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
common_debug('listenee: "'.$omb['listenee'].'"', __FILE__);
|
|
||||||
|
|
||||||
$user = User::staticGet('nickname', $omb['listenee']);
|
|
||||||
|
|
||||||
if (!$user) {
|
if (!$user) {
|
||||||
$this->clientError(_('User being listened to doesn\'t exist.'));
|
$this->clientError(_('User being listened to does not exist.'));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
$other = User::staticGet('uri', $omb['listener']);
|
$other = User::staticGet('uri', $service->getListenerURI());
|
||||||
|
|
||||||
if ($other) {
|
if ($other) {
|
||||||
$this->clientError(_('You can use the local subscription!'));
|
$this->clientError(_('You can use the local subscription!'));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
$fullname = $req->get_parameter('omb_listener_fullname');
|
$remote = Remote_profile::staticGet('uri', $service->getListenerURI());
|
||||||
$homepage = $req->get_parameter('omb_listener_homepage');
|
|
||||||
$bio = $req->get_parameter('omb_listener_bio');
|
|
||||||
$location = $req->get_parameter('omb_listener_location');
|
|
||||||
$avatar_url = $req->get_parameter('omb_listener_avatar');
|
|
||||||
|
|
||||||
list($newtok, $newsecret) = $this->access_token($omb);
|
$profile = Profile::staticGet($remote->id);
|
||||||
|
|
||||||
if (!$newtok || !$newsecret) {
|
|
||||||
$this->clientError(_('Couldn\'t convert request tokens to access tokens.'));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
# XXX: possible attack point; subscribe and return someone else's profile URI
|
|
||||||
|
|
||||||
$remote = Remote_profile::staticGet('uri', $omb['listener']);
|
|
||||||
|
|
||||||
if ($remote) {
|
|
||||||
$exists = true;
|
|
||||||
$profile = Profile::staticGet($remote->id);
|
|
||||||
$orig_remote = clone($remote);
|
|
||||||
$orig_profile = clone($profile);
|
|
||||||
# XXX: compare current postNotice and updateProfile URLs to the ones
|
|
||||||
# stored in the DB to avoid (possibly...) above attack
|
|
||||||
} else {
|
|
||||||
$exists = false;
|
|
||||||
$remote = new Remote_profile();
|
|
||||||
$remote->uri = $omb['listener'];
|
|
||||||
$profile = new Profile();
|
|
||||||
}
|
|
||||||
|
|
||||||
$profile->nickname = $nickname;
|
|
||||||
$profile->profileurl = $profile_url;
|
|
||||||
|
|
||||||
if (!is_null($fullname)) {
|
|
||||||
$profile->fullname = $fullname;
|
|
||||||
}
|
|
||||||
if (!is_null($homepage)) {
|
|
||||||
$profile->homepage = $homepage;
|
|
||||||
}
|
|
||||||
if (!is_null($bio)) {
|
|
||||||
$profile->bio = $bio;
|
|
||||||
}
|
|
||||||
if (!is_null($location)) {
|
|
||||||
$profile->location = $location;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($exists) {
|
|
||||||
$profile->update($orig_profile);
|
|
||||||
} else {
|
|
||||||
$profile->created = DB_DataObject_Cast::dateTime(); # current time
|
|
||||||
$id = $profile->insert();
|
|
||||||
if (!$id) {
|
|
||||||
$this->serverError(_('Error inserting new profile'));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
$remote->id = $id;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($avatar_url) {
|
|
||||||
if (!$this->add_avatar($profile, $avatar_url)) {
|
|
||||||
$this->serverError(_('Error inserting avatar'));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$remote->postnoticeurl = $omb['post_notice_url'];
|
|
||||||
$remote->updateprofileurl = $omb['update_profile_url'];
|
|
||||||
|
|
||||||
if ($exists) {
|
|
||||||
if (!$remote->update($orig_remote)) {
|
|
||||||
$this->serverError(_('Error updating remote profile'));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
$remote->created = DB_DataObject_Cast::dateTime(); # current time
|
|
||||||
if (!$remote->insert()) {
|
|
||||||
$this->serverError(_('Error inserting remote profile'));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($user->hasBlocked($profile)) {
|
if ($user->hasBlocked($profile)) {
|
||||||
$this->clientError(_('That user has blocked you from subscribing.'));
|
$this->clientError(_('That user has blocked you from subscribing.'));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
$sub = new Subscription();
|
/* Perform the handling itself via libomb. */
|
||||||
|
try {
|
||||||
$sub->subscriber = $remote->id;
|
$service->finishAuthorization();
|
||||||
$sub->subscribed = $user->id;
|
} catch (OAuthException $e) {
|
||||||
|
if ($e->getMessage() == 'The authorized token does not equal the ' .
|
||||||
$sub_exists = false;
|
'submitted token.') {
|
||||||
|
$this->clientError(_('You are not authorized.'));
|
||||||
if ($sub->find(true)) {
|
return;
|
||||||
$sub_exists = true;
|
} else {
|
||||||
$orig_sub = clone($sub);
|
$this->clientError(_('Could not convert request token to ' .
|
||||||
} else {
|
'access token.'));
|
||||||
$sub_exists = false;
|
return;
|
||||||
$sub->created = DB_DataObject_Cast::dateTime(); # current time
|
}
|
||||||
}
|
} catch (OMB_RemoteServiceException $e) {
|
||||||
|
$this->clientError(_('Remote service uses unknown version of ' .
|
||||||
$sub->token = $newtok;
|
'OMB protocol.'));
|
||||||
$sub->secret = $newsecret;
|
return;
|
||||||
|
} catch (Exception $e) {
|
||||||
if ($sub_exists) {
|
common_debug('Got exception ' . print_r($e, true), __FILE__);
|
||||||
$result = $sub->update($orig_sub);
|
$this->clientError($e->getMessage());
|
||||||
} else {
|
|
||||||
$result = $sub->insert();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!$result) {
|
|
||||||
common_log_db_error($sub, ($sub_exists) ? 'UPDATE' : 'INSERT', __FILE__);
|
|
||||||
$this->clientError(_('Couldn\'t insert new subscription.'));
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
# Notify user, if necessary
|
/* The service URLs are not accessible from datastore, so setting them
|
||||||
|
after insertion of the profile. */
|
||||||
|
$orig_remote = clone($remote);
|
||||||
|
|
||||||
mail_subscribe_notify_profile($user, $profile);
|
$remote->postnoticeurl =
|
||||||
|
$service->getServiceURI(OMB_ENDPOINT_POSTNOTICE);
|
||||||
|
$remote->updateprofileurl =
|
||||||
|
$service->getServiceURI(OMB_ENDPOINT_UPDATEPROFILE);
|
||||||
|
|
||||||
# Clear the data
|
if (!$remote->update($orig_remote)) {
|
||||||
|
$this->serverError(_('Error updating remote profile'));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Clear the session data. */
|
||||||
unset($_SESSION['oauth_authorization_request']);
|
unset($_SESSION['oauth_authorization_request']);
|
||||||
|
|
||||||
# If we show subscriptions in reverse chron order, this should
|
/* If we show subscriptions in reverse chronological order, the new one
|
||||||
# show up close to the top of the page
|
should show up close to the top of the page. */
|
||||||
|
|
||||||
common_redirect(common_local_url('subscribers', array('nickname' =>
|
common_redirect(common_local_url('subscribers', array('nickname' =>
|
||||||
$user->nickname)),
|
$user->nickname)),
|
||||||
303);
|
303);
|
||||||
}
|
}
|
||||||
|
|
||||||
function add_avatar($profile, $url)
|
|
||||||
{
|
|
||||||
$temp_filename = tempnam(sys_get_temp_dir(), 'listener_avatar');
|
|
||||||
copy($url, $temp_filename);
|
|
||||||
$imagefile = new ImageFile($profile->id, $temp_filename);
|
|
||||||
$filename = Avatar::filename($profile->id,
|
|
||||||
image_type_to_extension($imagefile->type),
|
|
||||||
null,
|
|
||||||
common_timestamp());
|
|
||||||
rename($temp_filename, Avatar::path($filename));
|
|
||||||
return $profile->setOriginal($filename);
|
|
||||||
}
|
|
||||||
|
|
||||||
function access_token($omb)
|
|
||||||
{
|
|
||||||
|
|
||||||
common_debug('starting request for access token', __FILE__);
|
|
||||||
|
|
||||||
$con = omb_oauth_consumer();
|
|
||||||
$tok = new OAuthToken($omb['token'], $omb['secret']);
|
|
||||||
|
|
||||||
common_debug('using request token "'.$tok.'"', __FILE__);
|
|
||||||
|
|
||||||
$url = $omb['access_token_url'];
|
|
||||||
|
|
||||||
common_debug('using access token url "'.$url.'"', __FILE__);
|
|
||||||
|
|
||||||
# XXX: Is this the right thing to do? Strip off GET params and make them
|
|
||||||
# POST params? Seems wrong to me.
|
|
||||||
|
|
||||||
$parsed = parse_url($url);
|
|
||||||
$params = array();
|
|
||||||
parse_str($parsed['query'], $params);
|
|
||||||
|
|
||||||
$req = OAuthRequest::from_consumer_and_token($con, $tok, "POST", $url, $params);
|
|
||||||
|
|
||||||
$req->set_parameter('omb_version', OMB_VERSION_01);
|
|
||||||
|
|
||||||
# XXX: test to see if endpoint accepts this signature method
|
|
||||||
|
|
||||||
$req->sign_request(omb_hmac_sha1(), $con, $tok);
|
|
||||||
|
|
||||||
# We re-use this tool's fetcher, since it's pretty good
|
|
||||||
|
|
||||||
common_debug('posting to access token url "'.$req->get_normalized_http_url().'"', __FILE__);
|
|
||||||
common_debug('posting request data "'.$req->to_postdata().'"', __FILE__);
|
|
||||||
|
|
||||||
$fetcher = Auth_Yadis_Yadis::getHTTPFetcher();
|
|
||||||
$result = $fetcher->post($req->get_normalized_http_url(),
|
|
||||||
$req->to_postdata(),
|
|
||||||
array('User-Agent: StatusNet/' . STATUSNET_VERSION));
|
|
||||||
|
|
||||||
common_debug('got result: "'.print_r($result,true).'"', __FILE__);
|
|
||||||
|
|
||||||
if ($result->status != 200) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
parse_str($result->body, $return);
|
|
||||||
|
|
||||||
return array($return['oauth_token'], $return['oauth_token_secret']);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -108,11 +108,29 @@ class FoafAction extends Action
|
|||||||
if ($this->profile->bio) {
|
if ($this->profile->bio) {
|
||||||
$this->element('bio:olb', null, $this->profile->bio);
|
$this->element('bio:olb', null, $this->profile->bio);
|
||||||
}
|
}
|
||||||
// XXX: more structured location data
|
|
||||||
if ($this->profile->location) {
|
$location = $this->profile->getLocation();
|
||||||
|
if ($location) {
|
||||||
|
$attr = array();
|
||||||
|
if ($location->getRdfURL()) {
|
||||||
|
$attr['rdf:about'] = $location->getRdfURL();
|
||||||
|
}
|
||||||
|
$location_name = $location->getName();
|
||||||
|
|
||||||
$this->elementStart('based_near');
|
$this->elementStart('based_near');
|
||||||
$this->elementStart('geo:SpatialThing');
|
$this->elementStart('geo:SpatialThing', $attr);
|
||||||
$this->element('name', null, $this->profile->location);
|
if ($location_name) {
|
||||||
|
$this->element('name', null, $location_name);
|
||||||
|
}
|
||||||
|
if ($location->lat) {
|
||||||
|
$this->element('geo:lat', null, $location->lat);
|
||||||
|
}
|
||||||
|
if ($location->lon) {
|
||||||
|
$this->element('geo:long', null, $location->lat);
|
||||||
|
}
|
||||||
|
if ($location->getURL()) {
|
||||||
|
$this->element('page', array('rdf:resource'=>$location->getURL()));
|
||||||
|
}
|
||||||
$this->elementEnd('geo:SpatialThing');
|
$this->elementEnd('geo:SpatialThing');
|
||||||
$this->elementEnd('based_near');
|
$this->elementEnd('based_near');
|
||||||
}
|
}
|
||||||
|
173
actions/foafgroup.php
Normal file
173
actions/foafgroup.php
Normal file
@ -0,0 +1,173 @@
|
|||||||
|
<?php
|
||||||
|
/*
|
||||||
|
* StatusNet the distributed open-source microblogging tool
|
||||||
|
* Copyright (C) 2008, 2009, StatusNet, Inc.
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* @category Mail
|
||||||
|
* @package StatusNet
|
||||||
|
* @author Evan Prodromou <evan@status.net>
|
||||||
|
* @author Toby Inkster <mail@tobyinkster.co.uk>
|
||||||
|
* @copyright 2009 StatusNet, Inc.
|
||||||
|
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||||
|
* @link http://status.net/
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (!defined('STATUSNET') && !defined('LACONICA')) { exit(1); }
|
||||||
|
|
||||||
|
class FoafGroupAction extends Action
|
||||||
|
{
|
||||||
|
function isReadOnly($args)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
function prepare($args)
|
||||||
|
{
|
||||||
|
parent::prepare($args);
|
||||||
|
|
||||||
|
$nickname_arg = $this->arg('nickname');
|
||||||
|
|
||||||
|
if (empty($nickname_arg)) {
|
||||||
|
$this->clientError(_('No such group.'), 404);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->nickname = common_canonical_nickname($nickname_arg);
|
||||||
|
|
||||||
|
// Permanent redirect on non-canonical nickname
|
||||||
|
|
||||||
|
if ($nickname_arg != $this->nickname) {
|
||||||
|
common_redirect(common_local_url('foafgroup',
|
||||||
|
array('nickname' => $this->nickname)),
|
||||||
|
301);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->group = User_group::staticGet('nickname', $this->nickname);
|
||||||
|
|
||||||
|
if (!$this->group) {
|
||||||
|
$this->clientError(_('No such group.'), 404);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
common_set_returnto($this->selfUrl());
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
function handle($args)
|
||||||
|
{
|
||||||
|
parent::handle($args);
|
||||||
|
|
||||||
|
header('Content-Type: application/rdf+xml');
|
||||||
|
|
||||||
|
$this->startXML();
|
||||||
|
$this->elementStart('rdf:RDF', array('xmlns:rdf' =>
|
||||||
|
'http://www.w3.org/1999/02/22-rdf-syntax-ns#',
|
||||||
|
'xmlns:dcterms' =>
|
||||||
|
'http://purl.org/dc/terms/',
|
||||||
|
'xmlns:sioc' =>
|
||||||
|
'http://rdfs.org/sioc/ns#',
|
||||||
|
'xmlns:foaf' =>
|
||||||
|
'http://xmlns.com/foaf/0.1/',
|
||||||
|
'xmlns:statusnet' =>
|
||||||
|
'http://status.net/ont/',
|
||||||
|
'xmlns' => 'http://xmlns.com/foaf/0.1/'));
|
||||||
|
|
||||||
|
$this->showPpd(common_local_url('foafgroup', array('nickname' => $this->nickname)), $this->group->permalink());
|
||||||
|
|
||||||
|
$this->elementStart('Group', array('rdf:about' =>
|
||||||
|
$this->group->permalink()));
|
||||||
|
if ($this->group->fullname) {
|
||||||
|
$this->element('name', null, $this->group->fullname);
|
||||||
|
}
|
||||||
|
if ($this->group->description) {
|
||||||
|
$this->element('dcterms:description', null, $this->group->description);
|
||||||
|
}
|
||||||
|
if ($this->group->nickname) {
|
||||||
|
$this->element('dcterms:identifier', null, $this->group->nickname);
|
||||||
|
$this->element('nick', null, $this->group->nickname);
|
||||||
|
}
|
||||||
|
foreach ($this->group->getAliases() as $alias) {
|
||||||
|
$this->element('nick', null, $alias);
|
||||||
|
}
|
||||||
|
if ($this->group->homeUrl()) {
|
||||||
|
$this->element('weblog', array('rdf:resource' => $this->group->homeUrl()));
|
||||||
|
}
|
||||||
|
if ($this->group->homepage) {
|
||||||
|
$this->element('page', array('rdf:resource' => $this->group->homepage));
|
||||||
|
}
|
||||||
|
if ($this->group->homepage_logo) {
|
||||||
|
$this->element('depiction', array('rdf:resource' => $this->group->homepage_logo));
|
||||||
|
}
|
||||||
|
|
||||||
|
$members = $this->group->getMembers();
|
||||||
|
$member_details = array();
|
||||||
|
while ($members->fetch()) {
|
||||||
|
$member_uri = common_local_url('userbyid', array('id'=>$members->id));
|
||||||
|
$member_details[$member_uri] = array(
|
||||||
|
'nickname' => $members->nickname
|
||||||
|
);
|
||||||
|
$this->element('member', array('rdf:resource' => $member_uri));
|
||||||
|
}
|
||||||
|
|
||||||
|
$admins = $this->group->getAdmins();
|
||||||
|
while ($admins->fetch()) {
|
||||||
|
$admin_uri = common_local_url('userbyid', array('id'=>$admins->id));
|
||||||
|
$member_details[$admin_uri]['is_admin'] = true;
|
||||||
|
$this->element('statusnet:groupAdmin', array('rdf:resource' => $admin_uri));
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->elementEnd('Group');
|
||||||
|
|
||||||
|
ksort($member_details);
|
||||||
|
foreach ($member_details as $uri => $details) {
|
||||||
|
if ($details['is_admin'])
|
||||||
|
{
|
||||||
|
$this->elementStart('Agent', array('rdf:about' => $uri));
|
||||||
|
$this->element('nick', null, $details['nickname']);
|
||||||
|
$this->elementStart('holdsAccount');
|
||||||
|
$this->elementStart('sioc:User', array('rdf:about'=>$uri.'#acct'));
|
||||||
|
$this->elementStart('sioc:has_function');
|
||||||
|
$this->elementStart('statusnet:GroupAdminRole');
|
||||||
|
$this->element('sioc:scope', array('rdf:resource' => $this->group->permalink()));
|
||||||
|
$this->elementEnd('statusnet:GroupAdminRole');
|
||||||
|
$this->elementEnd('sioc:has_function');
|
||||||
|
$this->elementEnd('sioc:User');
|
||||||
|
$this->elementEnd('holdsAccount');
|
||||||
|
$this->elementEnd('Agent');
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$this->element('Agent', array(
|
||||||
|
'foaf:nick' => $details['nickname'],
|
||||||
|
'rdf:about' => $uri,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->elementEnd('rdf:RDF');
|
||||||
|
$this->endXML();
|
||||||
|
}
|
||||||
|
|
||||||
|
function showPpd($foaf_url, $person_uri)
|
||||||
|
{
|
||||||
|
$this->elementStart('Document', array('rdf:about' => $foaf_url));
|
||||||
|
$this->element('primaryTopic', array('rdf:resource' => $person_uri));
|
||||||
|
$this->elementEnd('Document');
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
145
actions/getfile.php
Normal file
145
actions/getfile.php
Normal file
@ -0,0 +1,145 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* StatusNet, the distributed open-source microblogging tool
|
||||||
|
*
|
||||||
|
* Returns a given file attachment, allowing private sites to only allow
|
||||||
|
* access to file attachments after login.
|
||||||
|
*
|
||||||
|
* 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 Personal
|
||||||
|
* @package StatusNet
|
||||||
|
* @author Jeffery To <jeffery.to@gmail.com>
|
||||||
|
* @copyright 2008-2009 StatusNet, Inc.
|
||||||
|
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||||
|
* @link http://status.net/
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (!defined('STATUSNET') && !defined('LACONICA')) {
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
require_once 'MIME/Type.php';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Action for getting a file attachment
|
||||||
|
*
|
||||||
|
* @category Personal
|
||||||
|
* @package StatusNet
|
||||||
|
* @author Jeffery To <jeffery.to@gmail.com>
|
||||||
|
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||||
|
* @link http://status.net/
|
||||||
|
*/
|
||||||
|
|
||||||
|
class GetfileAction extends Action
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Path of file to return
|
||||||
|
*/
|
||||||
|
|
||||||
|
var $path = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get file name
|
||||||
|
*
|
||||||
|
* @param array $args $_REQUEST array
|
||||||
|
*
|
||||||
|
* @return success flag
|
||||||
|
*/
|
||||||
|
|
||||||
|
function prepare($args)
|
||||||
|
{
|
||||||
|
parent::prepare($args);
|
||||||
|
|
||||||
|
$filename = $this->trimmed('filename');
|
||||||
|
$path = null;
|
||||||
|
|
||||||
|
if ($filename) {
|
||||||
|
$path = common_config('attachments', 'dir') . $filename;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (empty($path) or !file_exists($path)) {
|
||||||
|
$this->clientError(_('No such file.'), 404);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!is_readable($path)) {
|
||||||
|
$this->clientError(_('Cannot read file.'), 403);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->path = $path;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Is this page read-only?
|
||||||
|
*
|
||||||
|
* @return boolean true
|
||||||
|
*/
|
||||||
|
|
||||||
|
function isReadOnly($args)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Last-modified date for file
|
||||||
|
*
|
||||||
|
* @return int last-modified date as unix timestamp
|
||||||
|
*/
|
||||||
|
|
||||||
|
function lastModified()
|
||||||
|
{
|
||||||
|
return filemtime($this->path);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* etag for file
|
||||||
|
*
|
||||||
|
* This returns the same data (inode, size, mtime) as Apache would,
|
||||||
|
* but in decimal instead of hex.
|
||||||
|
*
|
||||||
|
* @return string etag http header
|
||||||
|
*/
|
||||||
|
function etag()
|
||||||
|
{
|
||||||
|
$stat = stat($this->path);
|
||||||
|
return '"' . $stat['ino'] . '-' . $stat['size'] . '-' . $stat['mtime'] . '"';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle input, produce output
|
||||||
|
*
|
||||||
|
* @param array $args $_REQUEST contents
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
|
||||||
|
function handle($args)
|
||||||
|
{
|
||||||
|
// undo headers set by PHP sessions
|
||||||
|
$sec = session_cache_expire() * 60;
|
||||||
|
header('Expires: ' . date(DATE_RFC1123, time() + $sec));
|
||||||
|
header('Cache-Control: public, max-age=' . $sec);
|
||||||
|
header('Pragma: public');
|
||||||
|
|
||||||
|
parent::handle($args);
|
||||||
|
|
||||||
|
$path = $this->path;
|
||||||
|
header('Content-Type: ' . MIME_Type::autoDetect($path));
|
||||||
|
readfile($path);
|
||||||
|
}
|
||||||
|
}
|
@ -151,17 +151,19 @@ class GroupblockAction extends Action
|
|||||||
function areYouSureForm()
|
function areYouSureForm()
|
||||||
{
|
{
|
||||||
$id = $this->profile->id;
|
$id = $this->profile->id;
|
||||||
|
$this->elementStart('form', array('id' => 'block-' . $id,
|
||||||
|
'method' => 'post',
|
||||||
|
'class' => 'form_settings form_entity_block',
|
||||||
|
'action' => common_local_url('groupblock')));
|
||||||
|
$this->elementStart('fieldset');
|
||||||
|
$this->hidden('token', common_session_token());
|
||||||
|
$this->element('legend', _('Block user'));
|
||||||
$this->element('p', null,
|
$this->element('p', null,
|
||||||
sprintf(_('Are you sure you want to block user "%s" from the group "%s"? '.
|
sprintf(_('Are you sure you want to block user "%s" from the group "%s"? '.
|
||||||
'They will be removed from the group, unable to post, and '.
|
'They will be removed from the group, unable to post, and '.
|
||||||
'unable to subscribe to the group in the future.'),
|
'unable to subscribe to the group in the future.'),
|
||||||
$this->profile->getBestName(),
|
$this->profile->getBestName(),
|
||||||
$this->group->getBestName()));
|
$this->group->getBestName()));
|
||||||
$this->elementStart('form', array('id' => 'block-' . $id,
|
|
||||||
'method' => 'post',
|
|
||||||
'class' => 'block',
|
|
||||||
'action' => common_local_url('groupblock')));
|
|
||||||
$this->hidden('token', common_session_token());
|
|
||||||
$this->hidden('blockto-' . $this->profile->id,
|
$this->hidden('blockto-' . $this->profile->id,
|
||||||
$this->profile->id,
|
$this->profile->id,
|
||||||
'blockto');
|
'blockto');
|
||||||
@ -173,8 +175,9 @@ class GroupblockAction extends Action
|
|||||||
$this->hidden($k, $v);
|
$this->hidden($k, $v);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$this->submit('no', _('No'));
|
$this->submit('form_action-no', _('No'), 'submit form_action-primary', 'no', _("Do not block this user from this group"));
|
||||||
$this->submit('yes', _('Yes'));
|
$this->submit('form_action-yes', _('Yes'), 'submit form_action-secondary', 'yes', _('Block this user from this group'));
|
||||||
|
$this->elementEnd('fieldset');
|
||||||
$this->elementEnd('form');
|
$this->elementEnd('form');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -68,11 +68,6 @@ class GroupbyidAction extends Action
|
|||||||
{
|
{
|
||||||
parent::prepare($args);
|
parent::prepare($args);
|
||||||
|
|
||||||
if (!common_config('inboxes','enabled')) {
|
|
||||||
$this->serverError(_('Inboxes must be enabled for groups to work'));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
$id = $this->arg('id');
|
$id = $this->arg('id');
|
||||||
|
|
||||||
if (!$id) {
|
if (!$id) {
|
||||||
|
@ -64,11 +64,6 @@ class GroupDesignSettingsAction extends DesignSettingsAction
|
|||||||
{
|
{
|
||||||
parent::prepare($args);
|
parent::prepare($args);
|
||||||
|
|
||||||
if (!common_config('inboxes', 'enabled')) {
|
|
||||||
$this->serverError(_('Inboxes must be enabled for groups to work'));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!common_logged_in()) {
|
if (!common_logged_in()) {
|
||||||
$this->clientError(_('You must be logged in to edit a group.'));
|
$this->clientError(_('You must be logged in to edit a group.'));
|
||||||
return false;
|
return false;
|
||||||
|
@ -66,11 +66,6 @@ class GrouplogoAction extends GroupDesignAction
|
|||||||
{
|
{
|
||||||
parent::prepare($args);
|
parent::prepare($args);
|
||||||
|
|
||||||
if (!common_config('inboxes','enabled')) {
|
|
||||||
$this->serverError(_('Inboxes must be enabled for groups to work'));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!common_logged_in()) {
|
if (!common_logged_in()) {
|
||||||
$this->clientError(_('You must be logged in to create a group.'));
|
$this->clientError(_('You must be logged in to create a group.'));
|
||||||
return false;
|
return false;
|
||||||
|
@ -179,9 +179,12 @@ class GroupMemberListItem extends ProfileListItem
|
|||||||
function showActions()
|
function showActions()
|
||||||
{
|
{
|
||||||
$this->startActions();
|
$this->startActions();
|
||||||
$this->showSubscribeButton();
|
if (Event::handle('StartProfileListItemActionElements', array($this))) {
|
||||||
$this->showMakeAdminForm();
|
$this->showSubscribeButton();
|
||||||
$this->showGroupBlockForm();
|
$this->showMakeAdminForm();
|
||||||
|
$this->showGroupBlockForm();
|
||||||
|
Event::handle('EndProfileListItemActionElements', array($this));
|
||||||
|
}
|
||||||
$this->endActions();
|
$this->endActions();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -76,11 +76,6 @@ class groupRssAction extends Rss10Action
|
|||||||
{
|
{
|
||||||
parent::prepare($args);
|
parent::prepare($args);
|
||||||
|
|
||||||
if (!common_config('inboxes','enabled')) {
|
|
||||||
$this->serverError(_('Inboxes must be enabled for groups to work'));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
$nickname_arg = $this->arg('nickname');
|
$nickname_arg = $this->arg('nickname');
|
||||||
$nickname = common_canonical_nickname($nickname_arg);
|
$nickname = common_canonical_nickname($nickname_arg);
|
||||||
|
|
||||||
@ -104,6 +99,7 @@ class groupRssAction extends Rss10Action
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$this->notices = $this->getNotices($this->limit);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -82,8 +82,7 @@ class GroupsearchAction extends SearchAction
|
|||||||
$message = _('If you can\'t find the group you\'re looking for, you can [create it](%%action.newgroup%%) yourself.');
|
$message = _('If you can\'t find the group you\'re looking for, you can [create it](%%action.newgroup%%) yourself.');
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
$message = sprintf(_('Why not [register an account](%%%%action.%s%%%%) and [create the group](%%%%action.newgroup%%%%) yourself!'),
|
$message = _('Why not [register an account](%%action.register%%) and [create the group](%%action.newgroup%%) yourself!');
|
||||||
(!common_config('site','openidonly')) ? 'register' : 'openidlogin');
|
|
||||||
}
|
}
|
||||||
$this->elementStart('div', 'guide');
|
$this->elementStart('div', 'guide');
|
||||||
$this->raw(common_markup_to_html($message));
|
$this->raw(common_markup_to_html($message));
|
||||||
|
@ -68,7 +68,7 @@ class InviteAction extends CurrentUserDesignAction
|
|||||||
|
|
||||||
foreach ($addresses as $email) {
|
foreach ($addresses as $email) {
|
||||||
$email = trim($email);
|
$email = trim($email);
|
||||||
if (!Validate::email($email, true)) {
|
if (!Validate::email($email, common_config('email', 'check_domain'))) {
|
||||||
$this->showForm(sprintf(_('Invalid email address: %s'), $email));
|
$this->showForm(sprintf(_('Invalid email address: %s'), $email));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -241,7 +241,7 @@ class InviteAction extends CurrentUserDesignAction
|
|||||||
common_root_url(),
|
common_root_url(),
|
||||||
$personal,
|
$personal,
|
||||||
common_local_url('showstream', array('nickname' => $user->nickname)),
|
common_local_url('showstream', array('nickname' => $user->nickname)),
|
||||||
common_local_url((!common_config('site', 'openidonly')) ? 'register' : 'openidlogin', array('code' => $invite->code)));
|
common_local_url('register', array('code' => $invite->code)));
|
||||||
|
|
||||||
mail_send($recipients, $headers, $body);
|
mail_send($recipients, $headers, $body);
|
||||||
}
|
}
|
||||||
|
@ -56,11 +56,6 @@ class JoingroupAction extends Action
|
|||||||
{
|
{
|
||||||
parent::prepare($args);
|
parent::prepare($args);
|
||||||
|
|
||||||
if (!common_config('inboxes','enabled')) {
|
|
||||||
$this->serverError(_('Inboxes must be enabled for groups to work'));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!common_logged_in()) {
|
if (!common_logged_in()) {
|
||||||
$this->clientError(_('You must be logged in to join a group.'));
|
$this->clientError(_('You must be logged in to join a group.'));
|
||||||
return false;
|
return false;
|
||||||
|
@ -56,11 +56,6 @@ class LeavegroupAction extends Action
|
|||||||
{
|
{
|
||||||
parent::prepare($args);
|
parent::prepare($args);
|
||||||
|
|
||||||
if (!common_config('inboxes','enabled')) {
|
|
||||||
$this->serverError(_('Inboxes must be enabled for groups to work.'));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!common_logged_in()) {
|
if (!common_logged_in()) {
|
||||||
$this->clientError(_('You must be logged in to leave a group.'));
|
$this->clientError(_('You must be logged in to leave a group.'));
|
||||||
return false;
|
return false;
|
||||||
|
@ -67,8 +67,6 @@ class LoginAction extends Action
|
|||||||
*
|
*
|
||||||
* Switches on request method; either shows the form or handles its input.
|
* Switches on request method; either shows the form or handles its input.
|
||||||
*
|
*
|
||||||
* Checks if only OpenID is allowed and redirects to openidlogin if so.
|
|
||||||
*
|
|
||||||
* @param array $args $_REQUEST data
|
* @param array $args $_REQUEST data
|
||||||
*
|
*
|
||||||
* @return void
|
* @return void
|
||||||
@ -77,12 +75,12 @@ class LoginAction extends Action
|
|||||||
function handle($args)
|
function handle($args)
|
||||||
{
|
{
|
||||||
parent::handle($args);
|
parent::handle($args);
|
||||||
if (common_config('site', 'openidonly')) {
|
if (common_is_real_login()) {
|
||||||
common_redirect(common_local_url('openidlogin'));
|
|
||||||
} else if (common_is_real_login()) {
|
|
||||||
$this->clientError(_('Already logged in.'));
|
$this->clientError(_('Already logged in.'));
|
||||||
} else if ($_SERVER['REQUEST_METHOD'] == 'POST') {
|
} else if ($_SERVER['REQUEST_METHOD'] == 'POST') {
|
||||||
$this->checkLogin();
|
$this->checkLogin();
|
||||||
|
} else if (isset($args['user_id']) && isset($args['token'])){
|
||||||
|
$this->checkLogin($args['user_id'],$args['token']);
|
||||||
} else {
|
} else {
|
||||||
common_ensure_session();
|
common_ensure_session();
|
||||||
$this->showForm();
|
$this->showForm();
|
||||||
@ -99,23 +97,48 @@ class LoginAction extends Action
|
|||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
|
|
||||||
function checkLogin()
|
function checkLogin($user_id=null, $token=null)
|
||||||
{
|
{
|
||||||
// XXX: login throttle
|
if(isset($token) && isset($user_id)){
|
||||||
|
//Token based login (from the LoginCommand)
|
||||||
|
$login_token = Login_token::staticGet('user_id',$user_id);
|
||||||
|
if($login_token && $login_token->token == $token){
|
||||||
|
if($login_token->modified > time()+2*60){
|
||||||
|
//token has expired
|
||||||
|
//delete the token as it is useless
|
||||||
|
$login_token->delete();
|
||||||
|
$this->showForm(_('Invalid or expired token.'));
|
||||||
|
return;
|
||||||
|
}else{
|
||||||
|
//delete the token so it cannot be reused
|
||||||
|
$login_token->delete();
|
||||||
|
//it's a valid token - let them log in
|
||||||
|
$user = User::staticGet('id', $user_id);
|
||||||
|
//$user = User::staticGet('nickname', "candrews");
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
$this->showForm(_('Invalid or expired token.'));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
// Regular form submission login
|
||||||
|
|
||||||
// CSRF protection - token set in NoticeForm
|
// XXX: login throttle
|
||||||
$token = $this->trimmed('token');
|
|
||||||
if (!$token || $token != common_session_token()) {
|
// CSRF protection - token set in NoticeForm
|
||||||
$this->clientError(_('There was a problem with your session token. '.
|
$token = $this->trimmed('token');
|
||||||
'Try again, please.'));
|
if (!$token || $token != common_session_token()) {
|
||||||
return;
|
$this->clientError(_('There was a problem with your session token. '.
|
||||||
|
'Try again, please.'));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$nickname = $this->trimmed('nickname');
|
||||||
|
$password = $this->arg('password');
|
||||||
|
|
||||||
|
$user = common_check_user($nickname, $password);
|
||||||
}
|
}
|
||||||
|
|
||||||
$nickname = common_canonical_nickname($this->trimmed('nickname'));
|
|
||||||
$password = $this->arg('password');
|
|
||||||
|
|
||||||
$user = common_check_user($nickname, $password);
|
|
||||||
|
|
||||||
if (!$user) {
|
if (!$user) {
|
||||||
$this->showForm(_('Incorrect username or password.'));
|
$this->showForm(_('Incorrect username or password.'));
|
||||||
return;
|
return;
|
||||||
@ -123,7 +146,7 @@ class LoginAction extends Action
|
|||||||
|
|
||||||
// success!
|
// success!
|
||||||
if (!common_set_user($user)) {
|
if (!common_set_user($user)) {
|
||||||
$this->serverError(_('Error setting user.'));
|
$this->serverError(_('Error setting user. You are probably not authorized.'));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -141,7 +164,7 @@ class LoginAction extends Action
|
|||||||
} else {
|
} else {
|
||||||
$url = common_local_url('all',
|
$url = common_local_url('all',
|
||||||
array('nickname' =>
|
array('nickname' =>
|
||||||
$nickname));
|
$user->nickname));
|
||||||
}
|
}
|
||||||
|
|
||||||
common_redirect($url, 303);
|
common_redirect($url, 303);
|
||||||
@ -259,11 +282,6 @@ class LoginAction extends Action
|
|||||||
return _('For security reasons, please re-enter your ' .
|
return _('For security reasons, please re-enter your ' .
|
||||||
'user name and password ' .
|
'user name and password ' .
|
||||||
'before changing your settings.');
|
'before changing your settings.');
|
||||||
} else if (common_config('openid', 'enabled')) {
|
|
||||||
return _('Login with your username and password. ' .
|
|
||||||
'Don\'t have a username yet? ' .
|
|
||||||
'[Register](%%action.register%%) a new account, or ' .
|
|
||||||
'try [OpenID](%%action.openidlogin%%). ');
|
|
||||||
} else {
|
} else {
|
||||||
return _('Login with your username and password. ' .
|
return _('Login with your username and password. ' .
|
||||||
'Don\'t have a username yet? ' .
|
'Don\'t have a username yet? ' .
|
||||||
|
@ -32,8 +32,6 @@ if (!defined('STATUSNET') && !defined('LACONICA')) {
|
|||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
require_once INSTALLDIR.'/lib/openid.php';
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Logout action class.
|
* Logout action class.
|
||||||
*
|
*
|
||||||
|
@ -59,7 +59,7 @@ class MicrosummaryAction extends Action
|
|||||||
$user = User::staticGet('nickname', $nickname);
|
$user = User::staticGet('nickname', $nickname);
|
||||||
|
|
||||||
if (!$user) {
|
if (!$user) {
|
||||||
$this->clientError(_('No such user'), 404);
|
$this->clientError(_('No such user.'), 404);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -61,11 +61,6 @@ class NewgroupAction extends Action
|
|||||||
{
|
{
|
||||||
parent::prepare($args);
|
parent::prepare($args);
|
||||||
|
|
||||||
if (!common_config('inboxes','enabled')) {
|
|
||||||
$this->serverError(_('Inboxes must be enabled for groups to work'));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!common_logged_in()) {
|
if (!common_logged_in()) {
|
||||||
$this->clientError(_('You must be logged in to create a group.'));
|
$this->clientError(_('You must be logged in to create a group.'));
|
||||||
return false;
|
return false;
|
||||||
@ -146,8 +141,8 @@ class NewgroupAction extends Action
|
|||||||
} else if (!is_null($fullname) && mb_strlen($fullname) > 255) {
|
} else if (!is_null($fullname) && mb_strlen($fullname) > 255) {
|
||||||
$this->showForm(_('Full name is too long (max 255 chars).'));
|
$this->showForm(_('Full name is too long (max 255 chars).'));
|
||||||
return;
|
return;
|
||||||
} else if (!is_null($description) && mb_strlen($description) > 140) {
|
} else if (User_group::descriptionTooLong($description)) {
|
||||||
$this->showForm(_('description is too long (max 140 chars).'));
|
$this->showForm(sprintf(_('description is too long (max %d chars).'), User_group::maxDescription()));
|
||||||
return;
|
return;
|
||||||
} else if (!is_null($location) && mb_strlen($location) > 255) {
|
} else if (!is_null($location) && mb_strlen($location) > 255) {
|
||||||
$this->showForm(_('Location is too long (max 255 chars).'));
|
$this->showForm(_('Location is too long (max 255 chars).'));
|
||||||
@ -191,45 +186,13 @@ class NewgroupAction extends Action
|
|||||||
|
|
||||||
assert(!is_null($cur));
|
assert(!is_null($cur));
|
||||||
|
|
||||||
$group = new User_group();
|
$group = User_group::register(array('nickname' => $nickname,
|
||||||
|
'fullname' => $fullname,
|
||||||
$group->query('BEGIN');
|
'homepage' => $homepage,
|
||||||
|
'description' => $description,
|
||||||
$group->nickname = $nickname;
|
'location' => $location,
|
||||||
$group->fullname = $fullname;
|
'aliases' => $aliases,
|
||||||
$group->homepage = $homepage;
|
'userid' => $cur->id));
|
||||||
$group->description = $description;
|
|
||||||
$group->location = $location;
|
|
||||||
$group->created = common_sql_now();
|
|
||||||
|
|
||||||
$result = $group->insert();
|
|
||||||
|
|
||||||
if (!$result) {
|
|
||||||
common_log_db_error($group, 'INSERT', __FILE__);
|
|
||||||
$this->serverError(_('Could not create group.'));
|
|
||||||
}
|
|
||||||
|
|
||||||
$result = $group->setAliases($aliases);
|
|
||||||
|
|
||||||
if (!$result) {
|
|
||||||
$this->serverError(_('Could not create aliases.'));
|
|
||||||
}
|
|
||||||
|
|
||||||
$member = new Group_member();
|
|
||||||
|
|
||||||
$member->group_id = $group->id;
|
|
||||||
$member->profile_id = $cur->id;
|
|
||||||
$member->is_admin = 1;
|
|
||||||
$member->created = $group->created;
|
|
||||||
|
|
||||||
$result = $member->insert();
|
|
||||||
|
|
||||||
if (!$result) {
|
|
||||||
common_log_db_error($member, 'INSERT', __FILE__);
|
|
||||||
$this->serverError(_('Could not set group membership.'));
|
|
||||||
}
|
|
||||||
|
|
||||||
$group->query('COMMIT');
|
|
||||||
|
|
||||||
common_redirect($group->homeUrl(), 303);
|
common_redirect($group->homeUrl(), 303);
|
||||||
}
|
}
|
||||||
|
@ -99,7 +99,9 @@ class NewmessageAction extends Action
|
|||||||
$user = common_current_user();
|
$user = common_current_user();
|
||||||
|
|
||||||
if (!$user) {
|
if (!$user) {
|
||||||
$this->clientError(_('Only logged-in users can send direct messages.'), 403);
|
/* Go log in, and then come back. */
|
||||||
|
common_set_returnto($_SERVER['REQUEST_URI']);
|
||||||
|
common_redirect(common_local_url('login'));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -111,7 +113,7 @@ class NewmessageAction extends Action
|
|||||||
$this->other = User::staticGet('id', $this->to);
|
$this->other = User::staticGet('id', $this->to);
|
||||||
|
|
||||||
if (!$this->other) {
|
if (!$this->other) {
|
||||||
$this->clientError(_('No such user'), 404);
|
$this->clientError(_('No such user.'), 404);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -144,9 +146,10 @@ class NewmessageAction extends Action
|
|||||||
} else {
|
} else {
|
||||||
$content_shortened = common_shorten_links($this->content);
|
$content_shortened = common_shorten_links($this->content);
|
||||||
|
|
||||||
if (mb_strlen($content_shortened) > 140) {
|
if (Message::contentTooLong($content_shortened)) {
|
||||||
$this->showForm(_('That\'s too long. ' .
|
$this->showForm(sprintf(_('That\'s too long. ' .
|
||||||
'Max message size is 140 chars.'));
|
'Max message size is %d chars.'),
|
||||||
|
Message::maxContent()));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -220,7 +223,21 @@ class NewmessageAction extends Action
|
|||||||
}
|
}
|
||||||
|
|
||||||
$this->msg = $msg;
|
$this->msg = $msg;
|
||||||
$this->showPage();
|
if ($this->trimmed('ajax')) {
|
||||||
|
header('Content-Type: text/xml;charset=utf-8');
|
||||||
|
$this->xw->startDocument('1.0', 'UTF-8');
|
||||||
|
$this->elementStart('html');
|
||||||
|
$this->elementStart('head');
|
||||||
|
$this->element('title', null, _('New message'));
|
||||||
|
$this->elementEnd('head');
|
||||||
|
$this->elementStart('body');
|
||||||
|
$this->showNoticeForm();
|
||||||
|
$this->elementEnd('body');
|
||||||
|
$this->endHTML();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$this->showPage();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function showPageNotice()
|
function showPageNotice()
|
||||||
|
@ -33,7 +33,8 @@ if (!defined('STATUSNET') && !defined('LACONICA')) {
|
|||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
require_once INSTALLDIR.'/lib/noticelist.php';
|
require_once INSTALLDIR . '/lib/noticelist.php';
|
||||||
|
require_once INSTALLDIR . '/lib/mediafile.php';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Action for posting new notices
|
* Action for posting new notices
|
||||||
@ -113,33 +114,6 @@ class NewnoticeAction extends Action
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function getUploadedFileType() {
|
|
||||||
require_once 'MIME/Type.php';
|
|
||||||
|
|
||||||
$cmd = &PEAR::getStaticProperty('MIME_Type', 'fileCmd');
|
|
||||||
$cmd = common_config('attachments', 'filecommand');
|
|
||||||
|
|
||||||
$filetype = MIME_Type::autoDetect($_FILES['attach']['tmp_name']);
|
|
||||||
if (in_array($filetype, common_config('attachments', 'supported'))) {
|
|
||||||
return $filetype;
|
|
||||||
}
|
|
||||||
$media = MIME_Type::getMedia($filetype);
|
|
||||||
if ('application' !== $media) {
|
|
||||||
$hint = sprintf(_(' Try using another %s format.'), $media);
|
|
||||||
} else {
|
|
||||||
$hint = '';
|
|
||||||
}
|
|
||||||
$this->clientError(sprintf(
|
|
||||||
_('%s is not a supported filetype on this server.'), $filetype) . $hint);
|
|
||||||
}
|
|
||||||
|
|
||||||
function isRespectsQuota($user) {
|
|
||||||
$file = new File;
|
|
||||||
$ret = $file->isRespectsQuota($user,$_FILES['attach']['size']);
|
|
||||||
if (true === $ret) return true;
|
|
||||||
$this->clientError($ret);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Save a new notice, based on arguments
|
* Save a new notice, based on arguments
|
||||||
*
|
*
|
||||||
@ -160,17 +134,12 @@ class NewnoticeAction extends Action
|
|||||||
|
|
||||||
if (!$content) {
|
if (!$content) {
|
||||||
$this->clientError(_('No content!'));
|
$this->clientError(_('No content!'));
|
||||||
} else {
|
return;
|
||||||
$content_shortened = common_shorten_links($content);
|
|
||||||
if (mb_strlen($content_shortened) > 140) {
|
|
||||||
$this->clientError(_('That\'s too long. '.
|
|
||||||
'Max notice size is 140 chars.'));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$inter = new CommandInterpreter();
|
$inter = new CommandInterpreter();
|
||||||
|
|
||||||
$cmd = $inter->handle_command($user, $content_shortened);
|
$cmd = $inter->handle_command($user, $content);
|
||||||
|
|
||||||
if ($cmd) {
|
if ($cmd) {
|
||||||
if ($this->boolean('ajax')) {
|
if ($this->boolean('ajax')) {
|
||||||
@ -181,6 +150,13 @@ class NewnoticeAction extends Action
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$content_shortened = common_shorten_links($content);
|
||||||
|
if (Notice::contentTooLong($content_shortened)) {
|
||||||
|
$this->clientError(sprintf(_('That\'s too long. '.
|
||||||
|
'Max notice size is %d chars.'),
|
||||||
|
Notice::maxContent()));
|
||||||
|
}
|
||||||
|
|
||||||
$replyto = $this->trimmed('inreplyto');
|
$replyto = $this->trimmed('inreplyto');
|
||||||
#If an ID of 0 is wrongly passed here, it will cause a database error,
|
#If an ID of 0 is wrongly passed here, it will cause a database error,
|
||||||
#so override it...
|
#so override it...
|
||||||
@ -188,84 +164,36 @@ class NewnoticeAction extends Action
|
|||||||
$replyto = 'false';
|
$replyto = 'false';
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isset($_FILES['attach']['error'])) {
|
$lat = $this->trimmed('lat');
|
||||||
switch ($_FILES['attach']['error']) {
|
$lon = $this->trimmed('lon');
|
||||||
case UPLOAD_ERR_NO_FILE:
|
$location_id = $this->trimmed('location_id');
|
||||||
// no file uploaded, nothing to do
|
$location_ns = $this->trimmed('location_ns');
|
||||||
break;
|
|
||||||
|
|
||||||
case UPLOAD_ERR_OK:
|
$upload = null;
|
||||||
$mimetype = $this->getUploadedFileType();
|
$upload = MediaFile::fromUpload('attach');
|
||||||
if (!$this->isRespectsQuota($user)) {
|
|
||||||
die('clientError() should trigger an exception before reaching here.');
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case UPLOAD_ERR_INI_SIZE:
|
if (isset($upload)) {
|
||||||
$this->clientError(_('The uploaded file exceeds the upload_max_filesize directive in php.ini.'));
|
|
||||||
|
|
||||||
case UPLOAD_ERR_FORM_SIZE:
|
$content_shortened .= ' ' . $upload->shortUrl();
|
||||||
$this->clientError(_('The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form.'));
|
|
||||||
|
|
||||||
case UPLOAD_ERR_PARTIAL:
|
if (Notice::contentTooLong($content_shortened)) {
|
||||||
$this->clientError(_('The uploaded file was only partially uploaded.'));
|
$upload->delete();
|
||||||
|
$this->clientError(
|
||||||
case UPLOAD_ERR_NO_TMP_DIR:
|
sprintf(
|
||||||
$this->clientError(_('Missing a temporary folder.'));
|
_('Max notice size is %d chars, including attachment URL.'),
|
||||||
|
Notice::maxContent()
|
||||||
case UPLOAD_ERR_CANT_WRITE:
|
)
|
||||||
$this->clientError(_('Failed to write file to disk.'));
|
);
|
||||||
|
|
||||||
case UPLOAD_ERR_EXTENSION:
|
|
||||||
$this->clientError(_('File upload stopped by extension.'));
|
|
||||||
|
|
||||||
default:
|
|
||||||
die('Should never reach here.');
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isset($mimetype)) {
|
|
||||||
$filename = $this->saveFile($mimetype);
|
|
||||||
if (empty($filename)) {
|
|
||||||
$this->clientError(_('Couldn\'t save file.'));
|
|
||||||
}
|
|
||||||
|
|
||||||
$fileRecord = $this->storeFile($filename, $mimetype);
|
|
||||||
|
|
||||||
$fileurl = common_local_url('attachment',
|
|
||||||
array('attachment' => $fileRecord->id));
|
|
||||||
|
|
||||||
// not sure this is necessary -- Zach
|
|
||||||
$this->maybeAddRedir($fileRecord->id, $fileurl);
|
|
||||||
|
|
||||||
$short_fileurl = common_shorten_url($fileurl);
|
|
||||||
if (!$short_fileurl) {
|
|
||||||
// todo -- Consider forcing default shortener if none selected?
|
|
||||||
$short_fileurl = $fileurl;
|
|
||||||
}
|
|
||||||
$content_shortened .= ' ' . $short_fileurl;
|
|
||||||
|
|
||||||
if (mb_strlen($content_shortened) > 140) {
|
|
||||||
$this->deleteFile($filename);
|
|
||||||
$this->clientError(_('Max notice size is 140 chars, including attachment URL.'));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Also, not sure this is necessary -- Zach
|
|
||||||
$this->maybeAddRedir($fileRecord->id, $short_fileurl);
|
|
||||||
}
|
|
||||||
|
|
||||||
$notice = Notice::saveNew($user->id, $content_shortened, 'web', 1,
|
$notice = Notice::saveNew($user->id, $content_shortened, 'web', 1,
|
||||||
($replyto == 'false') ? null : $replyto);
|
($replyto == 'false') ? null : $replyto,
|
||||||
|
null, null,
|
||||||
|
$lat, $lon, $location_id, $location_ns);
|
||||||
|
|
||||||
if (is_string($notice)) {
|
if (isset($upload)) {
|
||||||
if (isset($filename)) {
|
$upload->attachToNotice($notice);
|
||||||
$this->deleteFile($filename);
|
|
||||||
}
|
|
||||||
$this->clientError($notice);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isset($mimetype)) {
|
|
||||||
$this->attachFile($notice, $fileRecord);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
common_broadcast_notice($notice);
|
common_broadcast_notice($notice);
|
||||||
@ -295,87 +223,6 @@ class NewnoticeAction extends Action
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function saveFile($mimetype) {
|
|
||||||
|
|
||||||
$cur = common_current_user();
|
|
||||||
|
|
||||||
if (empty($cur)) {
|
|
||||||
$this->serverError(_('Somehow lost the login in saveFile'));
|
|
||||||
}
|
|
||||||
|
|
||||||
$basename = basename($_FILES['attach']['name']);
|
|
||||||
|
|
||||||
$filename = File::filename($cur->getProfile(), $basename, $mimetype);
|
|
||||||
|
|
||||||
$filepath = File::path($filename);
|
|
||||||
|
|
||||||
if (move_uploaded_file($_FILES['attach']['tmp_name'], $filepath)) {
|
|
||||||
return $filename;
|
|
||||||
} else {
|
|
||||||
$this->clientError(_('File could not be moved to destination directory.'));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function deleteFile($filename)
|
|
||||||
{
|
|
||||||
$filepath = File::path($filename);
|
|
||||||
@unlink($filepath);
|
|
||||||
}
|
|
||||||
|
|
||||||
function storeFile($filename, $mimetype) {
|
|
||||||
|
|
||||||
$file = new File;
|
|
||||||
$file->filename = $filename;
|
|
||||||
|
|
||||||
$file->url = File::url($filename);
|
|
||||||
|
|
||||||
$filepath = File::path($filename);
|
|
||||||
|
|
||||||
$file->size = filesize($filepath);
|
|
||||||
$file->date = time();
|
|
||||||
$file->mimetype = $mimetype;
|
|
||||||
|
|
||||||
$file_id = $file->insert();
|
|
||||||
|
|
||||||
if (!$file_id) {
|
|
||||||
common_log_db_error($file, "INSERT", __FILE__);
|
|
||||||
$this->clientError(_('There was a database error while saving your file. Please try again.'));
|
|
||||||
}
|
|
||||||
|
|
||||||
return $file;
|
|
||||||
}
|
|
||||||
|
|
||||||
function rememberFile($file, $short)
|
|
||||||
{
|
|
||||||
$this->maybeAddRedir($file->id, $short);
|
|
||||||
}
|
|
||||||
|
|
||||||
function maybeAddRedir($file_id, $url)
|
|
||||||
{
|
|
||||||
$file_redir = File_redirection::staticGet('url', $url);
|
|
||||||
|
|
||||||
if (empty($file_redir)) {
|
|
||||||
$file_redir = new File_redirection;
|
|
||||||
$file_redir->url = $url;
|
|
||||||
$file_redir->file_id = $file_id;
|
|
||||||
|
|
||||||
$result = $file_redir->insert();
|
|
||||||
|
|
||||||
if (!$result) {
|
|
||||||
common_log_db_error($file_redir, "INSERT", __FILE__);
|
|
||||||
$this->clientError(_('There was a database error while saving your file. Please try again.'));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function attachFile($notice, $filerec)
|
|
||||||
{
|
|
||||||
File_to_post::processNew($filerec->id, $notice->id);
|
|
||||||
|
|
||||||
$this->maybeAddRedir($filerec->id,
|
|
||||||
common_local_url('file', array('notice' => $notice->id)));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Show an Ajax-y error message
|
* Show an Ajax-y error message
|
||||||
*
|
*
|
||||||
|
@ -104,7 +104,7 @@ class NoticesearchAction extends SearchAction
|
|||||||
{
|
{
|
||||||
$notice = new Notice();
|
$notice = new Notice();
|
||||||
|
|
||||||
$search_engine = $notice->getSearchEngine('identica_notices');
|
$search_engine = $notice->getSearchEngine('notice');
|
||||||
$search_engine->set_sort_mode('chron');
|
$search_engine->set_sort_mode('chron');
|
||||||
// Ask for an extra to see if there's more.
|
// Ask for an extra to see if there's more.
|
||||||
$search_engine->limit((($page-1)*NOTICES_PER_PAGE), NOTICES_PER_PAGE + 1);
|
$search_engine->limit((($page-1)*NOTICES_PER_PAGE), NOTICES_PER_PAGE + 1);
|
||||||
@ -121,9 +121,7 @@ class NoticesearchAction extends SearchAction
|
|||||||
$message = sprintf(_('Be the first to [post on this topic](%%%%action.newnotice%%%%?status_textarea=%s)!'), urlencode($q));
|
$message = sprintf(_('Be the first to [post on this topic](%%%%action.newnotice%%%%?status_textarea=%s)!'), urlencode($q));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
$message = sprintf(_('Why not [register an account](%%%%action.%s%%%%) and be the first to [post on this topic](%%%%action.newnotice%%%%?status_textarea=%s)!'),
|
$message = sprintf(_('Why not [register an account](%%%%action.register%%%%) and be the first to [post on this topic](%%%%action.newnotice%%%%?status_textarea=%s)!'), urlencode($q));
|
||||||
(!common_config('site','openidonly')) ? 'register' : 'openidlogin',
|
|
||||||
urlencode($q));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->elementStart('div', 'guide');
|
$this->elementStart('div', 'guide');
|
||||||
|
@ -62,7 +62,7 @@ class NoticesearchrssAction extends Rss10Action
|
|||||||
|
|
||||||
$notice = new Notice();
|
$notice = new Notice();
|
||||||
|
|
||||||
$search_engine = $notice->getSearchEngine('identica_notices');
|
$search_engine = $notice->getSearchEngine('notice');
|
||||||
$search_engine->set_sort_mode('chron');
|
$search_engine->set_sort_mode('chron');
|
||||||
|
|
||||||
if (!$limit) $limit = 20;
|
if (!$limit) $limit = 20;
|
||||||
|
@ -75,7 +75,7 @@ class OpensearchAction extends Action
|
|||||||
$this->element('Url', array('type' => 'text/html', 'method' => 'get',
|
$this->element('Url', array('type' => 'text/html', 'method' => 'get',
|
||||||
'template' => str_replace('---', '{searchTerms}', common_local_url($type, array('q' => '---')))));
|
'template' => str_replace('---', '{searchTerms}', common_local_url($type, array('q' => '---')))));
|
||||||
$this->element('Image', array('height' => 16, 'width' => 16, 'type' => 'image/vnd.microsoft.icon'), common_path('favicon.ico'));
|
$this->element('Image', array('height' => 16, 'width' => 16, 'type' => 'image/vnd.microsoft.icon'), common_path('favicon.ico'));
|
||||||
$this->element('Image', array('height' => 50, 'width' => 50, 'type' => 'image/png'), theme_path('logo.png'));
|
$this->element('Image', array('height' => 50, 'width' => 50, 'type' => 'image/png'), Theme::path('logo.png'));
|
||||||
$this->element('AdultContent', null, 'false');
|
$this->element('AdultContent', null, 'false');
|
||||||
$this->element('Language', null, common_language());
|
$this->element('Language', null, common_language());
|
||||||
$this->element('OutputEncoding', null, 'UTF-8');
|
$this->element('OutputEncoding', null, 'UTF-8');
|
||||||
|
@ -96,27 +96,28 @@ class OthersettingsAction extends AccountSettingsAction
|
|||||||
common_local_url('othersettings')));
|
common_local_url('othersettings')));
|
||||||
$this->elementStart('fieldset');
|
$this->elementStart('fieldset');
|
||||||
$this->hidden('token', common_session_token());
|
$this->hidden('token', common_session_token());
|
||||||
|
|
||||||
// I18N
|
|
||||||
|
|
||||||
$services = array(
|
|
||||||
'' => 'None',
|
|
||||||
'ur1.ca' => 'ur1.ca (free service)',
|
|
||||||
'2tu.us' => '2tu.us (free service)',
|
|
||||||
'ptiturl.com' => 'ptiturl.com',
|
|
||||||
'bit.ly' => 'bit.ly',
|
|
||||||
'tinyurl.com' => 'tinyurl.com',
|
|
||||||
'is.gd' => 'is.gd',
|
|
||||||
'snipr.com' => 'snipr.com',
|
|
||||||
'metamark.net' => 'metamark.net'
|
|
||||||
);
|
|
||||||
|
|
||||||
$this->elementStart('ul', 'form_data');
|
$this->elementStart('ul', 'form_data');
|
||||||
$this->elementStart('li');
|
|
||||||
$this->dropdown('urlshorteningservice', _('Shorten URLs with'),
|
$shorteners = array();
|
||||||
$services, _('Automatic shortening service to use.'),
|
Event::handle('GetUrlShorteners', array(&$shorteners));
|
||||||
false, $user->urlshorteningservice);
|
$services = array();
|
||||||
$this->elementEnd('li');
|
foreach($shorteners as $name=>$value)
|
||||||
|
{
|
||||||
|
$services[$name]=$name;
|
||||||
|
if($value['freeService']){
|
||||||
|
$services[$name].=_(' (free service)');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if($services)
|
||||||
|
{
|
||||||
|
asort($services);
|
||||||
|
|
||||||
|
$this->elementStart('li');
|
||||||
|
$this->dropdown('urlshorteningservice', _('Shorten URLs with'),
|
||||||
|
$services, _('Automatic shortening service to use.'),
|
||||||
|
false, $user->urlshorteningservice);
|
||||||
|
$this->elementEnd('li');
|
||||||
|
}
|
||||||
$this->elementStart('li');
|
$this->elementStart('li');
|
||||||
$this->checkbox('viewdesigns', _('View profile designs'),
|
$this->checkbox('viewdesigns', _('View profile designs'),
|
||||||
$user->viewdesigns, _('Show or hide profile designs.'));
|
$user->viewdesigns, _('Show or hide profile designs.'));
|
||||||
|
@ -86,6 +86,7 @@ class PasswordsettingsAction extends AccountSettingsAction
|
|||||||
function showContent()
|
function showContent()
|
||||||
{
|
{
|
||||||
$user = common_current_user();
|
$user = common_current_user();
|
||||||
|
|
||||||
$this->elementStart('form', array('method' => 'POST',
|
$this->elementStart('form', array('method' => 'POST',
|
||||||
'id' => 'form_password',
|
'id' => 'form_password',
|
||||||
'class' => 'form_settings',
|
'class' => 'form_settings',
|
||||||
@ -164,21 +165,28 @@ class PasswordsettingsAction extends AccountSettingsAction
|
|||||||
$this->showForm(_('Incorrect old password'));
|
$this->showForm(_('Incorrect old password'));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
}else{
|
||||||
|
$oldpassword = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
$original = clone($user);
|
$success = false;
|
||||||
|
if(! Event::handle('StartChangePassword', array($user, $oldpassword, $newpassword))){
|
||||||
|
//no handler changed the password, so change the password internally
|
||||||
|
$original = clone($user);
|
||||||
|
|
||||||
$user->password = common_munge_password($newpassword, $user->id);
|
$user->password = common_munge_password($newpassword, $user->id);
|
||||||
|
|
||||||
$val = $user->validate();
|
$val = $user->validate();
|
||||||
if ($val !== true) {
|
if ($val !== true) {
|
||||||
$this->showForm(_('Error saving user; invalid.'));
|
$this->showForm(_('Error saving user; invalid.'));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!$user->update($original)) {
|
if (!$user->update($original)) {
|
||||||
$this->serverError(_('Can\'t save new password.'));
|
$this->serverError(_('Can\'t save new password.'));
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
Event::handle('EndChangePassword', array($user));
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->showForm(_('Password saved.'), true);
|
$this->showForm(_('Password saved.'), true);
|
||||||
|
320
actions/pathsadminpanel.php
Normal file
320
actions/pathsadminpanel.php
Normal file
@ -0,0 +1,320 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* StatusNet, the distributed open-source microblogging tool
|
||||||
|
*
|
||||||
|
* Paths 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 Evan Prodromou <evan@status.net>
|
||||||
|
* @author Zach Copley <zach@status.net>
|
||||||
|
* @author Sarven Capadisli <csarven@status.net>
|
||||||
|
* @copyright 2008-2009 StatusNet, Inc.
|
||||||
|
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||||
|
* @link http://status.net/
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (!defined('STATUSNET')) {
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Paths settings
|
||||||
|
*
|
||||||
|
* @category Admin
|
||||||
|
* @package StatusNet
|
||||||
|
* @author Evan Prodromou <evan@status.net>
|
||||||
|
* @author Zach Copley <zach@status.net>
|
||||||
|
* @author Sarven Capadisli <csarven@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 PathsadminpanelAction extends AdminPanelAction
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the page title
|
||||||
|
*
|
||||||
|
* @return string page title
|
||||||
|
*/
|
||||||
|
|
||||||
|
function title()
|
||||||
|
{
|
||||||
|
return _('Paths');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Instructions for using this form.
|
||||||
|
*
|
||||||
|
* @return string instructions
|
||||||
|
*/
|
||||||
|
|
||||||
|
function getInstructions()
|
||||||
|
{
|
||||||
|
return _('Path and server settings for this StatusNet site.');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Show the paths admin panel form
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
|
||||||
|
function showForm()
|
||||||
|
{
|
||||||
|
$form = new PathsAdminPanelForm($this);
|
||||||
|
$form->show();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Save settings from the form
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
|
||||||
|
function saveSettings()
|
||||||
|
{
|
||||||
|
static $settings = array(
|
||||||
|
'site' => array('path', 'locale_path'),
|
||||||
|
'theme' => array('server', 'dir', 'path'),
|
||||||
|
'avatar' => array('server', 'dir', 'path'),
|
||||||
|
'background' => array('server', 'dir', 'path')
|
||||||
|
);
|
||||||
|
|
||||||
|
$values = array();
|
||||||
|
|
||||||
|
foreach ($settings as $section => $parts) {
|
||||||
|
foreach ($parts as $setting) {
|
||||||
|
$values[$section][$setting] = $this->trimmed("$section-$setting");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$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;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Attempt to validate setting values
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
|
||||||
|
function validate(&$values)
|
||||||
|
{
|
||||||
|
|
||||||
|
// Validate theme dir
|
||||||
|
|
||||||
|
if (!empty($values['theme']['dir']) && !is_readable($values['theme']['dir'])) {
|
||||||
|
$this->clientError(sprintf(_("Theme directory not readable: %s"), $values['theme']['dir']));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Validate avatar dir
|
||||||
|
|
||||||
|
if (empty($values['avatar']['dir']) || !is_writable($values['avatar']['dir'])) {
|
||||||
|
$this->clientError(sprintf(_("Avatar directory not writable: %s"), $values['avatar']['dir']));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Validate background dir
|
||||||
|
|
||||||
|
if (empty($values['background']['dir']) || !is_writable($values['background']['dir'])) {
|
||||||
|
$this->clientError(sprintf(_("Background directory not writable: %s"), $values['background']['dir']));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Validate locales dir
|
||||||
|
|
||||||
|
// XXX: What else do we need to validate for lacales path here? --Z
|
||||||
|
|
||||||
|
if (!empty($values['site']['locale_path']) && !is_readable($values['site']['locale_path'])) {
|
||||||
|
$this->clientError(sprintf(_("Locales directory not readable: %s"), $values['site']['locale_path']));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
class PathsAdminPanelForm extends AdminForm
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ID of the form
|
||||||
|
*
|
||||||
|
* @return int ID of the form
|
||||||
|
*/
|
||||||
|
|
||||||
|
function id()
|
||||||
|
{
|
||||||
|
return 'form_paths_admin_panel';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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('pathsadminpanel');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Data elements of the form
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
|
||||||
|
function formData()
|
||||||
|
{
|
||||||
|
$this->out->elementStart('fieldset', array('id' => 'settings_paths_locale'));
|
||||||
|
$this->out->element('legend', null, _('Site'), 'site');
|
||||||
|
$this->out->elementStart('ul', 'form_data');
|
||||||
|
|
||||||
|
$this->li();
|
||||||
|
$this->input('path', _('Path'), _('Site path'));
|
||||||
|
$this->unli();
|
||||||
|
|
||||||
|
$this->li();
|
||||||
|
$this->input('locale_path', _('Path to locales'), _('Directory path to locales'), 'site');
|
||||||
|
$this->unli();
|
||||||
|
|
||||||
|
$this->out->elementEnd('ul');
|
||||||
|
$this->out->elementEnd('fieldset');
|
||||||
|
|
||||||
|
$this->out->elementStart('fieldset', array('id' => 'settings_paths_theme'));
|
||||||
|
$this->out->element('legend', null, _('Theme'));
|
||||||
|
|
||||||
|
$this->out->elementStart('ul', 'form_data');
|
||||||
|
|
||||||
|
$this->li();
|
||||||
|
$this->input('server', _('Theme server'), 'Server for themes', 'theme');
|
||||||
|
$this->unli();
|
||||||
|
|
||||||
|
$this->li();
|
||||||
|
$this->input('path', _('Theme path'), 'Web path to themes', 'theme');
|
||||||
|
$this->unli();
|
||||||
|
|
||||||
|
$this->li();
|
||||||
|
$this->input('dir', _('Theme directory'), 'Directory where themes are located', 'theme');
|
||||||
|
$this->unli();
|
||||||
|
|
||||||
|
$this->out->elementEnd('ul');
|
||||||
|
|
||||||
|
$this->out->elementEnd('fieldset');
|
||||||
|
$this->out->elementStart('fieldset', array('id' => 'settings_avatar-paths'));
|
||||||
|
$this->out->element('legend', null, _('Avatars'));
|
||||||
|
|
||||||
|
$this->out->elementStart('ul', 'form_data');
|
||||||
|
|
||||||
|
$this->li();
|
||||||
|
$this->input('server', _('Avatar server'), 'Server for avatars', 'avatar');
|
||||||
|
$this->unli();
|
||||||
|
|
||||||
|
$this->li();
|
||||||
|
$this->input('path', _('Avatar path'), 'Web path to avatars', 'avatar');
|
||||||
|
$this->unli();
|
||||||
|
|
||||||
|
$this->li();
|
||||||
|
$this->input('dir', _('Avatar directory'), 'Directory where avatars are located', 'avatar');
|
||||||
|
$this->unli();
|
||||||
|
|
||||||
|
$this->out->elementEnd('ul');
|
||||||
|
|
||||||
|
$this->out->elementEnd('fieldset');
|
||||||
|
|
||||||
|
$this->out->elementStart('fieldset', array('id' =>
|
||||||
|
'settings_design_background-paths'));
|
||||||
|
$this->out->element('legend', null, _('Backgrounds'));
|
||||||
|
$this->out->elementStart('ul', 'form_data');
|
||||||
|
|
||||||
|
$this->li();
|
||||||
|
$this->input('server', _('Background server'), 'Server for backgrounds', 'background');
|
||||||
|
$this->unli();
|
||||||
|
|
||||||
|
$this->li();
|
||||||
|
$this->input('path', _('Background path'), 'Web path to backgrounds', 'background');
|
||||||
|
$this->unli();
|
||||||
|
|
||||||
|
$this->li();
|
||||||
|
$this->input('dir', _('Background directory'), 'Directory where backgrounds are located', 'background');
|
||||||
|
$this->unli();
|
||||||
|
|
||||||
|
$this->out->elementEnd('ul');
|
||||||
|
$this->out->elementEnd('fieldset');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Action elements
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
|
||||||
|
function formActions()
|
||||||
|
{
|
||||||
|
$this->out->submit('save', _('Save'), 'submit form_action-secondary',
|
||||||
|
'save', _('Save paths'));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Utility to simplify some of the duplicated code around
|
||||||
|
* params and settings. Overriding the input() in the base class
|
||||||
|
* to handle a whole bunch of cases of settings with the same
|
||||||
|
* name under different sections.
|
||||||
|
*
|
||||||
|
* @param string $setting Name of the setting
|
||||||
|
* @param string $title Title to use for the input
|
||||||
|
* @param string $instructions Instructions for this field
|
||||||
|
* @param string $section config section, default = 'site'
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
|
||||||
|
function input($setting, $title, $instructions, $section='site')
|
||||||
|
{
|
||||||
|
$this->out->input("$section-$setting", $title, $this->value($setting, $section), $instructions);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -61,7 +61,7 @@ class PeoplesearchAction extends SearchAction
|
|||||||
function showResults($q, $page)
|
function showResults($q, $page)
|
||||||
{
|
{
|
||||||
$profile = new Profile();
|
$profile = new Profile();
|
||||||
$search_engine = $profile->getSearchEngine('identica_people');
|
$search_engine = $profile->getSearchEngine('profile');
|
||||||
$search_engine->set_sort_mode('chron');
|
$search_engine->set_sort_mode('chron');
|
||||||
// Ask for an extra to see if there's more.
|
// Ask for an extra to see if there's more.
|
||||||
$search_engine->limit((($page-1)*PROFILES_PER_PAGE), PROFILES_PER_PAGE + 1);
|
$search_engine->limit((($page-1)*PROFILES_PER_PAGE), PROFILES_PER_PAGE + 1);
|
||||||
|
@ -1,5 +1,16 @@
|
|||||||
<?php
|
<?php
|
||||||
/*
|
/**
|
||||||
|
* Handle postnotice action
|
||||||
|
*
|
||||||
|
* PHP version 5
|
||||||
|
*
|
||||||
|
* @category Action
|
||||||
|
* @package StatusNet
|
||||||
|
* @author Evan Prodromou <evan@status.net>
|
||||||
|
* @author Robin Millette <millette@status.net>
|
||||||
|
* @license http://www.fsf.org/licensing/licenses/agpl.html AGPLv3
|
||||||
|
* @link http://status.net/
|
||||||
|
*
|
||||||
* StatusNet - the distributed open-source microblogging tool
|
* StatusNet - the distributed open-source microblogging tool
|
||||||
* Copyright (C) 2008, 2009, StatusNet, Inc.
|
* Copyright (C) 2008, 2009, StatusNet, Inc.
|
||||||
*
|
*
|
||||||
@ -19,73 +30,67 @@
|
|||||||
|
|
||||||
if (!defined('STATUSNET') && !defined('LACONICA')) { exit(1); }
|
if (!defined('STATUSNET') && !defined('LACONICA')) { exit(1); }
|
||||||
|
|
||||||
require_once(INSTALLDIR.'/lib/omb.php');
|
require_once INSTALLDIR.'/lib/omb.php';
|
||||||
|
require_once INSTALLDIR.'/extlib/libomb/service_provider.php';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handler for postnotice action
|
||||||
|
*
|
||||||
|
* @category Action
|
||||||
|
* @package StatusNet
|
||||||
|
* @author Evan Prodromou <evan@status.net>
|
||||||
|
* @author Robin Millette <millette@status.net>
|
||||||
|
* @license http://www.fsf.org/licensing/licenses/agpl.html AGPLv3
|
||||||
|
* @link http://status.net/
|
||||||
|
*/
|
||||||
class PostnoticeAction extends Action
|
class PostnoticeAction extends Action
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* For initializing members of the class.
|
||||||
|
*
|
||||||
|
* @param array $argarray misc. arguments
|
||||||
|
*
|
||||||
|
* @return boolean true
|
||||||
|
*/
|
||||||
|
function prepare($argarray)
|
||||||
|
{
|
||||||
|
parent::prepare($argarray);
|
||||||
|
try {
|
||||||
|
$this->checkNotice();
|
||||||
|
} catch (Exception $e) {
|
||||||
|
$this->clientError($e->getMessage());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
function handle($args)
|
function handle($args)
|
||||||
{
|
{
|
||||||
parent::handle($args);
|
parent::handle($args);
|
||||||
try {
|
try {
|
||||||
common_remove_magic_from_request();
|
$srv = new OMB_Service_Provider(null, omb_oauth_datastore(),
|
||||||
$req = OAuthRequest::from_request('POST', common_local_url('postnotice'));
|
omb_oauth_server());
|
||||||
# Note: server-to-server function!
|
$srv->handlePostNotice();
|
||||||
$server = omb_oauth_server();
|
} catch (Exception $e) {
|
||||||
list($consumer, $token) = $server->verify_request($req);
|
|
||||||
if ($this->save_notice($req, $consumer, $token)) {
|
|
||||||
print "omb_version=".OMB_VERSION_01;
|
|
||||||
}
|
|
||||||
} catch (OAuthException $e) {
|
|
||||||
$this->serverError($e->getMessage());
|
$this->serverError($e->getMessage());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function save_notice(&$req, &$consumer, &$token)
|
function checkNotice()
|
||||||
{
|
{
|
||||||
$version = $req->get_parameter('omb_version');
|
$content = common_shorten_links($_POST['omb_notice_content']);
|
||||||
if ($version != OMB_VERSION_01) {
|
if (Notice::contentTooLong($content)) {
|
||||||
$this->clientError(_('Unsupported OMB version'), 400);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
# First, check to see
|
|
||||||
$listenee = $req->get_parameter('omb_listenee');
|
|
||||||
$remote_profile = Remote_profile::staticGet('uri', $listenee);
|
|
||||||
if (!$remote_profile) {
|
|
||||||
$this->clientError(_('Profile unknown'), 403);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
$sub = Subscription::staticGet('token', $token->key);
|
|
||||||
if (!$sub) {
|
|
||||||
$this->clientError(_('No such subscription'), 403);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
$content = $req->get_parameter('omb_notice_content');
|
|
||||||
$content_shortened = common_shorten_links($content);
|
|
||||||
if (mb_strlen($content_shortened) > 140) {
|
|
||||||
$this->clientError(_('Invalid notice content'), 400);
|
$this->clientError(_('Invalid notice content'), 400);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
$notice_uri = $req->get_parameter('omb_notice');
|
$license = $_POST['omb_notice_license'];
|
||||||
if (!Validate::uri($notice_uri) &&
|
$site_license = common_config('license', 'url');
|
||||||
!common_valid_tag($notice_uri)) {
|
if ($license && !common_compatible_license($license, $site_license)) {
|
||||||
$this->clientError(_('Invalid notice uri'), 400);
|
throw new Exception(sprintf(_('Notice license ‘%s’ is not ' .
|
||||||
return false;
|
'compatible with site license ‘%s’.'),
|
||||||
|
$license, $site_license));
|
||||||
}
|
}
|
||||||
$notice_url = $req->get_parameter('omb_notice_url');
|
|
||||||
if ($notice_url && !common_valid_http_url($notice_url)) {
|
|
||||||
$this->clientError(_('Invalid notice url'), 400);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
$notice = Notice::staticGet('uri', $notice_uri);
|
|
||||||
if (!$notice) {
|
|
||||||
$notice = Notice::saveNew($remote_profile->id, $content, 'omb', false, null, $notice_uri);
|
|
||||||
if (is_string($notice)) {
|
|
||||||
common_server_serror($notice, 500);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
common_broadcast_notice($notice, true);
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
?>
|
@ -117,9 +117,16 @@ class ProfilesettingsAction extends AccountSettingsAction
|
|||||||
_('URL of your homepage, blog, or profile on another site'));
|
_('URL of your homepage, blog, or profile on another site'));
|
||||||
$this->elementEnd('li');
|
$this->elementEnd('li');
|
||||||
$this->elementStart('li');
|
$this->elementStart('li');
|
||||||
|
$maxBio = Profile::maxBio();
|
||||||
|
if ($maxBio > 0) {
|
||||||
|
$bioInstr = sprintf(_('Describe yourself and your interests in %d chars'),
|
||||||
|
$maxBio);
|
||||||
|
} else {
|
||||||
|
$bioInstr = _('Describe yourself and your interests');
|
||||||
|
}
|
||||||
$this->textarea('bio', _('Bio'),
|
$this->textarea('bio', _('Bio'),
|
||||||
($this->arg('bio')) ? $this->arg('bio') : $profile->bio,
|
($this->arg('bio')) ? $this->arg('bio') : $profile->bio,
|
||||||
_('Describe yourself and your interests in 140 chars'));
|
$bioInstr);
|
||||||
$this->elementEnd('li');
|
$this->elementEnd('li');
|
||||||
$this->elementStart('li');
|
$this->elementStart('li');
|
||||||
$this->input('location', _('Location'),
|
$this->input('location', _('Location'),
|
||||||
@ -210,8 +217,9 @@ class ProfilesettingsAction extends AccountSettingsAction
|
|||||||
} else if (!is_null($fullname) && mb_strlen($fullname) > 255) {
|
} else if (!is_null($fullname) && mb_strlen($fullname) > 255) {
|
||||||
$this->showForm(_('Full name is too long (max 255 chars).'));
|
$this->showForm(_('Full name is too long (max 255 chars).'));
|
||||||
return;
|
return;
|
||||||
} else if (!is_null($bio) && mb_strlen($bio) > 140) {
|
} else if (Profile::bioTooLong($bio)) {
|
||||||
$this->showForm(_('Bio is too long (max 140 chars).'));
|
$this->showForm(sprintf(_('Bio is too long (max %d chars).'),
|
||||||
|
Profile::maxBio()));
|
||||||
return;
|
return;
|
||||||
} else if (!is_null($location) && mb_strlen($location) > 255) {
|
} else if (!is_null($location) && mb_strlen($location) > 255) {
|
||||||
$this->showForm(_('Location is too long (max 255 chars).'));
|
$this->showForm(_('Location is too long (max 255 chars).'));
|
||||||
@ -298,6 +306,16 @@ class ProfilesettingsAction extends AccountSettingsAction
|
|||||||
$profile->homepage = $homepage;
|
$profile->homepage = $homepage;
|
||||||
$profile->bio = $bio;
|
$profile->bio = $bio;
|
||||||
$profile->location = $location;
|
$profile->location = $location;
|
||||||
|
|
||||||
|
$loc = Location::fromName($location);
|
||||||
|
|
||||||
|
if (!empty($loc)) {
|
||||||
|
$profile->lat = $loc->lat;
|
||||||
|
$profile->lon = $loc->lon;
|
||||||
|
$profile->location_id = $loc->location_id;
|
||||||
|
$profile->location_ns = $loc->location_ns;
|
||||||
|
}
|
||||||
|
|
||||||
$profile->profileurl = common_profile_url($nickname);
|
$profile->profileurl = common_profile_url($nickname);
|
||||||
|
|
||||||
common_debug('Old profile: ' . common_log_objstring($orig_profile), __FILE__);
|
common_debug('Old profile: ' . common_log_objstring($orig_profile), __FILE__);
|
||||||
@ -305,7 +323,7 @@ class ProfilesettingsAction extends AccountSettingsAction
|
|||||||
|
|
||||||
$result = $profile->update($orig_profile);
|
$result = $profile->update($orig_profile);
|
||||||
|
|
||||||
if (!$result) {
|
if ($result === false) {
|
||||||
common_log_db_error($profile, 'UPDATE', __FILE__);
|
common_log_db_error($profile, 'UPDATE', __FILE__);
|
||||||
$this->serverError(_('Couldn\'t save profile.'));
|
$this->serverError(_('Couldn\'t save profile.'));
|
||||||
return;
|
return;
|
||||||
|
@ -114,8 +114,6 @@ class PublicAction extends Action
|
|||||||
{
|
{
|
||||||
parent::handle($args);
|
parent::handle($args);
|
||||||
|
|
||||||
header('X-XRDS-Location: '. common_local_url('publicxrds'));
|
|
||||||
|
|
||||||
$this->showPage();
|
$this->showPage();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -133,6 +131,13 @@ class PublicAction extends Action
|
|||||||
return _('Public timeline');
|
return _('Public timeline');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function extraHead()
|
||||||
|
{
|
||||||
|
parent::extraHead();
|
||||||
|
$this->element('meta', array('http-equiv' => 'X-XRDS-Location',
|
||||||
|
'content' => common_local_url('publicxrds')));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Output <head> elements for RSS and Atom feeds
|
* Output <head> elements for RSS and Atom feeds
|
||||||
@ -145,33 +150,15 @@ class PublicAction extends Action
|
|||||||
return array(new Feed(Feed::RSS1, common_local_url('publicrss'),
|
return array(new Feed(Feed::RSS1, common_local_url('publicrss'),
|
||||||
_('Public Stream Feed (RSS 1.0)')),
|
_('Public Stream Feed (RSS 1.0)')),
|
||||||
new Feed(Feed::RSS2,
|
new Feed(Feed::RSS2,
|
||||||
common_local_url('api',
|
common_local_url('ApiTimelinePublic',
|
||||||
array('apiaction' => 'statuses',
|
array('format' => 'rss')),
|
||||||
'method' => 'public_timeline.rss')),
|
|
||||||
_('Public Stream Feed (RSS 2.0)')),
|
_('Public Stream Feed (RSS 2.0)')),
|
||||||
new Feed(Feed::ATOM,
|
new Feed(Feed::ATOM,
|
||||||
common_local_url('api',
|
common_local_url('ApiTimelinePublic',
|
||||||
array('apiaction' => 'statuses',
|
array('format' => 'atom')),
|
||||||
'method' => 'public_timeline.atom')),
|
|
||||||
_('Public Stream Feed (Atom)')));
|
_('Public Stream Feed (Atom)')));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Extra head elements
|
|
||||||
*
|
|
||||||
* We include a <meta> element linking to the publicxrds page, for OpenID
|
|
||||||
* client-side authentication.
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
|
|
||||||
function extraHead()
|
|
||||||
{
|
|
||||||
// for client side of OpenID authentication
|
|
||||||
$this->element('meta', array('http-equiv' => 'X-XRDS-Location',
|
|
||||||
'content' => common_local_url('publicxrds')));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Show tabset for this page
|
* Show tabset for this page
|
||||||
*
|
*
|
||||||
@ -196,8 +183,7 @@ class PublicAction extends Action
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (! (common_config('site','closed') || common_config('site','inviteonly'))) {
|
if (! (common_config('site','closed') || common_config('site','inviteonly'))) {
|
||||||
$message .= sprintf(_('Why not [register an account](%%%%action.%s%%%%) and be the first to post!'),
|
$message .= _('Why not [register an account](%%action.register%%) and be the first to post!');
|
||||||
(!common_config('site','openidonly')) ? 'register' : 'openidlogin');
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -244,11 +230,10 @@ class PublicAction extends Action
|
|||||||
function showAnonymousMessage()
|
function showAnonymousMessage()
|
||||||
{
|
{
|
||||||
if (! (common_config('site','closed') || common_config('site','inviteonly'))) {
|
if (! (common_config('site','closed') || common_config('site','inviteonly'))) {
|
||||||
$m = sprintf(_('This is %%%%site.name%%%%, a [micro-blogging](http://en.wikipedia.org/wiki/Micro-blogging) service ' .
|
$m = _('This is %%site.name%%, a [micro-blogging](http://en.wikipedia.org/wiki/Micro-blogging) service ' .
|
||||||
'based on the Free Software [StatusNet](http://status.net/) tool. ' .
|
'based on the Free Software [StatusNet](http://status.net/) tool. ' .
|
||||||
'[Join now](%%%%action.%s%%%%) to share notices about yourself with friends, family, and colleagues! ' .
|
'[Join now](%%action.register%%) to share notices about yourself with friends, family, and colleagues! ' .
|
||||||
'([Read more](%%%%doc.help%%%%))'),
|
'([Read more](%%doc.help%%))');
|
||||||
(!common_config('site','openidonly')) ? 'register' : 'openidlogin');
|
|
||||||
} else {
|
} else {
|
||||||
$m = _('This is %%site.name%%, a [micro-blogging](http://en.wikipedia.org/wiki/Micro-blogging) service ' .
|
$m = _('This is %%site.name%%, a [micro-blogging](http://en.wikipedia.org/wiki/Micro-blogging) service ' .
|
||||||
'based on the Free Software [StatusNet](http://status.net/) tool.');
|
'based on the Free Software [StatusNet](http://status.net/) tool.');
|
||||||
|
@ -49,9 +49,23 @@ require_once INSTALLDIR.'/lib/rssaction.php';
|
|||||||
*/
|
*/
|
||||||
class PublicrssAction extends Rss10Action
|
class PublicrssAction extends Rss10Action
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* Read arguments and initialize members
|
||||||
|
*
|
||||||
|
* @param array $args Arguments from $_REQUEST
|
||||||
|
* @return boolean success
|
||||||
|
*/
|
||||||
|
|
||||||
|
function prepare($args)
|
||||||
|
{
|
||||||
|
parent::prepare($args);
|
||||||
|
$this->notices = $this->getNotices($this->limit);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initialization.
|
* Initialization.
|
||||||
*
|
*
|
||||||
* @return boolean true
|
* @return boolean true
|
||||||
*/
|
*/
|
||||||
function init()
|
function init()
|
||||||
@ -73,7 +87,7 @@ class PublicrssAction extends Rss10Action
|
|||||||
while ($notice->fetch()) {
|
while ($notice->fetch()) {
|
||||||
$notices[] = clone($notice);
|
$notices[] = clone($notice);
|
||||||
}
|
}
|
||||||
|
|
||||||
return $notices;
|
return $notices;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -72,8 +72,7 @@ class PublictagcloudAction extends Action
|
|||||||
$message .= _('Be the first to post one!');
|
$message .= _('Be the first to post one!');
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
$message .= sprintf(_('Why not [register an account](%%%%action.%s%%%%) and be the first to post one!'),
|
$message .= _('Why not [register an account](%%action.register%%) and be the first to post one!');
|
||||||
(!common_config('site','openidonly')) ? 'register' : 'openidlogin');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->elementStart('div', 'guide');
|
$this->elementStart('div', 'guide');
|
||||||
|
@ -33,15 +33,17 @@ if (!defined('STATUSNET') && !defined('LACONICA')) {
|
|||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
require_once INSTALLDIR.'/lib/openid.php';
|
require_once INSTALLDIR.'/plugins/OpenID/openid.php';
|
||||||
|
require_once INSTALLDIR.'/lib/xrdsoutputter.php';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Public XRDS for OpenID
|
* Public XRDS
|
||||||
*
|
*
|
||||||
* @category Action
|
* @category Action
|
||||||
* @package StatusNet
|
* @package StatusNet
|
||||||
* @author Evan Prodromou <evan@status.net>
|
* @author Evan Prodromou <evan@status.net>
|
||||||
* @author Robin Millette <millette@status.net>
|
* @author Robin Millette <millette@status.net>
|
||||||
|
* @author Craig Andrews <candrews@integralblue.com>
|
||||||
* @license http://www.fsf.org/licensing/licenses/agpl.html AGPLv3
|
* @license http://www.fsf.org/licensing/licenses/agpl.html AGPLv3
|
||||||
* @link http://status.net/
|
* @link http://status.net/
|
||||||
*
|
*
|
||||||
@ -69,54 +71,11 @@ class PublicxrdsAction extends Action
|
|||||||
function handle($args)
|
function handle($args)
|
||||||
{
|
{
|
||||||
parent::handle($args);
|
parent::handle($args);
|
||||||
header('Content-Type: application/xrds+xml');
|
$xrdsOutputter = new XRDSOutputter();
|
||||||
$this->startXML();
|
$xrdsOutputter->startXRDS();
|
||||||
$this->elementStart('XRDS', array('xmlns' => 'xri://$xrds'));
|
Event::handle('StartPublicXRDS', array($this,&$xrdsOutputter));
|
||||||
$this->elementStart('XRD', array('xmlns' => 'xri://$xrd*($v*2.0)',
|
Event::handle('EndPublicXRDS', array($this,&$xrdsOutputter));
|
||||||
'xmlns:simple' => 'http://xrds-simple.net/core/1.0',
|
$xrdsOutputter->endXRDS();
|
||||||
'version' => '2.0'));
|
|
||||||
$this->element('Type', null, 'xri://$xrds*simple');
|
|
||||||
foreach (array('finishopenidlogin', 'finishaddopenid') as $finish) {
|
|
||||||
$this->showService(Auth_OpenID_RP_RETURN_TO_URL_TYPE,
|
|
||||||
common_local_url($finish));
|
|
||||||
}
|
|
||||||
$this->elementEnd('XRD');
|
|
||||||
$this->elementEnd('XRDS');
|
|
||||||
$this->endXML();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Show service.
|
|
||||||
*
|
|
||||||
* @param string $type XRDS type
|
|
||||||
* @param string $uri URI
|
|
||||||
* @param array $params type parameters, null by default
|
|
||||||
* @param array $sigs type signatures, null by default
|
|
||||||
* @param string $localId local ID, null by default
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
function showService($type, $uri, $params=null, $sigs=null, $localId=null)
|
|
||||||
{
|
|
||||||
$this->elementStart('Service');
|
|
||||||
if ($uri) {
|
|
||||||
$this->element('URI', null, $uri);
|
|
||||||
}
|
|
||||||
$this->element('Type', null, $type);
|
|
||||||
if ($params) {
|
|
||||||
foreach ($params as $param) {
|
|
||||||
$this->element('Type', null, $param);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if ($sigs) {
|
|
||||||
foreach ($sigs as $sig) {
|
|
||||||
$this->element('Type', null, $sig);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if ($localId) {
|
|
||||||
$this->element('LocalID', null, $localId);
|
|
||||||
}
|
|
||||||
$this->elementEnd('Service');
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -149,13 +149,13 @@ class RecoverpasswordAction extends Action
|
|||||||
$this->elementStart('div', 'instructions');
|
$this->elementStart('div', 'instructions');
|
||||||
if ($this->mode == 'recover') {
|
if ($this->mode == 'recover') {
|
||||||
$this->element('p', null,
|
$this->element('p', null,
|
||||||
_('If you\'ve forgotten or lost your' .
|
_('If you have forgotten or lost your' .
|
||||||
' password, you can get a new one sent to' .
|
' password, you can get a new one sent to' .
|
||||||
' the email address you have stored' .
|
' the email address you have stored' .
|
||||||
' in your account.'));
|
' in your account.'));
|
||||||
} else if ($this->mode == 'reset') {
|
} else if ($this->mode == 'reset') {
|
||||||
$this->element('p', null,
|
$this->element('p', null,
|
||||||
_('You\'ve been identified. Enter a' .
|
_('You have been identified. Enter a' .
|
||||||
' new password below. '));
|
' new password below. '));
|
||||||
}
|
}
|
||||||
$this->elementEnd('div');
|
$this->elementEnd('div');
|
||||||
@ -185,10 +185,10 @@ class RecoverpasswordAction extends Action
|
|||||||
'class' => 'form_settings',
|
'class' => 'form_settings',
|
||||||
'action' => common_local_url('recoverpassword')));
|
'action' => common_local_url('recoverpassword')));
|
||||||
$this->elementStart('fieldset');
|
$this->elementStart('fieldset');
|
||||||
$this->element('legend', null, _('Password recover'));
|
$this->element('legend', null, _('Password recovery'));
|
||||||
$this->elementStart('ul', 'form_data');
|
$this->elementStart('ul', 'form_data');
|
||||||
$this->elementStart('li');
|
$this->elementStart('li');
|
||||||
$this->input('nicknameoremail', _('Nickname or email'),
|
$this->input('nicknameoremail', _('Nickname or email address'),
|
||||||
$this->trimmed('nicknameoremail'),
|
$this->trimmed('nicknameoremail'),
|
||||||
_('Your nickname on this server, ' .
|
_('Your nickname on this server, ' .
|
||||||
'or your registered email address.'));
|
'or your registered email address.'));
|
||||||
|
@ -55,6 +55,12 @@ class RegisterAction extends Action
|
|||||||
|
|
||||||
var $registered = false;
|
var $registered = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Are we processing an invite?
|
||||||
|
*/
|
||||||
|
|
||||||
|
var $invite = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Prepare page to run
|
* Prepare page to run
|
||||||
*
|
*
|
||||||
@ -116,8 +122,6 @@ class RegisterAction extends Action
|
|||||||
*
|
*
|
||||||
* Checks if registration is closed and shows an error if so.
|
* Checks if registration is closed and shows an error if so.
|
||||||
*
|
*
|
||||||
* Checks if only OpenID is allowed and redirects to openidlogin if so.
|
|
||||||
*
|
|
||||||
* @param array $args $_REQUEST data
|
* @param array $args $_REQUEST data
|
||||||
*
|
*
|
||||||
* @return void
|
* @return void
|
||||||
@ -129,8 +133,6 @@ class RegisterAction extends Action
|
|||||||
|
|
||||||
if (common_config('site', 'closed')) {
|
if (common_config('site', 'closed')) {
|
||||||
$this->clientError(_('Registration not allowed.'));
|
$this->clientError(_('Registration not allowed.'));
|
||||||
} else if (common_config('site', 'openidonly')) {
|
|
||||||
common_redirect(common_local_url('openidlogin'));
|
|
||||||
} else if (common_logged_in()) {
|
} else if (common_logged_in()) {
|
||||||
$this->clientError(_('Already logged in.'));
|
$this->clientError(_('Already logged in.'));
|
||||||
} else if ($_SERVER['REQUEST_METHOD'] == 'POST') {
|
} else if ($_SERVER['REQUEST_METHOD'] == 'POST') {
|
||||||
@ -195,7 +197,7 @@ class RegisterAction extends Action
|
|||||||
if (!$this->boolean('license')) {
|
if (!$this->boolean('license')) {
|
||||||
$this->showForm(_('You can\'t register if you don\'t '.
|
$this->showForm(_('You can\'t register if you don\'t '.
|
||||||
'agree to the license.'));
|
'agree to the license.'));
|
||||||
} else if ($email && !Validate::email($email, true)) {
|
} else if ($email && !Validate::email($email, common_config('email', 'check_domain'))) {
|
||||||
$this->showForm(_('Not a valid email address.'));
|
$this->showForm(_('Not a valid email address.'));
|
||||||
} else if (!Validate::string($nickname, array('min_length' => 1,
|
} else if (!Validate::string($nickname, array('min_length' => 1,
|
||||||
'max_length' => 64,
|
'max_length' => 64,
|
||||||
@ -217,8 +219,9 @@ class RegisterAction extends Action
|
|||||||
} else if (!is_null($fullname) && mb_strlen($fullname) > 255) {
|
} else if (!is_null($fullname) && mb_strlen($fullname) > 255) {
|
||||||
$this->showForm(_('Full name is too long (max 255 chars).'));
|
$this->showForm(_('Full name is too long (max 255 chars).'));
|
||||||
return;
|
return;
|
||||||
} else if (!is_null($bio) && mb_strlen($bio) > 140) {
|
} else if (Profile::bioTooLong($bio)) {
|
||||||
$this->showForm(_('Bio is too long (max 140 chars).'));
|
$this->showForm(sprintf(_('Bio is too long (max %d chars).'),
|
||||||
|
Profile::maxBio()));
|
||||||
return;
|
return;
|
||||||
} else if (!is_null($location) && mb_strlen($location) > 255) {
|
} else if (!is_null($location) && mb_strlen($location) > 255) {
|
||||||
$this->showForm(_('Location is too long (max 255 chars).'));
|
$this->showForm(_('Location is too long (max 255 chars).'));
|
||||||
@ -335,22 +338,11 @@ class RegisterAction extends Action
|
|||||||
} else if ($this->error) {
|
} else if ($this->error) {
|
||||||
$this->element('p', 'error', $this->error);
|
$this->element('p', 'error', $this->error);
|
||||||
} else {
|
} else {
|
||||||
if (common_config('openid', 'enabled')) {
|
$instr =
|
||||||
$instr =
|
common_markup_to_html(_('With this form you can create '.
|
||||||
common_markup_to_html(_('With this form you can create '.
|
' a new account. ' .
|
||||||
' a new account. ' .
|
'You can then post notices and '.
|
||||||
'You can then post notices and '.
|
'link up to friends and colleagues. '));
|
||||||
'link up to friends and colleagues. '.
|
|
||||||
'(Have an [OpenID](http://openid.net/)? ' .
|
|
||||||
'Try our [OpenID registration]'.
|
|
||||||
'(%%action.openidlogin%%)!)'));
|
|
||||||
} else {
|
|
||||||
$instr =
|
|
||||||
common_markup_to_html(_('With this form you can create '.
|
|
||||||
' a new account. ' .
|
|
||||||
'You can then post notices and '.
|
|
||||||
'link up to friends and colleagues.'));
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->elementStart('div', 'instructions');
|
$this->elementStart('div', 'instructions');
|
||||||
$this->raw($instr);
|
$this->raw($instr);
|
||||||
@ -463,10 +455,16 @@ class RegisterAction extends Action
|
|||||||
'or profile on another site'));
|
'or profile on another site'));
|
||||||
$this->elementEnd('li');
|
$this->elementEnd('li');
|
||||||
$this->elementStart('li');
|
$this->elementStart('li');
|
||||||
|
$maxBio = Profile::maxBio();
|
||||||
|
if ($maxBio > 0) {
|
||||||
|
$bioInstr = sprintf(_('Describe yourself and your interests in %d chars'),
|
||||||
|
$maxBio);
|
||||||
|
} else {
|
||||||
|
$bioInstr = _('Describe yourself and your interests');
|
||||||
|
}
|
||||||
$this->textarea('bio', _('Bio'),
|
$this->textarea('bio', _('Bio'),
|
||||||
$this->trimmed('bio'),
|
$this->trimmed('bio'),
|
||||||
_('Describe yourself and your '.
|
$bioInstr);
|
||||||
'interests in 140 chars'));
|
|
||||||
$this->elementEnd('li');
|
$this->elementEnd('li');
|
||||||
$this->elementStart('li');
|
$this->elementStart('li');
|
||||||
$this->input('location', _('Location'),
|
$this->input('location', _('Location'),
|
||||||
|
@ -1,5 +1,16 @@
|
|||||||
<?php
|
<?php
|
||||||
/*
|
/**
|
||||||
|
* Handler for remote subscription
|
||||||
|
*
|
||||||
|
* PHP version 5
|
||||||
|
*
|
||||||
|
* @category Action
|
||||||
|
* @package StatusNet
|
||||||
|
* @author Evan Prodromou <evan@status.net>
|
||||||
|
* @author Robin Millette <millette@status.net>
|
||||||
|
* @license http://www.fsf.org/licensing/licenses/agpl.html AGPLv3
|
||||||
|
* @link http://status.net/
|
||||||
|
*
|
||||||
* StatusNet - the distributed open-source microblogging tool
|
* StatusNet - the distributed open-source microblogging tool
|
||||||
* Copyright (C) 2008, 2009, StatusNet, Inc.
|
* Copyright (C) 2008, 2009, StatusNet, Inc.
|
||||||
*
|
*
|
||||||
@ -15,11 +26,24 @@
|
|||||||
*
|
*
|
||||||
* You should have received a copy of the GNU Affero General Public License
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
**/
|
||||||
|
|
||||||
if (!defined('STATUSNET') && !defined('LACONICA')) { exit(1); }
|
if (!defined('STATUSNET') && !defined('LACONICA')) { exit(1); }
|
||||||
|
|
||||||
require_once(INSTALLDIR.'/lib/omb.php');
|
require_once INSTALLDIR.'/lib/omb.php';
|
||||||
|
require_once INSTALLDIR.'/extlib/libomb/service_consumer.php';
|
||||||
|
require_once INSTALLDIR.'/extlib/libomb/profile.php';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handler for remote subscription
|
||||||
|
*
|
||||||
|
* @category Action
|
||||||
|
* @package StatusNet
|
||||||
|
* @author Evan Prodromou <evan@status.net>
|
||||||
|
* @author Robin Millette <millette@status.net>
|
||||||
|
* @license http://www.fsf.org/licensing/licenses/agpl.html AGPLv3
|
||||||
|
* @link http://status.net/
|
||||||
|
*/
|
||||||
|
|
||||||
class RemotesubscribeAction extends Action
|
class RemotesubscribeAction extends Action
|
||||||
{
|
{
|
||||||
@ -36,7 +60,7 @@ class RemotesubscribeAction extends Action
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->nickname = $this->trimmed('nickname');
|
$this->nickname = $this->trimmed('nickname');
|
||||||
$this->profile_url = $this->trimmed('profile_url');
|
$this->profile_url = $this->trimmed('profile_url');
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@ -47,7 +71,7 @@ class RemotesubscribeAction extends Action
|
|||||||
parent::handle($args);
|
parent::handle($args);
|
||||||
|
|
||||||
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
|
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
|
||||||
# CSRF protection
|
/* Use a session token for CSRF protection. */
|
||||||
$token = $this->trimmed('token');
|
$token = $this->trimmed('token');
|
||||||
if (!$token || $token != common_session_token()) {
|
if (!$token || $token != common_session_token()) {
|
||||||
$this->showForm(_('There was a problem with your session token. '.
|
$this->showForm(_('There was a problem with your session token. '.
|
||||||
@ -71,13 +95,11 @@ class RemotesubscribeAction extends Action
|
|||||||
if ($this->err) {
|
if ($this->err) {
|
||||||
$this->element('div', 'error', $this->err);
|
$this->element('div', 'error', $this->err);
|
||||||
} else {
|
} else {
|
||||||
$inst = sprintf(_('To subscribe, you can [login](%%%%action.%s%%%%),' .
|
$inst = _('To subscribe, you can [login](%%action.login%%),' .
|
||||||
' or [register](%%%%action.%s%%%%) a new ' .
|
' or [register](%%action.register%%) a new ' .
|
||||||
' account. If you already have an account ' .
|
' account. If you already have an account ' .
|
||||||
' on a [compatible microblogging site](%%doc.openmublog%%), ' .
|
' on a [compatible microblogging site](%%doc.openmublog%%), ' .
|
||||||
' enter your profile URL below.'),
|
' enter your profile URL below.');
|
||||||
(!common_config('site','openidonly')) ? 'login' : 'openidlogin',
|
|
||||||
(!common_config('site','openidonly')) ? 'register' : 'openidlogin');
|
|
||||||
$output = common_markup_to_html($inst);
|
$output = common_markup_to_html($inst);
|
||||||
$this->elementStart('div', 'instructions');
|
$this->elementStart('div', 'instructions');
|
||||||
$this->raw($output);
|
$this->raw($output);
|
||||||
@ -92,8 +114,8 @@ class RemotesubscribeAction extends Action
|
|||||||
|
|
||||||
function showContent()
|
function showContent()
|
||||||
{
|
{
|
||||||
# id = remotesubscribe conflicts with the
|
/* The id 'remotesubscribe' conflicts with the
|
||||||
# button on profile page
|
button on profile page. */
|
||||||
$this->elementStart('form', array('id' => 'form_remote_subscribe',
|
$this->elementStart('form', array('id' => 'form_remote_subscribe',
|
||||||
'method' => 'post',
|
'method' => 'post',
|
||||||
'class' => 'form_settings',
|
'class' => 'form_settings',
|
||||||
@ -119,13 +141,13 @@ class RemotesubscribeAction extends Action
|
|||||||
|
|
||||||
function remoteSubscription()
|
function remoteSubscription()
|
||||||
{
|
{
|
||||||
$user = $this->getUser();
|
if (!$this->nickname) {
|
||||||
|
|
||||||
if (!$user) {
|
|
||||||
$this->showForm(_('No such user.'));
|
$this->showForm(_('No such user.'));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$user = User::staticGet('nickname', $this->nickname);
|
||||||
|
|
||||||
$this->profile_url = $this->trimmed('profile_url');
|
$this->profile_url = $this->trimmed('profile_url');
|
||||||
|
|
||||||
if (!$this->profile_url) {
|
if (!$this->profile_url) {
|
||||||
@ -133,233 +155,36 @@ class RemotesubscribeAction extends Action
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!Validate::uri($this->profile_url, array('allowed_schemes' => array('http', 'https')))) {
|
if (!common_valid_http_url($this->profile_url)) {
|
||||||
$this->showForm(_('Invalid profile URL (bad format)'));
|
$this->showForm(_('Invalid profile URL (bad format)'));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
$fetcher = Auth_Yadis_Yadis::getHTTPFetcher();
|
try {
|
||||||
$yadis = Auth_Yadis_Yadis::discover($this->profile_url, $fetcher);
|
$service = new OMB_Service_Consumer($this->profile_url,
|
||||||
|
common_root_url(),
|
||||||
if (!$yadis || $yadis->failed) {
|
omb_oauth_datastore());
|
||||||
$this->showForm(_('Not a valid profile URL (no YADIS document).'));
|
} catch (OMB_InvalidYadisException $e) {
|
||||||
|
$this->showForm(_('Not a valid profile URL (no YADIS document or ' .
|
||||||
|
'no or invalid XRDS defined).'));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
# XXX: a little liberal for sites that accidentally put whitespace before the xml declaration
|
if ($service->getServiceURI(OAUTH_ENDPOINT_REQUEST) ==
|
||||||
|
common_local_url('requesttoken') ||
|
||||||
$xrds =& Auth_Yadis_XRDS::parseXRDS(trim($yadis->response_text));
|
User::staticGet('uri', $service->getRemoteUserURI())) {
|
||||||
|
$this->showForm(_('That’s a local profile! Login to subscribe.'));
|
||||||
if (!$xrds) {
|
|
||||||
$this->showForm(_('Not a valid profile URL (no XRDS defined).'));
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
$omb = $this->getOmb($xrds);
|
try {
|
||||||
|
$service->requestToken();
|
||||||
if (!$omb) {
|
} catch (OMB_RemoteServiceException $e) {
|
||||||
$this->showForm(_('Not a valid profile URL (incorrect services).'));
|
$this->showForm(_('Couldn’t get a request token.'));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (omb_service_uri($omb[OAUTH_ENDPOINT_REQUEST]) ==
|
/* Create an OMB_Profile from $user. */
|
||||||
common_local_url('requesttoken'))
|
|
||||||
{
|
|
||||||
$this->showForm(_('That\'s a local profile! Login to subscribe.'));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (User::staticGet('uri', omb_local_id($omb[OAUTH_ENDPOINT_REQUEST]))) {
|
|
||||||
$this->showForm(_('That\'s a local profile! Login to subscribe.'));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
list($token, $secret) = $this->requestToken($omb);
|
|
||||||
|
|
||||||
if (!$token || !$secret) {
|
|
||||||
$this->showForm(_('Couldn\'t get a request token.'));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->requestAuthorization($user, $omb, $token, $secret);
|
|
||||||
}
|
|
||||||
|
|
||||||
function getUser()
|
|
||||||
{
|
|
||||||
$user = null;
|
|
||||||
if ($this->nickname) {
|
|
||||||
$user = User::staticGet('nickname', $this->nickname);
|
|
||||||
}
|
|
||||||
return $user;
|
|
||||||
}
|
|
||||||
|
|
||||||
function getOmb($xrds)
|
|
||||||
{
|
|
||||||
static $omb_endpoints = array(OMB_ENDPOINT_UPDATEPROFILE, OMB_ENDPOINT_POSTNOTICE);
|
|
||||||
static $oauth_endpoints = array(OAUTH_ENDPOINT_REQUEST, OAUTH_ENDPOINT_AUTHORIZE,
|
|
||||||
OAUTH_ENDPOINT_ACCESS);
|
|
||||||
$omb = array();
|
|
||||||
|
|
||||||
# XXX: the following code could probably be refactored to eliminate dupes
|
|
||||||
|
|
||||||
$oauth_services = omb_get_services($xrds, OAUTH_DISCOVERY);
|
|
||||||
|
|
||||||
if (!$oauth_services) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
$oauth_service = $oauth_services[0];
|
|
||||||
|
|
||||||
$oauth_xrd = $this->getXRD($oauth_service, $xrds);
|
|
||||||
|
|
||||||
if (!$oauth_xrd) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!$this->addServices($oauth_xrd, $oauth_endpoints, $omb)) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
$omb_services = omb_get_services($xrds, OMB_NAMESPACE);
|
|
||||||
|
|
||||||
if (!$omb_services) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
$omb_service = $omb_services[0];
|
|
||||||
|
|
||||||
$omb_xrd = $this->getXRD($omb_service, $xrds);
|
|
||||||
|
|
||||||
if (!$omb_xrd) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!$this->addServices($omb_xrd, $omb_endpoints, $omb)) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
# XXX: check that we got all the services we needed
|
|
||||||
|
|
||||||
foreach (array_merge($omb_endpoints, $oauth_endpoints) as $type) {
|
|
||||||
if (!array_key_exists($type, $omb) || !$omb[$type]) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!omb_local_id($omb[OAUTH_ENDPOINT_REQUEST])) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return $omb;
|
|
||||||
}
|
|
||||||
|
|
||||||
function getXRD($main_service, $main_xrds)
|
|
||||||
{
|
|
||||||
$uri = omb_service_uri($main_service);
|
|
||||||
if (strpos($uri, "#") !== 0) {
|
|
||||||
# FIXME: more rigorous handling of external service definitions
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
$id = substr($uri, 1);
|
|
||||||
$nodes = $main_xrds->allXrdNodes;
|
|
||||||
$parser = $main_xrds->parser;
|
|
||||||
foreach ($nodes as $node) {
|
|
||||||
$attrs = $parser->attributes($node);
|
|
||||||
if (array_key_exists('xml:id', $attrs) &&
|
|
||||||
$attrs['xml:id'] == $id) {
|
|
||||||
# XXX: trick the constructor into thinking this is the only node
|
|
||||||
$bogus_nodes = array($node);
|
|
||||||
return new Auth_Yadis_XRDS($parser, $bogus_nodes);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
function addServices($xrd, $types, &$omb)
|
|
||||||
{
|
|
||||||
foreach ($types as $type) {
|
|
||||||
$matches = omb_get_services($xrd, $type);
|
|
||||||
if ($matches) {
|
|
||||||
$omb[$type] = $matches[0];
|
|
||||||
} else {
|
|
||||||
# no match for type
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
function requestToken($omb)
|
|
||||||
{
|
|
||||||
$con = omb_oauth_consumer();
|
|
||||||
|
|
||||||
$url = omb_service_uri($omb[OAUTH_ENDPOINT_REQUEST]);
|
|
||||||
|
|
||||||
# XXX: Is this the right thing to do? Strip off GET params and make them
|
|
||||||
# POST params? Seems wrong to me.
|
|
||||||
|
|
||||||
$parsed = parse_url($url);
|
|
||||||
$params = array();
|
|
||||||
parse_str($parsed['query'], $params);
|
|
||||||
|
|
||||||
$req = OAuthRequest::from_consumer_and_token($con, null, "POST", $url, $params);
|
|
||||||
|
|
||||||
$listener = omb_local_id($omb[OAUTH_ENDPOINT_REQUEST]);
|
|
||||||
|
|
||||||
if (!$listener) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
$req->set_parameter('omb_listener', $listener);
|
|
||||||
$req->set_parameter('omb_version', OMB_VERSION_01);
|
|
||||||
|
|
||||||
# XXX: test to see if endpoint accepts this signature method
|
|
||||||
|
|
||||||
$req->sign_request(omb_hmac_sha1(), $con, null);
|
|
||||||
|
|
||||||
# We re-use this tool's fetcher, since it's pretty good
|
|
||||||
|
|
||||||
$fetcher = Auth_Yadis_Yadis::getHTTPFetcher();
|
|
||||||
|
|
||||||
$result = $fetcher->post($req->get_normalized_http_url(),
|
|
||||||
$req->to_postdata(),
|
|
||||||
array('User-Agent: StatusNet/' . STATUSNET_VERSION));
|
|
||||||
if ($result->status != 200) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
parse_str($result->body, $return);
|
|
||||||
|
|
||||||
return array($return['oauth_token'], $return['oauth_token_secret']);
|
|
||||||
}
|
|
||||||
|
|
||||||
function requestAuthorization($user, $omb, $token, $secret)
|
|
||||||
{
|
|
||||||
$con = omb_oauth_consumer();
|
|
||||||
$tok = new OAuthToken($token, $secret);
|
|
||||||
|
|
||||||
$url = omb_service_uri($omb[OAUTH_ENDPOINT_AUTHORIZE]);
|
|
||||||
|
|
||||||
# XXX: Is this the right thing to do? Strip off GET params and make them
|
|
||||||
# POST params? Seems wrong to me.
|
|
||||||
|
|
||||||
$parsed = parse_url($url);
|
|
||||||
$params = array();
|
|
||||||
parse_str($parsed['query'], $params);
|
|
||||||
|
|
||||||
$req = OAuthRequest::from_consumer_and_token($con, $tok, 'GET', $url, $params);
|
|
||||||
|
|
||||||
# We send over a ton of information. This lets the other
|
|
||||||
# server store info about our user, and it lets the current
|
|
||||||
# user decide if they really want to authorize the subscription.
|
|
||||||
|
|
||||||
$req->set_parameter('omb_version', OMB_VERSION_01);
|
|
||||||
$req->set_parameter('omb_listener', omb_local_id($omb[OAUTH_ENDPOINT_REQUEST]));
|
|
||||||
$req->set_parameter('omb_listenee', $user->uri);
|
|
||||||
$req->set_parameter('omb_listenee_profile', common_profile_url($user->nickname));
|
|
||||||
$req->set_parameter('omb_listenee_nickname', $user->nickname);
|
|
||||||
$req->set_parameter('omb_listenee_license', common_config('license', 'url'));
|
|
||||||
|
|
||||||
$profile = $user->getProfile();
|
$profile = $user->getProfile();
|
||||||
if (!$profile) {
|
if (!$profile) {
|
||||||
common_log_db_error($user, 'SELECT', __FILE__);
|
common_log_db_error($user, 'SELECT', __FILE__);
|
||||||
@ -367,49 +192,16 @@ class RemotesubscribeAction extends Action
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!is_null($profile->fullname)) {
|
$target_url = $service->requestAuthorization(
|
||||||
$req->set_parameter('omb_listenee_fullname', $profile->fullname);
|
profile_to_omb_profile($user->uri, $profile),
|
||||||
}
|
common_local_url('finishremotesubscribe'));
|
||||||
if (!is_null($profile->homepage)) {
|
|
||||||
$req->set_parameter('omb_listenee_homepage', $profile->homepage);
|
|
||||||
}
|
|
||||||
if (!is_null($profile->bio)) {
|
|
||||||
$req->set_parameter('omb_listenee_bio', $profile->bio);
|
|
||||||
}
|
|
||||||
if (!is_null($profile->location)) {
|
|
||||||
$req->set_parameter('omb_listenee_location', $profile->location);
|
|
||||||
}
|
|
||||||
$avatar = $profile->getAvatar(AVATAR_PROFILE_SIZE);
|
|
||||||
if ($avatar) {
|
|
||||||
$req->set_parameter('omb_listenee_avatar', $avatar->url);
|
|
||||||
}
|
|
||||||
|
|
||||||
# XXX: add a nonce to prevent replay attacks
|
|
||||||
|
|
||||||
$req->set_parameter('oauth_callback', common_local_url('finishremotesubscribe'));
|
|
||||||
|
|
||||||
# XXX: test to see if endpoint accepts this signature method
|
|
||||||
|
|
||||||
$req->sign_request(omb_hmac_sha1(), $con, $tok);
|
|
||||||
|
|
||||||
# store all our info here
|
|
||||||
|
|
||||||
$omb['listenee'] = $user->nickname;
|
|
||||||
$omb['listener'] = omb_local_id($omb[OAUTH_ENDPOINT_REQUEST]);
|
|
||||||
$omb['token'] = $token;
|
|
||||||
$omb['secret'] = $secret;
|
|
||||||
# call doesn't work after bounce back so we cache; maybe serialization issue...?
|
|
||||||
$omb['access_token_url'] = omb_service_uri($omb[OAUTH_ENDPOINT_ACCESS]);
|
|
||||||
$omb['post_notice_url'] = omb_service_uri($omb[OMB_ENDPOINT_POSTNOTICE]);
|
|
||||||
$omb['update_profile_url'] = omb_service_uri($omb[OMB_ENDPOINT_UPDATEPROFILE]);
|
|
||||||
|
|
||||||
common_ensure_session();
|
common_ensure_session();
|
||||||
|
|
||||||
$_SESSION['oauth_authorization_request'] = $omb;
|
$_SESSION['oauth_authorization_request'] = serialize($service);
|
||||||
|
|
||||||
# Redirect to authorization service
|
/* Redirect to the remote service for authorization. */
|
||||||
|
common_redirect($target_url, 303);
|
||||||
common_redirect($req->to_url(), 303);
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
?>
|
||||||
|
@ -138,11 +138,25 @@ class RepliesAction extends OwnerDesignAction
|
|||||||
|
|
||||||
function getFeeds()
|
function getFeeds()
|
||||||
{
|
{
|
||||||
$rssurl = common_local_url('repliesrss',
|
return array(new Feed(Feed::RSS1,
|
||||||
array('nickname' => $this->user->nickname));
|
common_local_url('repliesrss',
|
||||||
$rsstitle = sprintf(_('Feed for replies to %s'), $this->user->nickname);
|
array('nickname' => $this->user->nickname)),
|
||||||
|
sprintf(_('Replies feed for %s (RSS 1.0)'),
|
||||||
return array(new Feed(Feed::RSS1, $rssurl, $rsstitle));
|
$this->user->nickname)),
|
||||||
|
new Feed(Feed::RSS2,
|
||||||
|
common_local_url('ApiTimelineMentions',
|
||||||
|
array(
|
||||||
|
'id' => $this->user->nickname,
|
||||||
|
'format' => 'rss')),
|
||||||
|
sprintf(_('Replies feed for %s (RSS 2.0)'),
|
||||||
|
$this->user->nickname)),
|
||||||
|
new Feed(Feed::ATOM,
|
||||||
|
common_local_url('ApiTimelineMentions',
|
||||||
|
array(
|
||||||
|
'id' => $this->user->nickname,
|
||||||
|
'format' => 'atom')),
|
||||||
|
sprintf(_('Replies feed for %s (Atom)'),
|
||||||
|
$this->user->nickname)));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -192,9 +206,7 @@ class RepliesAction extends OwnerDesignAction
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
$message .= sprintf(_('Why not [register an account](%%%%action.%s%%%%) and then nudge %s or post a notice to his or her attention.'),
|
$message .= sprintf(_('Why not [register an account](%%%%action.register%%%%) and then nudge %s or post a notice to his or her attention.'), $this->user->nickname);
|
||||||
(!common_config('site','openidonly')) ? 'register' : 'openidlogin',
|
|
||||||
$this->user->nickname);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->elementStart('div', 'guide');
|
$this->elementStart('div', 'guide');
|
||||||
|
@ -38,6 +38,7 @@ class RepliesrssAction extends Rss10Action
|
|||||||
$this->clientError(_('No such user.'));
|
$this->clientError(_('No such user.'));
|
||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
|
$this->notices = $this->getNotices($this->limit);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -34,6 +34,7 @@ if (!defined('STATUSNET') && !defined('LACONICA')) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
require_once INSTALLDIR.'/lib/omb.php';
|
require_once INSTALLDIR.'/lib/omb.php';
|
||||||
|
require_once INSTALLDIR.'/extlib/libomb/service_provider.php';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Request token action class.
|
* Request token action class.
|
||||||
@ -49,17 +50,17 @@ class RequesttokenAction extends Action
|
|||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* Is read only?
|
* Is read only?
|
||||||
*
|
*
|
||||||
* @return boolean false
|
* @return boolean false
|
||||||
*/
|
*/
|
||||||
function isReadOnly($args)
|
function isReadOnly()
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class handler.
|
* Class handler.
|
||||||
*
|
*
|
||||||
* @param array $args array of arguments
|
* @param array $args array of arguments
|
||||||
*
|
*
|
||||||
* @return void
|
* @return void
|
||||||
@ -68,14 +69,12 @@ class RequesttokenAction extends Action
|
|||||||
{
|
{
|
||||||
parent::handle($args);
|
parent::handle($args);
|
||||||
try {
|
try {
|
||||||
common_remove_magic_from_request();
|
$srv = new OMB_Service_Provider(null, omb_oauth_datastore(),
|
||||||
$req = OAuthRequest::from_request('POST', common_local_url('requesttoken'));
|
omb_oauth_server());
|
||||||
$server = omb_oauth_server();
|
$srv->writeRequestToken();
|
||||||
$token = $server->fetch_request_token($req);
|
} catch (Exception $e) {
|
||||||
print $token.'&omb_version='.OMB_VERSION_01;
|
|
||||||
} catch (OAuthException $e) {
|
|
||||||
$this->serverError($e->getMessage());
|
$this->serverError($e->getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
?>
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user