forked from GNUsocial/gnu-social
Merge branch '1.0.x' of git://gitorious.org/statusnet/mainline
Conflicts: plugins/OStatus/actions/ostatusinit.php
This commit is contained in:
commit
31b29fde50
279
EVENTS.txt
279
EVENTS.txt
@ -1116,6 +1116,156 @@ EndGroupProfileElements: Start showing stuff about the group on its profile page
|
||||
- $action: action being executed (for output and params)
|
||||
- $group: group for the page
|
||||
|
||||
StartShowProfileTagContent: When showing a people tag page
|
||||
- $action: action being executed (for output and params)
|
||||
|
||||
EndShowProfileTagContent: After showing the contents of a people tag page
|
||||
- $action: action being executed (for output and params)
|
||||
|
||||
StartShowTaggedProfilesMiniList: at the start of mini list of tagged profiles
|
||||
- $action: action being executed (for output and params)
|
||||
|
||||
EndShowTaggedProfilesMiniList: at the end of mini list of tagged profiles
|
||||
- $action: action being executed (for output and params)
|
||||
|
||||
StartShowProfileTagSubscribersMiniList: at the start of mini list of people tag subscribers
|
||||
- $action: action being executed (for output and params)
|
||||
|
||||
EndShowProfileTagSubscribersMiniList: at the end of mini list of people tag subscribers
|
||||
- $action: action being executed (for output and params)
|
||||
|
||||
StartTagProfileAction: When starting to show profile tagging page
|
||||
- $action: action being executed (for output and params)
|
||||
- $profile: profile being tagged
|
||||
|
||||
EndTagProfileAction: After showing profile tagging page
|
||||
- $action: action being executed (for output and params)
|
||||
- $profile: profile being tagged
|
||||
|
||||
StartProfileCompletionSearch: When starting a profile search for autocompletion
|
||||
- $action: action being executed (for output and params)
|
||||
- &$profile: result Profile objects
|
||||
- $search_engine: the search engine
|
||||
|
||||
EndProfileCompletionSearch: After search results for profile autocompletion have been found
|
||||
- $action: profilec completion action
|
||||
- &$profile: current result Profile objects
|
||||
- $search_engine: The search engine object
|
||||
|
||||
StartShowTagProfileForm: When showing people tagging form
|
||||
- $action: action being executed (for output and params)
|
||||
- $profile: profile being tagged
|
||||
|
||||
EndShowTagProfileForm: After showing people tagging form
|
||||
- $action: action being executed (for output and params)
|
||||
- $profile: profile being tagged
|
||||
|
||||
StartSavePeopletags: When starting to save people tags
|
||||
- $action: action being executed (for output and params)
|
||||
- $tagstring: string input, a list of tags
|
||||
|
||||
EndSavePeopletags: After saving people tags
|
||||
- $action: action being executed (for output and params)
|
||||
- $tagstring: string input, a list of tags
|
||||
|
||||
StartProfiletagGetUri: when generating the Uri for a people tag
|
||||
- $profile_list: the people tag, a Profile_list object
|
||||
- &$uri: the URI
|
||||
|
||||
EndProfiletagGetUri: after generating the uri for a people tag
|
||||
- $profile_list: the people tag, a Profile_list object
|
||||
- &$uri: the URI
|
||||
|
||||
StartUserPeopletagHomeUrl: when generating the homepage url for a people tag
|
||||
- $profile_list: the people tag, a Profile_list object
|
||||
- &$url: the URL
|
||||
|
||||
EndUserPeopletagHomeUrl: after generating the homepage url for a people tag
|
||||
- $profile_list: the people tag, a Profile_list object
|
||||
- &$url: the URL
|
||||
|
||||
StartProfiletagPermalink: when generating the permalink url for a people tag
|
||||
- $profile_list: the people tag, a Profile_list object
|
||||
- &$url: the URL
|
||||
|
||||
EndProfiletagPermalink: after generating the permalink url for a people tag
|
||||
- $profile_list: the people tag, a Profile_list object
|
||||
- &$url: the URL
|
||||
|
||||
StartTagProfile: when tagging a profile
|
||||
- $tagger: profile tagging
|
||||
- $tagged: profile being tagged
|
||||
- $tag: the tag
|
||||
|
||||
EndTagProfile: after tagging a profile
|
||||
- $newtag: the newly created Profile_tag object
|
||||
|
||||
StartUntagProfile: when deleting a people tag
|
||||
- $ptag: the Profile_tag object being deleted
|
||||
|
||||
EndUntagProfile: after deleting a people tag
|
||||
- $orig: a copy of the deleted Profile_tag object
|
||||
|
||||
StartSubscribePeopletag: when subscribing to a people tag
|
||||
- $peopletag: Profile_list object being subscribed to
|
||||
- $profile: subscriber's profile
|
||||
|
||||
EndSubscribePeopletag: after subscribing to a people tag
|
||||
- $profile_list: the people tag, a Profile_list object: Profile_list object being subscribed to
|
||||
- $profile: subscriber's profile
|
||||
|
||||
StartUnsubscribePeopletag: when unsubscribing to a people tag
|
||||
- $profile_list: the people tag, a Profile_list object: Profile_list object being subscribed to
|
||||
- $profile: subscriber's profile
|
||||
|
||||
EndUnsubscribePeopletag: after unsubscribing to a people tag
|
||||
- $peopletag: Profile_list object being subscribed to
|
||||
- $profile: subscriber's profile
|
||||
|
||||
StartActivityObjectFromPeopletag: while starting to create an ActivityObject from a people tag
|
||||
- $profile_list: the people tag, a Profile_list object
|
||||
- &$object: activity object
|
||||
|
||||
EndActivityObjectFromPeopletag: after making an ActivityObject from a people tag
|
||||
- $profile_list: the people tag, a Profile_list object
|
||||
- &$object: activity object
|
||||
|
||||
StartPeopletagGroupNav: Showing the people tag nav menu
|
||||
- $menu: the menu widget; use $menu->action for output
|
||||
|
||||
EndPeopletagGroupNav: after showing the people tag nav menu
|
||||
- $menu: the menu widget; use $menu->action for output
|
||||
|
||||
StartShowPeopletagItem: when showing a people tag
|
||||
- $widget: PeopletagListItem widget
|
||||
|
||||
EndShowPeopletagItem: after showing a people tag
|
||||
- $widget: PeopletagListItem widget
|
||||
|
||||
StartSubscribePeopletagForm: when showing people tag subscription form
|
||||
- $action: action being executed (for output and params)
|
||||
- $peopletag: people tag being subscribed to
|
||||
|
||||
EndSubscribePeopletagForm: after showing the people tag subscription form
|
||||
- $action: action being executed (for output and params)
|
||||
- $peopletag: people tag being subscribed to
|
||||
|
||||
StartShowPeopletags: when showing a textual list of people tags
|
||||
- $widget: PeopletagsWidget; use $widget->out for output
|
||||
- $tagger: profile of the tagger
|
||||
- $tagged: profile tagged
|
||||
|
||||
EndShowPeopletags: after showing a textual list of people tags
|
||||
- $widget: PeopletagsWidget; use $widget->out for output
|
||||
- $tagger: profile of the tagger
|
||||
- $tagged: profile tagged
|
||||
|
||||
StartProfileListItemTags: when showing people tags in a profile list item widget
|
||||
- $widget: ProfileListItem widget
|
||||
|
||||
EndProfileListItemTags: after showing people tags in a profile list item widget
|
||||
- $widget: ProfileListItem widget
|
||||
|
||||
StartActivityObjectOutputAtom: Called at start of Atom XML output generation for ActivityObject chunks, just inside the <activity:object>. Cancel the event to take over its output completely (you're responsible for calling the matching End event if so)
|
||||
- $obj: ActivityObject
|
||||
- $out: XMLOutputter to append custom output
|
||||
@ -1139,3 +1289,132 @@ StartNoticeWhoGets: Called at start of inbox delivery prep; plugins can schedule
|
||||
EndNoticeWhoGets: Called at end of inbox delivery prep; plugins can filter out profiles from receiving inbox delivery here. Be aware that output can be cached or used several times, so should remain idempotent.
|
||||
- $notice Notice
|
||||
- &$ni: in/out array mapping profile IDs to constants: NOTICE_INBOX_SOURCE_SUB etc
|
||||
|
||||
StartDefaultLocalNav: When showing the default local nav
|
||||
- $menu: the menu
|
||||
- $user: current user
|
||||
|
||||
EndDefaultLocalNav: When showing the default local nav
|
||||
- $menu: the menu
|
||||
- $user: current user
|
||||
|
||||
StartShowAccountProfileBlock: When showing the profile block for an account
|
||||
- $out: XMLOutputter to append custom output
|
||||
- $profile: the profile being shown
|
||||
|
||||
EndShowAccountProfileBlock: After showing the profile block for an account
|
||||
- $out: XMLOutputter to append custom output
|
||||
- $profile: the profile being shown
|
||||
|
||||
StartShowGroupProfileBlock: When showing the profile block for a group
|
||||
- $out: XMLOutputter to append custom output
|
||||
- $profile: the profile being shown
|
||||
|
||||
EndShowGroupProfileBlock: After showing the profile block for a group
|
||||
- $out: XMLOutputter to append custom output
|
||||
- $group: the group being shown
|
||||
|
||||
StartShowThreadedNoticeTail: when showing the replies etc. to a notice
|
||||
- $nli: parent noticelistitem
|
||||
- $notice: parent notice
|
||||
- &$children: list of children
|
||||
|
||||
EndShowThreadedNoticeTail: when showing the replies etc. to a notice
|
||||
- $nli: parent noticelistitem
|
||||
- $notice: parent notice
|
||||
- $children: list of children
|
||||
|
||||
StartShowThreadedNoticeSub: when showing a reply to a notice
|
||||
- $nli: parent noticelistitem
|
||||
- $parent: parent notice
|
||||
- $child: child notice
|
||||
|
||||
EndShowThreadedNoticeSub: when showing a reply to a notice
|
||||
- $nli: parent noticelistitem
|
||||
- $parent: parent notice
|
||||
- $child: child notice
|
||||
|
||||
StartAddEmailAddress: when adding an email address through the Web UI
|
||||
- $user: user getting the new address
|
||||
- $email: email being added
|
||||
|
||||
EndAddEmailAddress: done adding an email address through the Web UI
|
||||
- $user: user getting the new address
|
||||
- $email: email being added
|
||||
|
||||
StartValidateEmailInvite: when validating an email address for invitations
|
||||
- $user: user doing the invite
|
||||
- $email: email address
|
||||
- &$valid: flag for if it's valid; can be modified
|
||||
|
||||
EndValidateEmailInvite: after validating an email address for invitations
|
||||
- $user: user doing the invite
|
||||
- $email: email address
|
||||
- &$valid: flag for if it's valid; can be modified
|
||||
|
||||
StartLocalURL: before resolving a local url for an action
|
||||
- &$action: action to find a path for
|
||||
- &$paramsi: parameters to pass to the action
|
||||
- &$fragment: any url fragement
|
||||
- &$addSession: whether to add session variable
|
||||
- &$url: resulting URL to local resource
|
||||
|
||||
EndLocalURL: before resolving a local url for an action
|
||||
- &$action: action to find a path for
|
||||
- &$paramsi: parameters to pass to the action
|
||||
- &$fragment: any url fragement
|
||||
- &$addSession: whether to add session variable
|
||||
- &$url: resulting URL to local resource
|
||||
|
||||
StartProfileGetAvatar: When getting an avatar for a profile
|
||||
- $profile: profile
|
||||
- $size: size of the avatar
|
||||
- &$avatar: avatar
|
||||
|
||||
EndProfileGetAvatar: After getting an avatar for a profile
|
||||
- $profile: profile
|
||||
- $size: size of the avatar
|
||||
- &$avatar: avatar
|
||||
|
||||
StartRegisterSuccess: Before showing the registration success message
|
||||
- $action: the registration action
|
||||
|
||||
StartRegisterSuccess: After showing the registration success message
|
||||
- $action: the registration action
|
||||
|
||||
StartDocFileForTitle: Before searching for a doc or mail template
|
||||
- $title: Title we're looking for
|
||||
- &$paths: Paths we're searching
|
||||
- &$filename: Filename so far (set this if you want)
|
||||
|
||||
EndDocFileForTitle: After searching for a doc or mail template
|
||||
- $title: Title we looked for
|
||||
- $paths: Paths we searched
|
||||
- &$filename: Filename so far (set this if you want)
|
||||
|
||||
StartReadWriteTables: when noting which tables must be read-write, even on read-only actions
|
||||
- &$tables: list of table names
|
||||
- &$rwdb: read-write database URI
|
||||
|
||||
EndReadWriteTables: after noting which tables must be read-write, even on read-only actions
|
||||
- $tables: list of table names
|
||||
- $rwdb: read-write database URI
|
||||
|
||||
StartShowInviteForm: Right before displaying the invitations form
|
||||
- $action: invitation action
|
||||
|
||||
EndShowInviteForm: After displaying the invitations form
|
||||
- $action: invitation action
|
||||
|
||||
StartSendInvitations: Right before sending invitations
|
||||
- $action: invitation action
|
||||
|
||||
EndSendInvitations: Right after sending invitations
|
||||
- $action: invitation action
|
||||
|
||||
StartShowInvitationSuccess: Right before showing invitations success msg
|
||||
- $action: invitation action
|
||||
|
||||
EndShowInvitationSuccess: After showing invitations success msg
|
||||
- $action: invitation action
|
||||
|
||||
|
116
README
116
README
@ -2,8 +2,8 @@
|
||||
README
|
||||
------
|
||||
|
||||
StatusNet 0.9.6 "Man on the Moon"
|
||||
29 October 2010
|
||||
StatusNet 0.9.7 "World Leader Pretend"
|
||||
17 March 2011
|
||||
|
||||
This is the README file for StatusNet, the Open Source microblogging
|
||||
platform. It includes installation instructions, descriptions of
|
||||
@ -96,43 +96,47 @@ for additional terms.
|
||||
New this version
|
||||
================
|
||||
|
||||
This is a security, bug and feature release since version 0.9.5 released on
|
||||
10 September 2010.
|
||||
This is a security, bug and feature release since version 0.9.6 released on
|
||||
23 October 2010.
|
||||
|
||||
For best compatibility with client software and site federation, and a lot of
|
||||
bug fixes, it is highly recommended that all public sites upgrade to the new
|
||||
version.
|
||||
For best compatibility with client software and site federation, and a
|
||||
lot of bug fixes, it is highly recommended that all public sites
|
||||
upgrade to the new version. Upgrades require new database indexes for
|
||||
best performance; see Upgrade below.
|
||||
|
||||
Notable changes this version:
|
||||
|
||||
- Site moderators can now delete groups.
|
||||
- New themes: clean, shiny, mnml, victorian
|
||||
- New YammerImport plugin allows site admins to import non-private profiles and
|
||||
message from an authenticated Yammer site.
|
||||
- New experimental plugins: AnonFavorites, SlicedFavorites, GroupFavorited,
|
||||
ForceGroup, ShareNotice
|
||||
- OAuth upgraded to 1.0a
|
||||
- Localization updates now include plugins, thanks to translatewiki.net!
|
||||
- SSL link generation should be more consistent; alternate SSL URLs can be
|
||||
set in the admin UI for more parts of the system.
|
||||
- Experimental backupuser.php, restoreuser.php command-line scripts to
|
||||
dump/restore a user's complete activity stream. Can be used to transfer
|
||||
accounts manually between sites, or to save a backup before deleting.
|
||||
- Unicode fixes for OStatus notices
|
||||
- Header metadata on notice pages to aid in manual reposting on Facebook
|
||||
- Lots of little fixes...
|
||||
- GroupPrivateMessage plugin lets users send private messages
|
||||
to a group. (Similar to "private groups" on Yammer.)
|
||||
- Support for Twitter streaming API in Twitter bridge plugin
|
||||
- Support for a new Activity Streams-based API using AtomPub, allowing
|
||||
richer API data. See http://status.net/wiki/AtomPub for details.
|
||||
- Unified Facebook plugin, replacing previous Facebook application
|
||||
and Facebook Connect plugin.
|
||||
- A plugin to send out a daily summary email to network users.
|
||||
- In-line thumbnails of some attachments (video, images) and oEmbed objects.
|
||||
- Local copies of remote profiles to let moderators manage OStatus users.
|
||||
- Upgrade upstream JS, minify everything.
|
||||
- Allow pushing plugin JS, CSS, and static files to a CDN.
|
||||
- Configurable nickname rules.
|
||||
- Better support for bit.ly URL shortener.
|
||||
- InProcessCache plugin for additional caching on top of memcached.
|
||||
- Support for Activity Streams JSON feeds on many streams.
|
||||
- User-initiated backup and restore of account data in Activity Streams
|
||||
format.
|
||||
- Bookmark plugin for making del.icio.us-like social bookmarking sites,
|
||||
including del.icio.us backup file import. Supports OStatus.
|
||||
- SQLProfile plugin to tune SQL queries.
|
||||
- Better sorting on timelines to support restored or imported data.
|
||||
- Hundreds of translations from http://translatewiki.net/
|
||||
- Hundreds of performance tunings, bug fixes, and UI improvements.
|
||||
- Remove deprecated data from Activity Streams Atom output, to the
|
||||
extent possible.
|
||||
- NewMenu plugin for new layout of menu items.
|
||||
- Experimental support for moving an account from one server to
|
||||
another, using new AtomPub API.
|
||||
|
||||
Changes from 0.9.6 release candidate 1:
|
||||
- fix for broken group pages when logged out
|
||||
- fix for stuck ping queue entries when bad profile
|
||||
- fix for bogus single-user nickname config entry error
|
||||
- i18n updates
|
||||
- nofollow updates
|
||||
- SSL-only mode secure cookie fix
|
||||
- experimental ApiLogger plugin for usage data gathering
|
||||
- experimental follow-everyone plugin
|
||||
|
||||
A full changelog is available at http://status.net/wiki/StatusNet_0.9.6.
|
||||
A full changelog is available at http://status.net/wiki/StatusNet_0.9.7.
|
||||
|
||||
Prerequisites
|
||||
=============
|
||||
@ -243,9 +247,9 @@ especially if you've previously installed PHP/MySQL packages.
|
||||
1. Unpack the tarball you downloaded on your Web server. Usually a
|
||||
command like this will work:
|
||||
|
||||
tar zxf statusnet-0.9.6.tar.gz
|
||||
tar zxf statusnet-0.9.7.tar.gz
|
||||
|
||||
...which will make a statusnet-0.9.6 subdirectory in your current
|
||||
...which will make a statusnet-0.9.7 subdirectory in your current
|
||||
directory. (If you don't have shell access on your Web server, you
|
||||
may have to unpack the tarball on your local computer and FTP the
|
||||
files to the server.)
|
||||
@ -253,7 +257,7 @@ especially if you've previously installed PHP/MySQL packages.
|
||||
2. Move the tarball to a directory of your choosing in your Web root
|
||||
directory. Usually something like this will work:
|
||||
|
||||
mv statusnet-0.9.6 /var/www/statusnet
|
||||
mv statusnet-0.9.7 /var/www/statusnet
|
||||
|
||||
This will make your StatusNet instance available in the statusnet path of
|
||||
your server, like "http://example.net/statusnet". "microblog" or
|
||||
@ -668,7 +672,7 @@ with this situation.
|
||||
If you've been using StatusNet 0.7, 0.6, 0.5 or lower, or if you've
|
||||
been tracking the "git" version of the software, you will probably
|
||||
want to upgrade and keep your existing data. There is no automated
|
||||
upgrade procedure in StatusNet 0.9.6. Try these step-by-step
|
||||
upgrade procedure in StatusNet 0.9.7. Try these step-by-step
|
||||
instructions; read to the end first before trying them.
|
||||
|
||||
0. Download StatusNet and set up all the prerequisites as if you were
|
||||
@ -689,25 +693,30 @@ instructions; read to the end first before trying them.
|
||||
5. Once all writing processes to your site are turned off, make a
|
||||
final backup of the Web directory and database.
|
||||
6. Move your StatusNet directory to a backup spot, like "statusnet.bak".
|
||||
7. Unpack your StatusNet 0.9.6 tarball and move it to "statusnet" or
|
||||
7. Unpack your StatusNet 0.9.7 tarball and move it to "statusnet" or
|
||||
wherever your code used to be.
|
||||
8. Copy the config.php file and the contents of the avatar/, background/,
|
||||
file/, and local/ subdirectories from your old directory to your new
|
||||
directory.
|
||||
9. Copy htaccess.sample to .htaccess in the new directory. Change the
|
||||
RewriteBase to use the correct path.
|
||||
10. Rebuild the database. (You can safely skip this step and go to #12
|
||||
if you're upgrading from another 0.9.x version).
|
||||
10. Rebuild the database.
|
||||
|
||||
NOTE: this step is destructive and cannot be
|
||||
reversed. YOU CAN EASILY DESTROY YOUR SITE WITH THIS STEP. Don't
|
||||
do it without a known-good backup!
|
||||
|
||||
If your database is at version 0.8.0 or above, you can run a
|
||||
If your database is at version 0.8.0 or higher in the 0.8.x line, you can run a
|
||||
special upgrade script:
|
||||
|
||||
mysql -u<rootuser> -p<rootpassword> <database> db/08to09.sql
|
||||
|
||||
If you are upgrading from any 0.9.x version like 0.9.6, run this script:
|
||||
|
||||
mysql -u<rootuser> -p<rootpassword> <database> db/096to097.sql
|
||||
|
||||
Despite the name, it should work for any 0.9.x branch.
|
||||
|
||||
Otherwise, go to your StatusNet directory and AFTER YOU MAKE A
|
||||
BACKUP run the rebuilddb.sh script like this:
|
||||
|
||||
@ -1143,6 +1152,9 @@ ssl: Whether to use SSL for JavaScript files. Default is null, which means
|
||||
sslserver: SSL server to use when page is HTTPS-encrypted. If
|
||||
unspecified, site ssl server and so on will be used.
|
||||
sslpath: If sslserver if defined, path to use when page is HTTPS-encrypted.
|
||||
bustframes: If true, all web pages will break out of framesets. If false,
|
||||
can comfortably live in a frame or iframe... probably. Default
|
||||
to true.
|
||||
|
||||
xmpp
|
||||
----
|
||||
@ -1392,13 +1404,25 @@ maxaliases: maximum number of aliases a group can have. Default 3. Set
|
||||
desclimit: maximum number of characters to allow in group descriptions.
|
||||
null (default) means to use the site-wide text limits. 0
|
||||
means no limit.
|
||||
addtag: Whether to add a tag for the group nickname for every group post
|
||||
(pre-1.0.x behaviour). Defaults to false.
|
||||
|
||||
oohembed
|
||||
oembed
|
||||
--------
|
||||
|
||||
oEmbed endpoint for multimedia attachments (links in posts).
|
||||
oEmbed endpoint for multimedia attachments (links in posts). Will also
|
||||
work as 'oohembed' for backwards compatibility.
|
||||
|
||||
endpoint: oohembed endpoint using http://oohembed.com/ software.
|
||||
endpoint: oohembed endpoint using http://oohembed.com/ software. Defaults to
|
||||
'http://oohembed.com/oohembed/'.
|
||||
order: Array of methods to check for OEmbed data. Methods include 'built-in'
|
||||
(use a built-in function to simulate oEmbed for some sites),
|
||||
'well-known' (use well-known public oEmbed endpoints),
|
||||
'discovery' (discover using <link> headers in HTML), 'service' (use
|
||||
a third-party service, like oohembed or embed.ly. Default is
|
||||
array('built-in', 'well-known', 'service', 'discovery'). Note that very
|
||||
few sites implement oEmbed; 'discovery' is going to fail 99% of the
|
||||
time.
|
||||
|
||||
search
|
||||
------
|
||||
@ -1472,6 +1496,8 @@ 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.
|
||||
defaultscope: default scope for notices. Defaults to 0; set to
|
||||
1 to keep notices private to this site by default.
|
||||
|
||||
message
|
||||
-------
|
||||
|
178
actions/addpeopletag.php
Normal file
178
actions/addpeopletag.php
Normal file
@ -0,0 +1,178 @@
|
||||
<?php
|
||||
/**
|
||||
* StatusNet - the distributed open-source microblogging tool
|
||||
* Copyright (C) 2008-2010, StatusNet, Inc.
|
||||
*
|
||||
* Action to add a people tag to a user.
|
||||
*
|
||||
* 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/>.
|
||||
*
|
||||
* PHP version 5
|
||||
*
|
||||
* @category Action
|
||||
* @package StatusNet
|
||||
* @author Shashi Gowda <connect2shashi@gmail.com>
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPLv3
|
||||
* @link http://status.net/
|
||||
*/
|
||||
|
||||
if (!defined('STATUSNET')) {
|
||||
exit(1);
|
||||
}
|
||||
|
||||
require_once INSTALLDIR . '/lib/togglepeopletag.php';
|
||||
|
||||
/**
|
||||
*
|
||||
* Action to tag a profile with a single tag.
|
||||
*
|
||||
* Takes parameters:
|
||||
*
|
||||
* - tagged: the ID of the profile being tagged
|
||||
* - token: session token to prevent CSRF attacks
|
||||
* - ajax: boolean; whether to return Ajax or full-browser results
|
||||
* - peopletag_id: the ID of the tag being used
|
||||
*
|
||||
* Only works if the current user is logged in.
|
||||
*
|
||||
* @category Action
|
||||
* @package StatusNet
|
||||
* @author Shashi Gowda <connect2shashi@gmail.com>
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPLv3
|
||||
* @link http://status.net/
|
||||
*/
|
||||
class AddpeopletagAction extends Action
|
||||
{
|
||||
var $user;
|
||||
var $tagged;
|
||||
var $peopletag;
|
||||
|
||||
/**
|
||||
* Check pre-requisites and instantiate attributes
|
||||
*
|
||||
* @param Array $args array of arguments (URL, GET, POST)
|
||||
*
|
||||
* @return boolean success flag
|
||||
*/
|
||||
function prepare($args)
|
||||
{
|
||||
parent::prepare($args);
|
||||
|
||||
// CSRF protection
|
||||
|
||||
$token = $this->trimmed('token');
|
||||
|
||||
if (!$token || $token != common_session_token()) {
|
||||
// TRANS: Client error displayed when the session token does not match or is not given.
|
||||
$this->clientError(_('There was a problem with your session token.'.
|
||||
' Try again, please.'));
|
||||
return false;
|
||||
}
|
||||
|
||||
// Only for logged-in users
|
||||
|
||||
$this->user = common_current_user();
|
||||
|
||||
if (empty($this->user)) {
|
||||
// TRANS: Error message displayed when trying to perform an action that requires a logged in user.
|
||||
$this->clientError(_('Not logged in.'));
|
||||
return false;
|
||||
}
|
||||
|
||||
// Profile to subscribe to
|
||||
|
||||
$tagged_id = $this->arg('tagged');
|
||||
|
||||
$this->tagged = Profile::staticGet('id', $tagged_id);
|
||||
|
||||
if (empty($this->tagged)) {
|
||||
// TRANS: Client error displayed trying to perform an action related to a non-existing profile.
|
||||
$this->clientError(_('No such profile.'));
|
||||
return false;
|
||||
}
|
||||
|
||||
$id = $this->arg('peopletag_id');
|
||||
$this->peopletag = Profile_list::staticGet('id', $id);
|
||||
|
||||
if (empty($this->peopletag)) {
|
||||
// TRANS: Client error displayed trying to reference a non-existing list.
|
||||
$this->clientError(_('No such list.'));
|
||||
return false;
|
||||
}
|
||||
|
||||
// OMB 0.1 doesn't have a mechanism for local-server-
|
||||
// originated tag.
|
||||
|
||||
$omb01 = Remote_profile::staticGet('id', $tagged_id);
|
||||
|
||||
if (!empty($omb01)) {
|
||||
// TRANS: Client error displayed when trying to add an OMB 0.1 remote profile to a list.
|
||||
$this->clientError(_('You cannot list an OMB 0.1 '.
|
||||
'remote profile with this action.'));
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle request
|
||||
*
|
||||
* Does the tagging and returns results.
|
||||
*
|
||||
* @param Array $args unused.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
function handle($args)
|
||||
{
|
||||
// Throws exception on error
|
||||
$ptag = Profile_tag::setTag($this->user->id, $this->tagged->id,
|
||||
$this->peopletag->tag);
|
||||
|
||||
if (!$ptag) {
|
||||
$user = User::staticGet('id', $id);
|
||||
if ($user) {
|
||||
$this->clientError(
|
||||
// TRANS: Client error displayed when an unknown error occurs when adding a user to a list.
|
||||
// TRANS: %s is a username.
|
||||
sprintf(_('There was an unexpected error while listing %s.'),
|
||||
$user->nickname));
|
||||
} else {
|
||||
// TRANS: Client error displayed when an unknown error occurs when adding a user to a list.
|
||||
// TRANS: %s is a profile URL.
|
||||
$this->clientError(sprintf(_('There was a problem listing %s. ' .
|
||||
'The remote server is probably not responding correctly. ' .
|
||||
'Please try retrying later.'), $this->profile->profileurl));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
if ($this->boolean('ajax')) {
|
||||
$this->startHTML('text/xml;charset=utf-8');
|
||||
$this->elementStart('head');
|
||||
// TRANS: Title after adding a user to a list.
|
||||
$this->element('title', null, _m('TITLE','Listed'));
|
||||
$this->elementEnd('head');
|
||||
$this->elementStart('body');
|
||||
$unsubscribe = new UntagButton($this, $this->tagged, $this->peopletag);
|
||||
$unsubscribe->show();
|
||||
$this->elementEnd('body');
|
||||
$this->elementEnd('html');
|
||||
} else {
|
||||
$url = common_local_url('subscriptions',
|
||||
array('nickname' => $this->user->nickname));
|
||||
common_redirect($url, 303);
|
||||
}
|
||||
}
|
||||
}
|
@ -55,17 +55,15 @@ class AllAction extends ProfileAction
|
||||
function prepare($args)
|
||||
{
|
||||
parent::prepare($args);
|
||||
$cur = common_current_user();
|
||||
|
||||
if (!empty($cur) && $cur->id == $this->user->id) {
|
||||
$this->notice = $this->user->noticeInboxThreaded(($this->page-1)*NOTICES_PER_PAGE, NOTICES_PER_PAGE + 1);
|
||||
} else {
|
||||
$this->notice = $this->user->noticesWithFriendsThreaded(($this->page-1)*NOTICES_PER_PAGE, NOTICES_PER_PAGE + 1);
|
||||
}
|
||||
$stream = new ThreadingInboxNoticeStream($this->user, Profile::current());
|
||||
|
||||
$this->notice = $stream->getNotices(($this->page-1)*NOTICES_PER_PAGE,
|
||||
NOTICES_PER_PAGE + 1);
|
||||
|
||||
if ($this->page > 1 && $this->notice->N == 0) {
|
||||
// TRANS: Server error when page not found (404).
|
||||
$this->serverError(_('No such page.'), $code = 404);
|
||||
$this->serverError(_('No such page.'), 404);
|
||||
}
|
||||
|
||||
return true;
|
||||
@ -86,12 +84,15 @@ class AllAction extends ProfileAction
|
||||
|
||||
function title()
|
||||
{
|
||||
if ($this->page > 1) {
|
||||
// TRANS: Page title. %1$s is user nickname, %2$d is page number
|
||||
return sprintf(_('%1$s and friends, page %2$d'), $this->user->nickname, $this->page);
|
||||
$user = common_current_user();
|
||||
if ($user->id == $this->user->id) {
|
||||
// TRANS: Title of a user's own start page.
|
||||
return _('Home timeline');
|
||||
} else {
|
||||
// TRANS: Page title. %s is user nickname
|
||||
return sprintf(_("%s and friends"), $this->user->nickname);
|
||||
$profile = $this->user->getProfile();
|
||||
// TRANS: Title of another user's start page.
|
||||
// TRANS: %s is the other user's name.
|
||||
return sprintf(_("%s's home timeline"), $profile->getBestName());
|
||||
}
|
||||
}
|
||||
|
||||
@ -157,7 +158,16 @@ class AllAction extends ProfileAction
|
||||
function showContent()
|
||||
{
|
||||
if (Event::handle('StartShowAllContent', array($this))) {
|
||||
$nl = new ThreadedNoticeList($this->notice, $this);
|
||||
|
||||
$profile = null;
|
||||
|
||||
$current_user = common_current_user();
|
||||
|
||||
if (!empty($current_user)) {
|
||||
$profile = $current_user->getProfile();
|
||||
}
|
||||
|
||||
$nl = new ThreadedNoticeList($this->notice, $this, $profile);
|
||||
|
||||
$cnt = $nl->show();
|
||||
|
||||
@ -174,15 +184,21 @@ class AllAction extends ProfileAction
|
||||
}
|
||||
}
|
||||
|
||||
function showPageTitle()
|
||||
function showSections()
|
||||
{
|
||||
$user = common_current_user();
|
||||
if ($user && ($user->id == $this->user->id)) {
|
||||
// TRANS: H1 text for page when viewing a list for self.
|
||||
$this->element('h1', null, _("You and friends"));
|
||||
} else {
|
||||
// TRANS: H1 text for page. %s is a user nickname.
|
||||
$this->element('h1', null, sprintf(_('%s and friends'), $this->user->nickname));
|
||||
$ibs = new InviteButtonSection($this);
|
||||
$ibs->show();
|
||||
$pop = new PopularNoticeSection($this);
|
||||
$pop->show();
|
||||
// $pop = new InboxTagCloudSection($this, $this->user);
|
||||
// $pop->show();
|
||||
}
|
||||
}
|
||||
|
||||
class ThreadingInboxNoticeStream extends ThreadingNoticeStream
|
||||
{
|
||||
function __construct($user, $profile)
|
||||
{
|
||||
parent::__construct(new InboxNoticeStream($user, $profile));
|
||||
}
|
||||
}
|
||||
|
@ -83,16 +83,9 @@ class AllrssAction extends Rss10Action
|
||||
*/
|
||||
function getNotices($limit=0)
|
||||
{
|
||||
$cur = common_current_user();
|
||||
$user = $this->user;
|
||||
$stream = new InboxNoticeStream($this->user);
|
||||
$notice = $stream->getNotices(0, $limit, null, null);
|
||||
|
||||
if (!empty($cur) && $cur->id == $user->id) {
|
||||
$notice = $this->user->noticeInbox(0, $limit);
|
||||
} else {
|
||||
$notice = $this->user->noticesWithFriends(0, $limit);
|
||||
}
|
||||
|
||||
$notice = $user->noticesWithFriends(0, $limit);
|
||||
$notices = array();
|
||||
|
||||
while ($notice->fetch()) {
|
||||
|
@ -66,6 +66,7 @@ class ApiAccountRateLimitStatusAction extends ApiBareAuthAction
|
||||
|
||||
if (!in_array($this->format, array('xml', 'json'))) {
|
||||
$this->clientError(
|
||||
// TRANS: Client error displayed when coming across a non-supported API method.
|
||||
_('API method not found.'),
|
||||
404,
|
||||
$this->format
|
||||
|
@ -88,7 +88,7 @@ class ApiAccountUpdateDeliveryDeviceAction extends ApiAuthAction
|
||||
|
||||
if (!in_array($this->format, array('xml', 'json'))) {
|
||||
$this->clientError(
|
||||
// TRANS: Client error displayed handling a non-existing API method.
|
||||
// TRANS: Client error displayed when coming across a non-supported API method.
|
||||
_('API method not found.'),
|
||||
404,
|
||||
$this->format
|
||||
|
@ -90,7 +90,7 @@ class ApiAccountUpdateProfileAction extends ApiAuthAction
|
||||
|
||||
if (!in_array($this->format, array('xml', 'json'))) {
|
||||
$this->clientError(
|
||||
// TRANS: Client error displayed when trying to handle an unknown API method.
|
||||
// TRANS: Client error displayed when coming across a non-supported API method.
|
||||
_('API method not found.'),
|
||||
404,
|
||||
$this->format
|
||||
@ -107,7 +107,7 @@ class ApiAccountUpdateProfileAction extends ApiAuthAction
|
||||
$profile = $this->user->getProfile();
|
||||
|
||||
if (empty($profile)) {
|
||||
// TRANS: Client error displayed if a user profile could not be found.
|
||||
// TRANS: Error message displayed when referring to a user without a profile.
|
||||
$this->clientError(_('User has no profile.'));
|
||||
return;
|
||||
}
|
||||
|
@ -88,7 +88,7 @@ class ApiAccountUpdateProfileBackgroundImageAction extends ApiAuthAction
|
||||
|
||||
if (!in_array($this->format, array('xml', 'json'))) {
|
||||
$this->clientError(
|
||||
// TRANS: Client error displayed when trying to handle an unknown API method.
|
||||
// TRANS: Client error displayed when coming across a non-supported API method.
|
||||
_('API method not found.'),
|
||||
404,
|
||||
$this->format
|
||||
@ -195,7 +195,7 @@ class ApiAccountUpdateProfileBackgroundImageAction extends ApiAuthAction
|
||||
$profile = $this->user->getProfile();
|
||||
|
||||
if (empty($profile)) {
|
||||
// TRANS: Client error displayed when a user has no profile.
|
||||
// TRANS: Error message displayed when referring to a user without a profile.
|
||||
$this->clientError(_('User has no profile.'));
|
||||
return;
|
||||
}
|
||||
|
@ -111,7 +111,7 @@ class ApiAccountUpdateProfileColorsAction extends ApiAuthAction
|
||||
|
||||
if (!in_array($this->format, array('xml', 'json'))) {
|
||||
$this->clientError(
|
||||
// TRANS: Client error displayed trying to execute an unknown API method updating profile colours.
|
||||
// TRANS: Client error displayed when coming across a non-supported API method.
|
||||
_('API method not found.'),
|
||||
404,
|
||||
$this->format
|
||||
@ -179,7 +179,7 @@ class ApiAccountUpdateProfileColorsAction extends ApiAuthAction
|
||||
$profile = $this->user->getProfile();
|
||||
|
||||
if (empty($profile)) {
|
||||
// TRANS: Client error displayed a user has no profile updating profile colours.
|
||||
// TRANS: Error message displayed when referring to a user without a profile.
|
||||
$this->clientError(_('User has no profile.'));
|
||||
return;
|
||||
}
|
||||
|
@ -127,7 +127,7 @@ class ApiAccountUpdateProfileImageAction extends ApiAuthAction
|
||||
$profile = $this->user->getProfile();
|
||||
|
||||
if (empty($profile)) {
|
||||
// TRANS: Client error displayed if a user profile could not be found updating a profile image.
|
||||
// TRANS: Error message displayed when referring to a user without a profile.
|
||||
$this->clientError(_('User has no profile.'));
|
||||
return;
|
||||
}
|
||||
|
@ -64,7 +64,7 @@ class ApiAccountVerifyCredentialsAction extends ApiAuthAction
|
||||
parent::handle($args);
|
||||
|
||||
if (!in_array($this->format, array('xml', 'json'))) {
|
||||
// TRANS: Client error displayed trying to execute an unknown API method verifying user credentials.
|
||||
// TRANS: Client error displayed when coming across a non-supported API method.
|
||||
$this->clientError(_('API method not found.'), $code = 404);
|
||||
return;
|
||||
}
|
||||
|
@ -153,7 +153,7 @@ class ApiDirectMessageAction extends ApiAuthAction
|
||||
$this->showJsonDirectMessages();
|
||||
break;
|
||||
default:
|
||||
// TRANS: Client error given when an API method was not found (404).
|
||||
// TRANS: Client error displayed when coming across a non-supported API method.
|
||||
$this->clientError(_('API method not found.'), $code = 404);
|
||||
break;
|
||||
}
|
||||
|
@ -94,7 +94,7 @@ class ApiFavoriteCreateAction extends ApiAuthAction
|
||||
|
||||
if (!in_array($this->format, array('xml', 'json'))) {
|
||||
$this->clientError(
|
||||
// TRANS: Client error displayed when trying to handle an unknown API method.
|
||||
// TRANS: Client error displayed when coming across a non-supported API method.
|
||||
_('API method not found.'),
|
||||
404,
|
||||
$this->format
|
||||
|
@ -94,7 +94,7 @@ class ApiFavoriteDestroyAction extends ApiAuthAction
|
||||
|
||||
if (!in_array($this->format, array('xml', 'json'))) {
|
||||
$this->clientError(
|
||||
// TRANS: Client error displayed when trying to handle an unknown API method.
|
||||
// TRANS: Client error displayed when coming across a non-supported API method.
|
||||
_('API method not found.'),
|
||||
404,
|
||||
$this->format
|
||||
|
@ -95,7 +95,7 @@ class ApiFriendshipsCreateAction extends ApiAuthAction
|
||||
|
||||
if (!in_array($this->format, array('xml', 'json'))) {
|
||||
$this->clientError(
|
||||
// TRANS: Client error displayed when trying to handle an unknown API method.
|
||||
// TRANS: Client error displayed when coming across a non-supported API method.
|
||||
_('API method not found.'),
|
||||
404,
|
||||
$this->format
|
||||
|
@ -95,7 +95,7 @@ class ApiFriendshipsDestroyAction extends ApiAuthAction
|
||||
|
||||
if (!in_array($this->format, array('xml', 'json'))) {
|
||||
$this->clientError(
|
||||
// TRANS: Client error displayed when trying to handle an unknown API method.
|
||||
// TRANS: Client error displayed when coming across a non-supported API method.
|
||||
_('API method not found.'),
|
||||
404,
|
||||
$this->format
|
||||
|
@ -120,7 +120,7 @@ class ApiFriendshipsShowAction extends ApiBareAuthAction
|
||||
parent::handle($args);
|
||||
|
||||
if (!in_array($this->format, array('xml', 'json'))) {
|
||||
// TRANS: Client error displayed trying to execute an unknown API method showing friendship.
|
||||
// TRANS: Client error displayed when coming across a non-supported API method.
|
||||
$this->clientError(_('API method not found.'), 404);
|
||||
return;
|
||||
}
|
||||
|
@ -134,7 +134,7 @@ class ApiGroupCreateAction extends ApiAuthAction
|
||||
break;
|
||||
default:
|
||||
$this->clientError(
|
||||
// TRANS: Client error given when an API method was not found (404).
|
||||
// TRANS: Client error displayed when coming across a non-supported API method.
|
||||
_('API method not found.'),
|
||||
404,
|
||||
$this->format
|
||||
|
@ -111,7 +111,7 @@ class ApiGroupIsMemberAction extends ApiBareAuthAction
|
||||
break;
|
||||
default:
|
||||
$this->clientError(
|
||||
// TRANS: Client error displayed trying to execute an unknown API method showing group membership.
|
||||
// TRANS: Client error displayed when coming across a non-supported API method.
|
||||
_('API method not found.'),
|
||||
400,
|
||||
$this->format
|
||||
|
@ -144,7 +144,7 @@ class ApiGroupJoinAction extends ApiAuthAction
|
||||
break;
|
||||
default:
|
||||
$this->clientError(
|
||||
// TRANS: Client error displayed trying to execute an unknown API method joining a group.
|
||||
// TRANS: Client error displayed when coming across a non-supported API method.
|
||||
_('API method not found.'),
|
||||
404,
|
||||
$this->format
|
||||
|
@ -134,7 +134,7 @@ class ApiGroupLeaveAction extends ApiAuthAction
|
||||
break;
|
||||
default:
|
||||
$this->clientError(
|
||||
// TRANS: Client error displayed trying to execute an unknown API method leaving a group.
|
||||
// TRANS: Client error displayed when coming across a non-supported API method.
|
||||
_('API method not found.'),
|
||||
404,
|
||||
$this->format
|
||||
|
@ -67,6 +67,7 @@ class ApiGroupListAction extends ApiBareAuthAction
|
||||
$this->user = $this->getTargetUser(null);
|
||||
|
||||
if (empty($this->user)) {
|
||||
// TRANS: Client error displayed when user not found for an action.
|
||||
$this->clientError(_('No such user.'), 404, $this->format);
|
||||
return false;
|
||||
}
|
||||
@ -130,7 +131,7 @@ class ApiGroupListAction extends ApiBareAuthAction
|
||||
break;
|
||||
default:
|
||||
$this->clientError(
|
||||
// TRANS: Client error displayed trying to execute an unknown API method checking group membership.
|
||||
// TRANS: Client error displayed when coming across a non-supported API method.
|
||||
_('API method not found.'),
|
||||
404,
|
||||
$this->format
|
||||
|
@ -89,7 +89,7 @@ class ApiGroupListAllAction extends ApiPrivateAuthAction
|
||||
$taguribase = TagURI::base();
|
||||
$id = "tag:$taguribase:Groups";
|
||||
$link = common_local_url('groups');
|
||||
// TRANS: Message is used as a subtitle when listing the lastest 20 groups. %s is a site name.
|
||||
// TRANS: Message is used as a subtitle when listing the latest 20 groups. %s is a site name.
|
||||
$subtitle = sprintf(_("groups on %s"), $sitename);
|
||||
|
||||
switch($this->format) {
|
||||
@ -116,7 +116,7 @@ class ApiGroupListAllAction extends ApiPrivateAuthAction
|
||||
break;
|
||||
default:
|
||||
$this->clientError(
|
||||
// TRANS: Client error displayed trying to execute an unknown API method listing the latest 20 groups.
|
||||
// TRANS: Client error displayed when coming across a non-supported API method.
|
||||
_('API method not found.'),
|
||||
404,
|
||||
$this->format
|
||||
|
@ -101,7 +101,7 @@ class ApiGroupMembershipAction extends ApiPrivateAuthAction
|
||||
break;
|
||||
default:
|
||||
$this->clientError(
|
||||
// TRANS: Client error displayed trying to execute an unknown API method showing group membership.
|
||||
// TRANS: Client error displayed when coming across a non-supported API method.
|
||||
_('API method not found.'),
|
||||
404,
|
||||
$this->format
|
||||
|
@ -85,6 +85,7 @@ class ApiGroupProfileUpdateAction extends ApiAuthAction
|
||||
|
||||
if ($_SERVER['REQUEST_METHOD'] != 'POST') {
|
||||
$this->clientError(
|
||||
// TRANS: Client error message. POST is a HTTP command. It should not be translated.
|
||||
_('This method requires a POST.'),
|
||||
400, $this->format
|
||||
);
|
||||
@ -93,7 +94,7 @@ class ApiGroupProfileUpdateAction extends ApiAuthAction
|
||||
|
||||
if (!in_array($this->format, array('xml', 'json'))) {
|
||||
$this->clientError(
|
||||
// TRANS: Client error displayed when using an unsupported API format.
|
||||
// TRANS: Client error displayed when coming across a non-supported API method.
|
||||
_('API method not found.'),
|
||||
404,
|
||||
$this->format
|
||||
@ -211,7 +212,7 @@ class ApiGroupProfileUpdateAction extends ApiAuthAction
|
||||
$this->showSingleJsonGroup($this->group);
|
||||
break;
|
||||
default:
|
||||
// TRANS: Client error displayed when using an unsupported API format.
|
||||
// TRANS: Client error displayed when coming across a non-supported API method.
|
||||
$this->clientError(_('API method not found.'), 404, $this->format);
|
||||
break;
|
||||
}
|
||||
|
@ -110,7 +110,7 @@ class ApiGroupShowAction extends ApiPrivateAuthAction
|
||||
$this->showSingleJsonGroup($this->group);
|
||||
break;
|
||||
default:
|
||||
// TRANS: Client error displayed trying to execute an unknown API method showing a group.
|
||||
// TRANS: Client error displayed when coming across a non-supported API method.
|
||||
$this->clientError(_('API method not found.'), 404, $this->format);
|
||||
break;
|
||||
}
|
||||
|
@ -80,7 +80,7 @@ class ApiHelpTestAction extends ApiPrivateAuthAction
|
||||
$this->endDocument('json');
|
||||
} else {
|
||||
$this->clientError(
|
||||
// TRANS: Client error displayed trying to execute an unknown API method testing API connectivity.
|
||||
// TRANS: Client error displayed when coming across a non-supported API method.
|
||||
_('API method not found.'),
|
||||
404,
|
||||
$this->format
|
||||
|
270
actions/apilist.php
Normal file
270
actions/apilist.php
Normal file
@ -0,0 +1,270 @@
|
||||
<?php
|
||||
/**
|
||||
* StatusNet, the distributed open-source microblogging tool
|
||||
*
|
||||
* Show, update or delete a list.
|
||||
*
|
||||
* 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 Shashi Gowda <connect2shashi@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/
|
||||
*/
|
||||
|
||||
if (!defined('STATUSNET')) {
|
||||
exit(1);
|
||||
}
|
||||
|
||||
require_once INSTALLDIR . '/lib/apibareauth.php';
|
||||
|
||||
class ApiListAction extends ApiBareAuthAction
|
||||
{
|
||||
/**
|
||||
* The list in question in the current request
|
||||
*/
|
||||
var $list = null;
|
||||
|
||||
/**
|
||||
* Is this an update request?
|
||||
*/
|
||||
var $update = false;
|
||||
|
||||
/**
|
||||
* Is this a delete request?
|
||||
*/
|
||||
var $delete = false;
|
||||
|
||||
/**
|
||||
* Set the flags for handling the request. Show list if this is a GET
|
||||
* request, update it if it is POST, delete list if method is DELETE
|
||||
* or if method is POST and an argument _method is set to DELETE. Act
|
||||
* like we don't know if the current user has no access to the list.
|
||||
*
|
||||
* Takes parameters:
|
||||
* - user: the user id or nickname
|
||||
* - id: the id of the tag or the tag itself
|
||||
*
|
||||
* @return boolean success flag
|
||||
*/
|
||||
function prepare($args)
|
||||
{
|
||||
parent::prepare($args);
|
||||
|
||||
$this->delete = ($_SERVER['REQUEST_METHOD'] == 'DELETE' ||
|
||||
($this->trimmed('_method') == 'DELETE' &&
|
||||
$_SERVER['REQUEST_METHOD'] == 'POST'));
|
||||
|
||||
// update list if method is POST or PUT and $this->delete is not true
|
||||
$this->update = (!$this->delete &&
|
||||
in_array($_SERVER['REQUEST_METHOD'], array('POST', 'PUT')));
|
||||
|
||||
$this->user = $this->getTargetUser($this->arg('user'));
|
||||
$this->list = $this->getTargetList($this->arg('user'), $this->arg('id'));
|
||||
|
||||
if (empty($this->list)) {
|
||||
// TRANS: Client error displayed when referring to a non-existing list.
|
||||
$this->clientError(_('List not found.'), 404, $this->format);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle the request
|
||||
*
|
||||
* @return boolean success flag
|
||||
*/
|
||||
function handle($args)
|
||||
{
|
||||
parent::handle($args);
|
||||
|
||||
if($this->delete) {
|
||||
$this->handleDelete();
|
||||
return true;
|
||||
}
|
||||
|
||||
if($this->update) {
|
||||
$this->handlePut();
|
||||
return true;
|
||||
}
|
||||
|
||||
switch($this->format) {
|
||||
case 'xml':
|
||||
$this->showSingleXmlList($this->list);
|
||||
break;
|
||||
case 'json':
|
||||
$this->showSingleJsonList($this->list);
|
||||
break;
|
||||
default:
|
||||
$this->clientError(
|
||||
// TRANS: Client error displayed when coming across a non-supported API method.
|
||||
_('API method not found.'),
|
||||
404,
|
||||
$this->format
|
||||
);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* require authentication if it is a write action or user is ambiguous
|
||||
*
|
||||
*/
|
||||
function requiresAuth()
|
||||
{
|
||||
return parent::requiresAuth() ||
|
||||
$this->create || $this->delete;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update a list
|
||||
*
|
||||
* @return boolean success
|
||||
*/
|
||||
function handlePut()
|
||||
{
|
||||
if($this->auth_user->id != $this->list->tagger) {
|
||||
$this->clientError(
|
||||
// TRANS: Client error displayed when trying to update another user's list.
|
||||
_('You cannot update lists that do not belong to you.'),
|
||||
401,
|
||||
$this->format
|
||||
);
|
||||
}
|
||||
|
||||
$new_list = clone($this->list);
|
||||
$new_list->tag = common_canonical_tag($this->arg('name'));
|
||||
$new_list->description = common_canonical_tag($this->arg('description'));
|
||||
$new_list->private = ($this->arg('mode') === 'private') ? true : false;
|
||||
|
||||
$result = $new_list->update($this->list);
|
||||
|
||||
if(!$result) {
|
||||
$this->clientError(
|
||||
// TRANS: Client error displayed when an unknown error occurs updating a list.
|
||||
_('An error occured.'),
|
||||
503,
|
||||
$this->format
|
||||
);
|
||||
}
|
||||
|
||||
switch($this->format) {
|
||||
case 'xml':
|
||||
$this->showSingleXmlList($new_list);
|
||||
break;
|
||||
case 'json':
|
||||
$this->showSingleJsonList($new_list);
|
||||
break;
|
||||
default:
|
||||
$this->clientError(
|
||||
// TRANS: Client error displayed when coming across a non-supported API method.
|
||||
_('API method not found.'),
|
||||
404,
|
||||
$this->format
|
||||
);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete a list
|
||||
*
|
||||
* @return boolean success
|
||||
*/
|
||||
function handleDelete()
|
||||
{
|
||||
if($this->auth_user->id != $this->list->tagger) {
|
||||
$this->clientError(
|
||||
// TRANS: Client error displayed when trying to delete another user's list.
|
||||
_('You cannot delete lists that do not belong to you.'),
|
||||
401,
|
||||
$this->format
|
||||
);
|
||||
}
|
||||
|
||||
$record = clone($this->list);
|
||||
$this->list->delete();
|
||||
|
||||
switch($this->format) {
|
||||
case 'xml':
|
||||
$this->showSingleXmlList($record);
|
||||
break;
|
||||
case 'json':
|
||||
$this->showSingleJsonList($record);
|
||||
break;
|
||||
default:
|
||||
$this->clientError(
|
||||
// TRANS: Client error displayed when coming across a non-supported API method.
|
||||
_('API method not found.'),
|
||||
404,
|
||||
$this->format
|
||||
);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicate that this resource is not read-only.
|
||||
*
|
||||
* @return boolean is_read-only=false
|
||||
*/
|
||||
function isReadOnly($args)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* When was the list (people tag) last updated?
|
||||
*
|
||||
* @return String time_last_modified
|
||||
*/
|
||||
function lastModified()
|
||||
{
|
||||
if(!empty($this->list)) {
|
||||
return strtotime($this->list->modified);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* An entity tag for this list
|
||||
*
|
||||
* Returns an Etag based on the action name, language, user ID and
|
||||
* timestamps of the first and last list the user has joined
|
||||
*
|
||||
* @return string etag
|
||||
*/
|
||||
function etag()
|
||||
{
|
||||
if (!empty($this->list)) {
|
||||
|
||||
return '"' . implode(
|
||||
':',
|
||||
array($this->arg('action'),
|
||||
common_language(),
|
||||
$this->user->id,
|
||||
strtotime($this->list->created),
|
||||
strtotime($this->list->modified))
|
||||
)
|
||||
. '"';
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
125
actions/apilistmember.php
Normal file
125
actions/apilistmember.php
Normal file
@ -0,0 +1,125 @@
|
||||
<?php
|
||||
/**
|
||||
* StatusNet, the distributed open-source microblogging tool
|
||||
*
|
||||
* API method to check if a user belongs to a list.
|
||||
*
|
||||
* 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 Shashi Gowda <connect2shashi@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/
|
||||
*/
|
||||
|
||||
if (!defined('STATUSNET')) {
|
||||
exit(1);
|
||||
}
|
||||
|
||||
require_once INSTALLDIR . '/lib/apibareauth.php';
|
||||
|
||||
/**
|
||||
* Action handler for Twitter list_memeber methods
|
||||
*
|
||||
* @category API
|
||||
* @package StatusNet
|
||||
* @author Shashi Gowda <connect2shashi@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/
|
||||
* @see ApiBareAuthAction
|
||||
*/
|
||||
class ApiListMemberAction extends ApiBareAuthAction
|
||||
{
|
||||
/**
|
||||
* Set the flags for handling the request. Show the profile if this
|
||||
* is a GET request AND the profile is a member of the list, add a member
|
||||
* if it is a POST, remove the profile from the list if method is DELETE
|
||||
* or if method is POST and an argument _method is set to DELETE. Act
|
||||
* like we don't know if the current user has no access to the list.
|
||||
*
|
||||
* Takes parameters:
|
||||
* - user: the user id or nickname
|
||||
* - list_id: the id of the tag or the tag itself
|
||||
* - id: the id of the member being looked for/added/removed
|
||||
*
|
||||
* @return boolean success flag
|
||||
*/
|
||||
function prepare($args)
|
||||
{
|
||||
parent::prepare($args);
|
||||
|
||||
$this->user = $this->getTargetUser($this->arg('id'));
|
||||
$this->list = $this->getTargetList($this->arg('user'), $this->arg('list_id'));
|
||||
|
||||
if (empty($this->list)) {
|
||||
// TRANS: Client error displayed when referring to a non-existing list.
|
||||
$this->clientError(_('List not found.'), 404, $this->format);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (empty($this->user)) {
|
||||
// TRANS: Client error displayed when referring to a non-existing user.
|
||||
$this->clientError(_('No such user.'), 404, $this->format);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle the request
|
||||
*
|
||||
* @return boolean success flag
|
||||
*/
|
||||
function handle($args)
|
||||
{
|
||||
parent::handle($args);
|
||||
|
||||
$arr = array('tagger' => $this->list->tagger,
|
||||
'tag' => $this->list->tag,
|
||||
'tagged' => $this->user->id);
|
||||
$ptag = Profile_tag::pkeyGet($arr);
|
||||
|
||||
if(empty($ptag)) {
|
||||
$this->clientError(
|
||||
// TRANS: Client error displayed when referring to a non-list member.
|
||||
_('The specified user is not a member of this list.'),
|
||||
400,
|
||||
$this->format
|
||||
);
|
||||
}
|
||||
|
||||
$user = $this->twitterUserArray($this->user->getProfile(), true);
|
||||
|
||||
switch($this->format) {
|
||||
case 'xml':
|
||||
$this->showTwitterXmlUser($user, 'user', true);
|
||||
break;
|
||||
case 'json':
|
||||
$this->showSingleJsonUser($user);
|
||||
break;
|
||||
default:
|
||||
$this->clientError(
|
||||
// TRANS: Client error displayed when coming across a non-supported API method.
|
||||
_('API method not found.'),
|
||||
404,
|
||||
$this->format
|
||||
);
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
179
actions/apilistmembers.php
Normal file
179
actions/apilistmembers.php
Normal file
@ -0,0 +1,179 @@
|
||||
<?php
|
||||
/**
|
||||
* StatusNet, the distributed open-source microblogging tool
|
||||
*
|
||||
* List/add/remove list 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 Shashi Gowda <connect2shashi@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/
|
||||
*/
|
||||
|
||||
if (!defined('STATUSNET')) {
|
||||
exit(1);
|
||||
}
|
||||
|
||||
require_once INSTALLDIR . '/lib/apilistusers.php';
|
||||
|
||||
class ApiListMembersAction extends ApiListUsersAction
|
||||
{
|
||||
/**
|
||||
* Add a user to a list (tag someone)
|
||||
*
|
||||
* @return boolean success
|
||||
*/
|
||||
function handlePost()
|
||||
{
|
||||
if($this->auth_user->id != $this->list->tagger) {
|
||||
$this->clientError(
|
||||
// TRANS: Client error displayed when trying to add members to a list without having the right to do so.
|
||||
_('You are not allowed to add members to this list.'),
|
||||
401,
|
||||
$this->format
|
||||
);
|
||||
return false;
|
||||
}
|
||||
|
||||
if($this->user === false) {
|
||||
$this->clientError(
|
||||
// TRANS: Client error displayed when trying to modify list members without specifying them.
|
||||
_('You must specify a member.'),
|
||||
400,
|
||||
$this->format
|
||||
);
|
||||
return false;
|
||||
}
|
||||
|
||||
$result = Profile_tag::setTag($this->auth_user->id,
|
||||
$this->user->id, $this->list->tag);
|
||||
|
||||
if(empty($result)) {
|
||||
$this->clientError(
|
||||
// TRANS: Client error displayed when an unknown error occurs viewing list members.
|
||||
_('An error occured.'),
|
||||
500,
|
||||
$this->format
|
||||
);
|
||||
return false;
|
||||
}
|
||||
|
||||
switch($this->format) {
|
||||
case 'xml':
|
||||
$this->showSingleXmlList($this->list);
|
||||
break;
|
||||
case 'json':
|
||||
$this->showSingleJsonList($this->list);
|
||||
break;
|
||||
default:
|
||||
$this->clientError(
|
||||
// TRANS: Client error displayed when coming across a non-supported API method.
|
||||
_('API method not found.'),
|
||||
404,
|
||||
$this->format
|
||||
);
|
||||
return false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove a user from a list (untag someone)
|
||||
*
|
||||
* @return boolean success
|
||||
*/
|
||||
function handleDelete()
|
||||
{
|
||||
if($this->auth_user->id != $this->list->tagger) {
|
||||
$this->clientError(
|
||||
// TRANS: Client error displayed when trying to remove members from a list without having the right to do so.
|
||||
_('You are not allowed to remove members from this list.'),
|
||||
401,
|
||||
$this->format
|
||||
);
|
||||
return false;
|
||||
}
|
||||
|
||||
if($this->user === false) {
|
||||
$this->clientError(
|
||||
// TRANS: Client error displayed when trying to modify list members without specifying them.
|
||||
_('You must specify a member.'),
|
||||
400,
|
||||
$this->format
|
||||
);
|
||||
return false;
|
||||
}
|
||||
|
||||
$args = array('tagger' => $this->auth_user->id,
|
||||
'tagged' => $this->user->id,
|
||||
'tag' => $this->list->tag);
|
||||
$ptag = Profile_tag::pkeyGet($args);
|
||||
|
||||
if(empty($ptag)) {
|
||||
$this->clientError(
|
||||
// TRANS: Client error displayed when trying to remove a list member that is not part of a list.
|
||||
_('The user you are trying to remove from the list is not a member.'),
|
||||
400,
|
||||
$this->format
|
||||
);
|
||||
return false;
|
||||
}
|
||||
|
||||
$result = $ptag->delete();
|
||||
|
||||
if(empty($result)) {
|
||||
$this->clientError(
|
||||
// TRANS: Client error displayed when an unknown error occurs viewing list members.
|
||||
_('An error occured.'),
|
||||
500,
|
||||
$this->format
|
||||
);
|
||||
return false;
|
||||
}
|
||||
|
||||
switch($this->format) {
|
||||
case 'xml':
|
||||
$this->showSingleXmlList($this->list);
|
||||
break;
|
||||
case 'json':
|
||||
$this->showSingleJsonList($this->list);
|
||||
break;
|
||||
default:
|
||||
$this->clientError(
|
||||
// TRANS: Client error displayed when coming across a non-supported API method.
|
||||
_('API method not found.'),
|
||||
404,
|
||||
$this->format
|
||||
);
|
||||
return false;
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* List the members of a list (people tagged)
|
||||
*/
|
||||
function getUsers()
|
||||
{
|
||||
$fn = array($this->list, 'getTagged');
|
||||
list($this->users, $this->next_cursor, $this->prev_cursor) =
|
||||
Profile_list::getAtCursor($fn, array(), $this->cursor, 20);
|
||||
}
|
||||
}
|
134
actions/apilistmemberships.php
Normal file
134
actions/apilistmemberships.php
Normal file
@ -0,0 +1,134 @@
|
||||
<?php
|
||||
/**
|
||||
* StatusNet, the distributed open-source microblogging tool
|
||||
*
|
||||
* Get a list of lists a user belongs to. (people tags for a user)
|
||||
*
|
||||
* PHP version 5
|
||||
*
|
||||
* LICENCE: This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* @category API
|
||||
* @package StatusNet
|
||||
* @author Shashi Gowda <connect2shashi@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/
|
||||
*/
|
||||
|
||||
if (!defined('STATUSNET')) {
|
||||
exit(1);
|
||||
}
|
||||
|
||||
require_once INSTALLDIR . '/lib/apibareauth.php';
|
||||
|
||||
/**
|
||||
* Action handler for API method to list lists a user belongs to.
|
||||
* (people tags for a user)
|
||||
*
|
||||
* @category API
|
||||
* @package StatusNet
|
||||
* @author Shashi Gowda <connect2shashi@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/
|
||||
* @see ApiBareAuthAction
|
||||
*/
|
||||
class ApiListMembershipsAction extends ApiBareAuthAction
|
||||
{
|
||||
var $lists = array();
|
||||
var $cursor = -1;
|
||||
var $next_cursor = 0;
|
||||
var $prev_cursor = 0;
|
||||
|
||||
/**
|
||||
* Prepare for running the action
|
||||
* Take arguments for running:s
|
||||
*
|
||||
* @param array $args $_REQUEST args
|
||||
*
|
||||
* @return boolean success flag
|
||||
*
|
||||
*/
|
||||
function prepare($args)
|
||||
{
|
||||
parent::prepare($args);
|
||||
|
||||
$this->cursor = (int) $this->arg('cursor', -1);
|
||||
$this->user = $this->getTargetUser($this->arg('user'));
|
||||
|
||||
if (empty($this->user)) {
|
||||
// TRANS: Client error displayed trying to perform an action related to a non-existing user.
|
||||
$this->clientError(_('No such user.'), 404, $this->format);
|
||||
return;
|
||||
}
|
||||
|
||||
$this->getLists();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle the request
|
||||
*
|
||||
* Show the lists
|
||||
*
|
||||
* @param array $args $_REQUEST data (unused)
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
function handle($args)
|
||||
{
|
||||
parent::handle($args);
|
||||
|
||||
switch($this->format) {
|
||||
case 'xml':
|
||||
$this->showXmlLists($this->lists, $this->next_cursor, $this->prev_cursor);
|
||||
break;
|
||||
case 'json':
|
||||
$this->showJsonLists($this->lists, $this->next_cursor, $this->prev_cursor);
|
||||
break;
|
||||
default:
|
||||
$this->clientError(
|
||||
// TRANS: Client error displayed when coming across a non-supported API method.
|
||||
_('API method not found.'),
|
||||
400,
|
||||
$this->format
|
||||
);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if read only.
|
||||
*
|
||||
* MAY override
|
||||
*
|
||||
* @param array $args other arguments
|
||||
*
|
||||
* @return boolean is read only action?
|
||||
*/
|
||||
function isReadOnly($args)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
function getLists()
|
||||
{
|
||||
$profile = $this->user->getProfile();
|
||||
$fn = array($profile, 'getOtherTags');
|
||||
|
||||
# 20 lists
|
||||
list($this->lists, $this->next_cursor, $this->prev_cursor) =
|
||||
Profile_list::getAtCursor($fn, array($this->auth_user), $this->cursor, 20);
|
||||
}
|
||||
}
|
240
actions/apilists.php
Normal file
240
actions/apilists.php
Normal file
@ -0,0 +1,240 @@
|
||||
<?php
|
||||
/**
|
||||
* StatusNet, the distributed open-source microblogging tool
|
||||
*
|
||||
* List existing lists or create a new list.
|
||||
*
|
||||
* 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 Shashi Gowda <connect2shashi@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/
|
||||
*/
|
||||
|
||||
if (!defined('STATUSNET')) {
|
||||
exit(1);
|
||||
}
|
||||
|
||||
require_once INSTALLDIR . '/lib/apibareauth.php';
|
||||
|
||||
/**
|
||||
* Action handler for Twitter list_memeber methods
|
||||
*
|
||||
* @category API
|
||||
* @package StatusNet
|
||||
* @author Shashi Gowda <connect2shashi@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/
|
||||
* @see ApiBareAuthAction
|
||||
*/
|
||||
class ApiListsAction extends ApiBareAuthAction
|
||||
{
|
||||
var $lists = null;
|
||||
var $cursor = 0;
|
||||
var $next_cursor = 0;
|
||||
var $prev_cursor = 0;
|
||||
var $create = false;
|
||||
|
||||
/**
|
||||
* Set the flags for handling the request. List lists created by user if this
|
||||
* is a GET request, create a new list if it is a POST request.
|
||||
*
|
||||
* Takes parameters:
|
||||
* - user: the user id or nickname
|
||||
* Parameters for POST request
|
||||
* - name: name of the new list (the people tag itself)
|
||||
* - mode: (optional) mode for the new list private/public
|
||||
* - description: (optional) description for the list
|
||||
*
|
||||
* @return boolean success flag
|
||||
*/
|
||||
function prepare($args)
|
||||
{
|
||||
parent::prepare($args);
|
||||
|
||||
$this->create = ($_SERVER['REQUEST_METHOD'] == 'POST');
|
||||
|
||||
if (!$this->create) {
|
||||
|
||||
$this->user = $this->getTargetUser($this->arg('user'));
|
||||
|
||||
if (empty($this->user)) {
|
||||
// TRANS: Client error displayed trying to perform an action related to a non-existing user.
|
||||
$this->clientError(_('No such user.'), 404, $this->format);
|
||||
return false;
|
||||
}
|
||||
$this->getLists();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* require authentication if it is a write action or user is ambiguous
|
||||
*
|
||||
*/
|
||||
function requiresAuth()
|
||||
{
|
||||
return parent::requiresAuth() ||
|
||||
$this->create || $this->delete;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle request:
|
||||
* Show the lists the user has created if the request method is GET
|
||||
* Create a new list by diferring to handlePost() if it is POST.
|
||||
*/
|
||||
function handle($args)
|
||||
{
|
||||
parent::handle($args);
|
||||
|
||||
if($this->create) {
|
||||
return $this->handlePost();
|
||||
}
|
||||
|
||||
switch($this->format) {
|
||||
case 'xml':
|
||||
$this->showXmlLists($this->lists, $this->next_cursor, $this->prev_cursor);
|
||||
break;
|
||||
case 'json':
|
||||
$this->showJsonLists($this->lists, $this->next_cursor, $this->prev_cursor);
|
||||
break;
|
||||
default:
|
||||
$this->clientError(
|
||||
// TRANS: Client error displayed when coming across a non-supported API method.
|
||||
_('API method not found.'),
|
||||
404,
|
||||
$this->format
|
||||
);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new list
|
||||
*
|
||||
* @return boolean success
|
||||
*/
|
||||
function handlePost()
|
||||
{
|
||||
$name=$this->arg('name');
|
||||
if(empty($name)) {
|
||||
// mimick twitter
|
||||
// TRANS: Client error displayed when trying to create a list without a name.
|
||||
print _("A list must have a name.");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// twitter creates a new list by appending a number to the end
|
||||
// if the list by the given name already exists
|
||||
// it makes more sense to return the existing list instead
|
||||
|
||||
$private = null;
|
||||
if ($this->arg('mode') === 'public') {
|
||||
$private = false;
|
||||
} else if ($this->arg('mode') === 'private') {
|
||||
$private = true;
|
||||
}
|
||||
|
||||
$list = Profile_list::ensureTag($this->auth_user->id,
|
||||
$this->arg('name'),
|
||||
$this->arg('description'),
|
||||
$private);
|
||||
if (empty($list)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
switch($this->format) {
|
||||
case 'xml':
|
||||
$this->showSingleXmlList($list);
|
||||
break;
|
||||
case 'json':
|
||||
$this->showSingleJsonList($list);
|
||||
break;
|
||||
default:
|
||||
$this->clientError(
|
||||
// TRANS: Client error displayed when coming across a non-supported API method.
|
||||
_('API method not found.'),
|
||||
404,
|
||||
$this->format
|
||||
);
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get lists
|
||||
*/
|
||||
function getLists()
|
||||
{
|
||||
$cursor = (int) $this->arg('cursor', -1);
|
||||
|
||||
// twitter fixes count at 20
|
||||
// there is no argument named count
|
||||
$count = 20;
|
||||
$profile = $this->user->getProfile();
|
||||
$fn = array($profile, 'getLists');
|
||||
|
||||
list($this->lists,
|
||||
$this->next_cursor,
|
||||
$this->prev_cursor) = Profile_list::getAtCursor($fn, array($this->auth_user), $cursor, $count);
|
||||
}
|
||||
|
||||
function isReadOnly($args)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
function lastModified()
|
||||
{
|
||||
if (!$this->create && !empty($this->lists) && (count($this->lists) > 0)) {
|
||||
return strtotime($this->lists[0]->created);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* An entity tag for this list of lists
|
||||
*
|
||||
* Returns an Etag based on the action name, language, user ID and
|
||||
* timestamps of the first and last list the user has joined
|
||||
*
|
||||
* @return string etag
|
||||
*/
|
||||
function etag()
|
||||
{
|
||||
if (!$this->create && !empty($this->lists) && (count($this->lists) > 0)) {
|
||||
|
||||
$last = count($this->lists) - 1;
|
||||
|
||||
return '"' . implode(
|
||||
':',
|
||||
array($this->arg('action'),
|
||||
common_language(),
|
||||
$this->user->id,
|
||||
strtotime($this->lists[0]->created),
|
||||
strtotime($this->lists[$last]->created))
|
||||
)
|
||||
. '"';
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
95
actions/apilistsubscriber.php
Normal file
95
actions/apilistsubscriber.php
Normal file
@ -0,0 +1,95 @@
|
||||
<?php
|
||||
/**
|
||||
* StatusNet, the distributed open-source microblogging tool
|
||||
*
|
||||
* Check if a user is subscribed to a list
|
||||
*
|
||||
* 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
|
||||
* @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';
|
||||
|
||||
class ApiListSubscriberAction extends ApiBareAuthAction
|
||||
{
|
||||
var $list = null;
|
||||
|
||||
function prepare($args)
|
||||
{
|
||||
parent::prepare($args);
|
||||
|
||||
$this->user = $this->getTargetUser($this->arg('id'));
|
||||
$this->list = $this->getTargetList($this->arg('user'), $this->arg('list_id'));
|
||||
|
||||
if (empty($this->list)) {
|
||||
// TRANS: Client error displayed trying to perform an action related to a non-existing list.
|
||||
$this->clientError(_('List not found.'), 404, $this->format);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (empty($this->user)) {
|
||||
// TRANS: Client error displayed trying to perform an action related to a non-existing user.
|
||||
$this->clientError(_('No such user.'), 404, $this->format);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
function handle($args)
|
||||
{
|
||||
parent::handle($args);
|
||||
|
||||
$arr = array('profile_tag_id' => $this->list->id,
|
||||
'profile_id' => $this->user->id);
|
||||
$sub = Profile_tag_subscription::pkeyGet($arr);
|
||||
|
||||
if(empty($sub)) {
|
||||
$this->clientError(
|
||||
// TRANS: Client error displayed when a membership check for a user is nagative.
|
||||
_('The specified user is not a subscriber of this list.'),
|
||||
400,
|
||||
$this->format
|
||||
);
|
||||
}
|
||||
|
||||
$user = $this->twitterUserArray($this->user->getProfile(), true);
|
||||
|
||||
switch($this->format) {
|
||||
case 'xml':
|
||||
$this->showTwitterXmlUser($user, 'user', true);
|
||||
break;
|
||||
case 'json':
|
||||
$this->showSingleJsonUser($user);
|
||||
break;
|
||||
default:
|
||||
$this->clientError(
|
||||
// TRANS: Client error displayed when coming across a non-supported API method.
|
||||
_('API method not found.'),
|
||||
404,
|
||||
$this->format
|
||||
);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
129
actions/apilistsubscribers.php
Normal file
129
actions/apilistsubscribers.php
Normal file
@ -0,0 +1,129 @@
|
||||
<?php
|
||||
/**
|
||||
* StatusNet, the distributed open-source microblogging tool
|
||||
*
|
||||
* Show/add/remove list 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
|
||||
* @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/apilistusers.php';
|
||||
|
||||
class ApiListSubscribersAction extends ApiListUsersAction
|
||||
{
|
||||
/**
|
||||
* Subscribe to list
|
||||
*
|
||||
* @return boolean success
|
||||
*/
|
||||
function handlePost()
|
||||
{
|
||||
$result = Profile_tag_subscription::add($this->list,
|
||||
$this->auth_user);
|
||||
|
||||
if(empty($result)) {
|
||||
$this->clientError(
|
||||
// TRANS: Client error displayed when an unknown error occurs in the list subscribers action.
|
||||
_('An error occured.'),
|
||||
500,
|
||||
$this->format
|
||||
);
|
||||
return false;
|
||||
}
|
||||
|
||||
switch($this->format) {
|
||||
case 'xml':
|
||||
$this->showSingleXmlList($this->list);
|
||||
break;
|
||||
case 'json':
|
||||
$this->showSingleJsonList($this->list);
|
||||
break;
|
||||
default:
|
||||
$this->clientError(
|
||||
// TRANS: Client error displayed when coming across a non-supported API method.
|
||||
_('API method not found.'),
|
||||
404,
|
||||
$this->format
|
||||
);
|
||||
return false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
function handleDelete()
|
||||
{
|
||||
$args = array('profile_tag_id' => $this->list->id,
|
||||
'profile_id' => $this->auth_user->id);
|
||||
$ptag = Profile_tag_subscription::pkeyGet($args);
|
||||
|
||||
if(empty($ptag)) {
|
||||
$this->clientError(
|
||||
// TRANS: Client error displayed when trying to unsubscribe from a non-subscribed list.
|
||||
_('You are not subscribed to this list.'),
|
||||
400,
|
||||
$this->format
|
||||
);
|
||||
return false;
|
||||
}
|
||||
|
||||
Profile_tag_subscription::remove($this->list, $this->auth_user);
|
||||
|
||||
if(empty($result)) {
|
||||
$this->clientError(
|
||||
// TRANS: Client error displayed when an unknown error occurs unsubscribing from a list.
|
||||
_('An error occured.'),
|
||||
500,
|
||||
$this->format
|
||||
);
|
||||
return false;
|
||||
}
|
||||
|
||||
switch($this->format) {
|
||||
case 'xml':
|
||||
$this->showSingleXmlList($this->list);
|
||||
break;
|
||||
case 'json':
|
||||
$this->showSingleJsonList($this->list);
|
||||
break;
|
||||
default:
|
||||
$this->clientError(
|
||||
// TRANS: Client error displayed when coming across a non-supported API method.
|
||||
_('API method not found.'),
|
||||
404,
|
||||
$this->format
|
||||
);
|
||||
return false;
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
function getUsers()
|
||||
{
|
||||
$fn = array($this->list, 'getSubscribers');
|
||||
list($this->users, $this->next_cursor, $this->prev_cursor) =
|
||||
Profile_list::getAtCursor($fn, array(), $this->cursor, 20);
|
||||
}
|
||||
}
|
125
actions/apilistsubscriptions.php
Normal file
125
actions/apilistsubscriptions.php
Normal file
@ -0,0 +1,125 @@
|
||||
<?php
|
||||
/**
|
||||
* StatusNet, the distributed open-source microblogging tool
|
||||
*
|
||||
* Get a list of lists a user is subscribed to.
|
||||
*
|
||||
* 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
|
||||
* @copyright 2009 StatusNet, Inc.
|
||||
* @copyright 2009 Free Software Foundation, Inc http://www.fsf.org
|
||||
* @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';
|
||||
|
||||
class ApiListSubscriptionsAction extends ApiBareAuthAction
|
||||
{
|
||||
var $lists = array();
|
||||
var $cursor = -1;
|
||||
var $next_cursor = 0;
|
||||
var $prev_cursor = 0;
|
||||
|
||||
/**
|
||||
* Take arguments for running
|
||||
*
|
||||
* @param array $args $_REQUEST args
|
||||
*
|
||||
* @return boolean success flag
|
||||
*
|
||||
*/
|
||||
function prepare($args)
|
||||
{
|
||||
parent::prepare($args);
|
||||
|
||||
$this->cursor = (int) $this->arg('cursor', -1);
|
||||
$this->user = $this->getTargetUser($this->arg('user'));
|
||||
$this->getLists();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle the request
|
||||
*
|
||||
* Show the lists
|
||||
*
|
||||
* @param array $args $_REQUEST data (unused)
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
function handle($args)
|
||||
{
|
||||
parent::handle($args);
|
||||
|
||||
if (empty($this->user)) {
|
||||
// TRANS: Client error displayed trying to perform an action related to a non-existing user.
|
||||
$this->clientError(_('No such user.'), 404, $this->format);
|
||||
return;
|
||||
}
|
||||
|
||||
switch($this->format) {
|
||||
case 'xml':
|
||||
$this->showXmlLists($this->lists, $this->next_cursor, $this->prev_cursor);
|
||||
break;
|
||||
case 'json':
|
||||
$this->showJsonLists($this->lists, $this->next_cursor, $this->prev_cursor);
|
||||
break;
|
||||
default:
|
||||
$this->clientError(
|
||||
// TRANS: Client error displayed when coming across a non-supported API method.
|
||||
_('API method not found.'),
|
||||
400,
|
||||
$this->format
|
||||
);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if read only.
|
||||
*
|
||||
* MAY override
|
||||
*
|
||||
* @param array $args other arguments
|
||||
*
|
||||
* @return boolean is read only action?
|
||||
*/
|
||||
function isReadOnly($args)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
function getLists()
|
||||
{
|
||||
if(empty($this->user)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$profile = $this->user->getProfile();
|
||||
$fn = array($profile, 'getTagSubscriptions');
|
||||
# 20 lists
|
||||
list($this->lists, $this->next_cursor, $this->prev_cursor) =
|
||||
Profile_list::getAtCursor($fn, array(), $this->cursor, 20);
|
||||
}
|
||||
}
|
@ -97,7 +97,7 @@ class ApiStatusesDestroyAction extends ApiAuthAction
|
||||
|
||||
if (!in_array($this->format, array('xml', 'json'))) {
|
||||
$this->clientError(
|
||||
// TRANS: Client error displayed trying to execute an unknown API method deleting a status.
|
||||
// TRANS: Client error displayed when coming across a non-supported API method.
|
||||
_('API method not found.'),
|
||||
404
|
||||
);
|
||||
|
@ -78,22 +78,6 @@ class ApiStatusesRetweetAction extends ApiAuthAction
|
||||
|
||||
$this->user = $this->auth_user;
|
||||
|
||||
if ($this->user->id == $this->original->profile_id) {
|
||||
// TRANS: Client error displayed trying to repeat an own notice through the API.
|
||||
$this->clientError(_('Cannot repeat your own notice.'),
|
||||
400, $this->format);
|
||||
return false;
|
||||
}
|
||||
|
||||
$profile = $this->user->getProfile();
|
||||
|
||||
if ($profile->hasRepeated($id)) {
|
||||
// TRANS: Client error displayed trying to re-repeat a notice through the API.
|
||||
$this->clientError(_('Already repeated that notice.'),
|
||||
400, $this->format);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -106,7 +106,7 @@ class ApiStatusesRetweetsAction extends ApiAuthAction
|
||||
$this->showJsonTimeline($strm);
|
||||
break;
|
||||
default:
|
||||
// TRANS: Client error displayed when trying to handle an unknown API method.
|
||||
// TRANS: Client error displayed when coming across a non-supported API method.
|
||||
$this->clientError(_('API method not found.'), $code = 404);
|
||||
break;
|
||||
}
|
||||
|
@ -101,7 +101,7 @@ class ApiStatusesShowAction extends ApiPrivateAuthAction
|
||||
parent::handle($args);
|
||||
|
||||
if (!in_array($this->format, array('xml', 'json', 'atom'))) {
|
||||
// TRANS: Client error displayed when trying to handle an unknown API method.
|
||||
// TRANS: Client error displayed when coming across a non-supported API method.
|
||||
$this->clientError(_('API method not found.'), 404);
|
||||
return;
|
||||
}
|
||||
|
@ -239,8 +239,8 @@ class ApiStatusesUpdateAction extends ApiAuthAction
|
||||
|
||||
$this->clientError(
|
||||
sprintf(
|
||||
// TRANS: Client error displayed when the parameter "status" is missing.
|
||||
// TRANS: %d is the maximum number of character for a notice.
|
||||
// TRANS: Client error displayed exceeding the maximum notice length.
|
||||
// TRANS: %d is the maximum length for a notice.
|
||||
_m('That\'s too long. Maximum notice size is %d character.',
|
||||
'That\'s too long. Maximum notice size is %d characters.',
|
||||
Notice::maxContent()),
|
||||
|
@ -135,7 +135,7 @@ class ApiStatusnetConfigAction extends ApiAction
|
||||
break;
|
||||
default:
|
||||
$this->clientError(
|
||||
// TRANS: Client error displayed when trying to handle an unknown API method.
|
||||
// TRANS: Client error displayed when coming across a non-supported API method.
|
||||
_('API method not found.'),
|
||||
404,
|
||||
$this->format
|
||||
|
@ -87,7 +87,7 @@ class ApiStatusnetVersionAction extends ApiPrivateAuthAction
|
||||
break;
|
||||
default:
|
||||
$this->clientError(
|
||||
// TRANS: Client error displayed when trying to handle an unknown API method.
|
||||
// TRANS: Client error displayed when coming across a non-supported API method.
|
||||
_('API method not found.'),
|
||||
404,
|
||||
$this->format
|
||||
|
@ -105,7 +105,7 @@ class ApiSubscriptionsAction extends ApiBareAuthAction
|
||||
parent::handle($args);
|
||||
|
||||
if (!in_array($this->format, array('xml', 'json'))) {
|
||||
// TRANS: Client error displayed when trying to handle an unknown API method.
|
||||
// TRANS: Client error displayed when coming across a non-supported API method.
|
||||
$this->clientError(_('API method not found.'), $code = 404);
|
||||
return;
|
||||
}
|
||||
|
@ -178,7 +178,7 @@ class ApiTimelineFavoritesAction extends ApiBareAuthAction
|
||||
$this->raw($doc->asString());
|
||||
break;
|
||||
default:
|
||||
// TRANS: Client error displayed when trying to handle an unknown API method.
|
||||
// TRANS: Client error displayed when coming across a non-supported API method.
|
||||
$this->clientError(_('API method not found.'), $code = 404);
|
||||
break;
|
||||
}
|
||||
|
@ -204,6 +204,8 @@ class ApiTimelineFriendsAction extends ApiBareAuthAction
|
||||
$profile = $this->user->getProfile();
|
||||
$avatar = $profile->getAvatar(AVATAR_PROFILE_SIZE);
|
||||
$sitename = common_config('site', 'name');
|
||||
// TRANS: Title of API timeline for a user and friends.
|
||||
// TRANS: %s is a username.
|
||||
$title = sprintf(_("%s and friends"), $this->user->nickname);
|
||||
$taguribase = TagURI::base();
|
||||
$id = "tag:$taguribase:FriendsTimeline:" . $this->user->id;
|
||||
@ -272,7 +274,7 @@ class ApiTimelineFriendsAction extends ApiBareAuthAction
|
||||
$this->raw($doc->asString());
|
||||
break;
|
||||
default:
|
||||
// TRANS: Client error displayed when trying to handle an unknown API method.
|
||||
// TRANS: Client error displayed when coming across a non-supported API method.
|
||||
$this->clientError(_('API method not found.'), $code = 404);
|
||||
break;
|
||||
}
|
||||
@ -287,15 +289,12 @@ class ApiTimelineFriendsAction extends ApiBareAuthAction
|
||||
{
|
||||
$notices = array();
|
||||
|
||||
if (!empty($this->auth_user) && $this->auth_user->id == $this->user->id) {
|
||||
$notice = $this->user->ownFriendsTimeline(($this->page-1) * $this->count,
|
||||
$this->count, $this->since_id,
|
||||
$stream = new InboxNoticeStream($this->user);
|
||||
|
||||
$notice = $stream->getNotices(($this->page-1) * $this->count,
|
||||
$this->count,
|
||||
$this->since_id,
|
||||
$this->max_id);
|
||||
} else {
|
||||
$notice = $this->user->friendsTimeline(($this->page-1) * $this->count,
|
||||
$this->count, $this->since_id,
|
||||
$this->max_id);
|
||||
}
|
||||
|
||||
while ($notice->fetch()) {
|
||||
$notices[] = clone($notice);
|
||||
|
@ -177,7 +177,7 @@ class ApiTimelineHomeAction extends ApiBareAuthAction
|
||||
$this->raw($doc->asString());
|
||||
break;
|
||||
default:
|
||||
// TRANS: Client error displayed when trying to handle an unknown API method.
|
||||
// TRANS: Client error displayed when coming across a non-supported API method.
|
||||
$this->clientError(_('API method not found.'), $code = 404);
|
||||
break;
|
||||
}
|
||||
@ -192,19 +192,12 @@ class ApiTimelineHomeAction extends ApiBareAuthAction
|
||||
{
|
||||
$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
|
||||
);
|
||||
} else {
|
||||
$notice = $this->user->noticesWithFriends(
|
||||
($this->page-1) * $this->count,
|
||||
$this->count, $this->since_id,
|
||||
$this->max_id
|
||||
);
|
||||
}
|
||||
$stream = new InboxNoticeStream($this->user);
|
||||
|
||||
$notice = $stream->getNotices(($this->page-1) * $this->count,
|
||||
$this->count,
|
||||
$this->since_id,
|
||||
$this->max_id);
|
||||
|
||||
while ($notice->fetch()) {
|
||||
$notices[] = clone($notice);
|
||||
|
258
actions/apitimelinelist.php
Normal file
258
actions/apitimelinelist.php
Normal file
@ -0,0 +1,258 @@
|
||||
<?php
|
||||
/**
|
||||
* StatusNet, the distributed open-source microblogging tool
|
||||
*
|
||||
* Show a list'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.
|
||||
* @copyright 2009 Free Software Foundation, Inc http://www.fsf.org
|
||||
* @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';
|
||||
require_once INSTALLDIR . '/lib/atomlistnoticefeed.php';
|
||||
|
||||
/**
|
||||
* Returns the most recent notices (default 20) posted to the list 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 ApiTimelineListAction extends ApiPrivateAuthAction
|
||||
{
|
||||
|
||||
var $list = null;
|
||||
var $notices = array();
|
||||
var $next_cursor = 0;
|
||||
var $prev_cursor = 0;
|
||||
var $cursor = -1;
|
||||
|
||||
/**
|
||||
* Take arguments for running
|
||||
*
|
||||
* @param array $args $_REQUEST args
|
||||
*
|
||||
* @return boolean success flag
|
||||
*
|
||||
*/
|
||||
function prepare($args)
|
||||
{
|
||||
parent::prepare($args);
|
||||
|
||||
$this->cursor = (int) $this->arg('cursor', -1);
|
||||
$this->list = $this->getTargetList($this->arg('user'), $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->list)) {
|
||||
// TRANS: Client error displayed trying to perform an action related to a non-existing list.
|
||||
$this->clientError(_('List not found.'), 404, $this->format);
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->getNotices();
|
||||
$this->showTimeline();
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the timeline of notices
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
function showTimeline()
|
||||
{
|
||||
// We'll pull common formatting out of this for other formats
|
||||
$atom = new AtomListNoticeFeed($this->list, $this->auth_user);
|
||||
|
||||
$self = $this->getSelfUri();
|
||||
|
||||
switch($this->format) {
|
||||
case 'xml':
|
||||
$this->initDocument('xml');
|
||||
$this->elementStart('statuses_list',
|
||||
array('xmlns:statusnet' => 'http://status.net/schema/api/1/'));
|
||||
$this->elementStart('statuses', array('type' => 'array'));
|
||||
|
||||
foreach ($this->notices as $n) {
|
||||
$twitter_status = $this->twitterStatusArray($n);
|
||||
$this->showTwitterXmlStatus($twitter_status);
|
||||
}
|
||||
|
||||
$this->elementEnd('statuses');
|
||||
$this->element('next_cursor', null, $this->next_cursor);
|
||||
$this->element('previous_cursor', null, $this->prev_cursor);
|
||||
$this->elementEnd('statuses_list');
|
||||
$this->endDocument('xml');
|
||||
break;
|
||||
case 'rss':
|
||||
$this->showRssTimeline(
|
||||
$this->notices,
|
||||
$atom->title,
|
||||
$this->list->getUri(),
|
||||
$atom->subtitle,
|
||||
null,
|
||||
$atom->logo,
|
||||
$self
|
||||
);
|
||||
break;
|
||||
case 'atom':
|
||||
header('Content-Type: application/atom+xml; charset=utf-8');
|
||||
|
||||
try {
|
||||
$atom->setId($self);
|
||||
$atom->setSelfLink($self);
|
||||
$atom->addEntryFromNotices($this->notices);
|
||||
$this->raw($atom->getString());
|
||||
} catch (Atom10FeedException $e) {
|
||||
// TRANS: Server error displayed whe trying to get a timeline fails.
|
||||
// TRANS: %s is the error message.
|
||||
$this->serverError( sprintf(_('Could not generate feed for list - %s'),$e->getMessage()));
|
||||
return;
|
||||
}
|
||||
|
||||
break;
|
||||
case 'json':
|
||||
$this->initDocument('json');
|
||||
|
||||
$statuses = array();
|
||||
foreach ($this->notices as $n) {
|
||||
$twitter_status = $this->twitterStatusArray($n);
|
||||
array_push($statuses, $twitter_status);
|
||||
}
|
||||
|
||||
$statuses_list = array('statuses' => $statuses,
|
||||
'next_cursor' => $this->next_cusror,
|
||||
'next_cursor_str' => strval($this->next_cusror),
|
||||
'previous_cursor' => $this->prev_cusror,
|
||||
'previous_cursor_str' => strval($this->prev_cusror)
|
||||
);
|
||||
$this->showJsonObjects($statuses_list);
|
||||
|
||||
$this->initDocument('json');
|
||||
break;
|
||||
default:
|
||||
$this->clientError(
|
||||
// TRANS: Client error displayed when coming across a non-supported API method.
|
||||
_('API method not found.'),
|
||||
404,
|
||||
$this->format
|
||||
);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get notices
|
||||
*
|
||||
* @return array notices
|
||||
*/
|
||||
function getNotices()
|
||||
{
|
||||
$fn = array($this->list, 'getNotices');
|
||||
list($this->notices, $this->next_cursor, $this->prev_cursor) =
|
||||
Profile_list::getAtCursor($fn, array(), $this->cursor, 20);
|
||||
if (!$this->notices) {
|
||||
$this->notices = array();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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, list 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->list->id,
|
||||
strtotime($this->notices[0]->created),
|
||||
strtotime($this->notices[$last]->created))
|
||||
)
|
||||
. '"';
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
@ -178,7 +178,7 @@ class ApiTimelineMentionsAction extends ApiBareAuthAction
|
||||
$this->raw($doc->asString());
|
||||
break;
|
||||
default:
|
||||
// TRANS: Client error displayed when trying to handle an unknown API method.
|
||||
// TRANS: Client error displayed when coming across a non-supported API method.
|
||||
$this->clientError(_('API method not found.'), $code = 404);
|
||||
break;
|
||||
}
|
||||
|
@ -243,7 +243,7 @@ class ApiTimelinePublicAction extends ApiPrivateAuthAction
|
||||
$this->raw($doc->asString());
|
||||
break;
|
||||
default:
|
||||
// TRANS: Client error displayed when trying to handle an unknown API method.
|
||||
// TRANS: Client error displayed when coming across a non-supported API method.
|
||||
$this->clientError(_('API method not found.'), $code = 404);
|
||||
break;
|
||||
}
|
||||
|
@ -146,7 +146,7 @@ class ApiTimelineRetweetedToMeAction extends ApiAuthAction
|
||||
$this->raw($doc->asString());
|
||||
break;
|
||||
default:
|
||||
// TRANS: Client error displayed when trying to handle an unknown API method.
|
||||
// TRANS: Client error displayed when coming across a non-supported API method.
|
||||
$this->clientError(_('API method not found.'), $code = 404);
|
||||
break;
|
||||
}
|
||||
|
@ -101,6 +101,8 @@ class ApiTimelineRetweetsOfMeAction extends ApiAuthAction
|
||||
$profile = $this->auth_user->getProfile();
|
||||
|
||||
$subtitle = sprintf(
|
||||
// TRANS: Subtitle of API time with retweets of me.
|
||||
// TRANS: %1$s is the StatusNet sitename, %2$s is the user nickname, %3$s is the user profile name.
|
||||
_('%1$s notices that %2$s / %3$s has repeated.'),
|
||||
$sitename, $this->auth_user->nickname, $profile->getBestName()
|
||||
);
|
||||
@ -143,7 +145,7 @@ class ApiTimelineRetweetsOfMeAction extends ApiAuthAction
|
||||
$this->raw($doc->asString());
|
||||
break;
|
||||
default:
|
||||
// TRANS: Client error displayed when trying to handle an unknown API method.
|
||||
// TRANS: Client error displayed when coming across a non-supported API method.
|
||||
$this->clientError(_('API method not found.'), 404);
|
||||
break;
|
||||
}
|
||||
|
@ -161,7 +161,7 @@ class ApiTimelineTagAction extends ApiPrivateAuthAction
|
||||
$this->raw($doc->asString());
|
||||
break;
|
||||
default:
|
||||
// TRANS: Client error displayed when trying to handle an unknown API method.
|
||||
// TRANS: Client error displayed when coming across a non-supported API method.
|
||||
$this->clientError(_('API method not found.'), $code = 404);
|
||||
break;
|
||||
}
|
||||
|
@ -213,7 +213,7 @@ class ApiTimelineUserAction extends ApiBareAuthAction
|
||||
$this->raw($doc->asString());
|
||||
break;
|
||||
default:
|
||||
// TRANS: Client error displayed when trying to handle an unknown API method.
|
||||
// TRANS: Client error displayed when coming across a non-supported API method.
|
||||
$this->clientError(_('API method not found.'), $code = 404);
|
||||
break;
|
||||
}
|
||||
|
@ -84,7 +84,7 @@ class ApiUserProfileImageAction extends ApiPrivateAuthAction
|
||||
$profile = $this->user->getProfile();
|
||||
|
||||
if (empty($profile)) {
|
||||
// TRANS: Client error displayed when requesting user information for a user without a profile.
|
||||
// TRANS: Error message displayed when referring to a user without a profile.
|
||||
$this->clientError(_('User has no profile.'));
|
||||
return;
|
||||
}
|
||||
|
@ -96,7 +96,7 @@ class ApiUserShowAction extends ApiPrivateAuthAction
|
||||
}
|
||||
|
||||
if (!in_array($this->format, array('xml', 'json'))) {
|
||||
// TRANS: Client error displayed when trying to handle an unknown API method.
|
||||
// TRANS: Client error displayed when coming across a non-supported API method.
|
||||
$this->clientError(_('API method not found.'), $code = 404);
|
||||
return;
|
||||
}
|
||||
@ -104,7 +104,7 @@ class ApiUserShowAction extends ApiPrivateAuthAction
|
||||
$profile = $this->user->getProfile();
|
||||
|
||||
if (empty($profile)) {
|
||||
// TRANS: Client error displayed when requesting user information for a user without a profile.
|
||||
// TRANS: Error message displayed when referring to a user without a profile.
|
||||
$this->clientError(_('User has no profile.'));
|
||||
return;
|
||||
}
|
||||
|
@ -121,6 +121,7 @@ class ApprovegroupAction extends Action
|
||||
|
||||
if (empty($this->request)) {
|
||||
// TRANS: Client error displayed trying to approve group membership for a non-existing request.
|
||||
// TRANS: %s is a nickname.
|
||||
$this->clientError(sprintf(_('%s is not in the moderation queue for this group.'), $this->profile->nickname), 403);
|
||||
}
|
||||
|
||||
@ -152,12 +153,12 @@ class ApprovegroupAction extends Action
|
||||
|
||||
try {
|
||||
if ($this->approve) {
|
||||
$this->profile->completeJoinGroup($this->group);
|
||||
$this->request->complete();
|
||||
} elseif ($this->cancel) {
|
||||
$this->profile->cancelJoinGroup($this->group);
|
||||
$this->request->abort();
|
||||
}
|
||||
} catch (Exception $e) {
|
||||
common_log(LOG_ERROR, "Exception canceling group sub: " . $e->getMessage());
|
||||
common_log(LOG_ERR, "Exception canceling group sub: " . $e->getMessage());
|
||||
// TRANS: Server error displayed when cancelling a queued group join request fails.
|
||||
// TRANS: %1$s is the leaving user's nickname, $2$s is the group nickname for which the leave failed.
|
||||
$this->serverError(sprintf(_('Could not cancel request for user %1$s to join group %2$s.'),
|
||||
|
145
actions/approvesub.php
Normal file
145
actions/approvesub.php
Normal file
@ -0,0 +1,145 @@
|
||||
<?php
|
||||
/**
|
||||
* StatusNet, the distributed open-source microblogging tool
|
||||
*
|
||||
* Approve group subscription request
|
||||
*
|
||||
* PHP version 5
|
||||
*
|
||||
* LICENCE: This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* @category Group
|
||||
* @package StatusNet
|
||||
* @author Evan Prodromou <evan@status.net>
|
||||
* @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);
|
||||
}
|
||||
|
||||
/**
|
||||
* Leave a group
|
||||
*
|
||||
* This is the action for leaving a group. It works more or less like the subscribe action
|
||||
* for users.
|
||||
*
|
||||
* @category Group
|
||||
* @package StatusNet
|
||||
* @author Evan Prodromou <evan@status.net>
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||
* @link http://status.net/
|
||||
*/
|
||||
class ApprovesubAction extends Action
|
||||
{
|
||||
var $profile = null;
|
||||
|
||||
/**
|
||||
* Prepare to run
|
||||
*/
|
||||
function prepare($args)
|
||||
{
|
||||
parent::prepare($args);
|
||||
|
||||
$cur = common_current_user();
|
||||
if (empty($cur)) {
|
||||
// TRANS: Client error displayed trying to approve group membership while not logged in.
|
||||
$this->clientError(_('Must be logged in.'), 403);
|
||||
return false;
|
||||
}
|
||||
if ($this->arg('profile_id')) {
|
||||
$this->profile = Profile::staticGet('id', $this->arg('profile_id'));
|
||||
} else {
|
||||
// TRANS: Client error displayed trying to approve subscriptionswithout specifying a profile to approve.
|
||||
$this->clientError(_('Must specify a profile.'));
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->request = Subscription_queue::pkeyGet(array('subscriber' => $this->profile->id,
|
||||
'subscribed' => $cur->id));
|
||||
|
||||
if (empty($this->request)) {
|
||||
// TRANS: Client error displayed trying to approve subscription for a non-existing request.
|
||||
$this->clientError(sprintf(_('%s is not in the moderation queue for your subscriptions.'), $this->profile->nickname), 403);
|
||||
}
|
||||
|
||||
$this->approve = (bool)$this->arg('approve');
|
||||
$this->cancel = (bool)$this->arg('cancel');
|
||||
if (!$this->approve && !$this->cancel) {
|
||||
// TRANS: Client error displayed trying to approve/deny subscription.
|
||||
$this->clientError(_('Internal error: received neither cancel nor abort.'));
|
||||
}
|
||||
if ($this->approve && $this->cancel) {
|
||||
// TRANS: Client error displayed trying to approve/deny subscription
|
||||
$this->clientError(_('Internal error: received both cancel and abort.'));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle the request
|
||||
*
|
||||
* On POST, add the current user to the group
|
||||
*
|
||||
* @param array $args unused
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
function handle($args)
|
||||
{
|
||||
parent::handle($args);
|
||||
$cur = common_current_user();
|
||||
|
||||
try {
|
||||
if ($this->approve) {
|
||||
$this->request->complete();
|
||||
} elseif ($this->cancel) {
|
||||
$this->request->abort();
|
||||
}
|
||||
} catch (Exception $e) {
|
||||
common_log(LOG_ERR, "Exception canceling sub: " . $e->getMessage());
|
||||
// TRANS: Server error displayed when cancelling a queued subscription request fails.
|
||||
// TRANS: %1$s is the leaving user's nickname, $2$s is the nickname for which the leave failed.
|
||||
$this->serverError(sprintf(_('Could not cancel or approve request for user %1$s to join group %2$s.'),
|
||||
$this->profile->nickname, $cur->nickname));
|
||||
return;
|
||||
}
|
||||
|
||||
if ($this->boolean('ajax')) {
|
||||
$this->startHTML('text/xml;charset=utf-8');
|
||||
$this->elementStart('head');
|
||||
// TRANS: Title for subscription approval ajax return
|
||||
// TRANS: %1$s is the approved user's nickname
|
||||
$this->element('title', null, sprintf(_m('TITLE','%1$s\'s request'),
|
||||
$this->profile->nickname));
|
||||
$this->elementEnd('head');
|
||||
$this->elementStart('body');
|
||||
if ($this->approve) {
|
||||
// TRANS: Message on page for user after approving a subscription request.
|
||||
$this->element('p', 'success', _('Subscription approved.'));
|
||||
} elseif ($this->cancel) {
|
||||
// TRANS: Message on page for user after rejecting a subscription request.
|
||||
$this->element('p', 'success', _('Subscription canceled.'));
|
||||
}
|
||||
$this->elementEnd('body');
|
||||
$this->elementEnd('html');
|
||||
} else {
|
||||
common_redirect(common_local_url('subqueue', array('nickname' =>
|
||||
$cur->nickname)),
|
||||
303);
|
||||
}
|
||||
}
|
||||
}
|
@ -143,15 +143,6 @@ class AttachmentAction extends Action
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Don't show local navigation
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
function showLocalNavBlock()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Fill the content area of the page
|
||||
*
|
||||
|
@ -81,7 +81,7 @@ class AvatarbynicknameAction extends Action
|
||||
}
|
||||
$profile = $user->getProfile();
|
||||
if (!$profile) {
|
||||
// TRANS: Client error displayed trying to get an avatar for a user without a profile.
|
||||
// TRANS: Error message displayed when referring to a user without a profile.
|
||||
$this->clientError(_('User has no profile.'));
|
||||
return;
|
||||
}
|
||||
|
@ -104,8 +104,8 @@ class AvatarsettingsAction extends SettingsAction
|
||||
|
||||
if (!$profile) {
|
||||
common_log_db_error($user, 'SELECT', __FILE__);
|
||||
// TRANS: Server error displayed in avatar upload page when no matching profile can be found for a user.
|
||||
$this->serverError(_('User without matching profile.'));
|
||||
// TRANS: Error message displayed when referring to a user without a profile.
|
||||
$this->serverError(_('User has no profile.'));
|
||||
return;
|
||||
}
|
||||
|
||||
@ -146,13 +146,15 @@ class AvatarsettingsAction extends SettingsAction
|
||||
// TRANS: Header on avatar upload page for thumbnail of to be used rendition of uploaded avatar (h2).
|
||||
$this->element('h2', null, _("Preview"));
|
||||
$this->elementStart('div', array('id'=>'avatar_preview_view'));
|
||||
$this->element('img', array('src' => $original->url,
|
||||
$this->element('img', array('src' => $avatar->url,
|
||||
'width' => AVATAR_PROFILE_SIZE,
|
||||
'height' => AVATAR_PROFILE_SIZE,
|
||||
'alt' => $user->nickname));
|
||||
$this->elementEnd('div');
|
||||
if (!empty($avatar->filename)) {
|
||||
// TRANS: Button on avatar upload page to delete current avatar.
|
||||
$this->submit('delete', _m('BUTTON','Delete'));
|
||||
}
|
||||
$this->elementEnd('li');
|
||||
}
|
||||
|
||||
@ -188,8 +190,8 @@ class AvatarsettingsAction extends SettingsAction
|
||||
|
||||
if (!$profile) {
|
||||
common_log_db_error($user, 'SELECT', __FILE__);
|
||||
// TRANS: Server error displayed in avatar upload page when no matching profile can be found for a user.
|
||||
$this->serverError(_('User without matching profile.'));
|
||||
// TRANS: Error message displayed when referring to a user without a profile.
|
||||
$this->serverError(_('User has no profile.'));
|
||||
return;
|
||||
}
|
||||
|
||||
@ -277,6 +279,7 @@ class AvatarsettingsAction extends SettingsAction
|
||||
|
||||
$token = $this->trimmed('token');
|
||||
if (!$token || $token != common_session_token()) {
|
||||
// TRANS: Client error displayed when the session token does not match or is not given.
|
||||
$this->showForm(_('There was a problem with your session token. '.
|
||||
'Try again, please.'));
|
||||
return;
|
||||
|
@ -139,9 +139,9 @@ class CancelgroupAction extends Action
|
||||
parent::handle($args);
|
||||
|
||||
try {
|
||||
$this->profile->cancelJoinGroup($this->group);
|
||||
$this->request->abort();
|
||||
} catch (Exception $e) {
|
||||
common_log(LOG_ERROR, "Exception canceling group sub: " . $e->getMessage());
|
||||
common_log(LOG_ERR, "Exception canceling group sub: " . $e->getMessage());
|
||||
// TRANS: Server error displayed when cancelling a queued group join request fails.
|
||||
// TRANS: %1$s is the leaving user's nickname, $2$s is the group nickname for which the leave failed.
|
||||
$this->serverError(sprintf(_('Could not cancel request for user %1$s to join group %2$s.'),
|
||||
|
124
actions/cancelsubscription.php
Normal file
124
actions/cancelsubscription.php
Normal file
@ -0,0 +1,124 @@
|
||||
<?php
|
||||
/**
|
||||
* StatusNet, the distributed open-source microblogging tool
|
||||
*
|
||||
* Leave a group
|
||||
*
|
||||
* PHP version 5
|
||||
*
|
||||
* LICENCE: This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* @category Group
|
||||
* @package StatusNet
|
||||
* @author Evan Prodromou <evan@status.net>
|
||||
* @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);
|
||||
}
|
||||
|
||||
/**
|
||||
* Leave a group
|
||||
*
|
||||
* This is the action for leaving a group. It works more or less like the subscribe action
|
||||
* for users.
|
||||
*
|
||||
* @category Group
|
||||
* @package StatusNet
|
||||
* @author Evan Prodromou <evan@status.net>
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||
* @link http://status.net/
|
||||
*/
|
||||
class CancelsubscriptionAction extends Action
|
||||
{
|
||||
|
||||
function handle($args)
|
||||
{
|
||||
parent::handle($args);
|
||||
if ($this->boolean('ajax')) {
|
||||
StatusNet::setApi(true);
|
||||
}
|
||||
if (!common_logged_in()) {
|
||||
// TRANS: Error message displayed when trying to perform an action that requires a logged in user.
|
||||
$this->clientError(_('Not logged in.'));
|
||||
return;
|
||||
}
|
||||
|
||||
$user = common_current_user();
|
||||
|
||||
if ($_SERVER['REQUEST_METHOD'] != 'POST') {
|
||||
common_redirect(common_local_url('subscriptions',
|
||||
array('nickname' => $user->nickname)));
|
||||
return;
|
||||
}
|
||||
|
||||
/* Use a session token for CSRF protection. */
|
||||
|
||||
$token = $this->trimmed('token');
|
||||
|
||||
if (!$token || $token != common_session_token()) {
|
||||
// TRANS: Client error displayed when the session token does not match or is not given.
|
||||
$this->clientError(_('There was a problem with your session token. ' .
|
||||
'Try again, please.'));
|
||||
return;
|
||||
}
|
||||
|
||||
$other_id = $this->arg('unsubscribeto');
|
||||
|
||||
if (!$other_id) {
|
||||
// TRANS: Client error displayed when trying to leave a group without specifying an ID.
|
||||
$this->clientError(_('No profile ID in request.'));
|
||||
return;
|
||||
}
|
||||
|
||||
$other = Profile::staticGet('id', $other_id);
|
||||
|
||||
if (!$other) {
|
||||
// TRANS: Client error displayed when trying to leave a non-existing group.
|
||||
$this->clientError(_('No profile with that ID.'));
|
||||
return;
|
||||
}
|
||||
|
||||
$this->request = Subscription_queue::pkeyGet(array('subscriber' => $user->id,
|
||||
'subscribed' => $other->id));
|
||||
|
||||
if (empty($this->request)) {
|
||||
// TRANS: Client error displayed when trying to approve a non-existing group join request.
|
||||
// TRANS: %s is a user nickname.
|
||||
$this->clientError(sprintf(_('%s is not in the moderation queue for this group.'), $this->profile->nickname), 403);
|
||||
}
|
||||
|
||||
$this->request->abort();
|
||||
|
||||
if ($this->boolean('ajax')) {
|
||||
$this->startHTML('text/xml;charset=utf-8');
|
||||
$this->elementStart('head');
|
||||
// TRANS: Title after unsubscribing from a group.
|
||||
$this->element('title', null, _m('TITLE','Unsubscribed'));
|
||||
$this->elementEnd('head');
|
||||
$this->elementStart('body');
|
||||
$subscribe = new SubscribeForm($this, $other);
|
||||
$subscribe->show();
|
||||
$this->elementEnd('body');
|
||||
$this->elementEnd('html');
|
||||
} else {
|
||||
common_redirect(common_local_url('subscriptions',
|
||||
array('nickname' => $user->nickname)),
|
||||
303);
|
||||
}
|
||||
}
|
||||
}
|
@ -49,6 +49,10 @@ class ConversationAction extends Action
|
||||
{
|
||||
var $id = null;
|
||||
var $page = null;
|
||||
var $notices = null;
|
||||
var $userProfile = null;
|
||||
|
||||
const MAX_NOTICES = 500;
|
||||
|
||||
/**
|
||||
* Initialization.
|
||||
@ -69,6 +73,19 @@ class ConversationAction extends Action
|
||||
if (empty($this->page)) {
|
||||
$this->page = 1;
|
||||
}
|
||||
|
||||
$cur = common_current_user();
|
||||
|
||||
if (empty($cur)) {
|
||||
$this->userProfile = null;
|
||||
} else {
|
||||
$this->userProfile = $cur->getProfile();
|
||||
}
|
||||
|
||||
$stream = new ConversationNoticeStream($this->id, $this->userProfile);
|
||||
|
||||
$this->notices = $stream->getNotices(0, self::MAX_NOTICES);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -106,11 +123,9 @@ class ConversationAction extends Action
|
||||
*/
|
||||
function showContent()
|
||||
{
|
||||
$notices = Notice::conversationStream($this->id, null, null);
|
||||
$tnl = new FullThreadedNoticeList($this->notices, $this, $this->userProfile);
|
||||
|
||||
$ct = new ConversationTree($notices, $this);
|
||||
|
||||
$cnt = $ct->show();
|
||||
$cnt = $tnl->show();
|
||||
}
|
||||
|
||||
function isReadOnly()
|
||||
@ -118,173 +133,3 @@ class ConversationAction extends Action
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Conversation tree
|
||||
*
|
||||
* The widget class for displaying a hierarchical list of notices.
|
||||
*
|
||||
* @category Widget
|
||||
* @package StatusNet
|
||||
* @author Evan Prodromou <evan@status.net>
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl.html AGPLv3
|
||||
* @link http://status.net/
|
||||
*/
|
||||
class ConversationTree extends NoticeList
|
||||
{
|
||||
var $tree = null;
|
||||
var $table = null;
|
||||
|
||||
/**
|
||||
* Show the tree of notices
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
function show()
|
||||
{
|
||||
$cnt = $this->_buildTree();
|
||||
|
||||
$this->out->elementStart('div', array('id' =>'notices_primary'));
|
||||
// TRANS: Header on conversation page. Hidden by default (h2).
|
||||
$this->out->element('h2', null, _('Notices'));
|
||||
$this->out->elementStart('ol', array('class' => 'notices xoxo'));
|
||||
|
||||
if (array_key_exists('root', $this->tree)) {
|
||||
$rootid = $this->tree['root'][0];
|
||||
$this->showNoticePlus($rootid);
|
||||
}
|
||||
|
||||
$this->out->elementEnd('ol');
|
||||
$this->out->elementEnd('div');
|
||||
|
||||
return $cnt;
|
||||
}
|
||||
|
||||
function _buildTree()
|
||||
{
|
||||
$cnt = 0;
|
||||
|
||||
$this->tree = array();
|
||||
$this->table = array();
|
||||
|
||||
while ($this->notice->fetch()) {
|
||||
|
||||
$cnt++;
|
||||
|
||||
$id = $this->notice->id;
|
||||
$notice = clone($this->notice);
|
||||
|
||||
$this->table[$id] = $notice;
|
||||
|
||||
if (is_null($notice->reply_to)) {
|
||||
$this->tree['root'] = array($notice->id);
|
||||
} else if (array_key_exists($notice->reply_to, $this->tree)) {
|
||||
$this->tree[$notice->reply_to][] = $notice->id;
|
||||
} else {
|
||||
$this->tree[$notice->reply_to] = array($notice->id);
|
||||
}
|
||||
}
|
||||
|
||||
return $cnt;
|
||||
}
|
||||
|
||||
/**
|
||||
* Shows a notice plus its list of children.
|
||||
*
|
||||
* @param integer $id ID of the notice to show
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
function showNoticePlus($id)
|
||||
{
|
||||
$notice = $this->table[$id];
|
||||
|
||||
// We take responsibility for doing the li
|
||||
|
||||
$this->out->elementStart('li', array('class' => 'hentry notice',
|
||||
'id' => 'notice-' . $id));
|
||||
|
||||
$item = $this->newListItem($notice);
|
||||
$item->show();
|
||||
|
||||
if (array_key_exists($id, $this->tree)) {
|
||||
$children = $this->tree[$id];
|
||||
|
||||
$this->out->elementStart('ol', array('class' => 'notices'));
|
||||
|
||||
sort($children);
|
||||
|
||||
foreach ($children as $child) {
|
||||
$this->showNoticePlus($child);
|
||||
}
|
||||
|
||||
$this->out->elementEnd('ol');
|
||||
}
|
||||
|
||||
$this->out->elementEnd('li');
|
||||
}
|
||||
|
||||
/**
|
||||
* Override parent class to return our preferred item.
|
||||
*
|
||||
* @param Notice $notice Notice to display
|
||||
*
|
||||
* @return NoticeListItem a list item to show
|
||||
*/
|
||||
function newListItem($notice)
|
||||
{
|
||||
return new ConversationTreeItem($notice, $this->out);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Conversation tree list item
|
||||
*
|
||||
* Special class of NoticeListItem for use inside conversation trees.
|
||||
*
|
||||
* @category Widget
|
||||
* @package StatusNet
|
||||
* @author Evan Prodromou <evan@status.net>
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl.html AGPLv3
|
||||
* @link http://status.net/
|
||||
*/
|
||||
class ConversationTreeItem extends NoticeListItem
|
||||
{
|
||||
/**
|
||||
* start a single notice.
|
||||
*
|
||||
* The default creates the <li>; we skip, since the ConversationTree
|
||||
* takes care of that.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
function showStart()
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* finish the notice
|
||||
*
|
||||
* The default closes the <li>; we skip, since the ConversationTree
|
||||
* takes care of that.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
function showEnd()
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* show link to notice conversation page
|
||||
*
|
||||
* Since we're only used on the conversation page, we skip this
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
function showContext()
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -66,9 +66,7 @@ class ConversationRepliesAction extends ConversationAction
|
||||
*/
|
||||
function showContent()
|
||||
{
|
||||
$notices = Notice::conversationStream($this->id, null, null);
|
||||
|
||||
$ct = new FullThreadedNoticeList($notices, $this);
|
||||
$ct = new FullThreadedNoticeList($this->notices, $this, $this->userProfile);
|
||||
|
||||
$cnt = $ct->show();
|
||||
}
|
||||
@ -88,19 +86,3 @@ class ConversationRepliesAction extends ConversationAction
|
||||
$this->elementEnd('html');
|
||||
}
|
||||
}
|
||||
|
||||
class FullThreadedNoticeList extends ThreadedNoticeList
|
||||
{
|
||||
function newListItem($notice)
|
||||
{
|
||||
return new FullThreadedNoticeListItem($notice, $this->out);
|
||||
}
|
||||
}
|
||||
|
||||
class FullThreadedNoticeListItem extends ThreadedNoticeListItem
|
||||
{
|
||||
function initialItems()
|
||||
{
|
||||
return 1000; // @fixme
|
||||
}
|
||||
}
|
||||
|
@ -99,6 +99,7 @@ class DeleteapplicationAction extends Action
|
||||
// CSRF protection
|
||||
$token = $this->trimmed('token');
|
||||
if (!$token || $token != common_session_token()) {
|
||||
// TRANS: Client error displayed when the session token does not match or is not given.
|
||||
$this->clientError(_('There was a problem with your session token.'));
|
||||
return;
|
||||
}
|
||||
|
@ -48,7 +48,7 @@ class DeletenoticeAction extends Action
|
||||
$this->user = common_current_user();
|
||||
|
||||
if (!$this->user) {
|
||||
// TRANS: Error message displayed trying to delete a notice while not logged in.
|
||||
// TRANS: Error message displayed when trying to perform an action that requires a logged in user.
|
||||
common_user_error(_('Not logged in.'));
|
||||
exit;
|
||||
}
|
||||
@ -174,6 +174,7 @@ class DeletenoticeAction extends Action
|
||||
$token = $this->trimmed('token');
|
||||
|
||||
if (!$token || $token != common_session_token()) {
|
||||
// TRANS: Client error displayed when the session token does not match or is not given.
|
||||
$this->showForm(_('There was a problem with your session token. ' .
|
||||
'Try again, please.'));
|
||||
return;
|
||||
|
@ -57,7 +57,7 @@ class DisfavorAction extends Action
|
||||
{
|
||||
parent::handle($args);
|
||||
if (!common_logged_in()) {
|
||||
// TRANS: Client error displayed when trying to remove a favorite while not logged in.
|
||||
// TRANS: Error message displayed when trying to perform an action that requires a logged in user.
|
||||
$this->clientError(_('Not logged in.'));
|
||||
return;
|
||||
}
|
||||
|
@ -147,80 +147,19 @@ class DocAction extends Action
|
||||
{
|
||||
if (Event::handle('StartLoadDoc', array(&$this->title, &$this->output))) {
|
||||
|
||||
$this->filename = $this->getFilename();
|
||||
$paths = DocFile::defaultPaths();
|
||||
|
||||
if (empty($this->filename)) {
|
||||
$docfile = DocFile::forTitle($this->title, $paths);
|
||||
|
||||
if (empty($docfile)) {
|
||||
// TRANS: Client exception thrown when requesting a document from the documentation that does not exist.
|
||||
// TRANS: %s is the non-existing document.
|
||||
throw new ClientException(sprintf(_('No such document "%s".'), $this->title), 404);
|
||||
}
|
||||
|
||||
$c = file_get_contents($this->filename);
|
||||
|
||||
$this->output = common_markup_to_html($c);
|
||||
$this->output = $docfile->toHTML();
|
||||
|
||||
Event::handle('EndLoadDoc', array($this->title, &$this->output));
|
||||
}
|
||||
}
|
||||
|
||||
function getFilename()
|
||||
{
|
||||
$localDef = null;
|
||||
$local = null;
|
||||
|
||||
$site = StatusNet::currentSite();
|
||||
|
||||
if (!empty($site) && file_exists(INSTALLDIR.'/local/doc-src/'.$site.'/'.$this->title)) {
|
||||
$localDef = INSTALLDIR.'/local/doc-src/'.$site.'/'.$this->title;
|
||||
|
||||
$local = glob(INSTALLDIR.'/local/doc-src/'.$site.'/'.$this->title.'.*');
|
||||
if ($local === false) {
|
||||
// Some systems return false, others array(), if dir didn't exist.
|
||||
$local = array();
|
||||
}
|
||||
} else {
|
||||
if (file_exists(INSTALLDIR.'/local/doc-src/'.$this->title)) {
|
||||
$localDef = INSTALLDIR.'/local/doc-src/'.$this->title;
|
||||
}
|
||||
|
||||
$local = glob(INSTALLDIR.'/local/doc-src/'.$this->title.'.*');
|
||||
if ($local === false) {
|
||||
$local = array();
|
||||
}
|
||||
}
|
||||
|
||||
if (count($local) || isset($localDef)) {
|
||||
return $this->negotiateLanguage($local, $localDef);
|
||||
}
|
||||
|
||||
if (file_exists(INSTALLDIR.'/doc-src/'.$this->title)) {
|
||||
$distDef = INSTALLDIR.'/doc-src/'.$this->title;
|
||||
}
|
||||
|
||||
$dist = glob(INSTALLDIR.'/doc-src/'.$this->title.'.*');
|
||||
if ($dist === false) {
|
||||
$dist = array();
|
||||
}
|
||||
|
||||
if (count($dist) || isset($distDef)) {
|
||||
return $this->negotiateLanguage($dist, $distDef);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
function negotiateLanguage($filenames, $defaultFilename=null)
|
||||
{
|
||||
// XXX: do this better
|
||||
|
||||
$langcode = common_language();
|
||||
|
||||
foreach ($filenames as $filename) {
|
||||
if (preg_match('/\.'.$langcode.'$/', $filename)) {
|
||||
return $filename;
|
||||
}
|
||||
}
|
||||
|
||||
return $defaultFilename;
|
||||
}
|
||||
}
|
||||
|
@ -128,6 +128,7 @@ class EditApplicationAction extends OwnerDesignAction
|
||||
// CSRF protection
|
||||
$token = $this->trimmed('token');
|
||||
if (!$token || $token != common_session_token()) {
|
||||
// TRANS: Client error displayed when the session token does not match or is not given.
|
||||
$this->clientError(_('There was a problem with your session token.'));
|
||||
return;
|
||||
}
|
||||
|
@ -185,7 +185,15 @@ class EditgroupAction extends GroupDesignAction
|
||||
$description = $this->trimmed('description');
|
||||
$location = $this->trimmed('location');
|
||||
$aliasstring = $this->trimmed('aliases');
|
||||
$join_policy = intval($this->arg('join_policy'));
|
||||
$private = $this->boolean('private');
|
||||
|
||||
if ($private) {
|
||||
$force_scope = 1;
|
||||
$join_policy = User_group::JOIN_POLICY_MODERATE;
|
||||
} else {
|
||||
$force_scope = 0;
|
||||
$join_policy = User_group::JOIN_POLICY_OPEN;
|
||||
}
|
||||
|
||||
if ($this->nicknameExists($nickname)) {
|
||||
// TRANS: Group edit form validation error.
|
||||
@ -267,6 +275,7 @@ class EditgroupAction extends GroupDesignAction
|
||||
$this->group->location = $location;
|
||||
$this->group->mainpage = common_local_url('showgroup', array('nickname' => $nickname));
|
||||
$this->group->join_policy = $join_policy;
|
||||
$this->group->force_scope = $force_scope;
|
||||
|
||||
$result = $this->group->update($orig);
|
||||
|
||||
|
333
actions/editpeopletag.php
Normal file
333
actions/editpeopletag.php
Normal file
@ -0,0 +1,333 @@
|
||||
<?php
|
||||
/**
|
||||
* StatusNet, the distributed open-source microblogging tool
|
||||
*
|
||||
* Edit an existing group
|
||||
*
|
||||
* PHP version 5
|
||||
*
|
||||
* LICENCE: This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* @category Group
|
||||
* @package StatusNet
|
||||
* @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);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a new group
|
||||
*
|
||||
* This is the form for adding a new group
|
||||
*
|
||||
* @category Group
|
||||
* @package StatusNet
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||
* @link http://status.net/
|
||||
*/
|
||||
|
||||
class EditpeopletagAction extends OwnerDesignAction
|
||||
{
|
||||
var $msg, $confirm, $confirm_args=array();
|
||||
|
||||
function title()
|
||||
{
|
||||
if ($_SERVER['REQUEST_METHOD'] == 'POST' && $this->boolean('delete')) {
|
||||
// TRANS: Title for edit list page after deleting a tag.
|
||||
// TRANS: %s is a list.
|
||||
return sprintf(_('Delete %s list'), $this->peopletag->tag);
|
||||
}
|
||||
// TRANS: Title for edit list page.
|
||||
// TRANS: %s is a list.
|
||||
return sprintf(_('Edit list %s'), $this->peopletag->tag);
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepare to run
|
||||
*/
|
||||
|
||||
function prepare($args)
|
||||
{
|
||||
parent::prepare($args);
|
||||
|
||||
if (!common_logged_in()) {
|
||||
// TRANS: Error message displayed when trying to perform an action that requires a logged in user.
|
||||
$this->clientError(_('Not logged in.'));
|
||||
return false;
|
||||
}
|
||||
|
||||
$id = $this->arg('id');
|
||||
$tagger_arg = $this->arg('tagger');
|
||||
$tag_arg = $this->arg('tag');
|
||||
|
||||
$tagger = common_canonical_nickname($tagger_arg);
|
||||
$tag = common_canonical_tag($tag_arg);
|
||||
|
||||
$current = common_current_user();
|
||||
|
||||
// Permanent redirect on non-canonical tag
|
||||
|
||||
if ($tagger_arg != $tagger || $tag_arg != $tag) {
|
||||
$args = array('tagger' => $tagger, 'tag' => $tag);
|
||||
common_redirect(common_local_url('editpeopletag', $args), 301);
|
||||
return false;
|
||||
}
|
||||
|
||||
$user = null;
|
||||
if ($id) {
|
||||
$this->peopletag = Profile_list::staticGet('id', $id);
|
||||
if (!empty($this->peopletag)) {
|
||||
$user = User::staticGet('id', $this->peopletag->tagger);
|
||||
}
|
||||
} else {
|
||||
if (!$tagger) {
|
||||
// TRANS: Error message displayed when trying to perform an action that requires a tagging user or ID.
|
||||
$this->clientError(_('No tagger or ID.'), 404);
|
||||
return false;
|
||||
}
|
||||
|
||||
$user = User::staticGet('nickname', $tagger);
|
||||
$this->peopletag = Profile_list::pkeyGet(array('tagger' => $user->id, 'tag' => $tag));
|
||||
}
|
||||
|
||||
if (!$this->peopletag) {
|
||||
// TRANS: Client error displayed when referring to a non-existing list.
|
||||
$this->clientError(_('No such list.'), 404);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!$user) {
|
||||
// This should not be happening
|
||||
// TRANS: Client error displayed when referring to non-local user.
|
||||
$this->clientError(_('Not a local user.'), 404);
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($current->id != $user->id) {
|
||||
// TRANS: Client error displayed when reting to edit a tag that was not self-created.
|
||||
$this->clientError(_('You must be the creator of the tag to edit it.'), 404);
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->tagger = $user->getProfile();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle the request
|
||||
*
|
||||
* On GET, show the form. On POST, try to save the group.
|
||||
*
|
||||
* @param array $args unused
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
function handle($args)
|
||||
{
|
||||
parent::handle($args);
|
||||
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
|
||||
$this->trySave();
|
||||
} else {
|
||||
$this->showForm();
|
||||
}
|
||||
}
|
||||
|
||||
function showConfirm($msg=null, $fwd=null)
|
||||
{
|
||||
$this->confirm = $msg;
|
||||
$this->confirm_args = $fwd;
|
||||
$this->showPage();
|
||||
}
|
||||
|
||||
function showConfirmForm()
|
||||
{
|
||||
$this->elementStart('form', array('id' => 'form_peopletag_edit_confirm',
|
||||
'class' => 'form_settings',
|
||||
'method' => 'post',
|
||||
'action' => common_local_url('editpeopletag',
|
||||
array('tagger' => $this->tagger->nickname,
|
||||
'tag' => $this->peopletag->tag))));
|
||||
$this->elementStart('fieldset');
|
||||
$this->hidden('token', common_session_token());
|
||||
$this->hidden('id', $this->arg('id'));
|
||||
|
||||
foreach ($this->confirm_args as $key => $val) {
|
||||
$this->hidden($key, $val);
|
||||
}
|
||||
|
||||
$this->submit('form_action-no',
|
||||
_m('BUTTON','No'),
|
||||
'submit form_action-primary',
|
||||
'cancel');
|
||||
$this->submit('form_action-yes',
|
||||
_m('BUTTON','Yes'),
|
||||
'submit form_action-secondary',
|
||||
'confirm');
|
||||
$this->elementEnd('fieldset');
|
||||
$this->elementEnd('form');
|
||||
}
|
||||
|
||||
function showForm($msg=null)
|
||||
{
|
||||
$this->msg = $msg;
|
||||
$this->showPage();
|
||||
}
|
||||
|
||||
function showObjectNav()
|
||||
{
|
||||
$nav = new PeopletagGroupNav($this, $this->peopletag);
|
||||
$nav->show();
|
||||
}
|
||||
|
||||
function showContent()
|
||||
{
|
||||
if ($this->confirm) {
|
||||
$this->showConfirmForm();
|
||||
return;
|
||||
}
|
||||
|
||||
$form = new PeopletagEditForm($this, $this->peopletag);
|
||||
$form->show();
|
||||
|
||||
$form->showProfileList();
|
||||
}
|
||||
|
||||
function showPageNotice()
|
||||
{
|
||||
if ($this->msg) {
|
||||
$this->element('p', 'error', $this->msg);
|
||||
} else if ($this->confirm) {
|
||||
$this->element('p', 'instructions', $this->confirm);
|
||||
} else {
|
||||
$this->element('p', 'instructions',
|
||||
// TRANS: Form instruction for edit list form.
|
||||
_('Use this form to edit the list.'));
|
||||
}
|
||||
}
|
||||
|
||||
function showScripts()
|
||||
{
|
||||
parent::showScripts();
|
||||
$this->autofocus('tag');
|
||||
}
|
||||
|
||||
function trySave()
|
||||
{
|
||||
$tag = common_canonical_tag($this->trimmed('tag'));
|
||||
$description = $this->trimmed('description');
|
||||
$private = $this->boolean('private');
|
||||
$delete = $this->arg('delete');
|
||||
$confirm = $this->arg('confirm');
|
||||
$cancel = $this->arg('cancel');
|
||||
|
||||
if ($delete && $cancel) {
|
||||
// TRANS: Form validation error displayed if the form data for deleting a tag was incorrect.
|
||||
$this->showForm(_('Delete aborted.'));
|
||||
return;
|
||||
}
|
||||
|
||||
$set_private = $private && $this->peopletag->private != $private;
|
||||
|
||||
if ($delete && !$confirm) {
|
||||
// TRANS: Text in confirmation dialog for deleting a tag.
|
||||
$this->showConfirm(_('Deleting this tag will permanantly remove ' .
|
||||
'all its subscription and membership records. ' .
|
||||
'Do you still want to continue?'), array('delete' => 1));
|
||||
return;
|
||||
} else if (common_valid_tag($tag)) {
|
||||
// TRANS: Form validation error displayed if a given tag is invalid.
|
||||
$this->showForm(_('Invalid tag.'));
|
||||
return;
|
||||
} else if ($tag != $this->peopletag->tag && $this->tagExists($tag)) {
|
||||
// TRANS: Form validation error displayed if a given tag is already present.
|
||||
// TRANS: %s is the already present tag.
|
||||
$this->showForm(sprintf(_('You already have a tag named %s.'), $tag));
|
||||
return;
|
||||
} else if (Profile_list::descriptionTooLong($description)) {
|
||||
$this->showForm(sprintf(
|
||||
// TRANS: Client error shown when providing too long a description when editing a list.
|
||||
// TRANS: %d is the maximum number of allowed characters.
|
||||
_m('Description is too long (maximum %d character).',
|
||||
'Description is too long (maximum %d characters).',
|
||||
Profile_list::maxDescription()),
|
||||
Profile_list::maxDescription()));
|
||||
return;
|
||||
} else if ($set_private && !$confirm && !$cancel) {
|
||||
$fwd = array('tag' => $tag,
|
||||
'description' => $description,
|
||||
'private' => (int) $private);
|
||||
|
||||
// TRANS: Text in confirmation dialog for setting a tag from public to private.
|
||||
$this->showConfirm(_('Setting a public tag as private will ' .
|
||||
'permanently remove all the existing ' .
|
||||
'subscriptions to it. Do you still want to continue?'), $fwd);
|
||||
return;
|
||||
}
|
||||
|
||||
$this->peopletag->query('BEGIN');
|
||||
|
||||
$orig = clone($this->peopletag);
|
||||
|
||||
$this->peopletag->tag = $tag;
|
||||
$this->peopletag->description = $description;
|
||||
if (!$set_private || $confirm) {
|
||||
$this->peopletag->private = $private;
|
||||
}
|
||||
|
||||
$result = $this->peopletag->update($orig);
|
||||
|
||||
if (!$result) {
|
||||
common_log_db_error($this->group, 'UPDATE', __FILE__);
|
||||
// TRANS: TRANS: Server error displayed when updating a list fails.
|
||||
$this->serverError(_('Could not update list.'));
|
||||
}
|
||||
|
||||
$this->peopletag->query('COMMIT');
|
||||
|
||||
if ($set_private && $confirm) {
|
||||
Profile_tag_subscription::cleanup($this->peopletag);
|
||||
}
|
||||
|
||||
if ($delete) {
|
||||
// This might take quite a bit of time.
|
||||
$this->peopletag->delete();
|
||||
// send home.
|
||||
common_redirect(common_local_url('all',
|
||||
array('nickname' => $this->tagger->nickname)),
|
||||
303);
|
||||
}
|
||||
|
||||
if ($tag != $orig->tag) {
|
||||
common_redirect(common_local_url('editpeopletag',
|
||||
array('tagger' => $this->tagger->nickname,
|
||||
'tag' => $tag)),
|
||||
303);
|
||||
} else {
|
||||
// TRANS: Edit list form success message.
|
||||
$this->showForm(_('Options saved.'));
|
||||
}
|
||||
}
|
||||
|
||||
function tagExists($tag)
|
||||
{
|
||||
$args = array('tagger' => $this->tagger->id, 'tag' => $tag);
|
||||
$ptag = Profile_list::pkeyGet($args);
|
||||
|
||||
return !empty($ptag);
|
||||
}
|
||||
}
|
@ -289,6 +289,7 @@ class EmailsettingsAction extends SettingsAction
|
||||
// CSRF protection
|
||||
$token = $this->trimmed('token');
|
||||
if (!$token || $token != common_session_token()) {
|
||||
// TRANS: Client error displayed when the session token does not match or is not given.
|
||||
$this->show_form(_('There was a problem with your session token. '.
|
||||
'Try again, please.'));
|
||||
return;
|
||||
@ -322,7 +323,6 @@ class EmailsettingsAction extends SettingsAction
|
||||
$user = common_current_user();
|
||||
|
||||
if (Event::handle('StartEmailSaveForm', array($this, &$user))) {
|
||||
|
||||
$emailnotifysub = $this->boolean('emailnotifysub');
|
||||
$emailnotifyfav = $this->boolean('emailnotifyfav');
|
||||
$emailnotifymsg = $this->boolean('emailnotifymsg');
|
||||
@ -404,6 +404,8 @@ class EmailsettingsAction extends SettingsAction
|
||||
return;
|
||||
}
|
||||
|
||||
if (Event::handle('StartAddEmailAddress', array($user, $email))) {
|
||||
|
||||
$confirm = new Confirm_address();
|
||||
|
||||
$confirm->address = $email;
|
||||
@ -422,6 +424,9 @@ class EmailsettingsAction extends SettingsAction
|
||||
|
||||
mail_confirm_address($user, $confirm->code, $user->nickname, $email);
|
||||
|
||||
Event::handle('EndAddEmailAddress', array($user, $email));
|
||||
}
|
||||
|
||||
// TRANS: Message given saving valid e-mail address that is to be confirmed.
|
||||
$msg = _('A confirmation code was sent to the email address you added. '.
|
||||
'Check your inbox (and spam box!) for the code and instructions '.
|
||||
|
@ -58,7 +58,7 @@ class FavorAction extends Action
|
||||
{
|
||||
parent::handle($args);
|
||||
if (!common_logged_in()) {
|
||||
// TRANS: Client error displayed when trying to mark a notice as favorite without being logged in.
|
||||
// TRANS: Error message displayed when trying to perform an action that requires a logged in user.
|
||||
$this->clientError(_('Not logged in.'));
|
||||
return;
|
||||
}
|
||||
@ -72,6 +72,7 @@ class FavorAction extends Action
|
||||
$notice = Notice::staticGet($id);
|
||||
$token = $this->trimmed('token-'.$notice->id);
|
||||
if (!$token || $token != common_session_token()) {
|
||||
// TRANS: Client error displayed when the session token does not match or is not given.
|
||||
$this->clientError(_('There was a problem with your session token. Try again, please.'));
|
||||
return;
|
||||
}
|
||||
|
@ -65,7 +65,7 @@ class FoafAction extends Action
|
||||
$this->profile = $this->user->getProfile();
|
||||
|
||||
if (!$this->profile) {
|
||||
// TRANS: Server error displayed when requesting Friends of a Friend feed for a user for which the profile could not be found.
|
||||
// TRANS: Error message displayed when referring to a user without a profile.
|
||||
$this->serverError(_('User has no profile.'), 500);
|
||||
return false;
|
||||
}
|
||||
|
@ -52,6 +52,7 @@ class GeocodeAction extends Action
|
||||
parent::prepare($args);
|
||||
$token = $this->trimmed('token');
|
||||
if (!$token || $token != common_session_token()) {
|
||||
// TRANS: Client error displayed when the session token does not match or is not given.
|
||||
$this->clientError(_('There was a problem with your session token. '.
|
||||
'Try again, please.'));
|
||||
}
|
||||
|
@ -56,12 +56,13 @@ class GroupblockAction extends RedirectingAction
|
||||
{
|
||||
parent::prepare($args);
|
||||
if (!common_logged_in()) {
|
||||
// TRANS: Client error displayed trying to block a user from a group while not logged in.
|
||||
// TRANS: Error message displayed when trying to perform an action that requires a logged in user.
|
||||
$this->clientError(_('Not logged in.'));
|
||||
return false;
|
||||
}
|
||||
$token = $this->trimmed('token');
|
||||
if (empty($token) || $token != common_session_token()) {
|
||||
// TRANS: Client error displayed when the session token does not match or is not given.
|
||||
$this->clientError(_('There was a problem with your session token. Try again, please.'));
|
||||
return;
|
||||
}
|
||||
|
@ -180,8 +180,8 @@ class GrouplogoAction extends GroupDesignAction
|
||||
|
||||
if (!$profile) {
|
||||
common_log_db_error($user, 'SELECT', __FILE__);
|
||||
// TRANS: Server error displayed coming across a request from a user without a profile.
|
||||
$this->serverError(_('User without matching profile.'));
|
||||
// TRANS: Error message displayed when referring to a user without a profile.
|
||||
$this->serverError(_('User has no profile.'));
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -156,11 +156,12 @@ class GroupqueueAction extends GroupDesignAction
|
||||
$members->free();
|
||||
|
||||
$this->pagination($this->page > 1, $cnt > PROFILES_PER_PAGE,
|
||||
$this->page, 'groupmembers',
|
||||
$this->page, 'groupqueue',
|
||||
array('nickname' => $this->group->nickname));
|
||||
}
|
||||
}
|
||||
|
||||
// @todo FIXME: documentation missing.
|
||||
class GroupQueueList extends GroupMemberList
|
||||
{
|
||||
function newListItem($profile)
|
||||
@ -169,6 +170,7 @@ class GroupQueueList extends GroupMemberList
|
||||
}
|
||||
}
|
||||
|
||||
// @todo FIXME: documentation missing.
|
||||
class GroupQueueListItem extends GroupMemberListItem
|
||||
{
|
||||
function showActions()
|
||||
|
@ -137,7 +137,7 @@ class groupRssAction extends Rss10Action
|
||||
// TRANS: Message is used as link title. %s is a user nickname.
|
||||
'title' => sprintf(_('%s timeline'), $group->nickname),
|
||||
'link' => common_local_url('showgroup', array('nickname' => $group->nickname)),
|
||||
// TRANS: Message is used as link description. %1$s is a username, %2$s is a site name.
|
||||
// TRANS: Message is used as link description. %1$s is a group name, %2$s is a site name.
|
||||
'description' => sprintf(_('Updates from members of %1$s on %2$s!'),
|
||||
$group->nickname, common_config('site', 'name')));
|
||||
return $c;
|
||||
|
@ -56,12 +56,13 @@ class GroupunblockAction extends Action
|
||||
{
|
||||
parent::prepare($args);
|
||||
if (!common_logged_in()) {
|
||||
// TRANS: Client error displayed when trying to unblock a user from a group while not logged in.
|
||||
// TRANS: Error message displayed when trying to perform an action that requires a logged in user.
|
||||
$this->clientError(_('Not logged in.'));
|
||||
return false;
|
||||
}
|
||||
$token = $this->trimmed('token');
|
||||
if (empty($token) || $token != common_session_token()) {
|
||||
// TRANS: Client error displayed when the session token does not match or is not given.
|
||||
$this->clientError(_('There was a problem with your session token. Try again, please.'));
|
||||
return;
|
||||
}
|
||||
|
@ -71,7 +71,7 @@ class HcardAction extends Action
|
||||
$this->profile = $this->user->getProfile();
|
||||
|
||||
if (!$this->profile) {
|
||||
// TRANS: Server error displayed when trying to get a user hCard for a user without a profile.
|
||||
// TRANS: Error message displayed when referring to a user without a profile.
|
||||
$this->serverError(_('User has no profile.'));
|
||||
return false;
|
||||
}
|
||||
|
@ -240,6 +240,7 @@ class ImsettingsAction extends SettingsAction
|
||||
// CSRF protection
|
||||
$token = $this->trimmed('token');
|
||||
if (!$token || $token != common_session_token()) {
|
||||
// TRANS: Client error displayed when the session token does not match or is not given.
|
||||
$this->showForm(_('There was a problem with your session token. '.
|
||||
'Try again, please.'));
|
||||
return;
|
||||
|
@ -1,7 +1,7 @@
|
||||
<?php
|
||||
/*
|
||||
* StatusNet - the distributed open-source microblogging tool
|
||||
* Copyright (C) 2008, 2009, StatusNet, Inc.
|
||||
* Copyright (C) 2008-2011, StatusNet, Inc.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
@ -28,6 +28,11 @@ class InviteAction extends CurrentUserDesignAction
|
||||
var $subbed = null;
|
||||
var $sent = null;
|
||||
|
||||
function showNoticeForm()
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
function isReadOnly($args)
|
||||
{
|
||||
return false;
|
||||
@ -54,9 +59,11 @@ class InviteAction extends CurrentUserDesignAction
|
||||
|
||||
function sendInvitations()
|
||||
{
|
||||
if (Event::handle('StartSendInvitations', array(&$this))) {
|
||||
// CSRF protection
|
||||
$token = $this->trimmed('token');
|
||||
if (!$token || $token != common_session_token()) {
|
||||
// TRANS: Client error displayed when the session token does not match or is not given.
|
||||
$this->showForm(_('There was a problem with your session token. Try again, please.'));
|
||||
return;
|
||||
}
|
||||
@ -69,15 +76,34 @@ class InviteAction extends CurrentUserDesignAction
|
||||
$personal = $this->trimmed('personal');
|
||||
|
||||
$addresses = explode("\n", $this->trimmed('addresses'));
|
||||
|
||||
foreach ($addresses as $email) {
|
||||
$email = trim($email);
|
||||
if (!Validate::email($email, common_config('email', 'check_domain'))) {
|
||||
$valid = null;
|
||||
|
||||
try {
|
||||
|
||||
if (Event::handle('StartValidateUserEmail', array(null, $email, &$valid))) {
|
||||
$valid = Validate::email($email, common_config('email', 'check_domain'));
|
||||
Event::handle('EndValidateUserEmail', array(null, $email, &$valid));
|
||||
}
|
||||
|
||||
if ($valid) {
|
||||
if (Event::handle('StartValidateEmailInvite', array($user, $email, &$valid))) {
|
||||
$valid = true;
|
||||
Event::handle('EndValidateEmailInvite', array($user, $email, &$valid));
|
||||
}
|
||||
}
|
||||
|
||||
if (!$valid) {
|
||||
// TRANS: Form validation message when providing an e-mail address that does not validate.
|
||||
// TRANS: %s is an invalid e-mail address.
|
||||
$this->showForm(sprintf(_('Invalid email address: %s.'), $email));
|
||||
return;
|
||||
}
|
||||
} catch (ClientException $e) {
|
||||
$this->showForm($e->getMessage());
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
$this->already = array();
|
||||
@ -102,6 +128,8 @@ class InviteAction extends CurrentUserDesignAction
|
||||
$this->mode = 'sent';
|
||||
|
||||
$this->showPage();
|
||||
Event::handle('EndSendInvitations', array($this));
|
||||
}
|
||||
}
|
||||
|
||||
function showScripts()
|
||||
@ -132,6 +160,7 @@ class InviteAction extends CurrentUserDesignAction
|
||||
|
||||
function showInvitationSuccess()
|
||||
{
|
||||
if (Event::handle('StartShowInvitationSuccess', array($this))) {
|
||||
if ($this->already) {
|
||||
// TRANS: Message displayed inviting users to use a StatusNet site while the inviting user
|
||||
// TRANS: is already subscribed to one or more users with the given e-mail address(es).
|
||||
@ -177,6 +206,8 @@ class InviteAction extends CurrentUserDesignAction
|
||||
// TRANS: people to join a StatusNet site.
|
||||
$this->element('p', null, _('You will be notified when your invitees accept the invitation and register on the site. Thanks for growing the community!'));
|
||||
}
|
||||
Event::handle('EndShowInvitationSuccess', array($this));
|
||||
}
|
||||
}
|
||||
|
||||
function showPageNotice()
|
||||
@ -203,35 +234,11 @@ class InviteAction extends CurrentUserDesignAction
|
||||
|
||||
function showInviteForm()
|
||||
{
|
||||
$this->elementStart('form', array('method' => 'post',
|
||||
'id' => 'form_invite',
|
||||
'class' => 'form_settings',
|
||||
'action' => common_local_url('invite')));
|
||||
$this->elementStart('fieldset');
|
||||
// TRANS: Form legend.
|
||||
$this->element('legend', null, 'Send an invitation');
|
||||
$this->hidden('token', common_session_token());
|
||||
|
||||
$this->elementStart('ul', 'form_data');
|
||||
$this->elementStart('li');
|
||||
// TRANS: Field label for a list of e-mail addresses.
|
||||
$this->textarea('addresses', _('Email addresses'),
|
||||
$this->trimmed('addresses'),
|
||||
// TRANS: Tooltip for field label for a list of e-mail addresses.
|
||||
_('Addresses of friends to invite (one per line).'));
|
||||
$this->elementEnd('li');
|
||||
$this->elementStart('li');
|
||||
// TRANS: Field label for a personal message to send to invitees.
|
||||
$this->textarea('personal', _('Personal message'),
|
||||
$this->trimmed('personal'),
|
||||
// TRANS: Tooltip for field label for a personal message to send to invitees.
|
||||
_('Optionally add a personal message to the invitation.'));
|
||||
$this->elementEnd('li');
|
||||
$this->elementEnd('ul');
|
||||
// TRANS: Send button for inviting friends
|
||||
$this->submit('send', _m('BUTTON', 'Send'));
|
||||
$this->elementEnd('fieldset');
|
||||
$this->elementEnd('form');
|
||||
if (Event::handle('StartShowInviteForm', array($this))) {
|
||||
$form = new InviteForm($this);
|
||||
$form->show();
|
||||
Event::handle('EndShowInviteForm', array($this));
|
||||
}
|
||||
}
|
||||
|
||||
function sendInvitation($email, $user, $personal)
|
||||
@ -254,44 +261,31 @@ class InviteAction extends CurrentUserDesignAction
|
||||
return false;
|
||||
}
|
||||
|
||||
$confirmUrl = common_local_url('register', array('code' => $invite->code));
|
||||
|
||||
$recipients = array($email);
|
||||
|
||||
$headers['From'] = mail_notify_from();
|
||||
$headers['To'] = trim($email);
|
||||
$headers['Content-Type'] = 'text/html; charset=UTF-8';
|
||||
|
||||
// TRANS: Subject for invitation email. Note that 'them' is correct as a gender-neutral
|
||||
// TRANS: singular 3rd-person pronoun in English. %1$s is the inviting user, $2$s is
|
||||
// TRANS: the StatusNet sitename.
|
||||
$headers['Subject'] = sprintf(_('%1$s has invited you to join them on %2$s'), $bestname, $sitename);
|
||||
|
||||
// TRANS: Body text for invitation email. Note that 'them' is correct as a gender-neutral
|
||||
// TRANS: singular 3rd-person pronoun in English. %1$s is the inviting user, %2$s is the
|
||||
// TRANS: StatusNet sitename, %3$s is the site URL, %4$s is the personal message from the
|
||||
// TRANS: inviting user, %s%5 a link to the timeline for the inviting user, %s$6 is a link
|
||||
// TRANS: to register with the StatusNet site.
|
||||
$body = sprintf(_("%1\$s has invited you to join them on %2\$s (%3\$s).\n\n".
|
||||
"%2\$s is a micro-blogging service that lets you keep up-to-date with people you know and people who interest you.\n\n".
|
||||
"You can also share news about yourself, your thoughts, or your life online with people who know about you. ".
|
||||
"It's also great for meeting new people who share your interests.\n\n".
|
||||
"%1\$s said:\n\n%4\$s\n\n".
|
||||
"You can see %1\$s's profile page on %2\$s here:\n\n".
|
||||
"%5\$s\n\n".
|
||||
"If you'd like to try the service, click on the link below to accept the invitation.\n\n".
|
||||
"%6\$s\n\n".
|
||||
"If not, you can ignore this message. Thanks for your patience and your time.\n\n".
|
||||
"Sincerely, %2\$s\n"),
|
||||
$bestname,
|
||||
$sitename,
|
||||
common_root_url(),
|
||||
$personal,
|
||||
common_local_url('showstream', array('nickname' => $user->nickname)),
|
||||
common_local_url('register', array('code' => $invite->code)));
|
||||
$title = (empty($personal)) ? 'invite' : 'invitepersonal';
|
||||
|
||||
// @todo FIXME: i18n issue.
|
||||
$inviteTemplate = DocFile::forTitle($title, DocFile::mailPaths());
|
||||
|
||||
$body = $inviteTemplate->toHTML(array('inviter' => $bestname,
|
||||
'inviterurl' => $profile->profileurl,
|
||||
'confirmurl' => $confirmUrl,
|
||||
'personal' => $personal));
|
||||
|
||||
common_debug('Confirm URL is ' . common_local_url('register', array('code' => $invite->code)));
|
||||
|
||||
mail_send($recipients, $headers, $body);
|
||||
}
|
||||
|
||||
function showObjectNav()
|
||||
{
|
||||
$nav = new SubGroupNav($this, common_current_user());
|
||||
$nav->show();
|
||||
}
|
||||
}
|
||||
|
@ -228,7 +228,7 @@ class LoginAction extends Action
|
||||
$this->elementStart('ul', 'form_data');
|
||||
$this->elementStart('li');
|
||||
// TRANS: Field label on login page.
|
||||
$this->input('nickname', _('Nickname'));
|
||||
$this->input('nickname', _('Username or email address'));
|
||||
$this->elementEnd('li');
|
||||
$this->elementStart('li');
|
||||
// TRANS: Field label on login page.
|
||||
|
@ -65,7 +65,7 @@ class LogoutAction extends Action
|
||||
{
|
||||
parent::handle($args);
|
||||
if (!common_logged_in()) {
|
||||
// TRANS: Client error displayed trying to log out when not logged in.
|
||||
// TRANS: Error message displayed when trying to perform an action that requires a logged in user.
|
||||
$this->clientError(_('Not logged in.'));
|
||||
} else {
|
||||
if (Event::handle('StartLogout', array($this))) {
|
||||
|
@ -58,12 +58,13 @@ class MakeadminAction extends RedirectingAction
|
||||
{
|
||||
parent::prepare($args);
|
||||
if (!common_logged_in()) {
|
||||
// TRANS: Client error displayed when trying to access the "make admin" page while not logged in.
|
||||
// TRANS: Error message displayed when trying to perform an action that requires a logged in user.
|
||||
$this->clientError(_('Not logged in.'));
|
||||
return false;
|
||||
}
|
||||
$token = $this->trimmed('token');
|
||||
if (empty($token) || $token != common_session_token()) {
|
||||
// TRANS: Client error displayed when the session token does not match or is not given.
|
||||
$this->clientError(_('There was a problem with your session token. Try again, please.'));
|
||||
return;
|
||||
}
|
||||
|
@ -109,6 +109,7 @@ class NewApplicationAction extends OwnerDesignAction
|
||||
// CSRF protection
|
||||
$token = $this->trimmed('token');
|
||||
if (!$token || $token != common_session_token()) {
|
||||
// TRANS: Client error displayed when the session token does not match or is not given.
|
||||
$this->clientError(_('There was a problem with your session token.'));
|
||||
return;
|
||||
}
|
||||
@ -294,7 +295,6 @@ class NewApplicationAction extends OwnerDesignAction
|
||||
$app->uploadLogo();
|
||||
} catch (Exception $e) {
|
||||
$app->query('ROLLBACK');
|
||||
// TRANS: Form validation error on New application page when providing an invalid image upload.
|
||||
$this->showForm(_('Invalid image.'));
|
||||
return;
|
||||
}
|
||||
|
@ -130,8 +130,8 @@ class NewgroupAction extends Action
|
||||
$homepage = $this->trimmed('homepage');
|
||||
$description = $this->trimmed('description');
|
||||
$location = $this->trimmed('location');
|
||||
$private = $this->boolean('private');
|
||||
$aliasstring = $this->trimmed('aliases');
|
||||
$join_policy = intval($this->arg('join_policy'));
|
||||
|
||||
if ($this->nicknameExists($nickname)) {
|
||||
// TRANS: Group create form validation error.
|
||||
@ -203,6 +203,14 @@ class NewgroupAction extends Action
|
||||
}
|
||||
}
|
||||
|
||||
if ($private) {
|
||||
$force_scope = 1;
|
||||
$join_policy = User_group::JOIN_POLICY_MODERATE;
|
||||
} else {
|
||||
$force_scope = 0;
|
||||
$join_policy = User_group::JOIN_POLICY_OPEN;
|
||||
}
|
||||
|
||||
$cur = common_current_user();
|
||||
|
||||
// Checked in prepare() above
|
||||
@ -217,6 +225,7 @@ class NewgroupAction extends Action
|
||||
'aliases' => $aliases,
|
||||
'userid' => $cur->id,
|
||||
'join_policy' => $join_policy,
|
||||
'force_scope' => $force_scope,
|
||||
'local' => true));
|
||||
|
||||
$this->group = $group;
|
||||
|
@ -85,7 +85,7 @@ class NewmessageAction extends Action
|
||||
parent::handle($args);
|
||||
|
||||
if (!common_logged_in()) {
|
||||
// TRANS: Client error displayed trying to create a new direct message while not logged in.
|
||||
// TRANS: Error message displayed when trying to perform an action that requires a logged in user.
|
||||
$this->clientError(_('Not logged in.'), 403);
|
||||
} else if ($_SERVER['REQUEST_METHOD'] == 'POST') {
|
||||
$this->saveNewMessage();
|
||||
@ -137,6 +137,7 @@ class NewmessageAction extends Action
|
||||
|
||||
$token = $this->trimmed('token');
|
||||
if (!$token || $token != common_session_token()) {
|
||||
// TRANS: Client error displayed when the session token does not match or is not given.
|
||||
$this->showForm(_('There was a problem with your session token. ' .
|
||||
'Try again, please.'));
|
||||
return;
|
||||
|
@ -64,7 +64,7 @@ class NewnoticeAction extends Action
|
||||
function title()
|
||||
{
|
||||
// TRANS: Page title for sending a new notice.
|
||||
return _('New notice');
|
||||
return _m('TITLE','New notice');
|
||||
}
|
||||
|
||||
/**
|
||||
@ -83,7 +83,7 @@ class NewnoticeAction extends Action
|
||||
function handle($args)
|
||||
{
|
||||
if (!common_logged_in()) {
|
||||
// TRANS: Client error displayed trying to send a notice while not logged in.
|
||||
// TRANS: Error message displayed when trying to perform an action that requires a logged in user.
|
||||
$this->clientError(_('Not logged in.'));
|
||||
} else if ($_SERVER['REQUEST_METHOD'] == 'POST') {
|
||||
// check for this before token since all POST and FILES data
|
||||
@ -101,6 +101,7 @@ class NewnoticeAction extends Action
|
||||
// CSRF protection
|
||||
$token = $this->trimmed('token');
|
||||
if (!$token || $token != common_session_token()) {
|
||||
// TRANS: Client error displayed when the session token does not match or is not given.
|
||||
$this->clientError(_('There was a problem with your session token. '.
|
||||
'Try again, please.'));
|
||||
}
|
||||
@ -180,6 +181,8 @@ class NewnoticeAction extends Action
|
||||
|
||||
if (Notice::contentTooLong($content_shortened)) {
|
||||
$upload->delete();
|
||||
// TRANS: Client error displayed exceeding the maximum notice length.
|
||||
// TRANS: %d is the maximum length for a notice.
|
||||
$this->clientError(sprintf(_m('Maximum notice size is %d character, including attachment URL.',
|
||||
'Maximum notice size is %d characters, including attachment URL.',
|
||||
Notice::maxContent()),
|
||||
@ -209,6 +212,10 @@ class NewnoticeAction extends Action
|
||||
$author_id = $user->id;
|
||||
$text = $content_shortened;
|
||||
|
||||
// Does the heavy-lifting for getting "To:" information
|
||||
|
||||
ToSelector::fillOptions($this, $options);
|
||||
|
||||
if (Event::handle('StartNoticeSaveWeb', array($this, &$author_id, &$text, &$options))) {
|
||||
|
||||
$notice = Notice::saveNew($user->id, $content_shortened, 'web', $options);
|
||||
@ -282,7 +289,8 @@ class NewnoticeAction extends Action
|
||||
{
|
||||
$this->startHTML('text/xml;charset=utf-8', true);
|
||||
$this->elementStart('head');
|
||||
$this->element('title', null, _('New notice'));
|
||||
// TRANS: Title for form to send a new notice.
|
||||
$this->element('title', null, _m('TITLE','New notice'));
|
||||
$this->elementEnd('head');
|
||||
$this->elementStart('body');
|
||||
|
||||
@ -323,6 +331,8 @@ class NewnoticeAction extends Action
|
||||
}
|
||||
|
||||
/**
|
||||
* // XXX: Should we be showing the notice form with microapps here?
|
||||
*
|
||||
* Overload for replies or bad results
|
||||
*
|
||||
* We show content in the notice form if there were replies or results.
|
||||
@ -344,10 +354,27 @@ class NewnoticeAction extends Action
|
||||
$inreplyto = null;
|
||||
}
|
||||
|
||||
$notice_form = new NoticeForm($this, array('content' => $content,
|
||||
'inreplyto' => $inreplyto));
|
||||
$this->elementStart('div', 'input_forms');
|
||||
$this->elementStart(
|
||||
'div',
|
||||
array(
|
||||
'id' => 'input_form_status',
|
||||
'class' => 'input_form current nonav'
|
||||
)
|
||||
);
|
||||
|
||||
$notice_form = new NoticeForm(
|
||||
$this,
|
||||
array(
|
||||
'content' => $content,
|
||||
'inreplyto' => $inreplyto
|
||||
)
|
||||
);
|
||||
|
||||
$notice_form->show();
|
||||
|
||||
$this->elementEnd('div');
|
||||
$this->elementEnd('div');
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -48,10 +48,36 @@ require_once INSTALLDIR.'/lib/searchaction.php';
|
||||
*/
|
||||
class NoticesearchAction extends SearchAction
|
||||
{
|
||||
protected $q = null;
|
||||
|
||||
function prepare($args)
|
||||
{
|
||||
parent::prepare($args);
|
||||
|
||||
$this->q = $this->trimmed('q');
|
||||
|
||||
// FIXME: very dependent on tag format
|
||||
if (preg_match('/^#([\pL\pN_\-\.]{1,64})/ue', $this->q)) {
|
||||
common_redirect(common_local_url('tag',
|
||||
array('tag' => common_canonical_tag(substr($this->q, 1)))),
|
||||
303);
|
||||
}
|
||||
|
||||
if (!empty($this->q)) {
|
||||
|
||||
$profile = Profile::current();
|
||||
$stream = new SearchNoticeStream($this->q, $profile);
|
||||
$page = $this->trimmed('page');
|
||||
|
||||
if (empty($page)) {
|
||||
$page = 1;
|
||||
} else {
|
||||
$page = (int)$page;
|
||||
}
|
||||
|
||||
$this->notice = $stream->getNotices((($page-1)*NOTICES_PER_PAGE), NOTICES_PER_PAGE + 1);
|
||||
}
|
||||
|
||||
common_set_returnto($this->selfUrl());
|
||||
|
||||
return true;
|
||||
@ -106,18 +132,25 @@ class NoticesearchAction extends SearchAction
|
||||
*/
|
||||
function showResults($q, $page)
|
||||
{
|
||||
$notice = new Notice();
|
||||
|
||||
$search_engine = $notice->getSearchEngine('notice');
|
||||
$search_engine->set_sort_mode('chron');
|
||||
// Ask for an extra to see if there's more.
|
||||
$search_engine->limit((($page-1)*NOTICES_PER_PAGE), NOTICES_PER_PAGE + 1);
|
||||
if (false === $search_engine->query($q)) {
|
||||
$cnt = 0;
|
||||
if (Event::handle('StartNoticeSearchShowResults', array($this, $q, $this->notice))) {
|
||||
if ($this->notice->N === 0) {
|
||||
$this->showEmptyResults($q, $page);
|
||||
} else {
|
||||
$cnt = $notice->find();
|
||||
$terms = preg_split('/[\s,]+/', $q);
|
||||
$nl = new SearchNoticeList($this->notice, $this, $terms);
|
||||
$cnt = $nl->show();
|
||||
$this->pagination($page > 1,
|
||||
$cnt > NOTICES_PER_PAGE,
|
||||
$page,
|
||||
'noticesearch',
|
||||
array('q' => $q));
|
||||
}
|
||||
if ($cnt === 0) {
|
||||
Event::handle('EndNoticeSearchShowResults', array($this, $q, $this->notice));
|
||||
}
|
||||
}
|
||||
|
||||
function showEmptyResults($q, $page)
|
||||
{
|
||||
// TRANS: Text for notice search results is the query had no results.
|
||||
$this->element('p', 'error', _('No results.'));
|
||||
|
||||
@ -138,15 +171,6 @@ class NoticesearchAction extends SearchAction
|
||||
$this->elementEnd('div');
|
||||
return;
|
||||
}
|
||||
if (Event::handle('StartNoticeSearchShowResults', array($this, $q, $notice))) {
|
||||
$terms = preg_split('/[\s,]+/', $q);
|
||||
$nl = new SearchNoticeList($notice, $this, $terms);
|
||||
$cnt = $nl->show();
|
||||
$this->pagination($page > 1, $cnt > NOTICES_PER_PAGE,
|
||||
$page, 'noticesearch', array('q' => $q));
|
||||
Event::handle('EndNoticeSearchShowResults', array($this, $q, $notice));
|
||||
}
|
||||
}
|
||||
|
||||
function showScripts()
|
||||
{
|
||||
|
@ -60,7 +60,7 @@ class NudgeAction extends Action
|
||||
parent::handle($args);
|
||||
|
||||
if (!common_logged_in()) {
|
||||
// TRANS: Client error displayed trying to nudge a user without being logged in.
|
||||
// TRANS: Error message displayed when trying to perform an action that requires a logged in user.
|
||||
$this->clientError(_('Not logged in.'));
|
||||
return;
|
||||
}
|
||||
@ -78,6 +78,7 @@ class NudgeAction extends Action
|
||||
$token = $this->trimmed('token');
|
||||
|
||||
if (!$token || $token != common_session_token()) {
|
||||
// TRANS: Client error displayed when the session token does not match or is not given.
|
||||
$this->clientError(_('There was a problem with your session token. Try again, please.'));
|
||||
return;
|
||||
}
|
||||
|
@ -132,6 +132,7 @@ class OauthconnectionssettingsAction extends SettingsAction
|
||||
|
||||
$token = $this->trimmed('token');
|
||||
if (!$token || $token != common_session_token()) {
|
||||
// TRANS: Client error displayed when the session token does not match or is not given.
|
||||
$this->showForm(_('There was a problem with your session token. '.
|
||||
'Try again, please.'));
|
||||
return;
|
||||
|
@ -143,6 +143,7 @@ class PasswordsettingsAction extends SettingsAction
|
||||
|
||||
$token = $this->trimmed('token');
|
||||
if (!$token || $token != common_session_token()) {
|
||||
// TRANS: Client error displayed when the session token does not match or is not given.
|
||||
$this->showForm(_('There was a problem with your session token. '.
|
||||
'Try again, please.'));
|
||||
return;
|
||||
|
@ -2,7 +2,7 @@
|
||||
/**
|
||||
* StatusNet, the distributed open-source microblogging tool
|
||||
*
|
||||
* Action for showing profiles self-tagged with a given tag
|
||||
* Lists by a user
|
||||
*
|
||||
* PHP version 5
|
||||
*
|
||||
@ -16,13 +16,16 @@
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* PHP version 5
|
||||
*
|
||||
* 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
|
||||
* @category Personal
|
||||
* @package StatusNet
|
||||
* @author Evan Prodromou <evan@status.net>
|
||||
* @author Zach Copley <zach@status.net>
|
||||
* @author Shashi Gowda <connect2shashi@gmail.com>
|
||||
* @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/
|
||||
@ -32,150 +35,131 @@ if (!defined('STATUSNET') && !defined('LACONICA')) {
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/**
|
||||
* This class outputs a paginated list of profiles self-tagged with a given tag
|
||||
*
|
||||
* @category Output
|
||||
* @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/
|
||||
*
|
||||
* @see Action
|
||||
*/
|
||||
require_once INSTALLDIR.'/lib/peopletaglist.php';
|
||||
// cache 3 pages
|
||||
define('PEOPLETAG_CACHE_WINDOW', PEOPLETAGS_PER_PAGE*3 + 1);
|
||||
|
||||
class PeopletagAction extends Action
|
||||
{
|
||||
|
||||
var $tag = null;
|
||||
var $page = null;
|
||||
var $tag = null;
|
||||
|
||||
/**
|
||||
* For initializing members of the class.
|
||||
*
|
||||
* @param array $argarray misc. arguments
|
||||
*
|
||||
* @return boolean true
|
||||
*/
|
||||
function prepare($argarray)
|
||||
function isReadOnly($args)
|
||||
{
|
||||
parent::prepare($argarray);
|
||||
|
||||
$this->tag = $this->trimmed('tag');
|
||||
|
||||
if (!common_valid_profile_tag($this->tag)) {
|
||||
// TRANS: Client error displayed when trying to tag a profile with an invalid tag.
|
||||
// TRANS: %s is the invalid tag.
|
||||
$this->clientError(sprintf(_('Not a valid people tag: %s.'),
|
||||
$this->tag));
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
|
||||
$this->page = ($this->arg('page')) ? $this->arg('page') : 1;
|
||||
function title()
|
||||
{
|
||||
if ($this->page == 1) {
|
||||
// TRANS: Title for list page.
|
||||
// TRANS: %s is a list.
|
||||
return sprintf(_('Public list %s'), $this->tag);
|
||||
} else {
|
||||
// TRANS: Title for list page.
|
||||
// TRANS: %1$s is a list, %2$d is a page number.
|
||||
return sprintf(_('Public list %1$s, page %2$d'), $this->tag, $this->page);
|
||||
}
|
||||
}
|
||||
|
||||
common_set_returnto($this->selfUrl());
|
||||
function prepare($args)
|
||||
{
|
||||
parent::prepare($args);
|
||||
$this->page = ($this->arg('page')) ? ($this->arg('page')+0) : 1;
|
||||
|
||||
$tag_arg = $this->arg('tag');
|
||||
$tag = common_canonical_tag($tag_arg);
|
||||
|
||||
// Permanent redirect on non-canonical nickname
|
||||
|
||||
if ($tag_arg != $tag) {
|
||||
$args = array('tag' => $nickname);
|
||||
if ($this->page && $this->page != 1) {
|
||||
$args['page'] = $this->page;
|
||||
}
|
||||
common_redirect(common_local_url('peopletag', $args), 301);
|
||||
return false;
|
||||
}
|
||||
$this->tag = $tag;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handler method
|
||||
*
|
||||
* @param array $argarray is ignored since it's now passed in in prepare()
|
||||
*
|
||||
* @return boolean is read only action?
|
||||
*/
|
||||
function handle($argarray)
|
||||
function handle($args)
|
||||
{
|
||||
parent::handle($argarray);
|
||||
parent::handle($args);
|
||||
$this->showPage();
|
||||
}
|
||||
|
||||
/**
|
||||
* Whips up a query to get a list of profiles based on the provided
|
||||
* people tag and page, initalizes a ProfileList widget, and displays
|
||||
* it to the user.
|
||||
*
|
||||
* @return nothing
|
||||
*/
|
||||
function showLocalNav()
|
||||
{
|
||||
$nav = new PublicGroupNav($this);
|
||||
$nav->show();
|
||||
}
|
||||
|
||||
function showAnonymousMessage()
|
||||
{
|
||||
$notice =
|
||||
// TRANS: Message for anonymous users on list page.
|
||||
// TRANS: This message contains Markdown links in the form [description](link).
|
||||
_('Lists are how you sort similar ' .
|
||||
'people on %%site.name%%, a [micro-blogging]' .
|
||||
'(http://en.wikipedia.org/wiki/Micro-blogging) service ' .
|
||||
'based on the Free Software [StatusNet](http://status.net/) tool. ' .
|
||||
'You can then easily keep track of what they ' .
|
||||
'are doing by subscribing to the list\'s timeline.' );
|
||||
$this->elementStart('div', array('id' => 'anon_notice'));
|
||||
$this->raw(common_markup_to_html($notice));
|
||||
$this->elementEnd('div');
|
||||
}
|
||||
|
||||
function showContent()
|
||||
{
|
||||
$offset = ($this->page-1) * PEOPLETAGS_PER_PAGE;
|
||||
$limit = PEOPLETAGS_PER_PAGE + 1;
|
||||
|
||||
$profile = new Profile();
|
||||
$ptags = new Profile_list();
|
||||
$ptags->tag = $this->tag;
|
||||
|
||||
$offset = ($this->page - 1) * PROFILES_PER_PAGE;
|
||||
$limit = PROFILES_PER_PAGE + 1;
|
||||
$user = common_current_user();
|
||||
|
||||
if (common_config('db', 'type') == 'pgsql') {
|
||||
$lim = ' LIMIT ' . $limit . ' OFFSET ' . $offset;
|
||||
if (empty($user)) {
|
||||
$ckey = sprintf('profile_list:tag:%s', $this->tag);
|
||||
$ptags->private = false;
|
||||
$ptags->orderBy('profile_list.modified DESC');
|
||||
|
||||
$c = Cache::instance();
|
||||
if ($offset+$limit <= PEOPLETAG_CACHE_WINDOW && !empty($c)) {
|
||||
$cached_ptags = Profile_list::getCached($ckey, $offset, $limit);
|
||||
if ($cached_ptags === false) {
|
||||
$ptags->limit(0, PEOPLETAG_CACHE_WINDOW);
|
||||
$ptags->find();
|
||||
|
||||
Profile_list::setCache($ckey, $ptags, $offset, $limit);
|
||||
} else {
|
||||
$lim = ' LIMIT ' . $offset . ', ' . $limit;
|
||||
$ptags = clone($cached_ptags);
|
||||
}
|
||||
} else {
|
||||
$ptags->limit($offset, $limit);
|
||||
$ptags->find();
|
||||
}
|
||||
} else {
|
||||
$ptags->whereAdd('(profile_list.private = false OR (' .
|
||||
' profile_list.tagger =' . $user->id .
|
||||
' AND profile_list.private = true) )');
|
||||
|
||||
$ptags->orderBy('profile_list.modified DESC');
|
||||
$ptags->find();
|
||||
}
|
||||
|
||||
// XXX: memcached this
|
||||
$pl = new PeopletagList($ptags, $this);
|
||||
$cnt = $pl->show();
|
||||
|
||||
$qry = 'SELECT profile.* ' .
|
||||
'FROM profile JOIN profile_tag ' .
|
||||
'ON profile.id = profile_tag.tagger ' .
|
||||
'WHERE profile_tag.tagger = profile_tag.tagged ' .
|
||||
"AND tag = '%s' " .
|
||||
'ORDER BY profile_tag.modified DESC%s';
|
||||
|
||||
$profile->query(sprintf($qry, $this->tag, $lim));
|
||||
|
||||
$ptl = new PeopleTagList($profile, $this); // pass the ammunition
|
||||
$cnt = $ptl->show();
|
||||
|
||||
$this->pagination($this->page > 1,
|
||||
$cnt > PROFILES_PER_PAGE,
|
||||
$this->page,
|
||||
'peopletag',
|
||||
array('tag' => $this->tag));
|
||||
$this->pagination($this->page > 1, $cnt > PEOPLETAGS_PER_PAGE,
|
||||
$this->page, 'peopletag', array('tag' => $this->tag));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the page title
|
||||
*
|
||||
* @return string page title
|
||||
*/
|
||||
function title()
|
||||
function showSections()
|
||||
{
|
||||
// TRANS: Page title for users with a certain self-tag.
|
||||
// TRANS: %1$s is the tag, %2$s is the page number.
|
||||
return sprintf(_('Users self-tagged with %1$s - page %2$d'),
|
||||
$this->tag, $this->page);
|
||||
}
|
||||
}
|
||||
|
||||
class PeopleTagList extends ProfileList
|
||||
{
|
||||
function newListItem($profile)
|
||||
{
|
||||
return new PeopleTagListItem($profile, $this->action);
|
||||
}
|
||||
}
|
||||
|
||||
class PeopleTagListItem extends ProfileListItem
|
||||
{
|
||||
function linkAttributes()
|
||||
{
|
||||
$aAttrs = parent::linkAttributes();
|
||||
|
||||
if (common_config('nofollow', 'peopletag')) {
|
||||
$aAttrs['rel'] .= ' nofollow';
|
||||
}
|
||||
|
||||
return $aAttrs;
|
||||
}
|
||||
|
||||
function homepageAttributes()
|
||||
{
|
||||
$aAttrs = parent::linkAttributes();
|
||||
|
||||
if (common_config('nofollow', 'peopletag')) {
|
||||
$aAttrs['rel'] = 'nofollow';
|
||||
}
|
||||
|
||||
return $aAttrs;
|
||||
}
|
||||
}
|
||||
|
126
actions/peopletagautocomplete.php
Normal file
126
actions/peopletagautocomplete.php
Normal file
@ -0,0 +1,126 @@
|
||||
<?php
|
||||
/**
|
||||
* StatusNet - the distributed open-source microblogging tool
|
||||
* Copyright (C) 2008-2010, StatusNet, Inc.
|
||||
*
|
||||
* Peopletag autocomple action.
|
||||
*
|
||||
* 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/>.
|
||||
*
|
||||
* PHP version 5
|
||||
*
|
||||
* @category Action
|
||||
* @package StatusNet
|
||||
* @author Shashi Gowda <connect2shashi@gmail.com>
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPLv3
|
||||
* @link http://status.net/
|
||||
*/
|
||||
|
||||
if (!defined('STATUSNET')) {
|
||||
exit(1);
|
||||
}
|
||||
|
||||
class PeopletagautocompleteAction extends Action
|
||||
{
|
||||
var $user;
|
||||
var $tags;
|
||||
var $last_mod;
|
||||
|
||||
/**
|
||||
* Check pre-requisites and instantiate attributes
|
||||
*
|
||||
* @param Array $args array of arguments (URL, GET, POST)
|
||||
*
|
||||
* @return boolean success flag
|
||||
*/
|
||||
function prepare($args)
|
||||
{
|
||||
parent::prepare($args);
|
||||
|
||||
// Only for logged-in users
|
||||
|
||||
$this->user = common_current_user();
|
||||
|
||||
if (empty($this->user)) {
|
||||
// TRANS: Error message displayed when trying to perform an action that requires a logged in user.
|
||||
$this->clientError(_('Not logged in.'));
|
||||
return false;
|
||||
}
|
||||
|
||||
// CSRF protection
|
||||
|
||||
$token = $this->trimmed('token');
|
||||
|
||||
if (!$token || $token != common_session_token()) {
|
||||
// TRANS: Client error displayed when the session token does not match or is not given.
|
||||
$this->clientError(_('There was a problem with your session token.'.
|
||||
' Try again, please.'));
|
||||
return false;
|
||||
}
|
||||
|
||||
$profile = $this->user->getProfile();
|
||||
$tags = $profile->getLists(common_current_user());
|
||||
|
||||
$this->tags = array();
|
||||
while ($tags->fetch()) {
|
||||
|
||||
if (empty($this->last_mod)) {
|
||||
$this->last_mod = $tags->modified;
|
||||
}
|
||||
|
||||
$arr = array();
|
||||
$arr['tag'] = $tags->tag;
|
||||
$arr['mode'] = $tags->private ? 'private' : 'public';
|
||||
// $arr['url'] = $tags->homeUrl();
|
||||
$arr['freq'] = $tags->taggedCount();
|
||||
|
||||
$this->tags[] = $arr;
|
||||
}
|
||||
|
||||
$tags = NULL;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Last modified time
|
||||
*
|
||||
* Helps in browser-caching
|
||||
*
|
||||
* @return String time
|
||||
*/
|
||||
function lastModified()
|
||||
{
|
||||
return strtotime($this->last_mod);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle request
|
||||
*
|
||||
* Print the JSON autocomplete data
|
||||
*
|
||||
* @param Array $args unused.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
function handle($args)
|
||||
{
|
||||
//common_log(LOG_DEBUG, 'Autocomplete data: ' . json_encode($this->tags));
|
||||
if ($this->tags) {
|
||||
print(json_encode($this->tags));
|
||||
exit(0);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
230
actions/peopletagged.php
Normal file
230
actions/peopletagged.php
Normal file
@ -0,0 +1,230 @@
|
||||
<?php
|
||||
/**
|
||||
* StatusNet, the distributed open-source microblogging tool
|
||||
*
|
||||
* List of people tagged by the user with a 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 Group
|
||||
* @package StatusNet
|
||||
* @author Shashi Gowda <connect2shashi@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(INSTALLDIR.'/lib/profilelist.php');
|
||||
|
||||
/**
|
||||
* List of people tagged by the user with a tag
|
||||
*
|
||||
* @category Peopletag
|
||||
* @package StatusNet
|
||||
* @author Shashi Gowda <connect2shashi@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 PeopletaggedAction extends OwnerDesignAction
|
||||
{
|
||||
var $page = null;
|
||||
var $peopletag = null;
|
||||
var $tagger = null;
|
||||
|
||||
function isReadOnly($args)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
function prepare($args)
|
||||
{
|
||||
parent::prepare($args);
|
||||
$this->page = ($this->arg('page')) ? ($this->arg('page')+0) : 1;
|
||||
|
||||
$tagger_arg = $this->arg('tagger');
|
||||
$tag_arg = $this->arg('tag');
|
||||
$tagger = common_canonical_nickname($tagger_arg);
|
||||
$tag = common_canonical_tag($tag_arg);
|
||||
|
||||
// Permanent redirect on non-canonical nickname
|
||||
|
||||
if ($tagger_arg != $tagger || $tag_arg != $tag) {
|
||||
$args = array('tagger' => $nickname, 'tag' => $tag);
|
||||
if ($this->page != 1) {
|
||||
$args['page'] = $this->page;
|
||||
}
|
||||
common_redirect(common_local_url('peopletagged', $args), 301);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!$tagger) {
|
||||
// TRANS: Client error displayed when a tagger is expected but not provided.
|
||||
$this->clientError(_('No tagger.'), 404);
|
||||
return false;
|
||||
}
|
||||
|
||||
$user = User::staticGet('nickname', $tagger);
|
||||
|
||||
if (!$user) {
|
||||
// TRANS: Client error displayed when referring to non-existing user.
|
||||
$this->clientError(_('No such user.'), 404);
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->tagger = $user->getProfile();
|
||||
$this->peopletag = Profile_list::pkeyGet(array('tagger' => $user->id, 'tag' => $tag));
|
||||
|
||||
if (!$this->peopletag) {
|
||||
// TRANS: Client error displayed when referring to a non-existing list.
|
||||
$this->clientError(_('No such list.'), 404);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
function title()
|
||||
{
|
||||
if ($this->page == 1) {
|
||||
// TRANS: Title for list of people listed by the user.
|
||||
// TRANS: %1$s is a list, %2$s is a username.
|
||||
return sprintf(_('People listed in %1$s by %2$s'),
|
||||
$this->peopletag->tag, $this->tagger->nickname);
|
||||
} else {
|
||||
// TRANS: Title for list of people listed by the user.
|
||||
// TRANS: %1$s is a list, %2$s is a username, %2$s is a page number.
|
||||
return sprintf(_('People listed in %1$s by %2$s, page %3$d'),
|
||||
$this->peopletag->tag, $this->user->nickname,
|
||||
$this->page);
|
||||
}
|
||||
}
|
||||
|
||||
function handle($args)
|
||||
{
|
||||
parent::handle($args);
|
||||
$this->showPage();
|
||||
}
|
||||
|
||||
function showPageNotice()
|
||||
{
|
||||
}
|
||||
|
||||
function showLocalNav()
|
||||
{
|
||||
$nav = new PeopletagGroupNav($this, $this->peopletag);
|
||||
$nav->show();
|
||||
}
|
||||
|
||||
function showContent()
|
||||
{
|
||||
$offset = ($this->page-1) * PROFILES_PER_PAGE;
|
||||
$limit = PROFILES_PER_PAGE + 1;
|
||||
|
||||
$cnt = 0;
|
||||
|
||||
$subs = $this->peopletag->getTagged($offset, $limit);
|
||||
|
||||
if ($subs) {
|
||||
$subscriber_list = new PeopletagMemberList($subs, $this->peopletag, $this);
|
||||
$cnt = $subscriber_list->show();
|
||||
}
|
||||
|
||||
$subs->free();
|
||||
|
||||
$this->pagination($this->page > 1, $cnt > PROFILES_PER_PAGE,
|
||||
$this->page, 'peopletagged',
|
||||
array('tagger' => $this->tagger->nickname,
|
||||
'tag' => $this->peopletag->tag));
|
||||
}
|
||||
}
|
||||
|
||||
class PeopletagMemberList extends ProfileList
|
||||
{
|
||||
var $peopletag = null;
|
||||
|
||||
function __construct($profile, $peopletag, $action)
|
||||
{
|
||||
parent::__construct($profile, $action);
|
||||
|
||||
$this->peopletag = $peopletag;
|
||||
}
|
||||
|
||||
function newListItem($profile)
|
||||
{
|
||||
return new PeopletagMemberListItem($profile, $this->peopletag, $this->action);
|
||||
}
|
||||
}
|
||||
|
||||
class PeopletagMemberListItem extends ProfileListItem
|
||||
{
|
||||
var $peopletag = null;
|
||||
|
||||
function __construct($profile, $peopletag, $action)
|
||||
{
|
||||
parent::__construct($profile, $action);
|
||||
|
||||
$this->peopletag = $peopletag;
|
||||
}
|
||||
|
||||
function showFullName()
|
||||
{
|
||||
parent::showFullName();
|
||||
if ($this->profile->id == $this->peopletag->tagger) {
|
||||
$this->out->text(' ');
|
||||
// TRANS: Addition in tag membership list for creator of a tag.
|
||||
$this->out->element('span', 'role', _('Creator'));
|
||||
}
|
||||
}
|
||||
|
||||
function showActions()
|
||||
{
|
||||
$this->startActions();
|
||||
if (Event::handle('StartProfileListItemActionElements', array($this))) {
|
||||
$this->showSubscribeButton();
|
||||
// TODO: Untag button
|
||||
Event::handle('EndProfileListItemActionElements', array($this));
|
||||
}
|
||||
$this->endActions();
|
||||
}
|
||||
|
||||
function linkAttributes()
|
||||
{
|
||||
// tagging people is healthy page-rank flow.
|
||||
return parent::linkAttributes();
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch necessary return-to arguments for the profile forms
|
||||
* to return to this list when they're done.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function returnToArgs()
|
||||
{
|
||||
$args = array('action' => 'peopletagged',
|
||||
'tag' => $this->peopletag->tag,
|
||||
'tagger' => $this->profile->nickname);
|
||||
$page = $this->out->arg('page');
|
||||
if ($page) {
|
||||
$args['param-page'] = $page;
|
||||
}
|
||||
return $args;
|
||||
}
|
||||
}
|
290
actions/peopletagsbyuser.php
Normal file
290
actions/peopletagsbyuser.php
Normal file
@ -0,0 +1,290 @@
|
||||
<?php
|
||||
/**
|
||||
* StatusNet, the distributed open-source microblogging tool
|
||||
*
|
||||
* Lists by 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 Personal
|
||||
* @package StatusNet
|
||||
* @author Shashi Gowda <connect2shashi@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 INSTALLDIR.'/lib/peopletaglist.php';
|
||||
|
||||
class PeopletagsbyuserAction extends OwnerDesignAction
|
||||
{
|
||||
var $page = null;
|
||||
var $tagger = null;
|
||||
var $tags = null;
|
||||
|
||||
function isReadOnly($args)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
function title()
|
||||
{
|
||||
if ($this->page == 1) {
|
||||
if ($this->isOwner()) {
|
||||
if ($this->arg('private')) {
|
||||
// TRANS: Title for lists by a user page for a private tag.
|
||||
return _('Private lists by you');
|
||||
} else if ($this->arg('public')) {
|
||||
// TRANS: Title for lists by a user page for a public tag.
|
||||
return _('Public lists by you');
|
||||
}
|
||||
// TRANS: Title for lists by a user page.
|
||||
return _('Lists by you');
|
||||
}
|
||||
// TRANS: Title for lists by a user page.
|
||||
// TRANS: %s is a user nickname.
|
||||
return sprintf(_('Lists by %s'), $this->tagger->nickname);
|
||||
} else {
|
||||
// TRANS: Title for lists by a user page.
|
||||
// TRANS: %1$s is a user nickname, %2$d is a page number.
|
||||
return sprintf(_('Lists by %1$s, page %2$d'), $this->tagger->nickname, $this->page);
|
||||
}
|
||||
}
|
||||
|
||||
function prepare($args)
|
||||
{
|
||||
parent::prepare($args);
|
||||
|
||||
if ($this->arg('public') && $this->arg('private')) {
|
||||
$this->args['public'] = $this->args['private'] = false;
|
||||
}
|
||||
|
||||
$nickname_arg = $this->arg('nickname');
|
||||
$nickname = common_canonical_nickname($nickname_arg);
|
||||
|
||||
// Permanent redirect on non-canonical nickname
|
||||
|
||||
if ($nickname_arg != $nickname) {
|
||||
$args = $this->getSelfUrlArgs();
|
||||
if ($this->arg('page') && $this->arg('page') != 1) {
|
||||
$args['page'] = $this->arg['page'];
|
||||
}
|
||||
common_redirect(common_local_url('peopletagsbyuser', $args), 301);
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->user = User::staticGet('nickname', $nickname);
|
||||
|
||||
if (!$this->user) {
|
||||
// TRANS: Client error displayed trying to perform an action related to a non-existing user.
|
||||
$this->clientError(_('No such user.'), 404);
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->tagger = $this->user->getProfile();
|
||||
|
||||
if (!$this->tagger) {
|
||||
// TRANS: Error message displayed when referring to a user without a profile.
|
||||
$this->serverError(_('User has no profile.'));
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->page = ($this->arg('page')) ? ($this->arg('page')+0) : 1;
|
||||
|
||||
|
||||
$offset = ($this->page-1) * PEOPLETAGS_PER_PAGE;
|
||||
$limit = PEOPLETAGS_PER_PAGE + 1;
|
||||
|
||||
$user = common_current_user();
|
||||
if ($this->arg('public')) {
|
||||
$this->tags = $this->tagger->getLists(false, $offset, $limit);
|
||||
} else if ($this->arg('private')) {
|
||||
if (empty($user)) {
|
||||
// TRANS: Error message displayed when trying to perform an action that requires a logged in user.
|
||||
$this->clientError(_('Not logged in.'), 403);
|
||||
}
|
||||
|
||||
if ($this->isOwner()) {
|
||||
$this->tags = $this->tagger->getPrivateTags($offset, $limit);
|
||||
} else {
|
||||
// TRANS: Client error displayed when trying view another user's private lists.
|
||||
$this->clientError(_('You cannot view others\' private lists'), 403);
|
||||
}
|
||||
} else {
|
||||
$this->tags = $this->tagger->getLists(common_current_user(), $offset, $limit);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
function handle($args)
|
||||
{
|
||||
parent::handle($args);
|
||||
|
||||
# Post from the tag dropdown; redirect to a GET
|
||||
|
||||
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
|
||||
common_redirect(common_local_url('peopletagsbyuser', $this->getSelfUrlArgs()), 303);
|
||||
return;
|
||||
}
|
||||
|
||||
$this->showPage();
|
||||
}
|
||||
|
||||
function showModeSelector()
|
||||
{
|
||||
$this->elementStart('dl', array('id'=>'filter_tags'));
|
||||
// TRANS: Mode selector label.
|
||||
$this->element('dt', null, _('Mode'));
|
||||
$this->elementStart('dd');
|
||||
$this->elementStart('ul');
|
||||
$this->elementStart('li', array('id' => 'filter_tags_for',
|
||||
'class' => 'child_1'));
|
||||
$this->element('a',
|
||||
array('href' =>
|
||||
common_local_url('peopletagsforuser',
|
||||
array('nickname' => $this->user->nickname))),
|
||||
// TRANS: Link text to show lists for user %s.
|
||||
sprintf(_('Lists for %s'), $this->tagger->nickname));
|
||||
$this->elementEnd('li');
|
||||
|
||||
if ($this->isOwner()) {
|
||||
$this->elementStart('li', array('id'=>'filter_tags_item'));
|
||||
$this->elementStart('form', array('name' => 'modeselector',
|
||||
'id' => 'form_filter_bymode',
|
||||
'action' => common_local_url('peopletagsbyuser',
|
||||
array('nickname' => $this->tagger->nickname)),
|
||||
'method' => 'post'));
|
||||
$this->elementStart('fieldset');
|
||||
// TRANS: Fieldset legend.
|
||||
$this->element('legend', null, _('Select tag to filter'));
|
||||
|
||||
$priv = $this->arg('private');
|
||||
$pub = $this->arg('public');
|
||||
|
||||
if (!$priv && !$pub) {
|
||||
$priv = $pub = true;
|
||||
}
|
||||
// TRANS: Checkbox label to show private tags.
|
||||
$this->checkbox('private', _m('LABEL','Private'), $priv,
|
||||
// TRANS: Checkbox title.
|
||||
_('Show private tags.'));
|
||||
// TRANS: Checkbox label to show public tags.
|
||||
$this->checkbox('public', _m('LABEL','Public'), $pub,
|
||||
// TRANS: Checkbox title.
|
||||
_('Show public tags.'));
|
||||
$this->hidden('nickname', $this->user->nickname);
|
||||
// TRANS: Submit button text for tag filter form.
|
||||
$this->submit('submit', _m('BUTTON','Go'));
|
||||
$this->elementEnd('fieldset');
|
||||
$this->elementEnd('form');
|
||||
$this->elementEnd('li');
|
||||
}
|
||||
$this->elementEnd('ul');
|
||||
$this->elementEnd('dd');
|
||||
$this->elementEnd('dl');
|
||||
}
|
||||
|
||||
function showAnonymousMessage()
|
||||
{
|
||||
$notice =
|
||||
// TRANS: Message displayed for anonymous users on page that displays lists by a user.
|
||||
// TRANS: This message contains Markdown links in the form [description](links).
|
||||
// TRANS: %s is a tagger nickname.
|
||||
sprintf(_('These are lists created by **%s**. ' .
|
||||
'Lists are how you sort similar ' .
|
||||
'people on %%%%site.name%%%%, a [micro-blogging]' .
|
||||
'(http://en.wikipedia.org/wiki/Micro-blogging) service ' .
|
||||
'based on the Free Software [StatusNet](http://status.net/) tool. ' .
|
||||
'You can easily keep track of what they ' .
|
||||
'are doing by subscribing to the tag\'s timeline.' ), $this->tagger->nickname);
|
||||
$this->elementStart('div', array('id' => 'anon_notice'));
|
||||
$this->raw(common_markup_to_html($notice));
|
||||
$this->elementEnd('div');
|
||||
}
|
||||
|
||||
function showPageNotice()
|
||||
{
|
||||
$this->elementStart('div', 'instructions');
|
||||
$this->showModeSelector();
|
||||
$this->elementEnd('div');
|
||||
}
|
||||
|
||||
function showContent()
|
||||
{
|
||||
#TODO: controls here.
|
||||
|
||||
$pl = new PeopletagList($this->tags, $this);
|
||||
$cnt = $pl->show();
|
||||
|
||||
if ($cnt == 0) {
|
||||
$this->showEmptyListMessage();
|
||||
}
|
||||
$this->pagination($this->page > 1, $cnt > PEOPLETAGS_PER_PAGE,
|
||||
$this->page, 'peopletagsbyuser', $this->getSelfUrlArgs());
|
||||
}
|
||||
|
||||
function getSelfUrlArgs()
|
||||
{
|
||||
$args = array();
|
||||
if ($this->arg('private')) {
|
||||
$args['private'] = 1;
|
||||
} else if ($this->arg('public')) {
|
||||
$args['public'] = 1;
|
||||
}
|
||||
$args['nickname'] = $this->trimmed('nickname');
|
||||
|
||||
return $args;
|
||||
}
|
||||
|
||||
function isOwner()
|
||||
{
|
||||
$user = common_current_user();
|
||||
return !empty($user) && $user->id == $this->tagger->id;
|
||||
}
|
||||
|
||||
function showObjectNav()
|
||||
{
|
||||
$nav = new PeopletagNav($this, $this->tagger);
|
||||
$nav->show();
|
||||
}
|
||||
|
||||
function showEmptyListMessage()
|
||||
{
|
||||
// TRANS: Message displayed on page that displays lists by a user when there are none.
|
||||
// TRANS: This message contains Markdown links in the form [description](links).
|
||||
// TRANS: %s is a tagger nickname.
|
||||
$message = sprintf(_('%s has not created any [lists](%%%%doc.lists%%%%) yet.'), $this->tagger->nickname);
|
||||
$this->elementStart('div', 'guide');
|
||||
$this->raw(common_markup_to_html($message));
|
||||
$this->elementEnd('div');
|
||||
}
|
||||
|
||||
function showProfileBlock()
|
||||
{
|
||||
$block = new AccountProfileBlock($this, $this->tagger);
|
||||
$block->show();
|
||||
}
|
||||
|
||||
function showSections()
|
||||
{
|
||||
#TODO: tags with most subscribers
|
||||
#TODO: tags with most "members"
|
||||
}
|
||||
}
|
167
actions/peopletagsforuser.php
Normal file
167
actions/peopletagsforuser.php
Normal file
@ -0,0 +1,167 @@
|
||||
<?php
|
||||
/**
|
||||
* StatusNet, the distributed open-source microblogging tool
|
||||
*
|
||||
* People tags for a user
|
||||
*
|
||||
* PHP version 5
|
||||
*
|
||||
* LICENCE: This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* @category Personal
|
||||
* @package StatusNet
|
||||
* @author Shashi Gowda <connect2shashi@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 INSTALLDIR.'/lib/peopletaglist.php';
|
||||
|
||||
class PeopletagsforuserAction extends OwnerDesignAction
|
||||
{
|
||||
var $page = null;
|
||||
var $tagged = null;
|
||||
|
||||
function isReadOnly($args)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
function title()
|
||||
{
|
||||
if ($this->page == 1) {
|
||||
// TRANS: Page title. %s is a tagged user's nickname.
|
||||
return sprintf(_('Lists with %s in them'), $this->tagged->nickname);
|
||||
} else {
|
||||
// TRANS: Page title. %1$s is a tagged user's nickname, %2$s is a page number.
|
||||
return sprintf(_('Lists with %1$s, page %2$d'), $this->tagged->nickname, $this->page);
|
||||
}
|
||||
}
|
||||
|
||||
function prepare($args)
|
||||
{
|
||||
parent::prepare($args);
|
||||
|
||||
$nickname_arg = $this->arg('nickname');
|
||||
$nickname = common_canonical_nickname($nickname_arg);
|
||||
|
||||
// Permanent redirect on non-canonical nickname
|
||||
|
||||
if ($nickname_arg != $nickname) {
|
||||
$args = array('nickname' => $nickname);
|
||||
if ($this->arg('page') && $this->arg('page') != 1) {
|
||||
$args['page'] = $this->arg['page'];
|
||||
}
|
||||
common_redirect(common_local_url('peopletagsforuser', $args), 301);
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->user = User::staticGet('nickname', $nickname);
|
||||
|
||||
if (!$this->user) {
|
||||
// TRANS: Client error displayed trying to perform an action related to a non-existing user.
|
||||
$this->clientError(_('No such user.'), 404);
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->tagged = $this->user->getProfile();
|
||||
|
||||
if (!$this->tagged) {
|
||||
// TRANS: Error message displayed when referring to a user without a profile.
|
||||
$this->serverError(_('User has no profile.'));
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->page = ($this->arg('page')) ? ($this->arg('page')+0) : 1;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
function handle($args)
|
||||
{
|
||||
parent::handle($args);
|
||||
$this->showPage();
|
||||
}
|
||||
|
||||
function showAnonymousMessage()
|
||||
{
|
||||
$notice =
|
||||
// TRANS: Message displayed for anonymous users on page that displays lists for a user.
|
||||
// TRANS: This message contains Markdown links in the form [description](links).
|
||||
// TRANS: %s is a tagger nickname.
|
||||
sprintf(_('These are lists for **%s**. ' .
|
||||
'lists are how you sort similar ' .
|
||||
'people on %%%%site.name%%%%, a [micro-blogging]' .
|
||||
'(http://en.wikipedia.org/wiki/Micro-blogging) service ' .
|
||||
'based on the Free Software [StatusNet](http://status.net/) tool. ' .
|
||||
'You can easily keep track of what they ' .
|
||||
'are doing by subscribing to the tag\'s timeline.' ), $this->tagged->nickname);
|
||||
$this->elementStart('div', array('id' => 'anon_notice'));
|
||||
$this->raw(common_markup_to_html($notice));
|
||||
$this->elementEnd('div');
|
||||
}
|
||||
|
||||
function showContent()
|
||||
{
|
||||
#TODO: controls here.
|
||||
|
||||
$offset = ($this->page-1) * PEOPLETAGS_PER_PAGE;
|
||||
$limit = PEOPLETAGS_PER_PAGE + 1;
|
||||
|
||||
$ptags = $this->tagged->getOtherTags(common_current_user(), $offset, $limit);
|
||||
|
||||
$pl = new PeopletagList($ptags, $this);
|
||||
$cnt = $pl->show();
|
||||
|
||||
if ($cnt == 0) {
|
||||
$this->showEmptyListMessage();
|
||||
}
|
||||
$this->pagination($this->page > 1, $cnt > PEOPLETAGS_PER_PAGE,
|
||||
$this->page, 'peopletagsforuser', array('nickname' => $this->tagged->id));
|
||||
}
|
||||
|
||||
function showEmptyListMessage()
|
||||
{
|
||||
// TRANS: Message displayed on page that displays lists a user was added to when there are none.
|
||||
// TRANS: This message contains Markdown links in the form [description](links).
|
||||
// TRANS: %s is a user nickname.
|
||||
$message = sprintf(_('%s has not been [listed](%%%%doc.lists%%%%) by anyone yet.'), $this->tagged->nickname);
|
||||
$this->elementStart('div', 'guide');
|
||||
$this->raw(common_markup_to_html($message));
|
||||
$this->elementEnd('div');
|
||||
}
|
||||
|
||||
function showObjectNav()
|
||||
{
|
||||
$nav = new PeopletagNav($this, $this->tagged);
|
||||
$nav->show();
|
||||
}
|
||||
|
||||
function showProfileBlock()
|
||||
{
|
||||
$block = new AccountProfileBlock($this, $this->tagged);
|
||||
$block->show();
|
||||
}
|
||||
|
||||
function showSections()
|
||||
{
|
||||
#TODO: tags with most subscribers
|
||||
#TODO: tags with most "members"
|
||||
}
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user