Merge branch 'nightly' of git.gnu.io:gnu/gnu-social into nightly

This commit is contained in:
abjectio 2016-02-27 20:37:03 +01:00
commit 12ad588a9b
205 changed files with 2600 additions and 792 deletions

View File

@ -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.
@ -673,7 +674,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

View File

@ -155,6 +155,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']).'>'.$type.'; rel="me"', false);
}
}
}
function extraHead()
{
if ($this->target->bio) {

View File

@ -207,7 +207,7 @@ class Avatar extends Managed_DataObject
}
}
static function defaultImage($size)
static function defaultImage($size=AVATAR_PROFILE_SIZE)
{
static $sizenames = array(AVATAR_PROFILE_SIZE => 'profile',
AVATAR_STREAM_SIZE => 'stream',

View File

@ -106,6 +106,27 @@ 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
$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 (EmptyIdException $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?
}
}
}
$file = new File;
$file->url = $given_url;
if (!empty($redir_data['protected'])) $file->protected = $redir_data['protected'];
@ -237,7 +258,7 @@ class File extends Managed_DataObject
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 +279,53 @@ 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 (Exception $e) { // FIXME: Make this exception more specific to "unknown mime=>ext relation"
// We don't know the extension for this mimetype, but let's guess.
// If we are very liberal with uploads ($config['attachments']['supported'] === true)
// then we try to do some guessing based on the filename, if it was supplied.
if (!is_null($filename) && common_config('attachments', 'supported')===true
&& 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];
}
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]);
}
/**

View File

@ -172,56 +172,83 @@ 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;
$f = File::getKV('id',$r->file_id);
if($file instanceof File) {
$r->file = $f;
$r->redir_url = $f->url;
} else {
// 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;
}
}

View File

@ -88,7 +88,7 @@ class Notice extends Managed_DataObject
'reply_to' => array('type' => 'int', 'description' => 'notice replied to (usually a guess)'),
'is_local' => array('type' => 'int', 'size' => 'tiny', 'default' => 0, 'description' => 'notice was generated by a user'),
'source' => array('type' => 'varchar', 'length' => 32, 'description' => 'source of comment, like "web", "im", or "clientname"'),
'conversation' => array('type' => 'int', 'description' => 'id of root notice in this conversation'),
'conversation' => array('type' => 'int', 'description' => 'the local numerical conversation id'),
'repeat_of' => array('type' => 'int', 'description' => 'notice this is a repeat of'),
'object_type' => array('type' => 'varchar', 'length' => 191, 'description' => 'URI representing activity streams object type', 'default' => null),
'verb' => array('type' => 'varchar', 'length' => 191, 'description' => 'URI representing activity streams verb', 'default' => 'http://activitystrea.ms/schema/1.0/post'),
@ -260,7 +260,8 @@ class Notice extends Managed_DataObject
public function getRendered()
{
if (is_null($this->rendered) || $this->rendered === '') {
// we test $this->id because if it's not inserted yet, we can't update the field
if (!empty($this->id) && (is_null($this->rendered) || $this->rendered === '')) {
// update to include rendered content on-the-fly, so we don't have to have a fix-up script in upgrade.php
common_debug('Rendering notice '.$this->getID().' as it had no rendered HTML content.');
$orig = clone($this);
@ -848,14 +849,14 @@ class Notice extends Managed_DataObject
$stored->url = $url;
$stored->verb = $act->verb;
$content = $act->content ?: $act->summary;
if (is_null($content) && !is_null($actobj)) {
$content = $actobj->content ?: $actobj->summary;
// we use mb_strlen because it _might_ be that the content is just the string "0"...
$content = mb_strlen($act->content) ? $act->content : $act->summary;
if (mb_strlen($content)===0 && !is_null($actobj)) {
$content = mb_strlen($actobj->content) ? $actobj->content : $actobj->summary;
}
// Strip out any bad HTML
$stored->rendered = common_purify($content);
// yeah, just don't use getRendered() here since it's not inserted yet ;)
$stored->content = common_strip_html($stored->rendered);
// Strip out any bad HTML from $content. URI.Base is used to sort out relative URLs.
$stored->rendered = common_purify($content, ['URI.Base' => $stored->url ?: null]);
$stored->content = common_strip_html($stored->getRendered(), true, true);
if (trim($stored->content) === '') {
// TRANS: Error message when the plain text content of a notice has zero length.
throw new ClientException(_('Empty notice content, will not save this.'));
@ -996,7 +997,9 @@ class Notice extends Managed_DataObject
}
}
if (!$stored instanceof Notice) {
throw new ServerException('StartNoticeSave did not give back a Notice');
throw new ServerException('StartNoticeSave did not give back a Notice.');
} elseif (empty($stored->id)) {
throw new ServerException('Supposedly saved Notice has no ID.');
}
// Only save 'attention' and metadata stuff (URLs, tags...) stuff if

View File

@ -900,6 +900,31 @@ class Profile extends Managed_DataObject
return parent::update($dataObject);
}
public function getRelSelf()
{
return ['href' => $this->getUrl(),
'text' => common_config('site', 'name'),
'image' => Avatar::urlByProfile($this)];
}
// All the known rel="me", used for the IndieWeb audience
public function getRelMes()
{
$relMes = array();
try {
$relMes[] = $this->getRelSelf();
} catch (InvalidUrlException $e) {
// no valid profile URL available
}
if (common_valid_http_url($this->getHomepage())) {
$relMes[] = ['href' => $this->getHomepage(),
'text' => _('Homepage'),
'image' => null];
}
Event::handle('OtherAccountProfiles', array($this, &$relMes));
return $relMes;
}
function delete($useWhere=false)
{
// just in case it hadn't been done before... (usually set before adding deluser to queue handling!)

View File

@ -105,6 +105,11 @@ class User_group extends Managed_DataObject
return $this->getProfile()->getNickname();
}
public function getFullname()
{
return $this->getProfile()->getFullname();
}
public static function defaultLogo($size)
{
static $sizenames = array(AVATAR_PROFILE_SIZE => 'profile',

File diff suppressed because it is too large Load Diff

View File

@ -1,39 +1,50 @@
<?php
//
// +----------------------------------------------------------------------+
// | PHP Version 4 |
// +----------------------------------------------------------------------+
// | Copyright (c) 1997-2003 The PHP Group |
// +----------------------------------------------------------------------+
// | This source file is subject to version 2.0 of the PHP license, |
// | that is bundled with this package in the file LICENSE, and is |
// | available at through the world-wide-web at |
// | http://www.php.net/license/2_02.txt. |
// | If you did not receive a copy of the PHP license and are unable to |
// | obtain it through the world-wide-web, please send a note to |
// | license@php.net so we can mail you a copy immediately. |
// +----------------------------------------------------------------------+
// | Authors: Stig Bakken <ssb@php.net> |
// | Chuck Hagenbuch <chuck@horde.org> |
// +----------------------------------------------------------------------+
//
// $Id: Socket.php,v 1.38 2008/02/15 18:24:17 chagenbu Exp $
/**
* Net_Socket
*
* PHP Version 4
*
* Copyright (c) 1997-2013 The PHP Group
*
* This source file is subject to version 2.0 of the PHP license,
* that is bundled with this package in the file LICENSE, and is
* available at through the world-wide-web at
* http://www.php.net/license/2_02.txt.
* If you did not receive a copy of the PHP license and are unable to
* obtain it through the world-wide-web, please send a note to
* license@php.net so we can mail you a copy immediately.
*
* Authors: Stig Bakken <ssb@php.net>
* Chuck Hagenbuch <chuck@horde.org>
*
* @category Net
* @package Net_Socket
* @author Stig Bakken <ssb@php.net>
* @author Chuck Hagenbuch <chuck@horde.org>
* @copyright 1997-2003 The PHP Group
* @license http://www.php.net/license/2_02.txt PHP 2.02
* @link http://pear.php.net/packages/Net_Socket
*/
require_once 'PEAR.php';
define('NET_SOCKET_READ', 1);
define('NET_SOCKET_READ', 1);
define('NET_SOCKET_WRITE', 2);
define('NET_SOCKET_ERROR', 4);
/**
* Generalized Socket class.
*
* @version 1.1
* @author Stig Bakken <ssb@php.net>
* @author Chuck Hagenbuch <chuck@horde.org>
* @category Net
* @package Net_Socket
* @author Stig Bakken <ssb@php.net>
* @author Chuck Hagenbuch <chuck@horde.org>
* @copyright 1997-2003 The PHP Group
* @license http://www.php.net/license/2_02.txt PHP 2.02
* @link http://pear.php.net/packages/Net_Socket
*/
class Net_Socket extends PEAR {
class Net_Socket extends PEAR
{
/**
* Socket file pointer.
* @var resource $fp
@ -65,11 +76,11 @@ class Net_Socket extends PEAR {
var $port = 0;
/**
* Number of seconds to wait on socket connections before assuming
* Number of seconds to wait on socket operations before assuming
* there's no more data. Defaults to no timeout.
* @var integer $timeout
* @var integer|float $timeout
*/
var $timeout = false;
var $timeout = null;
/**
* Number of bytes to read at a time in readLine() and
@ -78,23 +89,30 @@ class Net_Socket extends PEAR {
*/
var $lineLength = 2048;
/**
* The string to use as a newline terminator. Usually "\r\n" or "\n".
* @var string $newline
*/
var $newline = "\r\n";
/**
* Connect to the specified port. If called when the socket is
* already connected, it disconnects and connects again.
*
* @param string $addr IP address or host name.
* @param integer $port TCP port number.
* @param boolean $persistent (optional) Whether the connection is
* persistent (kept open between requests
* by the web server).
* @param integer $timeout (optional) How long to wait for data.
* @param array $options See options for stream_context_create.
* @param string $addr IP address or host name (may be with protocol prefix).
* @param integer $port TCP port number.
* @param boolean $persistent (optional) Whether the connection is
* persistent (kept open between requests
* by the web server).
* @param integer $timeout (optional) Connection socket timeout.
* @param array $options See options for stream_context_create.
*
* @access public
*
* @return boolean | PEAR_Error True on success or a PEAR_Error on failure.
* @return boolean|PEAR_Error True on success or a PEAR_Error on failure.
*/
function connect($addr, $port = 0, $persistent = null, $timeout = null, $options = null)
function connect($addr, $port = 0, $persistent = null,
$timeout = null, $options = null)
{
if (is_resource($this->fp)) {
@fclose($this->fp);
@ -103,11 +121,10 @@ class Net_Socket extends PEAR {
if (!$addr) {
return $this->raiseError('$addr cannot be empty');
} elseif (strspn($addr, '.0123456789') == strlen($addr) ||
strstr($addr, '/') !== false) {
$this->addr = $addr;
} else if (strspn($addr, ':.0123456789') == strlen($addr)) {
$this->addr = strpos($addr, ':') !== false ? '['.$addr.']' : $addr;
} else {
$this->addr = @gethostbyname($addr);
$this->addr = $addr;
}
$this->port = $port % 65536;
@ -116,40 +133,40 @@ class Net_Socket extends PEAR {
$this->persistent = $persistent;
}
if ($timeout !== null) {
$this->timeout = $timeout;
$openfunc = $this->persistent ? 'pfsockopen' : 'fsockopen';
$errno = 0;
$errstr = '';
$old_track_errors = @ini_set('track_errors', 1);
if ($timeout <= 0) {
$timeout = @ini_get('default_socket_timeout');
}
$openfunc = $this->persistent ? 'pfsockopen' : 'fsockopen';
$errno = 0;
$errstr = '';
$old_track_errors = @ini_set('track_errors', 1);
if ($options && function_exists('stream_context_create')) {
if ($this->timeout) {
$timeout = $this->timeout;
} else {
$timeout = 0;
}
$context = stream_context_create($options);
// Since PHP 5 fsockopen doesn't allow context specification
if (function_exists('stream_socket_client')) {
$flags = $this->persistent ? STREAM_CLIENT_PERSISTENT : STREAM_CLIENT_CONNECT;
$flags = STREAM_CLIENT_CONNECT;
if ($this->persistent) {
$flags = STREAM_CLIENT_PERSISTENT;
}
$addr = $this->addr . ':' . $this->port;
$fp = stream_socket_client($addr, $errno, $errstr, $timeout, $flags, $context);
$fp = stream_socket_client($addr, $errno, $errstr,
$timeout, $flags, $context);
} else {
$fp = @$openfunc($this->addr, $this->port, $errno, $errstr, $timeout, $context);
$fp = @$openfunc($this->addr, $this->port, $errno,
$errstr, $timeout, $context);
}
} else {
if ($this->timeout) {
$fp = @$openfunc($this->addr, $this->port, $errno, $errstr, $this->timeout);
} else {
$fp = @$openfunc($this->addr, $this->port, $errno, $errstr);
}
$fp = @$openfunc($this->addr, $this->port, $errno, $errstr, $timeout);
}
if (!$fp) {
if ($errno == 0 && isset($php_errormsg)) {
if ($errno == 0 && !strlen($errstr) && isset($php_errormsg)) {
$errstr = $php_errormsg;
}
@ini_set('track_errors', $old_track_errors);
@ -158,7 +175,7 @@ class Net_Socket extends PEAR {
@ini_set('track_errors', $old_track_errors);
$this->fp = $fp;
$this->setTimeout();
return $this->setBlocking($this->blocking);
}
@ -179,6 +196,18 @@ class Net_Socket extends PEAR {
return true;
}
/**
* Set the newline character/sequence to use.
*
* @param string $newline Newline character(s)
* @return boolean True
*/
function setNewline($newline)
{
$this->newline = $newline;
return true;
}
/**
* Find out if the socket is in blocking mode.
*
@ -196,7 +225,8 @@ class Net_Socket extends PEAR {
* if there is no data available, whereas it will block until there
* is data for blocking sockets.
*
* @param boolean $mode True for blocking sockets, false for nonblocking.
* @param boolean $mode True for blocking sockets, false for nonblocking.
*
* @access public
* @return mixed true on success or a PEAR_Error instance otherwise
*/
@ -207,7 +237,7 @@ class Net_Socket extends PEAR {
}
$this->blocking = $mode;
socket_set_blocking($this->fp, $this->blocking);
stream_set_blocking($this->fp, (int)$this->blocking);
return true;
}
@ -215,25 +245,40 @@ class Net_Socket extends PEAR {
* Sets the timeout value on socket descriptor,
* expressed in the sum of seconds and microseconds
*
* @param integer $seconds Seconds.
* @param integer $microseconds Microseconds.
* @param integer $seconds Seconds.
* @param integer $microseconds Microseconds, optional.
*
* @access public
* @return mixed true on success or a PEAR_Error instance otherwise
* @return mixed True on success or false on failure or
* a PEAR_Error instance when not connected
*/
function setTimeout($seconds, $microseconds)
function setTimeout($seconds = null, $microseconds = null)
{
if (!is_resource($this->fp)) {
return $this->raiseError('not connected');
}
return socket_set_timeout($this->fp, $seconds, $microseconds);
if ($seconds === null && $microseconds === null) {
$seconds = (int) $this->timeout;
$microseconds = (int) (($this->timeout - $seconds) * 1000000);
} else {
$this->timeout = $seconds + $microseconds/1000000;
}
if ($this->timeout > 0) {
return stream_set_timeout($this->fp, (int) $seconds, (int) $microseconds);
}
else {
return false;
}
}
/**
* Sets the file buffering size on the stream.
* See php's stream_set_write_buffer for more information.
*
* @param integer $size Write buffer size.
* @param integer $size Write buffer size.
*
* @access public
* @return mixed on success or an PEAR_Error object otherwise
*/
@ -262,7 +307,8 @@ class Net_Socket extends PEAR {
* </p>
*
* @access public
* @return mixed Array containing information about existing socket resource or a PEAR_Error instance otherwise
* @return mixed Array containing information about existing socket
* resource or a PEAR_Error instance otherwise
*/
function getStatus()
{
@ -270,23 +316,32 @@ class Net_Socket extends PEAR {
return $this->raiseError('not connected');
}
return socket_get_status($this->fp);
return stream_get_meta_data($this->fp);
}
/**
* Get a specified line of data
*
* @param int $size Reading ends when size - 1 bytes have been read,
* or a newline or an EOF (whichever comes first).
* If no size is specified, it will keep reading from
* the stream until it reaches the end of the line.
*
* @access public
* @return $size bytes of data from the socket, or a PEAR_Error if
* not connected.
* @return mixed $size bytes of data from the socket, or a PEAR_Error if
* not connected. If an error occurs, FALSE is returned.
*/
function gets($size)
function gets($size = null)
{
if (!is_resource($this->fp)) {
return $this->raiseError('not connected');
}
return @fgets($this->fp, $size);
if (is_null($size)) {
return @fgets($this->fp);
} else {
return @fgets($this->fp, $size);
}
}
/**
@ -295,7 +350,8 @@ class Net_Socket extends PEAR {
* chunk; if you know the size of the data you're getting
* beforehand, this is definitely the way to go.
*
* @param integer $size The number of bytes to read from the socket.
* @param integer $size The number of bytes to read from the socket.
*
* @access public
* @return $size bytes of data from the socket, or a PEAR_Error if
* not connected.
@ -312,14 +368,16 @@ class Net_Socket extends PEAR {
/**
* Write a specified amount of data.
*
* @param string $data Data to write.
* @param integer $blocksize Amount of data to write at once.
* NULL means all at once.
* @param string $data Data to write.
* @param integer $blocksize Amount of data to write at once.
* NULL means all at once.
*
* @access public
* @return mixed If the socket is not connected, returns an instance of PEAR_Error
* If the write succeeds, returns the number of bytes written
* @return mixed If the socket is not connected, returns an instance of
* PEAR_Error.
* If the write succeeds, returns the number of bytes written.
* If the write fails, returns false.
* If the socket times out, returns an instance of PEAR_Error.
*/
function write($data, $blocksize = null)
{
@ -328,19 +386,47 @@ class Net_Socket extends PEAR {
}
if (is_null($blocksize) && !OS_WINDOWS) {
return @fwrite($this->fp, $data);
$written = @fwrite($this->fp, $data);
// Check for timeout or lost connection
if (!$written) {
$meta_data = $this->getStatus();
if (!is_array($meta_data)) {
return $meta_data; // PEAR_Error
}
if (!empty($meta_data['timed_out'])) {
return $this->raiseError('timed out');
}
}
return $written;
} else {
if (is_null($blocksize)) {
$blocksize = 1024;
}
$pos = 0;
$pos = 0;
$size = strlen($data);
while ($pos < $size) {
$written = @fwrite($this->fp, substr($data, $pos, $blocksize));
if ($written === false) {
return false;
// Check for timeout or lost connection
if (!$written) {
$meta_data = $this->getStatus();
if (!is_array($meta_data)) {
return $meta_data; // PEAR_Error
}
if (!empty($meta_data['timed_out'])) {
return $this->raiseError('timed out');
}
return $written;
}
$pos += $written;
}
@ -349,10 +435,12 @@ class Net_Socket extends PEAR {
}
/**
* Write a line of data to the socket, followed by a trailing "\r\n".
* Write a line of data to the socket, followed by a trailing newline.
*
* @param string $data Data to write
*
* @access public
* @return mixed fputs result, or an error
* @return mixed fwrite() result, or PEAR_Error when not connected
*/
function writeLine($data)
{
@ -360,7 +448,7 @@ class Net_Socket extends PEAR {
return $this->raiseError('not connected');
}
return fwrite($this->fp, $data . "\r\n");
return fwrite($this->fp, $data . $this->newline);
}
/**
@ -441,7 +529,7 @@ class Net_Socket extends PEAR {
}
$string = '';
while (($char = @fread($this->fp, 1)) != "\x00") {
while (($char = @fread($this->fp, 1)) != "\x00") {
$string .= $char;
}
return $string;
@ -481,11 +569,13 @@ class Net_Socket extends PEAR {
}
$line = '';
$timeout = time() + $this->timeout;
while (!feof($this->fp) && (!$this->timeout || time() < $timeout)) {
$line .= @fgets($this->fp, $this->lineLength);
if (substr($line, -1) == "\n") {
return rtrim($line, "\r\n");
return rtrim($line, $this->newline);
}
}
return $line;
@ -521,9 +611,9 @@ class Net_Socket extends PEAR {
* Runs the equivalent of the select() system call on the socket
* with a timeout specified by tv_sec and tv_usec.
*
* @param integer $state Which of read/write/error to check for.
* @param integer $tv_sec Number of seconds for timeout.
* @param integer $tv_usec Number of microseconds for timeout.
* @param integer $state Which of read/write/error to check for.
* @param integer $tv_sec Number of seconds for timeout.
* @param integer $tv_usec Number of microseconds for timeout.
*
* @access public
* @return False if select fails, integer describing which of read/write/error
@ -535,8 +625,8 @@ class Net_Socket extends PEAR {
return $this->raiseError('not connected');
}
$read = null;
$write = null;
$read = null;
$write = null;
$except = null;
if ($state & NET_SOCKET_READ) {
$read[] = $this->fp;
@ -547,7 +637,8 @@ class Net_Socket extends PEAR {
if ($state & NET_SOCKET_ERROR) {
$except[] = $this->fp;
}
if (false === ($sr = stream_select($read, $write, $except, $tv_sec, $tv_usec))) {
if (false === ($sr = stream_select($read, $write, $except,
$tv_sec, $tv_usec))) {
return false;
}
@ -567,15 +658,17 @@ class Net_Socket extends PEAR {
/**
* Turns encryption on/off on a connected socket.
*
* @param bool $enabled Set this parameter to true to enable encryption
* and false to disable encryption.
* @param integer $type Type of encryption. See
* http://se.php.net/manual/en/function.stream-socket-enable-crypto.php for values.
* @param bool $enabled Set this parameter to true to enable encryption
* and false to disable encryption.
* @param integer $type Type of encryption. See stream_socket_enable_crypto()
* for values.
*
* @see http://se.php.net/manual/en/function.stream-socket-enable-crypto.php
* @access public
* @return false on error, true on success and 0 if there isn't enough data and the
* user should try again (non-blocking sockets only). A PEAR_Error object
* is returned if the socket is not connected
* @return false on error, true on success and 0 if there isn't enough data
* and the user should try again (non-blocking sockets only).
* A PEAR_Error object is returned if the socket is not
* connected
*/
function enableCrypto($enabled, $type)
{
@ -585,7 +678,8 @@ class Net_Socket extends PEAR {
}
return @stream_socket_enable_crypto($this->fp, $enabled, $type);
} else {
return $this->raiseError('Net_Socket::enableCrypto() requires php version >= 5.1.0');
$msg = 'Net_Socket::enableCrypto() requires php version >= 5.1.0';
return $this->raiseError($msg);
}
}

View File

@ -93,9 +93,9 @@ function handleError($error)
return;
}
$logmsg = "PEAR error: " . $error->getMessage();
$logmsg = "Exception thrown: " . _ve($error->getMessage());
if ($error instanceof PEAR_Exception && common_config('site', 'logdebug')) {
$logmsg .= " : ". $error->toText();
$logmsg .= " PEAR: ". $error->toText();
}
// DB queries often end up with a lot of newlines; merge to a single line
// for easier grepability...

View File

@ -241,6 +241,7 @@ $default =
'application/vnd.oasis.opendocument.text-web' => 'oth',
'application/pdf' => 'pdf',
'application/zip' => 'zip',
'application/x-go-sgf' => 'sgf',
'application/xml' => 'xml',
'image/png' => 'png',
'image/jpeg' => 'jpg',
@ -266,6 +267,10 @@ $default =
'show_html' => false, // show (filtered) text/html attachments (and oEmbed HTML etc.). Doesn't affect AJAX calls.
'show_thumbs' => true, // show thumbnails in notice lists for uploaded images, and photos and videos linked remotely that provide oEmbed info
'process_links' => true, // check linked resources for embeddable photos and videos; this will hit referenced external web sites when processing new messages.
'extblacklist' => [
'php' => 'phps',
'exe' => false, // this would deny any uploads to keep the "exe" file extension
],
),
'thumbnail' =>
array('crop' => false, // overridden to true if thumb height === null

View File

@ -62,6 +62,11 @@ class Feed
$this->title = $title;
}
function getUrl()
{
return $this->url;
}
function mimeType()
{
switch ($this->type) {

View File

@ -253,15 +253,15 @@ class MediaFile
File::respectsQuota($scoped, $_FILES[$param]['size']);
$mimetype = self::getUploadedMimeType($_FILES[$param]['tmp_name'], $_FILES[$param]['name']);
$basename = basename($_FILES[$param]['name']);
switch (common_config('attachments', 'filename_base')) {
case 'upload':
$basename = basename($_FILES[$param]['name']);
$filename = File::filename($scoped, $basename, $mimetype);
break;
case 'hash':
default:
$filename = strtolower($filehash) . '.' . File::guessMimeExtension($mimetype);
$filename = strtolower($filehash) . '.' . File::guessMimeExtension($mimetype, $basename);
}
$filepath = File::path($filename);

View File

@ -76,6 +76,16 @@ class Nickname
*/
const MAX_LEN = 64;
/**
* Regex with non-capturing group that matches whitespace and some
* characters which are allowed right before an @ or ! when mentioning
* other users. Like: 'This goes out to:@mmn (@chimo too) (!awwyiss).'
*
* FIXME: Make this so you can have multiple whitespace but not multiple
* parenthesis or something. '(((@n_n@)))' might as well be a smiley.
*/
const BEFORE_MENTIONS = '(?:^|[\s\.\,\:\;\[\(]+)';
/**
* Nice simple check of whether the given string is a valid input nickname,
* which can be normalized into an internally canonical form.

View File

@ -34,6 +34,18 @@ abstract class NoticestreamAction extends ProfileAction
// pass by default
}
public function extraHeaders()
{
parent::extraHeaders();
foreach ($this->getFeeds() as $feed) {
header('Link: <'.htmlspecialchars($feed->getUrl()).'>;' .
' rel="'.htmlspecialchars($feed->rel()).'";' .
' type="'.htmlspecialchars($feed->mimeType()).'"',
false // don't overwrite previous headers of this sort
);
}
}
// this fetches the NoticeStream
abstract public function getStream();
}

View File

@ -580,7 +580,7 @@ function common_canonical_email($email)
return $email;
}
function common_purify($html)
function common_purify($html, array $args=array())
{
require_once INSTALLDIR.'/extlib/HTMLPurifier/HTMLPurifier.auto.php';
@ -588,6 +588,10 @@ function common_purify($html)
$cfg->set('Attr.AllowedRel', ['bookmark', 'directory', 'enclosure', 'home', 'license', 'nofollow', 'payment', 'tag']); // http://microformats.org/wiki/rel
$cfg->set('HTML.ForbiddenAttributes', array('style')); // id, on* etc. are already filtered by default
$cfg->set('URI.AllowedSchemes', array_fill_keys(common_url_schemes(), true));
if (isset($args['URI.Base'])) {
$cfg->set('URI.Base', $args['URI.Base']); // if null this is like unsetting it I presume
$cfg->set('URI.MakeAbsolute', !is_null($args['URI.Base'])); // if we have a URI base, convert relative URLs to absolute ones.
}
// Remove more elements than what the default filter removes, default in GNU social are remotely
// linked resources such as img, video, audio
@ -800,7 +804,7 @@ function common_find_mentions($text, Profile $sender, Notice $parent=null)
// @#tag => mention of all subscriptions tagged 'tag'
preg_match_all('/(?:^|[\s\.\,\:\;]+)@#([\pL\pN_\-\.]{1,64})/',
preg_match_all('/'.Nickname::BEFORE_MENTIONS.'@#([\pL\pN_\-\.]{1,64})/',
$text, $hmatches, PREG_OFFSET_CAPTURE);
foreach ($hmatches[1] as $hmatch) {
$tag = common_canonical_tag($hmatch[0]);
@ -822,7 +826,7 @@ function common_find_mentions($text, Profile $sender, Notice $parent=null)
'url' => $url);
}
preg_match_all('/(?:^|[\s\.\,\:\;]+)!(' . Nickname::DISPLAY_FMT . ')/',
preg_match_all('/'.Nickname::BEFORE_MENTIONS.'!(' . Nickname::DISPLAY_FMT . ')/',
$text, $hmatches, PREG_OFFSET_CAPTURE);
foreach ($hmatches[1] as $hmatch) {
$nickname = Nickname::normalize($hmatch[0]);
@ -866,7 +870,7 @@ function common_find_mentions_raw($text)
$atmatches = array();
// the regexp's "(?!\@)" makes sure it doesn't matches the single "@remote" in "@remote@server.com"
preg_match_all('/(?:^|\s+)@(' . Nickname::DISPLAY_FMT . ')\b(?!\@)/',
preg_match_all('/'.Nickname::BEFORE_MENTIONS.'@(' . Nickname::DISPLAY_FMT . ')\b(?!\@)/',
$text,
$atmatches,
PREG_OFFSET_CAPTURE);

View File

@ -92,7 +92,7 @@ class AccountManagerPlugin extends Plugin
$versions[] = array('name' => 'AccountManager',
'version' => GNUSOCIAL_VERSION,
'author' => 'Craig Andrews',
'homepage' => 'http://status.net/wiki/Plugin:AccountManager',
'homepage' => 'https://git.gnu.io/gnu/gnu-social/tree/master/plugins/AccountManager',
'rawdescription' =>
// TRANS: Plugin description.
_m('The Account Manager plugin implements the Account Manager specification.'));

View File

@ -344,7 +344,7 @@ class ActivityPlugin extends Plugin
$versions[] = array('name' => 'Activity',
'version' => self::VERSION,
'author' => 'Evan Prodromou',
'homepage' => 'http://status.net/wiki/Plugin:Activity',
'homepage' => 'https://git.gnu.io/gnu/gnu-social/tree/master/plugins/Activity',
'rawdescription' =>
// TRANS: Plugin description.
_m('Emits notices when social activities happen.'));

View File

@ -220,7 +220,7 @@ class ActivitySpamPlugin extends Plugin
$versions[] = array('name' => 'ActivitySpam',
'version' => GNUSOCIAL_VERSION,
'author' => 'Evan Prodromou',
'homepage' => 'http://status.net/wiki/Plugin:ActivitySpam',
'homepage' => 'https://git.gnu.io/gnu/gnu-social/tree/master/plugins/ActivitySpam',
'description' =>
_m('Test notices against the Activity Spam service.'));
return true;

23
plugins/ActivitySpam/README Executable file
View File

@ -0,0 +1,23 @@
The ActivitySpam plugin is a spam filter for GNU social.
It needs to connect to a activityspam server.
You can run one yourself: https://github.com/e14n/activityspam
Or use a public instance ( ex: https://spamicity.info/ )
Installation
============
add "addPlugin('ActivitySpam');"
to the bottom of your config.php
Settings
========
server: URL to the activityspam server
consumerkey: The "key" provided by the activityspam server after you've registered and configured an account.
secret: The "secret" provided by the activityspam server after you've registered and configured an account
Example
=======
$config['activityspam']['server'] = 'https://spamicity.info/';
$config['activityspam']['consumerkey'] = 'CONSUMER_KEY';
$config['activityspam']['secret'] = 'SECRET';
addPlugin('ActivitySpam');

View File

@ -273,7 +273,7 @@ class AnonymousFavePlugin extends Plugin
*/
function onPluginVersion(array &$versions)
{
$url = 'http://status.net/wiki/Plugin:AnonymousFave';
$url = 'https://git.gnu.io/gnu/gnu-social/tree/master/plugins/AnonymousFave';
$versions[] = array('name' => 'AnonymousFave',
'version' => ANONYMOUS_FAVE_PLUGIN_VERSION,

14
plugins/AnonymousFave/README Executable file
View File

@ -0,0 +1,14 @@
The Anonymous Fave plugin allows anonymous (not logged in) users to favorite notices
Installation
============
add "addPlugin('AnonymousFave');"
to the bottom of your config.php
Settings
========
none
Example
=======
addPlugin('AnonymousFave');

11
plugins/AntiBrute/README Executable file
View File

@ -0,0 +1,11 @@
The AntiBrute plugin implements a time delay between successive failed login
attempts to slow down brute force attacks ( https://en.wikipedia.org/wiki/Brute-force_attack#Countermeasures ).
Installation
============
This plugin is enabled by default
Settings
========
none

View File

@ -80,7 +80,7 @@ class ApiLoggerPlugin extends Plugin
$versions[] = array('name' => 'ApiLogger',
'version' => GNUSOCIAL_VERSION,
'author' => 'Brion Vibber',
'homepage' => 'http://status.net/wiki/Plugin:ApiLogger',
'homepage' => 'https://git.gnu.io/gnu/gnu-social/tree/master/plugins/ApiLogger',
'rawdescription' =>
// TRANS: Plugin description.
_m('Allows random sampling of API requests.'));

18
plugins/ApiLogger/README Executable file
View File

@ -0,0 +1,18 @@
The ApiLogger plugin allows random sampling of API requests.
Installation
============
add "addPlugin('ApiLogger');"
to the bottom of your config.php
Settings
========
frequency: How often to sample (number between 0.0 and 1.0 representing
percentage -- e.g.: 0.1 will check about 10% of hits). Default 1.0
Example
=======
addPlugin('ApiLogger', array(
'frequency' => 1.0
));

View File

@ -155,7 +155,7 @@ class AuthCryptPlugin extends AuthenticationPlugin
$versions[] = array('name' => 'AuthCrypt',
'version' => GNUSOCIAL_VERSION,
'author' => 'Mikael Nordfeldth',
'homepage' => 'http://status.net/wiki/Plugin:AuthCrypt',
'homepage' => 'https://git.gnu.io/gnu/gnu-social/tree/master/plugins/AuthCrypt',
'rawdescription' =>
// TRANS: Plugin description.
_m('Authentication and password hashing with crypt()'));

View File

@ -61,7 +61,7 @@ class AutoSandboxPlugin extends Plugin
$versions[] = array('name' => 'AutoSandbox',
'version' => GNUSOCIAL_VERSION,
'author' => 'Sean Carmody',
'homepage' => 'http://status.net/wiki/Plugin:AutoSandbox',
'homepage' => 'https://git.gnu.io/gnu/gnu-social/tree/master/plugins/AutoSandbox',
'rawdescription' =>
// TRANS: Plugin description.
_m('Automatically sandboxes newly registered members.'));

View File

@ -57,7 +57,7 @@ class AutocompletePlugin extends Plugin
$versions[] = array('name' => 'Autocomplete',
'version' => GNUSOCIAL_VERSION,
'author' => 'Craig Andrews',
'homepage' => 'http://status.net/wiki/Plugin:Autocomplete',
'homepage' => 'https://git.gnu.io/gnu/gnu-social/tree/master/plugins/Autocomplete',
'rawdescription' =>
// TRANS: Plugin description.
_m('The autocomplete plugin adds autocompletion for @ replies.'));

View File

@ -50,7 +50,7 @@ class AwesomenessPlugin extends Plugin
'name' => 'Awesomeness',
'version' => self::VERSION,
'author' => 'Jeroen De Dauw',
'homepage' => 'http://status.net/wiki/Plugin:Awesomeness',
'homepage' => 'https://git.gnu.io/gnu/gnu-social/tree/master/plugins/Awesomeness',
// TRANS: Plugin description for a sample plugin.
'rawdescription' => _m('The Awesomeness plugin adds additional awesomeness ' .
'to a StatusNet installation.'

14
plugins/Awesomeness/README Executable file
View File

@ -0,0 +1,14 @@
Fun sample plugin: tweaks input data and adds a 'Cornify' ( http://www.cornify.com ) widget to sidebar.
Installation
============
add "addPlugin('Awesomeness');"
to the bottom of your config.php
Settings
========
none
Example
=======
addPlugin('Awesomeness');

View File

@ -150,7 +150,7 @@ class BitlyUrlPlugin extends UrlShortenerPlugin
$versions[] = array('name' => sprintf('BitlyUrl (%s)', $this->shortenerName),
'version' => GNUSOCIAL_VERSION,
'author' => 'Craig Andrews, Brion Vibber',
'homepage' => 'http://status.net/wiki/Plugin:BitlyUrl',
'homepage' => 'https://git.gnu.io/gnu/gnu-social/tree/master/plugins/BitlyUrl',
'rawdescription' =>
// TRANS: Plugin description. %1$s is the URL shortening service base URL (for example "bit.ly").
sprintf(_m('Uses <a href="http://%1$s/">%1$s</a> URL-shortener service.'),

View File

@ -297,7 +297,7 @@ class BlacklistPlugin extends Plugin
'version' => self::VERSION,
'author' => 'Evan Prodromou',
'homepage' =>
'http://status.net/wiki/Plugin:Blacklist',
'https://git.gnu.io/gnu/gnu-social/tree/master/plugins/Blacklist',
'description' =>
// TRANS: Plugin description.
_m('Keeps a blacklist of forbidden nickname '.

17
plugins/Blacklist/README Executable file
View File

@ -0,0 +1,17 @@
Plugin to prevent use of nicknames or URLs on a blacklist
Installation
============
add "addPlugin('Blacklist');"
to the bottom of your config.php
Settings
========
nicknames: Array of nicknames to blacklist
urls: Array of URLs to blacklist
Example
=======
$config['blacklist']['nicknames'] = array('bad_nickname', 'worse_nickname');
$config['blacklist']['urls'] = array('http://example.org', 'http://example.net');
addPlugin('Blacklist');

View File

@ -122,7 +122,7 @@ class BlankAdPlugin extends UAPPlugin
$versions[] = array('name' => 'BlankAd',
'version' => GNUSOCIAL_VERSION,
'author' => 'Evan Prodromou',
'homepage' => 'http://status.net/wiki/Plugin:BlankAdPlugin',
'homepage' => 'https://git.gnu.io/gnu/gnu-social/tree/master/plugins/BlankAdPlugin',
'rawdescription' =>
// TRANS: Plugin description.
_m('Plugin for testing ad layout.'));

14
plugins/BlankAd/README Executable file
View File

@ -0,0 +1,14 @@
Plugin for testing ad layout
This plugin uses the UAPPlugin framework to output ad content. However,
its ad content is just images with one red pixel stretched to the
right size. It's mostly useful for debugging theme layout.
To use this plugin, set the parameter for the ad size you want to use
to true (or anything non-null).
Example
=======
To make a leaderboard:
addPlugin('BlankAd', array('leaderboard' => true));

View File

@ -153,7 +153,7 @@ class BlogspamNetPlugin extends Plugin
$versions[] = array('name' => 'BlogspamNet',
'version' => BLOGSPAMNETPLUGIN_VERSION,
'author' => 'Evan Prodromou, Brion Vibber',
'homepage' => 'http://status.net/wiki/Plugin:BlogspamNet',
'homepage' => 'https://git.gnu.io/gnu/gnu-social/tree/master/plugins/BlogspamNet',
'rawdescription' =>
// TRANS: Plugin description.
_m('Plugin to check submitted notices with blogspam.net.'));

22
plugins/BlogspamNet/README Executable file
View File

@ -0,0 +1,22 @@
Plugin to check submitted notices with blogspam.net
When new notices are saved, we check their text with blogspam.net (or
a compatible service).
Blogspam.net is supposed to catch blog comment spam. Some of its tests
(min/max size, bayesian match) gave a lot of false positives so those
tests are turned off by default.
Installation
============
add "addPlugin('BlogspamNet');"
to the bottom of your config.php
Settings
========
none
Example
=======
addPlugin('BlogspamNet');

View File

@ -101,7 +101,7 @@ class CacheLogPlugin extends Plugin
$versions[] = array('name' => 'CacheLog',
'version' => GNUSOCIAL_VERSION,
'author' => 'Evan Prodromou',
'homepage' => 'http://status.net/wiki/Plugin:CacheLog',
'homepage' => 'https://git.gnu.io/gnu/gnu-social/tree/master/plugins/CacheLog',
'description' =>
// TRANS: Plugin description.
_m('Log reads and writes to the cache.'));

23
plugins/CacheLog/README Executable file
View File

@ -0,0 +1,23 @@
Log cache access
Adds "Cache MISS, Cache HIT, set cache value, delete cache value" etc.
information to the log file.
Note: entries are logged at the LOG_INFO level.
Installation
============
add "addPlugin('CacheLog');"
to the bottom of your config.php
Settings
========
none
Example
=======
Note that since most caching plugins return false for StartCache*
methods, you should add this plugin before them, i.e.
addPlugin('CacheLog');
addPlugin('XCache');

View File

@ -152,7 +152,7 @@ class CasAuthenticationPlugin extends AuthenticationPlugin
$versions[] = array('name' => 'CAS Authentication',
'version' => GNUSOCIAL_VERSION,
'author' => 'Craig Andrews',
'homepage' => 'http://status.net/wiki/Plugin:CasAuthentication',
'homepage' => 'https://git.gnu.io/gnu/gnu-social/tree/master/plugins/CasAuthentication',
// TRANS: Plugin description. CAS is Central Authentication Service.
'rawdescription' => _m('The CAS Authentication plugin allows for StatusNet to handle authentication through CAS (Central Authentication Service).'));
return true;

View File

@ -59,7 +59,7 @@ class ClientSideShortenPlugin extends Plugin
$versions[] = array('name' => 'Shorten',
'version' => GNUSOCIAL_VERSION,
'author' => 'Craig Andrews',
'homepage' => 'http://status.net/wiki/Plugin:ClientSideShorten',
'homepage' => 'https://git.gnu.io/gnu/gnu-social/tree/master/plugins/ClientSideShorten',
'rawdescription' =>
// TRANS: Plugin description.
_m('ClientSideShorten causes the web interface\'s notice form to automatically shorten URLs as they entered, and before the notice is submitted.'));

View File

@ -3,5 +3,5 @@ shorten URLs as they entered, and before the notice is submitted.
Installation
============
Add "addPlugin('ClientSideShorten');" to the bottom of your config.php
That's it!
This plugin is enabled by default

View File

@ -109,7 +109,7 @@ class CometPlugin extends RealtimePlugin
$versions[] = array('name' => 'Comet',
'version' => GNUSOCIAL_VERSION,
'author' => 'Evan Prodromou',
'homepage' => 'http://status.net/wiki/Plugin:Comet',
'homepage' => 'https://git.gnu.io/gnu/gnu-social/tree/master/plugins/Comet',
'rawdescription' =>
// TRANS: Plugin description message. Bayeux is a protocol for transporting asynchronous messages
// TRANS: and Comet is a web application model.

15
plugins/ConversationTree/README Executable file
View File

@ -0,0 +1,15 @@
The ConversationTree plugin displays conversation replies in a hierarchical
manner like StatusNet pre-v1.0 used to.
Installation
============
add "addPlugin('ConversationTree');"
to the bottom of your config.php
Settings
========
none
Example
=======
addPlugin('ConversationTree');

12
plugins/Cronish/README Executable file
View File

@ -0,0 +1,12 @@
The Cronish plugin executes events on a near-minutely/hour/day/week basis.
Intervals are approximate and will vary depending on how busy
the instance is.
Installation
============
This plugin is enabled by default
Settings
========
none

17
plugins/Diaspora/README Executable file
View File

@ -0,0 +1,17 @@
The Diaspora plugin allows GNU social users to subscribe to Diaspora feeds
Note: The feeds are read-only at the moment. That is, replying to an entry
coming from Diaspora will not propagate to Diaspora.
Installation
============
add "addPlugin('Diaspora');"
to the bottom of your config.php
Settings
========
none
Example
=======
addPlugin('Diaspora');

10
plugins/DirectMessage/README Executable file
View File

@ -0,0 +1,10 @@
The DirectMessage plugin allows users to send Direct Message to other local users
Installation
============
This plugin is enabled by default
Settings
========
none

View File

@ -246,7 +246,7 @@ class DirectionDetectorPlugin extends Plugin {
* plugin details
*/
function onPluginVersion(array &$versions){
$url = 'http://status.net/wiki/Plugin:DirectionDetector';
$url = 'https://git.gnu.io/gnu/gnu-social/tree/master/plugins/DirectionDetector';
$versions[] = array(
'name' => 'Direction detector',

View File

@ -0,0 +1,15 @@
The DirectionDetector plugin detects notices with RTL content and displays them
in the correct direction.
Installation
============
add "addPlugin('DirectionDetector');"
to the bottom of your config.php
Settings
========
none
Example
=======
addPlugin('DirectionDetector');

View File

@ -257,7 +257,7 @@ class DirectoryPlugin extends Plugin
'name' => 'Directory',
'version' => GNUSOCIAL_VERSION,
'author' => 'Zach Copley',
'homepage' => 'http://status.net/wiki/Plugin:Directory',
'homepage' => 'https://git.gnu.io/gnu/gnu-social/tree/master/plugins/Directory',
// TRANS: Plugin description.
'rawdescription' => _m('Add a user directory.')
);

15
plugins/Directory/README Executable file
View File

@ -0,0 +1,15 @@
The Directory plugin adds a user directory (list)
Installation
============
This plugin is enabled by default except on single-user instances, in which
case, it can be enabled by adding "addPlugin('Directory');" to the bottom of
your config.php
Settings
========
none
Example
=======
addPlugin('Directory');

View File

@ -166,7 +166,7 @@ class DiskCachePlugin extends Plugin
$versions[] = array('name' => 'DiskCache',
'version' => GNUSOCIAL_VERSION,
'author' => 'Evan Prodromou',
'homepage' => 'http://status.net/wiki/Plugin:DiskCache',
'homepage' => 'https://git.gnu.io/gnu/gnu-social/tree/master/plugins/DiskCache',
'rawdescription' =>
// TRANS: Plugin description.
_m('Plugin to implement cache interface with disk files.'));

17
plugins/DiskCache/README Executable file
View File

@ -0,0 +1,17 @@
The DiskCache plugin implements cache interface with disk files.
Installation
============
add "addPlugin('DiskCache');"
to the bottom of your config.php
Settings
========
root: Directory where to save cache data. Default /tmp
Example
=======
addPlugin('DiskCache', array(
'root' => '/tmp'
));

View File

@ -195,7 +195,7 @@ class DomainStatusNetworkPlugin extends Plugin
$versions[] = array('name' => 'DomainStatusNetwork',
'version' => GNUSOCIAL_VERSION,
'author' => 'Evan Prodromou',
'homepage' => 'http://status.net/wiki/Plugin:DomainStatusNetwork',
'homepage' => 'https://git.gnu.io/gnu/gnu-social/tree/master/plugins/DomainStatusNetwork',
'rawdescription' =>
// TRANS: Plugin description.
_m('A plugin that maps a single status_network to an email domain.'));

View File

@ -0,0 +1,24 @@
The DomainStatusNetwork plugin adds tools to map one status_network to one
email domain in a multi-site installation.
Relates to "status_network":
* /scripts/setup.cfg.sample
* /scripts/setup_status_network.sh
* /scripts/settag.php
* /scripts/delete_status_network.sh
* /scripts/move_status_network.sh
Installation
============
add "addPlugin('DomainStatusNetwork');"
to the bottom of your config.php
Settings
========
none
Example
=======
addPlugin('DomainStatusNetwork');

View File

@ -272,7 +272,7 @@ class DomainWhitelistPlugin extends Plugin
$versions[] = array('name' => 'DomainWhitelist',
'version' => GNUSOCIAL_VERSION,
'author' => 'Evan Prodromou, Zach Copley',
'homepage' => 'http://status.net/wiki/Plugin:DomainWhitelist',
'homepage' => 'https://git.gnu.io/gnu/gnu-social/tree/master/plugins/DomainWhitelist',
'rawdescription' =>
// TRANS: Plugin description.
_m('Restrict domains for email users.'));

16
plugins/DomainWhitelist/README Executable file
View File

@ -0,0 +1,16 @@
The DomainWhitelist plugin restricts the email addresses in a domain to a
select whitelist.
Installation
============
add "addPlugin('DomainWhitelist');"
to the bottom of your config.php
Settings
========
whitelist: An array of whitelisted domains
Example
=======
$config['email']['whitelist'] = array('example.org', 'example.net');
addPlugin('DomainWhitelist');

View File

@ -54,7 +54,7 @@ class EmailAuthenticationPlugin extends Plugin
$versions[] = array('name' => 'Email Authentication',
'version' => GNUSOCIAL_VERSION,
'author' => 'Craig Andrews',
'homepage' => 'http://status.net/wiki/Plugin:EmailAuthentication',
'homepage' => 'https://git.gnu.io/gnu/gnu-social/tree/master/plugins/EmailAuthentication',
'rawdescription' =>
// TRANS: Plugin description.
_m('The Email Authentication plugin allows users to login using their email address.'));

View File

@ -5,4 +5,9 @@ nickname and the provided password is checked.
Installation
============
add "addPlugin('emailAuthentication');" to the bottom of your config.php.
This plugin is enabled by default
Settings
========
none

View File

@ -177,7 +177,7 @@ class EmailRegistrationPlugin extends Plugin
$versions[] = array('name' => 'EmailRegistration',
'version' => GNUSOCIAL_VERSION,
'author' => 'Evan Prodromou',
'homepage' => 'http://status.net/wiki/Plugin:EmailRegistration',
'homepage' => 'https://git.gnu.io/gnu/gnu-social/tree/master/plugins/EmailRegistration',
'rawdescription' =>
// TRANS: Plugin description.
_m('Use email only for registration.'));

View File

@ -0,0 +1,25 @@
The EmailRegistration plugin allows user registration with just an email
address.
When users register, the part before '@' in their email address will become
their nickname/username (normalized). In case of collisions, a auto-increment
number will be added to the username.
For example, if someone registers with "user@example.org", their username
will be "user". If someone else registers with "user@example.net", their
username will be user1, and so on.
Installation
============
add "addPlugin('EmailRegistration');"
to the bottom of your config.php
Note: This plugin is enabled by default on private instances.
Settings
========
none
Example
=======
addPlugin('EmailRegistration');

View File

@ -185,7 +185,7 @@ class EmailReminderPlugin extends Plugin
'name' => 'EmailReminder',
'version' => GNUSOCIAL_VERSION,
'author' => 'Zach Copley',
'homepage' => 'http://status.net/wiki/Plugin:EmailReminder',
'homepage' => 'https://git.gnu.io/gnu/gnu-social/tree/master/plugins/EmailReminder',
// TRANS: Plugin description.
'rawdescription' => _m('Send email reminders for various things.')
);

21
plugins/EmailReminder/README Executable file
View File

@ -0,0 +1,21 @@
The EmailReminder plugin sends email reminders about various things
It will send reminder emails to email addresses that have been invited
but haven't registered yet.
It will also send reminders to email addresses that have registered but
haven't verified their email address yet.
Installation
============
add "addPlugin('EmailReminder');"
to the bottom of your config.php
Settings
========
none
Example
=======
addPlugin('EmailReminder');

View File

@ -71,7 +71,7 @@ class EmailSummaryPlugin extends Plugin
$versions[] = array('name' => 'EmailSummary',
'version' => GNUSOCIAL_VERSION,
'author' => 'Evan Prodromou',
'homepage' => 'http://status.net/wiki/Plugin:EmailSummary',
'homepage' => 'https://git.gnu.io/gnu/gnu-social/tree/master/plugins/EmailSummary',
'rawdescription' =>
// TRANS: Plugin description.
_m('Send an email summary of the inbox to users.'));

22
plugins/EmailSummary/README Executable file
View File

@ -0,0 +1,22 @@
The EmailSummary plugin sends an email summary of the inbox to users in the
network.
After enabling the plugin, users will have an option to enable/disable the
feature in their "Email Settings" section.
You can run ./script/sendemailsummary.php to send emails (options are
documented in the file). You can run this script automatically via your OS's
cron mechanism to send emails regularly.
Installation
============
add "addPlugin('EmailSummary');"
to the bottom of your config.php
Settings
========
none
Example
=======
addPlugin('EmailSummary');

View File

@ -102,7 +102,7 @@ class EventPlugin extends ActivityVerbHandlerPlugin
$versions[] = array('name' => 'Event',
'version' => GNUSOCIAL_VERSION,
'author' => 'Evan Prodromou',
'homepage' => 'http://status.net/wiki/Plugin:Event',
'homepage' => 'https://git.gnu.io/gnu/gnu-social/tree/master/plugins/Event',
'description' =>
// TRANS: Plugin description.
_m('Event invitations and RSVPs.'));

10
plugins/Event/README Normal file
View File

@ -0,0 +1,10 @@
The Event plugin adds event invitations and RSVPs types of notices.
Installation
============
This plugin is enabled by default
Settings
========
none

View File

@ -35,7 +35,7 @@ class ExtendedProfilePlugin extends Plugin
'name' => 'ExtendedProfile',
'version' => GNUSOCIAL_VERSION,
'author' => 'Brion Vibber, Samantha Doherty, Zach Copley',
'homepage' => 'http://status.net/wiki/Plugin:ExtendedProfile',
'homepage' => 'https://git.gnu.io/gnu/gnu-social/tree/master/plugins/ExtendedProfile',
// TRANS: Plugin description.
'rawdescription' => _m('UI extensions for additional profile fields.')
);

View File

@ -0,0 +1,23 @@
The ExtendedProfile plugin adds additional profile fields such as:
* Phone
* IM
* Website
* Work experience
* Education
Installation
============
add "addPlugin('ExtendedProfile');"
to the bottom of your config.php
Note: This plugin is enabled by default on private instances.
Settings
========
none
Example
=======
addPlugin('ExtendedProfile');

View File

@ -594,7 +594,7 @@ ENDOFSCRIPT;
'name' => 'Facebook Bridge',
'version' => GNUSOCIAL_VERSION,
'author' => 'Craig Andrews, Zach Copley',
'homepage' => 'http://status.net/wiki/Plugin:FacebookBridge',
'homepage' => 'https://git.gnu.io/gnu/gnu-social/tree/master/plugins/FacebookBridge',
'rawdescription' =>
// TRANS: Plugin description.
_m('A plugin for integrating StatusNet with Facebook.')

11
plugins/Favorite/README Normal file
View File

@ -0,0 +1,11 @@
The Favorite plugin adds the ability to mark a notice as a "favorite"
(i.e. "like").
Installation
============
This plugin is enabled by default
Settings
========
none

16
plugins/FeedPoller/README Normal file
View File

@ -0,0 +1,16 @@
The FeedPoller plugin allows users to subscribe to non-PuSH-enabled feeds
by regularly polling the source for new content.
Installation
============
add "addPlugin('FeedPoller');"
to the bottom of your config.php
Settings
========
none
Example
=======
addPlugin('FeedPoller');

View File

@ -170,7 +170,7 @@ class FollowEveryonePlugin extends Plugin
$versions[] = array('name' => 'FollowEveryone',
'version' => GNUSOCIAL_VERSION,
'author' => 'Evan Prodromou',
'homepage' => 'http://status.net/wiki/Plugin:FollowEveryone',
'homepage' => 'https://git.gnu.io/gnu/gnu-social/tree/master/plugins/FollowEveryone',
'rawdescription' =>
// TRANS: Plugin description.
_m('New users follow everyone at registration and are followed in return.'));

View File

@ -0,0 +1,16 @@
The FollowEveryone plugin makes it so that when a new user registers, all
existing users follow them automatically.
Installation
============
add "addPlugin('FollowEveryone');"
to the bottom of your config.php
Settings
========
none
Example
=======
addPlugin('FollowEveryone');

View File

@ -107,7 +107,7 @@ class ForceGroupPlugin extends Plugin
*/
function onPluginVersion(array &$versions)
{
$url = 'http://status.net/wiki/Plugin:ForceGroup';
$url = 'https://git.gnu.io/gnu/gnu-social/tree/master/plugins/ForceGroup';
$versions[] = array('name' => 'ForceGroup',
'version' => GNUSOCIAL_VERSION,

16
plugins/ForceGroup/README Normal file
View File

@ -0,0 +1,16 @@
The ForceGroup plugin allows forced group memberships and forces all notices
to appear in groups that users were forced in.
Installation
============
add "addPlugin('ForceGroup');"
to the bottom of your config.php
Settings
========
none
Example
=======
addPlugin('ForceGroup');

View File

View File

View File

View File

@ -121,7 +121,7 @@ class GeoURLPlugin extends Plugin
$versions[] = array('name' => 'GeoURL',
'version' => GNUSOCIAL_VERSION,
'author' => 'Evan Prodromou',
'homepage' => 'http://status.net/wiki/Plugin:GeoURL',
'homepage' => 'https://git.gnu.io/gnu/gnu-social/tree/master/plugins/GeoURL',
'rawdescription' =>
// TRANS: Plugin description.
_m('Ping <a href="http://geourl.org/">GeoURL</a> when '.

19
plugins/GeoURL/README Normal file
View File

@ -0,0 +1,19 @@
The GeoURL plugin add extra <meta> headers for certain pages that geourl.org
understands and pings geourl.org when those pages are created.
Note: The third-party service that this plugin depends on (geourl.org) seems to
be dead.
Installation
============
add "addPlugin('GeoURL');"
to the bottom of your config.php
Settings
========
none
Example
=======
addPlugin('GeoURL');

View File

@ -492,7 +492,7 @@ class GeonamesPlugin extends Plugin
$versions[] = array('name' => 'Geonames',
'version' => GNUSOCIAL_VERSION,
'author' => 'Evan Prodromou',
'homepage' => 'http://status.net/wiki/Plugin:Geonames',
'homepage' => 'https://git.gnu.io/gnu/gnu-social/tree/master/plugins/Geonames',
'rawdescription' =>
// TRANS: Plugin description.
_m('Uses <a href="http://geonames.org/">Geonames</a> service to get human-readable '.

19
plugins/Geonames/README Normal file
View File

@ -0,0 +1,19 @@
The Geonames plugin uses geonames.org to get human-readable names for locations
based on user-provided lat/long pairs.
The human-readable names appear after notices that have a lat/long location
attached to them.
Installation
============
add "addPlugin('Geonames');"
to the bottom of your config.php
Settings
========
none
Example
=======
addPlugin('Geonames');

View File

@ -67,7 +67,7 @@ class GroupFavoritedPlugin extends Plugin
*/
function onPluginVersion(array &$versions)
{
$url = 'http://status.net/wiki/Plugin:GroupFavorited';
$url = 'https://git.gnu.io/gnu/gnu-social/tree/master/plugins/GroupFavorited';
$versions[] = array('name' => 'GroupFavorited',
'version' => GNUSOCIAL_VERSION,

View File

@ -0,0 +1,15 @@
The GroupFavorited plugin adds a menu item for popular notices in groups.
Installation
============
add "addPlugin('GroupFavorited');"
to the bottom of your config.php
Settings
========
none
Example
=======
addPlugin('GroupFavorited');

View File

@ -410,7 +410,7 @@ class GroupPrivateMessagePlugin extends Plugin
$versions[] = array('name' => 'GroupPrivateMessage',
'version' => GNUSOCIAL_VERSION,
'author' => 'Evan Prodromou',
'homepage' => 'http://status.net/wiki/Plugin:GroupPrivateMessage',
'homepage' => 'https://git.gnu.io/gnu/gnu-social/tree/master/plugins/GroupPrivateMessage',
'rawdescription' =>
// TRANS: Plugin description.
_m('Allow posting private messages to groups.'));

View File

@ -0,0 +1,15 @@
The GroupPrivateMessage plugin allows users to send private messages to a group.
Installation
============
add "addPlugin('GroupPrivateMessage');"
to the bottom of your config.php
Settings
========
none
Example
=======
addPlugin('GroupPrivateMessage');

View File

@ -0,0 +1,21 @@
The ImageMagick plugin handles more kinds of image formats for thumbnails,
thanks to ImageMagick.
Note: This plugin depends on php5-imagick
Installation
============
add "addPlugin('ImageMagick');"
to the bottom of your config.php
Settings
========
animated: Whether to resize animated GIFs.
Note: We are not infinitely fast, so resizing animated GIFs is _not_ recommended.
Example
=======
$config['thumbnail']['animated'] = true;
addPlugin('ImageMagick');

View File

@ -81,7 +81,7 @@ class ImapPlugin extends Plugin
$versions[] = array('name' => 'IMAP',
'version' => GNUSOCIAL_VERSION,
'author' => 'Craig Andrews',
'homepage' => 'http://status.net/wiki/Plugin:IMAP',
'homepage' => 'https://git.gnu.io/gnu/gnu-social/tree/master/plugins/IMAP',
'rawdescription' =>
// TRANS: Plugin description.
_m('The IMAP plugin allows for StatusNet to check a POP or IMAP mailbox for incoming mail containing user posts.'));

View File

@ -172,7 +172,7 @@ class InProcessCachePlugin extends Plugin
*/
function onPluginVersion(array &$versions)
{
$url = 'http://status.net/wiki/Plugin:InProcessCache';
$url = 'https://git.gnu.io/gnu/gnu-social/tree/master/plugins/InProcessCache';
$versions[] = array('name' => 'InProcessCache',
'version' => GNUSOCIAL_VERSION,

View File

@ -0,0 +1,23 @@
The InProcessCache plugin adds an extra level of in-process caching to any
regular cache system like APC, XCache, or Memcache.
Installation
============
add "addPlugin('InProcessCache');"
to the bottom of your config.php
Settings
========
stats: Whether to dump statistics (cache size, etc) in the log file.
Note: entries are logged at the LOG_INFO level.
Example
=======
Note: since most caching plugins return false for StartCache* methods, you
should add this plugin before them, i.e.
$config['inprocess']['stats'] = true;
addPlugin('InProcessCache');
addPlugin('XCache');

View File

@ -46,7 +46,7 @@ class InfiniteScrollPlugin extends Plugin
$versions[] = array('name' => 'InfiniteScroll',
'version' => GNUSOCIAL_VERSION,
'author' => 'Craig Andrews',
'homepage' => 'http://status.net/wiki/Plugin:InfiniteScroll',
'homepage' => 'https://git.gnu.io/gnu/gnu-social/tree/master/plugins/InfiniteScroll',
'rawdescription' =>
// TRANS: Plugin dscription.
_m('Infinite Scroll adds the following functionality to your StatusNet installation: When a user scrolls towards the bottom of the page, the next page of notices is automatically retrieved and appended. This means they never need to click "Next Page", which dramatically increases stickiness.'));

14
plugins/LRDD/README Normal file
View File

@ -0,0 +1,14 @@
The LRDD plugin implements Link-based Resource Descriptor Discovery
based on RFC6415, Web Host Metadata, i.e. the predecessor to WebFinger resource
discovery.
See: http://tools.ietf.org/html/rfc6415
Installation
============
This plugin is enabled by default
Settings
========
none

View File

@ -147,7 +147,7 @@ class LdapAuthenticationPlugin extends AuthenticationPlugin
$versions[] = array('name' => 'LDAP Authentication',
'version' => GNUSOCIAL_VERSION,
'author' => 'Craig Andrews',
'homepage' => 'http://status.net/wiki/Plugin:LdapAuthentication',
'homepage' => 'https://git.gnu.io/gnu/gnu-social/tree/master/plugins/LdapAuthentication',
'rawdescription' =>
// TRANS: Plugin description.
_m('The LDAP Authentication plugin allows for StatusNet to handle authentication through LDAP.'));

View File

@ -123,7 +123,7 @@ class LdapAuthorizationPlugin extends AuthorizationPlugin
$versions[] = array('name' => 'LDAP Authorization',
'version' => GNUSOCIAL_VERSION,
'author' => 'Craig Andrews',
'homepage' => 'http://status.net/wiki/Plugin:LdapAuthorization',
'homepage' => 'https://git.gnu.io/gnu/gnu-social/tree/master/plugins/LdapAuthorization',
'rawdescription' =>
// TRANS: Plugin description.
_m('The LDAP Authorization plugin allows for StatusNet to handle authorization through LDAP.'));

View File

@ -62,7 +62,7 @@ class LilUrlPlugin extends UrlShortenerPlugin
$versions[] = array('name' => sprintf('LilUrl (%s)', $this->shortenerName),
'version' => GNUSOCIAL_VERSION,
'author' => 'Craig Andrews',
'homepage' => 'http://status.net/wiki/Plugin:LilUrl',
'homepage' => 'https://git.gnu.io/gnu/gnu-social/tree/master/plugins/LilUrl',
'rawdescription' =>
// TRANS: Plugin description.
// TRANS: %1$s is the service URL.

17
plugins/LilUrl/README Normal file
View File

@ -0,0 +1,17 @@
The LilUrl plugin shortens URLs via a lilURL instance.
See: http://lilurl.sourceforge.net/
Installation
============
add "addPlugin('LilUrl', array('serviceUrl' => 'http://example.org'));"
to the bottom of your config.php
Settings
========
serviceUrl: The URL to the LilUrl instance.
Example
=======
addPlugin('LilUrl', array('serviceUrl' => 'http://example.org'));

View File

@ -34,7 +34,7 @@ class LinkPreviewPlugin extends Plugin
$versions[] = array('name' => 'LinkPreview',
'version' => GNUSOCIAL_VERSION,
'author' => 'Brion Vibber',
'homepage' => 'http://status.net/wiki/Plugin:LinkPreview',
'homepage' => 'https://git.gnu.io/gnu/gnu-social/tree/master/plugins/LinkPreview',
'rawdescription' =>
// TRANS: Plugin description.
_m('UI extension for previewing thumbnails from links.'));

View File

@ -1 +1,23 @@
Depends on the oEmbed plugin (Oembed)
The LinkPreview plugin adds a UI for previewing thumbnails from links.
Note: This plugin depends on the "Oembed" plugin.
Installation
============
add "addPlugin('LinkPreview');"
to the bottom of your config.php
Settings
========
process_links: Whether to process links or not
thumbwidth: The width of the link preview
thumbheight: The height of the link preview
Example
=======
addPlugin('Oembed'); // Dependency
$config['attachments']['process_links'] = true;
$config['attachments']['thumbwidth'] = 42;
$config['attachments']['thumbheight'] = 42;
addPlugin('LinkPreview');

Some files were not shown because too many files have changed in this diff Show More