diff --git a/CONFIGURE b/CONFIGURE index 7e76ccf91b..b1773347d4 100644 --- a/CONFIGURE +++ b/CONFIGURE @@ -120,8 +120,9 @@ db -- This section is a reference to the configuration options for -DB_DataObject (see ). The ones that you may want to -set are listed below for clarity. +DB_DataObject (see +). +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 , so this can parallelize the job. - Defaults to null. + time , + 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 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 diff --git a/actions/showstream.php b/actions/showstream.php index 3ac837a67e..33ec49df99 100644 --- a/actions/showstream.php +++ b/actions/showstream.php @@ -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) { diff --git a/classes/Avatar.php b/classes/Avatar.php index d8cc134b80..62885f402b 100644 --- a/classes/Avatar.php +++ b/classes/Avatar.php @@ -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', diff --git a/classes/File.php b/classes/File.php index 6ba80eb5f6..ef4b2cfb3c 100644 --- a/classes/File.php +++ b/classes/File.php @@ -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]); } /** diff --git a/classes/File_redirection.php b/classes/File_redirection.php index 057647dfc5..8a490fb18a 100644 --- a/classes/File_redirection.php +++ b/classes/File_redirection.php @@ -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; } } diff --git a/classes/Notice.php b/classes/Notice.php index ccd398003d..2bae300115 100644 --- a/classes/Notice.php +++ b/classes/Notice.php @@ -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 diff --git a/classes/Profile.php b/classes/Profile.php index 7aae98fb5f..a5e0d092dc 100644 --- a/classes/Profile.php +++ b/classes/Profile.php @@ -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!) diff --git a/classes/User_group.php b/classes/User_group.php index 2484f3f265..ecec1ee663 100644 --- a/classes/User_group.php +++ b/classes/User_group.php @@ -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', diff --git a/extlib/Net/SMTP.php b/extlib/Net/SMTP.php index ea4b55e8d2..8f4e92b753 100644 --- a/extlib/Net/SMTP.php +++ b/extlib/Net/SMTP.php @@ -1,14 +1,14 @@ | // | Damian Alejandro Fernandez Sosa | // +----------------------------------------------------------------------+ -// -// $Id: SMTP.php 293948 2010-01-24 21:46:00Z jon $ require_once 'PEAR.php'; require_once 'Net/Socket.php'; /** * Provides an implementation of the SMTP protocol using PEAR's - * Net_Socket:: class. + * Net_Socket class. * * @package Net_SMTP * @author Chuck Hagenbuch * @author Jon Parise * @author Damian Alejandro Fernandez Sosa * - * @example basic.php A basic implementation of the Net_SMTP package. + * @example basic.php A basic implementation of the Net_SMTP package. */ class Net_SMTP { /** * The server to connect to. * @var string - * @access public */ - var $host = 'localhost'; + public $host = 'localhost'; /** * The port to connect to. * @var int - * @access public */ - var $port = 25; + public $port = 25; /** * The value to give when sending EHLO or HELO. * @var string - * @access public */ - var $localhost = 'localhost'; + public $localhost = 'localhost'; /** * List of supported authentication methods, in preferential order. * @var array - * @access public */ - var $auth_methods = array('DIGEST-MD5', 'CRAM-MD5', 'LOGIN', 'PLAIN'); + public $auth_methods = array(); /** * Use SMTP command pipelining (specified in RFC 2920) if the SMTP @@ -73,65 +67,69 @@ class Net_SMTP * SMTP server but return immediately. * * @var bool - * @access public */ - var $pipelining = false; + public $pipelining = false; /** * Number of pipelined commands. * @var int - * @access private */ - var $_pipelined_commands = 0; + protected $pipelined_commands = 0; /** * Should debugging output be enabled? * @var boolean - * @access private */ - var $_debug = false; + protected $debug = false; /** * Debug output handler. * @var callback - * @access private */ - var $_debug_handler = null; + protected $debug_handler = null; /** * The socket resource being used to connect to the SMTP server. * @var resource - * @access private */ - var $_socket = null; + protected $socket = null; + + /** + * Array of socket options that will be passed to Net_Socket::connect(). + * @see stream_context_create() + * @var array + */ + protected $socket_options = null; + + /** + * The socket I/O timeout value in seconds. + * @var int + */ + protected $timeout = 0; /** * The most recent server response code. * @var int - * @access private */ - var $_code = -1; + protected $code = -1; /** * The most recent server response arguments. * @var array - * @access private */ - var $_arguments = array(); + protected $arguments = array(); /** * Stores the SMTP server's greeting string. * @var string - * @access private */ - var $_greeting = null; + protected $greeting = null; /** * Stores detected features of the SMTP server. * @var array - * @access private */ - var $_esmtp = array(); + protected $esmtp = array(); /** * Instantiates a new Net_SMTP object, overriding any defaults @@ -144,16 +142,18 @@ class Net_SMTP * $smtp = new Net_SMTP('ssl://mail.host.com', 465); * $smtp->connect(); * - * @param string $host The server to connect to. - * @param integer $port The port to connect to. - * @param string $localhost The value to give when sending EHLO or HELO. - * @param boolean $pipeling Use SMTP command pipelining + * @param string $host The server to connect to. + * @param integer $port The port to connect to. + * @param string $localhost The value to give when sending EHLO or HELO. + * @param boolean $pipelining Use SMTP command pipelining + * @param integer $timeout Socket I/O timeout in seconds. + * @param array $socket_options Socket stream_context_create() options. * - * @access public - * @since 1.0 + * @since 1.0 */ - function Net_SMTP($host = null, $port = null, $localhost = null, $pipelining = false) - { + public function __construct($host = null, $port = null, $localhost = null, + $pipelining = false, $timeout = 0, $socket_options = null + ) { if (isset($host)) { $this->host = $host; } @@ -163,49 +163,65 @@ class Net_SMTP if (isset($localhost)) { $this->localhost = $localhost; } - $this->pipelining = $pipelining; - $this->_socket = new Net_Socket(); + $this->pipelining = $pipelining; + $this->socket = new Net_Socket(); + $this->socket_options = $socket_options; + $this->timeout = $timeout; - /* Include the Auth_SASL package. If the package is not - * available, we disable the authentication methods that - * depend upon it. */ - if ((@include_once 'Auth/SASL.php') === false) { - $pos = array_search('DIGEST-MD5', $this->auth_methods); - unset($this->auth_methods[$pos]); - $pos = array_search('CRAM-MD5', $this->auth_methods); - unset($this->auth_methods[$pos]); + /* Include the Auth_SASL package. If the package is available, we + * enable the authentication methods that depend upon it. */ + if (@include_once 'Auth/SASL.php') { + $this->setAuthMethod('CRAM-MD5', array($this, 'authCramMD5')); + $this->setAuthMethod('DIGEST-MD5', array($this, 'authDigestMD5')); } + + /* These standard authentication methods are always available. */ + $this->setAuthMethod('LOGIN', array($this, 'authLogin'), false); + $this->setAuthMethod('PLAIN', array($this, 'authPlain'), false); + } + + /** + * Set the socket I/O timeout value in seconds plus microseconds. + * + * @param integer $seconds Timeout value in seconds. + * @param integer $microseconds Additional value in microseconds. + * + * @since 1.5.0 + */ + public function setTimeout($seconds, $microseconds = 0) + { + return $this->socket->setTimeout($seconds, $microseconds); } /** * Set the value of the debugging flag. * - * @param boolean $debug New value for the debugging flag. + * @param boolean $debug New value for the debugging flag. + * @param callback $handler Debug handler callback * - * @access public - * @since 1.1.0 + * @since 1.1.0 */ - function setDebug($debug, $handler = null) + public function setDebug($debug, $handler = null) { - $this->_debug = $debug; - $this->_debug_handler = $handler; + $this->debug = $debug; + $this->debug_handler = $handler; } /** * Write the given debug text to the current debug output handler. * - * @param string $message Debug mesage text. + * @param string $message Debug mesage text. * - * @access private - * @since 1.3.3 + * @since 1.3.3 */ - function _debug($message) + protected function debug($message) { - if ($this->_debug) { - if ($this->_debug_handler) { - call_user_func_array($this->_debug_handler, - array(&$this, $message)); + if ($this->debug) { + if ($this->debug_handler) { + call_user_func_array( + $this->debug_handler, array(&$this, $message) + ); } else { echo "DEBUG: $message\n"; } @@ -215,24 +231,24 @@ class Net_SMTP /** * Send the given string of data to the server. * - * @param string $data The string of data to send. + * @param string $data The string of data to send. * - * @return mixed True on success or a PEAR_Error object on failure. + * @return mixed The number of bytes that were actually written, + * or a PEAR_Error object on failure. * - * @access private - * @since 1.1.0 + * @since 1.1.0 */ - function _send($data) + protected function send($data) { - $this->_debug("Send: $data"); + $this->debug("Send: $data"); - $error = $this->_socket->write($data); - if ($error === false || PEAR::isError($error)) { - $msg = ($error) ? $error->getMessage() : "unknown error"; + $result = $this->socket->write($data); + if (!$result || PEAR::isError($result)) { + $msg = $result ? $result->getMessage() : "unknown error"; return PEAR::raiseError("Failed to write to socket: $msg"); } - return true; + return $result; } /** @@ -240,19 +256,18 @@ class Net_SMTP * arguments. A carriage return / linefeed (CRLF) sequence will * be appended to each command string before it is sent to the * SMTP server - an error will be thrown if the command string - * already contains any newline characters. Use _send() for + * already contains any newline characters. Use send() for * commands that must contain newlines. * - * @param string $command The SMTP command to send to the server. - * @param string $args A string of optional arguments to append - * to the command. + * @param string $command The SMTP command to send to the server. + * @param string $args A string of optional arguments to append + * to the command. * - * @return mixed The result of the _send() call. + * @return mixed The result of the send() call. * - * @access private - * @since 1.1.0 + * @since 1.1.0 */ - function _put($command, $args = '') + protected function put($command, $args = '') { if (!empty($args)) { $command .= ' ' . $args; @@ -262,57 +277,56 @@ class Net_SMTP return PEAR::raiseError('Commands cannot contain newlines'); } - return $this->_send($command . "\r\n"); + return $this->send($command . "\r\n"); } /** * Read a reply from the SMTP server. The reply consists of a response * code and a response message. * - * @param mixed $valid The set of valid response codes. These - * may be specified as an array of integer - * values or as a single integer value. - * @param bool $later Do not parse the response now, but wait - * until the last command in the pipelined - * command group + * @param mixed $valid The set of valid response codes. These + * may be specified as an array of integer + * values or as a single integer value. + * @param bool $later Do not parse the response now, but wait + * until the last command in the pipelined + * command group * - * @return mixed True if the server returned a valid response code or - * a PEAR_Error object is an error condition is reached. + * @return mixed True if the server returned a valid response code or + * a PEAR_Error object is an error condition is reached. * - * @access private - * @since 1.1.0 + * @since 1.1.0 * - * @see getResponse + * @see getResponse */ - function _parseResponse($valid, $later = false) + protected function parseResponse($valid, $later = false) { - $this->_code = -1; - $this->_arguments = array(); + $this->code = -1; + $this->arguments = array(); if ($later) { - $this->_pipelined_commands++; + $this->pipelined_commands++; return true; } - for ($i = 0; $i <= $this->_pipelined_commands; $i++) { - while ($line = $this->_socket->readLine()) { - $this->_debug("Recv: $line"); + for ($i = 0; $i <= $this->pipelined_commands; $i++) { + while ($line = $this->socket->readLine()) { + $this->debug("Recv: $line"); - /* If we receive an empty line, the connection has been closed. */ + /* If we receive an empty line, the connection was closed. */ if (empty($line)) { $this->disconnect(); - return PEAR::raiseError('Connection was unexpectedly closed'); + return PEAR::raiseError('Connection was closed'); } /* Read the code and store the rest in the arguments array. */ $code = substr($line, 0, 3); - $this->_arguments[] = trim(substr($line, 4)); + $this->arguments[] = trim(substr($line, 4)); /* Check the syntax of the response code. */ if (is_numeric($code)) { - $this->_code = (int)$code; + $this->code = (int)$code; } else { - $this->_code = -1; + $this->code = -1; break; } @@ -323,79 +337,115 @@ class Net_SMTP } } - $this->_pipelined_commands = 0; + $this->pipelined_commands = 0; /* Compare the server's response code with the valid code/codes. */ - if (is_int($valid) && ($this->_code === $valid)) { + if (is_int($valid) && ($this->code === $valid)) { return true; - } elseif (is_array($valid) && in_array($this->_code, $valid, true)) { + } elseif (is_array($valid) && in_array($this->code, $valid, true)) { return true; } - return PEAR::raiseError('Invalid response code received from server', - $this->_code); + return PEAR::raiseError('Invalid response code received from server', $this->code); + } + + /** + * Issue an SMTP command and verify its response. + * + * @param string $command The SMTP command string or data. + * @param mixed $valid The set of valid response codes. These + * may be specified as an array of integer + * values or as a single integer value. + * + * @return mixed True on success or a PEAR_Error object on failure. + * + * @since 1.6.0 + */ + public function command($command, $valid) + { + if (PEAR::isError($error = $this->put($command))) { + return $error; + } + if (PEAR::isError($error = $this->parseResponse($valid))) { + return $error; + } + + return true; } /** * Return a 2-tuple containing the last response from the SMTP server. * - * @return array A two-element array: the first element contains the - * response code as an integer and the second element - * contains the response's arguments as a string. + * @return array A two-element array: the first element contains the + * response code as an integer and the second element + * contains the response's arguments as a string. * - * @access public - * @since 1.1.0 + * @since 1.1.0 */ - function getResponse() + public function getResponse() { - return array($this->_code, join("\n", $this->_arguments)); + return array($this->code, join("\n", $this->arguments)); } /** * Return the SMTP server's greeting string. * - * @return string A string containing the greeting string, or null if a - * greeting has not been received. + * @return string A string containing the greeting string, or null if + * a greeting has not been received. * - * @access public - * @since 1.3.3 + * @since 1.3.3 */ - function getGreeting() + public function getGreeting() { - return $this->_greeting; + return $this->greeting; } /** * Attempt to connect to the SMTP server. * - * @param int $timeout The timeout value (in seconds) for the - * socket connection. - * @param bool $persistent Should a persistent socket connection - * be used? + * @param int $timeout The timeout value (in seconds) for the + * socket connection attempt. + * @param bool $persistent Should a persistent socket connection + * be used? * * @return mixed Returns a PEAR_Error with an error message on any * kind of failure, or true on success. - * @access public - * @since 1.0 + * @since 1.0 */ - function connect($timeout = null, $persistent = false) + public function connect($timeout = null, $persistent = false) { - $this->_greeting = null; - $result = $this->_socket->connect($this->host, $this->port, - $persistent, $timeout); + $this->greeting = null; + + $result = $this->socket->connect( + $this->host, $this->port, $persistent, $timeout, $this->socket_options + ); + if (PEAR::isError($result)) { - return PEAR::raiseError('Failed to connect socket: ' . - $result->getMessage()); + return PEAR::raiseError( + 'Failed to connect socket: ' . $result->getMessage() + ); } - if (PEAR::isError($error = $this->_parseResponse(220))) { + /* + * Now that we're connected, reset the socket's timeout value for + * future I/O operations. This allows us to have different socket + * timeout values for the initial connection (our $timeout parameter) + * and all other socket operations. + */ + if ($this->timeout > 0) { + if (PEAR::isError($error = $this->setTimeout($this->timeout))) { + return $error; + } + } + + if (PEAR::isError($error = $this->parseResponse(220))) { return $error; } /* Extract and store a copy of the server's greeting string. */ - list(, $this->_greeting) = $this->getResponse(); + list(, $this->greeting) = $this->getResponse(); - if (PEAR::isError($error = $this->_negotiate())) { + if (PEAR::isError($error = $this->negotiate())) { return $error; } @@ -407,20 +457,20 @@ class Net_SMTP * * @return mixed Returns a PEAR_Error with an error message on any * kind of failure, or true on success. - * @access public - * @since 1.0 + * @since 1.0 */ - function disconnect() + public function disconnect() { - if (PEAR::isError($error = $this->_put('QUIT'))) { + if (PEAR::isError($error = $this->put('QUIT'))) { return $error; } - if (PEAR::isError($error = $this->_parseResponse(221))) { + if (PEAR::isError($error = $this->parseResponse(221))) { return $error; } - if (PEAR::isError($error = $this->_socket->disconnect())) { - return PEAR::raiseError('Failed to disconnect socket: ' . - $error->getMessage()); + if (PEAR::isError($error = $this->socket->disconnect())) { + return PEAR::raiseError( + 'Failed to disconnect socket: ' . $error->getMessage() + ); } return true; @@ -433,40 +483,34 @@ class Net_SMTP * @return mixed Returns a PEAR_Error with an error message on any * kind of failure, or true on success. * - * @access private - * @since 1.1.0 + * @since 1.1.0 */ - function _negotiate() + protected function negotiate() { - if (PEAR::isError($error = $this->_put('EHLO', $this->localhost))) { + if (PEAR::isError($error = $this->put('EHLO', $this->localhost))) { return $error; } - if (PEAR::isError($this->_parseResponse(250))) { - /* If we receive a 503 response, we're already authenticated. */ - if ($this->_code === 503) { - return true; - } - + if (PEAR::isError($this->parseResponse(250))) { /* If the EHLO failed, try the simpler HELO command. */ - if (PEAR::isError($error = $this->_put('HELO', $this->localhost))) { + if (PEAR::isError($error = $this->put('HELO', $this->localhost))) { return $error; } - if (PEAR::isError($this->_parseResponse(250))) { - return PEAR::raiseError('HELO was not accepted: ', $this->_code); + if (PEAR::isError($this->parseResponse(250))) { + return PEAR::raiseError('HELO was not accepted', $this->code); } return true; } - foreach ($this->_arguments as $argument) { - $verb = strtok($argument, ' '); - $arguments = substr($argument, strlen($verb) + 1, - strlen($argument) - strlen($verb) - 1); - $this->_esmtp[$verb] = $arguments; + foreach ($this->arguments as $argument) { + $verb = strtok($argument, ' '); + $len = strlen($verb); + $arguments = substr($argument, $len + 1, strlen($argument) - $len - 1); + $this->esmtp[$verb] = $arguments; } - if (!isset($this->_esmtp['PIPELINING'])) { + if (!isset($this->esmtp['PIPELINING'])) { $this->pipelining = false; } @@ -477,17 +521,16 @@ class Net_SMTP * Returns the name of the best authentication method that the server * has advertised. * - * @return mixed Returns a string containing the name of the best - * supported authentication method or a PEAR_Error object - * if a failure condition is encountered. - * @access private - * @since 1.1.0 + * @return mixed Returns a string containing the name of the best + * supported authentication method or a PEAR_Error object + * if a failure condition is encountered. + * @since 1.1.0 */ - function _getBestAuthMethod() + protected function getBestAuthMethod() { - $available_methods = explode(' ', $this->_esmtp['AUTH']); + $available_methods = explode(' ', $this->esmtp['AUTH']); - foreach ($this->auth_methods as $method) { + foreach ($this->auth_methods as $method => $callback) { if (in_array($method, $available_methods)) { return $method; } @@ -499,35 +542,47 @@ class Net_SMTP /** * Attempt to do SMTP authentication. * - * @param string The userid to authenticate as. - * @param string The password to authenticate with. - * @param string The requested authentication method. If none is - * specified, the best supported method will be used. - * @param bool Flag indicating whether or not TLS should be attempted. + * @param string $uid The userid to authenticate as. + * @param string $pwd The password to authenticate with. + * @param string $method The requested authentication method. If none is + * specified, the best supported method will be used. + * @param bool $tls Flag indicating whether or not TLS should be attempted. + * @param string $authz An optional authorization identifier. If specified, this + * identifier will be used as the authorization proxy. * * @return mixed Returns a PEAR_Error with an error message on any * kind of failure, or true on success. - * @access public - * @since 1.0 + * @since 1.0 */ - function auth($uid, $pwd , $method = '', $tls = true) + public function auth($uid, $pwd , $method = '', $tls = true, $authz = '') { /* We can only attempt a TLS connection if one has been requested, - * we're running PHP 5.1.0 or later, have access to the OpenSSL - * extension, are connected to an SMTP server which supports the - * STARTTLS extension, and aren't already connected over a secure + * we're running PHP 5.1.0 or later, have access to the OpenSSL + * extension, are connected to an SMTP server which supports the + * STARTTLS extension, and aren't already connected over a secure * (SSL) socket connection. */ - if ($tls && version_compare(PHP_VERSION, '5.1.0', '>=') && - extension_loaded('openssl') && isset($this->_esmtp['STARTTLS']) && - strncasecmp($this->host, 'ssl://', 6) !== 0) { + if ($tls && version_compare(PHP_VERSION, '5.1.0', '>=') + && extension_loaded('openssl') && isset($this->esmtp['STARTTLS']) + && strncasecmp($this->host, 'ssl://', 6) !== 0 + ) { /* Start the TLS connection attempt. */ - if (PEAR::isError($result = $this->_put('STARTTLS'))) { + if (PEAR::isError($result = $this->put('STARTTLS'))) { return $result; } - if (PEAR::isError($result = $this->_parseResponse(220))) { + if (PEAR::isError($result = $this->parseResponse(220))) { return $result; } - if (PEAR::isError($result = $this->_socket->enableCrypto(true, STREAM_CRYPTO_METHOD_TLS_CLIENT))) { + if (isset($this->socket_options['ssl']['crypto_method'])) { + $crypto_method = $this->socket_options['ssl']['crypto_method']; + } else { + /* STREAM_CRYPTO_METHOD_TLS_ANY_CLIENT constant does not exist + * and STREAM_CRYPTO_METHOD_SSLv23_CLIENT constant is + * inconsistent across PHP versions. */ + $crypto_method = STREAM_CRYPTO_METHOD_TLS_CLIENT + | @STREAM_CRYPTO_METHOD_TLSv1_1_CLIENT + | @STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT; + } + if (PEAR::isError($result = $this->socket->enableCrypto(true, $crypto_method))) { return $result; } elseif ($result !== true) { return PEAR::raiseError('STARTTLS failed'); @@ -535,47 +590,41 @@ class Net_SMTP /* Send EHLO again to recieve the AUTH string from the * SMTP server. */ - $this->_negotiate(); + $this->negotiate(); } - if (empty($this->_esmtp['AUTH'])) { + if (empty($this->esmtp['AUTH'])) { return PEAR::raiseError('SMTP server does not support authentication'); } /* If no method has been specified, get the name of the best * supported method advertised by the SMTP server. */ if (empty($method)) { - if (PEAR::isError($method = $this->_getBestAuthMethod())) { + if (PEAR::isError($method = $this->getBestAuthMethod())) { /* Return the PEAR_Error object from _getBestAuthMethod(). */ return $method; } } else { $method = strtoupper($method); - if (!in_array($method, $this->auth_methods)) { + if (!array_key_exists($method, $this->auth_methods)) { return PEAR::raiseError("$method is not a supported authentication method"); } } - switch ($method) { - case 'DIGEST-MD5': - $result = $this->_authDigest_MD5($uid, $pwd); - break; + if (!isset($this->auth_methods[$method])) { + return PEAR::raiseError("$method is not a supported authentication method"); + } - case 'CRAM-MD5': - $result = $this->_authCRAM_MD5($uid, $pwd); - break; + if (!is_callable($this->auth_methods[$method], false)) { + return PEAR::raiseError("$method authentication method cannot be called"); + } - case 'LOGIN': - $result = $this->_authLogin($uid, $pwd); - break; - - case 'PLAIN': - $result = $this->_authPlain($uid, $pwd); - break; - - default: - $result = PEAR::raiseError("$method is not a supported authentication method"); - break; + if (is_array($this->auth_methods[$method])) { + list($object, $method) = $this->auth_methods[$method]; + $result = $object->{$method}($uid, $pwd, $authz, $this); + } else { + $func = $this->auth_methods[$method]; + $result = $func($uid, $pwd, $authz, $this); } /* If an error was encountered, return the PEAR_Error object. */ @@ -586,52 +635,94 @@ class Net_SMTP return true; } + /** + * Add a new authentication method. + * + * @param string $name The authentication method name (e.g. 'PLAIN') + * @param mixed $callback The authentication callback (given as the name of a + * function or as an (object, method name) array). + * @param bool $prepend Should the new method be prepended to the list of + * available methods? This is the default behavior, + * giving the new method the highest priority. + * + * @return mixed True on success or a PEAR_Error object on failure. + * + * @since 1.6.0 + */ + public function setAuthMethod($name, $callback, $prepend = true) + { + if (!is_string($name)) { + return PEAR::raiseError('Method name is not a string'); + } + + if (!is_string($callback) && !is_array($callback)) { + return PEAR::raiseError('Method callback must be string or array'); + } + + if (is_array($callback)) { + if (!is_object($callback[0]) || !is_string($callback[1])) { + return PEAR::raiseError('Bad mMethod callback array'); + } + } + + if ($prepend) { + $this->auth_methods = array_merge( + array($name => $callback), $this->auth_methods + ); + } else { + $this->auth_methods[$name] = $callback; + } + + return true; + } + /** * Authenticates the user using the DIGEST-MD5 method. * - * @param string The userid to authenticate as. - * @param string The password to authenticate with. + * @param string $uid The userid to authenticate as. + * @param string $pwd The password to authenticate with. + * @param string $authz The optional authorization proxy identifier. * * @return mixed Returns a PEAR_Error with an error message on any * kind of failure, or true on success. - * @access private - * @since 1.1.0 + * @since 1.1.0 */ - function _authDigest_MD5($uid, $pwd) + protected function authDigestMD5($uid, $pwd, $authz = '') { - if (PEAR::isError($error = $this->_put('AUTH', 'DIGEST-MD5'))) { + if (PEAR::isError($error = $this->put('AUTH', 'DIGEST-MD5'))) { return $error; } /* 334: Continue authentication request */ - if (PEAR::isError($error = $this->_parseResponse(334))) { + if (PEAR::isError($error = $this->parseResponse(334))) { /* 503: Error: already authenticated */ - if ($this->_code === 503) { + if ($this->code === 503) { return true; } return $error; } - $challenge = base64_decode($this->_arguments[0]); - $digest = &Auth_SASL::factory('digestmd5'); - $auth_str = base64_encode($digest->getResponse($uid, $pwd, $challenge, - $this->host, "smtp")); + $digest = Auth_SASL::factory('digest-md5'); + $challenge = base64_decode($this->arguments[0]); + $auth_str = base64_encode( + $digest->getResponse($uid, $pwd, $challenge, $this->host, "smtp", $authz) + ); - if (PEAR::isError($error = $this->_put($auth_str))) { + if (PEAR::isError($error = $this->put($auth_str))) { return $error; } /* 334: Continue authentication request */ - if (PEAR::isError($error = $this->_parseResponse(334))) { + if (PEAR::isError($error = $this->parseResponse(334))) { return $error; } /* We don't use the protocol's third step because SMTP doesn't * allow subsequent authentication, so we just silently ignore * it. */ - if (PEAR::isError($error = $this->_put(''))) { + if (PEAR::isError($error = $this->put(''))) { return $error; } /* 235: Authentication successful */ - if (PEAR::isError($error = $this->_parseResponse(235))) { + if (PEAR::isError($error = $this->parseResponse(235))) { return $error; } } @@ -639,38 +730,38 @@ class Net_SMTP /** * Authenticates the user using the CRAM-MD5 method. * - * @param string The userid to authenticate as. - * @param string The password to authenticate with. + * @param string $uid The userid to authenticate as. + * @param string $pwd The password to authenticate with. + * @param string $authz The optional authorization proxy identifier. * * @return mixed Returns a PEAR_Error with an error message on any * kind of failure, or true on success. - * @access private - * @since 1.1.0 + * @since 1.1.0 */ - function _authCRAM_MD5($uid, $pwd) + protected function authCRAMMD5($uid, $pwd, $authz = '') { - if (PEAR::isError($error = $this->_put('AUTH', 'CRAM-MD5'))) { + if (PEAR::isError($error = $this->put('AUTH', 'CRAM-MD5'))) { return $error; } /* 334: Continue authentication request */ - if (PEAR::isError($error = $this->_parseResponse(334))) { + if (PEAR::isError($error = $this->parseResponse(334))) { /* 503: Error: already authenticated */ - if ($this->_code === 503) { + if ($this->code === 503) { return true; } return $error; } - $challenge = base64_decode($this->_arguments[0]); - $cram = &Auth_SASL::factory('crammd5'); - $auth_str = base64_encode($cram->getResponse($uid, $pwd, $challenge)); + $challenge = base64_decode($this->arguments[0]); + $cram = Auth_SASL::factory('cram-md5'); + $auth_str = base64_encode($cram->getResponse($uid, $pwd, $challenge)); - if (PEAR::isError($error = $this->_put($auth_str))) { + if (PEAR::isError($error = $this->put($auth_str))) { return $error; } /* 235: Authentication successful */ - if (PEAR::isError($error = $this->_parseResponse(235))) { + if (PEAR::isError($error = $this->parseResponse(235))) { return $error; } } @@ -678,42 +769,42 @@ class Net_SMTP /** * Authenticates the user using the LOGIN method. * - * @param string The userid to authenticate as. - * @param string The password to authenticate with. + * @param string $uid The userid to authenticate as. + * @param string $pwd The password to authenticate with. + * @param string $authz The optional authorization proxy identifier. * * @return mixed Returns a PEAR_Error with an error message on any * kind of failure, or true on success. - * @access private - * @since 1.1.0 + * @since 1.1.0 */ - function _authLogin($uid, $pwd) + protected function authLogin($uid, $pwd, $authz = '') { - if (PEAR::isError($error = $this->_put('AUTH', 'LOGIN'))) { + if (PEAR::isError($error = $this->put('AUTH', 'LOGIN'))) { return $error; } /* 334: Continue authentication request */ - if (PEAR::isError($error = $this->_parseResponse(334))) { + if (PEAR::isError($error = $this->parseResponse(334))) { /* 503: Error: already authenticated */ - if ($this->_code === 503) { + if ($this->code === 503) { return true; } return $error; } - if (PEAR::isError($error = $this->_put(base64_encode($uid)))) { + if (PEAR::isError($error = $this->put(base64_encode($uid)))) { return $error; } /* 334: Continue authentication request */ - if (PEAR::isError($error = $this->_parseResponse(334))) { + if (PEAR::isError($error = $this->parseResponse(334))) { return $error; } - if (PEAR::isError($error = $this->_put(base64_encode($pwd)))) { + if (PEAR::isError($error = $this->put(base64_encode($pwd)))) { return $error; } /* 235: Authentication successful */ - if (PEAR::isError($error = $this->_parseResponse(235))) { + if (PEAR::isError($error = $this->parseResponse(235))) { return $error; } @@ -723,36 +814,36 @@ class Net_SMTP /** * Authenticates the user using the PLAIN method. * - * @param string The userid to authenticate as. - * @param string The password to authenticate with. + * @param string $uid The userid to authenticate as. + * @param string $pwd The password to authenticate with. + * @param string $authz The optional authorization proxy identifier. * * @return mixed Returns a PEAR_Error with an error message on any * kind of failure, or true on success. - * @access private - * @since 1.1.0 + * @since 1.1.0 */ - function _authPlain($uid, $pwd) + protected function authPlain($uid, $pwd, $authz = '') { - if (PEAR::isError($error = $this->_put('AUTH', 'PLAIN'))) { + if (PEAR::isError($error = $this->put('AUTH', 'PLAIN'))) { return $error; } /* 334: Continue authentication request */ - if (PEAR::isError($error = $this->_parseResponse(334))) { + if (PEAR::isError($error = $this->parseResponse(334))) { /* 503: Error: already authenticated */ - if ($this->_code === 503) { + if ($this->code === 503) { return true; } return $error; } - $auth_str = base64_encode(chr(0) . $uid . chr(0) . $pwd); + $auth_str = base64_encode($authz . chr(0) . $uid . chr(0) . $pwd); - if (PEAR::isError($error = $this->_put($auth_str))) { + if (PEAR::isError($error = $this->put($auth_str))) { return $error; } /* 235: Authentication successful */ - if (PEAR::isError($error = $this->_parseResponse(235))) { + if (PEAR::isError($error = $this->parseResponse(235))) { return $error; } @@ -762,19 +853,18 @@ class Net_SMTP /** * Send the HELO command. * - * @param string The domain name to say we are. + * @param string $domain The domain name to say we are. * * @return mixed Returns a PEAR_Error with an error message on any * kind of failure, or true on success. - * @access public - * @since 1.0 + * @since 1.0 */ - function helo($domain) + public function helo($domain) { - if (PEAR::isError($error = $this->_put('HELO', $domain))) { + if (PEAR::isError($error = $this->put('HELO', $domain))) { return $error; } - if (PEAR::isError($error = $this->_parseResponse(250))) { + if (PEAR::isError($error = $this->parseResponse(250))) { return $error; } @@ -785,55 +875,50 @@ class Net_SMTP * Return the list of SMTP service extensions advertised by the server. * * @return array The list of SMTP service extensions. - * @access public * @since 1.3 */ - function getServiceExtensions() + public function getServiceExtensions() { - return $this->_esmtp; + return $this->esmtp; } /** * Send the MAIL FROM: command. * - * @param string $sender The sender (reverse path) to set. - * @param string $params String containing additional MAIL parameters, - * such as the NOTIFY flags defined by RFC 1891 - * or the VERP protocol. + * @param string $sender The sender (reverse path) to set. + * @param string $params String containing additional MAIL parameters, + * such as the NOTIFY flags defined by RFC 1891 + * or the VERP protocol. * - * If $params is an array, only the 'verp' option - * is supported. If 'verp' is true, the XVERP - * parameter is appended to the MAIL command. If - * the 'verp' value is a string, the full - * XVERP=value parameter is appended. + * If $params is an array, only the 'verp' option + * is supported. If 'verp' is true, the XVERP + * parameter is appended to the MAIL command. + * If the 'verp' value is a string, the full + * XVERP=value parameter is appended. * * @return mixed Returns a PEAR_Error with an error message on any * kind of failure, or true on success. - * @access public - * @since 1.0 + * @since 1.0 */ - function mailFrom($sender, $params = null) + public function mailFrom($sender, $params = null) { $args = "FROM:<$sender>"; /* Support the deprecated array form of $params. */ if (is_array($params) && isset($params['verp'])) { - /* XVERP */ if ($params['verp'] === true) { $args .= ' XVERP'; - - /* XVERP=something */ } elseif (trim($params['verp'])) { $args .= ' XVERP=' . $params['verp']; } - } elseif (is_string($params)) { + } elseif (is_string($params) && !empty($params)) { $args .= ' ' . $params; } - if (PEAR::isError($error = $this->_put('MAIL', $args))) { + if (PEAR::isError($error = $this->put('MAIL', $args))) { return $error; } - if (PEAR::isError($error = $this->_parseResponse(250, $this->pipelining))) { + if (PEAR::isError($error = $this->parseResponse(250, $this->pipelining))) { return $error; } @@ -850,20 +935,19 @@ class Net_SMTP * @return mixed Returns a PEAR_Error with an error message on any * kind of failure, or true on success. * - * @access public - * @since 1.0 + * @since 1.0 */ - function rcptTo($recipient, $params = null) + public function rcptTo($recipient, $params = null) { $args = "TO:<$recipient>"; if (is_string($params)) { $args .= ' ' . $params; } - if (PEAR::isError($error = $this->_put('RCPT', $args))) { + if (PEAR::isError($error = $this->put('RCPT', $args))) { return $error; } - if (PEAR::isError($error = $this->_parseResponse(array(250, 251), $this->pipelining))) { + if (PEAR::isError($error = $this->parseResponse(array(250, 251), $this->pipelining))) { return $error; } @@ -877,83 +961,77 @@ class Net_SMTP * easier overloading for the cases where it is desirable to * customize the quoting behavior. * - * @param string $data The message text to quote. The string must be passed + * @param string &$data The message text to quote. The string must be passed * by reference, and the text will be modified in place. * - * @access public - * @since 1.2 + * @since 1.2 */ - function quotedata(&$data) + public function quotedata(&$data) { - /* Change Unix (\n) and Mac (\r) linefeeds into - * Internet-standard CRLF (\r\n) linefeeds. */ - $data = preg_replace(array('/(?_esmtp['SIZE']) && ($this->_esmtp['SIZE'] > 0)) { - /* Start by considering the size of the optional headers string. - * We also account for the addition 4 character "\r\n\r\n" - * separator sequence. */ - $size = (is_null($headers)) ? 0 : strlen($headers) + 4; + /* Start by considering the size of the optional headers string. We + * also account for the addition 4 character "\r\n\r\n" separator + * sequence. */ + $size = (is_null($headers)) ? 0 : strlen($headers) + 4; - if (is_resource($data)) { - $stat = fstat($data); - if ($stat === false) { - return PEAR::raiseError('Failed to get file size'); - } - $size += $stat['size']; - } else { - $size += strlen($data); + if (is_resource($data)) { + $stat = fstat($data); + if ($stat === false) { + return PEAR::raiseError('Failed to get file size'); } + $size += $stat['size']; + } else { + $size += strlen($data); + } - if ($size >= $this->_esmtp['SIZE']) { - $this->disconnect(); - return PEAR::raiseError('Message size exceeds server limit'); - } + /* RFC 1870, section 3, subsection 3 states "a value of zero indicates + * that no fixed maximum message size is in force". Furthermore, it + * says that if "the parameter is omitted no information is conveyed + * about the server's fixed maximum message size". */ + $limit = (isset($this->esmtp['SIZE'])) ? $this->esmtp['SIZE'] : 0; + if ($limit > 0 && $size >= $limit) { + $this->disconnect(); + return PEAR::raiseError('Message size exceeds server limit'); } /* Initiate the DATA command. */ - if (PEAR::isError($error = $this->_put('DATA'))) { + if (PEAR::isError($error = $this->put('DATA'))) { return $error; } - if (PEAR::isError($error = $this->_parseResponse(354))) { + if (PEAR::isError($error = $this->parseResponse(354))) { return $error; } /* If we have a separate headers string, send it first. */ if (!is_null($headers)) { $this->quotedata($headers); - if (PEAR::isError($result = $this->_send($headers . "\r\n\r\n"))) { + if (PEAR::isError($result = $this->send($headers . "\r\n\r\n"))) { return $result; } } @@ -963,28 +1041,72 @@ class Net_SMTP /* Stream the contents of the file resource out over our socket * connection, line by line. Each line must be run through the * quoting routine. */ - while ($line = fgets($data, 1024)) { + while (strlen($line = fread($data, 8192)) > 0) { + /* If the last character is an newline, we need to grab the + * next character to check to see if it is a period. */ + while (!feof($data)) { + $char = fread($data, 1); + $line .= $char; + if ($char != "\n") { + break; + } + } $this->quotedata($line); - if (PEAR::isError($result = $this->_send($line))) { + if (PEAR::isError($result = $this->send($line))) { return $result; } } - /* Finally, send the DATA terminator sequence. */ - if (PEAR::isError($result = $this->_send("\r\n.\r\n"))) { - return $result; - } + $last = $line; } else { - /* Just send the entire quoted string followed by the DATA - * terminator. */ - $this->quotedata($data); - if (PEAR::isError($result = $this->_send($data . "\r\n.\r\n"))) { - return $result; + /* + * Break up the data by sending one chunk (up to 512k) at a time. + * This approach reduces our peak memory usage. + */ + for ($offset = 0; $offset < $size;) { + $end = $offset + 512000; + + /* + * Ensure we don't read beyond our data size or span multiple + * lines. quotedata() can't properly handle character data + * that's split across two line break boundaries. + */ + if ($end >= $size) { + $end = $size; + } else { + for (; $end < $size; $end++) { + if ($data[$end] != "\n") { + break; + } + } + } + + /* Extract our chunk and run it through the quoting routine. */ + $chunk = substr($data, $offset, $end - $offset); + $this->quotedata($chunk); + + /* If we run into a problem along the way, abort. */ + if (PEAR::isError($result = $this->send($chunk))) { + return $result; + } + + /* Advance the offset to the end of this chunk. */ + $offset = $end; } + + $last = $chunk; + } + + /* Don't add another CRLF sequence if it's already in the data */ + $terminator = (substr($last, -2) == "\r\n" ? '' : "\r\n") . ".\r\n"; + + /* Finally, send the DATA terminator sequence. */ + if (PEAR::isError($result = $this->send($terminator))) { + return $result; } /* Verify that the data was successfully received by the server. */ - if (PEAR::isError($error = $this->_parseResponse(250, $this->pipelining))) { + if (PEAR::isError($error = $this->parseResponse(250, $this->pipelining))) { return $error; } @@ -994,134 +1116,79 @@ class Net_SMTP /** * Send the SEND FROM: command. * - * @param string The reverse path to send. + * @param string $path The reverse path to send. * * @return mixed Returns a PEAR_Error with an error message on any * kind of failure, or true on success. - * @access public - * @since 1.2.6 + * @since 1.2.6 */ - function sendFrom($path) + public function sendFrom($path) { - if (PEAR::isError($error = $this->_put('SEND', "FROM:<$path>"))) { + if (PEAR::isError($error = $this->put('SEND', "FROM:<$path>"))) { return $error; } - if (PEAR::isError($error = $this->_parseResponse(250, $this->pipelining))) { + if (PEAR::isError($error = $this->parseResponse(250, $this->pipelining))) { return $error; } return true; } - /** - * Backwards-compatibility wrapper for sendFrom(). - * - * @param string The reverse path to send. - * - * @return mixed Returns a PEAR_Error with an error message on any - * kind of failure, or true on success. - * - * @access public - * @since 1.0 - * @deprecated 1.2.6 - */ - function send_from($path) - { - return sendFrom($path); - } - /** * Send the SOML FROM: command. * - * @param string The reverse path to send. + * @param string $path The reverse path to send. * * @return mixed Returns a PEAR_Error with an error message on any * kind of failure, or true on success. - * @access public - * @since 1.2.6 + * @since 1.2.6 */ - function somlFrom($path) + public function somlFrom($path) { - if (PEAR::isError($error = $this->_put('SOML', "FROM:<$path>"))) { + if (PEAR::isError($error = $this->put('SOML', "FROM:<$path>"))) { return $error; } - if (PEAR::isError($error = $this->_parseResponse(250, $this->pipelining))) { + if (PEAR::isError($error = $this->parseResponse(250, $this->pipelining))) { return $error; } return true; } - /** - * Backwards-compatibility wrapper for somlFrom(). - * - * @param string The reverse path to send. - * - * @return mixed Returns a PEAR_Error with an error message on any - * kind of failure, or true on success. - * - * @access public - * @since 1.0 - * @deprecated 1.2.6 - */ - function soml_from($path) - { - return somlFrom($path); - } - /** * Send the SAML FROM: command. * - * @param string The reverse path to send. + * @param string $path The reverse path to send. * * @return mixed Returns a PEAR_Error with an error message on any * kind of failure, or true on success. - * @access public - * @since 1.2.6 + * @since 1.2.6 */ - function samlFrom($path) + public function samlFrom($path) { - if (PEAR::isError($error = $this->_put('SAML', "FROM:<$path>"))) { + if (PEAR::isError($error = $this->put('SAML', "FROM:<$path>"))) { return $error; } - if (PEAR::isError($error = $this->_parseResponse(250, $this->pipelining))) { + if (PEAR::isError($error = $this->parseResponse(250, $this->pipelining))) { return $error; } return true; } - /** - * Backwards-compatibility wrapper for samlFrom(). - * - * @param string The reverse path to send. - * - * @return mixed Returns a PEAR_Error with an error message on any - * kind of failure, or true on success. - * - * @access public - * @since 1.0 - * @deprecated 1.2.6 - */ - function saml_from($path) - { - return samlFrom($path); - } - /** * Send the RSET command. * * @return mixed Returns a PEAR_Error with an error message on any * kind of failure, or true on success. - * @access public * @since 1.0 */ - function rset() + public function rset() { - if (PEAR::isError($error = $this->_put('RSET'))) { + if (PEAR::isError($error = $this->put('RSET'))) { return $error; } - if (PEAR::isError($error = $this->_parseResponse(250, $this->pipelining))) { + if (PEAR::isError($error = $this->parseResponse(250, $this->pipelining))) { return $error; } @@ -1131,20 +1198,19 @@ class Net_SMTP /** * Send the VRFY command. * - * @param string The string to verify + * @param string $string The string to verify * * @return mixed Returns a PEAR_Error with an error message on any * kind of failure, or true on success. - * @access public - * @since 1.0 + * @since 1.0 */ - function vrfy($string) + public function vrfy($string) { /* Note: 251 is also a valid response code */ - if (PEAR::isError($error = $this->_put('VRFY', $string))) { + if (PEAR::isError($error = $this->put('VRFY', $string))) { return $error; } - if (PEAR::isError($error = $this->_parseResponse(array(250, 252)))) { + if (PEAR::isError($error = $this->parseResponse(array(250, 252)))) { return $error; } @@ -1156,15 +1222,14 @@ class Net_SMTP * * @return mixed Returns a PEAR_Error with an error message on any * kind of failure, or true on success. - * @access public - * @since 1.0 + * @since 1.0 */ - function noop() + public function noop() { - if (PEAR::isError($error = $this->_put('NOOP'))) { + if (PEAR::isError($error = $this->put('NOOP'))) { return $error; } - if (PEAR::isError($error = $this->_parseResponse(250))) { + if (PEAR::isError($error = $this->parseResponse(250))) { return $error; } @@ -1175,14 +1240,12 @@ class Net_SMTP * Backwards-compatibility method. identifySender()'s functionality is * now handled internally. * - * @return boolean This method always return true. + * @return boolean This method always return true. * - * @access public - * @since 1.0 + * @since 1.0 */ - function identifySender() + public function identifySender() { return true; } - } diff --git a/extlib/Net/Socket.php b/extlib/Net/Socket.php index 73bb4dd11f..bf1d1bbcd1 100644 --- a/extlib/Net/Socket.php +++ b/extlib/Net/Socket.php @@ -1,39 +1,50 @@ | -// | Chuck Hagenbuch | -// +----------------------------------------------------------------------+ -// -// $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 + * Chuck Hagenbuch + * + * @category Net + * @package Net_Socket + * @author Stig Bakken + * @author Chuck Hagenbuch + * @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 - * @author Chuck Hagenbuch + * @category Net + * @package Net_Socket + * @author Stig Bakken + * @author Chuck Hagenbuch + * @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 { *

* * @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); } } diff --git a/index.php b/index.php index ecbfb3eb7b..eef894effc 100644 --- a/index.php +++ b/index.php @@ -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... diff --git a/lib/default.php b/lib/default.php index f8ce3bd4fe..c78803da97 100644 --- a/lib/default.php +++ b/lib/default.php @@ -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 diff --git a/lib/feed.php b/lib/feed.php index e04c69be6c..d61c3e8a34 100644 --- a/lib/feed.php +++ b/lib/feed.php @@ -62,6 +62,11 @@ class Feed $this->title = $title; } + function getUrl() + { + return $this->url; + } + function mimeType() { switch ($this->type) { diff --git a/lib/mediafile.php b/lib/mediafile.php index 9fe5432ad5..1e0fb39769 100644 --- a/lib/mediafile.php +++ b/lib/mediafile.php @@ -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); diff --git a/lib/nickname.php b/lib/nickname.php index 2dd08efc3f..5a5b515b4d 100644 --- a/lib/nickname.php +++ b/lib/nickname.php @@ -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. diff --git a/lib/noticestreamaction.php b/lib/noticestreamaction.php index fb592915a7..e668a27daf 100644 --- a/lib/noticestreamaction.php +++ b/lib/noticestreamaction.php @@ -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(); } diff --git a/lib/util.php b/lib/util.php index c87b0f1bf6..9f9b3f66d4 100644 --- a/lib/util.php +++ b/lib/util.php @@ -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); diff --git a/plugins/AccountManager/AccountManagerPlugin.php b/plugins/AccountManager/AccountManagerPlugin.php index 768f71510f..429e9d4e5e 100644 --- a/plugins/AccountManager/AccountManagerPlugin.php +++ b/plugins/AccountManager/AccountManagerPlugin.php @@ -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.')); diff --git a/plugins/Activity/ActivityPlugin.php b/plugins/Activity/ActivityPlugin.php index 6805b4fe07..0f306a427c 100644 --- a/plugins/Activity/ActivityPlugin.php +++ b/plugins/Activity/ActivityPlugin.php @@ -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.')); diff --git a/plugins/ActivitySpam/ActivitySpamPlugin.php b/plugins/ActivitySpam/ActivitySpamPlugin.php index 9d61b2dddd..d63d64c718 100644 --- a/plugins/ActivitySpam/ActivitySpamPlugin.php +++ b/plugins/ActivitySpam/ActivitySpamPlugin.php @@ -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; diff --git a/plugins/ActivitySpam/README b/plugins/ActivitySpam/README new file mode 100755 index 0000000000..6202c64a9e --- /dev/null +++ b/plugins/ActivitySpam/README @@ -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'); diff --git a/plugins/AnonymousFave/AnonymousFavePlugin.php b/plugins/AnonymousFave/AnonymousFavePlugin.php index 841b652401..ca4bdc832f 100644 --- a/plugins/AnonymousFave/AnonymousFavePlugin.php +++ b/plugins/AnonymousFave/AnonymousFavePlugin.php @@ -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, diff --git a/plugins/AnonymousFave/README b/plugins/AnonymousFave/README new file mode 100755 index 0000000000..fbe3386775 --- /dev/null +++ b/plugins/AnonymousFave/README @@ -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'); diff --git a/plugins/AntiBrute/README b/plugins/AntiBrute/README new file mode 100755 index 0000000000..ef1a486171 --- /dev/null +++ b/plugins/AntiBrute/README @@ -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 + diff --git a/plugins/ApiLogger/ApiLoggerPlugin.php b/plugins/ApiLogger/ApiLoggerPlugin.php index 920009de5a..3877c464f0 100644 --- a/plugins/ApiLogger/ApiLoggerPlugin.php +++ b/plugins/ApiLogger/ApiLoggerPlugin.php @@ -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.')); diff --git a/plugins/ApiLogger/README b/plugins/ApiLogger/README new file mode 100755 index 0000000000..9257ac04fd --- /dev/null +++ b/plugins/ApiLogger/README @@ -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 +)); + diff --git a/plugins/AuthCrypt/AuthCryptPlugin.php b/plugins/AuthCrypt/AuthCryptPlugin.php index 540019f9c2..62019aa015 100644 --- a/plugins/AuthCrypt/AuthCryptPlugin.php +++ b/plugins/AuthCrypt/AuthCryptPlugin.php @@ -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()')); diff --git a/plugins/AutoSandbox/AutoSandboxPlugin.php b/plugins/AutoSandbox/AutoSandboxPlugin.php index e914977cc9..706523564a 100644 --- a/plugins/AutoSandbox/AutoSandboxPlugin.php +++ b/plugins/AutoSandbox/AutoSandboxPlugin.php @@ -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.')); diff --git a/plugins/Autocomplete/AutocompletePlugin.php b/plugins/Autocomplete/AutocompletePlugin.php index 0f0c2592c2..55bdb8894a 100644 --- a/plugins/Autocomplete/AutocompletePlugin.php +++ b/plugins/Autocomplete/AutocompletePlugin.php @@ -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.')); diff --git a/plugins/Awesomeness/AwesomenessPlugin.php b/plugins/Awesomeness/AwesomenessPlugin.php index ca3b281df6..fff833d4ee 100644 --- a/plugins/Awesomeness/AwesomenessPlugin.php +++ b/plugins/Awesomeness/AwesomenessPlugin.php @@ -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.' diff --git a/plugins/Awesomeness/README b/plugins/Awesomeness/README new file mode 100755 index 0000000000..51fa7cf0c7 --- /dev/null +++ b/plugins/Awesomeness/README @@ -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'); diff --git a/plugins/BitlyUrl/BitlyUrlPlugin.php b/plugins/BitlyUrl/BitlyUrlPlugin.php index 13a1bf2ec4..079a06a3e7 100644 --- a/plugins/BitlyUrl/BitlyUrlPlugin.php +++ b/plugins/BitlyUrl/BitlyUrlPlugin.php @@ -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 %1$s URL-shortener service.'), diff --git a/plugins/Blacklist/BlacklistPlugin.php b/plugins/Blacklist/BlacklistPlugin.php index bad89f2457..31929fcadc 100644 --- a/plugins/Blacklist/BlacklistPlugin.php +++ b/plugins/Blacklist/BlacklistPlugin.php @@ -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 '. diff --git a/plugins/Blacklist/README b/plugins/Blacklist/README new file mode 100755 index 0000000000..e36dec424e --- /dev/null +++ b/plugins/Blacklist/README @@ -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'); diff --git a/plugins/BlankAd/BlankAdPlugin.php b/plugins/BlankAd/BlankAdPlugin.php index b5cd968c7f..fbcf70bb03 100644 --- a/plugins/BlankAd/BlankAdPlugin.php +++ b/plugins/BlankAd/BlankAdPlugin.php @@ -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.')); diff --git a/plugins/BlankAd/README b/plugins/BlankAd/README new file mode 100755 index 0000000000..68be82b0c8 --- /dev/null +++ b/plugins/BlankAd/README @@ -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)); diff --git a/plugins/BlogspamNet/BlogspamNetPlugin.php b/plugins/BlogspamNet/BlogspamNetPlugin.php index 2cab69be30..30e9cffe16 100644 --- a/plugins/BlogspamNet/BlogspamNetPlugin.php +++ b/plugins/BlogspamNet/BlogspamNetPlugin.php @@ -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.')); diff --git a/plugins/BlogspamNet/README b/plugins/BlogspamNet/README new file mode 100755 index 0000000000..d4884bb9fe --- /dev/null +++ b/plugins/BlogspamNet/README @@ -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'); + diff --git a/plugins/CacheLog/CacheLogPlugin.php b/plugins/CacheLog/CacheLogPlugin.php index 5c1b57e0e6..cf7e3a9884 100644 --- a/plugins/CacheLog/CacheLogPlugin.php +++ b/plugins/CacheLog/CacheLogPlugin.php @@ -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.')); diff --git a/plugins/CacheLog/README b/plugins/CacheLog/README new file mode 100755 index 0000000000..fea7767733 --- /dev/null +++ b/plugins/CacheLog/README @@ -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'); diff --git a/plugins/CasAuthentication/CasAuthenticationPlugin.php b/plugins/CasAuthentication/CasAuthenticationPlugin.php index 461655264e..cf0bf4ac52 100644 --- a/plugins/CasAuthentication/CasAuthenticationPlugin.php +++ b/plugins/CasAuthentication/CasAuthenticationPlugin.php @@ -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; diff --git a/plugins/ClientSideShorten/ClientSideShortenPlugin.php b/plugins/ClientSideShorten/ClientSideShortenPlugin.php index 4d87ab2240..0e4e7969aa 100644 --- a/plugins/ClientSideShorten/ClientSideShortenPlugin.php +++ b/plugins/ClientSideShorten/ClientSideShortenPlugin.php @@ -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.')); diff --git a/plugins/ClientSideShorten/README b/plugins/ClientSideShorten/README index 70300a85b4..c9d6d6cb27 100644 --- a/plugins/ClientSideShorten/README +++ b/plugins/ClientSideShorten/README @@ -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 + diff --git a/plugins/Comet/CometPlugin.php b/plugins/Comet/CometPlugin.php index 5b38b2ae11..83c4e70990 100644 --- a/plugins/Comet/CometPlugin.php +++ b/plugins/Comet/CometPlugin.php @@ -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. diff --git a/plugins/ConversationTree/README b/plugins/ConversationTree/README new file mode 100755 index 0000000000..5eea62afab --- /dev/null +++ b/plugins/ConversationTree/README @@ -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'); diff --git a/plugins/Cronish/README b/plugins/Cronish/README new file mode 100755 index 0000000000..9729699327 --- /dev/null +++ b/plugins/Cronish/README @@ -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 diff --git a/plugins/Diaspora/README b/plugins/Diaspora/README new file mode 100755 index 0000000000..a3b45328ec --- /dev/null +++ b/plugins/Diaspora/README @@ -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'); diff --git a/plugins/DirectMessage/README b/plugins/DirectMessage/README new file mode 100755 index 0000000000..b908a2472f --- /dev/null +++ b/plugins/DirectMessage/README @@ -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 + diff --git a/plugins/DirectionDetector/DirectionDetectorPlugin.php b/plugins/DirectionDetector/DirectionDetectorPlugin.php index b721ebb20e..1f77a61acc 100644 --- a/plugins/DirectionDetector/DirectionDetectorPlugin.php +++ b/plugins/DirectionDetector/DirectionDetectorPlugin.php @@ -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', diff --git a/plugins/DirectionDetector/README b/plugins/DirectionDetector/README new file mode 100755 index 0000000000..efb0d1acc9 --- /dev/null +++ b/plugins/DirectionDetector/README @@ -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'); diff --git a/plugins/Directory/DirectoryPlugin.php b/plugins/Directory/DirectoryPlugin.php index e06c1c7271..e8ef98969f 100644 --- a/plugins/Directory/DirectoryPlugin.php +++ b/plugins/Directory/DirectoryPlugin.php @@ -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.') ); diff --git a/plugins/Directory/README b/plugins/Directory/README new file mode 100755 index 0000000000..d87185c8fe --- /dev/null +++ b/plugins/Directory/README @@ -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'); diff --git a/plugins/DiskCache/DiskCachePlugin.php b/plugins/DiskCache/DiskCachePlugin.php index 967990c12f..a574bf5158 100644 --- a/plugins/DiskCache/DiskCachePlugin.php +++ b/plugins/DiskCache/DiskCachePlugin.php @@ -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.')); diff --git a/plugins/DiskCache/README b/plugins/DiskCache/README new file mode 100755 index 0000000000..488b2c2b06 --- /dev/null +++ b/plugins/DiskCache/README @@ -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' +)); + diff --git a/plugins/DomainStatusNetwork/DomainStatusNetworkPlugin.php b/plugins/DomainStatusNetwork/DomainStatusNetworkPlugin.php index 062151db17..24ca6c90b0 100644 --- a/plugins/DomainStatusNetwork/DomainStatusNetworkPlugin.php +++ b/plugins/DomainStatusNetwork/DomainStatusNetworkPlugin.php @@ -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.')); diff --git a/plugins/DomainStatusNetwork/README b/plugins/DomainStatusNetwork/README new file mode 100755 index 0000000000..00fdc7a3c5 --- /dev/null +++ b/plugins/DomainStatusNetwork/README @@ -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'); + diff --git a/plugins/DomainWhitelist/DomainWhitelistPlugin.php b/plugins/DomainWhitelist/DomainWhitelistPlugin.php index 2e15dd809a..e965cfaa04 100644 --- a/plugins/DomainWhitelist/DomainWhitelistPlugin.php +++ b/plugins/DomainWhitelist/DomainWhitelistPlugin.php @@ -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.')); diff --git a/plugins/DomainWhitelist/README b/plugins/DomainWhitelist/README new file mode 100755 index 0000000000..6e5afd6785 --- /dev/null +++ b/plugins/DomainWhitelist/README @@ -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'); diff --git a/plugins/EmailAuthentication/EmailAuthenticationPlugin.php b/plugins/EmailAuthentication/EmailAuthenticationPlugin.php index 524f1a6411..fda99a12f8 100644 --- a/plugins/EmailAuthentication/EmailAuthenticationPlugin.php +++ b/plugins/EmailAuthentication/EmailAuthenticationPlugin.php @@ -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.')); diff --git a/plugins/EmailAuthentication/README b/plugins/EmailAuthentication/README index 3fc40794be..780bf4648e 100644 --- a/plugins/EmailAuthentication/README +++ b/plugins/EmailAuthentication/README @@ -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 + diff --git a/plugins/EmailRegistration/EmailRegistrationPlugin.php b/plugins/EmailRegistration/EmailRegistrationPlugin.php index 9e0fd58856..56e022435e 100644 --- a/plugins/EmailRegistration/EmailRegistrationPlugin.php +++ b/plugins/EmailRegistration/EmailRegistrationPlugin.php @@ -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.')); diff --git a/plugins/EmailRegistration/README b/plugins/EmailRegistration/README new file mode 100755 index 0000000000..5140208240 --- /dev/null +++ b/plugins/EmailRegistration/README @@ -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'); diff --git a/plugins/EmailReminder/EmailReminderPlugin.php b/plugins/EmailReminder/EmailReminderPlugin.php index 9ac6275537..f30e8d9273 100644 --- a/plugins/EmailReminder/EmailReminderPlugin.php +++ b/plugins/EmailReminder/EmailReminderPlugin.php @@ -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.') ); diff --git a/plugins/EmailReminder/README b/plugins/EmailReminder/README new file mode 100755 index 0000000000..3be8e77bff --- /dev/null +++ b/plugins/EmailReminder/README @@ -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'); + diff --git a/plugins/EmailSummary/EmailSummaryPlugin.php b/plugins/EmailSummary/EmailSummaryPlugin.php index bc47fdece9..75985da32e 100644 --- a/plugins/EmailSummary/EmailSummaryPlugin.php +++ b/plugins/EmailSummary/EmailSummaryPlugin.php @@ -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.')); diff --git a/plugins/EmailSummary/README b/plugins/EmailSummary/README new file mode 100755 index 0000000000..1c648e8d43 --- /dev/null +++ b/plugins/EmailSummary/README @@ -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'); diff --git a/plugins/Event/EventPlugin.php b/plugins/Event/EventPlugin.php index 82ba2c19cb..ed6a01e9b4 100644 --- a/plugins/Event/EventPlugin.php +++ b/plugins/Event/EventPlugin.php @@ -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.')); diff --git a/plugins/Event/README b/plugins/Event/README new file mode 100644 index 0000000000..9b30dd1f5b --- /dev/null +++ b/plugins/Event/README @@ -0,0 +1,10 @@ +The Event plugin adds event invitations and RSVPs types of notices. + +Installation +============ +This plugin is enabled by default + +Settings +======== +none + diff --git a/plugins/ExtendedProfile/ExtendedProfilePlugin.php b/plugins/ExtendedProfile/ExtendedProfilePlugin.php index ea928b995e..a1717c897e 100644 --- a/plugins/ExtendedProfile/ExtendedProfilePlugin.php +++ b/plugins/ExtendedProfile/ExtendedProfilePlugin.php @@ -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.') ); diff --git a/plugins/ExtendedProfile/README b/plugins/ExtendedProfile/README new file mode 100644 index 0000000000..f1d32dd3d6 --- /dev/null +++ b/plugins/ExtendedProfile/README @@ -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'); + diff --git a/plugins/FacebookBridge/FacebookBridgePlugin.php b/plugins/FacebookBridge/FacebookBridgePlugin.php index 88dc4df496..bfb95882bd 100644 --- a/plugins/FacebookBridge/FacebookBridgePlugin.php +++ b/plugins/FacebookBridge/FacebookBridgePlugin.php @@ -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.') diff --git a/plugins/Favorite/README b/plugins/Favorite/README new file mode 100644 index 0000000000..7032d92e70 --- /dev/null +++ b/plugins/Favorite/README @@ -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 + diff --git a/plugins/FeedPoller/README b/plugins/FeedPoller/README new file mode 100644 index 0000000000..11f28f2ba4 --- /dev/null +++ b/plugins/FeedPoller/README @@ -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'); + diff --git a/plugins/FollowEveryone/FollowEveryonePlugin.php b/plugins/FollowEveryone/FollowEveryonePlugin.php index 3c26963e3e..58aae85ed0 100644 --- a/plugins/FollowEveryone/FollowEveryonePlugin.php +++ b/plugins/FollowEveryone/FollowEveryonePlugin.php @@ -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.')); diff --git a/plugins/FollowEveryone/README b/plugins/FollowEveryone/README new file mode 100644 index 0000000000..4c97f787e0 --- /dev/null +++ b/plugins/FollowEveryone/README @@ -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'); + diff --git a/plugins/ForceGroup/ForceGroupPlugin.php b/plugins/ForceGroup/ForceGroupPlugin.php index 56e33355e8..e0ab59822e 100644 --- a/plugins/ForceGroup/ForceGroupPlugin.php +++ b/plugins/ForceGroup/ForceGroupPlugin.php @@ -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, diff --git a/plugins/ForceGroup/README b/plugins/ForceGroup/README new file mode 100644 index 0000000000..f906a7950a --- /dev/null +++ b/plugins/ForceGroup/README @@ -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'); + diff --git a/plugins/GNUsocialPhoto/README b/plugins/GNUsocialPhoto/README new file mode 100644 index 0000000000..e69de29bb2 diff --git a/plugins/GNUsocialPhotos/README b/plugins/GNUsocialPhotos/README new file mode 100644 index 0000000000..e69de29bb2 diff --git a/plugins/GNUsocialVideo/README b/plugins/GNUsocialVideo/README new file mode 100644 index 0000000000..e69de29bb2 diff --git a/plugins/GeoURL/GeoURLPlugin.php b/plugins/GeoURL/GeoURLPlugin.php index a64ac7f4fd..be47bd5d27 100644 --- a/plugins/GeoURL/GeoURLPlugin.php +++ b/plugins/GeoURL/GeoURLPlugin.php @@ -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 GeoURL when '. diff --git a/plugins/GeoURL/README b/plugins/GeoURL/README new file mode 100644 index 0000000000..838152d19c --- /dev/null +++ b/plugins/GeoURL/README @@ -0,0 +1,19 @@ +The GeoURL plugin add extra 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'); + diff --git a/plugins/Geonames/GeonamesPlugin.php b/plugins/Geonames/GeonamesPlugin.php index ff9192283f..14a95a2114 100644 --- a/plugins/Geonames/GeonamesPlugin.php +++ b/plugins/Geonames/GeonamesPlugin.php @@ -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 Geonames service to get human-readable '. diff --git a/plugins/Geonames/README b/plugins/Geonames/README new file mode 100644 index 0000000000..ff548503c9 --- /dev/null +++ b/plugins/Geonames/README @@ -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'); + diff --git a/plugins/GroupFavorited/GroupFavoritedPlugin.php b/plugins/GroupFavorited/GroupFavoritedPlugin.php index bfb7374d1d..3c6fbd3af4 100644 --- a/plugins/GroupFavorited/GroupFavoritedPlugin.php +++ b/plugins/GroupFavorited/GroupFavoritedPlugin.php @@ -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, diff --git a/plugins/GroupFavorited/README b/plugins/GroupFavorited/README new file mode 100644 index 0000000000..2652e1c795 --- /dev/null +++ b/plugins/GroupFavorited/README @@ -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'); + diff --git a/plugins/GroupPrivateMessage/GroupPrivateMessagePlugin.php b/plugins/GroupPrivateMessage/GroupPrivateMessagePlugin.php index 61828239ca..bee504491f 100644 --- a/plugins/GroupPrivateMessage/GroupPrivateMessagePlugin.php +++ b/plugins/GroupPrivateMessage/GroupPrivateMessagePlugin.php @@ -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.')); diff --git a/plugins/GroupPrivateMessage/README b/plugins/GroupPrivateMessage/README new file mode 100644 index 0000000000..04801c97f6 --- /dev/null +++ b/plugins/GroupPrivateMessage/README @@ -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'); + diff --git a/plugins/ImageMagick/README b/plugins/ImageMagick/README new file mode 100644 index 0000000000..8994ec3583 --- /dev/null +++ b/plugins/ImageMagick/README @@ -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'); + diff --git a/plugins/Imap/ImapPlugin.php b/plugins/Imap/ImapPlugin.php index ea6eaabef8..15bd8159d7 100644 --- a/plugins/Imap/ImapPlugin.php +++ b/plugins/Imap/ImapPlugin.php @@ -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.')); diff --git a/plugins/InProcessCache/InProcessCachePlugin.php b/plugins/InProcessCache/InProcessCachePlugin.php index 4684d0169f..4bcfb8e2da 100644 --- a/plugins/InProcessCache/InProcessCachePlugin.php +++ b/plugins/InProcessCache/InProcessCachePlugin.php @@ -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, diff --git a/plugins/InProcessCache/README b/plugins/InProcessCache/README new file mode 100644 index 0000000000..4efa43a4db --- /dev/null +++ b/plugins/InProcessCache/README @@ -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'); + diff --git a/plugins/InfiniteScroll/InfiniteScrollPlugin.php b/plugins/InfiniteScroll/InfiniteScrollPlugin.php index 986ba36075..c9107ad824 100644 --- a/plugins/InfiniteScroll/InfiniteScrollPlugin.php +++ b/plugins/InfiniteScroll/InfiniteScrollPlugin.php @@ -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.')); diff --git a/plugins/LRDD/README b/plugins/LRDD/README new file mode 100644 index 0000000000..843ea0c35c --- /dev/null +++ b/plugins/LRDD/README @@ -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 + diff --git a/plugins/LdapAuthentication/LdapAuthenticationPlugin.php b/plugins/LdapAuthentication/LdapAuthenticationPlugin.php index 0efaec99b2..2a09ad7c81 100644 --- a/plugins/LdapAuthentication/LdapAuthenticationPlugin.php +++ b/plugins/LdapAuthentication/LdapAuthenticationPlugin.php @@ -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.')); diff --git a/plugins/LdapAuthorization/LdapAuthorizationPlugin.php b/plugins/LdapAuthorization/LdapAuthorizationPlugin.php index eca8e037a0..fb86ba57b8 100644 --- a/plugins/LdapAuthorization/LdapAuthorizationPlugin.php +++ b/plugins/LdapAuthorization/LdapAuthorizationPlugin.php @@ -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.')); diff --git a/plugins/LilUrl/LilUrlPlugin.php b/plugins/LilUrl/LilUrlPlugin.php index fcbee2b56d..1e4d135cc3 100644 --- a/plugins/LilUrl/LilUrlPlugin.php +++ b/plugins/LilUrl/LilUrlPlugin.php @@ -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. diff --git a/plugins/LilUrl/README b/plugins/LilUrl/README new file mode 100644 index 0000000000..f52bdc77a2 --- /dev/null +++ b/plugins/LilUrl/README @@ -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')); + diff --git a/plugins/LinkPreview/LinkPreviewPlugin.php b/plugins/LinkPreview/LinkPreviewPlugin.php index 5edf66767d..25e31f3f79 100644 --- a/plugins/LinkPreview/LinkPreviewPlugin.php +++ b/plugins/LinkPreview/LinkPreviewPlugin.php @@ -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.')); diff --git a/plugins/LinkPreview/README b/plugins/LinkPreview/README index a1b1a87303..e15c67a1a3 100644 --- a/plugins/LinkPreview/README +++ b/plugins/LinkPreview/README @@ -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'); + diff --git a/plugins/Linkback/LinkbackPlugin.php b/plugins/Linkback/LinkbackPlugin.php index 64165199eb..06c49b0809 100644 --- a/plugins/Linkback/LinkbackPlugin.php +++ b/plugins/Linkback/LinkbackPlugin.php @@ -337,7 +337,7 @@ class LinkbackPlugin extends Plugin $versions[] = array('name' => 'Linkback', 'version' => LINKBACKPLUGIN_VERSION, 'author' => 'Evan Prodromou', - 'homepage' => 'http://status.net/wiki/Plugin:Linkback', + 'homepage' => 'https://git.gnu.io/gnu/gnu-social/tree/master/plugins/Linkback', 'rawdescription' => // TRANS: Plugin description. _m('Notify blog authors when their posts have been linked in '. diff --git a/plugins/Linkback/README b/plugins/Linkback/README new file mode 100644 index 0000000000..29b493d54f --- /dev/null +++ b/plugins/Linkback/README @@ -0,0 +1,19 @@ +The Linkback plugin performs linkbacks (pingbacks, trackbacks, webmentions) for +notices containing links. + +See: +* https://en.wikipedia.org/wiki/Linkback + +Installation +============ +add "addPlugin('Linkback');" +to the bottom of your config.php + +Settings +======== +none + +Example +======= +addPlugin('Linkback'); + diff --git a/plugins/LogFilter/LogFilterPlugin.php b/plugins/LogFilter/LogFilterPlugin.php index 028af9bc9c..f0794af4a3 100644 --- a/plugins/LogFilter/LogFilterPlugin.php +++ b/plugins/LogFilter/LogFilterPlugin.php @@ -44,7 +44,7 @@ class LogFilterPlugin extends Plugin $versions[] = array('name' => 'LogFilter', 'version' => GNUSOCIAL_VERSION, 'author' => 'Brion Vibber', - 'homepage' => 'http://status.net/wiki/Plugin:LogFilter', + 'homepage' => 'https://git.gnu.io/gnu/gnu-social/tree/master/plugins/LogFilter', 'rawdescription' => // TRANS: Plugin description. _m('Provides server-side setting to filter log output by type or keyword.')); diff --git a/plugins/LogFilter/README b/plugins/LogFilter/README new file mode 100644 index 0000000000..fbd54e1663 --- /dev/null +++ b/plugins/LogFilter/README @@ -0,0 +1,20 @@ +The LogFilter plugin provides server-side setting to filter log output by type or keyword. + +Installation +============ +add "addPlugin('LogFilter');" +to the bottom of your config.php + +Settings +======== +none + +Example +======= +Disable all debug messages and those containing 'About to push': + +addPlugin('LogFilter', array( + 'priority' => array(LOG_DEBUG => false), + 'regex' => array('/About to push/' => false) +)); + diff --git a/plugins/Mapstraction/MapstractionPlugin.php b/plugins/Mapstraction/MapstractionPlugin.php index fcc9d88e56..bc43b9dff7 100644 --- a/plugins/Mapstraction/MapstractionPlugin.php +++ b/plugins/Mapstraction/MapstractionPlugin.php @@ -174,7 +174,7 @@ class MapstractionPlugin extends Plugin $versions[] = array('name' => 'Mapstraction', 'version' => self::VERSION, 'author' => 'Evan Prodromou', - 'homepage' => 'http://status.net/wiki/Plugin:Mapstraction', + 'homepage' => 'https://git.gnu.io/gnu/gnu-social/tree/master/plugins/Mapstraction', 'rawdescription' => // TRANS: Plugin description. _m('Show maps of users\' and friends\' notices '. diff --git a/plugins/Mapstraction/README b/plugins/Mapstraction/README new file mode 100644 index 0000000000..6a062cc7e9 --- /dev/null +++ b/plugins/Mapstraction/README @@ -0,0 +1,21 @@ +The Mapstraction plugin provides map visualization of location data. + +Show maps of users' and friends' notices with http://www.mapstraction.com/. + +Installation +============ +add "addPlugin('Mapstraction');" +to the bottom of your config.php + +Settings +======== +provider: Name of the service providing maps ('cloudmade', 'google', 'microsoft', 'openlayers', 'yahoo') +apikey: provider API key (or 'appid'), if required + +Example +======= +addPlugin('Mapstraction', array( + 'provider' => 'openlayers', + 'apikey' => 'API_KEY' +)); + diff --git a/plugins/Memcache/MemcachePlugin.php b/plugins/Memcache/MemcachePlugin.php index 7efb5e0284..dc0f943675 100644 --- a/plugins/Memcache/MemcachePlugin.php +++ b/plugins/Memcache/MemcachePlugin.php @@ -241,7 +241,7 @@ class MemcachePlugin extends Plugin $versions[] = array('name' => 'Memcache', 'version' => GNUSOCIAL_VERSION, 'author' => 'Evan Prodromou, Craig Andrews', - 'homepage' => 'http://status.net/wiki/Plugin:Memcache', + 'homepage' => 'https://git.gnu.io/gnu/gnu-social/tree/master/plugins/Memcache', 'rawdescription' => // TRANS: Plugin description. _m('Use Memcached to cache query results.')); diff --git a/plugins/Memcache/README b/plugins/Memcache/README new file mode 100644 index 0000000000..1344be8294 --- /dev/null +++ b/plugins/Memcache/README @@ -0,0 +1,28 @@ +The Memcache plugin implements cache interface for memcache. + +See: http://memcached.org/ + +Installation +============ +add "addPlugin('Memcache');" +to the bottom of your config.php + +Settings +======== +servers: Array of memcache servers addresses +defaultExpiry: How long before cache expires (in seconds) +compressThreshold: Items over this size threshold are eligible for compression (in bytes) +compressMinSaving: If the compression would save more than this ratio, items are eligible for compression + +Note: To be compressed, an item must be both over the size threshold AND save +more than the minimum ratio. + +Example +======= +addPlugin('Memcache', array( + 'servers' => array('127.0.0.1;11211'), + 'compressThreshold' => 20480, + 'compressMinSaving' => 0.2, + 'defaultExpiry' => 86400 // 24h +)); + diff --git a/plugins/Memcached/MemcachedPlugin.php b/plugins/Memcached/MemcachedPlugin.php index ca24b7b7d1..33b7772db4 100644 --- a/plugins/Memcached/MemcachedPlugin.php +++ b/plugins/Memcached/MemcachedPlugin.php @@ -212,7 +212,7 @@ class MemcachedPlugin extends Plugin $versions[] = array('name' => 'Memcached', 'version' => GNUSOCIAL_VERSION, 'author' => 'Evan Prodromou, Craig Andrews', - 'homepage' => 'http://status.net/wiki/Plugin:Memcached', + 'homepage' => 'https://git.gnu.io/gnu/gnu-social/tree/master/plugins/Memcached', 'rawdescription' => // TRANS: Plugin description. _m('Use Memcached to cache query results.')); diff --git a/plugins/Memcached/README b/plugins/Memcached/README new file mode 100644 index 0000000000..05ae884b02 --- /dev/null +++ b/plugins/Memcached/README @@ -0,0 +1,21 @@ +The Memcached plugin implements cache interface for memcached. + +See: http://memcached.org/ + +Installation +============ +add "addPlugin('Memcached');" +to the bottom of your config.php + +Settings +======== +servers: Array of memcached servers addresses +defaultExpiry: How long before cache expires (in seconds) + +Example +======= +addPlugin('Memcached', array( + 'servers' => array('127.0.0.1;11211'), + 'defaultExpiry' => 86400 // 24h +)); + diff --git a/plugins/MentionURL/README b/plugins/MentionURL/README new file mode 100644 index 0000000000..1c7475da36 --- /dev/null +++ b/plugins/MentionURL/README @@ -0,0 +1,15 @@ +The MentionURL plugin allows mentioning arbitrary URLs. + +Installation +============ +add "addPlugin('MentionURL');" +to the bottom of your config.php + +Settings +======== +none + +Example +======= +addPlugin('MentionURL'); + diff --git a/plugins/Meteor/MeteorPlugin.php b/plugins/Meteor/MeteorPlugin.php index 64c2fd3d69..9ce25386c1 100644 --- a/plugins/Meteor/MeteorPlugin.php +++ b/plugins/Meteor/MeteorPlugin.php @@ -165,7 +165,7 @@ class MeteorPlugin extends RealtimePlugin $versions[] = array('name' => 'Meteor', 'version' => GNUSOCIAL_VERSION, 'author' => 'Evan Prodromou', - 'homepage' => 'http://status.net/wiki/Plugin:Meteor', + 'homepage' => 'https://git.gnu.io/gnu/gnu-social/tree/master/plugins/Meteor', 'rawdescription' => // TRANS: Plugin description. _m('Plugin to do "real time" updates using Meteor.')); diff --git a/plugins/Minify/MinifyPlugin.php b/plugins/Minify/MinifyPlugin.php index 1dd3bdcf34..b970cd20c6 100644 --- a/plugins/Minify/MinifyPlugin.php +++ b/plugins/Minify/MinifyPlugin.php @@ -162,7 +162,7 @@ class MinifyPlugin extends Plugin $versions[] = array('name' => 'Minify', 'version' => GNUSOCIAL_VERSION, 'author' => 'Craig Andrews', - 'homepage' => 'http://status.net/wiki/Plugin:Minify', + 'homepage' => 'https://git.gnu.io/gnu/gnu-social/tree/master/plugins/Minify', 'rawdescription' => // TRANS: Plugin description. _m('The Minify plugin minifies StatusNet\'s CSS and JavaScript, removing whitespace and comments.')); diff --git a/plugins/Mobile/README b/plugins/Mobile/README new file mode 100644 index 0000000000..04e5b43409 --- /dev/null +++ b/plugins/Mobile/README @@ -0,0 +1,10 @@ +Superclass for WAP 2.0 support + +Installation +============ +N/A + +Settings +======== +none + diff --git a/plugins/MobileProfile/MobileProfilePlugin.php b/plugins/MobileProfile/MobileProfilePlugin.php index 4129035ebb..0e0ba170e8 100644 --- a/plugins/MobileProfile/MobileProfilePlugin.php +++ b/plugins/MobileProfile/MobileProfilePlugin.php @@ -373,7 +373,7 @@ class MobileProfilePlugin extends WAP20Plugin $versions[] = array('name' => 'MobileProfile', 'version' => GNUSOCIAL_VERSION, 'author' => 'Sarven Capadisli', - 'homepage' => 'http://status.net/wiki/Plugin:MobileProfile', + 'homepage' => 'https://git.gnu.io/gnu/gnu-social/tree/master/plugins/MobileProfile', 'rawdescription' => // TRANS: Plugin description. _m('XHTML MobileProfile output for supporting user agents.')); diff --git a/plugins/MobileProfile/README b/plugins/MobileProfile/README new file mode 100644 index 0000000000..ca6dd6a176 --- /dev/null +++ b/plugins/MobileProfile/README @@ -0,0 +1,20 @@ +The MobileProfile plugin implements XHTML MobileProfile output for supporting +user agents. + +See: https://en.wikipedia.org/wiki/XHTML_Mobile_Profile + +Installation +============ +add "addPlugin('MobileProfile');" +to the bottom of your config.php + +Note: This plugin is enabled by default on private and single-user instances. + +Settings +======== +none + +Example +======= +addPlugin('MobileProfile'); + diff --git a/plugins/ModHelper/ModHelperPlugin.php b/plugins/ModHelper/ModHelperPlugin.php index 88f2f2a731..45b8bf27d1 100644 --- a/plugins/ModHelper/ModHelperPlugin.php +++ b/plugins/ModHelper/ModHelperPlugin.php @@ -32,7 +32,7 @@ class ModHelperPlugin extends Plugin $versions[] = array('name' => 'ModHelper', 'version' => GNUSOCIAL_VERSION, 'author' => 'Brion Vibber', - 'homepage' => 'http://status.net/wiki/Plugin:ModHelper', + 'homepage' => 'https://git.gnu.io/gnu/gnu-social/tree/master/plugins/ModHelper', 'rawdescription' => // TRANS: Plugin description. _m('Lets users who have been manually marked as "modhelper"s silence accounts.')); diff --git a/plugins/ModHelper/README b/plugins/ModHelper/README new file mode 100644 index 0000000000..c968f8a827 --- /dev/null +++ b/plugins/ModHelper/README @@ -0,0 +1,16 @@ +The ModHelperPlugin plugin lets users who have been manually marked as +"modhelper"s silence accounts. + +Installation +============ +add "addPlugin('ModHelperPlugin');" +to the bottom of your config.php + +Settings +======== +none + +Example +======= +addPlugin('ModHelperPlugin'); + diff --git a/plugins/ModLog/ModLogPlugin.php b/plugins/ModLog/ModLogPlugin.php index d1e01ca849..84912ac914 100644 --- a/plugins/ModLog/ModLogPlugin.php +++ b/plugins/ModLog/ModLogPlugin.php @@ -189,7 +189,7 @@ class ModLogPlugin extends Plugin $versions[] = array('name' => 'ModLog', 'version' => GNUSOCIAL_VERSION, 'author' => 'Evan Prodromou', - 'homepage' => 'http://status.net/wiki/Plugin:ModLog', + 'homepage' => 'https://git.gnu.io/gnu/gnu-social/tree/master/plugins/ModLog', 'description' => _m('Show the moderation history for a profile in the sidebar')); return true; diff --git a/plugins/ModLog/README b/plugins/ModLog/README new file mode 100644 index 0000000000..263d4970fb --- /dev/null +++ b/plugins/ModLog/README @@ -0,0 +1,15 @@ +The ModLog plugin shows the moderation history for a profile in the sidebar. + +Installation +============ +add "addPlugin('ModLog');" +to the bottom of your config.php + +Settings +======== +none + +Example +======= +addPlugin('ModLog'); + diff --git a/plugins/ModPlus/ModPlusPlugin.php b/plugins/ModPlus/ModPlusPlugin.php index 816034f831..9facd12ef2 100644 --- a/plugins/ModPlus/ModPlusPlugin.php +++ b/plugins/ModPlus/ModPlusPlugin.php @@ -32,7 +32,7 @@ class ModPlusPlugin extends Plugin $versions[] = array('name' => 'ModPlus', 'version' => GNUSOCIAL_VERSION, 'author' => 'Brion Vibber', - 'homepage' => 'http://status.net/wiki/Plugin:ModPlus', + 'homepage' => 'https://git.gnu.io/gnu/gnu-social/tree/master/plugins/ModPlus', 'rawdescription' => // TRANS: Plugin description. _m('UI extension for profile moderation actions.')); diff --git a/plugins/ModPlus/README b/plugins/ModPlus/README new file mode 100644 index 0000000000..313453bff6 --- /dev/null +++ b/plugins/ModPlus/README @@ -0,0 +1,15 @@ +The ModPlus plugin shows UI extension for profile moderation actions. + +Installation +============ +add "addPlugin('ModPlus');" +to the bottom of your config.php + +Settings +======== +none + +Example +======= +addPlugin('ModPlus'); + diff --git a/plugins/NoticeTitle/NoticeTitlePlugin.php b/plugins/NoticeTitle/NoticeTitlePlugin.php index 22528d0b50..7721c343dd 100644 --- a/plugins/NoticeTitle/NoticeTitlePlugin.php +++ b/plugins/NoticeTitle/NoticeTitlePlugin.php @@ -86,7 +86,7 @@ class NoticeTitlePlugin extends Plugin */ function onPluginVersion(array &$versions) { - $url = 'http://status.net/wiki/Plugin:NoticeTitle'; + $url = 'https://git.gnu.io/gnu/gnu-social/tree/master/plugins/NoticeTitle'; $versions[] = array('name' => 'NoticeTitle', 'version' => NOTICE_TITLE_PLUGIN_VERSION, diff --git a/plugins/NoticeTitle/README b/plugins/NoticeTitle/README new file mode 100644 index 0000000000..9f994db881 --- /dev/null +++ b/plugins/NoticeTitle/README @@ -0,0 +1,17 @@ +The NoticeTitle plugin allows users to add titles to notices. + +Installation +============ +add "addPlugin('NoticeTitle');" +to the bottom of your config.php + +Settings +======== +restricted: Whether this option is restriced to users with the "richedit" role. + +Example +======= +addPlugin('NoticeTitle', array( + 'restricted' => false +)); + diff --git a/plugins/OStatus/OStatusPlugin.php b/plugins/OStatus/OStatusPlugin.php index c108e78e6c..17ce8e4623 100644 --- a/plugins/OStatus/OStatusPlugin.php +++ b/plugins/OStatus/OStatusPlugin.php @@ -669,7 +669,7 @@ class OStatusPlugin extends Plugin $other->getBestName()); $act->actor = $profile->asActivityObject(); - $act->object = $other->asActivityObject(); + $act->objects[] = $other->asActivityObject(); $oprofile->notifyActivity($act, $profile); @@ -707,7 +707,7 @@ class OStatusPlugin extends Plugin $act->actor = $profile->asActivityObject(); $act->verb = ActivityVerb::JOIN; - $act->object = $oprofile->asActivityObject(); + $act->objects[] = $oprofile->asActivityObject(); $act->time = time(); // TRANS: Title for joining a remote groep. @@ -761,7 +761,7 @@ class OStatusPlugin extends Plugin $act->actor = $member->asActivityObject(); $act->verb = ActivityVerb::LEAVE; - $act->object = $oprofile->asActivityObject(); + $act->objects[] = $oprofile->asActivityObject(); $act->time = time(); // TRANS: Title for leaving a remote group. @@ -807,7 +807,7 @@ class OStatusPlugin extends Plugin $act->actor = $sub->asActivityObject(); $act->verb = ActivityVerb::FOLLOW; - $act->object = $oprofile->asActivityObject(); + $act->objects[] = $oprofile->asActivityObject(); $act->time = time(); // TRANS: Title for following a remote list. @@ -859,7 +859,7 @@ class OStatusPlugin extends Plugin $act->actor = $member->asActivityObject(); $act->verb = ActivityVerb::UNFOLLOW; - $act->object = $oprofile->asActivityObject(); + $act->objects[] = $oprofile->asActivityObject(); $act->time = time(); // TRANS: Title for unfollowing a remote list. @@ -1051,7 +1051,7 @@ class OStatusPlugin extends Plugin $notice->getUrl()); $act->actor = $profile->asActivityObject(); - $act->object = $notice->asActivityObject(); + $act->objects[] = $notice->asActivityObject(); $oprofile->notifyActivity($act, $profile); @@ -1173,7 +1173,7 @@ class OStatusPlugin extends Plugin $profile->getBestName()); $act->actor = $profile->asActivityObject(); - $act->object = $act->actor; + $act->objects[] = $act->actor; while ($oprofile->fetch()) { $oprofile->notifyDeferred($act, $profile); @@ -1229,7 +1229,7 @@ class OStatusPlugin extends Plugin $versions[] = array('name' => 'OStatus', 'version' => GNUSOCIAL_VERSION, 'author' => 'Evan Prodromou, James Walker, Brion Vibber, Zach Copley', - 'homepage' => 'http://status.net/wiki/Plugin:OStatus', + 'homepage' => 'https://git.gnu.io/gnu/gnu-social/tree/master/plugins/OStatus', // TRANS: Plugin description. 'rawdescription' => _m('Follow people across social networks that implement '. 'OStatus.')); diff --git a/plugins/OStatus/actions/usersalmon.php b/plugins/OStatus/actions/usersalmon.php index 5d2a92d99b..ea5262aa3b 100644 --- a/plugins/OStatus/actions/usersalmon.php +++ b/plugins/OStatus/actions/usersalmon.php @@ -29,22 +29,44 @@ class UsersalmonAction extends SalmonAction { parent::prepare($args); - $id = $this->trimmed('id'); - - if (!$id) { - // TRANS: Client error displayed trying to perform an action without providing an ID. - $this->clientError(_m('No ID.')); - } - - $this->user = User::getKV('id', $id); - - if (!$this->user instanceof User) { - // TRANS: Client error displayed when referring to a non-existing user. - $this->clientError(_m('No such user.')); - } + $this->user = User::getByID($this->trimmed('id')); $this->target = $this->user->getProfile(); + // Notice must either be a) in reply to a notice by this user + // or b) in reply to a notice to the attention of this user + // or c) to the attention of this user + // or d) reference the user as an activity:object + + $notice = null; + + if (!empty($this->activity->context->replyToID)) { + try { + $notice = Notice::getByUri($this->activity->context->replyToID); + } catch (NoResultException $e) { + $notice = false; + } + } + + if ($notice instanceof Notice && + ($this->target->sameAs($notice->getProfile()) + || in_array($this->target->getID(), $notice->getAttentionProfileIDs()) + )) { + // In reply to a notice either from or mentioning this user. + common_debug('User is the owner or was in the attention list of thr:in-reply-to activity.'); + } elseif (!empty($this->activity->context->attention) && + array_key_exists($this->target->getUri(), $this->activity->context->attention)) { + // To the attention of this user. + common_debug('User was in attention list of salmon slap.'); + } elseif (!empty($this->activity->objects) && $this->activity->objects[0]->id === $this->target->getUri()) { + // The user is the object of this slap (unfollow for example) + common_debug('User URI was the id of the salmon slap object.'); + } else { + common_debug('User was NOT found in salmon slap context.'); + // TRANS: Client exception. + throw new ClientException(_m('The owner of this salmon endpoint was not in the context of the carried slap.')); + } + return true; } @@ -71,30 +93,6 @@ class UsersalmonAction extends SalmonAction throw new ClientException(_m('Cannot handle that kind of post.')); } - // Notice must either be a) in reply to a notice by this user - // or b) in reply to a notice to the attention of this user - // or c) to the attention of this user - - $context = $this->activity->context; - $notice = false; - - if (!empty($context->replyToID)) { - $notice = Notice::getKV('uri', $context->replyToID); - } - - if ($notice instanceof Notice && - ($notice->profile_id == $this->target->id || - array_key_exists($this->target->id, $notice->getReplies()))) - { - // In reply to a notice either from or mentioning this user. - } elseif (!empty($context->attention) && - array_key_exists($this->target->getUri(), $context->attention)) { - // To the attention of this user. - } else { - // TRANS: Client exception. - throw new ClientException(_m('Not to anyone in reply to anything.')); - } - try { $this->saveNotice(); } catch (AlreadyFulfilledException $e) { diff --git a/plugins/OStatus/lib/salmonaction.php b/plugins/OStatus/lib/salmonaction.php index 41e4262498..d1293728d2 100644 --- a/plugins/OStatus/lib/salmonaction.php +++ b/plugins/OStatus/lib/salmonaction.php @@ -98,6 +98,7 @@ class SalmonAction extends Action assert($this->target instanceof Profile); common_log(LOG_DEBUG, "Got a " . $this->activity->verb); + try { $options = [ 'source' => 'ostatus' ]; common_debug('Save salmon slap directly with Notice::saveActivity for actor=='.$this->actor->getID()); diff --git a/plugins/Oembed/OembedPlugin.php b/plugins/Oembed/OembedPlugin.php index c90f57439b..196b07d75d 100644 --- a/plugins/Oembed/OembedPlugin.php +++ b/plugins/Oembed/OembedPlugin.php @@ -73,18 +73,20 @@ class OembedPlugin extends Plugin $metadata = OpenGraphHelper::ogFromHtml($dom); } - // sometimes sites serve the path, not the full URL, for images - // let's "be liberal in what you accept from others"! - // add protocol and host if the thumbnail_url starts with / - if(substr($metadata->thumbnail_url,0,1) == '/') { - $thumbnail_url_parsed = parse_url($metadata->url); - $metadata->thumbnail_url = $thumbnail_url_parsed['scheme']."://".$thumbnail_url_parsed['host'].$metadata->thumbnail_url; - } + if (isset($metadata->thumbnail_url)) { + // sometimes sites serve the path, not the full URL, for images + // let's "be liberal in what you accept from others"! + // add protocol and host if the thumbnail_url starts with / + if(substr($metadata->thumbnail_url,0,1) == '/') { + $thumbnail_url_parsed = parse_url($metadata->url); + $metadata->thumbnail_url = $thumbnail_url_parsed['scheme']."://".$thumbnail_url_parsed['host'].$metadata->thumbnail_url; + } - // some wordpress opengraph implementations sometimes return a white blank image - // no need for us to save that! - if($metadata->thumbnail_url == 'https://s0.wp.com/i/blank.jpg') { - unset($metadata->thumbnail_url); + // some wordpress opengraph implementations sometimes return a white blank image + // no need for us to save that! + if($metadata->thumbnail_url == 'https://s0.wp.com/i/blank.jpg') { + unset($metadata->thumbnail_url); + } } } @@ -323,8 +325,10 @@ class OembedPlugin extends Plugin throw new UnsupportedMediaException(_('Image file had impossible geometry (0 width or height)')); } + $ext = File::guessMimeExtension($info['mime']); + // We'll trust sha256 (File::FILEHASH_ALG) not to have collision issues any time soon :) - $filename = hash(File::FILEHASH_ALG, $imgData) . '.' . common_supported_mime_to_ext($info['mime']); + $filename = hash(File::FILEHASH_ALG, $imgData) . ".{$ext}"; $fullpath = File_thumbnail::path($filename); // Write the file to disk. Throw Exception on failure if (!file_exists($fullpath) && file_put_contents($fullpath, $imgData) === false) { diff --git a/plugins/Oembed/README b/plugins/Oembed/README index be8c09f7a6..b5e1aeae1f 100644 --- a/plugins/Oembed/README +++ b/plugins/Oembed/README @@ -1 +1,29 @@ -It's really called oEmbed. +The Oembed plugin for using and representing oEmbed data. + +See: http://www.oembed.com/ + +Installation +============ +This plugin is enabled by default + +Settings +======== +width: Maximum width of the thumbnail in pixels. +height: Maximum height of the thumbnail in pixels. +show_html: Whether to show HTML oEmbed data. +domain_whitelist: Array of regular expressions. Always escape your dots and end your strings. +check_whitelist: Whether to check the domain_whitelist. + +Example +======= +$config['thumbnail']['width'] = 42; +$config['thumbnail']['height'] = 42; +$config['attachments']['show_html'] = true; +addPlugin('Oembed', array( + 'domain_whitelist' => array( + '^i\d*\.ytimg\.com$' => 'YouTube', + '^i\d*\.vimeocdn\.com$' => 'Vimeo' + ), + 'check_whitelist' => true +)); + diff --git a/plugins/OfflineBackup/OfflineBackupPlugin.php b/plugins/OfflineBackup/OfflineBackupPlugin.php index 1d7a17ca2c..b1c69558ea 100644 --- a/plugins/OfflineBackup/OfflineBackupPlugin.php +++ b/plugins/OfflineBackup/OfflineBackupPlugin.php @@ -76,7 +76,7 @@ class OfflineBackupPlugin extends Plugin $versions[] = array('name' => 'OfflineBackup', 'version' => GNUSOCIAL_VERSION, 'author' => 'Evan Prodromou', - 'homepage' => 'http://status.net/wiki/Plugin:OfflineBackup', + 'homepage' => 'https://git.gnu.io/gnu/gnu-social/tree/master/plugins/OfflineBackup', 'rawdescription' => // TRANS: Plugin description. _m('Backup user data in offline queue and email when ready.')); diff --git a/plugins/OfflineBackup/README b/plugins/OfflineBackup/README new file mode 100644 index 0000000000..17537f3561 --- /dev/null +++ b/plugins/OfflineBackup/README @@ -0,0 +1,16 @@ +The OfflineBackup plugin backups user data in offline queue and email when +ready. + +Installation +============ +add "addPlugin('OfflineBackup');" +to the bottom of your config.php + +Settings +======== +none + +Example +======= +addPlugin('OfflineBackup'); + diff --git a/plugins/OpenExternalLinkTarget/OpenExternalLinkTargetPlugin.php b/plugins/OpenExternalLinkTarget/OpenExternalLinkTargetPlugin.php index 06c75f7a93..89c7cbabfd 100644 --- a/plugins/OpenExternalLinkTarget/OpenExternalLinkTargetPlugin.php +++ b/plugins/OpenExternalLinkTarget/OpenExternalLinkTargetPlugin.php @@ -54,7 +54,7 @@ class OpenExternalLinkTargetPlugin extends Plugin $versions[] = array('name' => 'OpenExternalLinkTarget', 'version' => GNUSOCIAL_VERSION, 'author' => 'Sarven Capadisli', - 'homepage' => 'http://status.net/wiki/Plugin:OpenExternalLinkTarget', + 'homepage' => 'https://git.gnu.io/gnu/gnu-social/tree/master/plugins/OpenExternalLinkTarget', 'rawdescription' => // TRANS: Plugin description. _m('Opens external links (i.e. with rel=external) on a new window or tab.')); diff --git a/plugins/OpenExternalLinkTarget/README b/plugins/OpenExternalLinkTarget/README new file mode 100644 index 0000000000..6d4db6437a --- /dev/null +++ b/plugins/OpenExternalLinkTarget/README @@ -0,0 +1,15 @@ +The OpenExternalLinkTarget plugin opens external links in a new window or tab. + +Installation +============ +add "addPlugin('OpenExternalLinkTarget');" +to the bottom of your config.php + +Settings +======== +none + +Example +======= +addPlugin('OpenExternalLinkTarget'); + diff --git a/plugins/OpenID/OpenIDPlugin.php b/plugins/OpenID/OpenIDPlugin.php index c6f2d75a2b..c6d247caf3 100644 --- a/plugins/OpenID/OpenIDPlugin.php +++ b/plugins/OpenID/OpenIDPlugin.php @@ -597,7 +597,7 @@ class OpenIDPlugin extends Plugin $versions[] = array('name' => 'OpenID', 'version' => GNUSOCIAL_VERSION, 'author' => 'Evan Prodromou, Craig Andrews', - 'homepage' => 'http://status.net/wiki/Plugin:OpenID', + 'homepage' => 'https://git.gnu.io/gnu/gnu-social/tree/master/plugins/OpenID', 'rawdescription' => // TRANS: Plugin description. _m('Use OpenID to login to the site.')); diff --git a/plugins/OpenID/README b/plugins/OpenID/README new file mode 100644 index 0000000000..17114a1dc6 --- /dev/null +++ b/plugins/OpenID/README @@ -0,0 +1,21 @@ +The OpenID plugin allows users to use OpenID to login. + +See: http://openid.net/ + +Installation +============ +This plugin is enabled by default + +Settings +======== +openidonly: Whether we only allow logins through OpenID. +trusted_provider: URL to the OpenID provider. +append_username: Whether to append the username at the end of the OpenID URL + +Example +======= +$config['site']['openidonly'] = true; +$config['openid']['trusted_provider'] = "http://example.org"; +$config['openid']['append_username'] = true; +addPlugin('OpenID'); + diff --git a/plugins/OpenID/actions/openidsettings.php b/plugins/OpenID/actions/openidsettings.php index bf5d8886f1..75835ff1f1 100644 --- a/plugins/OpenID/actions/openidsettings.php +++ b/plugins/OpenID/actions/openidsettings.php @@ -287,7 +287,7 @@ class OpenidsettingsAction extends SettingsAction // TRANS: Form validation error for a non-existing OpenID. throw new ClientException(_m('No such OpenID.')); } - if ($this->scoped->getID() !== $oid->user_id) { + if ($this->scoped->getID() !== $oid->getID()) { // TRANS: Form validation error if OpenID is connected to another user. throw new ClientException(_m('That OpenID does not belong to you.')); } diff --git a/plugins/OpenID/classes/User_openid.php b/plugins/OpenID/classes/User_openid.php index 7e53d8ec95..2221a9e78a 100644 --- a/plugins/OpenID/classes/User_openid.php +++ b/plugins/OpenID/classes/User_openid.php @@ -45,6 +45,16 @@ class User_openid extends Managed_DataObject ); } + public function getID() + { + if (!isset($this->user_id)) { + throw new Exception('No ID set.'); + } elseif (empty($this->user_id)) { + throw new Exception('Empty ID for object! (not inserted yet?).'); + } + return intval($this->user_id); + } + static function hasOpenID($user_id) { $oid = new User_openid(); diff --git a/plugins/OpenX/OpenXPlugin.php b/plugins/OpenX/OpenXPlugin.php index 8d80197be3..f0c78905aa 100644 --- a/plugins/OpenX/OpenXPlugin.php +++ b/plugins/OpenX/OpenXPlugin.php @@ -204,7 +204,7 @@ ENDOFSCRIPT; $versions[] = array('name' => 'OpenX', 'version' => GNUSOCIAL_VERSION, 'author' => 'Evan Prodromou', - 'homepage' => 'http://status.net/wiki/Plugin:OpenX', + 'homepage' => 'https://git.gnu.io/gnu/gnu-social/tree/master/plugins/OpenX', 'rawdescription' => // TRANS: Plugin description. _m('Plugin for OpenX Ad Server.')); diff --git a/plugins/OpenX/README b/plugins/OpenX/README new file mode 100644 index 0000000000..6b05e8e4a5 --- /dev/null +++ b/plugins/OpenX/README @@ -0,0 +1,26 @@ +The OpenX plugin enables support for OpenX Ad Server. + +See: http://www.openx.org/ + +Installation +============ +add "addPlugin('OpenX');" +to the bottom of your config.php + +Settings +======== +mediumRectangle: +rectangle: +leaderboard: +wideSkyscraper: +adScript: + +Example +======= +$config['openx']['mediumRectangle'] = ''; +$config['openx']['rectangle'] = ''; +$config['openx']['leaderboard'] = ''; +$config['openx']['wideSkyscraper'] = ''; +$config['openx']['adScript'] = ''; +addPlugin('OpenX'); + diff --git a/plugins/Orbited/OrbitedPlugin.php b/plugins/Orbited/OrbitedPlugin.php index 5abd27e9ee..e007eebe7e 100644 --- a/plugins/Orbited/OrbitedPlugin.php +++ b/plugins/Orbited/OrbitedPlugin.php @@ -164,7 +164,7 @@ class OrbitedPlugin extends RealtimePlugin $versions[] = array('name' => 'Orbited', 'version' => GNUSOCIAL_VERSION, 'author' => 'Evan Prodromou', - 'homepage' => 'http://status.net/wiki/Plugin:Orbited', + 'homepage' => 'https://git.gnu.io/gnu/gnu-social/tree/master/plugins/Orbited', 'rawdescription' => // TRANS: Plugin description. _m('Plugin to make updates using Orbited and STOMP.')); diff --git a/plugins/Orbited/README b/plugins/Orbited/README new file mode 100644 index 0000000000..20d0598e24 --- /dev/null +++ b/plugins/Orbited/README @@ -0,0 +1,37 @@ +The Orbited plugin enables "real time" updates using Orbited + STOMP + +See: +* https://pypi.python.org/pypi/orbited +* https://en.wikipedia.org/wiki/Streaming_Text_Oriented_Messaging_Protocol + +Installation +============ +add "addPlugin('Orbited');" +to the bottom of your config.php + +Settings +======== +webserver: +webport: +channelbase: +stompserver: +stompport: +username: +password: +webuser: +webpass: + +Example +======= +addPlugin('Orbited', array( + 'webserver' => '', + 'webport' => '', + 'channelbase' => '', + 'stompserver' => '', + 'stompport' => '', + 'username' => '', + 'password' => '', + 'webuser' => '', + 'webpass' => '' +)); + diff --git a/plugins/PiwikAnalytics/PiwikAnalyticsPlugin.php b/plugins/PiwikAnalytics/PiwikAnalyticsPlugin.php index fa5894a8f5..b700e07db4 100644 --- a/plugins/PiwikAnalytics/PiwikAnalyticsPlugin.php +++ b/plugins/PiwikAnalytics/PiwikAnalyticsPlugin.php @@ -108,7 +108,7 @@ ENDOFPIWIK; $versions[] = array('name' => 'PiwikAnalytics', 'version' => GNUSOCIAL_VERSION, 'author' => 'Tobias Diekershoff, Evan Prodromou', - 'homepage' => 'http://status.net/wiki/Plugin:Piwik', + 'homepage' => 'https://git.gnu.io/gnu/gnu-social/tree/master/plugins/Piwik', 'rawdescription' => // TRANS: Plugin description. _m('Use Piwik Open Source web analytics software.')); diff --git a/plugins/PiwikAnalytics/README b/plugins/PiwikAnalytics/README new file mode 100644 index 0000000000..6d47ee89ff --- /dev/null +++ b/plugins/PiwikAnalytics/README @@ -0,0 +1,23 @@ +The PiwikAnalytics plugin adds JavaScript that sends various traffic details +to a Piwik server to track web access. + +See: +* http://piwik.org/ + +Installation +============ +add "addPlugin('PiwikAnalytics');" +to the bottom of your config.php + +Settings +======== +piwikroot: The root installation URL of the Piwik instance WITHOUT the protocol +piwikId: The ID provided by the Pwiki instance. + +Example +======= +addPlugin('PiwikAnalytics', array( + 'piwikroot' => 'example.org/piwik/', + 'piwikId' => 'PIWIK_ID' +)); + diff --git a/plugins/Poll/PollPlugin.php b/plugins/Poll/PollPlugin.php index 53a491ef47..4f74e82a35 100644 --- a/plugins/Poll/PollPlugin.php +++ b/plugins/Poll/PollPlugin.php @@ -125,7 +125,7 @@ class PollPlugin extends MicroAppPlugin $versions[] = array('name' => 'Poll', 'version' => self::VERSION, 'author' => 'Brion Vibber', - 'homepage' => 'http://status.net/wiki/Plugin:Poll', + 'homepage' => 'https://git.gnu.io/gnu/gnu-social/tree/master/plugins/Poll', 'rawdescription' => // TRANS: Plugin description. _m('Simple extension for supporting basic polls.')); diff --git a/plugins/PostDebug/PostDebugPlugin.php b/plugins/PostDebug/PostDebugPlugin.php index 120feee8fe..9f87494405 100644 --- a/plugins/PostDebug/PostDebugPlugin.php +++ b/plugins/PostDebug/PostDebugPlugin.php @@ -53,7 +53,7 @@ class PostDebugPlugin extends Plugin $versions[] = array('name' => 'PostDebug', 'version' => GNUSOCIAL_VERSION, 'author' => 'Brion Vibber', - 'homepage' => 'http://status.net/wiki/Plugin:PostDebug', + 'homepage' => 'https://git.gnu.io/gnu/gnu-social/tree/master/plugins/PostDebug', 'rawdescription' => // TRANS: Plugin description. _m('Debugging tool to record request details on POST.')); diff --git a/plugins/PostDebug/README b/plugins/PostDebug/README new file mode 100644 index 0000000000..61a69725d3 --- /dev/null +++ b/plugins/PostDebug/README @@ -0,0 +1,18 @@ +The PostDebug plugin records detailed data on POSTs requests. + +Installation +============ +add "addPlugin('PostDebug');" +to the bottom of your config.php + +Settings +======== +dir: The directory where the log file will be saved + +Example +======= + +addPlugin('PostDebug', array( + 'dir' => '/tmp' +)); + diff --git a/plugins/PtitUrl/PtitUrlPlugin.php b/plugins/PtitUrl/PtitUrlPlugin.php index 0e23a5f64e..031604b57f 100644 --- a/plugins/PtitUrl/PtitUrlPlugin.php +++ b/plugins/PtitUrl/PtitUrlPlugin.php @@ -62,7 +62,7 @@ class PtitUrlPlugin extends UrlShortenerPlugin $versions[] = array('name' => sprintf('PtitUrl (%s)', $this->shortenerName), 'version' => GNUSOCIAL_VERSION, 'author' => 'Craig Andrews', - 'homepage' => 'http://status.net/wiki/Plugin:PtitUrl', + 'homepage' => 'https://git.gnu.io/gnu/gnu-social/tree/master/plugins/PtitUrl', 'rawdescription' => // TRANS: Plugin description. %1$s is the URL shortening service base URL (for example "bit.ly"). sprintf(_m('Uses %1$s URL-shortener service.'), diff --git a/plugins/PtitUrl/README b/plugins/PtitUrl/README new file mode 100644 index 0000000000..507b9ecc26 --- /dev/null +++ b/plugins/PtitUrl/README @@ -0,0 +1,18 @@ +The PtitUrl plugin shortens URLS via a PtitUrl URL-shortener service + +Installation +============ +add "addPlugin('PtitUrl');" +to the bottom of your config.php + +Settings +======== +serviceUrl: The URL to the PtitUrl instance + +Example +======= + +addPlugin('PtitUrl', array( + 'serviceUrl' => 'http://example.org' +)); + diff --git a/plugins/QnA/QnAPlugin.php b/plugins/QnA/QnAPlugin.php index e8c983eb9a..6780637009 100644 --- a/plugins/QnA/QnAPlugin.php +++ b/plugins/QnA/QnAPlugin.php @@ -130,7 +130,7 @@ class QnAPlugin extends MicroAppPlugin 'name' => 'QnA', 'version' => GNUSOCIAL_VERSION, 'author' => 'Zach Copley', - 'homepage' => 'http://status.net/wiki/Plugin:QnA', + 'homepage' => 'https://git.gnu.io/gnu/gnu-social/tree/master/plugins/QnA', 'description' => // TRANS: Plugin description. _m('Question and Answers micro-app.') diff --git a/plugins/QnA/README b/plugins/QnA/README new file mode 100644 index 0000000000..c85b8d910d --- /dev/null +++ b/plugins/QnA/README @@ -0,0 +1,10 @@ +The QnA plugin enables Questions and Answers type of notices + +Installation +============ +This plugin is enabled by default + +Settings +======== +none + diff --git a/plugins/RSSCloud/RSSCloudPlugin.php b/plugins/RSSCloud/RSSCloudPlugin.php index 0fff0947a2..3a8a83749c 100644 --- a/plugins/RSSCloud/RSSCloudPlugin.php +++ b/plugins/RSSCloud/RSSCloudPlugin.php @@ -203,7 +203,7 @@ class RSSCloudPlugin extends Plugin $versions[] = array('name' => 'RSSCloud', 'version' => RSSCLOUDPLUGIN_VERSION, 'author' => 'Zach Copley', - 'homepage' => 'http://status.net/wiki/Plugin:RSSCloud', + 'homepage' => 'https://git.gnu.io/gnu/gnu-social/tree/master/plugins/RSSCloud', 'rawdescription' => // TRANS: Plugin description. _m('The RSSCloud plugin enables your StatusNet instance to publish ' . diff --git a/plugins/Recaptcha/RecaptchaPlugin.php b/plugins/Recaptcha/RecaptchaPlugin.php index c039dd5350..3cf3b65203 100644 --- a/plugins/Recaptcha/RecaptchaPlugin.php +++ b/plugins/Recaptcha/RecaptchaPlugin.php @@ -109,7 +109,7 @@ class RecaptchaPlugin extends Plugin $versions[] = array('name' => 'Recaptcha', 'version' => GNUSOCIAL_VERSION, 'author' => 'Eric Helgeson', - 'homepage' => 'http://status.net/wiki/Plugin:Recaptcha', + 'homepage' => 'https://git.gnu.io/gnu/gnu-social/tree/master/plugins/Recaptcha', 'rawdescription' => // TRANS: Plugin description. _m('Uses Recaptcha service to add a '. diff --git a/plugins/RegisterThrottle/README b/plugins/RegisterThrottle/README new file mode 100644 index 0000000000..049bfd77c6 --- /dev/null +++ b/plugins/RegisterThrottle/README @@ -0,0 +1,24 @@ +The RegisterThrottle plugin throttles registration by IP address + +Installation +============ +This plugin is enabled by default on public instances, otherwise it can be +enabled by adding "addPlugin('RegisterThrottle');" to the bottom of your +config.php + +Settings +======== +regLimits: Array of time spans in seconds to limits. Default is 3 registrations per hour, 5 per day, 10 per week. +silenced: Disallow registration if a silenced user has registered from this IP address + +Example +======= +addPlugin('RegisterThrottle', array( + 'regLimits' => array( + 604800 => 10, // per week + 86400 => 5, // per day + 3600 => 3 // per hour + ), + 'silenced' => true +)); + diff --git a/plugins/RegisterThrottle/RegisterThrottlePlugin.php b/plugins/RegisterThrottle/RegisterThrottlePlugin.php index 552420d8f6..5b999a4370 100644 --- a/plugins/RegisterThrottle/RegisterThrottlePlugin.php +++ b/plugins/RegisterThrottle/RegisterThrottlePlugin.php @@ -60,6 +60,14 @@ class RegisterThrottlePlugin extends Plugin */ public $silenced = true; + /** + * Auto-silence all other users from the same registration_ip + * as the one being silenced. Caution: Many users may come from + * the same IP (even entire countries) without having any sort + * of relevant connection for moderation. + */ + public $auto_silence_by_ip = false; + /** * Whether we're enabled; prevents recursion. */ @@ -233,7 +241,7 @@ class RegisterThrottlePlugin extends Plugin $versions[] = array('name' => 'RegisterThrottle', 'version' => GNUSOCIAL_VERSION, 'author' => 'Evan Prodromou', - 'homepage' => 'http://status.net/wiki/Plugin:RegisterThrottle', + 'homepage' => 'https://git.gnu.io/gnu/gnu-social/tree/master/plugins/RegisterThrottle', 'description' => // TRANS: Plugin description. _m('Throttles excessive registration from a single IP address.')); @@ -300,15 +308,15 @@ class RegisterThrottlePlugin extends Plugin return true; } - if ($role != Profile_role::SILENCED) { + if ($role !== Profile_role::SILENCED) { return true; } - if (!$this->silenced) { + if (!$this->auto_silence_by_ip) { return true; } - $ri = Registration_ip::getKV('user_id', $profile->id); + $ri = Registration_ip::getKV('user_id', $profile->getID()); if (empty($ri)) { return true; @@ -317,13 +325,13 @@ class RegisterThrottlePlugin extends Plugin $ids = Registration_ip::usersByIP($ri->ipaddress); foreach ($ids as $id) { - if ($id == $profile->id) { + if ($id == $profile->getID()) { continue; } - $other = Profile::getKV('id', $id); - - if (empty($other)) { + try { + $other = Profile::getByID($id); + } catch (NoResultException $e) { continue; } @@ -331,6 +339,11 @@ class RegisterThrottlePlugin extends Plugin continue; } + // 'enabled' here is used to prevent recursion, since + // we'll end up in this function again on ->silence() + // though I actually think it doesn't matter since we + // do this in onEndGrantRole and that means the above + // $other->isSilenced() test should've 'continue'd... $old = self::$enabled; self::$enabled = false; $other->silence(); diff --git a/plugins/RequireValidatedEmail/RequireValidatedEmailPlugin.php b/plugins/RequireValidatedEmail/RequireValidatedEmailPlugin.php index 734cabbcd5..6ca13b9097 100644 --- a/plugins/RequireValidatedEmail/RequireValidatedEmailPlugin.php +++ b/plugins/RequireValidatedEmail/RequireValidatedEmailPlugin.php @@ -221,7 +221,7 @@ class RequireValidatedEmailPlugin extends Plugin 'Evan Prodromou, '. 'Brion Vibber', 'homepage' => - 'http://status.net/wiki/Plugin:RequireValidatedEmail', + 'https://git.gnu.io/gnu/gnu-social/tree/master/plugins/RequireValidatedEmail', 'rawdescription' => // TRANS: Plugin description. _m('Disables posting without a validated email address.')); diff --git a/plugins/ReverseUsernameAuthentication/ReverseUsernameAuthenticationPlugin.php b/plugins/ReverseUsernameAuthentication/ReverseUsernameAuthenticationPlugin.php index 9a85a974ae..47f304414e 100644 --- a/plugins/ReverseUsernameAuthentication/ReverseUsernameAuthenticationPlugin.php +++ b/plugins/ReverseUsernameAuthentication/ReverseUsernameAuthenticationPlugin.php @@ -62,7 +62,7 @@ class ReverseUsernameAuthenticationPlugin extends AuthenticationPlugin $versions[] = array('name' => 'Reverse Username Authentication', 'version' => GNUSOCIAL_VERSION, 'author' => 'Craig Andrews', - 'homepage' => 'http://status.net/wiki/Plugin:ReverseUsernameAuthentication', + 'homepage' => 'https://git.gnu.io/gnu/gnu-social/tree/master/plugins/ReverseUsernameAuthentication', 'rawdescription' => // TRANS: Plugin description. _m('The Reverse Username Authentication plugin allows for StatusNet to handle authentication by checking if the provided password is the same as the reverse of the username.')); diff --git a/plugins/SQLProfile/README b/plugins/SQLProfile/README new file mode 100644 index 0000000000..03b42b3262 --- /dev/null +++ b/plugins/SQLProfile/README @@ -0,0 +1,17 @@ +The SQLProfile plugin watches for poorly indexed DB queries. + +Installation +============ +add "addPlugin('SQLProfile');" +to the bottom of your config.php + +Settings +======== +none + +Note: entries are logged at the LOG_DEBUG level. + +Example +======= +addPlugin('SQLProfile'); + diff --git a/plugins/SQLProfile/SQLProfilePlugin.php b/plugins/SQLProfile/SQLProfilePlugin.php index a7912844c2..3baa91e494 100644 --- a/plugins/SQLProfile/SQLProfilePlugin.php +++ b/plugins/SQLProfile/SQLProfilePlugin.php @@ -36,7 +36,7 @@ class SQLProfilePlugin extends Plugin $versions[] = array('name' => 'SQLProfile', 'version' => GNUSOCIAL_VERSION, 'author' => 'Brion Vibber', - 'homepage' => 'http://status.net/wiki/Plugin:SQLProfile', + 'homepage' => 'https://git.gnu.io/gnu/gnu-social/tree/master/plugins/SQLProfile', 'rawdescription' => // TRANS: Plugin description. _m('Debug tool to watch for poorly indexed DB queries.')); diff --git a/plugins/SQLStats/README b/plugins/SQLStats/README new file mode 100644 index 0000000000..0f840b1af5 --- /dev/null +++ b/plugins/SQLStats/README @@ -0,0 +1,18 @@ +The SQLStats plugin logs statistics on performed SQL queries. + +Installation +============ +add "addPlugin('SQLStats');" +to the bottom of your config.php + +Settings +======== +verbose: whether to be verbose or not + +Note: entries are logged at the LOG_INFO level. + +Example +======= +$config['sqlstats']['verbose'] = false; +addPlugin('SQLStats'); + diff --git a/plugins/SQLStats/SQLStatsPlugin.php b/plugins/SQLStats/SQLStatsPlugin.php index f67ed03012..bd83ac0a32 100644 --- a/plugins/SQLStats/SQLStatsPlugin.php +++ b/plugins/SQLStats/SQLStatsPlugin.php @@ -39,7 +39,7 @@ class SQLStatsPlugin extends Plugin $versions[] = array('name' => 'SQLStats', 'version' => GNUSOCIAL_VERSION, 'author' => 'Evan Prodromou', - 'homepage' => 'http://status.net/wiki/Plugin:SQLStats', + 'homepage' => 'https://git.gnu.io/gnu/gnu-social/tree/master/plugins/SQLStats', 'rawdescription' => // TRANS: Plugin decription. _m('Debug tool to watch for poorly indexed DB queries.')); diff --git a/plugins/Sample/README b/plugins/Sample/README new file mode 100644 index 0000000000..ff1188d8af --- /dev/null +++ b/plugins/Sample/README @@ -0,0 +1,19 @@ +The Sample plugin shows best practices for development of GNU social plugins. + +It adds a "Hello" menu item to the default menu and tracks how many times it +has greeted each user. + +Installation +============ +add "addPlugin('Sample');" +to the bottom of your config.php + +Settings +======== +none + +Example +======= + +addPlugin('Sample'); + diff --git a/plugins/Sample/SamplePlugin.php b/plugins/Sample/SamplePlugin.php index 80c46d17c4..4f8351cc08 100644 --- a/plugins/Sample/SamplePlugin.php +++ b/plugins/Sample/SamplePlugin.php @@ -227,7 +227,7 @@ class SamplePlugin extends Plugin $versions[] = array('name' => 'Sample', 'version' => GNUSOCIAL_VERSION, 'author' => 'Brion Vibber, Evan Prodromou', - 'homepage' => 'http://status.net/wiki/Plugin:Sample', + 'homepage' => 'https://git.gnu.io/gnu/gnu-social/tree/master/plugins/Sample', 'rawdescription' => // TRANS: Plugin description. _m('A sample plugin to show basics of development for new hackers.')); diff --git a/plugins/SearchSub/README b/plugins/SearchSub/README new file mode 100644 index 0000000000..7e9e693a8e --- /dev/null +++ b/plugins/SearchSub/README @@ -0,0 +1,10 @@ +The SearchSub plugin allows following all messages with a given search. + +Installation +============ +This plugin is enabled by default + +Settings +======== +none + diff --git a/plugins/SearchSub/SearchSubPlugin.php b/plugins/SearchSub/SearchSubPlugin.php index 57984d0e01..06d644235e 100644 --- a/plugins/SearchSub/SearchSubPlugin.php +++ b/plugins/SearchSub/SearchSubPlugin.php @@ -93,7 +93,7 @@ class SearchSubPlugin extends Plugin $versions[] = array('name' => 'SearchSub', 'version' => self::VERSION, 'author' => 'Brion Vibber', - 'homepage' => 'http://status.net/wiki/Plugin:SearchSub', + 'homepage' => 'https://git.gnu.io/gnu/gnu-social/tree/master/plugins/SearchSub', 'rawdescription' => // TRANS: Plugin description. _m('Plugin to allow following all messages with a given search.')); diff --git a/plugins/Share/README b/plugins/Share/README new file mode 100644 index 0000000000..6ca78ac7d0 --- /dev/null +++ b/plugins/Share/README @@ -0,0 +1,10 @@ +The Share plugin implements "Shares" (repeats) type of notices + +Installation +============ +This plugin is enabled by default + +Settings +======== +none + diff --git a/plugins/ShareNotice/README b/plugins/ShareNotice/README new file mode 100644 index 0000000000..0379c594db --- /dev/null +++ b/plugins/ShareNotice/README @@ -0,0 +1,23 @@ +The ShareNotice plugin allows sharing of notices to Twitter, Facebook and other +platforms. + +Installation +============ +add "addPlugin('ShareNotice');" +to the bottom of your config.php + +Settings +======== +targets: Array of platforms allowed to share to + +Example +======= + +addPlugin('ShareNotice', array( + 'targets' => array( + array('Twitter'), + array('Facebook'), + array('StatusNet', array('baseurl' => 'http://example.org')) + ) +)); + diff --git a/plugins/ShareNotice/ShareNoticePlugin.php b/plugins/ShareNotice/ShareNoticePlugin.php index 7a6fd28fee..fb60341e3d 100644 --- a/plugins/ShareNotice/ShareNoticePlugin.php +++ b/plugins/ShareNotice/ShareNoticePlugin.php @@ -211,7 +211,7 @@ class FacebookShareTarget extends NoticeShareTarget */ function onPluginVersion(array &$versions) { - $url = 'http://status.net/wiki/Plugin:ShareNotice'; + $url = 'https://git.gnu.io/gnu/gnu-social/tree/master/plugins/ShareNotice'; $versions[] = array('name' => 'ShareNotice', 'version' => GNUSOCIAL_VERSION, diff --git a/plugins/SimpleCaptcha/README b/plugins/SimpleCaptcha/README new file mode 100644 index 0000000000..754fe13c16 --- /dev/null +++ b/plugins/SimpleCaptcha/README @@ -0,0 +1,10 @@ +A simple captcha to get rid of spambots. + +Installation +============ +This plugin is enabled by default + +Settings +======== +none + diff --git a/plugins/SimpleUrl/README b/plugins/SimpleUrl/README new file mode 100644 index 0000000000..5a9f953d5d --- /dev/null +++ b/plugins/SimpleUrl/README @@ -0,0 +1,18 @@ +The SimpleUrl plugin shortens URLS via a SimpleUrl URL-shortener service + +Installation +============ +add "addPlugin('SimpleUrl');" +to the bottom of your config.php + +Settings +======== +serviceUrl: The URL to the SimpleUrl instance + +Example +======= + +addPlugin('SimpleUrl', array( + 'serviceUrl' => 'http://example.org' +)); + diff --git a/plugins/SimpleUrl/SimpleUrlPlugin.php b/plugins/SimpleUrl/SimpleUrlPlugin.php index 41e1998483..235a330e02 100644 --- a/plugins/SimpleUrl/SimpleUrlPlugin.php +++ b/plugins/SimpleUrl/SimpleUrlPlugin.php @@ -52,7 +52,7 @@ class SimpleUrlPlugin extends UrlShortenerPlugin $versions[] = array('name' => sprintf('SimpleUrl (%s)', $this->shortenerName), 'version' => GNUSOCIAL_VERSION, 'author' => 'Craig Andrews', - 'homepage' => 'http://status.net/wiki/Plugin:SimpleUrl', + 'homepage' => 'https://git.gnu.io/gnu/gnu-social/tree/master/plugins/SimpleUrl', 'rawdescription' => // TRANS: Plugin description. sprintf(_m('Uses %1$s URL-shortener service.'), diff --git a/plugins/SiteNoticeInSidebar/README b/plugins/SiteNoticeInSidebar/README new file mode 100644 index 0000000000..6e70cbc40e --- /dev/null +++ b/plugins/SiteNoticeInSidebar/README @@ -0,0 +1,16 @@ +The SiteNoticeInSidebar plugin puts the site notice in the sidebar. + +Installation +============ +add "addPlugin('SiteNoticeInSidebar');" +to the bottom of your config.php + +Settings +======== +notice: The text to use in the site notice + +Example +======= +$config['site']['notice'] = 'Site notice content'; +addPlugin('SiteNoticeInSidebar'); + diff --git a/plugins/Sitemap/README b/plugins/Sitemap/README new file mode 100644 index 0000000000..b6717da622 --- /dev/null +++ b/plugins/Sitemap/README @@ -0,0 +1,20 @@ +The Sitemap plugin creates a dynamic sitemap for Bing, Yahoo! and Google + +Installation +============ +add "addPlugin('Sitemap');" +to the bottom of your config.php + +Settings +======== +googlekey: The key provided by Google +yahookey: The key provided by Yahoo! +bingkey: The key provided by Bing + +Example +======= +$config['sitemap']['googlekey'] = 'GOOGLE_KEY'; +$config['sitemap']['yahookey'] = 'YAHOO_KEY'; +$config['sitemap']['bingkey'] = 'BING_KEY'; +addPlugin('Sitemap'); + diff --git a/plugins/Sitemap/SitemapPlugin.php b/plugins/Sitemap/SitemapPlugin.php index a1fe90b4b4..6bc5e07fef 100644 --- a/plugins/Sitemap/SitemapPlugin.php +++ b/plugins/Sitemap/SitemapPlugin.php @@ -176,7 +176,7 @@ class SitemapPlugin extends Plugin */ function onPluginVersion(array &$versions) { - $url = 'http://status.net/wiki/Plugin:Sitemap'; + $url = 'https://git.gnu.io/gnu/gnu-social/tree/master/plugins/Sitemap'; $versions[] = array('name' => 'Sitemap', 'version' => GNUSOCIAL_VERSION, diff --git a/plugins/SlicedFavorites/README b/plugins/SlicedFavorites/README new file mode 100644 index 0000000000..550e2feeb4 --- /dev/null +++ b/plugins/SlicedFavorites/README @@ -0,0 +1,30 @@ +The SlicedFavorites plugin shows timelines of popular notices for defined +subsets of users. + +Installation +============ +add "addPlugin('SlicedFavorites');" +to the bottom of your config.php + +Settings +======== +slices: Array of subsets + +Example +======= +addPlugin('SlicedFavorites', array( + 'slices' => array( + // show only pop's notices on /favorited + 'default' => array('include' => array('pop')), + + // show only son's notices on /favorited/blog + 'blog' => array('include' => array('son')), + + // show all favorited notices except pop's and son's on /favorited/submitted + 'submitted' => array('exclude' => array('pop', 'son')), + + // show all favorited notices on /favorited/everybody + 'everybody' => array(), + ) +)); + diff --git a/plugins/SlicedFavorites/SlicedFavoritesPlugin.php b/plugins/SlicedFavorites/SlicedFavoritesPlugin.php index 4e1129536d..fcf971de6a 100644 --- a/plugins/SlicedFavorites/SlicedFavoritesPlugin.php +++ b/plugins/SlicedFavorites/SlicedFavoritesPlugin.php @@ -97,7 +97,7 @@ class SlicedFavoritesPlugin extends Plugin */ function onPluginVersion(array &$versions) { - $url = 'http://status.net/wiki/Plugin:SlicedFavorites'; + $url = 'https://git.gnu.io/gnu/gnu-social/tree/master/plugins/SlicedFavorites'; $versions[] = array('name' => 'SlicedFavorites', 'version' => GNUSOCIAL_VERSION, diff --git a/plugins/SphinxSearch/README b/plugins/SphinxSearch/README index 5a2c063bd0..873a8cf692 100644 --- a/plugins/SphinxSearch/README +++ b/plugins/SphinxSearch/README @@ -8,9 +8,9 @@ Configuration In StatusNet's configuration, you can adjust the following settings under 'sphinx': -enabled: Set to true to enable. Default false. -server: a string with the hostname of the sphinx server. -port: an integer with the port number of the sphinx server. +enabled: Set to true to enable. Default true. +server: a string with the hostname of the sphinx server. Default localhost +port: an integer with the port number of the sphinx server. Default 3312 Requirements diff --git a/plugins/SphinxSearch/SphinxSearchPlugin.php b/plugins/SphinxSearch/SphinxSearchPlugin.php index 74744f18e6..8345ea59e7 100644 --- a/plugins/SphinxSearch/SphinxSearchPlugin.php +++ b/plugins/SphinxSearch/SphinxSearchPlugin.php @@ -107,7 +107,7 @@ class SphinxSearchPlugin extends Plugin */ function onPluginVersion(array &$versions) { - $url = 'http://status.net/wiki/Plugin:SphinxSearch'; + $url = 'https://git.gnu.io/gnu/gnu-social/tree/master/plugins/SphinxSearch'; $versions[] = array('name' => 'SphinxSearch', 'version' => GNUSOCIAL_VERSION, diff --git a/plugins/StoreRemoteMedia/README b/plugins/StoreRemoteMedia/README new file mode 100644 index 0000000000..a6bd91f605 --- /dev/null +++ b/plugins/StoreRemoteMedia/README @@ -0,0 +1,22 @@ +The StoreRemoteMedia plugin downloads remotely attached files to local server. + +Installation +============ +add "addPlugin('StoreRemoteMedia');" +to the bottom of your config.php + +Settings +======== +domain_whitelist: Array of regular expressions. Always escape your dots and end your strings. +check_whitelist: Whether to check the domain_whitelist. + +Example +======= +addPlugin('StoreRemoteMedia', array( + 'domain_whitelist' => array( + '^i\d*\.ytimg\.com$' => 'YouTube', + '^i\d*\.vimeocdn\.com$' => 'Vimeo' + ), + 'check_whitelist' => true +)); + diff --git a/plugins/StrictTransportSecurity/StrictTransportSecurityPlugin.php b/plugins/StrictTransportSecurity/StrictTransportSecurityPlugin.php index 67cb665018..e3c879943e 100644 --- a/plugins/StrictTransportSecurity/StrictTransportSecurityPlugin.php +++ b/plugins/StrictTransportSecurity/StrictTransportSecurityPlugin.php @@ -55,7 +55,7 @@ class StrictTransportSecurityPlugin extends Plugin $versions[] = array('name' => 'StrictTransportSecurity', 'version' => GNUSOCIAL_VERSION, 'author' => 'Craig Andrews', - 'homepage' => 'http://status.net/wiki/Plugin:StrictTransportSecurity', + 'homepage' => 'https://git.gnu.io/gnu/gnu-social/tree/master/plugins/StrictTransportSecurity', 'rawdescription' => // TRANS: Plugin description. _m('The Strict Transport Security plugin implements the Strict Transport Security header, improving the security of HTTPS only sites.')); diff --git a/plugins/SubMirror/README b/plugins/SubMirror/README new file mode 100644 index 0000000000..1910874d1c --- /dev/null +++ b/plugins/SubMirror/README @@ -0,0 +1,15 @@ +The SubMirror plugin pull PuSH-enabled feeds into your timeline. + +Installation +============ +add "addPlugin('SubMirror');" +to the bottom of your config.php + +Settings +======== +none + +Example +======= +addPlugin('SubMirror'); + diff --git a/plugins/SubMirror/SubMirrorPlugin.php b/plugins/SubMirror/SubMirrorPlugin.php index 27fc7c984d..83e15a9bd4 100644 --- a/plugins/SubMirror/SubMirrorPlugin.php +++ b/plugins/SubMirror/SubMirrorPlugin.php @@ -62,7 +62,7 @@ class SubMirrorPlugin extends Plugin $versions[] = array('name' => 'SubMirror', 'version' => GNUSOCIAL_VERSION, 'author' => 'Brion Vibber', - 'homepage' => 'http://status.net/wiki/Plugin:SubMirror', + 'homepage' => 'https://git.gnu.io/gnu/gnu-social/tree/master/plugins/SubMirror', 'rawdescription' => // TRANS: Plugin description. _m('Pull feeds into your timeline!')); diff --git a/plugins/SubscriptionThrottle/README b/plugins/SubscriptionThrottle/README new file mode 100644 index 0000000000..686ba2bc2f --- /dev/null +++ b/plugins/SubscriptionThrottle/README @@ -0,0 +1,26 @@ +The SubscriptionThrottle plugin limits how fast users can subscribe to groups +and other users. + +Installation +============ +add "addPlugin('SubscriptionThrottle');" +to the bottom of your config.php + +Settings +======== +subLimits: Array of time spans in seconds to limit subscriptions to users. +groupLimits: Array of time spans in seconds to limit subscriptions to groups. + +Example +======= +addPlugin('SubscriptionThrottle', array( + 'subLimits' => array( + 86400 => 100, // 100 subs per day + 3600 => 50; // 50 subs per hour + ), + 'groupLimits' => array( + 86400 => 50, // 50 subs per day + 3600 => 25; // 25 subs per hour + ) +)); + diff --git a/plugins/SubscriptionThrottle/SubscriptionThrottlePlugin.php b/plugins/SubscriptionThrottle/SubscriptionThrottlePlugin.php index fec91afdb7..30b9290273 100644 --- a/plugins/SubscriptionThrottle/SubscriptionThrottlePlugin.php +++ b/plugins/SubscriptionThrottle/SubscriptionThrottlePlugin.php @@ -162,7 +162,7 @@ class SubscriptionThrottlePlugin extends Plugin $versions[] = array('name' => 'SubscriptionThrottle', 'version' => GNUSOCIAL_VERSION, 'author' => 'Evan Prodromou', - 'homepage' => 'http://status.net/wiki/Plugin:SubscriptionThrottle', + 'homepage' => 'https://git.gnu.io/gnu/gnu-social/tree/master/plugins/SubscriptionThrottle', 'rawdescription' => // TRANS: Plugin description. _m('Configurable limits for subscriptions and group memberships.')); diff --git a/plugins/TabFocus/README b/plugins/TabFocus/README new file mode 100644 index 0000000000..61d7c60b2b --- /dev/null +++ b/plugins/TabFocus/README @@ -0,0 +1,17 @@ +The TabFocus plugin changes the notice form behavior so that, while in the text +area, pressing the tab key focuses the "Send" button, matching the behavior of +Twitter. + +Installation +============ +add "addPlugin('TabFocus');" +to the bottom of your config.php + +Settings +======== +none + +Example +======= +addPlugin('TabFocus'); + diff --git a/plugins/TabFocus/TabFocusPlugin.php b/plugins/TabFocus/TabFocusPlugin.php index df69298888..ff43613383 100644 --- a/plugins/TabFocus/TabFocusPlugin.php +++ b/plugins/TabFocus/TabFocusPlugin.php @@ -49,7 +49,7 @@ class TabFocusPlugin extends Plugin $versions[] = array('name' => 'TabFocus', 'version' => GNUSOCIAL_VERSION, 'author' => 'Craig Andrews and Paul Irish', - 'homepage' => 'http://status.net/wiki/Plugin:TabFocus', + 'homepage' => 'https://git.gnu.io/gnu/gnu-social/tree/master/plugins/TabFocus', 'rawdescription' => // TRANS: Plugin description. _m('TabFocus changes the notice form behavior so that, while in the text area, pressing the tab key focuses the "Send" button, matching the behavior of Twitter.')); diff --git a/plugins/TagSub/README b/plugins/TagSub/README new file mode 100644 index 0000000000..a13d4bf471 --- /dev/null +++ b/plugins/TagSub/README @@ -0,0 +1,10 @@ +The TagSub plugin allows following all messages with a given tag. + +Installation +============ +This plugin is enabled by default + +Settings +======== +none + diff --git a/plugins/TagSub/TagSubPlugin.php b/plugins/TagSub/TagSubPlugin.php index f1d1ab4622..14c0cd191b 100644 --- a/plugins/TagSub/TagSubPlugin.php +++ b/plugins/TagSub/TagSubPlugin.php @@ -94,7 +94,7 @@ class TagSubPlugin extends Plugin $versions[] = array('name' => 'TagSub', 'version' => self::VERSION, 'author' => 'Brion Vibber', - 'homepage' => 'http://status.net/wiki/Plugin:TagSub', + 'homepage' => 'https://git.gnu.io/gnu/gnu-social/tree/master/plugins/TagSub', 'rawdescription' => // TRANS: Plugin description. _m('Plugin to allow following all messages with a given tag.')); diff --git a/plugins/TightUrl/README b/plugins/TightUrl/README new file mode 100644 index 0000000000..35abb3bb7d --- /dev/null +++ b/plugins/TightUrl/README @@ -0,0 +1,18 @@ +The TightUrl plugin shortens URLS via a TightUrl URL-shortener service + +Installation +============ +add "addPlugin('TightUrl');" +to the bottom of your config.php + +Settings +======== +serviceUrl: The URL to the TightUrl instance + +Example +======= + +addPlugin('TightUrl', array( + 'serviceUrl' => 'http://example.org' +)); + diff --git a/plugins/TightUrl/TightUrlPlugin.php b/plugins/TightUrl/TightUrlPlugin.php index 52e5184392..a3bc492ad1 100644 --- a/plugins/TightUrl/TightUrlPlugin.php +++ b/plugins/TightUrl/TightUrlPlugin.php @@ -62,7 +62,7 @@ class TightUrlPlugin extends UrlShortenerPlugin $versions[] = array('name' => sprintf('TightUrl (%s)', $this->shortenerName), 'version' => GNUSOCIAL_VERSION, 'author' => 'Craig Andrews', - 'homepage' => 'http://status.net/wiki/Plugin:TightUrl', + 'homepage' => 'https://git.gnu.io/gnu/gnu-social/tree/master/plugins/TightUrl', 'rawdescription' => // TRANS: Plugin description. %s is the shortener name. sprintf(_m('Uses %1$s URL-shortener service.'), diff --git a/plugins/TwitterBridge/TwitterBridgePlugin.php b/plugins/TwitterBridge/TwitterBridgePlugin.php index 623e2b51d8..0a88716853 100644 --- a/plugins/TwitterBridge/TwitterBridgePlugin.php +++ b/plugins/TwitterBridge/TwitterBridgePlugin.php @@ -301,7 +301,7 @@ class TwitterBridgePlugin extends Plugin 'name' => 'TwitterBridge', 'version' => self::VERSION, 'author' => 'Zach Copley, Julien C, Jean Baptiste Favre', - 'homepage' => 'http://status.net/wiki/Plugin:TwitterBridge', + 'homepage' => 'https://git.gnu.io/gnu/gnu-social/tree/master/plugins/TwitterBridge', // TRANS: Plugin description. 'rawdescription' => _m('The Twitter "bridge" plugin allows integration ' . 'of a StatusNet instance with ' . diff --git a/plugins/UserFlag/README b/plugins/UserFlag/README new file mode 100644 index 0000000000..9fbfcc7c01 --- /dev/null +++ b/plugins/UserFlag/README @@ -0,0 +1,18 @@ +The UserFlag plugin allows flagging of profiles for review and reviewing +flagged profiles. + +Installation +============ +add "addPlugin('UserFlag');" +to the bottom of your config.php + +Settings +======== +flagOnBlock: Whether to automatically flag a profile when a user blocks it. + +Example +======= +addPlugin('UserFlag', array( + 'flagOnBlock' => true +)); + diff --git a/plugins/UserFlag/UserFlagPlugin.php b/plugins/UserFlag/UserFlagPlugin.php index d2afeaced8..8b2971f35e 100644 --- a/plugins/UserFlag/UserFlagPlugin.php +++ b/plugins/UserFlag/UserFlagPlugin.php @@ -229,7 +229,7 @@ class UserFlagPlugin extends Plugin */ function onPluginVersion(array &$versions) { - $url = 'http://status.net/wiki/Plugin:UserFlag'; + $url = 'https://git.gnu.io/gnu/gnu-social/tree/master/plugins/UserFlag'; $versions[] = array('name' => 'UserFlag', 'version' => GNUSOCIAL_VERSION, diff --git a/plugins/UserLimit/README b/plugins/UserLimit/README new file mode 100644 index 0000000000..07f32bb41e --- /dev/null +++ b/plugins/UserLimit/README @@ -0,0 +1,17 @@ +The UserLimit plugin limits the number of users who can register. + +Installation +============ +add "addPlugin('UserLimit');" +to the bottom of your config.php + +Settings +======== +maxUsers: The number of maximum users allowed. + +Example +======= +addPlugin('UserLimit', array( + 'maxUsers' => 42 +)); + diff --git a/plugins/UserLimit/UserLimitPlugin.php b/plugins/UserLimit/UserLimitPlugin.php index ac4d503151..2bb1218a72 100644 --- a/plugins/UserLimit/UserLimitPlugin.php +++ b/plugins/UserLimit/UserLimitPlugin.php @@ -86,7 +86,7 @@ class UserLimitPlugin extends Plugin $versions[] = array('name' => 'UserLimit', 'version' => GNUSOCIAL_VERSION, 'author' => 'Evan Prodromou', - 'homepage' => 'http://status.net/wiki/Plugin:UserLimit', + 'homepage' => 'https://git.gnu.io/gnu/gnu-social/tree/master/plugins/UserLimit', 'description' => // TRANS: Plugin description. _m('Limit the number of users who can register.')); diff --git a/plugins/VideoThumbnails/README b/plugins/VideoThumbnails/README new file mode 100644 index 0000000000..0967532c8c --- /dev/null +++ b/plugins/VideoThumbnails/README @@ -0,0 +1,19 @@ +The VideoThumbnails plugin enables video thumbnail preview support. + +Installation +============ +add "addPlugin('VideoThumbnails');" +to the bottom of your config.php + +Note: This plugin depends on +* avconv +* php5-gd + +Settings +======== +none + +Example +======= +addPlugin('VideoThumbnails'); + diff --git a/plugins/WebFinger/README b/plugins/WebFinger/README new file mode 100644 index 0000000000..3c49338515 --- /dev/null +++ b/plugins/WebFinger/README @@ -0,0 +1,10 @@ +The WebFinger plugin adds WebFinger lookup to GNU Social + +Installation +============ +This plugin is enabled by default except on private instances + +Settings +======== +none + diff --git a/plugins/WikiHashtags/REAME b/plugins/WikiHashtags/REAME new file mode 100644 index 0000000000..209b0c3802 --- /dev/null +++ b/plugins/WikiHashtags/REAME @@ -0,0 +1,17 @@ +The WikiHashtags plugin shows WikiHashtags content in the sidebar + +See: http://hashtags.wikia.com/wiki/WikiHashtags + +Installation +============ +add "addPlugin('WikiHashtags');" +to the bottom of your config.php + +Settings +======== +none + +Example +======= +addPlugin('WikiHashtags'); + diff --git a/plugins/WikiHashtags/WikiHashtagsPlugin.php b/plugins/WikiHashtags/WikiHashtagsPlugin.php index db33eb801a..46d0470143 100644 --- a/plugins/WikiHashtags/WikiHashtagsPlugin.php +++ b/plugins/WikiHashtags/WikiHashtagsPlugin.php @@ -109,7 +109,7 @@ class WikiHashtagsPlugin extends Plugin $versions[] = array('name' => 'WikiHashtags', 'version' => self::VERSION, 'author' => 'Evan Prodromou', - 'homepage' => 'http://status.net/wiki/Plugin:WikiHashtags', + 'homepage' => 'https://git.gnu.io/gnu/gnu-social/tree/master/plugins/WikiHashtags', 'rawdescription' => // TRANS: Plugin description. _m('Gets hashtag descriptions from WikiHashtags.')); diff --git a/plugins/WikiHowProfile/WikiHowProfilePlugin.php b/plugins/WikiHowProfile/WikiHowProfilePlugin.php index 8656272e48..9d8daf8adb 100644 --- a/plugins/WikiHowProfile/WikiHowProfilePlugin.php +++ b/plugins/WikiHowProfile/WikiHowProfilePlugin.php @@ -54,7 +54,7 @@ class WikiHowProfilePlugin extends Plugin $versions[] = array('name' => 'WikiHow avatar fetcher', 'version' => GNUSOCIAL_VERSION, 'author' => 'Brion Vibber', - 'homepage' => 'http://status.net/wiki/Plugin:Sample', + 'homepage' => 'https://git.gnu.io/gnu/gnu-social/tree/master/plugins/Sample', 'rawdescription' => // TRANS: Plugin description. _m('Fetches avatar and other profile information for WikiHow users when setting up an account via OpenID.')); diff --git a/plugins/Xmpp/XmppPlugin.php b/plugins/Xmpp/XmppPlugin.php index 6867eb093e..f8476cd8f2 100644 --- a/plugins/Xmpp/XmppPlugin.php +++ b/plugins/Xmpp/XmppPlugin.php @@ -461,7 +461,7 @@ class XmppPlugin extends ImPlugin $versions[] = array('name' => 'XMPP', 'version' => GNUSOCIAL_VERSION, 'author' => 'Craig Andrews, Evan Prodromou', - 'homepage' => 'http://status.net/wiki/Plugin:XMPP', + 'homepage' => 'https://git.gnu.io/gnu/gnu-social/tree/master/plugins/XMPP', 'rawdescription' => // TRANS: Plugin description. _m('The XMPP plugin allows users to send and receive notices over the XMPP/Jabber network.')); diff --git a/scripts/delete_notice.php b/scripts/delete_notice.php index bf10cbb2b2..cd29cffc15 100755 --- a/scripts/delete_notice.php +++ b/scripts/delete_notice.php @@ -20,8 +20,8 @@ define('INSTALLDIR', realpath(dirname(__FILE__) . '/..')); -$shortoptions = 'i::n::u::y'; -$longoptions = array('id=', 'nickname=', 'uri=', 'yes'); +$shortoptions = 'i::u::y'; +$longoptions = array('id=', 'uri=', 'yes'); $helptext = <<getMessage()}\n"; exit(1); } diff --git a/socialfy-your-domain/README.txt b/socialfy-another-domain/README.txt similarity index 85% rename from socialfy-your-domain/README.txt rename to socialfy-another-domain/README.txt index b7691abe8d..7cb01ed2ef 100644 --- a/socialfy-your-domain/README.txt +++ b/socialfy-another-domain/README.txt @@ -1,6 +1,11 @@ Initial simple way to Webfinger enable your domain -- needs PHP. ================================================================ +This guide needs some updating, since it will only guide you to present +XML data (while the curl command likely gives you JSON). The workaround +is to simply make curl get 'webfinger.xml' instead, and/or have another +file that contains JSON, but that requires editing the PHP file as well. + Step 1 ====== diff --git a/socialfy-your-domain/dot-well-known/host-meta b/socialfy-another-domain/dot-well-known/host-meta similarity index 100% rename from socialfy-your-domain/dot-well-known/host-meta rename to socialfy-another-domain/dot-well-known/host-meta diff --git a/socialfy-your-domain/dot-well-known/webfinger/example@example.com.xml b/socialfy-another-domain/dot-well-known/webfinger/example@example.com.xml similarity index 100% rename from socialfy-your-domain/dot-well-known/webfinger/example@example.com.xml rename to socialfy-another-domain/dot-well-known/webfinger/example@example.com.xml diff --git a/socialfy-your-domain/dot-well-known/webfinger/index.php b/socialfy-another-domain/dot-well-known/webfinger/index.php similarity index 100% rename from socialfy-your-domain/dot-well-known/webfinger/index.php rename to socialfy-another-domain/dot-well-known/webfinger/index.php