[REALTIME] Reviewed both the superclass and its dist plugins
This commit is contained in:
parent
52800c3a65
commit
e0b17fc97d
|
@ -1,35 +1,31 @@
|
|||
<?php
|
||||
// This file is part of GNU social - https://www.gnu.org/software/social
|
||||
//
|
||||
// GNU social 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.
|
||||
//
|
||||
// GNU social 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 GNU social. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
/**
|
||||
* StatusNet, the distributed open-source microblogging tool
|
||||
*
|
||||
* Superclass for plugins that do "real time" updates of timelines using Ajax
|
||||
*
|
||||
* PHP version 5
|
||||
*
|
||||
* LICENCE: This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* @category Plugin
|
||||
* @package StatusNet
|
||||
* @package GNUsocial
|
||||
* @author Evan Prodromou <evan@status.net>
|
||||
* @author Mikael Nordfeldth <mmn@hethane.se>
|
||||
* @copyright 2009 StatusNet, Inc.
|
||||
* @copyright 2014 Free Software Foundation, Inc.
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||
* @link http://status.net/
|
||||
* @copyright 2009-2019 Free Software Foundation, Inc http://www.fsf.org
|
||||
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
|
||||
*/
|
||||
|
||||
if (!defined('GNUSOCIAL')) { exit(1); }
|
||||
defined('GNUSOCIAL') || die();
|
||||
|
||||
/**
|
||||
* Superclass for plugin to do realtime updates
|
||||
|
@ -37,13 +33,12 @@ if (!defined('GNUSOCIAL')) { exit(1); }
|
|||
* Based on experience with the Comet and Meteor plugins,
|
||||
* this superclass extracts out some of the common functionality
|
||||
*
|
||||
* Currently depends on Favorite plugin.
|
||||
* Currently depends on the Favorite module.
|
||||
*
|
||||
* @category Plugin
|
||||
* @package StatusNet
|
||||
* @package GNUsocial
|
||||
* @author Evan Prodromou <evan@status.net>
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||
* @link http://status.net/
|
||||
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
|
||||
*/
|
||||
class RealtimePlugin extends Plugin
|
||||
{
|
||||
|
@ -53,15 +48,17 @@ class RealtimePlugin extends Plugin
|
|||
* When it's time to initialize the plugin, calculate and
|
||||
* pass the URLs we need.
|
||||
*/
|
||||
function onInitializePlugin()
|
||||
public function onInitializePlugin()
|
||||
{
|
||||
// FIXME: need to find a better way to pass this pattern in
|
||||
$this->showurl = common_local_url('shownotice',
|
||||
array('notice' => '0000000000'));
|
||||
$this->showurl = common_local_url(
|
||||
'shownotice',
|
||||
['notice' => '0000000000']
|
||||
);
|
||||
return true;
|
||||
}
|
||||
|
||||
function onCheckSchema()
|
||||
public function onCheckSchema()
|
||||
{
|
||||
$schema = Schema::get();
|
||||
$schema->ensureTable('realtime_channel', Realtime_channel::schemaDef());
|
||||
|
@ -72,20 +69,25 @@ class RealtimePlugin extends Plugin
|
|||
* Hook for RouterInitialized event.
|
||||
*
|
||||
* @param URLMapper $m path-to-action mapper
|
||||
* @return boolean hook return
|
||||
* @return bool hook return
|
||||
* @throws Exception
|
||||
*/
|
||||
public function onRouterInitialized(URLMapper $m)
|
||||
{
|
||||
$m->connect('main/channel/:channelkey/keepalive',
|
||||
['action' => 'keepalivechannel'],
|
||||
['channelkey' => '[a-z0-9]{32}']);
|
||||
$m->connect('main/channel/:channelkey/close',
|
||||
['action' => 'closechannel'],
|
||||
['channelkey' => '[a-z0-9]{32}']);
|
||||
$m->connect(
|
||||
'main/channel/:channelkey/keepalive',
|
||||
['action' => 'keepalivechannel'],
|
||||
['channelkey' => '[a-z0-9]{32}']
|
||||
);
|
||||
$m->connect(
|
||||
'main/channel/:channelkey/close',
|
||||
['action' => 'closechannel'],
|
||||
['channelkey' => '[a-z0-9]{32}']
|
||||
);
|
||||
return true;
|
||||
}
|
||||
|
||||
function onEndShowScripts($action)
|
||||
public function onEndShowScripts(Action $action)
|
||||
{
|
||||
$channel = $this->_getChannel($action);
|
||||
|
||||
|
@ -93,7 +95,7 @@ class RealtimePlugin extends Plugin
|
|||
return true;
|
||||
}
|
||||
|
||||
$timeline = $this->_pathToChannel(array($channel->channel_key));
|
||||
$timeline = $this->_pathToChannel([$channel->channel_key]);
|
||||
|
||||
// If there's not a timeline on this page,
|
||||
// just return true
|
||||
|
@ -125,11 +127,10 @@ class RealtimePlugin extends Plugin
|
|||
|
||||
if ($action->boolean('realtime')) {
|
||||
$realtimeUI = ' RealtimeUpdate.initPopupWindow();';
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
$pluginPath = common_path('plugins/Realtime/');
|
||||
$keepalive = common_local_url('keepalivechannel', array('channelkey' => $channel->channel_key));
|
||||
$close = common_local_url('closechannel', array('channelkey' => $channel->channel_key));
|
||||
$keepalive = common_local_url('keepalivechannel', ['channelkey' => $channel->channel_key]);
|
||||
$close = common_local_url('closechannel', ['channelkey' => $channel->channel_key]);
|
||||
$realtimeUI = ' RealtimeUpdate.initActions('.json_encode($url).', '.json_encode($timeline).', '.json_encode($pluginPath).', '.json_encode($keepalive).', '.json_encode($close).'); ';
|
||||
}
|
||||
|
||||
|
@ -144,15 +145,17 @@ class RealtimePlugin extends Plugin
|
|||
|
||||
public function onEndShowStylesheets(Action $action)
|
||||
{
|
||||
$urlpath = self::staticPath(str_replace('Plugin','',__CLASS__),
|
||||
'css/realtimeupdate.css');
|
||||
$urlpath = self::staticPath(
|
||||
str_replace('Plugin', '', __CLASS__),
|
||||
'css/realtimeupdate.css'
|
||||
);
|
||||
$action->cssLink($urlpath, null, 'screen, projection, tv');
|
||||
return true;
|
||||
}
|
||||
|
||||
public function onHandleQueuedNotice(Notice $notice)
|
||||
{
|
||||
$paths = array();
|
||||
$paths = [];
|
||||
|
||||
// Add to the author's timeline
|
||||
|
||||
|
@ -165,7 +168,7 @@ class RealtimePlugin extends Plugin
|
|||
|
||||
try {
|
||||
$user = $profile->getUser();
|
||||
$paths[] = array('showstream', $user->nickname, null);
|
||||
$paths[] = ['showstream', $user->nickname, null];
|
||||
} catch (NoSuchUserException $e) {
|
||||
// We really should handle the remote profile views too
|
||||
$user = null;
|
||||
|
@ -176,7 +179,7 @@ class RealtimePlugin extends Plugin
|
|||
$is_local = intval($notice->is_local);
|
||||
if ($is_local === Notice::LOCAL_PUBLIC ||
|
||||
($is_local === Notice::REMOTE && !common_config('public', 'localonly'))) {
|
||||
$paths[] = array('public', null, null);
|
||||
$paths[] = ['public', null, null];
|
||||
}
|
||||
|
||||
// Add to the tags timeline
|
||||
|
@ -185,7 +188,7 @@ class RealtimePlugin extends Plugin
|
|||
|
||||
if (!empty($tags)) {
|
||||
foreach ($tags as $tag) {
|
||||
$paths[] = array('tag', $tag, null);
|
||||
$paths[] = ['tag', $tag, null];
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -196,7 +199,7 @@ class RealtimePlugin extends Plugin
|
|||
|
||||
foreach (array_keys($ni) as $user_id) {
|
||||
$user = User::getKV('id', $user_id);
|
||||
$paths[] = array('all', $user->nickname, null);
|
||||
$paths[] = ['all', $user->getNickname(), null];
|
||||
}
|
||||
|
||||
// Add to the replies timeline
|
||||
|
@ -208,7 +211,7 @@ class RealtimePlugin extends Plugin
|
|||
while ($reply->fetch()) {
|
||||
$user = User::getKV('id', $reply->profile_id);
|
||||
if (!empty($user)) {
|
||||
$paths[] = array('replies', $user->nickname, null);
|
||||
$paths[] = ['replies', $user->getNickname(), null];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -222,12 +225,11 @@ class RealtimePlugin extends Plugin
|
|||
if ($gi->find()) {
|
||||
while ($gi->fetch()) {
|
||||
$ug = User_group::getKV('id', $gi->group_id);
|
||||
$paths[] = array('showgroup', $ug->nickname, null);
|
||||
$paths[] = ['showgroup', $ug->getNickname(), null];
|
||||
}
|
||||
}
|
||||
|
||||
if (count($paths) > 0) {
|
||||
|
||||
$json = $this->noticeAsJson($notice);
|
||||
|
||||
$this->_connect();
|
||||
|
@ -236,13 +238,14 @@ class RealtimePlugin extends Plugin
|
|||
// new queue item for each path
|
||||
|
||||
foreach ($paths as $path) {
|
||||
|
||||
list($action, $arg1, $arg2) = $path;
|
||||
|
||||
$channels = Realtime_channel::getAllChannels($action, $arg1, $arg2);
|
||||
$this->log(LOG_INFO, sprintf(_("%d candidate channels for notice %d"),
|
||||
count($channels),
|
||||
$notice->id));
|
||||
$this->log(LOG_INFO, sprintf(
|
||||
_("%d candidate channels for notice %d"),
|
||||
count($channels),
|
||||
$notice->id
|
||||
));
|
||||
|
||||
foreach ($channels as $channel) {
|
||||
|
||||
|
@ -255,14 +258,18 @@ class RealtimePlugin extends Plugin
|
|||
$profile = Profile::getKV('id', $channel->user_id);
|
||||
}
|
||||
if ($notice->inScope($profile)) {
|
||||
$this->log(LOG_INFO,
|
||||
sprintf(_("Delivering notice %d to channel (%s, %s, %s) for user '%s'"),
|
||||
$notice->id,
|
||||
$channel->action,
|
||||
$channel->arg1,
|
||||
$channel->arg2,
|
||||
($profile) ? ($profile->nickname) : "<public>"));
|
||||
$timeline = $this->_pathToChannel(array($channel->channel_key));
|
||||
$this->log(
|
||||
LOG_INFO,
|
||||
sprintf(
|
||||
_m("Delivering notice %d to channel (%s, %s, %s) for user '%s'"),
|
||||
$notice->id,
|
||||
$channel->action,
|
||||
$channel->arg1,
|
||||
$channel->arg2,
|
||||
($profile ? $profile->getNickname() : '<public>')
|
||||
)
|
||||
);
|
||||
$timeline = $this->_pathToChannel([$channel->channel_key]);
|
||||
$this->_publish($timeline, $json);
|
||||
}
|
||||
}
|
||||
|
@ -274,18 +281,23 @@ class RealtimePlugin extends Plugin
|
|||
return true;
|
||||
}
|
||||
|
||||
function onStartShowBody($action)
|
||||
public function onStartShowBody(Action $action)
|
||||
{
|
||||
$realtime = $action->boolean('realtime');
|
||||
if (!$realtime) {
|
||||
return true;
|
||||
}
|
||||
|
||||
$action->elementStart('body',
|
||||
(common_current_user()) ? array('id' => $action->trimmed('action'),
|
||||
'class' => 'user_in realtime-popup')
|
||||
: array('id' => $action->trimmed('action'),
|
||||
'class'=> 'realtime-popup'));
|
||||
$action->elementStart(
|
||||
'body',
|
||||
(common_current_user() ? [
|
||||
'id' => $action->trimmed('action'),
|
||||
'class' => 'user_in realtime-popup',
|
||||
] : [
|
||||
'id' => $action->trimmed('action'),
|
||||
'class'=> 'realtime-popup',
|
||||
])
|
||||
);
|
||||
|
||||
// XXX hack to deal with JS that tries to get the
|
||||
// root url from page output
|
||||
|
@ -294,14 +306,17 @@ class RealtimePlugin extends Plugin
|
|||
|
||||
if (common_config('singleuser', 'enabled')) {
|
||||
$user = User::singleUser();
|
||||
$url = common_local_url('showstream', array('nickname' => $user->nickname));
|
||||
$url = common_local_url('showstream', ['nickname' => $user->nickname]);
|
||||
} else {
|
||||
$url = common_local_url('public');
|
||||
}
|
||||
|
||||
$action->element('a', array('class' => 'url',
|
||||
'href' => $url),
|
||||
'');
|
||||
$action->element(
|
||||
'a',
|
||||
['class' => 'url',
|
||||
'href' => $url],
|
||||
''
|
||||
);
|
||||
|
||||
$action->elementEnd('address');
|
||||
|
||||
|
@ -311,7 +326,7 @@ class RealtimePlugin extends Plugin
|
|||
return false; // No default processing
|
||||
}
|
||||
|
||||
function noticeAsJson(Notice $notice)
|
||||
public function noticeAsJson(Notice $notice)
|
||||
{
|
||||
// FIXME: this code should be abstracted to a neutral third
|
||||
// party, like Notice::asJson(). I'm not sure of the ethics
|
||||
|
@ -347,7 +362,7 @@ class RealtimePlugin extends Plugin
|
|||
return $arr;
|
||||
}
|
||||
|
||||
function getNoticeTags(Notice $notice)
|
||||
public function getNoticeTags(Notice $notice)
|
||||
{
|
||||
$tags = null;
|
||||
|
||||
|
@ -355,7 +370,7 @@ class RealtimePlugin extends Plugin
|
|||
$nt->notice_id = $notice->id;
|
||||
|
||||
if ($nt->find()) {
|
||||
$tags = array();
|
||||
$tags = [];
|
||||
while ($nt->fetch()) {
|
||||
$tags[] = $nt->tag;
|
||||
}
|
||||
|
@ -367,11 +382,13 @@ class RealtimePlugin extends Plugin
|
|||
return $tags;
|
||||
}
|
||||
|
||||
function _getScripts()
|
||||
public function _getScripts(): array
|
||||
{
|
||||
$urlpath = self::staticPath(str_replace('Plugin','',__CLASS__),
|
||||
'js/realtimeupdate.js');
|
||||
return array($urlpath);
|
||||
$urlpath = self::staticPath(
|
||||
str_replace('Plugin', '', __CLASS__),
|
||||
'js/realtimeupdate.js'
|
||||
);
|
||||
return [$urlpath];
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -380,9 +397,10 @@ class RealtimePlugin extends Plugin
|
|||
* @param Action $action
|
||||
* @param array $messages
|
||||
*
|
||||
* @return boolean hook return value
|
||||
* @return bool hook return value
|
||||
* @throws Exception
|
||||
*/
|
||||
function onEndScriptMessages($action, &$messages)
|
||||
public function onEndScriptMessages(Action $action, array &$messages)
|
||||
{
|
||||
// TRANS: Text label for realtime view "play" button, usually replaced by an icon.
|
||||
$messages['realtime_play'] = _m('BUTTON', 'Play');
|
||||
|
@ -400,40 +418,40 @@ class RealtimePlugin extends Plugin
|
|||
return true;
|
||||
}
|
||||
|
||||
function _updateInitialize($timeline, $user_id)
|
||||
public function _updateInitialize($timeline, int $user_id)
|
||||
{
|
||||
return "RealtimeUpdate.init($user_id, \"$this->showurl\"); ";
|
||||
}
|
||||
|
||||
function _connect()
|
||||
public function _connect()
|
||||
{
|
||||
}
|
||||
|
||||
function _publish($timeline, $json)
|
||||
public function _publish($timeline, $json)
|
||||
{
|
||||
}
|
||||
|
||||
function _disconnect()
|
||||
public function _disconnect()
|
||||
{
|
||||
}
|
||||
|
||||
function _pathToChannel($path)
|
||||
public function _pathToChannel(array $path): string
|
||||
{
|
||||
return '';
|
||||
}
|
||||
|
||||
|
||||
function _getTimeline($action)
|
||||
public function _getTimeline(Action $action)
|
||||
{
|
||||
$channel = $this->_getChannel($action);
|
||||
if (empty($channel)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return $this->_pathToChannel(array($channel->channel_key));
|
||||
return $this->_pathToChannel([$channel->channel_key]);
|
||||
}
|
||||
|
||||
function _getChannel($action)
|
||||
public function _getChannel(Action $action)
|
||||
{
|
||||
$timeline = null;
|
||||
$arg1 = null;
|
||||
|
@ -478,15 +496,17 @@ class RealtimePlugin extends Plugin
|
|||
|
||||
$user_id = (!empty($user)) ? $user->id : null;
|
||||
|
||||
$channel = Realtime_channel::getChannel($user_id,
|
||||
$action_name,
|
||||
$arg1,
|
||||
$arg2);
|
||||
$channel = Realtime_channel::getChannel(
|
||||
$user_id,
|
||||
$action_name,
|
||||
$arg1,
|
||||
$arg2
|
||||
);
|
||||
|
||||
return $channel;
|
||||
}
|
||||
|
||||
function onStartReadWriteTables(&$alwaysRW, &$rwdb)
|
||||
public function onStartReadWriteTables(&$alwaysRW, &$rwdb)
|
||||
{
|
||||
$alwaysRW[] = 'realtime_channel';
|
||||
return true;
|
|
@ -1,48 +1,38 @@
|
|||
<?php
|
||||
/**
|
||||
* StatusNet - the distributed open-source microblogging tool
|
||||
* Copyright (C) 2011, StatusNet, Inc.
|
||||
*
|
||||
* action to close a channel
|
||||
*
|
||||
* 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 Realtime
|
||||
* @package StatusNet
|
||||
* @author Evan Prodromou <evan@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);
|
||||
}
|
||||
// This file is part of GNU social - https://www.gnu.org/software/social
|
||||
//
|
||||
// GNU social 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.
|
||||
//
|
||||
// GNU social 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 GNU social. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
/**
|
||||
* Action to close a channel
|
||||
*
|
||||
* @category Realtime
|
||||
* @package StatusNet
|
||||
* @package GNUsocial
|
||||
* @author Evan Prodromou <evan@status.net>
|
||||
* @copyright 2011 StatusNet, Inc.
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0
|
||||
* @link http://status.net/
|
||||
* @copyright 2011-2019 Free Software Foundation, Inc http://www.fsf.org
|
||||
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
|
||||
*/
|
||||
|
||||
defined('GNUSOCIAL') || die();
|
||||
|
||||
/**
|
||||
* Action to close a channel
|
||||
*
|
||||
* @category Realtime
|
||||
* @package GNUsocial
|
||||
* @author Evan Prodromou <evan@status.net>
|
||||
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
|
||||
*/
|
||||
class ClosechannelAction extends Action
|
||||
{
|
||||
|
@ -57,7 +47,7 @@ class ClosechannelAction extends Action
|
|||
* @return boolean true
|
||||
* @throws ClientException
|
||||
*/
|
||||
function prepare(array $args = [])
|
||||
public function prepare(array $args = [])
|
||||
{
|
||||
parent::prepare($args);
|
||||
|
||||
|
@ -88,7 +78,7 @@ class ClosechannelAction extends Action
|
|||
*
|
||||
* @return void
|
||||
*/
|
||||
function handle()
|
||||
public function handle(): void
|
||||
{
|
||||
$this->channel->decrement();
|
||||
|
||||
|
@ -104,9 +94,9 @@ class ClosechannelAction extends Action
|
|||
*
|
||||
* @param array $args other arguments
|
||||
*
|
||||
* @return boolean is read only action?
|
||||
* @return bool is read only action?
|
||||
*/
|
||||
function isReadOnly($args)
|
||||
public function isReadOnly($args): bool
|
||||
{
|
||||
return false;
|
||||
}
|
|
@ -54,10 +54,10 @@ class KeepalivechannelAction extends Action
|
|||
*
|
||||
* @param array $args misc. arguments
|
||||
*
|
||||
* @return boolean true
|
||||
* @return bool true
|
||||
* @throws ClientException
|
||||
*/
|
||||
function prepare(array $args = [])
|
||||
public function prepare(array $args = []): bool
|
||||
{
|
||||
parent::prepare($args);
|
||||
|
||||
|
@ -88,7 +88,7 @@ class KeepalivechannelAction extends Action
|
|||
*
|
||||
* @return void
|
||||
*/
|
||||
function handle()
|
||||
public function handle(): void
|
||||
{
|
||||
$this->channel->touch();
|
||||
|
||||
|
@ -104,9 +104,9 @@ class KeepalivechannelAction extends Action
|
|||
*
|
||||
* @param array $args other arguments
|
||||
*
|
||||
* @return boolean is read only action?
|
||||
* @return bool is read only action?
|
||||
*/
|
||||
function isReadOnly($args)
|
||||
public function isReadOnly($args): bool
|
||||
{
|
||||
return false;
|
||||
}
|
|
@ -23,7 +23,7 @@
|
|||
* @category Realtime
|
||||
* @package GNUsocial
|
||||
* @author Evan Prodromou <evan@status.net>
|
||||
* @copyright 2011 StatusNet, Inc.
|
||||
* @copyright 2011-2019 Free Software Foundation, Inc http://www.fsf.org
|
||||
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
|
||||
*/
|
||||
|
||||
|
@ -32,10 +32,9 @@ defined('GNUSOCIAL') || die();
|
|||
/**
|
||||
* A channel for real-time browser data
|
||||
*
|
||||
* @copyright 2011 StatusNet, Inc.
|
||||
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
|
||||
*
|
||||
* @see DB_DataObject
|
||||
* @see DB_DataObject
|
||||
*/
|
||||
class Realtime_channel extends Managed_DataObject
|
||||
{
|
||||
|
@ -57,64 +56,64 @@ class Realtime_channel extends Managed_DataObject
|
|||
*/
|
||||
public static function schemaDef()
|
||||
{
|
||||
return array(
|
||||
return [
|
||||
'description' => 'A channel of realtime notice data',
|
||||
'fields' => array(
|
||||
'user_id' => array('type' => 'int',
|
||||
'not null' => false,
|
||||
'description' => 'user viewing page; can be null'),
|
||||
'action' => array('type' => 'varchar',
|
||||
'length' => 191,
|
||||
'not null' => true,
|
||||
'description' => 'page being viewed'),
|
||||
'arg1' => array('type' => 'varchar',
|
||||
'length' => 191,
|
||||
'not null' => false,
|
||||
'description' => 'page argument, like username or tag'),
|
||||
'arg2' => array('type' => 'varchar',
|
||||
'length' => 191,
|
||||
'not null' => false,
|
||||
'description' => 'second page argument, like tag for showstream'),
|
||||
'channel_key' => array('type' => 'varchar',
|
||||
'length' => 32,
|
||||
'not null' => true,
|
||||
'description' => 'shared secret key for this channel'),
|
||||
'audience' => array('type' => 'int',
|
||||
'not null' => true,
|
||||
'default' => 0,
|
||||
'description' => 'reference count'),
|
||||
'created' => array('type' => 'datetime',
|
||||
'not null' => true,
|
||||
'description' => 'date this record was created'),
|
||||
'modified' => array('type' => 'datetime',
|
||||
'not null' => true,
|
||||
'description' => 'date this record was modified'),
|
||||
),
|
||||
'primary key' => array('channel_key'),
|
||||
'unique keys' => array('realtime_channel_user_page_idx' => array('user_id', 'action', 'arg1', 'arg2')),
|
||||
'foreign keys' => array(
|
||||
'realtime_channel_user_id_fkey' => array('user', array('user_id' => 'id')),
|
||||
),
|
||||
'indexes' => array(
|
||||
'realtime_channel_modified_idx' => array('modified'),
|
||||
'realtime_channel_page_idx' => array('action', 'arg1', 'arg2')
|
||||
),
|
||||
);
|
||||
'fields' => [
|
||||
'user_id' => ['type' => 'int',
|
||||
'not null' => false,
|
||||
'description' => 'user viewing page; can be null'],
|
||||
'action' => ['type' => 'varchar',
|
||||
'length' => 191,
|
||||
'not null' => true,
|
||||
'description' => 'page being viewed'],
|
||||
'arg1' => ['type' => 'varchar',
|
||||
'length' => 191,
|
||||
'not null' => false,
|
||||
'description' => 'page argument, like username or tag'],
|
||||
'arg2' => ['type' => 'varchar',
|
||||
'length' => 191,
|
||||
'not null' => false,
|
||||
'description' => 'second page argument, like tag for showstream'],
|
||||
'channel_key' => ['type' => 'varchar',
|
||||
'length' => 32,
|
||||
'not null' => true,
|
||||
'description' => 'shared secret key for this channel'],
|
||||
'audience' => ['type' => 'int',
|
||||
'not null' => true,
|
||||
'default' => 0,
|
||||
'description' => 'reference count'],
|
||||
'created' => ['type' => 'datetime',
|
||||
'not null' => true,
|
||||
'description' => 'date this record was created'],
|
||||
'modified' => ['type' => 'datetime',
|
||||
'not null' => true,
|
||||
'description' => 'date this record was modified'],
|
||||
],
|
||||
'primary key' => ['channel_key'],
|
||||
'unique keys' => ['realtime_channel_user_page_idx' => ['user_id', 'action', 'arg1', 'arg2']],
|
||||
'foreign keys' => [
|
||||
'realtime_channel_user_id_fkey' => ['user', ['user_id' => 'id']],
|
||||
],
|
||||
'indexes' => [
|
||||
'realtime_channel_modified_idx' => ['modified'],
|
||||
'realtime_channel_page_idx' => ['action', 'arg1', 'arg2']
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
public static function saveNew($user_id, $action, $arg1, $arg2)
|
||||
public static function saveNew(int $user_id, Action $action, $arg1, $arg2): Realtime_channel
|
||||
{
|
||||
$channel = new Realtime_channel();
|
||||
|
||||
$channel->user_id = $user_id;
|
||||
$channel->action = $action;
|
||||
$channel->arg1 = $arg1;
|
||||
$channel->arg2 = $arg2;
|
||||
$channel->audience = 1;
|
||||
$channel->action = $action;
|
||||
$channel->arg1 = $arg1;
|
||||
$channel->arg2 = $arg2;
|
||||
$channel->audience = 1;
|
||||
|
||||
$channel->channel_key = common_random_hexstr(16); // 128-bit key, 32 hex chars
|
||||
|
||||
$channel->created = common_sql_now();
|
||||
$channel->created = common_sql_now();
|
||||
$channel->modified = $channel->created;
|
||||
|
||||
$channel->insert();
|
||||
|
@ -122,7 +121,7 @@ class Realtime_channel extends Managed_DataObject
|
|||
return $channel;
|
||||
}
|
||||
|
||||
public static function getChannel($user_id, $action, $arg1, $arg2)
|
||||
public static function getChannel(int $user_id, Action $action, $arg1, $arg2): Realtime_channel
|
||||
{
|
||||
$channel = self::fetchChannel($user_id, $action, $arg1, $arg2);
|
||||
|
||||
|
@ -143,7 +142,7 @@ class Realtime_channel extends Managed_DataObject
|
|||
return $channel;
|
||||
}
|
||||
|
||||
public static function getAllChannels($action, $arg1, $arg2)
|
||||
public static function getAllChannels(Action $action, $arg1, $arg2): array
|
||||
{
|
||||
$channel = new Realtime_channel();
|
||||
|
||||
|
@ -172,7 +171,7 @@ class Realtime_channel extends Managed_DataObject
|
|||
return $channels;
|
||||
}
|
||||
|
||||
public static function fetchChannel($user_id, $action, $arg1, $arg2)
|
||||
public static function fetchChannel(int $user_id, Action $action, $arg1, $arg2): ?Realtime_channel
|
||||
{
|
||||
$channel = new Realtime_channel();
|
||||
|
||||
|
@ -204,7 +203,7 @@ class Realtime_channel extends Managed_DataObject
|
|||
}
|
||||
}
|
||||
|
||||
public function increment()
|
||||
public function increment(): void
|
||||
{
|
||||
// XXX: race
|
||||
$orig = clone($this);
|
||||
|
@ -213,7 +212,7 @@ class Realtime_channel extends Managed_DataObject
|
|||
$this->update($orig);
|
||||
}
|
||||
|
||||
public function touch()
|
||||
public function touch(): void
|
||||
{
|
||||
// XXX: race
|
||||
$orig = clone($this);
|
||||
|
@ -221,7 +220,7 @@ class Realtime_channel extends Managed_DataObject
|
|||
$this->update($orig);
|
||||
}
|
||||
|
||||
public function decrement()
|
||||
public function decrement(): void
|
||||
{
|
||||
// XXX: race
|
||||
if ($this->audience == 1) {
|
|
@ -20,7 +20,7 @@
|
|||
*
|
||||
* @package Realtime
|
||||
* @author Mikael Nordfeldth <mmn@hethane.se>
|
||||
* @copyright 2011 StatusNet, Inc.
|
||||
* @copyright 2011-2019 Free Software Foundation, Inc http://www.fsf.org
|
||||
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
|
||||
*/
|
||||
|
||||
|
@ -28,7 +28,7 @@ define('INSTALLDIR', dirname(__DIR__, 3));
|
|||
define('PUBLICDIR', INSTALLDIR . DIRECTORY_SEPARATOR . 'public');
|
||||
|
||||
$shortoptions = 'u';
|
||||
$longoptions = array('universe');
|
||||
$longoptions = ['universe'];
|
||||
|
||||
$helptext = <<<END_OF_CLEANUPCHANNELS_HELP
|
||||
cleanupchannels.php [options]
|
|
@ -26,6 +26,17 @@
|
|||
|
||||
defined('GNUSOCIAL') || die();
|
||||
|
||||
/**
|
||||
* Class TheFreeNetworkModule
|
||||
* This module ensures that multiple protocols serving the same purpose won't result in duplicated data.
|
||||
* This class is not to be extended but a developer implementing a new protocol should be aware of it and notify the
|
||||
* StartTFNCensus event.
|
||||
*
|
||||
* @category Module
|
||||
* @package GNUsocial
|
||||
* @author Bruno Casteleiro <brunoccast@fc.up.pt>
|
||||
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
|
||||
*/
|
||||
class TheFreeNetworkModule extends Module
|
||||
{
|
||||
const MODULE_VERSION = '0.1.0alpha0';
|
||||
|
|
|
@ -46,6 +46,8 @@ const ACTIVITYPUB_HTTP_CLIENT_HEADERS = [
|
|||
];
|
||||
|
||||
/**
|
||||
* Adds ActivityPub support to GNU social when enabled
|
||||
*
|
||||
* @category Plugin
|
||||
* @package GNUsocial
|
||||
* @author Diogo Cordeiro <diogo@fc.up.pt>
|
||||
|
|
|
@ -31,7 +31,7 @@ if (!defined('GNUSOCIAL') && !defined('STATUSNET')) {
|
|||
exit(1);
|
||||
}
|
||||
|
||||
require_once INSTALLDIR.'/plugins/Realtime/RealtimePlugin.php';
|
||||
require_once INSTALLDIR . DIRECTORY_SEPARATOR . 'lib/modules/Realtime/RealtimePlugin.php';
|
||||
|
||||
/**
|
||||
* Plugin to do realtime updates using Comet
|
||||
|
@ -52,8 +52,12 @@ class CometPlugin extends RealtimePlugin
|
|||
public $prefix = null;
|
||||
protected $bay = null;
|
||||
|
||||
function __construct($server=null, $username=null, $password=null, $prefix=null)
|
||||
{
|
||||
public function __construct(
|
||||
?string $server = null,
|
||||
?string $username = null,
|
||||
?string $password = null,
|
||||
?string $prefix = null
|
||||
) {
|
||||
$this->server = $server;
|
||||
$this->username = $username;
|
||||
$this->password = $password;
|
||||
|
@ -62,11 +66,11 @@ class CometPlugin extends RealtimePlugin
|
|||
parent::__construct();
|
||||
}
|
||||
|
||||
function _getScripts()
|
||||
public function _getScripts(): array
|
||||
{
|
||||
$scripts = parent::_getScripts();
|
||||
|
||||
$ours = array('js/jquery.comet.js', 'js/cometupdate.js');
|
||||
$ours = ['js/jquery.comet.js', 'js/cometupdate.js'];
|
||||
|
||||
foreach ($ours as $script) {
|
||||
$scripts[] = $this->path($script);
|
||||
|
@ -75,30 +79,30 @@ class CometPlugin extends RealtimePlugin
|
|||
return $scripts;
|
||||
}
|
||||
|
||||
function _updateInitialize($timeline, $user_id)
|
||||
public function _updateInitialize($timeline, int $user_id)
|
||||
{
|
||||
$script = parent::_updateInitialize($timeline, $user_id);
|
||||
return $script." CometUpdate.init(\"$this->server\", \"$timeline\", $user_id, \"$this->replyurl\", \"$this->favorurl\", \"$this->deleteurl\");";
|
||||
}
|
||||
|
||||
function _connect()
|
||||
public function _connect(): void
|
||||
{
|
||||
require_once INSTALLDIR.'/plugins/Comet/extlib/Bayeux/Bayeux.class.php';
|
||||
require_once __DIR__. DIRECTORY_SEPARATOR . 'extlib/Bayeux/Bayeux.class.php';
|
||||
// Bayeux? Comet? Huh? These terms confuse me
|
||||
$this->bay = new Bayeux($this->server, $this->user, $this->password);
|
||||
}
|
||||
|
||||
function _publish($timeline, $json)
|
||||
public function _publish($timeline, $json): void
|
||||
{
|
||||
$this->bay->publish($timeline, $json);
|
||||
}
|
||||
|
||||
function _disconnect()
|
||||
public function _disconnect(): void
|
||||
{
|
||||
unset($this->bay);
|
||||
}
|
||||
|
||||
function _pathToChannel($path)
|
||||
public function _pathToChannel(array $path): string
|
||||
{
|
||||
if (!empty($this->prefix)) {
|
||||
array_unshift($path, $this->prefix);
|
||||
|
@ -108,14 +112,16 @@ class CometPlugin extends RealtimePlugin
|
|||
|
||||
public function onPluginVersion(array &$versions): bool
|
||||
{
|
||||
$versions[] = array('name' => 'Comet',
|
||||
'version' => self::PLUGIN_VERSION,
|
||||
'author' => 'Evan Prodromou',
|
||||
'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.
|
||||
_m('Plugin to make updates using Comet and Bayeux.'));
|
||||
$versions[] = [
|
||||
'name' => 'Comet',
|
||||
'version' => self::PLUGIN_VERSION,
|
||||
'author' => 'Evan Prodromou',
|
||||
'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.
|
||||
_m('Plugin to make updates using Comet and Bayeux.')
|
||||
];
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -30,36 +30,36 @@ class Bayeux
|
|||
|
||||
public $sUrl = '';
|
||||
|
||||
function __construct($sUrl, $sUser='', $sPassword='')
|
||||
public function __construct($sUrl, $sUser='', $sPassword='')
|
||||
{
|
||||
$this->sUrl = $sUrl;
|
||||
|
||||
$this->oCurl = curl_init();
|
||||
|
||||
$aHeaders = array();
|
||||
$aHeaders = [];
|
||||
$aHeaders[] = 'Connection: Keep-Alive';
|
||||
|
||||
curl_setopt($this->oCurl, CURLOPT_URL, $sUrl);
|
||||
curl_setopt($this->oCurl, CURLOPT_HTTPHEADER, $aHeaders);
|
||||
curl_setopt($this->oCurl, CURLOPT_HEADER, 0);
|
||||
curl_setopt($this->oCurl, CURLOPT_POST, 1);
|
||||
curl_setopt($this->oCurl, CURLOPT_RETURNTRANSFER,1);
|
||||
curl_setopt($this->oCurl, CURLOPT_RETURNTRANSFER, 1);
|
||||
|
||||
if (!is_null($sUser) && mb_strlen($sUser) > 0) {
|
||||
curl_setopt($this->oCurl, CURLOPT_USERPWD,"$sUser:$sPassword");
|
||||
curl_setopt($this->oCurl, CURLOPT_USERPWD, "$sUser:$sPassword");
|
||||
}
|
||||
|
||||
$this->handShake();
|
||||
}
|
||||
|
||||
function __destruct()
|
||||
public function __destruct()
|
||||
{
|
||||
$this->disconnect();
|
||||
}
|
||||
|
||||
function handShake()
|
||||
public function handShake()
|
||||
{
|
||||
$msgHandshake = array();
|
||||
$msgHandshake = [];
|
||||
$msgHandshake['channel'] = '/meta/handshake';
|
||||
$msgHandshake['version'] = "1.0";
|
||||
$msgHandshake['minimumVersion'] = "0.9";
|
||||
|
@ -70,8 +70,9 @@ class Bayeux
|
|||
|
||||
$data = curl_exec($this->oCurl);
|
||||
|
||||
if(curl_errno($this->oCurl))
|
||||
die("Error: " . curl_error($this->oCurl));
|
||||
if (curl_errno($this->oCurl)) {
|
||||
die("Error: " . curl_error($this->oCurl));
|
||||
}
|
||||
|
||||
$oReturn = json_decode($data);
|
||||
|
||||
|
@ -81,8 +82,7 @@ class Bayeux
|
|||
|
||||
$bSuccessful = ($oReturn->successful) ? true : false;
|
||||
|
||||
if($bSuccessful)
|
||||
{
|
||||
if ($bSuccessful) {
|
||||
$this->clientId = $oReturn->clientId;
|
||||
|
||||
$this->connect();
|
||||
|
@ -101,9 +101,9 @@ class Bayeux
|
|||
$data = curl_exec($this->oCurl);
|
||||
}
|
||||
|
||||
function disconnect()
|
||||
public function disconnect()
|
||||
{
|
||||
$msgHandshake = array();
|
||||
$msgHandshake = [];
|
||||
$msgHandshake['channel'] = '/meta/disconnect';
|
||||
$msgHandshake['id'] = $this->nNextId++;
|
||||
$msgHandshake['clientId'] = $this->clientId;
|
||||
|
@ -115,10 +115,11 @@ class Bayeux
|
|||
|
||||
public function publish($sChannel, $oData)
|
||||
{
|
||||
if(!$sChannel || !$oData)
|
||||
return;
|
||||
if (!$sChannel || !$oData) {
|
||||
return;
|
||||
}
|
||||
|
||||
$aMsg = array();
|
||||
$aMsg = [];
|
||||
|
||||
$aMsg['channel'] = $sChannel;
|
||||
$aMsg['id'] = $this->nNextId++;
|
||||
|
|
|
@ -1,46 +1,40 @@
|
|||
<?php
|
||||
// This file is part of GNU social - https://www.gnu.org/software/social
|
||||
//
|
||||
// GNU social 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.
|
||||
//
|
||||
// GNU social 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 GNU social. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
/**
|
||||
* StatusNet, the distributed open-source microblogging tool
|
||||
*
|
||||
* Plugin to do "real time" updates using Meteor
|
||||
*
|
||||
* PHP version 5
|
||||
*
|
||||
* LICENCE: This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* @category Plugin
|
||||
* @package StatusNet
|
||||
* @package GNUsocial
|
||||
* @author Evan Prodromou <evan@status.net>
|
||||
* @copyright 2009 StatusNet, Inc.
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||
* @link http://status.net/
|
||||
* @copyright 2010-2019 Free Software Foundation, Inc http://www.fsf.org
|
||||
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
|
||||
*/
|
||||
|
||||
if (!defined('GNUSOCIAL') && !defined('STATUSNET')) {
|
||||
exit(1);
|
||||
}
|
||||
defined('GNUSOCIAL') || die();
|
||||
|
||||
require_once INSTALLDIR.'/plugins/Realtime/RealtimePlugin.php';
|
||||
require_once INSTALLDIR . DIRECTORY_SEPARATOR . 'lib/modules/Realtime/RealtimePlugin.php';
|
||||
|
||||
/**
|
||||
* Plugin to do realtime updates using Meteor
|
||||
*
|
||||
* @category Plugin
|
||||
* @package StatusNet
|
||||
* @author Evan Prodromou <evan@status.net>
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||
* @link http://status.net/
|
||||
* @category Plugin
|
||||
* @package GNUsocial
|
||||
* @author Evan Prodromou <evan@status.net>
|
||||
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
|
||||
*/
|
||||
class MeteorPlugin extends RealtimePlugin
|
||||
{
|
||||
|
@ -55,8 +49,14 @@ class MeteorPlugin extends RealtimePlugin
|
|||
public $persistent = true;
|
||||
protected $_socket = null;
|
||||
|
||||
function __construct($webserver=null, $webport=4670, $controlport=4671, $controlserver=null, $channelbase='', $protocol='http')
|
||||
{
|
||||
public function __construct(
|
||||
?string $webserver = null,
|
||||
int $webport = 4670,
|
||||
int $controlport = 4671,
|
||||
?string $controlserver = null,
|
||||
string $channelbase = '',
|
||||
string $protocol = 'http'
|
||||
) {
|
||||
global $config;
|
||||
|
||||
$this->webserver = (empty($webserver)) ? $config['site']['server'] : $webserver;
|
||||
|
@ -64,22 +64,24 @@ class MeteorPlugin extends RealtimePlugin
|
|||
$this->controlport = $controlport;
|
||||
$this->controlserver = (empty($controlserver)) ? $webserver : $controlserver;
|
||||
$this->channelbase = $channelbase;
|
||||
$this->protocol = $protocol;
|
||||
|
||||
$this->protocol = $protocol;
|
||||
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
/**
|
||||
* Pull settings from config file/database if set.
|
||||
*/
|
||||
function initialize()
|
||||
public function initialize()
|
||||
{
|
||||
$settings = array('webserver',
|
||||
'webport',
|
||||
'controlport',
|
||||
'controlserver',
|
||||
'channelbase',
|
||||
'protocol');
|
||||
$settings = [
|
||||
'webserver',
|
||||
'webport',
|
||||
'controlport',
|
||||
'controlserver',
|
||||
'channelbase',
|
||||
'protocol',
|
||||
];
|
||||
foreach ($settings as $name) {
|
||||
$val = common_config('meteor', $name);
|
||||
if ($val !== false) {
|
||||
|
@ -90,47 +92,57 @@ class MeteorPlugin extends RealtimePlugin
|
|||
return parent::initialize();
|
||||
}
|
||||
|
||||
function _getScripts()
|
||||
public function _getScripts()
|
||||
{
|
||||
$scripts = parent::_getScripts();
|
||||
if ($this->protocol == 'https') {
|
||||
$scripts[] = 'https://'.$this->webserver.(($this->webport == 443) ? '':':'.$this->webport).'/meteor.js';
|
||||
$scripts[] = 'https://' . $this->webserver . (($this->webport == 443) ? '' : ':' . $this->webport) . '/meteor.js';
|
||||
} else {
|
||||
$scripts[] = 'http://'.$this->webserver.(($this->webport == 80) ? '':':'.$this->webport).'/meteor.js';
|
||||
$scripts[] = 'http://' . $this->webserver . (($this->webport == 80) ? '' : ':' . $this->webport) . '/meteor.js';
|
||||
}
|
||||
$scripts[] = $this->path('js/meteorupdater.js');
|
||||
return $scripts;
|
||||
}
|
||||
|
||||
function _updateInitialize($timeline, $user_id)
|
||||
public function _updateInitialize($timeline, int $user_id)
|
||||
{
|
||||
$script = parent::_updateInitialize($timeline, $user_id);
|
||||
$ours = sprintf("MeteorUpdater.init(%s, %s, %s, %s);",
|
||||
json_encode($this->webserver),
|
||||
json_encode($this->webport),
|
||||
json_encode($this->protocol),
|
||||
json_encode($timeline));
|
||||
$ours = sprintf(
|
||||
"MeteorUpdater.init(%s, %s, %s, %s);",
|
||||
json_encode($this->webserver),
|
||||
json_encode($this->webport),
|
||||
json_encode($this->protocol),
|
||||
json_encode($timeline)
|
||||
);
|
||||
return $script." ".$ours;
|
||||
}
|
||||
|
||||
function _connect()
|
||||
public function _connect()
|
||||
{
|
||||
$controlserver = (empty($this->controlserver)) ? $this->webserver : $this->controlserver;
|
||||
|
||||
$errno = $errstr = null;
|
||||
$timeout = 5;
|
||||
$flags = STREAM_CLIENT_CONNECT;
|
||||
if ($this->persistent) $flags |= STREAM_CLIENT_PERSISTENT;
|
||||
if ($this->persistent) {
|
||||
$flags |= STREAM_CLIENT_PERSISTENT;
|
||||
}
|
||||
|
||||
// May throw an exception.
|
||||
$this->_socket = stream_socket_client("tcp://{$controlserver}:{$this->controlport}", $errno, $errstr, $timeout, $flags);
|
||||
$this->_socket = stream_socket_client(
|
||||
"tcp://{$controlserver}:{$this->controlport}",
|
||||
$errno,
|
||||
$errstr,
|
||||
$timeout,
|
||||
$flags
|
||||
);
|
||||
if (!$this->_socket) {
|
||||
// TRANS: Exception. %1$s is the control server, %2$s is the control port.
|
||||
throw new Exception(sprintf(_m('Could not connect to %1$s on %2$s.'),$controlserver,$this->controlport));
|
||||
throw new Exception(sprintf(_m('Could not connect to %1$s on %2$s.'), $controlserver, $this->controlport));
|
||||
}
|
||||
}
|
||||
|
||||
function _publish($channel, $message)
|
||||
public function _publish($channel, $message)
|
||||
{
|
||||
$message = json_encode($message);
|
||||
$message = addslashes($message);
|
||||
|
@ -139,12 +151,12 @@ class MeteorPlugin extends RealtimePlugin
|
|||
$result = fgets($this->_socket);
|
||||
if (preg_match('/^ERR (.*)$/', $result, $matches)) {
|
||||
// TRANS: Exception. %s is the Meteor message that could not be added.
|
||||
throw new Exception(sprintf(_m('Error adding meteor message "%s".'),$matches[1]));
|
||||
throw new Exception(sprintf(_m('Error adding meteor message "%s".'), $matches[1]));
|
||||
}
|
||||
// TODO: parse and deal with result
|
||||
}
|
||||
|
||||
function _disconnect()
|
||||
public function _disconnect()
|
||||
{
|
||||
if (!$this->persistent) {
|
||||
$cnt = fwrite($this->_socket, "QUIT\n");
|
||||
|
@ -154,7 +166,7 @@ class MeteorPlugin extends RealtimePlugin
|
|||
|
||||
// Meteord flips out with default '/' separator
|
||||
|
||||
function _pathToChannel($path)
|
||||
public function _pathToChannel(array $path): string
|
||||
{
|
||||
if (!empty($this->channelbase)) {
|
||||
array_unshift($path, $this->channelbase);
|
||||
|
@ -164,13 +176,15 @@ class MeteorPlugin extends RealtimePlugin
|
|||
|
||||
public function onPluginVersion(array &$versions): bool
|
||||
{
|
||||
$versions[] = array('name' => 'Meteor',
|
||||
'version' => self::PLUGIN_VERSION,
|
||||
'author' => 'Evan Prodromou',
|
||||
'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.'));
|
||||
$versions[] = [
|
||||
'name' => 'Meteor',
|
||||
'version' => self::PLUGIN_VERSION,
|
||||
'author' => 'Evan Prodromou',
|
||||
'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.')
|
||||
];
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,7 +4,7 @@ FriendFeed's "real time" news.
|
|||
|
||||
It requires a meteor server.
|
||||
|
||||
http://meteorserver.org/
|
||||
https://github.com/visitsb/meteorserver/
|
||||
|
||||
Note that the controller interface needs to be accessible by the Web server, and
|
||||
the subscriber interface needs to be accessible by your Web users. You MUST
|
||||
|
@ -13,7 +13,7 @@ push any message to your subscribers. Not good!
|
|||
|
||||
You can enable the plugin with this line in config.php:
|
||||
|
||||
addPlugin('Meteor', array('webserver' => 'meteor server address'));
|
||||
addPlugin('Meteor', ['webserver' => 'meteor server address']);
|
||||
|
||||
Available parameters:
|
||||
* webserver: Web server address. Defaults to site server.
|
|
@ -1,9 +0,0 @@
|
|||
.fake: all clean
|
||||
|
||||
all: realtimeupdate.min.js
|
||||
|
||||
clean:
|
||||
rm -f js/realtimeupdate.min.js
|
||||
|
||||
realtimeupdate.min.js: js/realtimeupdate.js
|
||||
yui-compressor js/realtimeupdate.js > js/realtimeupdate.min.js
|
Loading…
Reference in New Issue
Block a user