Merge branch '1.0.x' into testing
This commit is contained in:
commit
4989fc72d2
@ -73,6 +73,7 @@ class ApprovesubAction extends Action
|
||||
|
||||
if (empty($this->request)) {
|
||||
// TRANS: Client error displayed trying to approve subscription for a non-existing request.
|
||||
// TRANS: %s is a user nickname.
|
||||
$this->clientError(sprintf(_('%s is not in the moderation queue for your subscriptions.'), $this->profile->nickname), 403);
|
||||
}
|
||||
|
||||
|
@ -260,7 +260,7 @@ class RecoverpasswordAction extends Action
|
||||
$this->elementStart('li');
|
||||
// TRANS: Field label for password reset form where the password has to be typed again.
|
||||
$this->password('confirm', _('Confirm'),
|
||||
// TRANS: Ttile for field label for password reset form where the password has to be typed again.
|
||||
// TRANS: Title for field label for password reset form where the password has to be typed again.
|
||||
_('Same as password above.'));
|
||||
$this->elementEnd('li');
|
||||
$this->elementEnd('ul');
|
||||
|
@ -157,13 +157,13 @@ class SiteadminpanelAction extends AdminPanelAction
|
||||
// Validate logos
|
||||
if (!empty($values['site']['logo']) &&
|
||||
!Validate::uri($values['site']['logo'], array('allowed_schemes' => array('http', 'https')))) {
|
||||
// TRANS: Client error displayed when a logo URL does is not valid.
|
||||
// TRANS: Client error displayed when a logo URL is not valid.
|
||||
$this->clientError(_('Invalid logo URL.'));
|
||||
}
|
||||
|
||||
if (!empty($values['site']['ssllogo']) &&
|
||||
!Validate::uri($values['site']['ssllogo'], array('allowed_schemes' => array('https')))) {
|
||||
// TRANS: Client error displayed when an SSL logo URL is invalid.
|
||||
// TRANS: Client error displayed when a SSL logo URL is invalid.
|
||||
$this->clientError(_('Invalid SSL logo URL.'));
|
||||
}
|
||||
|
||||
@ -196,7 +196,7 @@ class SiteadminpanelAction extends AdminPanelAction
|
||||
|
||||
if (!Validate::number($values['site']['dupelimit'], array('min' => 1))) {
|
||||
// TRANS: Client error displayed trying to save site settings with a text limit below 1.
|
||||
$this->clientError(_("Dupe limit must be one or more seconds."));
|
||||
$this->clientError(_('Dupe limit must be one or more seconds.'));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -302,7 +302,7 @@ class SiteAdminPanelForm extends AdminForm
|
||||
_('Default language'),
|
||||
get_nice_language_list(),
|
||||
// TRANS: Dropdown title on site settings panel.
|
||||
_('Site language when autodetection from browser settings is not available'),
|
||||
_('The site language when autodetection from browser settings is not available.'),
|
||||
false, $this->value('language'));
|
||||
$this->unli();
|
||||
|
||||
@ -374,6 +374,6 @@ class SiteAdminPanelForm extends AdminForm
|
||||
'submit',
|
||||
null,
|
||||
// TRANS: Button title for saving site settings.
|
||||
_('Save site settings'));
|
||||
_('Save the site settings.'));
|
||||
}
|
||||
}
|
||||
|
@ -1,183 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Data class for counting greetings
|
||||
*
|
||||
* PHP version 5
|
||||
*
|
||||
* @category Data
|
||||
* @package StatusNet
|
||||
* @author Evan Prodromou <evan@status.net>
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl.html AGPLv3
|
||||
* @link http://status.net/
|
||||
*
|
||||
* StatusNet - the distributed open-source microblogging tool
|
||||
* Copyright (C) 2009, StatusNet, Inc.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
if (!defined('STATUSNET')) {
|
||||
exit(1);
|
||||
}
|
||||
|
||||
require_once INSTALLDIR . '/classes/Memcached_DataObject.php';
|
||||
|
||||
/**
|
||||
* Data class for counting greetings
|
||||
*
|
||||
* We use the DB_DataObject framework for data classes in StatusNet. Each
|
||||
* table maps to a particular data class, making it easier to manipulate
|
||||
* data.
|
||||
*
|
||||
* Data classes should extend Memcached_DataObject, the (slightly misnamed)
|
||||
* extension of DB_DataObject that provides caching, internationalization,
|
||||
* and other bits of good functionality to StatusNet-specific data classes.
|
||||
*
|
||||
* @category Action
|
||||
* @package StatusNet
|
||||
* @author Evan Prodromou <evan@status.net>
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl.html AGPLv3
|
||||
* @link http://status.net/
|
||||
*
|
||||
* @see DB_DataObject
|
||||
*/
|
||||
class User_greeting_count extends Memcached_DataObject
|
||||
{
|
||||
public $__table = 'user_greeting_count'; // table name
|
||||
public $user_id; // int(4) primary_key not_null
|
||||
public $greeting_count; // int(4)
|
||||
|
||||
/**
|
||||
* Get an instance by key
|
||||
*
|
||||
* This is a utility method to get a single instance with a given key value.
|
||||
*
|
||||
* @param string $k Key to use to lookup (usually 'user_id' for this class)
|
||||
* @param mixed $v Value to lookup
|
||||
*
|
||||
* @return User_greeting_count object found, or null for no hits
|
||||
*
|
||||
*/
|
||||
function staticGet($k, $v=null)
|
||||
{
|
||||
return Memcached_DataObject::staticGet('User_greeting_count', $k, $v);
|
||||
}
|
||||
|
||||
/**
|
||||
* return table definition for DB_DataObject
|
||||
*
|
||||
* DB_DataObject needs to know something about the table to manipulate
|
||||
* instances. This method provides all the DB_DataObject needs to know.
|
||||
*
|
||||
* @return array array of column definitions
|
||||
*/
|
||||
function table()
|
||||
{
|
||||
return array('user_id' => DB_DATAOBJECT_INT + DB_DATAOBJECT_NOTNULL,
|
||||
'greeting_count' => DB_DATAOBJECT_INT);
|
||||
}
|
||||
|
||||
/**
|
||||
* return key definitions for DB_DataObject
|
||||
*
|
||||
* DB_DataObject needs to know about keys that the table has, since it
|
||||
* won't appear in StatusNet's own keys list. In most cases, this will
|
||||
* simply reference your keyTypes() function.
|
||||
*
|
||||
* @return array list of key field names
|
||||
*/
|
||||
function keys()
|
||||
{
|
||||
return array_keys($this->keyTypes());
|
||||
}
|
||||
|
||||
/**
|
||||
* return key definitions for Memcached_DataObject
|
||||
*
|
||||
* Our caching system uses the same key definitions, but uses a different
|
||||
* method to get them. This key information is used to store and clear
|
||||
* cached data, so be sure to list any key that will be used for static
|
||||
* lookups.
|
||||
*
|
||||
* @return array associative array of key definitions, field name to type:
|
||||
* 'K' for primary key: for compound keys, add an entry for each component;
|
||||
* 'U' for unique keys: compound keys are not well supported here.
|
||||
*/
|
||||
function keyTypes()
|
||||
{
|
||||
return array('user_id' => 'K');
|
||||
}
|
||||
|
||||
/**
|
||||
* Magic formula for non-autoincrementing integer primary keys
|
||||
*
|
||||
* If a table has a single integer column as its primary key, DB_DataObject
|
||||
* assumes that the column is auto-incrementing and makes a sequence table
|
||||
* to do this incrementation. Since we don't need this for our class, we
|
||||
* overload this method and return the magic formula that DB_DataObject needs.
|
||||
*
|
||||
* @return array magic three-false array that stops auto-incrementing.
|
||||
*/
|
||||
function sequenceKey()
|
||||
{
|
||||
return array(false, false, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Increment a user's greeting count and return instance
|
||||
*
|
||||
* This method handles the ins and outs of creating a new greeting_count for a
|
||||
* user or fetching the existing greeting count and incrementing its value.
|
||||
*
|
||||
* @param integer $user_id ID of the user to get a count for
|
||||
*
|
||||
* @return User_greeting_count instance for this user, with count already incremented.
|
||||
*/
|
||||
static function inc($user_id)
|
||||
{
|
||||
$gc = User_greeting_count::staticGet('user_id', $user_id);
|
||||
|
||||
if (empty($gc)) {
|
||||
|
||||
$gc = new User_greeting_count();
|
||||
|
||||
$gc->user_id = $user_id;
|
||||
$gc->greeting_count = 1;
|
||||
|
||||
$result = $gc->insert();
|
||||
|
||||
if (!$result) {
|
||||
// TRANS: Exception thrown when the user greeting count could not be saved in the database.
|
||||
// TRANS: %d is a user ID (number).
|
||||
throw Exception(sprintf(_m("Could not save new greeting count for %d."),
|
||||
$user_id));
|
||||
}
|
||||
} else {
|
||||
$orig = clone($gc);
|
||||
|
||||
$gc->greeting_count++;
|
||||
|
||||
$result = $gc->update($orig);
|
||||
|
||||
if (!$result) {
|
||||
// TRANS: Exception thrown when the user greeting count could not be saved in the database.
|
||||
// TRANS: %d is a user ID (number).
|
||||
throw Exception(sprintf(_m('Could not increment greeting count for %d.'),
|
||||
$user_id));
|
||||
}
|
||||
}
|
||||
|
||||
return $gc;
|
||||
}
|
||||
}
|
209
plugins/EmailReminder/EmailReminderPlugin.php
Normal file
209
plugins/EmailReminder/EmailReminderPlugin.php
Normal file
@ -0,0 +1,209 @@
|
||||
<?php
|
||||
/**
|
||||
* StatusNet - the distributed open-source microblogging tool
|
||||
* Copyright (C) 2011, StatusNet, Inc.
|
||||
*
|
||||
* Plugin for sending email reminders about various things
|
||||
*
|
||||
* PHP version 5
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* @category OnDemand
|
||||
* @package StatusNet
|
||||
* @author Zach Copley <zach@status.net>
|
||||
* @copyright 2011 StatusNet, Inc.
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0
|
||||
* @link http://status.net/
|
||||
*/
|
||||
|
||||
if (!defined('STATUSNET')) {
|
||||
// This check helps protect against security problems;
|
||||
// your code file can't be executed directly from the web.
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Email reminder plugin
|
||||
*
|
||||
* @category Plugin
|
||||
* @package StatusNet
|
||||
* @author Zach Copley <zach@status.net>
|
||||
* @copyright 2011 StatusNet, Inc.
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0
|
||||
* @link http://status.net/
|
||||
*/
|
||||
class EmailReminderPlugin extends Plugin
|
||||
{
|
||||
/**
|
||||
* Set up email_reminder table
|
||||
*
|
||||
* @see Schema
|
||||
* @see ColumnDef
|
||||
*
|
||||
* @return boolean hook value; true means continue processing, false means stop.
|
||||
*/
|
||||
function onCheckSchema()
|
||||
{
|
||||
$schema = Schema::get();
|
||||
$schema->ensureTable('email_reminder', Email_reminder::schemaDef());
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Load related modules when needed
|
||||
*
|
||||
* @param string $cls Name of the class to be loaded
|
||||
*
|
||||
* @return boolean hook value; true means continue processing, false
|
||||
* means stop.
|
||||
*/
|
||||
function onAutoload($cls) {
|
||||
$base = dirname(__FILE__);
|
||||
$lower = strtolower($cls);
|
||||
|
||||
$files = array("$base/classes/$cls.php",
|
||||
"$base/lib/$lower.php");
|
||||
if (substr($lower, -6) == 'action') {
|
||||
$files[] = "$base/actions/" . substr($lower, 0, -6) . ".php";
|
||||
}
|
||||
foreach ($files as $file) {
|
||||
if (file_exists($file)) {
|
||||
include_once $file;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Register our queue handlers
|
||||
*
|
||||
* @param QueueManager $qm Current queue manager
|
||||
*
|
||||
* @return boolean hook value
|
||||
*/
|
||||
function onEndInitializeQueueManager($qm)
|
||||
{
|
||||
$qm->connect('siterem', 'SiteConfirmReminderHandler');
|
||||
$qm->connect('uregrem', 'UserConfirmRegReminderHandler');
|
||||
$qm->connect('uinvrem', 'UserInviteReminderHandler');
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
function onEndDocFileForTitle($title, $paths, &$filename)
|
||||
{
|
||||
if (empty($filename)) {
|
||||
$filename = dirname(__FILE__) . '/mail-src/' . $title;
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param type $object
|
||||
* @param type $subject
|
||||
* @param type $day
|
||||
*/
|
||||
static function sendReminder($type, $object, $subject, $day)
|
||||
{
|
||||
common_debug("QQQQQ sendReminder() enter ... ", __FILE__);
|
||||
|
||||
$title = "{$type}-{$day}";
|
||||
|
||||
common_debug("QQQQ title = {$title}", __FILE__);
|
||||
|
||||
// Record the fact that we sent a reminder
|
||||
if (self::sendReminderEmail($type, $object, $subject, $title)) {
|
||||
common_debug("Recording reminder record for {$object->address}", __FILE__);
|
||||
try {
|
||||
Email_reminder::recordReminder($type, $object, $day);
|
||||
} catch (Exception $e) {
|
||||
// oh noez
|
||||
common_log(LOG_ERR, $e->getMessage(), __FILE__);
|
||||
}
|
||||
}
|
||||
|
||||
common_debug("QQQQQ sendReminder() exit ... ", __FILE__);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param type $object
|
||||
* @param type $subject
|
||||
* @param type $title
|
||||
* @return type
|
||||
*/
|
||||
static function sendReminderEmail($type, $object, $subject, $title=null) {
|
||||
|
||||
$sitename = common_config('site', 'name');
|
||||
$recipients = array($object->address);
|
||||
$inviter = null;
|
||||
$inviterurl = null;
|
||||
|
||||
if ($type == UserInviteReminderHandler::INVITE_REMINDER) {
|
||||
$user = User::staticGet($object->user_id);
|
||||
if (!empty($user)) {
|
||||
$profile = $user->getProfile();
|
||||
$inviter = $profile->getBestName();
|
||||
$inviterUrl = $profile->profileurl;
|
||||
}
|
||||
}
|
||||
|
||||
$headers['From'] = mail_notify_from();
|
||||
$headers['To'] = trim($object->address);
|
||||
// TRANS: Subject for confirmation e-mail.
|
||||
// TRANS: %s is the StatusNet sitename.
|
||||
$headers['Subject'] = $subject;
|
||||
$headers['Content-Type'] = 'text/html; charset=UTF-8';
|
||||
|
||||
$confirmUrl = common_local_url('register', array('code' => $object->code));
|
||||
|
||||
$template = DocFile::forTitle($title, DocFile::mailPaths());
|
||||
|
||||
$body = $template->toHTML(
|
||||
array(
|
||||
'confirmurl' => $confirmUrl,
|
||||
'inviter' => $inviter,
|
||||
'inviterurl' => $inviterUrl
|
||||
// @todo private invitation message
|
||||
)
|
||||
);
|
||||
|
||||
return mail_send($recipients, $headers, $body);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param type $versions
|
||||
* @return type
|
||||
*/
|
||||
function onPluginVersion(&$versions)
|
||||
{
|
||||
$versions[] = array(
|
||||
'name' => 'EmailReminder',
|
||||
'version' => STATUSNET_VERSION,
|
||||
'author' => 'Zach Copley',
|
||||
'homepage' => 'http://status.net/wiki/Plugin:EmailReminder',
|
||||
'rawdescription' => _m('Send email reminders for various things.')
|
||||
);
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
154
plugins/EmailReminder/classes/Email_reminder.php
Normal file
154
plugins/EmailReminder/classes/Email_reminder.php
Normal file
@ -0,0 +1,154 @@
|
||||
<?php
|
||||
/**
|
||||
* StatusNet - the distributed open-source microblogging tool
|
||||
* Copyright (C) 2011, StatusNet, Inc.
|
||||
*
|
||||
* Data class for email reminders
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* @category Data
|
||||
* @package EmailReminder
|
||||
* @author Zach Copley <zach@status.net>
|
||||
* @copyright 2011 StatusNet, Inc.
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0
|
||||
* @link http://status.net/
|
||||
*/
|
||||
|
||||
class Email_reminder extends Managed_DataObject
|
||||
{
|
||||
const INVITE_REMINDER = 'invite'; // @todo Move this to the invite reminder handler
|
||||
|
||||
public $__table = 'email_reminder';
|
||||
|
||||
public $type; // type of reminder
|
||||
public $code; // confirmation code
|
||||
public $days; // number of days after code was created
|
||||
public $sent; // timestamp
|
||||
public $created; // timestamp
|
||||
public $modified; // timestamp
|
||||
|
||||
/**
|
||||
* Get an instance by key
|
||||
*
|
||||
* This is a utility method to get a single instance with a given key value.
|
||||
*
|
||||
* @param string $k Key to use to lookup
|
||||
* @param mixed $v Value to lookup
|
||||
*
|
||||
* @return QnA_Answer object found, or null for no hits
|
||||
*
|
||||
*/
|
||||
function staticGet($k, $v=null)
|
||||
{
|
||||
return Memcached_DataObject::staticGet('email_reminder', $k, $v);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param type $type
|
||||
* @param type $confirm
|
||||
* @param type $day
|
||||
* @return type
|
||||
*/
|
||||
static function needsReminder($type, $confirm, $days) {
|
||||
|
||||
$reminder = new Email_reminder();
|
||||
$reminder->type = $type;
|
||||
$reminder->code = $confirm->code;
|
||||
$reminder->days = $days;
|
||||
|
||||
$result = $reminder->find(true);
|
||||
|
||||
if (empty($result)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param type $type
|
||||
* @param type $confirm
|
||||
* @param type $day
|
||||
* @return type
|
||||
*/
|
||||
static function recordReminder($type, $confirm, $days) {
|
||||
|
||||
$reminder = new Email_reminder();
|
||||
$reminder->type = $type;
|
||||
$reminder->code = $confirm->code;
|
||||
$reminder->days = $days;
|
||||
$reminder->sent = $reminder->created = common_sql_now();
|
||||
$result = $reminder->insert();
|
||||
|
||||
if (empty($result)) {
|
||||
common_log_db_error($reminder, 'INSERT', __FILE__);
|
||||
throw new ServerException(
|
||||
_m('Database error inserting reminder record.')
|
||||
);
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Data definition for email reminders
|
||||
*/
|
||||
public static function schemaDef()
|
||||
{
|
||||
return array(
|
||||
'description' => 'Record of email reminders that have been sent',
|
||||
'fields' => array(
|
||||
'type' => array(
|
||||
'type' => 'varchar',
|
||||
'length' => 255,
|
||||
'not null' => true,
|
||||
'description' => 'type of reminder'
|
||||
),
|
||||
'code' => array(
|
||||
'type' => 'varchar',
|
||||
'not null' => 'true',
|
||||
'length' => 255,
|
||||
'description' => 'confirmation code'
|
||||
),
|
||||
'days' => array(
|
||||
'type' => 'int',
|
||||
'not null' => 'true',
|
||||
'description' => 'number of days since code creation'
|
||||
),
|
||||
'sent' => array(
|
||||
'type' => 'datetime',
|
||||
'not null' => true,
|
||||
'description' => 'Date and time the reminder was sent'
|
||||
),
|
||||
'created' => array(
|
||||
'type' => 'datetime',
|
||||
'not null' => true,
|
||||
'description' => 'Date and time the record was created'
|
||||
),
|
||||
'modified' => array(
|
||||
'type' => 'timestamp',
|
||||
'not null' => true,
|
||||
'description' => 'Date and time the record was last modified'
|
||||
),
|
||||
),
|
||||
'primary key' => array('type', 'code', 'days'),
|
||||
'indexes' => array(
|
||||
'sent_idx' => array('sent'),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
112
plugins/EmailReminder/lib/siteconfirmreminderhandler.php
Normal file
112
plugins/EmailReminder/lib/siteconfirmreminderhandler.php
Normal file
@ -0,0 +1,112 @@
|
||||
<?php
|
||||
/*
|
||||
* StatusNet - the distributed open-source microblogging tool
|
||||
*
|
||||
* Handler for reminder queue items which send reminder emails to all users
|
||||
* we would like to complete a given process (e.g.: registration).
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* @category Email
|
||||
* @package StatusNet
|
||||
* @author Zach Copley <zach@status.net>
|
||||
* @copyright 2011 StatusNet, Inc.
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0
|
||||
* @link http://status.net/
|
||||
*/
|
||||
|
||||
if (!defined('STATUSNET')) {
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handler for reminder queue items which send reminder emails to all users
|
||||
* we would like to complete a given process (e.g.: registration)
|
||||
*
|
||||
* @category Email
|
||||
* @package StatusNet
|
||||
* @author Zach Copley <zach@status.net>
|
||||
* @copyright 2011 StatusNet, Inc.
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0
|
||||
* @link http://status.net/
|
||||
*/
|
||||
class SiteConfirmReminderHandler extends QueueHandler
|
||||
{
|
||||
/**
|
||||
* Return transport keyword which identifies items this queue handler
|
||||
* services; must be defined for all subclasses.
|
||||
*
|
||||
* Must be 8 characters or less to fit in the queue_item database.
|
||||
* ex "email", "jabber", "sms", "irc", ...
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
function transport()
|
||||
{
|
||||
return 'siterem';
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle the site
|
||||
*
|
||||
* @param string $reminderType type of reminder to send
|
||||
* @return boolean true on success, false on failure
|
||||
*/
|
||||
function handle($reminderType)
|
||||
{
|
||||
$qm = QueueManager::get();
|
||||
|
||||
try {
|
||||
switch($reminderType) {
|
||||
case UserConfirmRegReminderHandler::REGISTER_REMINDER:
|
||||
$confirm = new Confirm_address();
|
||||
$confirm->address_type = $object;
|
||||
$confirm->find();
|
||||
while ($confirm->fetch()) {
|
||||
try {
|
||||
$qm->enqueue($confirm, 'uregrem');
|
||||
} catch (Exception $e) {
|
||||
common_log(LOG_WARNING, $e->getMessage());
|
||||
continue;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case UserInviteReminderHandler::INVITE_REMINDER:
|
||||
$invitation = new Invitation();
|
||||
$invitation->find();
|
||||
while ($invitation->fetch()) {
|
||||
try {
|
||||
$qm->enqueue($invitation, 'uinvrem');
|
||||
} catch (Exception $e) {
|
||||
common_log(LOG_WARNING, $e->getMessage());
|
||||
continue;
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
// WTF?
|
||||
common_log(
|
||||
LOG_ERR,
|
||||
"Received unknown confirmation address type",
|
||||
__FILE__
|
||||
);
|
||||
}
|
||||
} catch (Exception $e) {
|
||||
common_log(LOG_ERR, $e->getMessage());
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
126
plugins/EmailReminder/lib/userconfirmregreminderhandler.php
Normal file
126
plugins/EmailReminder/lib/userconfirmregreminderhandler.php
Normal file
@ -0,0 +1,126 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* StatusNet - the distributed open-source microblogging tool
|
||||
*
|
||||
* Handler for queue items of type 'uregem' - sends email registration
|
||||
* confirmation reminders to a particular user.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* @category Email
|
||||
* @package StatusNet
|
||||
* @author Zach Copley <zach@status.net>
|
||||
* @copyright 2011 StatusNet, Inc.
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0
|
||||
* @link http://status.net/
|
||||
*/
|
||||
if (!defined('STATUSNET')) {
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handler for queue items of type 'uregrem'
|
||||
*
|
||||
* @category Email
|
||||
* @package StatusNet
|
||||
* @author Zach Copley <zach@status.net>
|
||||
* @copyright 2011 StatusNet, Inc.
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0
|
||||
* @link http://status.net/
|
||||
*/
|
||||
class UserConfirmRegReminderHandler extends UserReminderHandler {
|
||||
|
||||
const REGISTER_REMINDER = 'register';
|
||||
|
||||
/**
|
||||
* Return transport keyword which identifies items this queue handler
|
||||
* services; must be defined for all subclasses.
|
||||
*
|
||||
* Must be 8 characters or less to fit in the queue_item database.
|
||||
* ex "email", "jabber", "sms", "irc", ...
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
function transport() {
|
||||
return 'uregrem';
|
||||
}
|
||||
|
||||
/**
|
||||
* Send an email registration confirmation reminder until the user
|
||||
* confirms her registration. We'll send a reminder after one day,
|
||||
* three days, and a full week.
|
||||
*
|
||||
* @todo abstract this bit further
|
||||
*
|
||||
* @param Confirm_address $confirm
|
||||
* @return boolean success value
|
||||
*/
|
||||
function sendNextReminder($confirm)
|
||||
{
|
||||
$regDate = strtotime($confirm->modified); // Seems like my best bet
|
||||
$now = strtotime('now');
|
||||
|
||||
// Days since registration
|
||||
$days = ($now - $regDate) / 86499; // 60*60*24 = 86499
|
||||
|
||||
// Welcome to one of the ugliest switch statement I've ever written
|
||||
|
||||
switch($days) {
|
||||
case ($days > 1 && $days < 2):
|
||||
if (Email_reminder::needsReminder(self::REGISTER_REMINDER, $confirm, 1)) {
|
||||
common_log(LOG_INFO, "Sending one day registration confirmation reminder to {$confirm->address}", __FILE__);
|
||||
$subject = _m("Reminder - please confirm your registration!");
|
||||
return EmailReminderPlugin::sendReminder(
|
||||
self::REGISTER_REMINDER,
|
||||
$confirm,
|
||||
$subject,
|
||||
1);
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
case ($days > 3 && $days < 4):
|
||||
if (Email_reminder::needsReminder(self::REGISTER_REMINDER, $confirm, 3)) {
|
||||
common_log(LOG_INFO, "Sending three day registration confirmation reminder to {$confirm->address}", __FILE__);
|
||||
$subject = _m("Second reminder - please confirm your registration!");
|
||||
return EmailReminderPlugin::sendReminder(
|
||||
self::REGISTER_REMINDER,
|
||||
$confirm,
|
||||
$subject,
|
||||
3
|
||||
);
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
case ($days > 7 && $days < 8):
|
||||
if (Email_reminder::needsReminder(self::REGISTER_REMINDER, $confirm, 7)) {
|
||||
common_log(LOG_INFO, "Sending one week registration confirmation reminder to {$confirm->address}", __FILE__);
|
||||
$subject = _m("Final reminder - please confirm your registration!");
|
||||
return EmailReminderPlugin::sendReminder(
|
||||
self::REGISTER_REMINDER,
|
||||
$confirm,
|
||||
$subject,
|
||||
7
|
||||
);
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
110
plugins/EmailReminder/lib/userinvitereminderhandler.php
Normal file
110
plugins/EmailReminder/lib/userinvitereminderhandler.php
Normal file
@ -0,0 +1,110 @@
|
||||
<?php
|
||||
/**
|
||||
* StatusNet - the distributed open-source microblogging tool
|
||||
*
|
||||
* Handler for queue items of type 'uinvrem' - sends an email reminder to
|
||||
* an email address of someone who has been invited to the site
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* @category Email
|
||||
* @package StatusNet
|
||||
* @author Zach Copley <zach@status.net>
|
||||
* @copyright 2011 StatusNet, Inc.
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0
|
||||
* @link http://status.net/
|
||||
*/
|
||||
if (!defined('STATUSNET')) {
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handler for queue items of type 'uinvrem' (user invite reminder)
|
||||
*
|
||||
* @category Email
|
||||
* @package StatusNet
|
||||
* @author Zach Copley <zach@status.net>
|
||||
* @copyright 2011 StatusNet, Inc.
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0
|
||||
* @link http://status.net/
|
||||
*/
|
||||
class UserInviteReminderHandler extends UserReminderHandler {
|
||||
|
||||
const INVITE_REMINDER = 'invite';
|
||||
|
||||
/**
|
||||
* Return transport keyword which identifies items this queue handler
|
||||
* services; must be defined for all subclasses.
|
||||
*
|
||||
* Must be 8 characters or less to fit in the queue_item database.
|
||||
* ex "email", "jabber", "sms", "irc", ...
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
function transport() {
|
||||
return 'uinvrem';
|
||||
}
|
||||
|
||||
/**
|
||||
* Send an invitation reminder. We'll send one after one day, and then
|
||||
* one after three days.
|
||||
*
|
||||
* @todo Abstract this stuff further
|
||||
*
|
||||
* @param Invitation $invitation
|
||||
* @return boolean success value
|
||||
*/
|
||||
function sendNextReminder($invitation)
|
||||
{
|
||||
$invDate = strtotime($invitation->created);
|
||||
$now = strtotime('now');
|
||||
|
||||
// Days since first invitation was sent
|
||||
$days = ($now - $invDate) / 86499; // 60*60*24 = 86499
|
||||
|
||||
$siteName = common_config('site', 'name');
|
||||
|
||||
switch($days) {
|
||||
case ($days > 1 && $days < 2):
|
||||
if (Email_reminder::needsReminder(self::INVITE_REMINDER, $invitation, 1)) {
|
||||
common_log(LOG_INFO, "Sending one day invitation reminder to {$invitation->address}", __FILE__);
|
||||
$subject = _m("Reminder - You have been invited to join {$siteName}!");
|
||||
return EmailReminderPlugin::sendReminder(
|
||||
self::INVITE_REMINDER,
|
||||
$invitation,
|
||||
$subject,
|
||||
1);
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
case ($days > 3 && $days < 4):
|
||||
if (Email_reminder::needsReminder(self::INVITE_REMINDER, $invitation, 3)) {
|
||||
common_log(LOG_INFO, "Sending three day invitation reminder to {$invitation->address}", __FILE__);
|
||||
$subject = _m("Final reminder - you have been invited to join {$siteName}!");
|
||||
return EmailReminderPlugin::sendReminder(
|
||||
self::INVITE_REMINDER,
|
||||
$invitation,
|
||||
$subject,
|
||||
3
|
||||
);
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
63
plugins/EmailReminder/lib/userreminderhandler.php
Normal file
63
plugins/EmailReminder/lib/userreminderhandler.php
Normal file
@ -0,0 +1,63 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* StatusNet - the distributed open-source microblogging tool
|
||||
*
|
||||
* Base handler for email reminders
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* @category Email
|
||||
* @package StatusNet
|
||||
* @author Zach Copley <zach@status.net>
|
||||
* @copyright 2011 StatusNet, Inc.
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0
|
||||
* @link http://status.net/
|
||||
*/
|
||||
if (!defined('STATUSNET')) {
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handler for email reminder queue items
|
||||
*
|
||||
* @category Email
|
||||
* @package StatusNet
|
||||
* @author Zach Copley <zach@status.net>
|
||||
* @copyright 2011 StatusNet, Inc.
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0
|
||||
* @link http://status.net/
|
||||
*/
|
||||
class UserReminderHandler extends QueueHandler {
|
||||
|
||||
/**
|
||||
* Send the next email reminder to the confirm address
|
||||
*
|
||||
* @param Confirm_address $confirm the confirmation email/code
|
||||
* @return boolean true on success, false on failure
|
||||
*/
|
||||
function handle($confirm) {
|
||||
return $this->sendNextReminder($confirm);
|
||||
}
|
||||
|
||||
/**
|
||||
* Send the next reminder if one needs sending.
|
||||
* Subclasses must override
|
||||
*
|
||||
* @param Confirm_address $confirm the confirmation email/code
|
||||
*/
|
||||
function sendNextReminder($confirm)
|
||||
{
|
||||
}
|
||||
}
|
26
plugins/EmailReminder/mail-src/invite-1
Normal file
26
plugins/EmailReminder/mail-src/invite-1
Normal file
@ -0,0 +1,26 @@
|
||||
First reminder...
|
||||
|
||||
%%arg.inviter%% has invited you to join them on %%site.name%%.
|
||||
|
||||
%%site.name%% is a micro-blogging service that lets you keep
|
||||
up-to-date with people you know and people who interest you.
|
||||
|
||||
You can also share news about yourself, your thoughts, or your life
|
||||
online with people who know about you.
|
||||
|
||||
It's great for meeting new people who share your interests.
|
||||
|
||||
You can see %%arg.inviter%%'s profile page on %%site.name%% here:
|
||||
|
||||
> [%%arg.inviterurl%%](%%arg.inviterurl%%)
|
||||
|
||||
If you'd like to try the service, click on the link below to accept
|
||||
the invitation.
|
||||
|
||||
> [%%arg.confirmurl%%](%%arg.confirmurl%%)
|
||||
|
||||
If not, you can ignore this message. Thanks for your patience and your time.
|
||||
|
||||
Sincerely,
|
||||
|
||||
%%site.name%%
|
26
plugins/EmailReminder/mail-src/invite-3
Normal file
26
plugins/EmailReminder/mail-src/invite-3
Normal file
@ -0,0 +1,26 @@
|
||||
Second and final reminder...
|
||||
|
||||
%%arg.inviter%% has invited you to join them on %%site.name%%.
|
||||
|
||||
%%site.name%% is a micro-blogging service that lets you keep
|
||||
up-to-date with people you know and people who interest you.
|
||||
|
||||
You can also share news about yourself, your thoughts, or your life
|
||||
online with people who know about you.
|
||||
|
||||
It's great for meeting new people who share your interests.
|
||||
|
||||
You can see %%arg.inviter%%'s profile page on %%site.name%% here:
|
||||
|
||||
> [%%arg.inviterurl%%](%%arg.inviterurl%%)
|
||||
|
||||
If you'd like to try the service, click on the link below to accept
|
||||
the invitation.
|
||||
|
||||
> [%%arg.confirmurl%%](%%arg.confirmurl%%)
|
||||
|
||||
If not, you can ignore this message. Thanks for your patience and your time.
|
||||
|
||||
Sincerely,
|
||||
|
||||
%%site.name%%
|
9
plugins/EmailReminder/mail-src/register-1
Normal file
9
plugins/EmailReminder/mail-src/register-1
Normal file
@ -0,0 +1,9 @@
|
||||
Hey, it's been a whole day!
|
||||
|
||||
Someone (probably you) has requested an account on %%site.name%% using this email address.
|
||||
|
||||
To confirm the address, click the following URL or copy it into the address bar of your browser.
|
||||
|
||||
> [%%arg.confirmurl%%](%%arg.confirmurl%%)
|
||||
|
||||
If it was not you, you can safely ignore this message.
|
9
plugins/EmailReminder/mail-src/register-3
Normal file
9
plugins/EmailReminder/mail-src/register-3
Normal file
@ -0,0 +1,9 @@
|
||||
Hey, it's been three days!!
|
||||
|
||||
Someone (probably you) has requested an account on %%site.name%% using this email address.
|
||||
|
||||
To confirm the address, click the following URL or copy it into the address bar of your browser.
|
||||
|
||||
> [%%arg.confirmurl%%](%%arg.confirmurl%%)
|
||||
|
||||
If it was not you, you can safely ignore this message.
|
9
plugins/EmailReminder/mail-src/register-7
Normal file
9
plugins/EmailReminder/mail-src/register-7
Normal file
@ -0,0 +1,9 @@
|
||||
IT'S BEEN A WHOLE WEEK! Final reminder...
|
||||
|
||||
Someone (probably you) has requested an account on %%site.name%% using this email address.
|
||||
|
||||
To confirm the address, click the following URL or copy it into the address bar of your browser.
|
||||
|
||||
> [%%arg.confirmurl%%](%%arg.confirmurl%%)
|
||||
|
||||
If it was not you, you can safely ignore this message.
|
1
plugins/EmailReminder/scripts/cron.sample
Normal file
1
plugins/EmailReminder/scripts/cron.sample
Normal file
@ -0,0 +1 @@
|
||||
* * * * * /opt/local/bin/php /path/to/statusnet/plugins/EmailReminder/scripts/sendemailreminder.php -t all -a -q > /tmp/cron.log
|
132
plugins/EmailReminder/scripts/sendemailreminder.php
Normal file
132
plugins/EmailReminder/scripts/sendemailreminder.php
Normal file
@ -0,0 +1,132 @@
|
||||
#!/usr/bin/env php
|
||||
<?php
|
||||
/*
|
||||
* StatusNet - a distributed open-source microblogging tool
|
||||
* Copyright (C) 2011, StatusNet, Inc.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
define('INSTALLDIR', realpath(dirname(__FILE__) . '/../../..'));
|
||||
|
||||
$shortoptions = 't:e:au';
|
||||
$longoptions = array('type=', 'email=', 'all', 'universe');
|
||||
|
||||
$helptext = <<<END_OF_SENDEMAILREMINDER_HELP
|
||||
sendemailreminder.php [options]
|
||||
Send an email summary of the inbox to users
|
||||
|
||||
-t --type type of reminder to send (register | invite | all)
|
||||
-e --email email address to send reminder to
|
||||
-a --all send reminder to all addresses
|
||||
-u --universe send reminder to all addresses on all sites
|
||||
|
||||
END_OF_SENDEMAILREMINDER_HELP;
|
||||
|
||||
require_once INSTALLDIR . '/scripts/commandline.inc';
|
||||
|
||||
$quiet = have_option('q', 'quiet');
|
||||
|
||||
$types = array(
|
||||
// registration confirmation reminder
|
||||
'register' => array(
|
||||
'type' => 'register',
|
||||
'className' => 'Confirm_address',
|
||||
'utransport' => 'uregrem'
|
||||
),
|
||||
// invitation confirmation reminder
|
||||
'invite' => array(
|
||||
'type' => 'invite',
|
||||
'className' => 'Invitation',
|
||||
'utransport' => 'uinvrem'
|
||||
)
|
||||
// ... add more here
|
||||
);
|
||||
|
||||
$type = null;
|
||||
|
||||
if (have_option('t', 'type')) {
|
||||
$type = trim(get_option_value('t', 'type'));
|
||||
if (!in_array($type, array_keys($types)) && $type !== 'all') {
|
||||
print _m("Unknown reminder type: {$type}.\n");
|
||||
exit(1);
|
||||
}
|
||||
} else {
|
||||
show_help();
|
||||
exit(1);
|
||||
}
|
||||
|
||||
$reminders = array();
|
||||
|
||||
switch($type) {
|
||||
case 'register':
|
||||
$reminders[] = $types['register'];
|
||||
break;
|
||||
case 'invite':
|
||||
$reminders[] = $types['invite'];
|
||||
break;
|
||||
case 'all':
|
||||
$reminders = $types;
|
||||
break;
|
||||
}
|
||||
|
||||
if (have_option('u', 'universe')) {
|
||||
$sn = new Status_network();
|
||||
if ($sn->find()) {
|
||||
while ($sn->fetch()) {
|
||||
$server = $sn->getServerName();
|
||||
StatusNet::init($server);
|
||||
// Different queue manager, maybe!
|
||||
$qm = QueueManager::get();
|
||||
foreach ($reminders as $reminder) {
|
||||
extract($reminder);
|
||||
$qm->enqueue($type, 'siterem');
|
||||
if (!$quiet) { print "Sent pending {$type} reminders to all unconfirmed addresses in the known universe.\n"; }
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$qm = QueueManager::get();
|
||||
try {
|
||||
// enqueue reminder for specific email address or all unconfirmed addresses
|
||||
if (have_option('e', 'email')) {
|
||||
$address = trim(get_option_value('e', 'email'));
|
||||
foreach ($reminders as $reminder) {
|
||||
// real bad voodoo here
|
||||
extract($reminder);
|
||||
$confirm = new $className;
|
||||
$confirm->address = $address;
|
||||
$result = $confirm->find(true);
|
||||
if (empty($result)) {
|
||||
throw new Exception("No confirmation code found for {$address}.");
|
||||
}
|
||||
$qm->enqueue($confirm, $utransport);
|
||||
if (!$quiet) { print "Sent all pending {$type} reminder to {$address}.\n"; }
|
||||
}
|
||||
} else if (have_option('a', 'all')) {
|
||||
foreach ($reminders as $reminder) {
|
||||
extract($reminder);
|
||||
$qm->enqueue($type, 'siterem');
|
||||
if (!$quiet) { print "Sent pending {$type} reminders to all unconfirmed addresses on the site.\n"; }
|
||||
}
|
||||
} else {
|
||||
show_help();
|
||||
exit(1);
|
||||
}
|
||||
} catch (Exception $e) {
|
||||
if (!$quiet) { print $e->getMessage() . "\n"; }
|
||||
common_log(LOG_ERR, $e->getMessage(), __FILE__);
|
||||
exit(1);
|
||||
}
|
||||
}
|
@ -117,8 +117,8 @@ class XCachePlugin extends Plugin
|
||||
'author' => 'Craig Andrews',
|
||||
'homepage' => 'http://status.net/wiki/Plugin:XCache',
|
||||
'rawdescription' =>
|
||||
// TRANS: Plugin description.
|
||||
_m('Use the <a href="http://xcache.lighttpd.net/">XCache</a> variable cache to cache query results.'));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,4 +1,5 @@
|
||||
The XMPP plugin allows users to send and receive notices over the XMPP/Jabber/GTalk network.
|
||||
The XMPP plugin allows users to send and receive notices over the
|
||||
XMPP/Jabber/GTalk network.
|
||||
|
||||
Installation
|
||||
============
|
||||
@ -6,9 +7,10 @@ add "addPlugin('xmpp',
|
||||
array('setting'=>'value', 'setting2'=>'value2', ...);"
|
||||
to the bottom of your config.php
|
||||
|
||||
The daemon included with this plugin must be running. It will be started by
|
||||
the plugin along with their other daemons when you run scripts/startdaemons.sh.
|
||||
See the StatusNet README for more about queuing and daemons.
|
||||
The daemon included with this plugin must be running. It will be
|
||||
started by the plugin along with their other daemons when you run
|
||||
scripts/startdaemons.sh. See the StatusNet README for more about queuing and
|
||||
daemons.
|
||||
|
||||
Settings
|
||||
========
|
||||
@ -32,4 +34,3 @@ addPlugin('xmpp', array(
|
||||
'password'=>'...',
|
||||
'public'=>array('bob@aol.com', 'sue@google.com')
|
||||
));
|
||||
|
||||
|
@ -44,7 +44,6 @@ if (!defined('STATUSNET')) {
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0
|
||||
* @link http://status.net/
|
||||
*/
|
||||
|
||||
class XmppPlugin extends ImPlugin
|
||||
{
|
||||
public $server = null;
|
||||
@ -59,22 +58,22 @@ class XmppPlugin extends ImPlugin
|
||||
public $transport = 'xmpp';
|
||||
|
||||
function getDisplayName(){
|
||||
// TRANS: Plugin display name.
|
||||
return _m('XMPP/Jabber/GTalk');
|
||||
}
|
||||
|
||||
/**
|
||||
* Splits a Jabber ID (JID) into node, domain, and resource portions.
|
||||
*
|
||||
*
|
||||
* Based on validation routine submitted by:
|
||||
* @copyright 2009 Patrick Georgi <patrick@georgi-clan.de>
|
||||
* @license Licensed under ISC-L, which is compatible with everything else that keeps the copyright notice intact.
|
||||
* @license Licensed under ISC-L, which is compatible with everything else that keeps the copyright notice intact.
|
||||
*
|
||||
* @param string $jid string to check
|
||||
*
|
||||
* @return array with "node", "domain", and "resource" indices
|
||||
* @throws Exception if input is not valid
|
||||
*/
|
||||
|
||||
protected function splitJid($jid)
|
||||
{
|
||||
$chars = '';
|
||||
@ -102,11 +101,11 @@ class XmppPlugin extends ImPlugin
|
||||
$chars .= "\x{340}\x{341}\x{200e}\x{200f}\x{202a}-\x{202e}\x{206a}-\x{206f}";
|
||||
/* C9 - Tagging characters */
|
||||
$chars .= "\x{e0001}\x{e0020}-\x{e007f}";
|
||||
|
||||
|
||||
/* Nodeprep forbids some more characters */
|
||||
$nodeprepchars = $chars;
|
||||
$nodeprepchars .= "\x{22}\x{26}\x{27}\x{2f}\x{3a}\x{3c}\x{3e}\x{40}";
|
||||
|
||||
|
||||
$parts = explode("/", $jid, 2);
|
||||
if (count($parts) > 1) {
|
||||
$resource = $parts[1];
|
||||
@ -117,10 +116,11 @@ class XmppPlugin extends ImPlugin
|
||||
} else {
|
||||
$resource = null;
|
||||
}
|
||||
|
||||
|
||||
$node = explode("@", $parts[0]);
|
||||
if ((count($node) > 2) || (count($node) == 0)) {
|
||||
throw new Exception("Invalid JID: too many @s");
|
||||
// TRANS: Exception thrown when using too many @ signs in a Jabber ID.
|
||||
throw new Exception(_m('Invalid JID: too many @s.'));
|
||||
} else if (count($node) == 1) {
|
||||
$domain = $node[0];
|
||||
$node = null;
|
||||
@ -128,47 +128,57 @@ class XmppPlugin extends ImPlugin
|
||||
$domain = $node[1];
|
||||
$node = $node[0];
|
||||
if ($node == '') {
|
||||
throw new Exception("Invalid JID: @ but no node");
|
||||
// TRANS: Exception thrown when using @ sign not followed by a Jabber ID.
|
||||
throw new Exception(_m('Invalid JID: @ but no node'));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Length limits per http://xmpp.org/rfcs/rfc3920.html#addressing
|
||||
if ($node !== null) {
|
||||
if (strlen($node) > 1023) {
|
||||
throw new Exception("Invalid JID: node too long.");
|
||||
// TRANS: Exception thrown when using too long a Jabber ID (>1023).
|
||||
throw new Exception(_m('Invalid JID: node too long.'));
|
||||
}
|
||||
if (preg_match("/[".$nodeprepchars."]/u", $node)) {
|
||||
throw new Exception("Invalid JID node '$node'");
|
||||
// TRANS: Exception thrown when using an invalid Jabber ID.
|
||||
// TRANS: %s is the invalid Jabber ID.
|
||||
throw new Exception(sprintf(_m('Invalid JID node "%s".'),$node));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (strlen($domain) > 1023) {
|
||||
throw new Exception("Invalid JID: domain too long.");
|
||||
// TRANS: Exception thrown when using too long a Jabber domain (>1023).
|
||||
throw new Exception(_m('Invalid JID: domain too long.'));
|
||||
}
|
||||
if (!common_valid_domain($domain)) {
|
||||
throw new Exception("Invalid JID domain name '$domain'");
|
||||
// TRANS: Exception thrown when using an invalid Jabber domain name.
|
||||
// TRANS: %s is the invalid domain name.
|
||||
throw new Exception(sprintf(_m('Invalid JID domain name "%s".'),$domain));
|
||||
}
|
||||
|
||||
|
||||
if ($resource !== null) {
|
||||
if (strlen($resource) > 1023) {
|
||||
// TRANS: Exception thrown when using too long a resource (>1023).
|
||||
throw new Exception("Invalid JID: resource too long.");
|
||||
}
|
||||
if (preg_match("/[".$chars."]/u", $resource)) {
|
||||
throw new Exception("Invalid JID resource '$resource'");
|
||||
// TRANS: Exception thrown when using an invalid Jabber resource.
|
||||
// TRANS: %s is the invalid resource.
|
||||
throw new Exception(sprintf(_m('Invalid JID resource "%s".'),$resource));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return array('node' => is_null($node) ? null : mb_strtolower($node),
|
||||
'domain' => is_null($domain) ? null : mb_strtolower($domain),
|
||||
'resource' => $resource);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Checks whether a string is a syntactically valid Jabber ID (JID),
|
||||
* either with or without a resource.
|
||||
*
|
||||
*
|
||||
* Note that a bare domain can be a valid JID.
|
||||
*
|
||||
*
|
||||
* @param string $jid string to check
|
||||
* @param bool $check_domain whether we should validate that domain...
|
||||
*
|
||||
@ -188,15 +198,15 @@ class XmppPlugin extends ImPlugin
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Checks whether a string is a syntactically valid base Jabber ID (JID).
|
||||
* A base JID won't include a resource specifier on the end; since we
|
||||
* take it off when reading input we can't really use them reliably
|
||||
* to direct outgoing messages yet (sorry guys!)
|
||||
*
|
||||
*
|
||||
* Note that a bare domain can be a valid JID.
|
||||
*
|
||||
*
|
||||
* @param string $jid string to check
|
||||
* @param bool $check_domain whether we should validate that domain...
|
||||
*
|
||||
@ -225,7 +235,6 @@ class XmppPlugin extends ImPlugin
|
||||
*
|
||||
* @return string an equivalent JID in normalized (lowercase) form
|
||||
*/
|
||||
|
||||
function normalize($jid)
|
||||
{
|
||||
try {
|
||||
@ -308,7 +317,7 @@ class XmppPlugin extends ImPlugin
|
||||
|
||||
function microiduri($screenname)
|
||||
{
|
||||
return 'xmpp:' . $screenname;
|
||||
return 'xmpp:' . $screenname;
|
||||
}
|
||||
|
||||
function sendMessage($screenname, $body)
|
||||
@ -320,7 +329,7 @@ class XmppPlugin extends ImPlugin
|
||||
{
|
||||
$msg = $this->formatNotice($notice);
|
||||
$entry = $this->format_entry($notice);
|
||||
|
||||
|
||||
$this->queuedConnection()->message($screenname, $msg, 'chat', null, $entry);
|
||||
return true;
|
||||
}
|
||||
@ -333,7 +342,6 @@ class XmppPlugin extends ImPlugin
|
||||
*
|
||||
* @return string Extra information (Atom, HTML, addresses) in string format
|
||||
*/
|
||||
|
||||
function format_entry($notice)
|
||||
{
|
||||
$profile = $notice->getProfile();
|
||||
@ -355,6 +363,7 @@ class XmppPlugin extends ImPlugin
|
||||
$xs->element('a', array(
|
||||
'href'=>common_local_url('conversation',
|
||||
array('id' => $notice->conversation)).'#notice-'.$notice->id),
|
||||
// TRANS: Link description to notice in conversation.
|
||||
// TRANS: %s is a notice ID.
|
||||
sprintf(_m('[%s]'),$notice->id));
|
||||
$xs->elementEnd('body');
|
||||
@ -380,14 +389,14 @@ class XmppPlugin extends ImPlugin
|
||||
}
|
||||
|
||||
$this->handleIncoming($from, $pl['body']);
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Build a queue-proxied XMPP interface object. Any outgoing messages
|
||||
* will be run back through us for enqueing rather than sent directly.
|
||||
*
|
||||
*
|
||||
* @return Queued_XMPP
|
||||
* @throws Exception if server settings are invalid.
|
||||
*/
|
||||
|
@ -29,16 +29,14 @@ if (!defined('STATUSNET') && !defined('LACONICA')) { exit(1); }
|
||||
* In a multi-site queuedaemon.php run, one connection will be instantiated
|
||||
* for each site being handled by the current process that has XMPP enabled.
|
||||
*/
|
||||
|
||||
class XmppManager extends ImManager
|
||||
{
|
||||
protected $lastping = null;
|
||||
protected $pingid = null;
|
||||
|
||||
public $conn = null;
|
||||
|
||||
|
||||
const PING_INTERVAL = 120;
|
||||
|
||||
|
||||
/**
|
||||
* Initialize connection to server.
|
||||
@ -114,7 +112,7 @@ class XmppManager extends ImManager
|
||||
*
|
||||
* Side effect: kills process on exception from XMPP library.
|
||||
*
|
||||
* @fixme non-dying error handling
|
||||
* @todo FIXME: non-dying error handling
|
||||
*/
|
||||
public function idle($timeout=0)
|
||||
{
|
||||
@ -165,6 +163,7 @@ class XmppManager extends ImManager
|
||||
}
|
||||
|
||||
$this->conn->processUntil('session_start');
|
||||
// TRANS: Presence announcement for XMPP.
|
||||
$this->send_presence(_m('Send me a message to post a notice'), 'available', null, 'available', 100);
|
||||
}
|
||||
return $this->conn;
|
||||
@ -204,6 +203,7 @@ class XmppManager extends ImManager
|
||||
common_log(LOG_NOTICE, 'XMPP reconnected');
|
||||
|
||||
$this->conn->processUntil('session_start');
|
||||
// TRANS: Message for XMPP reconnect.
|
||||
$this->send_presence(_m('Send me a message to post a notice'), 'available', null, 'available', 100);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user