]> git.mxchange.org Git - quix0rs-gnu-social.git/blob - plugins/SubMirror/classes/SubMirror.php
Merge remote branch 'statusnet/1.0.x' into irc-plugin
[quix0rs-gnu-social.git] / plugins / SubMirror / classes / SubMirror.php
1 <?php
2 /*
3  * StatusNet - the distributed open-source microblogging tool
4  * Copyright (C) 2010, StatusNet, Inc.
5  *
6  * This program is free software: you can redistribute it and/or modify
7  * it under the terms of the GNU Affero General Public License as published by
8  * the Free Software Foundation, either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU Affero General Public License for more details.
15  *
16  * You should have received a copy of the GNU Affero General Public License
17  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
18  */
19
20 /**
21  * @package SubMirrorPlugin
22  * @maintainer Brion Vibber <brion@status.net>
23  */
24
25 class SubMirror extends Memcached_DataObject
26 {
27     public $__table = 'submirror';
28
29     public $subscriber;
30     public $subscribed;
31
32     public $style;
33
34     public $created;
35     public $modified;
36
37     public /*static*/ function staticGet($k, $v=null)
38     {
39         return parent::staticGet(__CLASS__, $k, $v);
40     }
41
42     /**
43      * return table definition for DB_DataObject
44      *
45      * DB_DataObject needs to know something about the table to manipulate
46      * instances. This method provides all the DB_DataObject needs to know.
47      *
48      * @return array array of column definitions
49      */
50
51     function table()
52     {
53         return array('subscriber' =>  DB_DATAOBJECT_INT + DB_DATAOBJECT_NOTNULL,
54                      'subscribed' => DB_DATAOBJECT_INT + DB_DATAOBJECT_NOTNULL,
55
56                      'style' => DB_DATAOBJECT_STR,
57
58                      'created' => DB_DATAOBJECT_STR + DB_DATAOBJECT_DATE + DB_DATAOBJECT_TIME + DB_DATAOBJECT_NOTNULL,
59                      'modified' => DB_DATAOBJECT_STR + DB_DATAOBJECT_DATE + DB_DATAOBJECT_TIME + DB_DATAOBJECT_NOTNULL);
60     }
61
62     static function schemaDef()
63     {
64         // @fixme need a reverse key on (subscribed, subscriber) as well
65         return array(new ColumnDef('subscriber', 'integer',
66                                    null, false, 'PRI'),
67                      new ColumnDef('subscribed', 'integer',
68                                    null, false, 'PRI'),
69
70                      new ColumnDef('style', 'varchar',
71                                    16, true),
72
73                      new ColumnDef('created', 'datetime',
74                                    null, false),
75                      new ColumnDef('modified', 'datetime',
76                                    null, false));
77     }
78
79     /**
80      * return key definitions for DB_DataObject
81      *
82      * DB_DataObject needs to know about keys that the table has; this function
83      * defines them.
84      *
85      * @return array key definitions
86      */
87
88     function keys()
89     {
90         return array_keys($this->keyTypes());
91     }
92
93     /**
94      * return key definitions for Memcached_DataObject
95      *
96      * Our caching system uses the same key definitions, but uses a different
97      * method to get them.
98      *
99      * @return array key definitions
100      */
101
102     function keyTypes()
103     {
104         // @fixme keys
105         // need a sane key for reverse lookup too
106         return array('subscriber' => 'K', 'subscribed' => 'K');
107     }
108
109     function sequenceKey()
110     {
111         return array(false, false, false);
112     }
113
114     /**
115      * @param Profile $subscribed
116      * @param Profile $subscribed
117      * @return SubMirror
118      * @throws ServerException
119      */
120     public static function saveMirror($subscriber, $subscribed, $style='repeat')
121     {
122         // @fixme make sure they're subscribed!
123         $mirror = new SubMirror();
124
125         $mirror->subscriber = $subscriber->id;
126         $mirror->subscribed = $subscribed->id;
127         $mirror->style = $style;
128
129         $mirror->created = common_sql_now();
130         $mirror->modified = common_sql_now();
131         $mirror->insert();
132         
133         return $mirror;
134     }
135
136     /**
137      * @param Notice $notice
138      * @return mixed Notice on successful mirroring, boolean if not
139      */
140     public function mirrorNotice($notice)
141     {
142         $profile = Profile::staticGet('id', $this->subscriber);
143         if (!$profile) {
144             common_log(LOG_ERROR, "SubMirror plugin skipping auto-repeat of notice $notice->id for missing user $profile->id");
145             return false;
146         }
147
148         if ($this->style == 'copy') {
149             return $this->copyNotice($profile, $notice);
150         } else { // default to repeat mode
151             return $this->repeatNotice($profile, $notice);
152         }
153     }
154
155     /**
156      * Mirror a notice using StatusNet's repeat functionality.
157      * This retains attribution within the site, and other nice things,
158      * but currently ends up looking like 'RT @foobar bla bla' when
159      * bridged out over OStatus or TwitterBridge.
160      * 
161      * @param Notice $notice
162      * @return mixed Notice on successful repeat, true if already repeated, false on failure
163      */
164     protected function repeatNotice($profile, $notice)
165     {
166         if($profile->hasRepeated($notice->id)) {
167             common_log(LOG_INFO, "SubMirror plugin skipping auto-repeat of notice $notice->id for user $profile->id; already repeated.");
168             return true;
169         } else {
170             common_log(LOG_INFO, "SubMirror plugin auto-repeating notice $notice->id for $profile->id");
171             return $notice->repeat($profile->id, 'mirror');
172         }
173     }
174
175     /**
176      * Mirror a notice by emitting a new notice with the same contents.
177      * Kind of dirty, but if pulling an external data feed into an account
178      * that may be what you want.
179      * 
180      * @param Notice $notice
181      * @return mixed Notice on successful repeat, true if already repeated, false on failure
182      */
183     protected function copyNotice($profile, $notice)
184     {
185         $options = array('is_local' => Notice::LOCAL_PUBLIC,
186                          'url' => $notice->bestUrl(), // pass through the foreign link...
187                          'rendered' => $notice->rendered);
188
189         $saved = Notice::saveNew($profile->id,
190                                  $notice->content,
191                                  'feed',
192                                  $options);
193         return $saved;
194     }
195
196     public /*static*/ function pkeyGet($v)
197     {
198         return parent::pkeyGet(__CLASS__, $v);
199     }
200
201     /**
202      * Get the mirroring setting for a pair of profiles, if existing.
203      * 
204      * @param Profile $subscriber
205      * @param Profile $subscribed
206      * @return mixed Profile or empty
207      */
208     public static function getMirror($subscriber, $subscribed)
209     {
210         return self::pkeyGet(array('subscriber' => $subscriber->id,
211                                    'subscribed' => $subscribed->id));
212     }
213 }