]> git.mxchange.org Git - quix0rs-gnu-social.git/blob - plugins/SubMirror/classes/SubMirror.php
Merge remote branch 'chat-interface-plugins/msn-plugin' into 1.0.x
[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      * Temporary hack to set up the compound index, since we can't do
81      * it yet through regular Schema interface. (Coming for 1.0...)
82      * 
83      * @param Schema $schema
84      * @return void
85      */
86     static function fixIndexes($schema)
87     {
88         try {
89             $schema->createIndex('submirror', array('subscribed', 'subscriber'));
90         } catch (Exception $e) {
91             common_log(LOG_ERR, __METHOD__ . ': ' . $e->getMessage());
92         }
93     }
94
95     /**
96      * return key definitions for DB_DataObject
97      *
98      * DB_DataObject needs to know about keys that the table has; this function
99      * defines them.
100      *
101      * @return array key definitions
102      */
103
104     function keys()
105     {
106         return array_keys($this->keyTypes());
107     }
108
109     /**
110      * return key definitions for Memcached_DataObject
111      *
112      * Our caching system uses the same key definitions, but uses a different
113      * method to get them.
114      *
115      * @return array key definitions
116      */
117
118     function keyTypes()
119     {
120         // @fixme keys
121         // need a sane key for reverse lookup too
122         return array('subscriber' => 'K', 'subscribed' => 'K');
123     }
124
125     function sequenceKey()
126     {
127         return array(false, false, false);
128     }
129
130     /**
131      * @param Profile $subscribed
132      * @param Profile $subscribed
133      * @return SubMirror
134      * @throws ServerException
135      */
136     public static function saveMirror($subscriber, $subscribed, $style='repeat')
137     {
138         // @fixme make sure they're subscribed!
139         $mirror = new SubMirror();
140
141         $mirror->subscriber = $subscriber->id;
142         $mirror->subscribed = $subscribed->id;
143         $mirror->style = $style;
144
145         $mirror->created = common_sql_now();
146         $mirror->modified = common_sql_now();
147         $mirror->insert();
148         
149         return $mirror;
150     }
151
152     /**
153      * @param Notice $notice
154      * @return mixed Notice on successful mirroring, boolean if not
155      */
156     public function mirrorNotice($notice)
157     {
158         $profile = Profile::staticGet('id', $this->subscriber);
159         if (!$profile) {
160             common_log(LOG_ERROR, "SubMirror plugin skipping auto-repeat of notice $notice->id for missing user $profile->id");
161             return false;
162         }
163
164         if ($this->style == 'copy') {
165             return $this->copyNotice($profile, $notice);
166         } else { // default to repeat mode
167             return $this->repeatNotice($profile, $notice);
168         }
169     }
170
171     /**
172      * Mirror a notice using StatusNet's repeat functionality.
173      * This retains attribution within the site, and other nice things,
174      * but currently ends up looking like 'RT @foobar bla bla' when
175      * bridged out over OStatus or TwitterBridge.
176      * 
177      * @param Notice $notice
178      * @return mixed Notice on successful repeat, true if already repeated, false on failure
179      */
180     protected function repeatNotice($profile, $notice)
181     {
182         if($profile->hasRepeated($notice->id)) {
183             common_log(LOG_INFO, "SubMirror plugin skipping auto-repeat of notice $notice->id for user $profile->id; already repeated.");
184             return true;
185         } else {
186             common_log(LOG_INFO, "SubMirror plugin auto-repeating notice $notice->id for $profile->id");
187             return $notice->repeat($profile->id, 'mirror');
188         }
189     }
190
191     /**
192      * Mirror a notice by emitting a new notice with the same contents.
193      * Kind of dirty, but if pulling an external data feed into an account
194      * that may be what you want.
195      * 
196      * @param Notice $notice
197      * @return mixed Notice on successful repeat, true if already repeated, false on failure
198      */
199     protected function copyNotice($profile, $notice)
200     {
201         $options = array('is_local' => Notice::LOCAL_PUBLIC,
202                          'url' => $notice->bestUrl(), // pass through the foreign link...
203                          'rendered' => $notice->rendered);
204
205         $saved = Notice::saveNew($profile->id,
206                                  $notice->content,
207                                  'feed',
208                                  $options);
209         return $saved;
210     }
211
212     public /*static*/ function pkeyGet($v)
213     {
214         return parent::pkeyGet(__CLASS__, $v);
215     }
216
217     /**
218      * Get the mirroring setting for a pair of profiles, if existing.
219      * 
220      * @param Profile $subscriber
221      * @param Profile $subscribed
222      * @return mixed Profile or empty
223      */
224     public static function getMirror($subscriber, $subscribed)
225     {
226         return self::pkeyGet(array('subscriber' => $subscriber->id,
227                                    'subscribed' => $subscribed->id));
228     }
229 }