Merge branch 'nightly' into 'master'
GNU social 1.3.0 See merge request diogo/gnu-social!1
This commit is contained in:
commit
63ab20d20b
15
CONFIGURE
15
CONFIGURE
@ -120,8 +120,9 @@ db
|
||||
--
|
||||
|
||||
This section is a reference to the configuration options for
|
||||
DB_DataObject (see <http://ur1.ca/7xp>). The ones that you may want to
|
||||
set are listed below for clarity.
|
||||
DB_DataObject (see
|
||||
<http://pear.php.net/manual/en/package.database.db-dataobject.intro-configuration.php>).
|
||||
The ones that you may want to set are listed below for clarity.
|
||||
|
||||
database: a DSN (Data Source Name) for your StatusNet database. This is
|
||||
in the format 'protocol://username:password@hostname/databasename',
|
||||
@ -322,8 +323,8 @@ server: If set, defines another server where avatars are stored in the
|
||||
the client to speed up page loading, either with another
|
||||
virtual server or with an NFS or SAMBA share. Clients
|
||||
typically only make 2 connections to a single server at a
|
||||
time <http://ur1.ca/6ih>, so this can parallelize the job.
|
||||
Defaults to null.
|
||||
time <https://www.w3.org/Protocols/rfc2616/rfc2616-sec8.html#sec8.1.4>,
|
||||
so this can parallelize the job. Defaults to null.
|
||||
ssl: Whether to access avatars using HTTPS. Defaults to null, meaning
|
||||
to guess based on site-wide SSL settings.
|
||||
|
||||
@ -496,9 +497,9 @@ Profile management.
|
||||
|
||||
biolimit: max character length of bio; 0 means no limit; null means to use
|
||||
the site text limit default.
|
||||
backup: whether users can backup their own profiles. Defaults to true.
|
||||
backup: whether users can backup their own profiles. Defaults to false.
|
||||
restore: whether users can restore their profiles from backup files. Defaults
|
||||
to true.
|
||||
to false.
|
||||
delete: whether users can delete their own accounts. Defaults to false.
|
||||
move: whether users can move their accounts to another server. Defaults
|
||||
to true.
|
||||
@ -672,7 +673,7 @@ Web crawlers. See http://www.robotstxt.org/ for more information
|
||||
on the format of this file.
|
||||
|
||||
crawldelay: if non-empty, this value is provided as the Crawl-Delay:
|
||||
for the robots.txt file. see http://ur1.ca/l5a0
|
||||
for the robots.txt file. see <https://en.wikipedia.org/wiki/Robots_exclusion_standard#Crawl-delay_directive>
|
||||
for more information. Default is zero, no explicit delay.
|
||||
disallow: Array of (virtual) directories to disallow. Default is 'main',
|
||||
'search', 'message', 'settings', 'admin'. Ignored when site
|
||||
|
44
INSTALL
44
INSTALL
@ -26,16 +26,12 @@ PHP modules
|
||||
The following software packages are *required* for this software to
|
||||
run correctly.
|
||||
|
||||
- PHP 5.5+ For newer versions, some functions that are used may be
|
||||
disabled by default, such as the pcntl_* family. See the
|
||||
section on 'Queues and daemons' for more information.
|
||||
- MariaDB 5+ GNU Social uses, by default, a MariaDB server for data
|
||||
storage. Versions 5.x and 10.x have both reportedly
|
||||
worked well. It is also possible to run MySQL 5.5+.
|
||||
- Web server Apache, lighttpd and nginx will all work. CGI mode is
|
||||
recommended and also some variant of 'suexec' (or a
|
||||
proper setup php-fpm pool)
|
||||
NOTE: mod_rewrite or its equivalent is extremely useful.
|
||||
- PHP 5.6+ PHP7.x is also supported.
|
||||
- MariaDB 5+ MariaDB 10.x is also supported.
|
||||
- Web server Apache, lighttpd and nginx will all work, see sample
|
||||
configuration files in the web root. Please use PHP-FPM
|
||||
and configure mod_rewrite (or equivalent) for an optimal
|
||||
experience.
|
||||
|
||||
Your PHP installation must include the following PHP extensions for a
|
||||
functional setup of GNU Social:
|
||||
@ -49,9 +45,22 @@ functional setup of GNU Social:
|
||||
- php5-mysqlnd The native driver for PHP5 MariaDB connections. If you
|
||||
use MySQL, 'php5-mysql' or 'php5-mysqli' may be enough.
|
||||
|
||||
The above package names are for Debian based systems. In the case of
|
||||
Arch Linux, PHP is compiled with support for most extensions but they
|
||||
require manual enabling in the relevant php.ini file (mostly php5-gmp).
|
||||
Or, for PHP7, some or all of these will be necessary. PHP7 works and on
|
||||
the development servers we are successful running PHP7.2. This is a good
|
||||
list of PHP modules you will want installed with PHP7:
|
||||
php7.0-bcmath
|
||||
php7.0-curl
|
||||
php7.0-exif
|
||||
php7.0-gd
|
||||
php7.0-intl
|
||||
php7.0-mbstring
|
||||
php7.0-mysql
|
||||
php7.0-opcache
|
||||
php7.0-readline
|
||||
php7.0-xmlwriter
|
||||
|
||||
NOTE: In Arch Linux, at least PHP5 requires manual enabling in the
|
||||
relevant php.ini for some modules, most notably 'gmp'.
|
||||
|
||||
Better performance
|
||||
------------------
|
||||
@ -61,19 +70,10 @@ For some functionality, you will also need the following extensions:
|
||||
- opcache Improves performance a _lot_. Included in PHP, must be
|
||||
enabled manually in php.ini for most distributions. Find
|
||||
and set at least: opcache.enable=1
|
||||
- mailparse Efficient parsing of email requires this extension.
|
||||
Submission by email or SMS-over-email uses this.
|
||||
- sphinx A client for the sphinx server, an alternative to MySQL
|
||||
or Postgresql fulltext search. You will also need a
|
||||
Sphinx server to serve the search queries.
|
||||
- gettext For multiple languages. Default on many PHP installs;
|
||||
will be emulated if not present.
|
||||
- exif For thumbnails to be properly oriented.
|
||||
|
||||
You may also experience better performance from your site if you configure
|
||||
a PHP cache/accelerator. Most distributions come with "opcache" support.
|
||||
Enable it in your php.ini where it is documented together with its settings.
|
||||
|
||||
Installation
|
||||
============
|
||||
|
||||
|
@ -107,6 +107,7 @@ So far it includes the following changes:
|
||||
|
||||
- Backing up a user's account is more and more complete.
|
||||
- Emojis 😸 (utf8mb4 support)
|
||||
- Fully qualified group mentions (!group@example.com)
|
||||
|
||||
The last release, 1.1.3, gave us these improvements:
|
||||
|
||||
|
3
UPGRADE
3
UPGRADE
@ -11,6 +11,9 @@ and follow this procedure:
|
||||
0. Backup your data. The StatusNet upgrade discussions below have some
|
||||
guidelines to back up the database and files (mysqldump and rsync).
|
||||
|
||||
MAKE SURE YOU ARE THE SAME USER THAT RUNS THE PHP FILES WHILE PERFORMING
|
||||
THE COMMANDS BELOW (I usually prepend the commands with 'sudo -u social')
|
||||
|
||||
1. Stop your queue daemons (you can run this command even if you do not
|
||||
use the queue daemons):
|
||||
$ bash scripts/stopdaemons.sh
|
||||
|
@ -65,7 +65,7 @@ class AddpeopletagAction extends Action
|
||||
*
|
||||
* @return boolean success flag
|
||||
*/
|
||||
function prepare($args)
|
||||
function prepare(array $args = array())
|
||||
{
|
||||
parent::prepare($args);
|
||||
|
||||
@ -119,7 +119,7 @@ class AddpeopletagAction extends Action
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
function handle($args)
|
||||
function handle()
|
||||
{
|
||||
// Throws exception on error
|
||||
$ptag = Profile_tag::setTag($this->user->id, $this->tagged->id,
|
||||
|
@ -170,12 +170,6 @@ class AllAction extends ShowstreamAction
|
||||
}
|
||||
$ibs->show();
|
||||
}
|
||||
// XXX: make this a little more convenient
|
||||
|
||||
if (!common_config('performance', 'high')) {
|
||||
$pop = new InboxTagCloudSection($this, $this->target);
|
||||
$pop->show();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -46,7 +46,7 @@ class AllrssAction extends TargetedRss10Action
|
||||
{
|
||||
protected function getNotices()
|
||||
{
|
||||
$stream = new InboxNoticeStream($this->target);
|
||||
$stream = new InboxNoticeStream($this->target, $this->scoped);
|
||||
return $stream->getNotices(0, $this->limit)->fetchAll();
|
||||
}
|
||||
|
||||
|
@ -54,7 +54,7 @@ class ApiAccountUpdateDeliveryDeviceAction extends ApiAuthAction
|
||||
*
|
||||
* @return boolean success flag
|
||||
*/
|
||||
function prepare($args)
|
||||
function prepare(array $args = array())
|
||||
{
|
||||
parent::prepare($args);
|
||||
|
||||
@ -73,9 +73,9 @@ class ApiAccountUpdateDeliveryDeviceAction extends ApiAuthAction
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
function handle($args)
|
||||
function handle()
|
||||
{
|
||||
parent::handle($args);
|
||||
parent::handle();
|
||||
|
||||
if (!in_array($this->format, array('xml', 'json'))) {
|
||||
$this->clientError(
|
||||
|
@ -51,7 +51,7 @@ class ApiAtomServiceAction extends ApiBareAuthAction
|
||||
* @return boolean success flag
|
||||
*
|
||||
*/
|
||||
function prepare($args)
|
||||
function prepare(array $args = array())
|
||||
{
|
||||
parent::prepare($args);
|
||||
$this->user = $this->getTargetUser($this->arg('id'));
|
||||
@ -71,9 +71,9 @@ class ApiAtomServiceAction extends ApiBareAuthAction
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
function handle($args)
|
||||
function handle()
|
||||
{
|
||||
parent::handle($args);
|
||||
parent::handle();
|
||||
|
||||
header('Content-Type: application/atomsvc+xml');
|
||||
|
||||
|
@ -58,7 +58,7 @@ class ApiGroupListAllAction extends ApiPrivateAuthAction
|
||||
*
|
||||
* @return boolean success flag
|
||||
*/
|
||||
function prepare($args)
|
||||
function prepare(array $args = array())
|
||||
{
|
||||
parent::prepare($args);
|
||||
|
||||
@ -77,9 +77,9 @@ class ApiGroupListAllAction extends ApiPrivateAuthAction
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
function handle($args)
|
||||
function handle()
|
||||
{
|
||||
parent::handle($args);
|
||||
parent::handle();
|
||||
|
||||
$sitename = common_config('site', 'name');
|
||||
// TRANS: Message is used as a title when listing the lastest 20 groups. %s is a site name.
|
||||
|
@ -28,9 +28,7 @@
|
||||
* @link http://status.net/
|
||||
*/
|
||||
|
||||
if (!defined('STATUSNET')) {
|
||||
exit(1);
|
||||
}
|
||||
if (!defined('GNUSOCIAL')) { exit(1); }
|
||||
|
||||
/**
|
||||
* Returns the string "ok" in the requested format with a 200 OK HTTP status code.
|
||||
@ -44,29 +42,9 @@ if (!defined('STATUSNET')) {
|
||||
*/
|
||||
class ApiHelpTestAction extends ApiPrivateAuthAction
|
||||
{
|
||||
/**
|
||||
* Take arguments for running
|
||||
*
|
||||
* @param array $args $_REQUEST args
|
||||
*
|
||||
* @return boolean success flag
|
||||
*/
|
||||
function prepare($args)
|
||||
protected function handle()
|
||||
{
|
||||
parent::prepare($args);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle the request
|
||||
*
|
||||
* @param array $args $_REQUEST data (unused)
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
function handle($args)
|
||||
{
|
||||
parent::handle($args);
|
||||
parent::handle();
|
||||
|
||||
if ($this->format == 'xml') {
|
||||
$this->initDocument('xml');
|
||||
@ -77,12 +55,8 @@ class ApiHelpTestAction extends ApiPrivateAuthAction
|
||||
print '"ok"';
|
||||
$this->endDocument('json');
|
||||
} else {
|
||||
$this->clientError(
|
||||
// TRANS: Client error displayed when coming across a non-supported API method.
|
||||
_('API method not found.'),
|
||||
404,
|
||||
$this->format
|
||||
);
|
||||
// TRANS: Client error displayed when coming across a non-supported API method.
|
||||
throw new ClientException(_('API method not found.'), 404);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -33,7 +33,7 @@ class ApiListSubscriberAction extends ApiBareAuthAction
|
||||
{
|
||||
var $list = null;
|
||||
|
||||
function prepare($args)
|
||||
function prepare(array $args = array())
|
||||
{
|
||||
parent::prepare($args);
|
||||
|
||||
@ -52,9 +52,9 @@ class ApiListSubscriberAction extends ApiBareAuthAction
|
||||
return true;
|
||||
}
|
||||
|
||||
function handle($args)
|
||||
function handle()
|
||||
{
|
||||
parent::handle($args);
|
||||
parent::handle();
|
||||
|
||||
$arr = array('profile_tag_id' => $this->list->id,
|
||||
'profile_id' => $this->target->id);
|
||||
|
@ -52,9 +52,9 @@ class ApiOAuthAccessTokenAction extends ApiOAuthAction
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
function handle($args)
|
||||
function handle()
|
||||
{
|
||||
parent::handle($args);
|
||||
parent::handle();
|
||||
|
||||
$datastore = new ApiGNUsocialOAuthDataStore();
|
||||
$server = new OAuthServer($datastore);
|
||||
|
@ -60,7 +60,7 @@ class ApiOAuthAuthorizeAction extends ApiOAuthAction
|
||||
return false;
|
||||
}
|
||||
|
||||
function prepare($args)
|
||||
function prepare(array $args = array())
|
||||
{
|
||||
parent::prepare($args);
|
||||
|
||||
@ -88,9 +88,9 @@ class ApiOAuthAuthorizeAction extends ApiOAuthAction
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
function handle($args)
|
||||
function handle()
|
||||
{
|
||||
parent::handle($args);
|
||||
parent::handle();
|
||||
|
||||
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
|
||||
|
||||
|
@ -49,7 +49,7 @@ class ApiOAuthRequestTokenAction extends ApiOAuthAction
|
||||
*
|
||||
* @return boolean success flag
|
||||
*/
|
||||
function prepare($args)
|
||||
function prepare(array $args = array())
|
||||
{
|
||||
parent::prepare($args);
|
||||
|
||||
@ -69,9 +69,9 @@ class ApiOAuthRequestTokenAction extends ApiOAuthAction
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
function handle($args)
|
||||
function handle()
|
||||
{
|
||||
parent::handle($args);
|
||||
parent::handle();
|
||||
|
||||
$datastore = new ApiGNUsocialOAuthDataStore();
|
||||
$server = new OAuthServer($datastore);
|
||||
|
@ -88,7 +88,7 @@ class ApiSearchAtomAction extends ApiPrivateAuthAction
|
||||
*
|
||||
* @return boolean success
|
||||
*/
|
||||
function prepare($args)
|
||||
function prepare(array $args = array())
|
||||
{
|
||||
parent::prepare($args);
|
||||
|
||||
@ -128,9 +128,9 @@ class ApiSearchAtomAction extends ApiPrivateAuthAction
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
function handle($args)
|
||||
function handle()
|
||||
{
|
||||
parent::handle($args);
|
||||
parent::handle();
|
||||
common_debug("In apisearchatom handle()");
|
||||
$this->showAtom();
|
||||
}
|
||||
|
@ -57,7 +57,7 @@ class ApiSearchJSONAction extends ApiPrivateAuthAction
|
||||
*
|
||||
* @return boolean true if nothing goes wrong
|
||||
*/
|
||||
function prepare($args)
|
||||
function prepare(array $args = array())
|
||||
{
|
||||
parent::prepare($args);
|
||||
|
||||
@ -95,9 +95,9 @@ class ApiSearchJSONAction extends ApiPrivateAuthAction
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
function handle($args)
|
||||
function handle()
|
||||
{
|
||||
parent::handle($args);
|
||||
parent::handle();
|
||||
$this->showResults();
|
||||
}
|
||||
|
||||
|
@ -34,9 +34,7 @@
|
||||
* @link http://status.net/
|
||||
*/
|
||||
|
||||
if (!defined('STATUSNET')) {
|
||||
exit(1);
|
||||
}
|
||||
if (!defined('GNUSOCIAL')) { exit(1); }
|
||||
|
||||
/**
|
||||
* Deletes one of the authenticating user's statuses (notices).
|
||||
@ -55,87 +53,46 @@ if (!defined('STATUSNET')) {
|
||||
*/
|
||||
class ApiStatusesDestroyAction extends ApiAuthAction
|
||||
{
|
||||
var $status = null;
|
||||
|
||||
/**
|
||||
* Take arguments for running
|
||||
*
|
||||
* @param array $args $_REQUEST args
|
||||
*
|
||||
* @return boolean success flag
|
||||
*/
|
||||
function prepare($args)
|
||||
protected function prepare(array $args=array())
|
||||
{
|
||||
parent::prepare($args);
|
||||
|
||||
$this->user = $this->auth_user;
|
||||
$this->notice_id = (int)$this->trimmed('id');
|
||||
|
||||
if (empty($notice_id)) {
|
||||
$this->notice_id = (int)$this->arg('id');
|
||||
if (!in_array($_SERVER['REQUEST_METHOD'], array('POST', 'DELETE'))) {
|
||||
// TRANS: Client error displayed trying to delete a status not using POST or DELETE.
|
||||
// TRANS: POST and DELETE should not be translated.
|
||||
throw new ClientException(_('This method requires a POST or DELETE.'));
|
||||
}
|
||||
|
||||
$this->notice = Notice::getKV((int)$this->notice_id);
|
||||
// FIXME: Return with a Not Acceptable status code?
|
||||
if (!in_array($this->format, array('xml', 'json'))) {
|
||||
// TRANS: Client error displayed when coming across a non-supported API method.
|
||||
throw new ClientException(_('API method not found.'), 404);
|
||||
}
|
||||
|
||||
try {
|
||||
$this->notice = Notice::getByID($this->trimmed('id'));
|
||||
} catch (NoResultException $e) {
|
||||
// TRANS: Client error displayed trying to delete a status with an invalid ID.
|
||||
throw new ClientException(_('No status found with that ID.'), 404);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle the request
|
||||
*
|
||||
* Delete the notice and all related replies
|
||||
*
|
||||
* @param array $args $_REQUEST data (unused)
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
function handle($args)
|
||||
protected function handle()
|
||||
{
|
||||
parent::handle($args);
|
||||
parent::handle();
|
||||
|
||||
if (!in_array($this->format, array('xml', 'json'))) {
|
||||
$this->clientError(
|
||||
// TRANS: Client error displayed when coming across a non-supported API method.
|
||||
_('API method not found.'),
|
||||
404
|
||||
);
|
||||
return;
|
||||
if (!$this->scoped->sameAs($this->notice->getProfile()) && !$this->scoped->hasRight(Right::DELETEOTHERSNOTICE)) {
|
||||
// TRANS: Client error displayed trying to delete a status of another user.
|
||||
throw new AuthorizationException(_('You may not delete another user\'s status.'));
|
||||
}
|
||||
|
||||
if (!in_array($_SERVER['REQUEST_METHOD'], array('POST', 'DELETE'))) {
|
||||
$this->clientError(
|
||||
// TRANS: Client error displayed trying to delete a status not using POST or DELETE.
|
||||
// TRANS: POST and DELETE should not be translated.
|
||||
_('This method requires a POST or DELETE.'),
|
||||
400,
|
||||
$this->format
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
if (empty($this->notice)) {
|
||||
$this->clientError(
|
||||
// TRANS: Client error displayed trying to delete a status with an invalid ID.
|
||||
_('No status found with that ID.'),
|
||||
404, $this->format
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
if ($this->user->id == $this->notice->profile_id) {
|
||||
if (Event::handle('StartDeleteOwnNotice', array($this->user, $this->notice))) {
|
||||
$this->notice->deleteAs($this->scoped);
|
||||
Event::handle('EndDeleteOwnNotice', array($this->user, $this->notice));
|
||||
}
|
||||
$this->showNotice();
|
||||
} else {
|
||||
$this->clientError(
|
||||
// TRANS: Client error displayed trying to delete a status of another user.
|
||||
_('You may not delete another user\'s status.'),
|
||||
403,
|
||||
$this->format
|
||||
);
|
||||
if (Event::handle('StartDeleteOwnNotice', array($this->scoped->getUser(), $this->notice))) {
|
||||
$this->notice->deleteAs($this->scoped);
|
||||
Event::handle('EndDeleteOwnNotice', array($this->scoped->getUser(), $this->notice));
|
||||
}
|
||||
$this->showNotice();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -46,7 +46,7 @@
|
||||
/api/statuses/update.:format
|
||||
|
||||
@par Formats (:format)
|
||||
xml, json
|
||||
xml, json, atom
|
||||
|
||||
@par HTTP Method(s)
|
||||
POST
|
||||
@ -174,7 +174,7 @@ class ApiStatusesUpdateAction extends ApiAuthAction
|
||||
foreach (array_unique($matches[0]) as $match) {
|
||||
try {
|
||||
$this->media_ids[$match] = File::getByID($match);
|
||||
} catch (EmptyIdException $e) {
|
||||
} catch (EmptyPkeyValueException $e) {
|
||||
// got a zero from the client, at least Twidere does this on occasion
|
||||
} catch (NoResultException $e) {
|
||||
// File ID was not found. Do we abort and report to the client?
|
||||
@ -339,6 +339,8 @@ class ApiStatusesUpdateAction extends ApiAuthAction
|
||||
$this->showSingleXmlStatus($this->notice);
|
||||
} elseif ($this->format == 'json') {
|
||||
$this->show_single_json_status($this->notice);
|
||||
} elseif ($this->format == 'atom') {
|
||||
$this->showSingleAtomStatus($this->notice);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -53,7 +53,7 @@ class ApiTrendsAction extends ApiPrivateAuthAction
|
||||
*
|
||||
* @return boolean false if user doesn't exist
|
||||
*/
|
||||
function prepare($args)
|
||||
function prepare(array $args = array())
|
||||
{
|
||||
parent::prepare($args);
|
||||
return true;
|
||||
@ -66,9 +66,9 @@ class ApiTrendsAction extends ApiPrivateAuthAction
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
function handle($args)
|
||||
function handle()
|
||||
{
|
||||
parent::handle($args);
|
||||
parent::handle();
|
||||
$this->showTrends();
|
||||
}
|
||||
|
||||
|
@ -50,7 +50,7 @@ class ApprovegroupAction extends Action
|
||||
/**
|
||||
* Prepare to run
|
||||
*/
|
||||
function prepare($args)
|
||||
function prepare(array $args = array())
|
||||
{
|
||||
parent::prepare($args);
|
||||
|
||||
@ -139,9 +139,9 @@ class ApprovegroupAction extends Action
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
function handle($args)
|
||||
function handle()
|
||||
{
|
||||
parent::handle($args);
|
||||
parent::handle();
|
||||
|
||||
try {
|
||||
if ($this->approve) {
|
||||
|
@ -50,7 +50,7 @@ class ApprovesubAction extends Action
|
||||
/**
|
||||
* Prepare to run
|
||||
*/
|
||||
function prepare($args)
|
||||
function prepare(array $args = array())
|
||||
{
|
||||
parent::prepare($args);
|
||||
|
||||
@ -97,9 +97,9 @@ class ApprovesubAction extends Action
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
function handle($args)
|
||||
function handle()
|
||||
{
|
||||
parent::handle($args);
|
||||
parent::handle();
|
||||
$cur = common_current_user();
|
||||
|
||||
try {
|
||||
|
@ -96,7 +96,7 @@ class AttachmentAction extends ManagedAction
|
||||
{
|
||||
if (empty($this->attachment->filename)) {
|
||||
// if it's not a local file, gtfo
|
||||
common_redirect($this->attachment->url, 303);
|
||||
common_redirect($this->attachment->getUrl(), 303);
|
||||
}
|
||||
|
||||
parent::showPage();
|
||||
@ -132,9 +132,5 @@ class AttachmentAction extends ManagedAction
|
||||
function showSections() {
|
||||
$ns = new AttachmentNoticeSection($this);
|
||||
$ns->show();
|
||||
if (!common_config('performance', 'high')) {
|
||||
$atcs = new AttachmentTagCloudSection($this);
|
||||
$atcs->show();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
20
actions/attachment_download.php
Normal file
20
actions/attachment_download.php
Normal file
@ -0,0 +1,20 @@
|
||||
<?php
|
||||
|
||||
if (!defined('GNUSOCIAL')) { exit(1); }
|
||||
|
||||
/**
|
||||
* Download notice attachment
|
||||
*
|
||||
* @category Personal
|
||||
* @package GNUsocial
|
||||
* @author Mikael Nordfeldth <mmn@hethane.se>
|
||||
* @license https://www.gnu.org/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||
* @link https:/gnu.io/social
|
||||
*/
|
||||
class Attachment_downloadAction extends AttachmentAction
|
||||
{
|
||||
public function showPage()
|
||||
{
|
||||
common_redirect($this->attachment->getUrl(), 302);
|
||||
}
|
||||
}
|
@ -62,6 +62,6 @@ class Attachment_thumbnailAction extends AttachmentAction
|
||||
common_redirect($e->file->getUrl(), 302);
|
||||
}
|
||||
|
||||
common_redirect(File_thumbnail::url($thumbnail->filename), 302);
|
||||
common_redirect(File_thumbnail::url($thumbnail->getFilename()), 302);
|
||||
}
|
||||
}
|
||||
|
@ -49,6 +49,20 @@ class AvatarsettingsAction extends SettingsAction
|
||||
var $imagefile = null;
|
||||
var $filename = null;
|
||||
|
||||
function prepare(array $args=array())
|
||||
{
|
||||
$avatarpath = Avatar::path('');
|
||||
|
||||
if (!is_writable($avatarpath)) {
|
||||
throw new Exception(_("The administrator of your site needs to
|
||||
add write permissions on the avatar upload folder before
|
||||
you're able to set one."));
|
||||
}
|
||||
|
||||
parent::prepare($args);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Title of the page
|
||||
*
|
||||
@ -92,16 +106,6 @@ class AvatarsettingsAction extends SettingsAction
|
||||
|
||||
function showUploadForm()
|
||||
{
|
||||
$user = common_current_user();
|
||||
|
||||
$profile = $user->getProfile();
|
||||
|
||||
if (!$profile) {
|
||||
common_log_db_error($user, 'SELECT', __FILE__);
|
||||
// TRANS: Error message displayed when referring to a user without a profile.
|
||||
$this->serverError(_('User has no profile.'));
|
||||
}
|
||||
|
||||
$this->elementStart('form', array('enctype' => 'multipart/form-data',
|
||||
'method' => 'post',
|
||||
'id' => 'form_settings_avatar',
|
||||
@ -116,7 +120,7 @@ class AvatarsettingsAction extends SettingsAction
|
||||
if (Event::handle('StartAvatarFormData', array($this))) {
|
||||
$this->elementStart('ul', 'form_data');
|
||||
try {
|
||||
$original = Avatar::getUploaded($profile);
|
||||
$original = Avatar::getUploaded($this->scoped);
|
||||
|
||||
$this->elementStart('li', array('id' => 'avatar_original',
|
||||
'class' => 'avatar_view'));
|
||||
@ -126,7 +130,7 @@ class AvatarsettingsAction extends SettingsAction
|
||||
$this->element('img', array('src' => $original->displayUrl(),
|
||||
'width' => $original->width,
|
||||
'height' => $original->height,
|
||||
'alt' => $user->nickname));
|
||||
'alt' => $this->scoped->getNickname()));
|
||||
$this->elementEnd('div');
|
||||
$this->elementEnd('li');
|
||||
} catch (NoAvatarException $e) {
|
||||
@ -134,7 +138,7 @@ class AvatarsettingsAction extends SettingsAction
|
||||
}
|
||||
|
||||
try {
|
||||
$avatar = $profile->getAvatar(AVATAR_PROFILE_SIZE);
|
||||
$avatar = $this->scoped->getAvatar(AVATAR_PROFILE_SIZE);
|
||||
$this->elementStart('li', array('id' => 'avatar_preview',
|
||||
'class' => 'avatar_view'));
|
||||
// TRANS: Header on avatar upload page for thumbnail of to be used rendition of uploaded avatar (h2).
|
||||
@ -143,7 +147,7 @@ class AvatarsettingsAction extends SettingsAction
|
||||
$this->element('img', array('src' => $avatar->displayUrl(),
|
||||
'width' => AVATAR_PROFILE_SIZE,
|
||||
'height' => AVATAR_PROFILE_SIZE,
|
||||
'alt' => $user->nickname));
|
||||
'alt' => $this->scoped->getNickname()));
|
||||
$this->elementEnd('div');
|
||||
if (!empty($avatar->filename)) {
|
||||
// TRANS: Button on avatar upload page to delete current avatar.
|
||||
@ -180,16 +184,6 @@ class AvatarsettingsAction extends SettingsAction
|
||||
|
||||
function showCropForm()
|
||||
{
|
||||
$user = common_current_user();
|
||||
|
||||
$profile = $user->getProfile();
|
||||
|
||||
if (!$profile) {
|
||||
common_log_db_error($user, 'SELECT', __FILE__);
|
||||
// TRANS: Error message displayed when referring to a user without a profile.
|
||||
$this->serverError(_('User has no profile.'));
|
||||
}
|
||||
|
||||
$this->elementStart('form', array('method' => 'post',
|
||||
'id' => 'form_settings_avatar',
|
||||
'class' => 'form_settings',
|
||||
@ -211,7 +205,7 @@ class AvatarsettingsAction extends SettingsAction
|
||||
$this->element('img', array('src' => Avatar::url($this->filedata['filename']),
|
||||
'width' => $this->filedata['width'],
|
||||
'height' => $this->filedata['height'],
|
||||
'alt' => $user->nickname));
|
||||
'alt' => $this->scoped->getNickname()));
|
||||
$this->elementEnd('div');
|
||||
$this->elementEnd('li');
|
||||
|
||||
@ -224,7 +218,7 @@ class AvatarsettingsAction extends SettingsAction
|
||||
$this->element('img', array('src' => Avatar::url($this->filedata['filename']),
|
||||
'width' => AVATAR_PROFILE_SIZE,
|
||||
'height' => AVATAR_PROFILE_SIZE,
|
||||
'alt' => $user->nickname));
|
||||
'alt' => $this->scoped->getNickname()));
|
||||
$this->elementEnd('div');
|
||||
|
||||
foreach (array('avatar_crop_x', 'avatar_crop_y',
|
||||
|
@ -74,6 +74,9 @@ class BackupaccountAction extends FormAction
|
||||
// @fixme atom feed logic is in getString...
|
||||
// but we just want it to output to the outputter.
|
||||
$this->raw($stream->getString());
|
||||
|
||||
// Don't print the page HTML
|
||||
exit(0);
|
||||
}
|
||||
|
||||
public function isReadOnly($args) {
|
||||
|
@ -53,7 +53,7 @@ class BlockAction extends ProfileFormAction
|
||||
*
|
||||
* @return boolean success flag
|
||||
*/
|
||||
function prepare($args)
|
||||
function prepare(array $args = array())
|
||||
{
|
||||
if (!parent::prepare($args)) {
|
||||
return false;
|
||||
@ -78,7 +78,7 @@ class BlockAction extends ProfileFormAction
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
function handle($args)
|
||||
function handle()
|
||||
{
|
||||
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
|
||||
if ($this->arg('no')) {
|
||||
|
@ -151,7 +151,7 @@ class GroupBlockList extends ProfileList
|
||||
$this->group = $group;
|
||||
}
|
||||
|
||||
function newListItem($profile)
|
||||
function newListItem(Profile $profile)
|
||||
{
|
||||
return new GroupBlockListItem($profile, $this->group, $this->action);
|
||||
}
|
||||
|
@ -50,7 +50,7 @@ class CancelgroupAction extends Action
|
||||
/**
|
||||
* Prepare to run
|
||||
*/
|
||||
function prepare($args)
|
||||
function prepare(array $args = array())
|
||||
{
|
||||
parent::prepare($args);
|
||||
|
||||
@ -127,9 +127,9 @@ class CancelgroupAction extends Action
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
function handle($args)
|
||||
function handle()
|
||||
{
|
||||
parent::handle($args);
|
||||
parent::handle();
|
||||
|
||||
try {
|
||||
$this->request->abort();
|
||||
|
@ -27,9 +27,7 @@
|
||||
* @link http://status.net/
|
||||
*/
|
||||
|
||||
if (!defined('STATUSNET') && !defined('LACONICA')) {
|
||||
exit(1);
|
||||
}
|
||||
if (!defined('GNUSOCIAL')) { exit(1); }
|
||||
|
||||
/**
|
||||
* Confirm an address
|
||||
@ -44,25 +42,14 @@ if (!defined('STATUSNET') && !defined('LACONICA')) {
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||
* @link http://status.net/
|
||||
*/
|
||||
class ConfirmaddressAction extends Action
|
||||
class ConfirmaddressAction extends ManagedAction
|
||||
{
|
||||
/** type of confirmation. */
|
||||
|
||||
var $address;
|
||||
protected $address;
|
||||
|
||||
/**
|
||||
* Accept a confirmation code
|
||||
*
|
||||
* Checks the code and confirms the address in the
|
||||
* user record
|
||||
*
|
||||
* @param args $args $_REQUEST array
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
function handle($args)
|
||||
protected function doPreparation()
|
||||
{
|
||||
parent::handle($args);
|
||||
if (!common_logged_in()) {
|
||||
common_set_returnto($this->selfUrl());
|
||||
common_redirect(common_local_url('login'));
|
||||
@ -70,32 +57,45 @@ class ConfirmaddressAction extends Action
|
||||
$code = $this->trimmed('code');
|
||||
if (!$code) {
|
||||
// TRANS: Client error displayed when not providing a confirmation code in the contact address confirmation action.
|
||||
$this->clientError(_('No confirmation code.'));
|
||||
throw new ClientException(_('No confirmation code.'));
|
||||
}
|
||||
$confirm = Confirm_address::getKV('code', $code);
|
||||
if (!$confirm) {
|
||||
if (!$confirm instanceof Confirm_address) {
|
||||
// TRANS: Client error displayed when providing a non-existing confirmation code in the contact address confirmation action.
|
||||
$this->clientError(_('Confirmation code not found.'));
|
||||
throw new ClientException(_('Confirmation code not found.'), 404);
|
||||
}
|
||||
$cur = common_current_user();
|
||||
if ($cur->id != $confirm->user_id) {
|
||||
|
||||
try {
|
||||
$profile = Profile::getByID($confirm->user_id);
|
||||
} catch (NoResultException $e) {
|
||||
common_log(LOG_INFO, 'Tried to confirm the email for a deleted profile: '._ve(['id'=>$confirm->user_id, 'email'=>$confirm->address]));
|
||||
$confirm->delete();
|
||||
throw $e;
|
||||
}
|
||||
if (!$profile->sameAs($this->scoped)) {
|
||||
// TRANS: Client error displayed when not providing a confirmation code for another user in the contact address confirmation action.
|
||||
$this->clientError(_('That confirmation code is not for you!'));
|
||||
throw new AuthorizationException(_('That confirmation code is not for you!'));
|
||||
}
|
||||
|
||||
$type = $confirm->address_type;
|
||||
$transports = array();
|
||||
Event::handle('GetImTransports', array(&$transports));
|
||||
if (!in_array($type, array('email', 'sms')) && !in_array($type, array_keys($transports))) {
|
||||
// TRANS: Server error for an unknown address type, which can be 'email', 'sms', or the name of an IM network (such as 'xmpp' or 'aim')
|
||||
$this->serverError(sprintf(_('Unrecognized address type %s'), $type));
|
||||
throw new ServerException(sprintf(_('Unrecognized address type %s'), $type));
|
||||
}
|
||||
$this->address = $confirm->address;
|
||||
|
||||
$cur = $this->scoped->getUser();
|
||||
|
||||
$cur->query('BEGIN');
|
||||
if (in_array($type, array('email', 'sms')))
|
||||
{
|
||||
if (in_array($type, array('email', 'sms'))) {
|
||||
common_debug("Confirming {$type} address for user {$this->scoped->getID()}");
|
||||
if ($cur->$type == $confirm->address) {
|
||||
// Already verified, so delete the confirm_address entry
|
||||
$confirm->delete();
|
||||
// TRANS: Client error for an already confirmed email/jabber/sms address.
|
||||
$this->clientError(_('That address has already been confirmed.'));
|
||||
throw new AlreadyFulfilledException(_('That address has already been confirmed.'));
|
||||
}
|
||||
|
||||
$orig_user = clone($cur);
|
||||
@ -122,16 +122,18 @@ class ConfirmaddressAction extends Action
|
||||
$user_im_prefs->user_id = $cur->id;
|
||||
if ($user_im_prefs->find() && $user_im_prefs->fetch()) {
|
||||
if($user_im_prefs->screenname == $confirm->address){
|
||||
// Already verified, so delete the confirm_address entry
|
||||
$confirm->delete();
|
||||
// TRANS: Client error for an already confirmed IM address.
|
||||
$this->clientError(_('That address has already been confirmed.'));
|
||||
throw new AlreadyFulfilledException(_('That address has already been confirmed.'));
|
||||
}
|
||||
$user_im_prefs->screenname = $confirm->address;
|
||||
$result = $user_im_prefs->update();
|
||||
|
||||
if (!$result) {
|
||||
if ($result === false) {
|
||||
common_log_db_error($user_im_prefs, 'UPDATE', __FILE__);
|
||||
// TRANS: Server error displayed when updating IM preferences fails.
|
||||
$this->serverError(_('Could not update user IM preferences.'));
|
||||
throw new ServerException(_('Could not update user IM preferences.'));
|
||||
}
|
||||
}else{
|
||||
$user_im_prefs = new User_im_prefs();
|
||||
@ -140,26 +142,18 @@ class ConfirmaddressAction extends Action
|
||||
$user_im_prefs->user_id = $cur->id;
|
||||
$result = $user_im_prefs->insert();
|
||||
|
||||
if (!$result) {
|
||||
if ($result === false) {
|
||||
common_log_db_error($user_im_prefs, 'INSERT', __FILE__);
|
||||
// TRANS: Server error displayed when adding IM preferences fails.
|
||||
$this->serverError(_('Could not insert user IM preferences.'));
|
||||
throw new ServerException(_('Could not insert user IM preferences.'));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
$result = $confirm->delete();
|
||||
|
||||
if (!$result) {
|
||||
common_log_db_error($confirm, 'DELETE', __FILE__);
|
||||
// TRANS: Server error displayed when an address confirmation code deletion from the
|
||||
// TRANS: database fails in the contact address confirmation action.
|
||||
$this->serverError(_('Could not delete address confirmation.'));
|
||||
}
|
||||
$confirm->delete();
|
||||
|
||||
$cur->query('COMMIT');
|
||||
$this->showPage();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -180,8 +174,6 @@ class ConfirmaddressAction extends Action
|
||||
*/
|
||||
function showContent()
|
||||
{
|
||||
$cur = common_current_user();
|
||||
|
||||
$this->element('p', null,
|
||||
// TRANS: Success message for the contact address confirmation action.
|
||||
// TRANS: %s can be 'email', 'jabber', or 'sms'.
|
||||
|
@ -51,7 +51,7 @@ class DeleteapplicationAction extends Action
|
||||
*
|
||||
* @return boolean success flag
|
||||
*/
|
||||
function prepare($args)
|
||||
function prepare(array $args = array())
|
||||
{
|
||||
if (!parent::prepare($args)) {
|
||||
return false;
|
||||
@ -89,7 +89,7 @@ class DeleteapplicationAction extends Action
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
function handle($args)
|
||||
function handle()
|
||||
{
|
||||
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
|
||||
|
||||
|
@ -55,7 +55,7 @@ class DeletegroupAction extends RedirectingAction
|
||||
* @fixme merge common setup code with other group actions
|
||||
* @fixme allow group admins to delete their own groups
|
||||
*/
|
||||
function prepare($args)
|
||||
function prepare(array $args = array())
|
||||
{
|
||||
parent::prepare($args);
|
||||
|
||||
@ -114,9 +114,9 @@ class DeletegroupAction extends RedirectingAction
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
function handle($args)
|
||||
function handle()
|
||||
{
|
||||
parent::handle($args);
|
||||
parent::handle();
|
||||
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
|
||||
if ($this->arg('no')) {
|
||||
$this->returnToPrevious();
|
||||
|
@ -80,7 +80,7 @@ class DeleteuserAction extends ProfileFormAction
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
function handle($args)
|
||||
function handle()
|
||||
{
|
||||
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
|
||||
if ($this->arg('no')) {
|
||||
|
@ -57,7 +57,7 @@ class EditApplicationAction extends Action
|
||||
/**
|
||||
* Prepare to run
|
||||
*/
|
||||
function prepare($args)
|
||||
function prepare(array $args = array())
|
||||
{
|
||||
parent::prepare($args);
|
||||
|
||||
@ -94,9 +94,9 @@ class EditApplicationAction extends Action
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
function handle($args)
|
||||
function handle()
|
||||
{
|
||||
parent::handle($args);
|
||||
parent::handle();
|
||||
|
||||
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
|
||||
$this->handlePost($args);
|
||||
|
@ -60,7 +60,7 @@ class EditpeopletagAction extends Action
|
||||
* Prepare to run
|
||||
*/
|
||||
|
||||
function prepare($args)
|
||||
function prepare(array $args = array())
|
||||
{
|
||||
parent::prepare($args);
|
||||
|
||||
@ -135,9 +135,9 @@ class EditpeopletagAction extends Action
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
function handle($args)
|
||||
function handle()
|
||||
{
|
||||
parent::handle($args);
|
||||
parent::handle();
|
||||
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
|
||||
$this->trySave();
|
||||
} else {
|
||||
|
@ -369,8 +369,7 @@ class EmailsettingsAction extends SettingsAction
|
||||
throw new ServerException(_('Could not insert confirmation code.'));
|
||||
}
|
||||
|
||||
common_debug('Sending confirmation address for user '.$user->getID().' to email '.$email);
|
||||
mail_confirm_address($user, $confirm->code, $user->getNickname(), $email);
|
||||
$confirm->sendConfirmation();
|
||||
|
||||
Event::handle('EndAddEmailAddress', array($user, $email));
|
||||
}
|
||||
@ -401,13 +400,7 @@ class EmailsettingsAction extends SettingsAction
|
||||
throw new AlreadyFulfilledException(_('No pending confirmation to cancel.'));
|
||||
}
|
||||
|
||||
$result = $confirm->delete();
|
||||
|
||||
if ($result === false) {
|
||||
common_log_db_error($confirm, 'DELETE', __FILE__);
|
||||
// TRANS: Server error thrown on database error canceling e-mail address confirmation.
|
||||
throw new ServerException(_('Could not delete email confirmation.'));
|
||||
}
|
||||
$confirm->delete();
|
||||
|
||||
// TRANS: Message given after successfully canceling e-mail address confirmation.
|
||||
return _('Email confirmation cancelled.');
|
||||
|
@ -54,7 +54,7 @@ class FeaturedAction extends Action
|
||||
return true;
|
||||
}
|
||||
|
||||
function prepare($args)
|
||||
function prepare(array $args = array())
|
||||
{
|
||||
parent::prepare($args);
|
||||
$this->page = ($this->arg('page')) ? ($this->arg('page')+0) : 1;
|
||||
@ -74,9 +74,9 @@ class FeaturedAction extends Action
|
||||
}
|
||||
}
|
||||
|
||||
function handle($args)
|
||||
function handle()
|
||||
{
|
||||
parent::handle($args);
|
||||
parent::handle();
|
||||
|
||||
$this->showPage();
|
||||
}
|
||||
|
@ -35,7 +35,7 @@ class FoafGroupAction extends Action
|
||||
return true;
|
||||
}
|
||||
|
||||
function prepare($args)
|
||||
function prepare(array $args = array())
|
||||
{
|
||||
parent::prepare($args);
|
||||
|
||||
@ -76,9 +76,9 @@ class FoafGroupAction extends Action
|
||||
return true;
|
||||
}
|
||||
|
||||
function handle($args)
|
||||
function handle()
|
||||
{
|
||||
parent::handle($args);
|
||||
parent::handle();
|
||||
|
||||
header('Content-Type: application/rdf+xml');
|
||||
|
||||
|
@ -47,7 +47,7 @@ class GeocodeAction extends Action
|
||||
var $lon = null;
|
||||
var $location = null;
|
||||
|
||||
function prepare($args)
|
||||
function prepare(array $args = array())
|
||||
{
|
||||
parent::prepare($args);
|
||||
$token = $this->trimmed('token');
|
||||
@ -70,7 +70,7 @@ class GeocodeAction extends Action
|
||||
* @return nothing
|
||||
*
|
||||
*/
|
||||
function handle($args)
|
||||
function handle()
|
||||
{
|
||||
header('Content-Type: application/json; charset=utf-8');
|
||||
$location_object = array();
|
||||
|
@ -49,7 +49,7 @@ class GrantRoleAction extends ProfileFormAction
|
||||
*
|
||||
* @return boolean success flag
|
||||
*/
|
||||
function prepare($args)
|
||||
function prepare(array $args = array())
|
||||
{
|
||||
if (!parent::prepare($args)) {
|
||||
return false;
|
||||
|
@ -52,7 +52,7 @@ class GroupblockAction extends RedirectingAction
|
||||
*
|
||||
* @return boolean success flag
|
||||
*/
|
||||
function prepare($args)
|
||||
function prepare(array $args = array())
|
||||
{
|
||||
parent::prepare($args);
|
||||
if (!common_logged_in()) {
|
||||
@ -110,9 +110,9 @@ class GroupblockAction extends RedirectingAction
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
function handle($args)
|
||||
function handle()
|
||||
{
|
||||
parent::handle($args);
|
||||
parent::handle();
|
||||
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
|
||||
if ($this->arg('no')) {
|
||||
$this->returnToPrevious();
|
||||
|
@ -42,7 +42,7 @@ if (!defined('GNUSOCIAL')) { exit(1); }
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||
* @link http://status.net/
|
||||
*/
|
||||
class GroupbyidAction extends ManagedAction
|
||||
class GroupbyidAction extends ShowgroupAction
|
||||
{
|
||||
/** group we're viewing. */
|
||||
protected $group = null;
|
||||
@ -55,10 +55,10 @@ class GroupbyidAction extends ManagedAction
|
||||
protected function doPreparation()
|
||||
{
|
||||
$this->group = User_group::getByID($this->arg('id'));
|
||||
}
|
||||
$this->target = $this->group->getProfile();
|
||||
|
||||
public function showPage()
|
||||
{
|
||||
common_redirect($this->group->homeUrl(), 303);
|
||||
if ($this->target->isLocal()) {
|
||||
common_redirect($this->target->getUrl());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -211,6 +211,10 @@ class GrouplogoAction extends GroupAction
|
||||
'height' => AVATAR_PROFILE_SIZE,
|
||||
'alt' => $this->group->nickname));
|
||||
$this->elementEnd('div');
|
||||
if (!empty($this->group->homepage_logo)) {
|
||||
// TRANS: Button on group logo upload page to delete current group logo.
|
||||
$this->submit('delete', _('Delete'));
|
||||
}
|
||||
$this->elementEnd('li');
|
||||
}
|
||||
|
||||
@ -315,6 +319,8 @@ class GrouplogoAction extends GroupAction
|
||||
$this->uploadLogo();
|
||||
} else if ($this->arg('crop')) {
|
||||
$this->cropLogo();
|
||||
} else if ($this->arg('delete')) {
|
||||
$this->deleteLogo();
|
||||
} else {
|
||||
// TRANS: Form validation error message when an unsupported argument is used.
|
||||
$this->showForm(_('Unexpected form submission.'));
|
||||
@ -409,6 +415,29 @@ class GrouplogoAction extends GroupAction
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get rid of the current group logo.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
function deleteLogo()
|
||||
{
|
||||
$orig = clone($this->group);
|
||||
Avatar::deleteFromProfile($this->group->getProfile());
|
||||
@unlink(Avatar::path(basename($this->group->original_logo)));
|
||||
@unlink(Avatar::path(basename($this->group->homepage_logo)));
|
||||
@unlink(Avatar::path(basename($this->group->stream_logo)));
|
||||
@unlink(Avatar::path(basename($this->group->mini_logo)));
|
||||
$this->group->original_logo=User_group::defaultLogo(AVATAR_PROFILE_SIZE);
|
||||
$this->group->homepage_logo=User_group::defaultLogo(AVATAR_PROFILE_SIZE);
|
||||
$this->group->stream_logo=User_group::defaultLogo(AVATAR_STREAM_SIZE);
|
||||
$this->group->mini_logo=User_group::defaultLogo(AVATAR_MINI_SIZE);
|
||||
$this->group->update($orig);
|
||||
|
||||
// TRANS: Success message for deleting the group logo.
|
||||
$this->showForm(_('Logo deleted.'));
|
||||
}
|
||||
|
||||
function showPageNotice()
|
||||
{
|
||||
if ($this->msg) {
|
||||
|
@ -27,12 +27,7 @@
|
||||
* @link http://status.net/
|
||||
*/
|
||||
|
||||
if (!defined('STATUSNET') && !defined('LACONICA')) {
|
||||
exit(1);
|
||||
}
|
||||
|
||||
require_once(INSTALLDIR.'/lib/profilelist.php');
|
||||
require_once INSTALLDIR.'/lib/publicgroupnav.php';
|
||||
if (!defined('GNUSOCIAL')) { exit(1); }
|
||||
|
||||
/**
|
||||
* List of group members
|
||||
@ -52,15 +47,6 @@ class GroupmembersAction extends GroupAction
|
||||
return true;
|
||||
}
|
||||
|
||||
protected function prepare(array $args=array())
|
||||
{
|
||||
parent::prepare($args);
|
||||
|
||||
$this->page = ($this->arg('page')) ? ($this->arg('page')+0) : 1;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
function title()
|
||||
{
|
||||
if ($this->page == 1) {
|
||||
|
@ -153,7 +153,7 @@ class GroupqueueAction extends GroupAction
|
||||
// @todo FIXME: documentation missing.
|
||||
class GroupQueueList extends GroupMemberList
|
||||
{
|
||||
function newListItem($profile)
|
||||
function newListItem(Profile $profile)
|
||||
{
|
||||
return new GroupQueueListItem($profile, $this->group, $this->action);
|
||||
}
|
||||
|
@ -67,16 +67,16 @@ class GroupsAction extends Action
|
||||
}
|
||||
}
|
||||
|
||||
function prepare($args)
|
||||
function prepare(array $args = array())
|
||||
{
|
||||
parent::prepare($args);
|
||||
$this->page = ($this->arg('page')) ? ($this->arg('page')+0) : 1;
|
||||
return true;
|
||||
}
|
||||
|
||||
function handle($args)
|
||||
function handle()
|
||||
{
|
||||
parent::handle($args);
|
||||
parent::handle();
|
||||
$this->showPage();
|
||||
}
|
||||
|
||||
|
@ -52,7 +52,7 @@ class GroupunblockAction extends Action
|
||||
*
|
||||
* @return boolean success flag
|
||||
*/
|
||||
function prepare($args)
|
||||
function prepare(array $args = array())
|
||||
{
|
||||
parent::prepare($args);
|
||||
if (!common_logged_in()) {
|
||||
@ -103,9 +103,9 @@ class GroupunblockAction extends Action
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
function handle($args)
|
||||
function handle()
|
||||
{
|
||||
parent::handle($args);
|
||||
parent::handle();
|
||||
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
|
||||
$this->unblockProfile();
|
||||
}
|
||||
|
@ -359,13 +359,7 @@ class ImsettingsAction extends SettingsAction
|
||||
throw new AlreadyFulfilledException(_('No pending confirmation to cancel.'));
|
||||
}
|
||||
|
||||
$result = $confirm->delete();
|
||||
|
||||
if ($result === false) {
|
||||
common_log_db_error($confirm, 'DELETE', __FILE__);
|
||||
// TRANS: Server error thrown on database error canceling IM address confirmation.
|
||||
throw new ServerException(_('Could not delete confirmation.'));
|
||||
}
|
||||
$confirm->delete();
|
||||
|
||||
// TRANS: Message given after successfully canceling IM address confirmation.
|
||||
return _('IM confirmation cancelled.');
|
||||
|
@ -38,9 +38,9 @@ class InviteAction extends Action
|
||||
return false;
|
||||
}
|
||||
|
||||
function handle($args)
|
||||
function handle()
|
||||
{
|
||||
parent::handle($args);
|
||||
parent::handle();
|
||||
if (!common_config('invite', 'enabled')) {
|
||||
// TRANS: Client error displayed when trying to sent invites while they have been disabled.
|
||||
$this->clientError(_('Invites have been disabled.'));
|
||||
|
@ -54,7 +54,7 @@ class MakeadminAction extends RedirectingAction
|
||||
* @return boolean success flag
|
||||
*/
|
||||
|
||||
function prepare($args)
|
||||
function prepare(array $args = array())
|
||||
{
|
||||
parent::prepare($args);
|
||||
if (!common_logged_in()) {
|
||||
@ -111,9 +111,9 @@ class MakeadminAction extends RedirectingAction
|
||||
* @return void
|
||||
*/
|
||||
|
||||
function handle($args)
|
||||
function handle()
|
||||
{
|
||||
parent::handle($args);
|
||||
parent::handle();
|
||||
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
|
||||
$this->makeAdmin();
|
||||
}
|
||||
|
@ -1,82 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Microsummary action, see https://wiki.mozilla.org/Microsummaries
|
||||
*
|
||||
* PHP version 5
|
||||
*
|
||||
* @category Action
|
||||
* @package StatusNet
|
||||
* @author Evan Prodromou <evan@status.net>
|
||||
* @author Robin Millette <millette@status.net>
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl.html AGPLv3
|
||||
* @link http://status.net/
|
||||
*
|
||||
* StatusNet - the distributed open-source microblogging tool
|
||||
* Copyright (C) 2008, 2009, StatusNet, Inc.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
if (!defined('STATUSNET') && !defined('LACONICA')) {
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Microsummary action class.
|
||||
*
|
||||
* @category Action
|
||||
* @package StatusNet
|
||||
* @author Evan Prodromou <evan@status.net>
|
||||
* @author Robin Millette <millette@status.net>
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl.html AGPLv3
|
||||
* @link http://status.net/
|
||||
*/
|
||||
class MicrosummaryAction extends Action
|
||||
{
|
||||
/**
|
||||
* Class handler.
|
||||
*
|
||||
* @param array $args array of arguments
|
||||
*
|
||||
* @return nothing
|
||||
*/
|
||||
function handle($args)
|
||||
{
|
||||
parent::handle($args);
|
||||
|
||||
$nickname = common_canonical_nickname($this->arg('nickname'));
|
||||
$user = User::getKV('nickname', $nickname);
|
||||
|
||||
if (!$user) {
|
||||
// TRANS: Client error displayed trying to make a micro summary without providing a valid user.
|
||||
$this->clientError(_('No such user.'), 404);
|
||||
}
|
||||
|
||||
$notice = $user->getCurrentNotice();
|
||||
|
||||
if (!$notice) {
|
||||
// TRANS: Client error displayed trying to make a micro summary without providing a status.
|
||||
$this->clientError(_('No current status.'), 404);
|
||||
}
|
||||
|
||||
header('Content-Type: text/plain');
|
||||
|
||||
print $user->nickname . ': ' . $notice->content;
|
||||
}
|
||||
|
||||
function isReadOnly($args)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
@ -47,6 +47,8 @@ class NewnoticeAction extends FormAction
|
||||
{
|
||||
protected $form = 'Notice';
|
||||
|
||||
protected $inreplyto = null;
|
||||
|
||||
/**
|
||||
* Title of the page
|
||||
*
|
||||
@ -75,6 +77,11 @@ class NewnoticeAction extends FormAction
|
||||
}
|
||||
}
|
||||
|
||||
if ($this->int('inreplyto')) {
|
||||
// Throws exception if the inreplyto Notice is given but not found.
|
||||
$this->inreplyto = Notice::getByID($this->int('inreplyto'));
|
||||
}
|
||||
|
||||
// Backwards compatibility for "share this" widget things.
|
||||
// If no 'content', use 'status_textarea'
|
||||
$this->formOpts['content'] = $this->trimmed('content') ?: $this->trimmed('status_textarea');
|
||||
@ -115,7 +122,7 @@ class NewnoticeAction extends FormAction
|
||||
// simply no attached media to the new notice
|
||||
if (empty($content)) {
|
||||
// TRANS: Client error displayed trying to send a notice without content.
|
||||
$this->clientError(_('No content!'));
|
||||
throw new ClientException(_('No content!'));
|
||||
}
|
||||
}
|
||||
|
||||
@ -132,13 +139,6 @@ class NewnoticeAction extends FormAction
|
||||
return;
|
||||
}
|
||||
|
||||
if ($this->int('inreplyto')) {
|
||||
// Throws exception if the inreplyto Notice is given but not found.
|
||||
$parent = Notice::getByID($this->int('inreplyto'));
|
||||
} else {
|
||||
$parent = null;
|
||||
}
|
||||
|
||||
$act = new Activity();
|
||||
$act->verb = ActivityVerb::POST;
|
||||
$act->time = time();
|
||||
@ -157,9 +157,9 @@ class NewnoticeAction extends FormAction
|
||||
|
||||
$act->context = new ActivityContext();
|
||||
|
||||
if ($parent instanceof Notice) {
|
||||
$act->context->replyToID = $parent->getUri();
|
||||
$act->context->replyToUrl = $parent->getUrl(true); // maybe we don't have to send true here to force a URL?
|
||||
if ($this->inreplyto instanceof Notice) {
|
||||
$act->context->replyToID = $this->inreplyto->getUri();
|
||||
$act->context->replyToUrl = $this->inreplyto->getUrl(true); // maybe we don't have to send true here to force a URL?
|
||||
}
|
||||
|
||||
if ($this->scoped->shareLocation()) {
|
||||
@ -188,14 +188,14 @@ class NewnoticeAction extends FormAction
|
||||
|
||||
// FIXME: We should be able to get the attentions from common_render_content!
|
||||
// and maybe even directly save whether they're local or not!
|
||||
$act->context->attention = common_get_attentions($content, $this->scoped, $parent);
|
||||
$act->context->attention = common_get_attentions($content, $this->scoped, $this->inreplyto);
|
||||
|
||||
// $options gets filled with possible scoping settings
|
||||
ToSelector::fillActivity($this, $act, $options);
|
||||
|
||||
$actobj = new ActivityObject();
|
||||
$actobj->type = ActivityObject::NOTE;
|
||||
$actobj->content = common_render_content($content, $this->scoped, $parent);
|
||||
$actobj->content = common_render_content($content, $this->scoped, $this->inreplyto);
|
||||
|
||||
// Finally add the activity object to our activity
|
||||
$act->objects[] = $actobj;
|
||||
@ -224,6 +224,9 @@ class NewnoticeAction extends FormAction
|
||||
if ($this->getInfo() && $this->stored instanceof Notice) {
|
||||
$this->showNotice($this->stored);
|
||||
} elseif (!$this->getError()) {
|
||||
if (!GNUsocial::isAjax() && $this->inreplyto instanceof Notice) {
|
||||
$this->showNotice($this->inreplyto);
|
||||
}
|
||||
parent::showContent();
|
||||
}
|
||||
}
|
||||
|
@ -50,7 +50,7 @@ class NoticesearchAction extends SearchAction
|
||||
{
|
||||
protected $q = null;
|
||||
|
||||
function prepare($args)
|
||||
function prepare(array $args = array())
|
||||
{
|
||||
parent::prepare($args);
|
||||
|
||||
@ -65,8 +65,7 @@ class NoticesearchAction extends SearchAction
|
||||
|
||||
if (!empty($this->q)) {
|
||||
|
||||
$profile = Profile::current();
|
||||
$stream = new SearchNoticeStream($this->q, $profile);
|
||||
$stream = new SearchNoticeStream($this->q, $this->scoped);
|
||||
$page = $this->trimmed('page');
|
||||
|
||||
if (empty($page)) {
|
||||
@ -186,7 +185,7 @@ class SearchNoticeList extends NoticeList {
|
||||
$this->terms = $terms;
|
||||
}
|
||||
|
||||
function newListItem($notice)
|
||||
function newListItem(Notice $notice)
|
||||
{
|
||||
return new SearchNoticeListItem($notice, $this->out, $this->terms);
|
||||
}
|
||||
|
@ -55,9 +55,9 @@ class NudgeAction extends Action
|
||||
*
|
||||
* @return nothing
|
||||
*/
|
||||
function handle($args)
|
||||
function handle()
|
||||
{
|
||||
parent::handle($args);
|
||||
parent::handle();
|
||||
|
||||
if (!common_logged_in()) {
|
||||
// TRANS: Error message displayed when trying to perform an action that requires a logged in user.
|
||||
|
@ -53,9 +53,9 @@ class OpensearchAction extends Action
|
||||
*
|
||||
* @return boolean false if user doesn't exist
|
||||
*/
|
||||
function handle($args)
|
||||
function handle()
|
||||
{
|
||||
parent::handle($args);
|
||||
parent::handle();
|
||||
$type = $this->trimmed('type');
|
||||
$short_name = '';
|
||||
if ($type == 'people') {
|
||||
|
@ -53,7 +53,7 @@ class OtpAction extends Action
|
||||
var $returnto;
|
||||
var $lt;
|
||||
|
||||
function prepare($args)
|
||||
function prepare(array $args = array())
|
||||
{
|
||||
parent::prepare($args);
|
||||
|
||||
@ -110,9 +110,9 @@ class OtpAction extends Action
|
||||
return true;
|
||||
}
|
||||
|
||||
function handle($args)
|
||||
function handle()
|
||||
{
|
||||
parent::handle($args);
|
||||
parent::handle();
|
||||
|
||||
// success!
|
||||
if (!common_set_user($this->user)) {
|
||||
|
@ -62,7 +62,7 @@ class PeopletagAction extends Action
|
||||
}
|
||||
}
|
||||
|
||||
function prepare($args)
|
||||
function prepare(array $args = array())
|
||||
{
|
||||
parent::prepare($args);
|
||||
$this->page = ($this->arg('page')) ? ($this->arg('page')+0) : 1;
|
||||
@ -84,9 +84,9 @@ class PeopletagAction extends Action
|
||||
return true;
|
||||
}
|
||||
|
||||
function handle($args)
|
||||
function handle()
|
||||
{
|
||||
parent::handle($args);
|
||||
parent::handle();
|
||||
$this->showPage();
|
||||
}
|
||||
|
||||
|
@ -44,7 +44,7 @@ class PeopletagautocompleteAction extends Action
|
||||
*
|
||||
* @return boolean success flag
|
||||
*/
|
||||
function prepare($args)
|
||||
function prepare(array $args = array())
|
||||
{
|
||||
parent::prepare($args);
|
||||
|
||||
@ -112,7 +112,7 @@ class PeopletagautocompleteAction extends Action
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
function handle($args)
|
||||
function handle()
|
||||
{
|
||||
//common_log(LOG_DEBUG, 'Autocomplete data: ' . json_encode($this->tags));
|
||||
if ($this->tags) {
|
||||
|
@ -53,7 +53,7 @@ class PeopletaggedAction extends Action
|
||||
return true;
|
||||
}
|
||||
|
||||
function prepare($args)
|
||||
function prepare(array $args = array())
|
||||
{
|
||||
parent::prepare($args);
|
||||
$this->page = ($this->arg('page')) ? ($this->arg('page')+0) : 1;
|
||||
@ -117,9 +117,9 @@ class PeopletaggedAction extends Action
|
||||
}
|
||||
}
|
||||
|
||||
function handle($args)
|
||||
function handle()
|
||||
{
|
||||
parent::handle($args);
|
||||
parent::handle();
|
||||
$this->showPage();
|
||||
}
|
||||
|
||||
@ -167,7 +167,7 @@ class PeopletagMemberList extends ProfileList
|
||||
$this->peopletag = $peopletag;
|
||||
}
|
||||
|
||||
function newListItem($profile)
|
||||
function newListItem(Profile $profile)
|
||||
{
|
||||
return new PeopletagMemberListItem($profile, $this->peopletag, $this->action);
|
||||
}
|
||||
|
@ -68,7 +68,7 @@ class PeopletagsbyuserAction extends Action
|
||||
}
|
||||
}
|
||||
|
||||
function prepare($args)
|
||||
function prepare(array $args = array())
|
||||
{
|
||||
parent::prepare($args);
|
||||
|
||||
@ -135,9 +135,9 @@ class PeopletagsbyuserAction extends Action
|
||||
return true;
|
||||
}
|
||||
|
||||
function handle($args)
|
||||
function handle()
|
||||
{
|
||||
parent::handle($args);
|
||||
parent::handle();
|
||||
|
||||
# Post from the tag dropdown; redirect to a GET
|
||||
|
||||
|
@ -54,7 +54,7 @@ class PeopletagsforuserAction extends Action
|
||||
}
|
||||
}
|
||||
|
||||
function prepare($args)
|
||||
function prepare(array $args = array())
|
||||
{
|
||||
parent::prepare($args);
|
||||
|
||||
@ -95,9 +95,9 @@ class PeopletagsforuserAction extends Action
|
||||
return true;
|
||||
}
|
||||
|
||||
function handle($args)
|
||||
function handle()
|
||||
{
|
||||
parent::handle($args);
|
||||
parent::handle();
|
||||
$this->showPage();
|
||||
}
|
||||
|
||||
|
@ -53,7 +53,7 @@ class PeopletagsubscribersAction extends Action
|
||||
return true;
|
||||
}
|
||||
|
||||
function prepare($args)
|
||||
function prepare(array $args = array())
|
||||
{
|
||||
parent::prepare($args);
|
||||
$this->page = ($this->arg('page')) ? ($this->arg('page')+0) : 1;
|
||||
@ -117,9 +117,9 @@ class PeopletagsubscribersAction extends Action
|
||||
}
|
||||
}
|
||||
|
||||
function handle($args)
|
||||
function handle()
|
||||
{
|
||||
parent::handle($args);
|
||||
parent::handle();
|
||||
$this->showPage();
|
||||
}
|
||||
|
||||
@ -167,7 +167,7 @@ class PeopletagSubscriberList extends ProfileList
|
||||
$this->peopletag = $peopletag;
|
||||
}
|
||||
|
||||
function newListItem($profile)
|
||||
function newListItem(Profile $profile)
|
||||
{
|
||||
return new PeopletagSubscriberListItem($profile, $this->peopletag, $this->action);
|
||||
}
|
||||
|
@ -56,7 +56,7 @@ class PeopletagsubscriptionsAction extends Action
|
||||
}
|
||||
}
|
||||
|
||||
function prepare($args)
|
||||
function prepare(array $args = array())
|
||||
{
|
||||
parent::prepare($args);
|
||||
|
||||
@ -97,9 +97,9 @@ class PeopletagsubscriptionsAction extends Action
|
||||
return true;
|
||||
}
|
||||
|
||||
function handle($args)
|
||||
function handle()
|
||||
{
|
||||
parent::handle($args);
|
||||
parent::handle();
|
||||
$this->showPage();
|
||||
}
|
||||
|
||||
|
@ -64,7 +64,7 @@ class PluginEnableAction extends Action
|
||||
*
|
||||
* @return boolean success flag
|
||||
*/
|
||||
function prepare($args)
|
||||
function prepare(array $args = array())
|
||||
{
|
||||
parent::prepare($args);
|
||||
|
||||
@ -121,7 +121,7 @@ class PluginEnableAction extends Action
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
function handle($args)
|
||||
function handle()
|
||||
{
|
||||
$key = 'disable-' . $this->plugin;
|
||||
Config::save('plugins', $key, $this->overrideValue());
|
||||
|
@ -68,7 +68,7 @@ class ProfilecompletionAction extends Action
|
||||
*
|
||||
* @return boolean success flag
|
||||
*/
|
||||
function prepare($args)
|
||||
function prepare(array $args = array())
|
||||
{
|
||||
parent::prepare($args);
|
||||
|
||||
@ -120,7 +120,7 @@ class ProfilecompletionAction extends Action
|
||||
* @return void
|
||||
*/
|
||||
|
||||
function handle($args)
|
||||
function handle()
|
||||
{
|
||||
$this->msg = null;
|
||||
|
||||
|
@ -45,7 +45,7 @@ class ProfiletagbyidAction extends Action
|
||||
return true;
|
||||
}
|
||||
|
||||
function prepare($args)
|
||||
function prepare(array $args = array())
|
||||
{
|
||||
parent::prepare($args);
|
||||
|
||||
@ -83,7 +83,7 @@ class ProfiletagbyidAction extends Action
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
function handle($args)
|
||||
function handle()
|
||||
{
|
||||
common_redirect($this->peopletag->homeUrl(), 303);
|
||||
}
|
||||
|
@ -86,12 +86,6 @@ class PublicAction extends SitestreamAction
|
||||
$ibs->show();
|
||||
}
|
||||
|
||||
$p = Profile::current();
|
||||
|
||||
if (!common_config('performance', 'high')) {
|
||||
$cloud = new PublicTagCloudSection($this);
|
||||
$cloud->show();
|
||||
}
|
||||
$feat = new FeaturedUsersSection($this);
|
||||
$feat->show();
|
||||
}
|
||||
|
@ -29,9 +29,9 @@ class RecoverpasswordAction extends Action
|
||||
var $msg = null;
|
||||
var $success = null;
|
||||
|
||||
function handle($args)
|
||||
function handle()
|
||||
{
|
||||
parent::handle($args);
|
||||
parent::handle();
|
||||
if (common_logged_in()) {
|
||||
// TRANS: Client error displayed trying to recover password while already logged in.
|
||||
$this->clientError(_('You are already logged in!'));
|
||||
@ -79,13 +79,7 @@ class RecoverpasswordAction extends Action
|
||||
|
||||
// Burn this code
|
||||
|
||||
$result = $confirm->delete();
|
||||
|
||||
if (!$result) {
|
||||
common_log_db_error($confirm, 'DELETE', __FILE__);
|
||||
// TRANS: Server error displayed removing a password recovery code from the database.
|
||||
$this->serverError(_('Error with confirmation code.'));
|
||||
}
|
||||
$confirm->delete();
|
||||
|
||||
// These should be reaped, but for now we just check mod time
|
||||
// Note: it's still deleted; let's avoid a second attempt!
|
||||
|
@ -63,7 +63,7 @@ class RedirectAction extends Action
|
||||
*
|
||||
* @return nothing
|
||||
*/
|
||||
function handle($args)
|
||||
function handle()
|
||||
{
|
||||
common_redirect(common_local_url($this->arg('nextAction'), $this->arg('args')));
|
||||
}
|
||||
|
@ -120,9 +120,9 @@ class RegisterAction extends Action
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
function handle($args)
|
||||
function handle()
|
||||
{
|
||||
parent::handle($args);
|
||||
parent::handle();
|
||||
|
||||
if (common_config('site', 'closed')) {
|
||||
// TRANS: Client error displayed when trying to register to a closed site.
|
||||
|
@ -66,7 +66,7 @@ class RemovepeopletagAction extends Action
|
||||
*
|
||||
* @return boolean success flag
|
||||
*/
|
||||
function prepare($args)
|
||||
function prepare(array $args = array())
|
||||
{
|
||||
parent::prepare($args);
|
||||
|
||||
@ -120,7 +120,7 @@ class RemovepeopletagAction extends Action
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
function handle($args)
|
||||
function handle()
|
||||
{
|
||||
// Throws exception on error
|
||||
|
||||
|
@ -49,7 +49,7 @@ class RevokeRoleAction extends ProfileFormAction
|
||||
*
|
||||
* @return boolean success flag
|
||||
*/
|
||||
function prepare($args)
|
||||
function prepare(array $args = array())
|
||||
{
|
||||
if (!parent::prepare($args)) {
|
||||
return false;
|
||||
|
@ -85,7 +85,7 @@ class RsdAction extends Action
|
||||
*
|
||||
* @return boolean success flag
|
||||
*/
|
||||
function prepare($args)
|
||||
function prepare(array $args = array())
|
||||
{
|
||||
parent::prepare($args);
|
||||
|
||||
@ -126,7 +126,7 @@ class RsdAction extends Action
|
||||
*
|
||||
* @return nothing
|
||||
*/
|
||||
function handle($args)
|
||||
function handle()
|
||||
{
|
||||
header('Content-Type: application/rsd+xml');
|
||||
|
||||
|
@ -49,7 +49,7 @@ class SandboxAction extends ProfileFormAction
|
||||
*
|
||||
* @return boolean success flag
|
||||
*/
|
||||
function prepare($args)
|
||||
function prepare(array $args = array())
|
||||
{
|
||||
if (!parent::prepare($args)) {
|
||||
return false;
|
||||
|
@ -158,9 +158,9 @@ class SelftagAction extends Action
|
||||
|
||||
class SelfTagProfileList extends ProfileList
|
||||
{
|
||||
function newListItem($profile)
|
||||
function newListItem(Profile $target)
|
||||
{
|
||||
return new SelfTagProfileListItem($profile, $this->action);
|
||||
return new SelfTagProfileListItem($target, $this->action);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -65,7 +65,7 @@ class ShowApplicationAction extends Action
|
||||
*
|
||||
* @return success flag
|
||||
*/
|
||||
function prepare($args)
|
||||
function prepare(array $args = array())
|
||||
{
|
||||
parent::prepare($args);
|
||||
|
||||
@ -101,9 +101,9 @@ class ShowApplicationAction extends Action
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
function handle($args)
|
||||
function handle()
|
||||
{
|
||||
parent::handle($args);
|
||||
parent::handle();
|
||||
|
||||
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
|
||||
|
||||
|
@ -28,12 +28,7 @@
|
||||
* @link http://status.net/
|
||||
*/
|
||||
|
||||
if (!defined('STATUSNET') && !defined('LACONICA')) {
|
||||
exit(1);
|
||||
}
|
||||
|
||||
require_once INSTALLDIR.'/lib/noticelist.php';
|
||||
require_once INSTALLDIR.'/lib/feedlist.php';
|
||||
if (!defined('GNUSOCIAL')) { exit(1); }
|
||||
|
||||
/**
|
||||
* Group main page
|
||||
@ -48,7 +43,6 @@ class ShowgroupAction extends GroupAction
|
||||
{
|
||||
/** page we're viewing. */
|
||||
var $page = null;
|
||||
var $userProfile = null;
|
||||
var $notice = null;
|
||||
|
||||
/**
|
||||
@ -82,85 +76,15 @@ class ShowgroupAction extends GroupAction
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepare the action
|
||||
*
|
||||
* Reads and validates arguments and instantiates the attributes.
|
||||
*
|
||||
* @param array $args $_REQUEST args
|
||||
*
|
||||
* @return boolean success flag
|
||||
*/
|
||||
protected function prepare(array $args=array())
|
||||
public function getStream()
|
||||
{
|
||||
parent::prepare($args);
|
||||
|
||||
$this->page = ($this->arg('page')) ? ($this->arg('page')+0) : 1;
|
||||
|
||||
$this->userProfile = Profile::current();
|
||||
|
||||
$user = common_current_user();
|
||||
|
||||
if (!empty($user) && $user->streamModeOnly()) {
|
||||
$stream = new GroupNoticeStream($this->group, $this->userProfile);
|
||||
if ($this->scoped instanceof Profile && $this->scoped->isLocal() && $this->scoped->getUser()->streamModeOnly()) {
|
||||
$stream = new GroupNoticeStream($this->group, $this->scoped);
|
||||
} else {
|
||||
$stream = new ThreadingGroupNoticeStream($this->group, $this->userProfile);
|
||||
$stream = new ThreadingGroupNoticeStream($this->group, $this->scoped);
|
||||
}
|
||||
|
||||
$this->notice = $stream->getNotices(($this->page-1)*NOTICES_PER_PAGE,
|
||||
NOTICES_PER_PAGE + 1);
|
||||
|
||||
common_set_returnto($this->selfUrl());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle the request
|
||||
*
|
||||
* Shows a profile for the group, some controls, and a list of
|
||||
* group notices.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function handle()
|
||||
{
|
||||
parent::handle();
|
||||
$this->showPage();
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the page content
|
||||
*
|
||||
* Shows a group profile and a list of group notices
|
||||
*/
|
||||
function showContent()
|
||||
{
|
||||
$this->showGroupNotices();
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the group notices
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
function showGroupNotices()
|
||||
{
|
||||
$user = common_current_user();
|
||||
|
||||
if (!empty($user) && $user->streamModeOnly()) {
|
||||
$nl = new PrimaryNoticeList($this->notice, $this, array('show_n'=>NOTICES_PER_PAGE));
|
||||
} else {
|
||||
$nl = new ThreadedNoticeList($this->notice, $this, $this->userProfile);
|
||||
}
|
||||
|
||||
$cnt = $nl->show();
|
||||
|
||||
$this->pagination($this->page > 1,
|
||||
$cnt > NOTICES_PER_PAGE,
|
||||
$this->page,
|
||||
'showgroup',
|
||||
array('nickname' => $this->group->nickname));
|
||||
return $stream;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -113,6 +113,18 @@ class ShowstreamAction extends NoticestreamAction
|
||||
$this->target->getNickname(), $this->tag)));
|
||||
}
|
||||
|
||||
if (!$this->target->isLocal()) {
|
||||
// remote profiles at least have Atom, but we can't guarantee anything else
|
||||
return array(
|
||||
new Feed(Feed::ATOM,
|
||||
$this->target->getAtomFeed(),
|
||||
// TRANS: Title for link to notice feed.
|
||||
// TRANS: %s is a user nickname.
|
||||
sprintf(_('Notice feed for %s (Atom)'),
|
||||
$this->target->getNickname()))
|
||||
);
|
||||
}
|
||||
|
||||
return array(new Feed(Feed::JSON,
|
||||
common_local_url('ApiTimelineUser',
|
||||
array(
|
||||
@ -139,10 +151,7 @@ class ShowstreamAction extends NoticestreamAction
|
||||
sprintf(_('Notice feed for %s (RSS 2.0)'),
|
||||
$this->target->getNickname())),
|
||||
new Feed(Feed::ATOM,
|
||||
common_local_url('ApiTimelineUser',
|
||||
array(
|
||||
'id' => $this->target->getID(),
|
||||
'format' => 'atom')),
|
||||
$this->target->getAtomFeed(),
|
||||
// TRANS: Title for link to notice feed.
|
||||
// TRANS: %s is a user nickname.
|
||||
sprintf(_('Notice feed for %s (Atom)'),
|
||||
@ -155,6 +164,17 @@ class ShowstreamAction extends NoticestreamAction
|
||||
sprintf(_('FOAF for %s'), $this->target->getNickname())));
|
||||
}
|
||||
|
||||
public function extraHeaders()
|
||||
{
|
||||
parent::extraHeaders();
|
||||
// Publish all the rel="me" in the HTTP headers on our main profile page
|
||||
if (get_class($this) == 'ShowstreamAction') {
|
||||
foreach ($this->target->getRelMes() as $relMe) {
|
||||
header('Link: <'.htmlspecialchars($relMe['href']).'>; rel="me"', false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function extraHead()
|
||||
{
|
||||
if ($this->target->bio) {
|
||||
@ -162,12 +182,6 @@ class ShowstreamAction extends NoticestreamAction
|
||||
'content' => $this->target->getDescription()));
|
||||
}
|
||||
|
||||
// See https://wiki.mozilla.org/Microsummaries
|
||||
|
||||
$this->element('link', array('rel' => 'microsummary',
|
||||
'href' => common_local_url('microsummary',
|
||||
array('nickname' => $this->target->getNickname()))));
|
||||
|
||||
$rsd = common_local_url('rsd',
|
||||
array('nickname' => $this->target->getNickname()));
|
||||
|
||||
@ -210,19 +224,20 @@ class ShowstreamAction extends NoticestreamAction
|
||||
|
||||
function showNotices()
|
||||
{
|
||||
$pnl = new NoticeList($this->notice, $this);
|
||||
$pnl = new PrimaryNoticeList($this->notice, $this);
|
||||
$cnt = $pnl->show();
|
||||
if (0 == $cnt) {
|
||||
$this->showEmptyListMessage();
|
||||
}
|
||||
|
||||
$args = array('nickname' => $this->target->getNickname());
|
||||
// either nickname or id will be used, depending on which action (showstream, userbyid...)
|
||||
$args = array('nickname' => $this->target->getNickname(), 'id' => $this->target->getID());
|
||||
if (!empty($this->tag))
|
||||
{
|
||||
$args['tag'] = $this->tag;
|
||||
}
|
||||
$this->pagination($this->page>1, $cnt>NOTICES_PER_PAGE, $this->page,
|
||||
'showstream', $args);
|
||||
$this->getActionName(), $args);
|
||||
}
|
||||
|
||||
function showAnonymousMessage()
|
||||
@ -246,15 +261,6 @@ class ShowstreamAction extends NoticestreamAction
|
||||
$this->elementEnd('div');
|
||||
}
|
||||
|
||||
function showSections()
|
||||
{
|
||||
parent::showSections();
|
||||
if (!common_config('performance', 'high')) {
|
||||
$cloud = new PersonalTagCloudSection($this->target, $this);
|
||||
$cloud->show();
|
||||
}
|
||||
}
|
||||
|
||||
function noticeFormOptions()
|
||||
{
|
||||
$options = parent::noticeFormOptions();
|
||||
|
@ -110,9 +110,7 @@ class SitenoticeadminpanelAction extends AdminPanelAction
|
||||
}
|
||||
|
||||
// scrub HTML input
|
||||
require_once INSTALLDIR.'/extlib/HTMLPurifier/HTMLPurifier.auto.php';
|
||||
$purifier = new HTMLPurifier();
|
||||
$siteNotice = $purifier->purify($siteNotice);
|
||||
$siteNotice = common_purify($siteNotice);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -368,13 +368,7 @@ class SmssettingsAction extends SettingsAction
|
||||
throw new AlreadyFulfilledException(_('No pending confirmation to cancel.'));
|
||||
}
|
||||
|
||||
$result = $confirm->delete();
|
||||
|
||||
if ($result === false) {
|
||||
common_log_db_error($confirm, 'DELETE', __FILE__);
|
||||
// TRANS: Server error thrown on database error canceling SMS phone number confirmation.
|
||||
throw new ServerException(_('Could not delete SMS confirmation.'));
|
||||
}
|
||||
$confirm->delete();
|
||||
|
||||
// TRANS: Message given after successfully canceling SMS phone number confirmation.
|
||||
return _('SMS confirmation cancelled.');
|
||||
|
@ -24,7 +24,7 @@ class SubeditAction extends Action
|
||||
{
|
||||
var $profile = null;
|
||||
|
||||
function prepare($args)
|
||||
function prepare(array $args = array())
|
||||
{
|
||||
parent::prepare($args);
|
||||
|
||||
@ -58,9 +58,9 @@ class SubeditAction extends Action
|
||||
return true;
|
||||
}
|
||||
|
||||
function handle($args)
|
||||
function handle()
|
||||
{
|
||||
parent::handle($args);
|
||||
parent::handle();
|
||||
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
|
||||
$cur = common_current_user();
|
||||
|
||||
|
@ -64,7 +64,7 @@ class SubscribeAction extends Action
|
||||
*
|
||||
* @return boolean success flag
|
||||
*/
|
||||
function prepare($args)
|
||||
function prepare(array $args = array())
|
||||
{
|
||||
parent::prepare($args);
|
||||
|
||||
@ -118,7 +118,7 @@ class SubscribeAction extends Action
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
function handle($args)
|
||||
function handle()
|
||||
{
|
||||
// Throws exception on error
|
||||
|
||||
|
@ -50,7 +50,7 @@ class SubscribepeopletagAction extends Action
|
||||
/**
|
||||
* Prepare to run
|
||||
*/
|
||||
function prepare($args)
|
||||
function prepare(array $args = array())
|
||||
{
|
||||
parent::prepare($args);
|
||||
|
||||
@ -106,9 +106,9 @@ class SubscribepeopletagAction extends Action
|
||||
* @return void
|
||||
*/
|
||||
|
||||
function handle($args)
|
||||
function handle()
|
||||
{
|
||||
parent::handle($args);
|
||||
parent::handle();
|
||||
|
||||
$cur = common_current_user();
|
||||
|
||||
|
@ -22,9 +22,9 @@ if (!defined('STATUSNET') && !defined('LACONICA')) { exit(1); }
|
||||
// @todo FIXME: documentation needed.
|
||||
class SupAction extends Action
|
||||
{
|
||||
function handle($args)
|
||||
function handle()
|
||||
{
|
||||
parent::handle($args);
|
||||
parent::handle();
|
||||
|
||||
$seconds = $this->trimmed('seconds');
|
||||
|
||||
|
@ -34,7 +34,7 @@ class TagAction extends ManagedAction
|
||||
$this->tag = common_canonical_tag($taginput);
|
||||
|
||||
if (empty($this->tag)) {
|
||||
common_redirect(common_local_url('publictagcloud'), 301);
|
||||
throw new ClientException(_('No valid tag data.'));
|
||||
}
|
||||
|
||||
// after common_canonical_tag we have a lowercase, no-specials tag string
|
||||
|
@ -44,7 +44,7 @@ if (!defined('STATUSNET') && !defined('LACONICA')) {
|
||||
*/
|
||||
class UnblockAction extends ProfileFormAction
|
||||
{
|
||||
function prepare($args)
|
||||
function prepare(array $args = array())
|
||||
{
|
||||
if (!parent::prepare($args)) {
|
||||
return false;
|
||||
|
@ -49,7 +49,7 @@ class UnsandboxAction extends ProfileFormAction
|
||||
*
|
||||
* @return boolean success flag
|
||||
*/
|
||||
function prepare($args)
|
||||
function prepare(array $args = array())
|
||||
{
|
||||
if (!parent::prepare($args)) {
|
||||
return false;
|
||||
|
@ -44,9 +44,9 @@ if (!defined('STATUSNET') && !defined('LACONICA')) {
|
||||
*/
|
||||
class UnsubscribeAction extends Action
|
||||
{
|
||||
function handle($args)
|
||||
function handle()
|
||||
{
|
||||
parent::handle($args);
|
||||
parent::handle();
|
||||
if (!common_logged_in()) {
|
||||
// TRANS: Error message displayed when trying to perform an action that requires a logged in user.
|
||||
$this->clientError(_('Not logged in.'));
|
||||
|
@ -51,7 +51,7 @@ class UnsubscribepeopletagAction extends Action
|
||||
* Prepare to run
|
||||
*/
|
||||
|
||||
function prepare($args)
|
||||
function prepare(array $args = array())
|
||||
{
|
||||
parent::prepare($args);
|
||||
|
||||
@ -106,9 +106,9 @@ class UnsubscribepeopletagAction extends Action
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
function handle($args)
|
||||
function handle()
|
||||
{
|
||||
parent::handle($args);
|
||||
parent::handle();
|
||||
|
||||
$cur = common_current_user();
|
||||
|
||||
|
@ -53,7 +53,7 @@ class Attention extends Managed_DataObject
|
||||
{
|
||||
try {
|
||||
$att = Attention::getByKeys(['notice_id'=>$notice->getID(), 'profile_id'=>$target->getID()]);
|
||||
throw new AlreadyFulfilledException('Attention already exists with reason: '.var_export($att->reason,true));
|
||||
throw new AlreadyFulfilledException('Attention already exists with reason: '._ve($att->reason));
|
||||
} catch (NoResultException $e) {
|
||||
$att = new Attention();
|
||||
|
||||
@ -67,6 +67,7 @@ class Attention extends Managed_DataObject
|
||||
throw new Exception('Failed Attention::saveNew for notice id=='.$notice->getID().' target id=='.$target->getID().', reason=="'.$reason.'"');
|
||||
}
|
||||
}
|
||||
self::blow('attention:stream:%d', $target->getID());
|
||||
return $att;
|
||||
}
|
||||
}
|
||||
|
@ -207,8 +207,11 @@ class Avatar extends Managed_DataObject
|
||||
}
|
||||
}
|
||||
|
||||
static function defaultImage($size)
|
||||
static function defaultImage($size=null)
|
||||
{
|
||||
if (is_null($size)) {
|
||||
$size = AVATAR_PROFILE_SIZE;
|
||||
}
|
||||
static $sizenames = array(AVATAR_PROFILE_SIZE => 'profile',
|
||||
AVATAR_STREAM_SIZE => 'stream',
|
||||
AVATAR_MINI_SIZE => 'mini');
|
||||
|
@ -35,18 +35,18 @@ class Confirm_address extends Managed_DataObject
|
||||
);
|
||||
}
|
||||
|
||||
static function getAddress($address, $addressType)
|
||||
static function getByAddress($address, $addressType)
|
||||
{
|
||||
$ca = new Confirm_address();
|
||||
|
||||
$ca->address = $address;
|
||||
$ca->address_type = $addressType;
|
||||
|
||||
if ($ca->find(true)) {
|
||||
return $ca;
|
||||
if (!$ca->find(true)) {
|
||||
throw new NoResultException($ca);
|
||||
}
|
||||
|
||||
return null;
|
||||
return $ca;
|
||||
}
|
||||
|
||||
static function saveNew($user, $address, $addressType, $extra=null)
|
||||
@ -66,4 +66,96 @@ class Confirm_address extends Managed_DataObject
|
||||
|
||||
return $ca;
|
||||
}
|
||||
|
||||
public function getAddress()
|
||||
{
|
||||
return $this->address;
|
||||
}
|
||||
|
||||
public function getAddressType()
|
||||
{
|
||||
return $this->address_type;
|
||||
}
|
||||
|
||||
public function getCode()
|
||||
{
|
||||
return $this->code;
|
||||
}
|
||||
|
||||
public function getProfile()
|
||||
{
|
||||
return Profile::getByID($this->user_id);
|
||||
}
|
||||
|
||||
public function getUrl()
|
||||
{
|
||||
return common_local_url('confirmaddress', array('code' => $this->code));
|
||||
}
|
||||
|
||||
/**
|
||||
* Supply arguments in $args. Currently known args:
|
||||
* headers Array with headers (only used for email)
|
||||
* nickname How we great the user (defaults to nickname, but can be any string)
|
||||
* sitename Name we sign the email with (defaults to sitename, but can be any string)
|
||||
* url The confirmation address URL.
|
||||
*/
|
||||
public function sendConfirmation(array $args=array())
|
||||
{
|
||||
common_debug('Sending confirmation URL for user '._ve($this->user_id).' using '._ve($this->address_type));
|
||||
|
||||
$defaults = [
|
||||
'headers' => array(),
|
||||
'nickname' => $this->getProfile()->getNickname(),
|
||||
'sitename' => common_config('site', 'name'),
|
||||
'url' => $this->getUrl(),
|
||||
];
|
||||
foreach (array_keys($defaults) as $key) {
|
||||
if (!isset($args[$key])) {
|
||||
$args[$key] = $defaults[$key];
|
||||
}
|
||||
}
|
||||
|
||||
switch ($this->getAddressType()) {
|
||||
case 'email':
|
||||
$this->sendEmailConfirmation($args);
|
||||
break;
|
||||
default:
|
||||
throw ServerException('Unable to handle confirm_address address type: '._ve($this->address_type));
|
||||
}
|
||||
}
|
||||
|
||||
public function sendEmailConfirmation(array $args=array())
|
||||
{
|
||||
// TRANS: Subject for address confirmation email.
|
||||
$subject = _('Email address confirmation');
|
||||
|
||||
// TRANS: Body for address confirmation email.
|
||||
// TRANS: %1$s is the addressed user's nickname, %2$s is the StatusNet sitename,
|
||||
// TRANS: %3$s is the URL to confirm at.
|
||||
$body = sprintf(_("Hey, %1\$s.\n\n".
|
||||
"Someone just entered this email address on %2\$s.\n\n" .
|
||||
"If it was you, and you want to confirm your entry, ".
|
||||
"use the URL below:\n\n\t%3\$s\n\n" .
|
||||
"If not, just ignore this message.\n\n".
|
||||
"Thanks for your time, \n%2\$s\n"),
|
||||
$args['nickname'],
|
||||
$args['sitename'],
|
||||
$args['url']);
|
||||
|
||||
require_once(INSTALLDIR . '/lib/mail.php');
|
||||
return mail_to_user($this->getProfile()->getUser(), $subject, $body, $args['headers'], $this->getAddress());
|
||||
}
|
||||
|
||||
public function delete($useWhere=false)
|
||||
{
|
||||
$result = parent::delete($useWhere);
|
||||
|
||||
if ($result === false) {
|
||||
common_log_db_error($confirm, 'DELETE', __FILE__);
|
||||
// TRANS: Server error displayed when an address confirmation code deletion from the
|
||||
// TRANS: database fails in the contact address confirmation action.
|
||||
throw new ServerException(_('Could not delete address confirmation.'));
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
|
@ -36,6 +36,7 @@ class Conversation extends Managed_DataObject
|
||||
public $__table = 'conversation'; // table name
|
||||
public $id; // int(4) primary_key not_null auto_increment
|
||||
public $uri; // varchar(191) unique_key not 255 because utf8mb4 takes more space
|
||||
public $url; // varchar(191) unique_key not 255 because utf8mb4 takes more space
|
||||
public $created; // datetime not_null
|
||||
public $modified; // timestamp not_null default_CURRENT_TIMESTAMP
|
||||
|
||||
@ -45,6 +46,7 @@ class Conversation extends Managed_DataObject
|
||||
'fields' => array(
|
||||
'id' => array('type' => 'serial', 'not null' => true, 'description' => 'Unique identifier, (again) unrelated to notice id since 2016-01-06'),
|
||||
'uri' => array('type' => 'varchar', 'not null'=>true, 'length' => 191, 'description' => 'URI of the conversation'),
|
||||
'url' => array('type' => 'varchar', 'length' => 191, 'description' => 'Resolvable URL, preferrably remote (local can be generated on the fly)'),
|
||||
'created' => array('type' => 'datetime', 'not null' => true, 'description' => 'date this record was created'),
|
||||
'modified' => array('type' => 'timestamp', 'not null' => true, 'description' => 'date this record was modified'),
|
||||
),
|
||||
@ -89,15 +91,21 @@ class Conversation extends Managed_DataObject
|
||||
*
|
||||
* @return Conversation the new conversation DO
|
||||
*/
|
||||
static function create($uri=null, $created=null)
|
||||
static function create(ActivityContext $ctx=null, $created=null)
|
||||
{
|
||||
// Be aware that the Notice does not have an id yet since it's not inserted!
|
||||
$conv = new Conversation();
|
||||
$conv->created = $created ?: common_sql_now();
|
||||
$conv->uri = $uri ?: sprintf('%s%s=%s:%s=%s',
|
||||
if ($ctx instanceof ActivityContext) {
|
||||
$conv->uri = $ctx->conversation;
|
||||
$conv->url = $ctx->conversation_url;
|
||||
} else {
|
||||
$conv->uri = sprintf('%s%s=%s:%s=%s',
|
||||
TagURI::mint(),
|
||||
'objectType', 'thread',
|
||||
'nonce', common_random_hexstr(8));
|
||||
$conv->url = null; // locally generated Conversation objects don't get static URLs stored
|
||||
}
|
||||
// This insert throws exceptions on failure
|
||||
$conv->insert();
|
||||
|
||||
|
181
classes/File.php
181
classes/File.php
@ -106,6 +106,40 @@ class File extends Managed_DataObject
|
||||
// We don't have the file's URL since before, so let's continue.
|
||||
}
|
||||
|
||||
// if the given url is an local attachment url and the id already exists, don't
|
||||
// save a new file record. This should never happen, but let's make it foolproof
|
||||
// FIXME: how about attachments servers?
|
||||
$u = parse_url($given_url);
|
||||
if (isset($u['host']) && $u['host'] === common_config('site', 'server')) {
|
||||
$r = Router::get();
|
||||
// Skip the / in the beginning or $r->map won't match
|
||||
try {
|
||||
$args = $r->map(mb_substr($u['path'], 1));
|
||||
if ($args['action'] === 'attachment') {
|
||||
try {
|
||||
// $args['attachment'] should always be set if action===attachment, given our routing rules
|
||||
$file = File::getByID($args['attachment']);
|
||||
return $file;
|
||||
} catch (EmptyPkeyValueException $e) {
|
||||
// ...but $args['attachment'] can also be 0...
|
||||
} catch (NoResultException $e) {
|
||||
// apparently this link goes to us, but is _not_ an existing attachment (File) ID?
|
||||
}
|
||||
}
|
||||
} catch (Exception $e) {
|
||||
// Some other exception was thrown from $r->map, likely a
|
||||
// ClientException (404) because of some malformed link to
|
||||
// our own instance. It's still a valid URL however, so we
|
||||
// won't abort anything... I noticed this when linking:
|
||||
// https://social.umeahackerspace.se/mmn/foaf' (notice the
|
||||
// apostrophe in the end, making it unrecognizable for our
|
||||
// URL routing.
|
||||
// That specific issue (the apostrophe being part of a link
|
||||
// is something that may or may not have been fixed since,
|
||||
// in lib/util.php in common_replace_urls_callback().
|
||||
}
|
||||
}
|
||||
|
||||
$file = new File;
|
||||
$file->url = $given_url;
|
||||
if (!empty($redir_data['protected'])) $file->protected = $redir_data['protected'];
|
||||
@ -160,10 +194,14 @@ class File extends Managed_DataObject
|
||||
}
|
||||
|
||||
$redir = File_redirection::where($given_url);
|
||||
$file = $redir->getFile();
|
||||
|
||||
if (!$file instanceof File || empty($file->id)) {
|
||||
try {
|
||||
$file = $redir->getFile();
|
||||
} catch (EmptyPkeyValueException $e) {
|
||||
common_log(LOG_ERR, 'File_redirection::where gave object with empty file_id for given_url '._ve($given_url));
|
||||
throw new ServerException('URL processing failed without new File object');
|
||||
} catch (NoResultException $e) {
|
||||
// This should not happen
|
||||
common_log(LOG_ERR, 'File_redirection after discovery could still not return a File object.');
|
||||
throw new ServerException('URL processing failed without new File object');
|
||||
}
|
||||
|
||||
@ -226,18 +264,19 @@ class File extends Managed_DataObject
|
||||
|
||||
public function getFilename()
|
||||
{
|
||||
if (!self::validFilename($this->filename)) {
|
||||
// TRANS: Client exception thrown if a file upload does not have a valid name.
|
||||
throw new ClientException(_("Invalid filename."));
|
||||
}
|
||||
return $this->filename;
|
||||
return self::tryFilename($this->filename);
|
||||
}
|
||||
|
||||
public function getSize()
|
||||
{
|
||||
return intval($this->size);
|
||||
}
|
||||
|
||||
// where should the file go?
|
||||
|
||||
static function filename(Profile $profile, $origname, $mimetype)
|
||||
{
|
||||
$ext = self::guessMimeExtension($mimetype);
|
||||
$ext = self::guessMimeExtension($mimetype, $origname);
|
||||
|
||||
// Normalize and make the original filename more URL friendly.
|
||||
$origname = basename($origname, ".$ext");
|
||||
@ -258,19 +297,54 @@ class File extends Managed_DataObject
|
||||
return $filename;
|
||||
}
|
||||
|
||||
static function guessMimeExtension($mimetype)
|
||||
/**
|
||||
* @param $mimetype The mimetype we've discovered for this file.
|
||||
* @param $filename An optional filename which we can use on failure.
|
||||
*/
|
||||
static function guessMimeExtension($mimetype, $filename=null)
|
||||
{
|
||||
try {
|
||||
// first see if we know the extension for our mimetype
|
||||
$ext = common_supported_mime_to_ext($mimetype);
|
||||
} catch (Exception $e) {
|
||||
// We don't support this mimetype, but let's guess the extension
|
||||
$matches = array();
|
||||
if (!preg_match('/\/([a-z0-9]+)/', mb_strtolower($mimetype), $matches)) {
|
||||
throw new Exception('Malformed mimetype: '.$mimetype);
|
||||
// we do, so use it!
|
||||
return $ext;
|
||||
} catch (UnknownMimeExtensionException $e) {
|
||||
// We don't know the extension for this mimetype, but let's guess.
|
||||
|
||||
// If we can't recognize the extension from the MIME, we try
|
||||
// to guess based on filename, if one was supplied.
|
||||
if (!is_null($filename) && preg_match('/^.+\.([A-Za-z0-9]+)$/', $filename, $matches)) {
|
||||
// we matched on a file extension, so let's see if it means something.
|
||||
$ext = mb_strtolower($matches[1]);
|
||||
|
||||
$blacklist = common_config('attachments', 'extblacklist');
|
||||
// If we got an extension from $filename we want to check if it's in a blacklist
|
||||
// so we avoid people uploading .php files etc.
|
||||
if (array_key_exists($ext, $blacklist)) {
|
||||
if (!is_string($blacklist[$ext])) {
|
||||
// we don't have a safe replacement extension
|
||||
throw new ClientException(_('Blacklisted file extension.'));
|
||||
}
|
||||
common_debug('Found replaced extension for filename '._ve($filename).': '._ve($ext));
|
||||
|
||||
// return a safe replacement extension ('php' => 'phps' for example)
|
||||
return $blacklist[$ext];
|
||||
}
|
||||
// the attachment extension based on its filename was not blacklisted so it's ok to use it
|
||||
return $ext;
|
||||
}
|
||||
$ext = $matches[1];
|
||||
} catch (Exception $e) {
|
||||
common_log(LOG_INFO, 'Problem when figuring out extension for mimetype: '._ve($e));
|
||||
}
|
||||
return mb_strtolower($ext);
|
||||
|
||||
// If nothing else has given us a result, try to extract it from
|
||||
// the mimetype value (this turns .jpg to .jpeg for example...)
|
||||
$matches = array();
|
||||
// FIXME: try to build a regexp that will get jpeg from image/jpeg as well as json from application/jrd+json
|
||||
if (!preg_match('/\/([a-z0-9]+)/', mb_strtolower($mimetype), $matches)) {
|
||||
throw new Exception('Malformed mimetype: '.$mimetype);
|
||||
}
|
||||
return mb_strtolower($matches[1]);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -281,19 +355,27 @@ class File extends Managed_DataObject
|
||||
return preg_match('/^[A-Za-z0-9._-]+$/', $filename);
|
||||
}
|
||||
|
||||
static function tryFilename($filename)
|
||||
{
|
||||
if (!self::validFilename($filename))
|
||||
{
|
||||
throw new InvalidFilenameException($filename);
|
||||
}
|
||||
// if successful, return the filename for easy if-statementing
|
||||
return $filename;
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws ClientException on invalid filename
|
||||
*/
|
||||
static function path($filename)
|
||||
{
|
||||
if (!self::validFilename($filename)) {
|
||||
// TRANS: Client exception thrown if a file upload does not have a valid name.
|
||||
throw new ClientException(_("Invalid filename."));
|
||||
}
|
||||
self::tryFilename($filename);
|
||||
|
||||
$dir = common_config('attachments', 'dir');
|
||||
|
||||
if ($dir[strlen($dir)-1] != '/') {
|
||||
$dir .= '/';
|
||||
if (!in_array($dir[mb_strlen($dir)-1], ['/', '\\'])) {
|
||||
$dir .= DIRECTORY_SEPARATOR;
|
||||
}
|
||||
|
||||
return $dir . $filename;
|
||||
@ -301,10 +383,7 @@ class File extends Managed_DataObject
|
||||
|
||||
static function url($filename)
|
||||
{
|
||||
if (!self::validFilename($filename)) {
|
||||
// TRANS: Client exception thrown if a file upload does not have a valid name.
|
||||
throw new ClientException(_("Invalid filename."));
|
||||
}
|
||||
self::tryFilename($filename);
|
||||
|
||||
if (common_config('site','private')) {
|
||||
|
||||
@ -409,6 +488,8 @@ class File extends Managed_DataObject
|
||||
* @param $width int Max width of thumbnail in pixels. (if null, use common_config values)
|
||||
* @param $height int Max height of thumbnail in pixels. (if null, square-crop to $width)
|
||||
* @param $crop bool Crop to the max-values' aspect ratio
|
||||
* @param $force_still bool Don't allow fallback to showing original (such as animated GIF)
|
||||
* @param $upscale mixed Whether or not to scale smaller images up to larger thumbnail sizes. (null = site default)
|
||||
*
|
||||
* @return File_thumbnail
|
||||
*
|
||||
@ -424,7 +505,13 @@ class File extends Managed_DataObject
|
||||
// null means "always use file as thumbnail"
|
||||
// false means you get choice between frozen frame or original when calling getThumbnail
|
||||
if (is_null(common_config('thumbnail', 'animated')) || !$force_still) {
|
||||
throw new UseFileAsThumbnailException($this->id);
|
||||
try {
|
||||
// remote files with animated GIFs as thumbnails will match this
|
||||
return File_thumbnail::byFile($this);
|
||||
} catch (NoResultException $e) {
|
||||
// and if it's not a remote file, it'll be safe to use the locally stored File
|
||||
throw new UseFileAsThumbnailException($this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -441,13 +528,28 @@ class File extends Managed_DataObject
|
||||
return $filepath;
|
||||
}
|
||||
|
||||
public function getUrl($prefer_local=true)
|
||||
public function getAttachmentUrl()
|
||||
{
|
||||
if ($prefer_local && !empty($this->filename)) {
|
||||
// A locally stored file, so let's generate a URL for our instance.
|
||||
return self::url($this->filename);
|
||||
return common_local_url('attachment', array('attachment'=>$this->getID()));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $use_local true means require local, null means prefer local, false means use whatever is stored
|
||||
*/
|
||||
public function getUrl($use_local=null)
|
||||
{
|
||||
if ($use_local !== false) {
|
||||
if (is_string($this->filename) || !empty($this->filename)) {
|
||||
// A locally stored file, so let's generate a URL for our instance.
|
||||
return self::url($this->getFilename());
|
||||
}
|
||||
if ($use_local) {
|
||||
// if the file wasn't stored locally (has filename) and we require a local URL
|
||||
throw new FileNotStoredLocallyException($this);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// No local filename available, return the URL we have stored
|
||||
return $this->url;
|
||||
}
|
||||
@ -524,7 +626,9 @@ class File extends Managed_DataObject
|
||||
|
||||
function stream($offset=0, $limit=NOTICES_PER_PAGE, $since_id=0, $max_id=0)
|
||||
{
|
||||
$stream = new FileNoticeStream($this);
|
||||
// FIXME: Try to get the Profile::current() here in some other way to avoid mixing
|
||||
// the current session user with possibly background/queue processing.
|
||||
$stream = new FileNoticeStream($this, Profile::current());
|
||||
return $stream->getNotices($offset, $limit, $since_id, $max_id);
|
||||
}
|
||||
|
||||
@ -593,6 +697,13 @@ class File extends Managed_DataObject
|
||||
return $title ?: null;
|
||||
}
|
||||
|
||||
public function setTitle($title)
|
||||
{
|
||||
$orig = clone($this);
|
||||
$this->title = mb_strlen($title) > 0 ? $title : null;
|
||||
return $this->update($orig);
|
||||
}
|
||||
|
||||
static public function hashurl($url)
|
||||
{
|
||||
if (empty($url)) {
|
||||
@ -624,16 +735,18 @@ class File extends Managed_DataObject
|
||||
$dupfile = new File();
|
||||
// First we find file entries that would be duplicates of this when shortened
|
||||
// ... and we'll just throw the dupes out the window for now! It's already so borken.
|
||||
$dupfile->query(sprintf('SELECT * FROM file WHERE LEFT(url, 191) = "%1$s"', $file->shortenedurl));
|
||||
$dupfile->query(sprintf('SELECT * FROM file WHERE LEFT(url, 191) = %1$s', $dupfile->_quote($file->shortenedurl)));
|
||||
// Leave one of the URLs in the database by using ->find(true) (fetches first entry)
|
||||
if ($dupfile->find(true)) {
|
||||
print "\nShortening url entry for $table id: {$file->id} [";
|
||||
$orig = clone($dupfile);
|
||||
$origurl = $dupfile->url; // save for logging purposes
|
||||
$dupfile->url = $file->shortenedurl; // make sure it's only 191 chars from now on
|
||||
$dupfile->update($orig);
|
||||
print "\nDeleting duplicate entries of too long URL on $table id: {$file->id} [";
|
||||
// only start deleting with this fetch.
|
||||
while($dupfile->fetch()) {
|
||||
common_log(LOG_INFO, sprintf('Deleting duplicate File entry of %1$d: %2$d (original URL: %3$s collides with these first 191 characters: %4$s', $dupfile->id, $file->id, $origurl, $file->shortenedurl));
|
||||
print ".";
|
||||
$dupfile->delete();
|
||||
}
|
||||
|
@ -172,56 +172,82 @@ class File_redirection extends Managed_DataObject
|
||||
|
||||
try {
|
||||
$r = File_redirection::getByUrl($in_url);
|
||||
if($r instanceof File_redirection) {
|
||||
try {
|
||||
$f = File::getKV('id',$r->file_id);
|
||||
$r->file = $f;
|
||||
$r->redir_url = $f->url;
|
||||
} catch (NoResultException $e) {
|
||||
// Invalid entry, delete and run again
|
||||
common_log(LOG_ERR, "Could not find File with id=".$r->file_id." referenced in File_redirection, deleting File redirection entry and creating new File and File_redirection entries.");
|
||||
$r->delete();
|
||||
return self::where($in_url);
|
||||
}
|
||||
return $r;
|
||||
|
||||
try {
|
||||
$f = File::getByID($r->file_id);
|
||||
$r->file = $f;
|
||||
$r->redir_url = $f->url;
|
||||
} catch (NoResultException $e) {
|
||||
// Invalid entry, delete and run again
|
||||
common_log(LOG_ERR, "Could not find File with id=".$r->file_id." referenced in File_redirection, deleting File redirection entry and and trying again...");
|
||||
$r->delete();
|
||||
return self::where($in_url);
|
||||
}
|
||||
|
||||
// File_redirecion and File record found, return both
|
||||
return $r;
|
||||
|
||||
} catch (NoResultException $e) {
|
||||
// File_redirecion record not found, but this might be a direct link to a file
|
||||
try {
|
||||
$f = File::getByUrl($in_url);
|
||||
$redir->file_id = $f->id;
|
||||
$redir->file = $f;
|
||||
return $redir;
|
||||
} catch (NoResultException $e) {
|
||||
// Oh well, let's keep going
|
||||
// nope, this was not a direct link to a file either, let's keep going
|
||||
}
|
||||
}
|
||||
|
||||
if ($discover) {
|
||||
// try to follow redirects and get the final url
|
||||
$redir_info = File_redirection::lookupWhere($in_url);
|
||||
if(is_string($redir_info)) {
|
||||
$redir_info = array('url' => $redir_info);
|
||||
}
|
||||
|
||||
// Save the file if we don't have it already
|
||||
$redir->file = File::saveNew($redir_info,$redir_info['url']);
|
||||
|
||||
// If this is a redirection, save it
|
||||
// (if it hasn't been saved yet by some other process while we we
|
||||
// were running lookupWhere())
|
||||
if($redir_info['url'] != $in_url) {
|
||||
try {
|
||||
$file_redir = File_redirection::getByUrl($in_url);
|
||||
} catch (NoResultException $e) {
|
||||
$file_redir = new File_redirection();
|
||||
$file_redir->urlhash = File::hashurl($in_url);
|
||||
$file_redir->url = $in_url;
|
||||
$file_redir->file_id = $redir->file->getID();
|
||||
$file_redir->insert();
|
||||
$file_redir->redir_url = $redir->file->url;
|
||||
}
|
||||
|
||||
// the last url in the redirection chain can actually be a redirect!
|
||||
// this is the case with local /attachment/{file_id} links
|
||||
// in that case we have the file id already
|
||||
try {
|
||||
$r = File_redirection::getByUrl($redir_info['url']);
|
||||
|
||||
$f = File::getKV('id',$r->file_id);
|
||||
|
||||
if($f instanceof File) {
|
||||
$redir->file = $f;
|
||||
$redir->redir_url = $f->url;
|
||||
} else {
|
||||
// Invalid entry in File_redirection, delete and run again
|
||||
common_log(LOG_ERR, "Could not find File with id=".$r->file_id." referenced in File_redirection, deleting File_redirection entry and trying again...");
|
||||
$r->delete();
|
||||
return self::where($in_url);
|
||||
}
|
||||
} catch (NoResultException $e) {
|
||||
// save the file now when we know that we don't have it in File_redirection
|
||||
try {
|
||||
$redir->file = File::saveNew($redir_info,$redir_info['url']);
|
||||
} catch (ServerException $e) {
|
||||
common_log(LOG_ERR, $e);
|
||||
}
|
||||
}
|
||||
|
||||
// If this is a redirection and we have a file to redirect to, save it
|
||||
// (if it doesn't exist in File_redirection already)
|
||||
if($redir->file instanceof File && $redir_info['url'] != $in_url) {
|
||||
try {
|
||||
$file_redir = File_redirection::getByUrl($in_url);
|
||||
} catch (NoResultException $e) {
|
||||
$file_redir = new File_redirection();
|
||||
$file_redir->urlhash = File::hashurl($in_url);
|
||||
$file_redir->url = $in_url;
|
||||
$file_redir->file_id = $redir->file->getID();
|
||||
$file_redir->insert();
|
||||
$file_redir->redir_url = $redir->file->url;
|
||||
}
|
||||
|
||||
$file_redir->file = $redir->file;
|
||||
return $file_redir;
|
||||
$file_redir->file = $redir->file;
|
||||
return $file_redir;
|
||||
}
|
||||
}
|
||||
|
||||
@ -419,8 +445,8 @@ class File_redirection extends Managed_DataObject
|
||||
}
|
||||
|
||||
public function getFile() {
|
||||
if(empty($this->file) && $this->file_id) {
|
||||
$this->file = File::getKV('id', $this->file_id);
|
||||
if (!$this->file instanceof File) {
|
||||
$this->file = File::getByID($this->file_id);
|
||||
}
|
||||
|
||||
return $this->file;
|
||||
|
@ -98,6 +98,7 @@ class File_thumbnail extends Managed_DataObject
|
||||
if ($notNullUrl) {
|
||||
$thumb->whereAdd('url IS NOT NULL');
|
||||
}
|
||||
$thumb->orderBy('modified ASC'); // the first created, a somewhat ugly hack
|
||||
$thumb->limit(1);
|
||||
if (!$thumb->find(true)) {
|
||||
throw new NoResultException($thumb);
|
||||
@ -129,23 +130,88 @@ class File_thumbnail extends Managed_DataObject
|
||||
|
||||
static function path($filename)
|
||||
{
|
||||
// TODO: Store thumbnails in their own directory and don't use File::path here
|
||||
return File::path($filename);
|
||||
File::tryFilename($filename);
|
||||
|
||||
// NOTE: If this is left empty in default config, it will be set to File::path('thumb')
|
||||
$dir = common_config('thumbnail', 'dir');
|
||||
|
||||
if (!in_array($dir[mb_strlen($dir)-1], ['/', '\\'])) {
|
||||
$dir .= DIRECTORY_SEPARATOR;
|
||||
}
|
||||
|
||||
return $dir . $filename;
|
||||
}
|
||||
|
||||
static function url($filename)
|
||||
{
|
||||
// TODO: Store thumbnails in their own directory and don't use File::url here
|
||||
return File::url($filename);
|
||||
File::tryFilename($filename);
|
||||
|
||||
// FIXME: private site thumbnails?
|
||||
|
||||
$path = common_config('thumbnail', 'path');
|
||||
if (empty($path)) {
|
||||
return File::url('thumb')."/{$filename}";
|
||||
}
|
||||
|
||||
$protocol = (GNUsocial::useHTTPS() ? 'https' : 'http');
|
||||
$server = common_config('thumbnail', 'server') ?: common_config('site', 'server');
|
||||
|
||||
if ($path[mb_strlen($path)-1] != '/') {
|
||||
$path .= '/';
|
||||
}
|
||||
if ($path[0] != '/') {
|
||||
$path = '/'.$path;
|
||||
}
|
||||
|
||||
return $protocol.'://'.$server.$path.$filename;
|
||||
}
|
||||
|
||||
public function getFilename()
|
||||
{
|
||||
return File::tryFilename($this->filename);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return string full filesystem path to the locally stored thumbnail file
|
||||
* @throws
|
||||
*/
|
||||
public function getPath()
|
||||
{
|
||||
$filepath = self::path($this->filename);
|
||||
if (!file_exists($filepath)) {
|
||||
throw new FileNotFoundException($filepath);
|
||||
$oldpath = File::path($this->getFilename());
|
||||
$thumbpath = self::path($this->getFilename());
|
||||
|
||||
// If we have a file in our old thumbnail storage path, move (or copy) it to the new one
|
||||
// (if the if/elseif don't match, we have a $thumbpath just as we should and can return it)
|
||||
if (file_exists($oldpath) && !file_exists($thumbpath)) {
|
||||
try {
|
||||
// let's get the filename of the File, to check below if it happens to be identical
|
||||
$file_filename = $this->getFile()->getFilename();
|
||||
} catch (NoResultException $e) {
|
||||
// reasonably the function calling us will handle the following as "File_thumbnail entry should be deleted"
|
||||
throw new FileNotFoundException($thumbpath);
|
||||
} catch (InvalidFilenameException $e) {
|
||||
// invalid filename in getFile()->getFilename(), just
|
||||
// means the File object isn't stored locally and that
|
||||
// means it's safe to move it below.
|
||||
$file_filename = null;
|
||||
}
|
||||
|
||||
if ($this->getFilename() === $file_filename) {
|
||||
// special case where thumbnail file exactly matches stored File filename
|
||||
common_debug('File filename and File_thumbnail filename match on '.$this->file_id.', copying instead');
|
||||
copy($oldpath, $thumbpath);
|
||||
} elseif (!rename($oldpath, $thumbpath)) {
|
||||
common_log(LOG_ERR, 'Could not move thumbnail from '._ve($oldpath).' to '._ve($thumbpath));
|
||||
throw new ServerException('Could not move thumbnail from old path to new path.');
|
||||
} else {
|
||||
common_log(LOG_DEBUG, 'Moved thumbnail '.$this->file_id.' from '._ve($oldpath).' to '._ve($thumbpath));
|
||||
}
|
||||
} elseif (!file_exists($thumbpath)) {
|
||||
throw new FileNotFoundException($thumbpath);
|
||||
}
|
||||
return $filepath;
|
||||
|
||||
return $thumbpath;
|
||||
}
|
||||
|
||||
public function getUrl()
|
||||
@ -188,11 +254,15 @@ class File_thumbnail extends Managed_DataObject
|
||||
|
||||
public function delete($useWhere=false)
|
||||
{
|
||||
if (!empty($this->filename) && file_exists(File_thumbnail::path($this->filename))) {
|
||||
$deleted = @unlink(self::path($this->filename));
|
||||
try {
|
||||
$thumbpath = self::path($this->getFilename());
|
||||
// if file does not exist, try to delete it
|
||||
$deleted = !file_exists($thumbpath) || @unlink($thumbpath);
|
||||
if (!$deleted) {
|
||||
common_log(LOG_ERR, sprintf('Could not unlink existing file: "%s"', self::path($this->filename)));
|
||||
common_log(LOG_ERR, 'Could not unlink existing thumbnail file: '._ve($thumbpath));
|
||||
}
|
||||
} catch (InvalidFilenameException $e) {
|
||||
common_log(LOG_ERR, 'Deleting object but not attempting deleting file: '._ve($e->getMessage()));
|
||||
}
|
||||
|
||||
return parent::delete($useWhere);
|
||||
@ -203,6 +273,10 @@ class File_thumbnail extends Managed_DataObject
|
||||
return File::getByID($this->file_id);
|
||||
}
|
||||
|
||||
public function getFileId()
|
||||
{
|
||||
return $this->file_id;
|
||||
}
|
||||
|
||||
static public function hashurl($url)
|
||||
{
|
||||
|
@ -89,7 +89,7 @@ class Foreign_link extends Managed_DataObject
|
||||
return $flink;
|
||||
}
|
||||
|
||||
function set_flags($noticesend, $noticerecv, $replysync, $friendsync)
|
||||
function set_flags($noticesend, $noticerecv, $replysync, $repeatsync, $friendsync)
|
||||
{
|
||||
if ($noticesend) {
|
||||
$this->noticesync |= FOREIGN_NOTICE_SEND;
|
||||
@ -109,6 +109,12 @@ class Foreign_link extends Managed_DataObject
|
||||
$this->noticesync &= ~FOREIGN_NOTICE_SEND_REPLY;
|
||||
}
|
||||
|
||||
if ($repeatsync) {
|
||||
$this->noticesync |= FOREIGN_NOTICE_SEND_REPEAT;
|
||||
} else {
|
||||
$this->noticesync &= ~FOREIGN_NOTICE_SEND_REPEAT;
|
||||
}
|
||||
|
||||
if ($friendsync) {
|
||||
$this->friendsync |= FOREIGN_FRIEND_RECV;
|
||||
} else {
|
||||
|
@ -383,14 +383,35 @@ abstract class Managed_DataObject extends Memcached_DataObject
|
||||
|
||||
static function getByID($id)
|
||||
{
|
||||
if (!property_exists(get_called_class(), 'id')) {
|
||||
throw new ServerException('Trying to get undefined property of dataobject class.');
|
||||
}
|
||||
if (empty($id)) {
|
||||
throw new EmptyIdException(get_called_class());
|
||||
throw new EmptyPkeyValueException(get_called_class(), 'id');
|
||||
}
|
||||
// getByPK throws exception if id is null
|
||||
// or if the class does not have a single 'id' column as primary key
|
||||
return static::getByPK(array('id' => $id));
|
||||
}
|
||||
|
||||
static function getByUri($uri)
|
||||
{
|
||||
if (!property_exists(get_called_class(), 'uri')) {
|
||||
throw new ServerException('Trying to get undefined property of dataobject class.');
|
||||
}
|
||||
if (empty($uri)) {
|
||||
throw new EmptyPkeyValueException(get_called_class(), 'uri');
|
||||
}
|
||||
|
||||
$class = get_called_class();
|
||||
$obj = new $class();
|
||||
$obj->uri = $uri;
|
||||
if (!$obj->find(true)) {
|
||||
throw new NoResultException($obj);
|
||||
}
|
||||
return $obj;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an ID, checked that it is set and reasonably valid
|
||||
*
|
||||
@ -483,6 +504,8 @@ abstract class Managed_DataObject extends Memcached_DataObject
|
||||
throw new ServerException('DataObject must be the result of a query (N>=1) before updateWithKeys()');
|
||||
}
|
||||
|
||||
$this->onUpdateKeys($orig);
|
||||
|
||||
// do it in a transaction
|
||||
$this->query('BEGIN');
|
||||
|
||||
@ -580,6 +603,11 @@ abstract class Managed_DataObject extends Memcached_DataObject
|
||||
// NOOP by default
|
||||
}
|
||||
|
||||
protected function onUpdateKeys(Managed_DataObject $orig)
|
||||
{
|
||||
// NOOP by default
|
||||
}
|
||||
|
||||
public function insert()
|
||||
{
|
||||
$this->onInsert();
|
||||
|
@ -67,10 +67,11 @@ class Memcached_DataObject extends Safe_DataObject
|
||||
* @param string $cls Class to fetch
|
||||
* @param string $keyCol name of column for key
|
||||
* @param array $keyVals key values to fetch
|
||||
* @param boolean $skipNulls skip provided null values
|
||||
*
|
||||
* @return array Array of objects, in order
|
||||
*/
|
||||
static function multiGetClass($cls, $keyCol, array $keyVals)
|
||||
static function multiGetClass($cls, $keyCol, array $keyVals, $skipNulls=true)
|
||||
{
|
||||
$obj = new $cls;
|
||||
|
||||
@ -83,6 +84,14 @@ class Memcached_DataObject extends Safe_DataObject
|
||||
throw new ServerException('Cannot do multiGet on anything but integer columns');
|
||||
}
|
||||
|
||||
if ($skipNulls) {
|
||||
foreach ($keyVals as $key=>$val) {
|
||||
if (is_null($val)) {
|
||||
unset($keyVals[$key]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$obj->whereAddIn($keyCol, $keyVals, $colType);
|
||||
|
||||
// Since we're inputting straight to a query: format and escape
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user