Merge branch '1.0.x' into schema-x
Conflicts: plugins/OStatus/classes/Ostatus_profile.php
This commit is contained in:
commit
99194e03fa
1
.gitignore
vendored
1
.gitignore
vendored
@ -25,3 +25,4 @@ good-config.php
|
||||
lac08.log
|
||||
php.log
|
||||
.DS_Store
|
||||
nbproject
|
||||
|
101
EVENTS.txt
101
EVENTS.txt
@ -258,10 +258,28 @@ EndShowExportData: just after showing the <div> with export data (feeds)
|
||||
- $action: action object being shown
|
||||
|
||||
StartShowNoticeItem: just before showing the notice item
|
||||
- $action: action object being shown
|
||||
- $item: The NoticeListItem object being shown
|
||||
|
||||
EndShowNoticeItem: just after showing the notice item
|
||||
- $action: action object being shown
|
||||
- $item: the NoticeListItem object being shown
|
||||
|
||||
StartShowNoticeInfo: just before showing notice info
|
||||
- $item: The NoticeListItem object being shown
|
||||
|
||||
EndShowNoticeInfo: just after showing notice info
|
||||
- $item: The NoticeListItem object being shown
|
||||
|
||||
StartShowNoticeOptions: just before showing notice options like fave, repeat, etc.
|
||||
- $item: the NoticeListItem object being shown
|
||||
|
||||
EndShowNoticeOptions: just after showing notice options like fave, repeat, etc.
|
||||
- $item: the NoticeListItem object being shown
|
||||
|
||||
StartShowFaveForm: just before showing the fave form
|
||||
- $item: the NoticeListItem object being shown
|
||||
|
||||
EndShowFaveForm: just after showing the fave form
|
||||
- $item: the NoticeListItem object being shown
|
||||
|
||||
StartShowPageNotice: just before showing the page notice (instructions or error)
|
||||
- $action: action object being shown
|
||||
@ -551,6 +569,12 @@ EndPublicXRDS: End XRDS output (right before the closing XRDS tag)
|
||||
- $action: the current action
|
||||
- &$xrdsoutputter - XRDSOutputter object to write to
|
||||
|
||||
StartHostMetaLinks: Start /.well-known/host-meta links
|
||||
- &links: array containing the links elements to be written
|
||||
|
||||
EndHostMetaLinks: End /.well-known/host-meta links
|
||||
- &links: array containing the links elements to be written
|
||||
|
||||
StartCheckPassword: Check a username/password
|
||||
- $nickname: The nickname to check
|
||||
- $password: The password to check
|
||||
@ -774,6 +798,22 @@ EndDisfavorNotice: After saving a notice as a favorite
|
||||
- $profile: profile of the person faving (can be remote!)
|
||||
- $notice: notice being faved
|
||||
|
||||
StartFavorNoticeForm: starting the data in the form for favoring a notice
|
||||
- $FavorForm: the favor form being shown
|
||||
- $notice: notice being favored
|
||||
|
||||
EndFavorNoticeForm: Ending the data in the form for favoring a notice
|
||||
- $FavorForm: the favor form being shown
|
||||
- $notice: notice being favored
|
||||
|
||||
StartDisFavorNoticeForm: starting the data in the form for disfavoring a notice
|
||||
- $DisfavorForm: the disfavor form being shown
|
||||
- $notice: notice being difavored
|
||||
|
||||
EndDisFavorNoticeForm: Ending the data in the form for disfavoring a notice
|
||||
- $DisfavorForm: the disfavor form being shown
|
||||
- $notice: notice being disfavored
|
||||
|
||||
StartFindMentions: start finding mentions in a block of text
|
||||
- $sender: sender profile
|
||||
- $text: plain text version of the notice
|
||||
@ -1063,3 +1103,60 @@ StartActivityEnd: before the closing </entry> in a notice activity entry (last c
|
||||
EndActivityEnd: after the closing </entry> in a notice activity entry
|
||||
- &$notice: notice being output
|
||||
- &$xs: XMLStringer for output
|
||||
|
||||
StartNoticeSaveWeb: before saving a notice through the Web interface
|
||||
- $action: action being executed (instance of NewNoticeAction)
|
||||
- &$authorId: integer ID of the author
|
||||
- &$text: text of the notice
|
||||
- &$options: additional options (location, replies, etc.)
|
||||
|
||||
EndNoticeSaveWeb: after saving a notice through the Web interface
|
||||
- $action: action being executed (instance of NewNoticeAction)
|
||||
- $notice: notice that was saved
|
||||
|
||||
StartRssEntryArray: at the start of copying a notice to an array
|
||||
- $notice: the notice being copied
|
||||
- &$entry: the entry (empty at beginning)
|
||||
|
||||
EndRssEntryArray: at the end of copying a notice to an array
|
||||
- $notice: the notice being copied
|
||||
- &$entry: the entry, with all the fields filled up
|
||||
|
||||
NoticeDeleteRelated: at the beginning of deleting related fields to a notice
|
||||
- $notice: notice being deleted
|
||||
|
||||
StartShowHeadTitle: when beginning to show the <title> element
|
||||
- $action: action being shown
|
||||
|
||||
EndShowHeadTitle: when done showing the <title>
|
||||
- $action: action being shown
|
||||
|
||||
StartShowPageTitle: when beginning to show the page title <h1>
|
||||
- $action: action being shown
|
||||
|
||||
EndShowPageTitle: when done showing the page title <h1>
|
||||
- $action: action being shown
|
||||
|
||||
StartDeleteOwnNotice: when a user starts to delete their own notice
|
||||
- $user: the user doing the delete
|
||||
- $notice: the notice being deleted
|
||||
|
||||
EndDeleteOwnNotice: when a user has deleted their own notice
|
||||
- $user: the user doing the delete
|
||||
- $notice: the notice being deleted
|
||||
|
||||
StartShowFeedLinkList: before showing the feed list in the sidebar
|
||||
- $action: action being executed
|
||||
- $feeds: list of feeds to show
|
||||
|
||||
EndShowFeedLinkList: after showing the feed list in the sidebar
|
||||
- $action: action being executed
|
||||
- $feeds: list of feeds shown
|
||||
|
||||
StartShowFeedLink: before showing an individual feed item
|
||||
- $action: action being executed
|
||||
- $feed: feed to show
|
||||
|
||||
EndShowFeedLink: after showing an individual feed
|
||||
- $action: action being executed
|
||||
- $feed: feed to show
|
||||
|
73
README
73
README
@ -2,8 +2,8 @@
|
||||
README
|
||||
------
|
||||
|
||||
StatusNet 0.9.4beta2
|
||||
11 August 2010
|
||||
StatusNet 0.9.5 "What's The Frequency, Kenneth?"
|
||||
10 September 2010
|
||||
|
||||
This is the README file for StatusNet, the Open Source microblogging
|
||||
platform. It includes installation instructions, descriptions of
|
||||
@ -38,11 +38,16 @@ more, please see the Open Software Service Definition 1.1:
|
||||
http://www.opendefinition.org/ossd
|
||||
|
||||
StatusNet, Inc. <http://status.net/> also offers this software as a
|
||||
Web service, requiring no installation on your part. The software run
|
||||
Web service, requiring no installation on your part. See
|
||||
<http://status.net/signup> for details. The software run
|
||||
on status.net is identical to the software available for download, so
|
||||
you can move back and forth between a hosted version or a version
|
||||
installed on your own servers.
|
||||
|
||||
A commercial software subscription is available from StatusNet Inc. It
|
||||
includes 24-hour technical support and developer support. More
|
||||
information at http://status.net/contact or email sales@status.net.
|
||||
|
||||
License
|
||||
=======
|
||||
|
||||
@ -68,6 +73,20 @@ License along with this program, in the file "COPYING". If not, see
|
||||
of using the software, and if you do not wish to share your
|
||||
modifications, *YOU MAY NOT INSTALL STATUSNET*.
|
||||
|
||||
Documentation in the /doc-src/ directory is available under the
|
||||
Creative Commons Attribution 3.0 Unported license, with attribution to
|
||||
"StatusNet". See http://creativecommons.org/licenses/by/3.0/ for details.
|
||||
|
||||
CSS and images in the /theme/ directory are available under the
|
||||
Creative Commons Attribution 3.0 Unported license, with attribution to
|
||||
"StatusNet". See http://creativecommons.org/licenses/by/3.0/ for details.
|
||||
|
||||
Our understanding and intention is that if you add your own theme that
|
||||
uses only CSS and images, those files are not subject to the copyleft
|
||||
requirements of the Affero General Public License 3.0. See
|
||||
http://wordpress.org/news/2009/07/themes-are-gpl-too/ . This is not
|
||||
legal advice; consult your lawyer.
|
||||
|
||||
Additional library software has been made available in the 'extlib'
|
||||
directory. All of it is Free Software and can be distributed under
|
||||
liberal terms, but those terms may differ in detail from the AGPL's
|
||||
@ -77,31 +96,33 @@ for additional terms.
|
||||
New this version
|
||||
================
|
||||
|
||||
This is a security, bug and feature release since version 0.9.3 released on
|
||||
29 June 2010.
|
||||
This is a security, bug and feature release since version 0.9.4 released on
|
||||
16 August 2010.
|
||||
|
||||
For best compatibility with client software and site federation, and a lot of
|
||||
bug fixes, it is highly recommended that all public sites upgrade to the new
|
||||
version.
|
||||
|
||||
Changes from 0.9.4beta1:
|
||||
- fix for daemon config switching on multi-site setup
|
||||
|
||||
Notable changes this version:
|
||||
|
||||
- OpenID and OAuth libraries patched for potential timing attack
|
||||
- OStatus feed i/o updated for Activity Streams
|
||||
- Correctness fixes on XRD, other discovery bits
|
||||
- Support for contacting SNI-based SSL virtual hosts when SSL
|
||||
certificate verification is enabled (requires PHP 5.3.2+ or
|
||||
enabling CURL backend with $config['http']['curl'] = true)
|
||||
- Experimental SubMirror plugin
|
||||
- Multi-site status_network table mode has been tweaked to support
|
||||
multiple tags better
|
||||
- Many updates to user interface translation from TranslateWiki
|
||||
- Many other bugfixes
|
||||
- Change of license for default themes and documentation from
|
||||
AGPLv3 to CC-By 3.0 Unported.
|
||||
- An experimental TinyMCE plugin to do in-browser rich editing of
|
||||
status updates. Does not support StatusNet syntax like @-replies or
|
||||
#hashtags very well.
|
||||
- An experimental plugin to add titles to notices.
|
||||
- A plugin to support the Echo <http://aboutecho.com/> commenting
|
||||
system.
|
||||
- A plugin to support the Disqus <http://disqus.com/> commenting system.
|
||||
- Changes to OStatus support to make StatusNet work for the Social Web
|
||||
Acid Test Level 0 <http://federatedsocialweb.net/wiki/SWAT0>.
|
||||
- Themes now support a theme.ini file for theme configuration, including
|
||||
defining a "base" theme.
|
||||
- Improved two-way Twitter integration, including support for
|
||||
repeats and retweets, replies, and faves going both ways across the
|
||||
bridge, as well as better parsing of Twitter statuses.
|
||||
|
||||
A full changelog is available at http://status.net/wiki/StatusNet_0.9.4.
|
||||
A full changelog is available at http://status.net/wiki/StatusNet_0.9.5.
|
||||
|
||||
Prerequisites
|
||||
=============
|
||||
@ -214,9 +235,9 @@ especially if you've previously installed PHP/MySQL packages.
|
||||
1. Unpack the tarball you downloaded on your Web server. Usually a
|
||||
command like this will work:
|
||||
|
||||
tar zxf statusnet-0.9.4.tar.gz
|
||||
tar zxf statusnet-0.9.5.tar.gz
|
||||
|
||||
...which will make a statusnet-0.9.2 subdirectory in your current
|
||||
...which will make a statusnet-0.9.5 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.)
|
||||
@ -224,7 +245,7 @@ especially if you've previously installed PHP/MySQL packages.
|
||||
2. Move the tarball to a directory of your choosing in your Web root
|
||||
directory. Usually something like this will work:
|
||||
|
||||
mv statusnet-0.9.4 /var/www/statusnet
|
||||
mv statusnet-0.9.5 /var/www/statusnet
|
||||
|
||||
This will make your StatusNet instance available in the statusnet path of
|
||||
your server, like "http://example.net/statusnet". "microblog" or
|
||||
@ -639,7 +660,7 @@ with this situation.
|
||||
If you've been using StatusNet 0.7, 0.6, 0.5 or lower, or if you've
|
||||
been tracking the "git" version of the software, you will probably
|
||||
want to upgrade and keep your existing data. There is no automated
|
||||
upgrade procedure in StatusNet 0.9.2. Try these step-by-step
|
||||
upgrade procedure in StatusNet 0.9.5. 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
|
||||
@ -660,7 +681,7 @@ instructions; read to the end first before trying them.
|
||||
5. Once all writing processes to your site are turned off, make a
|
||||
final backup of the Web directory and database.
|
||||
6. Move your StatusNet directory to a backup spot, like "statusnet.bak".
|
||||
7. Unpack your StatusNet 0.9.2 tarball and move it to "statusnet" or
|
||||
7. Unpack your StatusNet 0.9.5 tarball and move it to "statusnet" or
|
||||
wherever your code used to be.
|
||||
8. Copy the config.php file and avatar directory from your old
|
||||
directory to your new directory.
|
||||
@ -1537,7 +1558,7 @@ repository (see below), and you get a compilation error ("unexpected
|
||||
T_STRING") in the browser, check to see that you don't have any
|
||||
conflicts in your code.
|
||||
|
||||
If you upgraded to StatusNet 0.9.2 without reading the "Notice
|
||||
If you upgraded to StatusNet 0.9.5 without reading the "Notice
|
||||
inboxes" section above, and all your users' 'Personal' tabs are empty,
|
||||
read the "Notice inboxes" section above.
|
||||
|
||||
|
@ -83,6 +83,7 @@ class ApiAccountUpdateDeliveryDeviceAction 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
|
||||
);
|
||||
|
@ -86,6 +86,7 @@ class ApiAccountUpdateProfileAction extends ApiAuthAction
|
||||
|
||||
if ($_SERVER['REQUEST_METHOD'] != 'POST') {
|
||||
$this->clientError(
|
||||
// TRANS: Client error. POST is a HTTP command. It should not be translated.
|
||||
_('This method requires a POST.'),
|
||||
400, $this->format
|
||||
);
|
||||
|
@ -83,6 +83,7 @@ class ApiAccountUpdateProfileBackgroundImageAction extends ApiAuthAction
|
||||
|
||||
if ($_SERVER['REQUEST_METHOD'] != 'POST') {
|
||||
$this->clientError(
|
||||
// TRANS: Client error. POST is a HTTP command. It should not be translated.
|
||||
_('This method requires a POST.'),
|
||||
400, $this->format
|
||||
);
|
||||
|
@ -107,6 +107,7 @@ class ApiAccountUpdateProfileColorsAction extends ApiAuthAction
|
||||
|
||||
if ($_SERVER['REQUEST_METHOD'] != 'POST') {
|
||||
$this->clientError(
|
||||
// TRANS: Client error. POST is a HTTP command. It should not be translated.
|
||||
_('This method requires a POST.'),
|
||||
400, $this->format
|
||||
);
|
||||
|
@ -81,6 +81,7 @@ class ApiAccountUpdateProfileImageAction extends ApiAuthAction
|
||||
|
||||
if ($_SERVER['REQUEST_METHOD'] != 'POST') {
|
||||
$this->clientError(
|
||||
// TRANS: Client error. POST is a HTTP command. It should not be translated.
|
||||
_('This method requires a POST.'),
|
||||
400, $this->format
|
||||
);
|
||||
|
@ -86,6 +86,7 @@ class ApiBlockCreateAction extends ApiAuthAction
|
||||
|
||||
if ($_SERVER['REQUEST_METHOD'] != 'POST') {
|
||||
$this->clientError(
|
||||
// TRANS: Client error. POST is a HTTP command. It should not be translated.
|
||||
_('This method requires a POST.'),
|
||||
400,
|
||||
$this->format
|
||||
|
@ -85,6 +85,7 @@ class ApiBlockDestroyAction extends ApiAuthAction
|
||||
|
||||
if ($_SERVER['REQUEST_METHOD'] != 'POST') {
|
||||
$this->clientError(
|
||||
// TRANS: Client error. POST is a HTTP command. It should not be translated.
|
||||
_('This method requires a POST.'),
|
||||
400,
|
||||
$this->format
|
||||
|
@ -357,6 +357,7 @@ class ApiDirectMessageAction extends ApiAuthAction
|
||||
return '"' . implode(
|
||||
':',
|
||||
array($this->arg('action'),
|
||||
common_user_cache_hash($this->auth_user),
|
||||
common_language(),
|
||||
strtotime($this->messages[0]->created),
|
||||
strtotime($this->messages[$last]->created)
|
||||
|
@ -106,6 +106,7 @@ class ApiDirectMessageNewAction extends ApiAuthAction
|
||||
|
||||
if ($_SERVER['REQUEST_METHOD'] != 'POST') {
|
||||
$this->clientError(
|
||||
// TRANS: Client error. POST is a HTTP command. It should not be translated.
|
||||
_('This method requires a POST.'),
|
||||
400,
|
||||
$this->format
|
||||
|
@ -88,6 +88,7 @@ class ApiFavoriteCreateAction extends ApiAuthAction
|
||||
|
||||
if ($_SERVER['REQUEST_METHOD'] != 'POST') {
|
||||
$this->clientError(
|
||||
// TRANS: Client error. POST is a HTTP command. It should not be translated.
|
||||
_('This method requires a POST.'),
|
||||
400,
|
||||
$this->format
|
||||
|
@ -89,6 +89,7 @@ class ApiFavoriteDestroyAction extends ApiAuthAction
|
||||
|
||||
if ($_SERVER['REQUEST_METHOD'] != 'POST') {
|
||||
$this->clientError(
|
||||
// TRANS: Client error. POST is a HTTP command. It should not be translated.
|
||||
_('This method requires a POST.'),
|
||||
400,
|
||||
$this->format
|
||||
|
@ -88,6 +88,7 @@ class ApiFriendshipsCreateAction extends ApiAuthAction
|
||||
|
||||
if ($_SERVER['REQUEST_METHOD'] != 'POST') {
|
||||
$this->clientError(
|
||||
// TRANS: Client error. POST is a HTTP command. It should not be translated.
|
||||
_('This method requires a POST.'),
|
||||
400,
|
||||
$this->format
|
||||
|
@ -88,6 +88,7 @@ class ApiFriendshipsDestroyAction extends ApiAuthAction
|
||||
|
||||
if ($_SERVER['REQUEST_METHOD'] != 'POST') {
|
||||
$this->clientError(
|
||||
// TRANS: Client error. POST is a HTTP command. It should not be translated.
|
||||
_('This method requires a POST.'),
|
||||
400,
|
||||
$this->format
|
||||
|
@ -102,6 +102,7 @@ class ApiGroupCreateAction extends ApiAuthAction
|
||||
|
||||
if ($_SERVER['REQUEST_METHOD'] != 'POST') {
|
||||
$this->clientError(
|
||||
// TRANS: Client error. POST is a HTTP command. It should not be translated.
|
||||
_('This method requires a POST.'),
|
||||
400,
|
||||
$this->format
|
||||
|
@ -89,6 +89,7 @@ class ApiGroupJoinAction extends ApiAuthAction
|
||||
|
||||
if ($_SERVER['REQUEST_METHOD'] != 'POST') {
|
||||
$this->clientError(
|
||||
// TRANS: Client error. POST is a HTTP command. It should not be translated.
|
||||
_('This method requires a POST.'),
|
||||
400,
|
||||
$this->format
|
||||
|
@ -89,6 +89,7 @@ class ApiGroupLeaveAction extends ApiAuthAction
|
||||
|
||||
if ($_SERVER['REQUEST_METHOD'] != 'POST') {
|
||||
$this->clientError(
|
||||
// TRANS: Client error. POST is a HTTP command. It should not be translated.
|
||||
_('This method requires a POST.'),
|
||||
400,
|
||||
$this->format
|
||||
|
@ -213,6 +213,7 @@ class ApiGroupListAction extends ApiBareAuthAction
|
||||
return '"' . implode(
|
||||
':',
|
||||
array($this->arg('action'),
|
||||
common_user_cache_hash($this->auth_user),
|
||||
common_language(),
|
||||
$this->user->id,
|
||||
strtotime($this->groups[0]->created),
|
||||
|
@ -204,6 +204,7 @@ class ApiGroupListAllAction extends ApiPrivateAuthAction
|
||||
return '"' . implode(
|
||||
':',
|
||||
array($this->arg('action'),
|
||||
common_user_cache_hash($this->auth_user),
|
||||
common_language(),
|
||||
strtotime($this->groups[0]->created),
|
||||
strtotime($this->groups[$last]->created))
|
||||
|
@ -183,6 +183,7 @@ class ApiGroupMembershipAction extends ApiPrivateAuthAction
|
||||
return '"' . implode(
|
||||
':',
|
||||
array($this->arg('action'),
|
||||
common_user_cache_hash($this->auth_user),
|
||||
common_language(),
|
||||
$this->group->id,
|
||||
strtotime($this->profiles[0]->created),
|
||||
|
@ -149,6 +149,7 @@ class ApiGroupShowAction extends ApiPrivateAuthAction
|
||||
return '"' . implode(
|
||||
':',
|
||||
array($this->arg('action'),
|
||||
common_user_cache_hash($this->auth_user),
|
||||
common_language(),
|
||||
$this->group->id,
|
||||
strtotime($this->group->modified))
|
||||
|
@ -64,6 +64,7 @@ class ApiMediaUploadAction extends ApiAuthAction
|
||||
|
||||
if ($_SERVER['REQUEST_METHOD'] != 'POST') {
|
||||
$this->clientError(
|
||||
// TRANS: Client error. POST is a HTTP command. It should not be translated.
|
||||
_('This method requires a POST.'),
|
||||
400, $this->format
|
||||
);
|
||||
|
@ -270,7 +270,7 @@ class ApiOauthAuthorizeAction extends ApiOauthAction
|
||||
$this->elementStart('form', array('method' => 'post',
|
||||
'id' => 'form_apioauthauthorize',
|
||||
'class' => 'form_settings',
|
||||
'action' => common_local_url('apioauthauthorize')));
|
||||
'action' => common_local_url('ApiOauthAuthorize')));
|
||||
$this->elementStart('fieldset');
|
||||
$this->element('legend', array('id' => 'apioauthauthorize_allowdeny'),
|
||||
_('Allow or deny access'));
|
||||
|
@ -125,10 +125,10 @@ class ApiStatusesDestroyAction extends ApiAuthAction
|
||||
}
|
||||
|
||||
if ($this->user->id == $this->notice->profile_id) {
|
||||
$replies = new Reply;
|
||||
$replies->get('notice_id', $this->notice_id);
|
||||
$replies->delete();
|
||||
if (Event::handle('StartDeleteOwnNotice', array($this->user, $this->notice))) {
|
||||
$this->notice->delete();
|
||||
Event::handle('EndDeleteOwnNotice', array($this->user, $this->notice));
|
||||
}
|
||||
$this->showNotice();
|
||||
} else {
|
||||
$this->clientError(
|
||||
|
@ -62,6 +62,7 @@ class ApiStatusesRetweetAction extends ApiAuthAction
|
||||
parent::prepare($args);
|
||||
|
||||
if ($_SERVER['REQUEST_METHOD'] != 'POST') {
|
||||
// TRANS: Client error. POST is a HTTP command. It should not be translated.
|
||||
$this->clientError(_('This method requires a POST.'),
|
||||
400, $this->format);
|
||||
return false;
|
||||
|
@ -194,6 +194,7 @@ class ApiStatusesShowAction extends ApiPrivateAuthAction
|
||||
return '"' . implode(
|
||||
':',
|
||||
array($this->arg('action'),
|
||||
common_user_cache_hash($this->auth_user),
|
||||
common_language(),
|
||||
$this->notice->id,
|
||||
strtotime($this->notice->created))
|
||||
|
@ -195,6 +195,7 @@ class ApiStatusesUpdateAction extends ApiAuthAction
|
||||
|
||||
if ($_SERVER['REQUEST_METHOD'] != 'POST') {
|
||||
$this->clientError(
|
||||
// TRANS: Client error. POST is a HTTP command. It should not be translated.
|
||||
_('This method requires a POST.'),
|
||||
400,
|
||||
$this->format
|
||||
|
@ -181,6 +181,7 @@ class ApiSubscriptionsAction extends ApiBareAuthAction
|
||||
return '"' . implode(
|
||||
':',
|
||||
array($this->arg('action'),
|
||||
common_user_cache_hash($this->auth_user),
|
||||
common_language(),
|
||||
$this->user->id,
|
||||
isset($this->ids_only) ? 'IDs' : 'Profiles',
|
||||
|
@ -259,6 +259,7 @@ class ApiTimelineFavoritesAction extends ApiBareAuthAction
|
||||
return '"' . implode(
|
||||
':',
|
||||
array($this->arg('action'),
|
||||
common_user_cache_hash($this->auth_user),
|
||||
common_language(),
|
||||
$this->user->id,
|
||||
strtotime($this->notices[0]->created),
|
||||
|
@ -346,6 +346,7 @@ class ApiTimelineFriendsAction extends ApiBareAuthAction
|
||||
return '"' . implode(
|
||||
':',
|
||||
array($this->arg('action'),
|
||||
common_user_cache_hash($this->auth_user),
|
||||
common_language(),
|
||||
$this->user->id,
|
||||
strtotime($this->notices[0]->created),
|
||||
|
@ -229,6 +229,7 @@ class ApiTimelineGroupAction extends ApiPrivateAuthAction
|
||||
return '"' . implode(
|
||||
':',
|
||||
array($this->arg('action'),
|
||||
common_user_cache_hash($this->auth_user),
|
||||
common_language(),
|
||||
$this->group->id,
|
||||
strtotime($this->notices[0]->created),
|
||||
|
@ -254,6 +254,7 @@ class ApiTimelineHomeAction extends ApiBareAuthAction
|
||||
return '"' . implode(
|
||||
':',
|
||||
array($this->arg('action'),
|
||||
common_user_cache_hash($this->auth_user),
|
||||
common_language(),
|
||||
$this->user->id,
|
||||
strtotime($this->notices[0]->created),
|
||||
|
@ -244,6 +244,7 @@ class ApiTimelineMentionsAction extends ApiBareAuthAction
|
||||
return '"' . implode(
|
||||
':',
|
||||
array($this->arg('action'),
|
||||
common_user_cache_hash($this->auth_user),
|
||||
common_language(),
|
||||
$this->user->id,
|
||||
strtotime($this->notices[0]->created),
|
||||
|
@ -311,6 +311,7 @@ class ApiTimelinePublicAction extends ApiPrivateAuthAction
|
||||
return '"' . implode(
|
||||
':',
|
||||
array($this->arg('action'),
|
||||
common_user_cache_hash($this->auth_user),
|
||||
common_language(),
|
||||
strtotime($this->notices[0]->created),
|
||||
strtotime($this->notices[$last]->created))
|
||||
|
@ -232,6 +232,7 @@ class ApiTimelineTagAction extends ApiPrivateAuthAction
|
||||
return '"' . implode(
|
||||
':',
|
||||
array($this->arg('action'),
|
||||
common_user_cache_hash($this->auth_user),
|
||||
common_language(),
|
||||
$this->tag,
|
||||
strtotime($this->notices[0]->created),
|
||||
|
@ -234,6 +234,7 @@ class ApiTimelineUserAction extends ApiBareAuthAction
|
||||
return '"' . implode(
|
||||
':',
|
||||
array($this->arg('action'),
|
||||
common_user_cache_hash($this->auth_user),
|
||||
common_language(),
|
||||
$this->user->id,
|
||||
strtotime($this->notices[0]->created),
|
||||
|
@ -172,7 +172,10 @@ class DeletenoticeAction extends Action
|
||||
}
|
||||
|
||||
if ($this->arg('yes')) {
|
||||
if (Event::handle('StartDeleteOwnNotice', array($this->user, $this->notice))) {
|
||||
$this->notice->delete();
|
||||
Event::handle('EndDeleteOwnNotice', array($this->user, $this->notice));
|
||||
}
|
||||
}
|
||||
|
||||
$url = common_get_returnto();
|
||||
|
@ -71,7 +71,7 @@ class DesignadminpanelAction extends AdminPanelAction
|
||||
|
||||
function getInstructions()
|
||||
{
|
||||
return _('Design settings for this StatusNet site.');
|
||||
return _('Design settings for this StatusNet site');
|
||||
}
|
||||
|
||||
/**
|
||||
@ -154,9 +154,22 @@ class DesignadminpanelAction extends AdminPanelAction
|
||||
|
||||
$config->query('BEGIN');
|
||||
|
||||
// Only update colors if the theme has not changed.
|
||||
if ($themeChanged) {
|
||||
// If the theme has changed, reset custom colors and let them pick
|
||||
// up the new theme's defaults.
|
||||
$colors = array('background', 'content', 'sidebar', 'text', 'link');
|
||||
foreach ($colors as $colorKey) {
|
||||
// Clear from global config so we see defaults on this page...
|
||||
$GLOBALS['config']['design'][$colorKey . 'color'] = false;
|
||||
|
||||
if (!$themeChanged) {
|
||||
// And remove old settings from DB...
|
||||
$this->deleteSetting('design', $colorKey . 'color');
|
||||
}
|
||||
} else {
|
||||
// Only save colors from the form if the theme has not changed.
|
||||
//
|
||||
// @fixme a future more ajaxy form should allow theme switch
|
||||
// and color customization in one step.
|
||||
|
||||
$bgcolor = new WebColor($this->trimmed('design_background'));
|
||||
$ccolor = new WebColor($this->trimmed('design_content'));
|
||||
|
@ -188,7 +188,7 @@ class EditApplicationAction extends OwnerDesignAction
|
||||
} elseif (Oauth_application::descriptionTooLong($description)) {
|
||||
$this->showForm(sprintf(
|
||||
_('Description is too long (max %d chars).'),
|
||||
Oauth_application::maxDescription()));
|
||||
Oauth_application::maxDesc()));
|
||||
return;
|
||||
} elseif (mb_strlen($source_url) > 255) {
|
||||
$this->showForm(_('Source URL is too long.'));
|
||||
@ -253,7 +253,10 @@ class EditApplicationAction extends OwnerDesignAction
|
||||
|
||||
$result = $this->app->update($orig);
|
||||
|
||||
if (!$result) {
|
||||
// Note: 0 means no rows changed, which can happen if the only
|
||||
// thing we changed was the icon, since it's not altered until
|
||||
// the next step.
|
||||
if ($result === false) {
|
||||
common_log_db_error($this->app, 'UPDATE', __FILE__);
|
||||
$this->serverError(_('Could not update application.'));
|
||||
}
|
||||
|
@ -131,7 +131,11 @@ class EmailsettingsAction extends AccountSettingsAction
|
||||
// TRANS: Field label for e-mail address input in e-mail settings form.
|
||||
$this->input('email', _('Email address'),
|
||||
($this->arg('email')) ? $this->arg('email') : null,
|
||||
// TRANS: Instructions for e-mail address input form.
|
||||
// TRANS: Instructions for e-mail address input form. Do not translate
|
||||
// TRANS: "example.org". It is one of the domain names reserved for
|
||||
// TRANS: use in examples by http://www.rfc-editor.org/rfc/rfc2606.txt.
|
||||
// TRANS: Any other domain may be owned by a legitimate person or
|
||||
// TRANS: organization.
|
||||
_('Email address, like "UserName@example.org"'));
|
||||
$this->elementEnd('li');
|
||||
$this->elementEnd('ul');
|
||||
|
@ -129,9 +129,9 @@ class GetfileAction extends Action
|
||||
return null;
|
||||
}
|
||||
|
||||
$cache = common_memcache();
|
||||
$cache = Cache::instance();
|
||||
if($cache) {
|
||||
$key = common_cache_key('attachments:etag:' . $this->path);
|
||||
$key = Cache::key('attachments:etag:' . $this->path);
|
||||
$etag = $cache->get($key);
|
||||
if($etag === false) {
|
||||
$etag = crc32(file_get_contents($this->path));
|
||||
|
@ -97,9 +97,13 @@ class GroupmembersAction extends GroupDesignAction
|
||||
function title()
|
||||
{
|
||||
if ($this->page == 1) {
|
||||
// TRANS: Title of the page showing group members.
|
||||
// TRANS: %s is the name of the group.
|
||||
return sprintf(_('%s group members'),
|
||||
$this->group->nickname);
|
||||
} else {
|
||||
// TRANS: Title of the page showing group members.
|
||||
// TRANS: %1$s is the name of the group, %2$d is the page number of the members list.
|
||||
return sprintf(_('%1$s group members, page %2$d'),
|
||||
$this->group->nickname,
|
||||
$this->page);
|
||||
@ -389,7 +393,14 @@ class GroupBlockForm extends Form
|
||||
|
||||
function formActions()
|
||||
{
|
||||
$this->out->submit('submit', _('Block'), 'submit', null, _('Block this user'));
|
||||
$this->out->submit(
|
||||
'submit',
|
||||
// TRANS: Button text for the form that will block a user from a group.
|
||||
_m('BUTTON','Block'),
|
||||
'submit',
|
||||
null,
|
||||
// TRANS: Submit button title.
|
||||
_m('TOOLTIP', 'Block this user'));
|
||||
}
|
||||
}
|
||||
|
||||
@ -516,6 +527,13 @@ class MakeAdminForm extends Form
|
||||
|
||||
function formActions()
|
||||
{
|
||||
$this->out->submit('submit', _('Make Admin'), 'submit', null, _('Make this user an admin'));
|
||||
$this->out->submit(
|
||||
'submit',
|
||||
// TRANS: Button text for the form that will make a user administrator.
|
||||
_m('BUTTON','Make Admin'),
|
||||
'submit',
|
||||
null,
|
||||
// TRANS: Submit button title.
|
||||
_m('TOOLTIP','Make this user an admin'));
|
||||
}
|
||||
}
|
||||
|
@ -18,8 +18,10 @@
|
||||
*/
|
||||
|
||||
/**
|
||||
* @package OStatusPlugin
|
||||
* @category Action
|
||||
* @package StatusNet
|
||||
* @maintainer James Walker <james@status.net>
|
||||
* @author Craig Andrews <candrews@integralblue.com>
|
||||
*/
|
||||
|
||||
if (!defined('STATUSNET') && !defined('LACONICA')) { exit(1); }
|
||||
@ -27,19 +29,28 @@ if (!defined('STATUSNET') && !defined('LACONICA')) { exit(1); }
|
||||
class HostMetaAction extends Action
|
||||
{
|
||||
|
||||
/**
|
||||
* Is read only?
|
||||
*
|
||||
* @return boolean true
|
||||
*/
|
||||
function isReadOnly()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
function handle()
|
||||
{
|
||||
parent::handle();
|
||||
|
||||
$domain = common_config('site', 'server');
|
||||
$url = common_local_url('userxrd');
|
||||
$url.= '?uri={uri}';
|
||||
|
||||
$xrd = new XRD();
|
||||
$xrd->host = $domain;
|
||||
$xrd->links[] = array('rel' => Discovery::LRDD_REL,
|
||||
'template' => $url,
|
||||
'title' => array('Resource Descriptor'));
|
||||
|
||||
if(Event::handle('StartHostMetaLinks', array(&$xrd->links))) {
|
||||
Event::handle('EndHostMetaLinks', array(&$xrd->links));
|
||||
}
|
||||
|
||||
header('Content-type: application/xrd+xml');
|
||||
print $xrd->toXML();
|
@ -133,7 +133,7 @@ class ImsettingsAction extends ConnectSettingsAction
|
||||
'message with further instructions. '.
|
||||
'(Did you add %s to your buddy list?)'),
|
||||
$transport_info['display'],
|
||||
$transport_info['daemon_screenname']));
|
||||
$transport_info['daemonScreenname']));
|
||||
$this->hidden('screenname', $confirm->address);
|
||||
// TRANS: Button label to cancel an IM address confirmation procedure.
|
||||
$this->submit('cancel', _m('BUTTON','Cancel'));
|
||||
|
322
actions/licenseadminpanel.php
Normal file
322
actions/licenseadminpanel.php
Normal file
@ -0,0 +1,322 @@
|
||||
<?php
|
||||
/**
|
||||
* StatusNet, the distributed open-source microblogging tool
|
||||
*
|
||||
* License administration panel
|
||||
*
|
||||
* PHP version 5
|
||||
*
|
||||
* LICENCE: This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* @category Settings
|
||||
* @package StatusNet
|
||||
* @author Zach Copley <zach@status.net>
|
||||
* @copyright 2010 StatusNet, Inc.
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||
* @link http://status.net/
|
||||
*/
|
||||
|
||||
if (!defined('STATUSNET')) {
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/**
|
||||
* License settings
|
||||
*
|
||||
* @category Admin
|
||||
* @package StatusNet
|
||||
* @author Zach Copley <zach@status.net>
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||
* @link http://status.net/
|
||||
*/
|
||||
|
||||
class LicenseadminpanelAction extends AdminPanelAction
|
||||
{
|
||||
|
||||
/**
|
||||
* Returns the page title
|
||||
*
|
||||
* @return string page title
|
||||
*/
|
||||
|
||||
function title()
|
||||
{
|
||||
// TRANS: User admin panel title
|
||||
return _m('TITLE', 'License');
|
||||
}
|
||||
|
||||
/**
|
||||
* Instructions for using this form.
|
||||
*
|
||||
* @return string instructions
|
||||
*/
|
||||
|
||||
function getInstructions()
|
||||
{
|
||||
return _('License for this StatusNet site');
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the site admin panel form
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
|
||||
function showForm()
|
||||
{
|
||||
$form = new LicenseAdminPanelForm($this);
|
||||
$form->show();
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Save settings from the form
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
|
||||
function saveSettings()
|
||||
{
|
||||
static $settings = array(
|
||||
'license' => array('type', 'owner', 'url', 'title', 'image')
|
||||
);
|
||||
|
||||
$values = array();
|
||||
|
||||
foreach ($settings as $section => $parts) {
|
||||
foreach ($parts as $setting) {
|
||||
$values[$section][$setting] = $this->trimmed($setting);
|
||||
}
|
||||
}
|
||||
|
||||
// This throws an exception on validation errors
|
||||
|
||||
$this->validate($values);
|
||||
|
||||
// assert(all values are valid);
|
||||
|
||||
$config = new Config();
|
||||
|
||||
$config->query('BEGIN');
|
||||
|
||||
foreach ($settings as $section => $parts) {
|
||||
foreach ($parts as $setting) {
|
||||
Config::save($section, $setting, $values[$section][$setting]);
|
||||
}
|
||||
}
|
||||
|
||||
$config->query('COMMIT');
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate License admin form values
|
||||
*
|
||||
* @param array &$values from the form
|
||||
*
|
||||
* @return nothing
|
||||
*/
|
||||
|
||||
function validate(&$values)
|
||||
{
|
||||
// Validate license type (shouldn't have to do it, but just in case)
|
||||
|
||||
$types = array('private', 'allrightsreserved', 'cc');
|
||||
|
||||
if (!in_array($values['license']['type'], $types)) {
|
||||
$this->clientError(_("Invalid license selection."));
|
||||
}
|
||||
|
||||
// Make sure the user has set an owner if the site has a private
|
||||
// license
|
||||
|
||||
if ($values['license']['type'] == 'allrightsreserved'
|
||||
&& empty($values['license']['owner'])
|
||||
) {
|
||||
$this->clientError(
|
||||
_("You must specify the owner of the content when using the All Rights Reserved license.")
|
||||
);
|
||||
}
|
||||
|
||||
// Make sure the license title is not too long
|
||||
if (mb_strlen($values['license']['type']) > 255) {
|
||||
$this->clientError(
|
||||
_("Invalid license title. Max length is 255 characters.")
|
||||
);
|
||||
}
|
||||
|
||||
// make sure the license URL and license image URL are valid URLs
|
||||
|
||||
$options = array('allowed_schemes' => array('http', 'https'));
|
||||
|
||||
// URLs should be set for cc license
|
||||
|
||||
if ($values['license']['type'] == 'cc') {
|
||||
if (!Validate::uri($values['license']['url'], $options)) {
|
||||
$this->clientError(_("Invalid license URL."));
|
||||
}
|
||||
if (!Validate::uri($values['license']['image'], $options)) {
|
||||
$this->clientError(_("Invalid license image URL."));
|
||||
}
|
||||
}
|
||||
|
||||
// can be either blank or a valid URL for private & allrightsreserved
|
||||
|
||||
if (!empty($values['license']['url'])) {
|
||||
if (!Validate::uri($values['license']['url'], $options)) {
|
||||
$this->clientError(_("License URL must be blank or a valid URL."));
|
||||
}
|
||||
}
|
||||
|
||||
// can be either blank or a valid URL for private & allrightsreserved
|
||||
|
||||
if (!empty($values['license']['image'])) {
|
||||
if (!Validate::uri($values['license']['image'], $options)) {
|
||||
$this->clientError(_("License image must be blank or valid URL."));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class LicenseAdminPanelForm extends AdminForm
|
||||
{
|
||||
/**
|
||||
* ID of the form
|
||||
*
|
||||
* @return int ID of the form
|
||||
*/
|
||||
|
||||
function id()
|
||||
{
|
||||
return 'licenseadminpanel';
|
||||
}
|
||||
|
||||
/**
|
||||
* class of the form
|
||||
*
|
||||
* @return string class of the form
|
||||
*/
|
||||
|
||||
function formClass()
|
||||
{
|
||||
return 'form_settings';
|
||||
}
|
||||
|
||||
/**
|
||||
* Action of the form
|
||||
*
|
||||
* @return string URL of the action
|
||||
*/
|
||||
|
||||
function action()
|
||||
{
|
||||
return common_local_url('licenseadminpanel');
|
||||
}
|
||||
|
||||
/**
|
||||
* Data elements of the form
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
|
||||
function formData()
|
||||
{
|
||||
$this->out->elementStart(
|
||||
'fieldset', array('id' => 'settings_license-selection')
|
||||
);
|
||||
$this->out->element('legend', null, _('License selection'));
|
||||
$this->out->elementStart('ul', 'form_data');
|
||||
|
||||
$this->li();
|
||||
|
||||
$types = array(
|
||||
'private' => _('Private'),
|
||||
'allrightsreserved' => _('All Rights Reserved'),
|
||||
'cc' => _('Creative Commons')
|
||||
);
|
||||
|
||||
$this->out->dropdown(
|
||||
'type',
|
||||
_('Type'),
|
||||
$types,
|
||||
_('Select license'),
|
||||
false,
|
||||
$this->value('type', 'license')
|
||||
);
|
||||
|
||||
$this->unli();
|
||||
|
||||
$this->out->elementEnd('ul');
|
||||
$this->out->elementEnd('fieldset');
|
||||
|
||||
$this->out->elementStart(
|
||||
'fieldset',
|
||||
array('id' => 'settings_license-details')
|
||||
);
|
||||
$this->out->element('legend', null, _('License details'));
|
||||
$this->out->elementStart('ul', 'form_data');
|
||||
|
||||
$this->li();
|
||||
$this->input(
|
||||
'owner',
|
||||
_('Owner'),
|
||||
_('Name of the owner of the site\'s content (if applicable).'),
|
||||
'license'
|
||||
);
|
||||
$this->unli();
|
||||
|
||||
$this->li();
|
||||
$this->input(
|
||||
'title',
|
||||
_('License Title'),
|
||||
_('The title of the license.'),
|
||||
'license'
|
||||
);
|
||||
$this->unli();
|
||||
|
||||
$this->li();
|
||||
$this->input(
|
||||
'url',
|
||||
_('License URL'),
|
||||
_('URL for more information about the license.'),
|
||||
'license'
|
||||
);
|
||||
$this->unli();
|
||||
|
||||
$this->li();
|
||||
$this->input(
|
||||
'image', _('License Image URL'),
|
||||
_('URL for an image to display with the license.'),
|
||||
'license'
|
||||
);
|
||||
$this->unli();
|
||||
|
||||
$this->out->elementEnd('ul');
|
||||
$this->out->elementEnd('fieldset');
|
||||
}
|
||||
|
||||
/**
|
||||
* Action elements
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
|
||||
function formActions()
|
||||
{
|
||||
$this->out->submit(
|
||||
'submit', _('Save'), 'submit', null, _('Save license settings')
|
||||
);
|
||||
}
|
||||
}
|
@ -118,27 +118,10 @@ class LoginAction extends Action
|
||||
* @return void
|
||||
*/
|
||||
|
||||
function checkLogin($user_id=null, $token=null)
|
||||
function checkLogin($user_id=null)
|
||||
{
|
||||
// XXX: login throttle
|
||||
|
||||
// CSRF protection - token set in NoticeForm
|
||||
$token = $this->trimmed('token');
|
||||
if (!$token || $token != common_session_token()) {
|
||||
$st = common_session_token();
|
||||
if (empty($token)) {
|
||||
common_log(LOG_WARNING, 'No token provided by client.');
|
||||
} else if (empty($st)) {
|
||||
common_log(LOG_WARNING, 'No session token stored.');
|
||||
} else {
|
||||
common_log(LOG_WARNING, 'Token = ' . $token . ' and session token = ' . $st);
|
||||
}
|
||||
|
||||
$this->clientError(_('There was a problem with your session token. '.
|
||||
'Try again, please.'));
|
||||
return;
|
||||
}
|
||||
|
||||
$nickname = $this->trimmed('nickname');
|
||||
$password = $this->arg('password');
|
||||
|
||||
@ -261,7 +244,6 @@ class LoginAction extends Action
|
||||
$this->elementEnd('li');
|
||||
$this->elementEnd('ul');
|
||||
$this->submit('submit', _('Login'));
|
||||
$this->hidden('token', common_session_token());
|
||||
$this->elementEnd('fieldset');
|
||||
$this->elementEnd('form');
|
||||
$this->elementStart('p');
|
||||
|
@ -170,7 +170,7 @@ class NewApplicationAction extends OwnerDesignAction
|
||||
} elseif (Oauth_application::descriptionTooLong($description)) {
|
||||
$this->showForm(sprintf(
|
||||
_('Description is too long (max %d chars).'),
|
||||
Oauth_application::maxDescription()));
|
||||
Oauth_application::maxDesc()));
|
||||
return;
|
||||
} elseif (empty($source_url)) {
|
||||
$this->showForm(_('Source URL is required.'));
|
||||
|
@ -161,7 +161,7 @@ class NewnoticeAction extends Action
|
||||
|
||||
$replyto = intval($this->trimmed('inreplyto'));
|
||||
if ($replyto) {
|
||||
$options['replyto'] = $replyto;
|
||||
$options['reply_to'] = $replyto;
|
||||
}
|
||||
|
||||
$upload = null;
|
||||
@ -204,11 +204,19 @@ class NewnoticeAction extends Action
|
||||
$options = array_merge($options, $locOptions);
|
||||
}
|
||||
|
||||
$author_id = $user->id;
|
||||
$text = $content_shortened;
|
||||
|
||||
if (Event::handle('StartNoticeSaveWeb', array($this, &$author_id, &$text, &$options))) {
|
||||
|
||||
$notice = Notice::saveNew($user->id, $content_shortened, 'web', $options);
|
||||
|
||||
if (isset($upload)) {
|
||||
$upload->attachToNotice($notice);
|
||||
}
|
||||
|
||||
Event::handle('EndNoticeSaveWeb', array($this, $notice));
|
||||
}
|
||||
Event::handle('EndSaveNewNoticeWeb', array($this, $user, &$content_shortened, &$options));
|
||||
|
||||
if ($this->boolean('ajax')) {
|
||||
|
@ -80,7 +80,7 @@ class OauthconnectionssettingsAction extends ConnectSettingsAction
|
||||
|
||||
function getInstructions()
|
||||
{
|
||||
return _('You have allowed the following applications to access you account.');
|
||||
return _('You have allowed the following applications to access your account.');
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -67,7 +67,7 @@ class PathsadminpanelAction extends AdminPanelAction
|
||||
|
||||
function getInstructions()
|
||||
{
|
||||
return _('Path and server settings for this StatusNet site.');
|
||||
return _('Path and server settings for this StatusNet site');
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -62,7 +62,7 @@ class SessionsadminpanelAction extends AdminPanelAction
|
||||
|
||||
function getInstructions()
|
||||
{
|
||||
return _('Session settings for this StatusNet site.');
|
||||
return _('Session settings for this StatusNet site');
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -271,17 +271,17 @@ class ShowApplicationAction extends OwnerDesignAction
|
||||
|
||||
$this->elementStart('dl', 'entity_request_token_url');
|
||||
$this->element('dt', null, _('Request token URL'));
|
||||
$this->element('dd', null, common_local_url('apioauthrequesttoken'));
|
||||
$this->element('dd', null, common_local_url('ApiOauthRequestToken'));
|
||||
$this->elementEnd('dl');
|
||||
|
||||
$this->elementStart('dl', 'entity_access_token_url');
|
||||
$this->element('dt', null, _('Access token URL'));
|
||||
$this->element('dd', null, common_local_url('apioauthaccesstoken'));
|
||||
$this->element('dd', null, common_local_url('ApiOauthAccessToken'));
|
||||
$this->elementEnd('dl');
|
||||
|
||||
$this->elementStart('dl', 'entity_authorize_url');
|
||||
$this->element('dt', null, _('Authorize URL'));
|
||||
$this->element('dd', null, common_local_url('apioauthauthorize'));
|
||||
$this->element('dd', null, common_local_url('ApiOauthAuthorize'));
|
||||
$this->elementEnd('dl');
|
||||
|
||||
$this->element('p', 'note',
|
||||
|
@ -151,6 +151,7 @@ class ShownoticeAction extends OwnerDesignAction
|
||||
strtotime($this->avatar->modified) : 0;
|
||||
|
||||
return 'W/"' . implode(':', array($this->arg('action'),
|
||||
common_user_cache_hash(),
|
||||
common_language(),
|
||||
$this->notice->id,
|
||||
strtotime($this->notice->created),
|
||||
@ -291,6 +292,16 @@ class ShownoticeAction extends OwnerDesignAction
|
||||
array(),
|
||||
array('format'=>'xml','url'=>$this->notice->uri)),
|
||||
'title'=>'oEmbed'),null);
|
||||
|
||||
// Extras to aid in sharing notices to Facebook
|
||||
$avatar = $this->profile->getAvatar(AVATAR_PROFILE_SIZE);
|
||||
$avatarUrl = ($avatar) ?
|
||||
$avatar->displayUrl() :
|
||||
Avatar::defaultImage(AVATAR_PROFILE_SIZE);
|
||||
$this->element('meta', array('property' => 'og:image',
|
||||
'content' => $avatarUrl));
|
||||
$this->element('meta', array('property' => 'og:description',
|
||||
'content' => $this->notice->content));
|
||||
}
|
||||
}
|
||||
|
||||
@ -307,10 +318,14 @@ class SingleNoticeItem extends NoticeListItem
|
||||
function show()
|
||||
{
|
||||
$this->showStart();
|
||||
if (Event::handle('StartShowNoticeItem', array($this))) {
|
||||
$this->showNotice();
|
||||
$this->showNoticeAttachments();
|
||||
$this->showNoticeInfo();
|
||||
$this->showNoticeOptions();
|
||||
Event::handle('EndShowNoticeItem', array($this));
|
||||
}
|
||||
|
||||
$this->showEnd();
|
||||
}
|
||||
|
||||
|
@ -216,7 +216,10 @@ class ShowstreamAction extends ProfileAction
|
||||
? $this->user->getNotices(($this->page-1)*NOTICES_PER_PAGE, NOTICES_PER_PAGE + 1)
|
||||
: $this->user->getTaggedNotices($this->tag, ($this->page-1)*NOTICES_PER_PAGE, NOTICES_PER_PAGE + 1, 0, 0, null);
|
||||
|
||||
$pnl = null;
|
||||
if (Event::handle('ShowStreamNoticeList', array($notice, $this, &$pnl))) {
|
||||
$pnl = new ProfileNoticeList($notice, $this);
|
||||
}
|
||||
$cnt = $pnl->show();
|
||||
if (0 == $cnt) {
|
||||
$this->showEmptyListMessage();
|
||||
|
@ -12,6 +12,7 @@
|
||||
* (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.
|
||||
@ -24,7 +25,7 @@
|
||||
* @author Evan Prodromou <evan@status.net>
|
||||
* @author Zach Copley <zach@status.net>
|
||||
* @author Sarven Capadisli <csarven@status.net>
|
||||
* @copyright 2008-2009 StatusNet, Inc.
|
||||
* @copyright 2008-2010 StatusNet, Inc.
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||
* @link http://status.net/
|
||||
*/
|
||||
@ -67,7 +68,7 @@ class UseradminpanelAction extends AdminPanelAction
|
||||
|
||||
function getInstructions()
|
||||
{
|
||||
return _('User settings for this StatusNet site.');
|
||||
return _('User settings for this StatusNet site');
|
||||
}
|
||||
|
||||
/**
|
||||
@ -291,6 +292,6 @@ class UserAdminPanelForm extends AdminForm
|
||||
|
||||
function formActions()
|
||||
{
|
||||
$this->out->submit('submit', _('Save'), 'submit', null, _('Save site settings'));
|
||||
$this->out->submit('submit', _('Save'), 'submit', null, _('Save user settings'));
|
||||
}
|
||||
}
|
||||
|
@ -42,8 +42,9 @@ class Avatar extends Memcached_DataObject
|
||||
return Memcached_DataObject::pkeyGet('Avatar', $kv);
|
||||
}
|
||||
|
||||
// where should the avatar go for this user?
|
||||
|
||||
/**
|
||||
* Where should the avatar go for this user?
|
||||
*/
|
||||
static function filename($id, $extension, $size=null, $extra=null)
|
||||
{
|
||||
if ($size) {
|
||||
|
@ -58,7 +58,7 @@ class Config extends Memcached_DataObject
|
||||
$c = self::memcache();
|
||||
|
||||
if (!empty($c)) {
|
||||
$settings = $c->get(common_cache_key(self::settingsKey));
|
||||
$settings = $c->get(Cache::key(self::settingsKey));
|
||||
if ($settings !== false) {
|
||||
return $settings;
|
||||
}
|
||||
@ -77,7 +77,7 @@ class Config extends Memcached_DataObject
|
||||
$config->free();
|
||||
|
||||
if (!empty($c)) {
|
||||
$c->set(common_cache_key(self::settingsKey), $settings);
|
||||
$c->set(Cache::key(self::settingsKey), $settings);
|
||||
}
|
||||
|
||||
return $settings;
|
||||
@ -154,7 +154,7 @@ class Config extends Memcached_DataObject
|
||||
$c = self::memcache();
|
||||
|
||||
if (!empty($c)) {
|
||||
$c->delete(common_cache_key(self::settingsKey));
|
||||
$c->delete(Cache::key(self::settingsKey));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -65,5 +65,4 @@ class Consumer extends Memcached_DataObject
|
||||
$nonce->consumer_key = $this->consumer_key;
|
||||
$nonce->delete();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -74,6 +74,4 @@ class Conversation extends Memcached_DataObject
|
||||
|
||||
return $conv;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
@ -129,4 +129,32 @@ class Fave extends Memcached_DataObject
|
||||
|
||||
return $ids;
|
||||
}
|
||||
|
||||
function asActivity()
|
||||
{
|
||||
$notice = Notice::staticGet('id', $this->notice_id);
|
||||
$profile = Profile::staticGet('id', $this->user_id);
|
||||
|
||||
$act = new Activity();
|
||||
|
||||
$act->verb = ActivityVerb::FAVORITE;
|
||||
$act->id = TagURI::mint('favor:%d:%d:%s',
|
||||
$profile->id,
|
||||
$notice->id,
|
||||
common_date_iso8601($this->modified));
|
||||
|
||||
$act->time = strtotime($this->modified);
|
||||
// TRANS: Activity title when marking a notice as favorite.
|
||||
$act->title = _("Favor");
|
||||
// TRANS: Ntofication given when a user marks a notice as favorite.
|
||||
// TRANS: %1$s is a user nickname or full name, %2$s is a notice URI.
|
||||
$act->content = sprintf(_('%1$s marked notice %2$s as a favorite.'),
|
||||
$profile->getBestName(),
|
||||
$notice->uri);
|
||||
|
||||
$act->actor = ActivityObject::fromProfile($profile);
|
||||
$act->objects[] = ActivityObject::fromNotice($notice);
|
||||
|
||||
return $act;
|
||||
}
|
||||
}
|
||||
|
@ -29,7 +29,6 @@ require_once INSTALLDIR.'/classes/File_to_post.php';
|
||||
/**
|
||||
* Table Definition for file
|
||||
*/
|
||||
|
||||
class File extends Memcached_DataObject
|
||||
{
|
||||
###START_AUTOCODE
|
||||
|
@ -131,4 +131,3 @@ class File_oembed extends Memcached_DataObject
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -240,6 +240,14 @@ class File_redirection extends Memcached_DataObject
|
||||
} else if (is_string($redir_data)) {
|
||||
// The file is a known redirect target.
|
||||
$file = File::staticGet('url', $redir_data);
|
||||
if (empty($file)) {
|
||||
// @fixme should we save a new one?
|
||||
// this case was triggering sometimes for redirects
|
||||
// with unresolvable targets; found while fixing
|
||||
// "can't linkify" bugs with shortened links to
|
||||
// SSL sites with cert issues.
|
||||
return null;
|
||||
}
|
||||
$file_id = $file->id;
|
||||
}
|
||||
} else {
|
||||
@ -303,4 +311,3 @@ class File_redirection extends Memcached_DataObject
|
||||
$file_redir->insert();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -57,4 +57,3 @@ class File_thumbnail extends Memcached_DataObject
|
||||
$tn->insert();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -67,4 +67,3 @@ class File_to_post extends Memcached_DataObject
|
||||
return Memcached_DataObject::pkeyGet('File_to_post', $kv);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -44,7 +44,6 @@ class Foreign_link extends Memcached_DataObject
|
||||
$result = $flink->find(true);
|
||||
|
||||
return empty($result) ? null : $flink;
|
||||
|
||||
}
|
||||
|
||||
static function getByForeignID($foreign_id, $service)
|
||||
@ -129,5 +128,4 @@ class Foreign_link extends Memcached_DataObject
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -83,5 +83,4 @@ class Foreign_user extends Memcached_DataObject
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -111,5 +111,4 @@ class Group_block extends Memcached_DataObject
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,8 +1,8 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Table Definition for group_inbox
|
||||
*/
|
||||
|
||||
class Group_inbox extends Memcached_DataObject
|
||||
{
|
||||
###START_AUTOCODE
|
||||
|
@ -65,4 +65,59 @@ class Group_member extends Memcached_DataObject
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
function getMember()
|
||||
{
|
||||
$member = Profile::staticGet('id', $this->profile_id);
|
||||
|
||||
if (empty($member)) {
|
||||
// TRANS: Exception thrown providing an invalid profile ID.
|
||||
// TRANS: %s is the invalid profile ID.
|
||||
throw new Exception(sprintf(_("Profile ID %s is invalid."),$this->profile_id));
|
||||
}
|
||||
|
||||
return $member;
|
||||
}
|
||||
|
||||
function getGroup()
|
||||
{
|
||||
$group = User_group::staticGet('id', $this->group_id);
|
||||
|
||||
if (empty($group)) {
|
||||
// TRANS: Exception thrown providing an invalid group ID.
|
||||
// TRANS: %s is the invalid group ID.
|
||||
throw new Exception(sprintf(_("Group ID %s is invalid."),$this->group_id));
|
||||
}
|
||||
|
||||
return $group;
|
||||
}
|
||||
|
||||
function asActivity()
|
||||
{
|
||||
$member = $this->getMember();
|
||||
$group = $this->getGroup();
|
||||
|
||||
$act = new Activity();
|
||||
|
||||
$act->id = TagURI::mint('join:%d:%d:%s',
|
||||
$member->id,
|
||||
$group->id,
|
||||
common_date_iso8601($this->created));
|
||||
|
||||
$act->actor = ActivityObject::fromProfile($member);
|
||||
$act->verb = ActivityVerb::JOIN;
|
||||
$act->objects[] = ActivityObject::fromGroup($group);
|
||||
|
||||
$act->time = strtotime($this->created);
|
||||
// TRANS: Activity title.
|
||||
$act->title = _("Join");
|
||||
|
||||
// TRANS: Success message for subscribe to group attempt through OStatus.
|
||||
// TRANS: %1$s is the member name, %2$s is the subscribed group's name.
|
||||
$act->content = sprintf(_('%1$s has joined group %2$s.'),
|
||||
$member->getBestName(),
|
||||
$group->getBestName());
|
||||
|
||||
return $act;
|
||||
}
|
||||
}
|
||||
|
@ -55,7 +55,6 @@ class Inbox extends Memcached_DataObject
|
||||
/**
|
||||
* Create a new inbox from existing Notice_inbox stuff
|
||||
*/
|
||||
|
||||
static function initialize($user_id)
|
||||
{
|
||||
$inbox = Inbox::fromNoticeInbox($user_id);
|
||||
|
@ -124,7 +124,7 @@ class Memcached_DataObject extends Safe_DataObject
|
||||
}
|
||||
|
||||
static function memcache() {
|
||||
return common_memcache();
|
||||
return Cache::instance();
|
||||
}
|
||||
|
||||
static function cacheKey($cls, $k, $v) {
|
||||
@ -134,7 +134,7 @@ class Memcached_DataObject extends Safe_DataObject
|
||||
str_replace("\n", " ", $e->getTraceAsString()));
|
||||
}
|
||||
$vstr = self::valueString($v);
|
||||
return common_cache_key(strtolower($cls).':'.$k.':'.$vstr);
|
||||
return Cache::key(strtolower($cls).':'.$k.':'.$vstr);
|
||||
}
|
||||
|
||||
static function getcached($cls, $k, $v) {
|
||||
@ -302,8 +302,8 @@ class Memcached_DataObject extends Safe_DataObject
|
||||
$inst->query($qry);
|
||||
return $inst;
|
||||
}
|
||||
$key_part = common_keyize($cls).':'.md5($qry);
|
||||
$ckey = common_cache_key($key_part);
|
||||
$key_part = Cache::keyize($cls).':'.md5($qry);
|
||||
$ckey = Cache::key($key_part);
|
||||
$stored = $c->get($ckey);
|
||||
|
||||
if ($stored !== false) {
|
||||
@ -550,7 +550,7 @@ class Memcached_DataObject extends Safe_DataObject
|
||||
|
||||
$keyPart = vsprintf($format, $args);
|
||||
|
||||
$cacheKey = common_cache_key($keyPart);
|
||||
$cacheKey = Cache::key($keyPart);
|
||||
|
||||
return $c->delete($cacheKey);
|
||||
}
|
||||
@ -592,7 +592,7 @@ class Memcached_DataObject extends Safe_DataObject
|
||||
return false;
|
||||
}
|
||||
|
||||
$cacheKey = common_cache_key($keyPart);
|
||||
$cacheKey = Cache::key($keyPart);
|
||||
|
||||
return $c->get($cacheKey);
|
||||
}
|
||||
@ -605,7 +605,7 @@ class Memcached_DataObject extends Safe_DataObject
|
||||
return false;
|
||||
}
|
||||
|
||||
$cacheKey = common_cache_key($keyPart);
|
||||
$cacheKey = Cache::key($keyPart);
|
||||
|
||||
return $c->set($cacheKey, $value, $flag, $expiry);
|
||||
}
|
||||
@ -637,4 +637,3 @@ class Memcached_DataObject extends Safe_DataObject
|
||||
return $vstr;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -38,7 +38,6 @@ class Message extends Memcached_DataObject
|
||||
}
|
||||
|
||||
static function saveNew($from, $to, $content, $source) {
|
||||
|
||||
$sender = Profile::staticGet('id', $from);
|
||||
|
||||
if (!$sender->hasRight(Right::NEWMESSAGE)) {
|
||||
|
@ -36,5 +36,4 @@ class Nonce extends Memcached_DataObject
|
||||
{
|
||||
return array('consumer_key,token' => 'token:consumer_key,token');
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -121,6 +121,8 @@ class Notice extends Memcached_DataObject
|
||||
$deleted->insert();
|
||||
}
|
||||
|
||||
if (Event::handle('NoticeDeleteRelated', array($this))) {
|
||||
|
||||
// Clear related records
|
||||
|
||||
$this->clearReplies();
|
||||
@ -131,6 +133,7 @@ class Notice extends Memcached_DataObject
|
||||
|
||||
// NOTE: we don't clear inboxes
|
||||
// NOTE: we don't clear queue items
|
||||
}
|
||||
|
||||
$result = parent::delete();
|
||||
|
||||
@ -245,6 +248,8 @@ class Notice extends Memcached_DataObject
|
||||
if (!empty($options)) {
|
||||
$options = $options + $defaults;
|
||||
extract($options);
|
||||
} else {
|
||||
extract($defaults);
|
||||
}
|
||||
|
||||
if (!isset($is_local)) {
|
||||
@ -578,15 +583,17 @@ class Notice extends Memcached_DataObject
|
||||
if ($f2p->find()) {
|
||||
while ($f2p->fetch()) {
|
||||
$f = File::staticGet($f2p->file_id);
|
||||
if ($f) {
|
||||
$att[] = clone($f);
|
||||
}
|
||||
}
|
||||
}
|
||||
return $att;
|
||||
}
|
||||
|
||||
function getStreamByIds($ids)
|
||||
{
|
||||
$cache = common_memcache();
|
||||
$cache = Cache::instance();
|
||||
|
||||
if (!empty($cache)) {
|
||||
$notices = array();
|
||||
@ -738,6 +745,7 @@ class Notice extends Memcached_DataObject
|
||||
1,
|
||||
1
|
||||
);
|
||||
|
||||
if ($conversation->N > 0) {
|
||||
return true;
|
||||
}
|
||||
@ -746,15 +754,22 @@ class Notice extends Memcached_DataObject
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $groups array of Group *objects*
|
||||
* @param $recipients array of profile *ids*
|
||||
* Pull up a full list of local recipients who will be getting
|
||||
* this notice in their inbox. Results will be cached, so don't
|
||||
* change the input data wily-nilly!
|
||||
*
|
||||
* @param array $groups optional list of Group objects;
|
||||
* if left empty, will be loaded from group_inbox records
|
||||
* @param array $recipient optional list of reply profile ids
|
||||
* if left empty, will be loaded from reply records
|
||||
* @return array associating recipient user IDs with an inbox source constant
|
||||
*/
|
||||
function whoGets($groups=null, $recipients=null)
|
||||
{
|
||||
$c = self::memcache();
|
||||
|
||||
if (!empty($c)) {
|
||||
$ni = $c->get(common_cache_key('notice:who_gets:'.$this->id));
|
||||
$ni = $c->get(Cache::key('notice:who_gets:'.$this->id));
|
||||
if ($ni !== false) {
|
||||
return $ni;
|
||||
}
|
||||
@ -780,33 +795,33 @@ class Notice extends Memcached_DataObject
|
||||
$ni[$id] = NOTICE_INBOX_SOURCE_SUB;
|
||||
}
|
||||
|
||||
$profile = $this->getProfile();
|
||||
|
||||
foreach ($groups as $group) {
|
||||
$users = $group->getUserMembers();
|
||||
foreach ($users as $id) {
|
||||
if (!array_key_exists($id, $ni)) {
|
||||
$user = User::staticGet('id', $id);
|
||||
if (!$user->hasBlocked($profile)) {
|
||||
$ni[$id] = NOTICE_INBOX_SOURCE_GROUP;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($recipients as $recipient) {
|
||||
|
||||
if (!array_key_exists($recipient, $ni)) {
|
||||
$recipientUser = User::staticGet('id', $recipient);
|
||||
if (!empty($recipientUser)) {
|
||||
$ni[$recipient] = NOTICE_INBOX_SOURCE_REPLY;
|
||||
}
|
||||
}
|
||||
|
||||
// Exclude any deleted, non-local, or blocking recipients.
|
||||
$profile = $this->getProfile();
|
||||
foreach ($ni as $id => $source) {
|
||||
$user = User::staticGet('id', $id);
|
||||
if (empty($user) || $user->hasBlocked($profile)) {
|
||||
unset($ni[$id]);
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($c)) {
|
||||
// XXX: pack this data better
|
||||
$c->set(common_cache_key('notice:who_gets:'.$this->id), $ni);
|
||||
$c->set(Cache::key('notice:who_gets:'.$this->id), $ni);
|
||||
}
|
||||
|
||||
return $ni;
|
||||
@ -1014,26 +1029,32 @@ class Notice extends Memcached_DataObject
|
||||
if (empty($uris)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$sender = Profile::staticGet($this->profile_id);
|
||||
|
||||
foreach (array_unique($uris) as $uri) {
|
||||
|
||||
$user = User::staticGet('uri', $uri);
|
||||
$profile = Profile::fromURI($uri);
|
||||
|
||||
if (!empty($user)) {
|
||||
if ($user->hasBlocked($sender)) {
|
||||
if (empty($profile)) {
|
||||
common_log(LOG_WARNING, "Unable to determine profile for URI '$uri'");
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($profile->hasBlocked($sender)) {
|
||||
common_log(LOG_INFO, "Not saving reply to profile {$profile->id} ($uri) from sender {$sender->id} because of a block.");
|
||||
continue;
|
||||
}
|
||||
|
||||
$reply = new Reply();
|
||||
|
||||
$reply->notice_id = $this->id;
|
||||
$reply->profile_id = $user->id;
|
||||
common_log(LOG_INFO, __METHOD__ . ": saving reply: notice $this->id to profile $user->id");
|
||||
$reply->profile_id = $profile->id;
|
||||
|
||||
common_log(LOG_INFO, __METHOD__ . ": saving reply: notice $this->id to profile $profile->id");
|
||||
|
||||
$id = $reply->insert();
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
@ -1096,7 +1117,7 @@ class Notice extends Memcached_DataObject
|
||||
common_log_db_error($reply, 'INSERT', __FILE__);
|
||||
// TRANS: Server exception thrown when a reply cannot be saved.
|
||||
// TRANS: %1$d is a notice ID, %2$d is the ID of the mentioned user.
|
||||
throw new ServerException(sprintf(_("Could not save reply for %1$d, %2$d."), $this->id, $mentioned->id));
|
||||
throw new ServerException(sprintf(_('Could not save reply for %1$d, %2$d.'), $this->id, $mentioned->id));
|
||||
} else {
|
||||
$replied[$mentioned->id] = 1;
|
||||
self::blow('reply:stream:%d', $mentioned->id);
|
||||
@ -1199,6 +1220,64 @@ class Notice extends Memcached_DataObject
|
||||
return $groups;
|
||||
}
|
||||
|
||||
function asActivity()
|
||||
{
|
||||
$profile = $this->getProfile();
|
||||
|
||||
$act = new Activity();
|
||||
|
||||
$act->actor = ActivityObject::fromProfile($profile);
|
||||
$act->verb = ActivityVerb::POST;
|
||||
$act->objects[] = ActivityObject::fromNotice($this);
|
||||
|
||||
$act->time = strtotime($this->created);
|
||||
$act->link = $this->bestUrl();
|
||||
|
||||
$act->content = common_xml_safe_str($this->rendered);
|
||||
$act->id = $this->uri;
|
||||
$act->title = common_xml_safe_str($this->content);
|
||||
|
||||
$ctx = new ActivityContext();
|
||||
|
||||
if (!empty($this->reply_to)) {
|
||||
$reply = Notice::staticGet('id', $this->reply_to);
|
||||
if (!empty($reply)) {
|
||||
$ctx->replyToID = $reply->uri;
|
||||
$ctx->replyToUrl = $reply->bestUrl();
|
||||
}
|
||||
}
|
||||
|
||||
$ctx->location = $this->getLocation();
|
||||
|
||||
$conv = null;
|
||||
|
||||
if (!empty($this->conversation)) {
|
||||
$conv = Conversation::staticGet('id', $this->conversation);
|
||||
if (!empty($conv)) {
|
||||
$ctx->conversation = $conv->uri;
|
||||
}
|
||||
}
|
||||
|
||||
$reply_ids = $this->getReplies();
|
||||
|
||||
foreach ($reply_ids as $id) {
|
||||
$profile = Profile::staticGet('id', $id);
|
||||
if (!empty($profile)) {
|
||||
$ctx->attention[] = $profile->getUri();
|
||||
}
|
||||
}
|
||||
|
||||
$groups = $this->getGroups();
|
||||
|
||||
foreach ($groups as $group) {
|
||||
$ctx->attention[] = $group->uri;
|
||||
}
|
||||
|
||||
$act->context = $ctx;
|
||||
|
||||
return $act;
|
||||
}
|
||||
|
||||
// This has gotten way too long. Needs to be sliced up into functional bits
|
||||
// or ideally exported to a utility class.
|
||||
|
||||
@ -1227,13 +1306,10 @@ class Notice extends Memcached_DataObject
|
||||
}
|
||||
|
||||
if (Event::handle('StartActivitySource', array(&$this, &$xs))) {
|
||||
|
||||
if ($source) {
|
||||
|
||||
$atom_feed = $profile->getAtomFeed();
|
||||
|
||||
if (!empty($atom_feed)) {
|
||||
|
||||
$xs->elementStart('source');
|
||||
|
||||
// XXX: we should store the actual feed ID
|
||||
@ -1574,7 +1650,7 @@ class Notice extends Memcached_DataObject
|
||||
|
||||
function stream($fn, $args, $cachekey, $offset=0, $limit=20, $since_id=0, $max_id=0)
|
||||
{
|
||||
$cache = common_memcache();
|
||||
$cache = Cache::instance();
|
||||
|
||||
if (empty($cache) ||
|
||||
$since_id != 0 || $max_id != 0 ||
|
||||
@ -1584,7 +1660,7 @@ class Notice extends Memcached_DataObject
|
||||
$max_id)));
|
||||
}
|
||||
|
||||
$idkey = common_cache_key($cachekey);
|
||||
$idkey = Cache::key($cachekey);
|
||||
|
||||
$idstr = $cache->get($idkey);
|
||||
|
||||
@ -1766,17 +1842,17 @@ class Notice extends Memcached_DataObject
|
||||
|
||||
function repeatStream($limit=100)
|
||||
{
|
||||
$cache = common_memcache();
|
||||
$cache = Cache::instance();
|
||||
|
||||
if (empty($cache)) {
|
||||
$ids = $this->_repeatStreamDirect($limit);
|
||||
} else {
|
||||
$idstr = $cache->get(common_cache_key('notice:repeats:'.$this->id));
|
||||
$idstr = $cache->get(Cache::key('notice:repeats:'.$this->id));
|
||||
if ($idstr !== false) {
|
||||
$ids = explode(',', $idstr);
|
||||
} else {
|
||||
$ids = $this->_repeatStreamDirect(100);
|
||||
$cache->set(common_cache_key('notice:repeats:'.$this->id), implode(',', $ids));
|
||||
$cache->set(Cache::key('notice:repeats:'.$this->id), implode(',', $ids));
|
||||
}
|
||||
if ($limit < 100) {
|
||||
// We do a max of 100, so slice down to limit
|
||||
@ -1821,7 +1897,6 @@ class Notice extends Memcached_DataObject
|
||||
$options = array();
|
||||
|
||||
if (!empty($location_id) && !empty($location_ns)) {
|
||||
|
||||
$options['location_id'] = $location_id;
|
||||
$options['location_ns'] = $location_ns;
|
||||
|
||||
@ -1833,7 +1908,6 @@ class Notice extends Memcached_DataObject
|
||||
}
|
||||
|
||||
} else if (!empty($lat) && !empty($lon)) {
|
||||
|
||||
$options['lat'] = $lat;
|
||||
$options['lon'] = $lon;
|
||||
|
||||
@ -1844,7 +1918,6 @@ class Notice extends Memcached_DataObject
|
||||
$options['location_ns'] = $location->location_ns;
|
||||
}
|
||||
} else if (!empty($profile)) {
|
||||
|
||||
if (isset($profile->lat) && isset($profile->lon)) {
|
||||
$options['lat'] = $profile->lat;
|
||||
$options['lon'] = $profile->lon;
|
||||
@ -1930,10 +2003,10 @@ class Notice extends Memcached_DataObject
|
||||
|
||||
if ($tag->find()) {
|
||||
while ($tag->fetch()) {
|
||||
self::blow('profile:notice_ids_tagged:%d:%s', $this->profile_id, common_keyize($tag->tag));
|
||||
self::blow('profile:notice_ids_tagged:%d:%s;last', $this->profile_id, common_keyize($tag->tag));
|
||||
self::blow('notice_tag:notice_ids:%s', common_keyize($tag->tag));
|
||||
self::blow('notice_tag:notice_ids:%s;last', common_keyize($tag->tag));
|
||||
self::blow('profile:notice_ids_tagged:%d:%s', $this->profile_id, Cache::keyize($tag->tag));
|
||||
self::blow('profile:notice_ids_tagged:%d:%s;last', $this->profile_id, Cache::keyize($tag->tag));
|
||||
self::blow('notice_tag:notice_ids:%s', Cache::keyize($tag->tag));
|
||||
self::blow('notice_tag:notice_ids:%s;last', Cache::keyize($tag->tag));
|
||||
$tag->delete();
|
||||
}
|
||||
}
|
||||
@ -1961,6 +2034,7 @@ class Notice extends Memcached_DataObject
|
||||
{
|
||||
// We always insert for the author so they don't
|
||||
// have to wait
|
||||
Event::handle('StartNoticeDistribute', array($this));
|
||||
|
||||
$user = User::staticGet('id', $this->profile_id);
|
||||
if (!empty($user)) {
|
||||
|
@ -40,7 +40,7 @@ class Notice_tag extends Memcached_DataObject
|
||||
|
||||
$ids = Notice::stream(array('Notice_tag', '_streamDirect'),
|
||||
array($tag),
|
||||
'notice_tag:notice_ids:' . common_keyize($tag),
|
||||
'notice_tag:notice_ids:' . Cache::keyize($tag),
|
||||
$offset, $limit);
|
||||
|
||||
return Notice::getStreamByIds($ids);
|
||||
@ -82,9 +82,9 @@ class Notice_tag extends Memcached_DataObject
|
||||
|
||||
function blowCache($blowLast=false)
|
||||
{
|
||||
self::blow('notice_tag:notice_ids:%s', common_keyize($this->tag));
|
||||
self::blow('notice_tag:notice_ids:%s', Cache::keyize($this->tag));
|
||||
if ($blowLast) {
|
||||
self::blow('notice_tag:notice_ids:%s;last', common_keyize($this->tag));
|
||||
self::blow('notice_tag:notice_ids:%s;last', Cache::keyize($this->tag));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -110,7 +110,6 @@ class Oauth_application extends Memcached_DataObject
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
|
||||
function uploadLogo()
|
||||
{
|
||||
if ($_FILES['app_icon']['error'] ==
|
||||
@ -153,5 +152,4 @@ class Oauth_application extends Memcached_DataObject
|
||||
$oauser->application_id = $this->id;
|
||||
$oauser->delete();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -40,5 +40,4 @@ class Oauth_application_user extends Memcached_DataObject
|
||||
|
||||
return empty($result) ? null : $oau;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -103,7 +103,6 @@ class Profile extends Memcached_DataObject
|
||||
foreach (array(AVATAR_PROFILE_SIZE, AVATAR_STREAM_SIZE, AVATAR_MINI_SIZE) as $size) {
|
||||
# We don't do a scaled one if original is our scaled size
|
||||
if (!($avatar->width == $size && $avatar->height == $size)) {
|
||||
|
||||
$scaled_filename = $imagefile->resize($size);
|
||||
|
||||
//$scaled = DB_DataObject::factory('avatar');
|
||||
@ -429,10 +428,10 @@ class Profile extends Memcached_DataObject
|
||||
|
||||
function subscriptionCount()
|
||||
{
|
||||
$c = common_memcache();
|
||||
$c = Cache::instance();
|
||||
|
||||
if (!empty($c)) {
|
||||
$cnt = $c->get(common_cache_key('profile:subscription_count:'.$this->id));
|
||||
$cnt = $c->get(Cache::key('profile:subscription_count:'.$this->id));
|
||||
if (is_integer($cnt)) {
|
||||
return (int) $cnt;
|
||||
}
|
||||
@ -446,7 +445,7 @@ class Profile extends Memcached_DataObject
|
||||
$cnt = ($cnt > 0) ? $cnt - 1 : $cnt;
|
||||
|
||||
if (!empty($c)) {
|
||||
$c->set(common_cache_key('profile:subscription_count:'.$this->id), $cnt);
|
||||
$c->set(Cache::key('profile:subscription_count:'.$this->id), $cnt);
|
||||
}
|
||||
|
||||
return $cnt;
|
||||
@ -454,9 +453,9 @@ class Profile extends Memcached_DataObject
|
||||
|
||||
function subscriberCount()
|
||||
{
|
||||
$c = common_memcache();
|
||||
$c = Cache::instance();
|
||||
if (!empty($c)) {
|
||||
$cnt = $c->get(common_cache_key('profile:subscriber_count:'.$this->id));
|
||||
$cnt = $c->get(Cache::key('profile:subscriber_count:'.$this->id));
|
||||
if (is_integer($cnt)) {
|
||||
return (int) $cnt;
|
||||
}
|
||||
@ -468,17 +467,52 @@ class Profile extends Memcached_DataObject
|
||||
$cnt = (int) $sub->count('distinct subscriber');
|
||||
|
||||
if (!empty($c)) {
|
||||
$c->set(common_cache_key('profile:subscriber_count:'.$this->id), $cnt);
|
||||
$c->set(Cache::key('profile:subscriber_count:'.$this->id), $cnt);
|
||||
}
|
||||
|
||||
return $cnt;
|
||||
}
|
||||
|
||||
function hasFave($notice)
|
||||
{
|
||||
$cache = Cache::instance();
|
||||
|
||||
// XXX: Kind of a hack.
|
||||
|
||||
if (!empty($cache)) {
|
||||
// This is the stream of favorite notices, in rev chron
|
||||
// order. This forces it into cache.
|
||||
|
||||
$ids = Fave::stream($this->id, 0, NOTICE_CACHE_WINDOW);
|
||||
|
||||
// If it's in the list, then it's a fave
|
||||
|
||||
if (in_array($notice->id, $ids)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// If we're not past the end of the cache window,
|
||||
// then the cache has all available faves, so this one
|
||||
// is not a fave.
|
||||
|
||||
if (count($ids) < NOTICE_CACHE_WINDOW) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Otherwise, cache doesn't have all faves;
|
||||
// fall through to the default
|
||||
}
|
||||
|
||||
$fave = Fave::pkeyGet(array('user_id' => $this->id,
|
||||
'notice_id' => $notice->id));
|
||||
return ((is_null($fave)) ? false : true);
|
||||
}
|
||||
|
||||
function faveCount()
|
||||
{
|
||||
$c = common_memcache();
|
||||
$c = Cache::instance();
|
||||
if (!empty($c)) {
|
||||
$cnt = $c->get(common_cache_key('profile:fave_count:'.$this->id));
|
||||
$cnt = $c->get(Cache::key('profile:fave_count:'.$this->id));
|
||||
if (is_integer($cnt)) {
|
||||
return (int) $cnt;
|
||||
}
|
||||
@ -489,7 +523,7 @@ class Profile extends Memcached_DataObject
|
||||
$cnt = (int) $faves->count('distinct notice_id');
|
||||
|
||||
if (!empty($c)) {
|
||||
$c->set(common_cache_key('profile:fave_count:'.$this->id), $cnt);
|
||||
$c->set(Cache::key('profile:fave_count:'.$this->id), $cnt);
|
||||
}
|
||||
|
||||
return $cnt;
|
||||
@ -497,10 +531,10 @@ class Profile extends Memcached_DataObject
|
||||
|
||||
function noticeCount()
|
||||
{
|
||||
$c = common_memcache();
|
||||
$c = Cache::instance();
|
||||
|
||||
if (!empty($c)) {
|
||||
$cnt = $c->get(common_cache_key('profile:notice_count:'.$this->id));
|
||||
$cnt = $c->get(Cache::key('profile:notice_count:'.$this->id));
|
||||
if (is_integer($cnt)) {
|
||||
return (int) $cnt;
|
||||
}
|
||||
@ -511,41 +545,55 @@ class Profile extends Memcached_DataObject
|
||||
$cnt = (int) $notices->count('distinct id');
|
||||
|
||||
if (!empty($c)) {
|
||||
$c->set(common_cache_key('profile:notice_count:'.$this->id), $cnt);
|
||||
$c->set(Cache::key('profile:notice_count:'.$this->id), $cnt);
|
||||
}
|
||||
|
||||
return $cnt;
|
||||
}
|
||||
|
||||
function blowFavesCache()
|
||||
{
|
||||
$cache = common_memcache();
|
||||
if ($cache) {
|
||||
// Faves don't happen chronologically, so we need to blow
|
||||
// ;last cache, too
|
||||
$cache->delete(common_cache_key('fave:ids_by_user:'.$this->id));
|
||||
$cache->delete(common_cache_key('fave:ids_by_user:'.$this->id.';last'));
|
||||
$cache->delete(common_cache_key('fave:ids_by_user_own:'.$this->id));
|
||||
$cache->delete(common_cache_key('fave:ids_by_user_own:'.$this->id.';last'));
|
||||
}
|
||||
$this->blowFaveCount();
|
||||
}
|
||||
|
||||
function blowSubscriberCount()
|
||||
{
|
||||
$c = common_memcache();
|
||||
$c = Cache::instance();
|
||||
if (!empty($c)) {
|
||||
$c->delete(common_cache_key('profile:subscriber_count:'.$this->id));
|
||||
$c->delete(Cache::key('profile:subscriber_count:'.$this->id));
|
||||
}
|
||||
}
|
||||
|
||||
function blowSubscriptionCount()
|
||||
{
|
||||
$c = common_memcache();
|
||||
$c = Cache::instance();
|
||||
if (!empty($c)) {
|
||||
$c->delete(common_cache_key('profile:subscription_count:'.$this->id));
|
||||
$c->delete(Cache::key('profile:subscription_count:'.$this->id));
|
||||
}
|
||||
}
|
||||
|
||||
function blowFaveCount()
|
||||
{
|
||||
$c = common_memcache();
|
||||
$c = Cache::instance();
|
||||
if (!empty($c)) {
|
||||
$c->delete(common_cache_key('profile:fave_count:'.$this->id));
|
||||
$c->delete(Cache::key('profile:fave_count:'.$this->id));
|
||||
}
|
||||
}
|
||||
|
||||
function blowNoticeCount()
|
||||
{
|
||||
$c = common_memcache();
|
||||
$c = Cache::instance();
|
||||
if (!empty($c)) {
|
||||
$c->delete(common_cache_key('profile:notice_count:'.$this->id));
|
||||
$c->delete(Cache::key('profile:notice_count:'.$this->id));
|
||||
}
|
||||
}
|
||||
|
||||
@ -790,13 +838,14 @@ class Profile extends Memcached_DataObject
|
||||
* @param $right string Name of the right, usually a constant in class Right
|
||||
* @return boolean whether the user has the right in question
|
||||
*/
|
||||
|
||||
function hasRight($right)
|
||||
{
|
||||
$result = false;
|
||||
|
||||
if ($this->hasRole(Profile_role::DELETED)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (Event::handle('UserRightsCheck', array($this, $right, &$result))) {
|
||||
switch ($right)
|
||||
{
|
||||
@ -960,4 +1009,25 @@ class Profile extends Memcached_DataObject
|
||||
|
||||
return $feed;
|
||||
}
|
||||
|
||||
static function fromURI($uri)
|
||||
{
|
||||
$profile = null;
|
||||
|
||||
if (Event::handle('StartGetProfileFromURI', array($uri, &$profile))) {
|
||||
// Get a local user or remote (OMB 0.1) profile
|
||||
$user = User::staticGet('uri', $uri);
|
||||
if (!empty($user)) {
|
||||
$profile = $user->getProfile();
|
||||
} else {
|
||||
$remote_profile = Remote_profile::staticGet('uri', $uri);
|
||||
if (!empty($remote_profile)) {
|
||||
$profile = Profile::staticGet('id', $remote_profile->profile_id);
|
||||
}
|
||||
}
|
||||
Event::handle('EndGetProfileFromURI', array($uri, $profile));
|
||||
}
|
||||
|
||||
return $profile;
|
||||
}
|
||||
}
|
||||
|
@ -23,7 +23,6 @@ class Profile_tag extends Memcached_DataObject
|
||||
###END_AUTOCODE
|
||||
|
||||
static function getTags($tagger, $tagged) {
|
||||
|
||||
$tags = array();
|
||||
|
||||
# XXX: store this in memcached
|
||||
@ -44,7 +43,6 @@ class Profile_tag extends Memcached_DataObject
|
||||
}
|
||||
|
||||
static function setTags($tagger, $tagged, $newtags) {
|
||||
|
||||
$newtags = array_unique($newtags);
|
||||
$oldtags = Profile_tag::getTags($tagger, $tagged);
|
||||
|
||||
|
@ -16,11 +16,15 @@ class Remember_me extends Memcached_DataObject
|
||||
|
||||
/* Static get */
|
||||
function staticGet($k,$v=null)
|
||||
{ return Memcached_DataObject::staticGet('Remember_me',$k,$v); }
|
||||
{
|
||||
return Memcached_DataObject::staticGet('Remember_me',$k,$v);
|
||||
}
|
||||
|
||||
/* the code above is auto generated do not remove the tag below */
|
||||
###END_AUTOCODE
|
||||
|
||||
function sequenceKey()
|
||||
{ return array(false, false); }
|
||||
{
|
||||
return array(false, false);
|
||||
}
|
||||
}
|
||||
|
@ -287,4 +287,3 @@ class Safe_DataObject extends DB_DataObject
|
||||
return Safe_DataObject::$iniCache[$key];
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -167,9 +167,8 @@ class Status_network extends Safe_DataObject
|
||||
' WHERE nickname = ' . $this->_quote($this->nickname);
|
||||
$orig->decache();
|
||||
$result = $this->query($qry);
|
||||
if ($result) {
|
||||
$this->encache();
|
||||
}
|
||||
$this->decache();
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
@ -308,15 +307,7 @@ class Status_network extends Safe_DataObject
|
||||
*/
|
||||
function getTags()
|
||||
{
|
||||
$result = array();
|
||||
|
||||
$tags = new Status_network_tag();
|
||||
$tags->site_id = $this->site_id;
|
||||
if ($tags->find()) {
|
||||
while ($tags->fetch()) {
|
||||
$result[] = $tags->tag;
|
||||
}
|
||||
}
|
||||
$result = Status_network_tag::getTags($this->site_id);
|
||||
|
||||
// XXX : for backwards compatibility
|
||||
if (empty($result)) {
|
||||
@ -329,6 +320,7 @@ class Status_network extends Safe_DataObject
|
||||
/**
|
||||
* Save a given set of tags
|
||||
* @param array tags
|
||||
* @fixme only add/remove differentials
|
||||
*/
|
||||
function setTags($tags)
|
||||
{
|
||||
|
@ -61,9 +61,73 @@ class Status_network_tag extends Safe_DataObject
|
||||
###END_AUTOCODE
|
||||
|
||||
|
||||
|
||||
function pkeyGet($kv)
|
||||
{
|
||||
return Memcached_DataObject::pkeyGet('Status_network_tag', $kv);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch the (possibly cached) tag entries for the given site id.
|
||||
* Uses status_network's cache settings.
|
||||
*
|
||||
* @param string $site_id
|
||||
* @return array of strings
|
||||
*/
|
||||
static function getTags($site_id)
|
||||
{
|
||||
$key = 'status_network_tags:' . $site_id;
|
||||
if (Status_network::$cache) {
|
||||
$packed = Status_network::$cache->get($key);
|
||||
if (is_string($packed)) {
|
||||
if ($packed == '') {
|
||||
return array();
|
||||
} else {
|
||||
return explode('|', $packed);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$result = array();
|
||||
|
||||
$tags = new Status_network_tag();
|
||||
$tags->site_id = $site_id;
|
||||
if ($tags->find()) {
|
||||
while ($tags->fetch()) {
|
||||
$result[] = $tags->tag;
|
||||
}
|
||||
}
|
||||
|
||||
if (Status_network::$cache) {
|
||||
$packed = implode('|', $result);
|
||||
Status_network::$cache->set($key, $packed, 3600);
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Drop the cached tag entries for this site.
|
||||
* Needed after inserting/deleting a tag entry.
|
||||
*/
|
||||
function decache()
|
||||
{
|
||||
$key = 'status_network_tags:' . $this->site_id;
|
||||
if (Status_network::$cache) {
|
||||
Status_network::$cache->delete($key);
|
||||
}
|
||||
}
|
||||
|
||||
function insert()
|
||||
{
|
||||
$ret = parent::insert();
|
||||
$this->decache();
|
||||
return $ret;
|
||||
}
|
||||
|
||||
function delete()
|
||||
{
|
||||
$ret = parent::delete();
|
||||
$this->decache();
|
||||
return $ret;
|
||||
}
|
||||
}
|
||||
|
@ -235,4 +235,33 @@ class Subscription extends Memcached_DataObject
|
||||
'subscribed' => $other->id));
|
||||
return (empty($sub)) ? false : true;
|
||||
}
|
||||
|
||||
function asActivity()
|
||||
{
|
||||
$subscriber = Profile::staticGet('id', $this->subscriber);
|
||||
$subscribed = Profile::staticGet('id', $this->subscribed);
|
||||
|
||||
$act = new Activity();
|
||||
|
||||
$act->verb = ActivityVerb::FOLLOW;
|
||||
|
||||
$act->id = TagURI::mint('follow:%d:%d:%s',
|
||||
$subscriber->id,
|
||||
$subscribed->id,
|
||||
common_date_iso8601($this->created));
|
||||
|
||||
$act->time = strtotime($this->created);
|
||||
// TRANS: Activity tile when subscribing to another person.
|
||||
$act->title = _("Follow");
|
||||
// TRANS: Notification given when one person starts following another.
|
||||
// TRANS: %1$s is the subscriber, %2$s is the subscribed.
|
||||
$act->content = sprintf(_('%1$s is now following %2$s.'),
|
||||
$subscriber->getBestName(),
|
||||
$subscribed->getBestName());
|
||||
|
||||
$act->actor = ActivityObject::fromProfile($subscriber);
|
||||
$act->objects[] = ActivityObject::fromProfile($subscribed);
|
||||
|
||||
return $act;
|
||||
}
|
||||
}
|
||||
|
@ -250,6 +250,19 @@ class User extends Memcached_DataObject
|
||||
|
||||
$user->inboxed = 1;
|
||||
|
||||
// Set default-on options here, otherwise they'll be disabled
|
||||
// initially for sites using caching, since the initial encache
|
||||
// doesn't know about the defaults in the database.
|
||||
$user->emailnotifysub = 1;
|
||||
$user->emailnotifyfav = 1;
|
||||
$user->emailnotifynudge = 1;
|
||||
$user->emailnotifymsg = 1;
|
||||
$user->emailnotifyattn = 1;
|
||||
$user->emailmicroid = 1;
|
||||
$user->emailpost = 1;
|
||||
$user->jabbermicroid = 1;
|
||||
$user->viewdesigns = 1;
|
||||
|
||||
$user->created = common_sql_now();
|
||||
|
||||
if (Event::handle('StartUserRegister', array(&$user, &$profile))) {
|
||||
@ -264,7 +277,13 @@ class User extends Memcached_DataObject
|
||||
}
|
||||
|
||||
$user->id = $id;
|
||||
|
||||
if (!empty($uri)) {
|
||||
$user->uri = $uri;
|
||||
} else {
|
||||
$user->uri = common_user_uri($user);
|
||||
}
|
||||
|
||||
if (!empty($password)) { // may not have a password for OpenID users
|
||||
$user->password = common_munge_password($password, $id);
|
||||
}
|
||||
@ -388,37 +407,8 @@ class User extends Memcached_DataObject
|
||||
|
||||
function hasFave($notice)
|
||||
{
|
||||
$cache = common_memcache();
|
||||
|
||||
// XXX: Kind of a hack.
|
||||
|
||||
if ($cache) {
|
||||
// This is the stream of favorite notices, in rev chron
|
||||
// order. This forces it into cache.
|
||||
|
||||
$ids = Fave::stream($this->id, 0, NOTICE_CACHE_WINDOW);
|
||||
|
||||
// If it's in the list, then it's a fave
|
||||
|
||||
if (in_array($notice->id, $ids)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// If we're not past the end of the cache window,
|
||||
// then the cache has all available faves, so this one
|
||||
// is not a fave.
|
||||
|
||||
if (count($ids) < NOTICE_CACHE_WINDOW) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Otherwise, cache doesn't have all faves;
|
||||
// fall through to the default
|
||||
}
|
||||
|
||||
$fave = Fave::pkeyGet(array('user_id' => $this->id,
|
||||
'notice_id' => $notice->id));
|
||||
return ((is_null($fave)) ? false : true);
|
||||
$profile = $this->getProfile();
|
||||
return $profile->hasFave($notice);
|
||||
}
|
||||
|
||||
function mutuallySubscribed($other)
|
||||
@ -487,17 +477,8 @@ class User extends Memcached_DataObject
|
||||
|
||||
function blowFavesCache()
|
||||
{
|
||||
$cache = common_memcache();
|
||||
if ($cache) {
|
||||
// Faves don't happen chronologically, so we need to blow
|
||||
// ;last cache, too
|
||||
$cache->delete(common_cache_key('fave:ids_by_user:'.$this->id));
|
||||
$cache->delete(common_cache_key('fave:ids_by_user:'.$this->id.';last'));
|
||||
$cache->delete(common_cache_key('fave:ids_by_user_own:'.$this->id));
|
||||
$cache->delete(common_cache_key('fave:ids_by_user_own:'.$this->id.';last'));
|
||||
}
|
||||
$profile = $this->getProfile();
|
||||
$profile->blowFaveCount();
|
||||
$profile->blowFavesCache();
|
||||
}
|
||||
|
||||
function getSelfTags()
|
||||
@ -547,6 +528,9 @@ class User extends Memcached_DataObject
|
||||
if (Subscription::exists($other, $self)) {
|
||||
Subscription::cancel($other, $self);
|
||||
}
|
||||
if (Subscription::exists($self, $other)) {
|
||||
Subscription::cancel($self, $other);
|
||||
}
|
||||
|
||||
$block->query('COMMIT');
|
||||
|
||||
|
@ -465,7 +465,6 @@ class User_group extends Memcached_DataObject
|
||||
}
|
||||
|
||||
static function register($fields) {
|
||||
|
||||
// MAGICALLY put fields into current scope
|
||||
|
||||
extract($fields);
|
||||
|
@ -18,7 +18,9 @@ class User_username extends Memcached_DataObject
|
||||
|
||||
/* Static get */
|
||||
function staticGet($k,$v=null)
|
||||
{ return Memcached_DataObject::staticGet('User_username',$k,$v); }
|
||||
{
|
||||
return Memcached_DataObject::staticGet('User_username',$k,$v);
|
||||
}
|
||||
|
||||
/* the code above is auto generated do not remove the tag below */
|
||||
###END_AUTOCODE
|
||||
@ -37,6 +39,7 @@ class User_username extends Memcached_DataObject
|
||||
$user_username->provider_name = $provider_name;
|
||||
$user_username->username = $username;
|
||||
$user_username->created = DB_DataObject_Cast::dateTime();
|
||||
|
||||
if($user_username->insert()){
|
||||
return $user_username;
|
||||
}else{
|
||||
@ -57,5 +60,4 @@ class User_username extends Memcached_DataObject
|
||||
function keys() {
|
||||
return array('provider_name' => 'K', 'username' => 'K');
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -120,3 +120,21 @@ create table inbox (
|
||||
|
||||
);
|
||||
|
||||
create table user_location_prefs (
|
||||
user_id integer not null /*comment 'user who has the preference'*/ references "user" (id),
|
||||
share_location int default 1 /* comment 'Whether to share location data'*/,
|
||||
created timestamp not null /*comment 'date this record was created'*/,
|
||||
modified timestamp /* comment 'date this record was modified'*/,
|
||||
|
||||
primary key (user_id)
|
||||
);
|
||||
|
||||
create table inbox (
|
||||
|
||||
user_id integer not null /* comment 'user receiving the notice' */ references "user" (id),
|
||||
notice_ids bytea /* comment 'packed list of notice ids' */,
|
||||
|
||||
primary key (user_id)
|
||||
|
||||
);
|
||||
|
||||
|
@ -52,6 +52,10 @@ VALUES
|
||||
('socialoomphBfD4pMqz31', 'SocialOomph', 'http://www.socialoomph.com/', now()),
|
||||
('spaz','Spaz','http://funkatron.com/spaz', now()),
|
||||
('StatusNet Desktop', 'StatusNet Desktop', 'http://status.net/desktop', now()),
|
||||
('StatusNet Mobile', 'StatusNet Mobile', 'http://status.net/mobile', now()),
|
||||
('StatusNet iPhone', 'iPhone', 'http://status.net/iphone', now()),
|
||||
('StatusNet Android', 'Android', 'http://status.net/android', now()),
|
||||
('StatusNet Blackberry', 'Blackberry', 'http://status.net/blackberry', now()),
|
||||
('tarpipe','tarpipe','http://tarpipe.com/', now()),
|
||||
('tjunar','Tjunar','http://nederflash.nl/boek/titels/tjunar-air', now()),
|
||||
('tr.im','tr.im','http://tr.im/', now()),
|
||||
|
@ -136,7 +136,6 @@ create table notice (
|
||||
is_local integer default 0 /* comment 'notice was generated by a user' */,
|
||||
source varchar(32) /* comment 'source of comment, like "web", "im", or "clientname"' */,
|
||||
conversation integer /*id of root notice in this conversation' */ references notice (id),
|
||||
location varchar(255) /* comment 'physical location' */,
|
||||
lat decimal(10,7) /* comment 'latitude'*/ ,
|
||||
lon decimal(10,7) /* comment 'longitude'*/ ,
|
||||
location_id integer /* comment 'location id if possible'*/ ,
|
||||
|
@ -1,3 +1,7 @@
|
||||
<!-- Copyright 2008-2010 StatusNet Inc. and contributors. -->
|
||||
<!-- Document licensed under Creative Commons Attribution 3.0 Unported. See -->
|
||||
<!-- http://creativecommons.org/licenses/by/3.0/ for details. -->
|
||||
|
||||
%%site.name%% is a
|
||||
[micro-blogging](http://en.wikipedia.org/wiki/Micro-blogging) service
|
||||
based on the Free Software [StatusNet](http://status.net/) tool.
|
||||
|
@ -1,3 +1,7 @@
|
||||
<!-- Copyright 2008-2010 StatusNet Inc. and contributors. -->
|
||||
<!-- Document licensed under Creative Commons Attribution 3.0 Unported. See -->
|
||||
<!-- http://creativecommons.org/licenses/by/3.0/ for details. -->
|
||||
|
||||
Install the %%site.name%% badge on your blog or web site to show the latest updates
|
||||
from you and your friends!
|
||||
|
||||
|
@ -1,3 +1,7 @@
|
||||
<!-- Copyright 2008-2010 StatusNet Inc. and contributors. -->
|
||||
<!-- Document licensed under Creative Commons Attribution 3.0 Unported. See -->
|
||||
<!-- http://creativecommons.org/licenses/by/3.0/ for details. -->
|
||||
|
||||
A bookmarklet is a small piece of javascript code used as a bookmark. This one will let you post to %%site.name%% simply by selecting some text on a page and pressing the bookmarklet.
|
||||
|
||||
Drag-and-drop the following link to your bookmarks bar or right-click it and add it to your browser favorites to keep it handy.
|
||||
|
@ -1,3 +1,7 @@
|
||||
<!-- Copyright 2008-2010 StatusNet Inc. and contributors. -->
|
||||
<!-- Document licensed under Creative Commons Attribution 3.0 Unported. See -->
|
||||
<!-- http://creativecommons.org/licenses/by/3.0/ for details. -->
|
||||
|
||||
There are a number of options for getting in contact with responsible
|
||||
people for %%site.name%%.
|
||||
|
||||
|
@ -1,3 +1,7 @@
|
||||
<!-- Copyright 2008-2010 StatusNet Inc. and contributors. -->
|
||||
<!-- Document licensed under Creative Commons Attribution 3.0 Unported. See -->
|
||||
<!-- http://creativecommons.org/licenses/by/3.0/ for details. -->
|
||||
|
||||
These are some *Frequently Asked Questions* about this service, with
|
||||
some answers.
|
||||
|
||||
|
@ -1,3 +1,7 @@
|
||||
<!-- Copyright 2008-2010 StatusNet Inc. and contributors. -->
|
||||
<!-- Document licensed under Creative Commons Attribution 3.0 Unported. See -->
|
||||
<!-- http://creativecommons.org/licenses/by/3.0/ for details. -->
|
||||
|
||||
Users on %%site.name%% can create *groups* that other users can join.
|
||||
Groups can be a great way to share information and entertainment with
|
||||
a group of people who have a common interest or background.
|
||||
|
@ -1,3 +1,7 @@
|
||||
<!-- Copyright 2008-2010 StatusNet Inc. and contributors. -->
|
||||
<!-- Document licensed under Creative Commons Attribution 3.0 Unported. See -->
|
||||
<!-- http://creativecommons.org/licenses/by/3.0/ for details. -->
|
||||
|
||||
%%site.name%% is a **microblogging service**. Users post short (%%site.textlimit%%
|
||||
character) notices which are broadcast to their friends and fans using
|
||||
the Web, RSS, or instant messages.
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user