2010-08-05 21:37:47 +01:00
|
|
|
<?php
|
|
|
|
/*
|
|
|
|
* StatusNet - the distributed open-source microblogging tool
|
|
|
|
* Copyright (C) 2010, 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/>.
|
|
|
|
*/
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @package SubMirrorPlugin
|
|
|
|
* @maintainer Brion Vibber <brion@status.net>
|
|
|
|
*/
|
|
|
|
|
|
|
|
class SubMirror extends Memcached_DataObject
|
|
|
|
{
|
|
|
|
public $__table = 'submirror';
|
|
|
|
|
|
|
|
public $subscriber;
|
|
|
|
public $subscribed;
|
|
|
|
|
|
|
|
public $style;
|
|
|
|
|
|
|
|
public $created;
|
|
|
|
public $modified;
|
|
|
|
|
|
|
|
public /*static*/ function staticGet($k, $v=null)
|
|
|
|
{
|
|
|
|
return parent::staticGet(__CLASS__, $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('subscriber' => DB_DATAOBJECT_INT + DB_DATAOBJECT_NOTNULL,
|
|
|
|
'subscribed' => DB_DATAOBJECT_INT + DB_DATAOBJECT_NOTNULL,
|
|
|
|
|
|
|
|
'style' => DB_DATAOBJECT_STR,
|
|
|
|
|
|
|
|
'created' => DB_DATAOBJECT_STR + DB_DATAOBJECT_DATE + DB_DATAOBJECT_TIME + DB_DATAOBJECT_NOTNULL,
|
|
|
|
'modified' => DB_DATAOBJECT_STR + DB_DATAOBJECT_DATE + DB_DATAOBJECT_TIME + DB_DATAOBJECT_NOTNULL);
|
|
|
|
}
|
|
|
|
|
|
|
|
static function schemaDef()
|
|
|
|
{
|
|
|
|
// @fixme need a reverse key on (subscribed, subscriber) as well
|
|
|
|
return array(new ColumnDef('subscriber', 'integer',
|
|
|
|
null, false, 'PRI'),
|
|
|
|
new ColumnDef('subscribed', 'integer',
|
|
|
|
null, false, 'PRI'),
|
|
|
|
|
|
|
|
new ColumnDef('style', 'varchar',
|
|
|
|
16, true),
|
|
|
|
|
|
|
|
new ColumnDef('created', 'datetime',
|
|
|
|
null, false),
|
|
|
|
new ColumnDef('modified', 'datetime',
|
|
|
|
null, false));
|
|
|
|
}
|
|
|
|
|
2010-08-10 19:45:34 +01:00
|
|
|
/**
|
|
|
|
* Temporary hack to set up the compound index, since we can't do
|
|
|
|
* it yet through regular Schema interface. (Coming for 1.0...)
|
2010-09-18 21:31:41 +01:00
|
|
|
*
|
2010-08-10 19:45:34 +01:00
|
|
|
* @param Schema $schema
|
|
|
|
* @return void
|
|
|
|
*/
|
|
|
|
static function fixIndexes($schema)
|
|
|
|
{
|
|
|
|
try {
|
|
|
|
$schema->createIndex('submirror', array('subscribed', 'subscriber'));
|
|
|
|
} catch (Exception $e) {
|
|
|
|
common_log(LOG_ERR, __METHOD__ . ': ' . $e->getMessage());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-08-05 21:37:47 +01:00
|
|
|
/**
|
|
|
|
* return key definitions for DB_DataObject
|
|
|
|
*
|
|
|
|
* DB_DataObject needs to know about keys that the table has; this function
|
|
|
|
* defines them.
|
|
|
|
*
|
|
|
|
* @return array key definitions
|
|
|
|
*/
|
|
|
|
|
|
|
|
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.
|
|
|
|
*
|
|
|
|
* @return array key definitions
|
|
|
|
*/
|
|
|
|
|
|
|
|
function keyTypes()
|
|
|
|
{
|
2011-06-05 23:38:38 +01:00
|
|
|
// @todo FIXME keys
|
2010-08-05 21:37:47 +01:00
|
|
|
// need a sane key for reverse lookup too
|
|
|
|
return array('subscriber' => 'K', 'subscribed' => 'K');
|
|
|
|
}
|
|
|
|
|
|
|
|
function sequenceKey()
|
|
|
|
{
|
|
|
|
return array(false, false, false);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @param Profile $subscribed
|
|
|
|
* @param Profile $subscribed
|
|
|
|
* @return SubMirror
|
|
|
|
* @throws ServerException
|
|
|
|
*/
|
|
|
|
public static function saveMirror($subscriber, $subscribed, $style='repeat')
|
|
|
|
{
|
|
|
|
// @fixme make sure they're subscribed!
|
|
|
|
$mirror = new SubMirror();
|
|
|
|
|
|
|
|
$mirror->subscriber = $subscriber->id;
|
|
|
|
$mirror->subscribed = $subscribed->id;
|
|
|
|
$mirror->style = $style;
|
|
|
|
|
|
|
|
$mirror->created = common_sql_now();
|
|
|
|
$mirror->modified = common_sql_now();
|
|
|
|
$mirror->insert();
|
2010-09-18 21:31:41 +01:00
|
|
|
|
2010-08-05 21:37:47 +01:00
|
|
|
return $mirror;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @param Notice $notice
|
|
|
|
* @return mixed Notice on successful mirroring, boolean if not
|
|
|
|
*/
|
|
|
|
public function mirrorNotice($notice)
|
|
|
|
{
|
|
|
|
$profile = Profile::staticGet('id', $this->subscriber);
|
|
|
|
if (!$profile) {
|
2012-01-27 20:01:51 +00:00
|
|
|
common_log(LOG_ERR, "SubMirror plugin skipping auto-repeat of notice $notice->id for missing user $profile->id");
|
2010-08-05 21:37:47 +01:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ($this->style == 'copy') {
|
|
|
|
return $this->copyNotice($profile, $notice);
|
|
|
|
} else { // default to repeat mode
|
|
|
|
return $this->repeatNotice($profile, $notice);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Mirror a notice using StatusNet's repeat functionality.
|
|
|
|
* This retains attribution within the site, and other nice things,
|
|
|
|
* but currently ends up looking like 'RT @foobar bla bla' when
|
|
|
|
* bridged out over OStatus or TwitterBridge.
|
2010-09-18 21:31:41 +01:00
|
|
|
*
|
2010-08-05 21:37:47 +01:00
|
|
|
* @param Notice $notice
|
|
|
|
* @return mixed Notice on successful repeat, true if already repeated, false on failure
|
|
|
|
*/
|
|
|
|
protected function repeatNotice($profile, $notice)
|
|
|
|
{
|
|
|
|
if($profile->hasRepeated($notice->id)) {
|
|
|
|
common_log(LOG_INFO, "SubMirror plugin skipping auto-repeat of notice $notice->id for user $profile->id; already repeated.");
|
|
|
|
return true;
|
|
|
|
} else {
|
|
|
|
common_log(LOG_INFO, "SubMirror plugin auto-repeating notice $notice->id for $profile->id");
|
|
|
|
return $notice->repeat($profile->id, 'mirror');
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Mirror a notice by emitting a new notice with the same contents.
|
|
|
|
* Kind of dirty, but if pulling an external data feed into an account
|
|
|
|
* that may be what you want.
|
2010-09-18 21:31:41 +01:00
|
|
|
*
|
2010-08-05 21:37:47 +01:00
|
|
|
* @param Notice $notice
|
|
|
|
* @return mixed Notice on successful repeat, true if already repeated, false on failure
|
|
|
|
*/
|
|
|
|
protected function copyNotice($profile, $notice)
|
|
|
|
{
|
|
|
|
$options = array('is_local' => Notice::LOCAL_PUBLIC,
|
|
|
|
'url' => $notice->bestUrl(), // pass through the foreign link...
|
|
|
|
'rendered' => $notice->rendered);
|
|
|
|
|
|
|
|
$saved = Notice::saveNew($profile->id,
|
|
|
|
$notice->content,
|
|
|
|
'feed',
|
|
|
|
$options);
|
|
|
|
return $saved;
|
|
|
|
}
|
|
|
|
|
|
|
|
public /*static*/ function pkeyGet($v)
|
|
|
|
{
|
|
|
|
return parent::pkeyGet(__CLASS__, $v);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Get the mirroring setting for a pair of profiles, if existing.
|
2010-09-18 21:31:41 +01:00
|
|
|
*
|
2010-08-05 21:37:47 +01:00
|
|
|
* @param Profile $subscriber
|
|
|
|
* @param Profile $subscribed
|
|
|
|
* @return mixed Profile or empty
|
|
|
|
*/
|
|
|
|
public static function getMirror($subscriber, $subscribed)
|
|
|
|
{
|
|
|
|
return self::pkeyGet(array('subscriber' => $subscriber->id,
|
|
|
|
'subscribed' => $subscribed->id));
|
|
|
|
}
|
|
|
|
}
|