]> git.mxchange.org Git - quix0rs-gnu-social.git/blob - classes/Profile.php
Merge commit 'refs/merge-requests/1815' of git://gitorious.org/statusnet/mainline...
[quix0rs-gnu-social.git] / classes / Profile.php
1 <?php
2 /*
3  * StatusNet - the distributed open-source microblogging tool
4  * Copyright (C) 2008, 2009, 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 if (!defined('STATUSNET') && !defined('LACONICA')) { exit(1); }
21
22 /**
23  * Table Definition for profile
24  */
25 require_once INSTALLDIR.'/classes/Memcached_DataObject.php';
26
27 class Profile extends Memcached_DataObject
28 {
29     ###START_AUTOCODE
30     /* the code below is auto generated do not remove the above tag */
31
32     public $__table = 'profile';                         // table name
33     public $id;                              // int(4)  primary_key not_null
34     public $nickname;                        // varchar(64)  multiple_key not_null
35     public $fullname;                        // varchar(255)  multiple_key
36     public $profileurl;                      // varchar(255)
37     public $homepage;                        // varchar(255)  multiple_key
38     public $bio;                             // text()  multiple_key
39     public $location;                        // varchar(255)  multiple_key
40     public $created;                         // datetime()   not_null
41     public $modified;                        // timestamp()   not_null default_CURRENT_TIMESTAMP
42
43     /* Static get */
44     function staticGet($k,$v=NULL) { return Memcached_DataObject::staticGet('Profile',$k,$v); }
45
46     /* the code above is auto generated do not remove the tag below */
47     ###END_AUTOCODE
48
49     function getUser()
50     {
51         return User::staticGet('id', $this->id);
52     }
53
54     function getAvatar($width, $height=null)
55     {
56         if (is_null($height)) {
57             $height = $width;
58         }
59         return Avatar::pkeyGet(array('profile_id' => $this->id,
60                                      'width' => $width,
61                                      'height' => $height));
62     }
63
64     function getOriginalAvatar()
65     {
66         $avatar = DB_DataObject::factory('avatar');
67         $avatar->profile_id = $this->id;
68         $avatar->original = true;
69         if ($avatar->find(true)) {
70             return $avatar;
71         } else {
72             return null;
73         }
74     }
75
76     function setOriginal($filename)
77     {
78         $imagefile = new ImageFile($this->id, Avatar::path($filename));
79
80         $avatar = new Avatar();
81         $avatar->profile_id = $this->id;
82         $avatar->width = $imagefile->width;
83         $avatar->height = $imagefile->height;
84         $avatar->mediatype = image_type_to_mime_type($imagefile->type);
85         $avatar->filename = $filename;
86         $avatar->original = true;
87         $avatar->url = Avatar::url($filename);
88         $avatar->created = DB_DataObject_Cast::dateTime(); # current time
89
90         # XXX: start a transaction here
91
92         if (!$this->delete_avatars() || !$avatar->insert()) {
93             @unlink(Avatar::path($filename));
94             return null;
95         }
96
97         foreach (array(AVATAR_PROFILE_SIZE, AVATAR_STREAM_SIZE, AVATAR_MINI_SIZE) as $size) {
98             # We don't do a scaled one if original is our scaled size
99             if (!($avatar->width == $size && $avatar->height == $size)) {
100
101                 $scaled_filename = $imagefile->resize($size);
102
103                 //$scaled = DB_DataObject::factory('avatar');
104                 $scaled = new Avatar();
105                 $scaled->profile_id = $this->id;
106                 $scaled->width = $size;
107                 $scaled->height = $size;
108                 $scaled->original = false;
109                 $scaled->mediatype = image_type_to_mime_type($imagefile->type);
110                 $scaled->filename = $scaled_filename;
111                 $scaled->url = Avatar::url($scaled_filename);
112                 $scaled->created = DB_DataObject_Cast::dateTime(); # current time
113
114                 if (!$scaled->insert()) {
115                     return null;
116                 }
117             }
118         }
119
120         return $avatar;
121     }
122
123     function delete_avatars($original=true)
124     {
125         $avatar = new Avatar();
126         $avatar->profile_id = $this->id;
127         $avatar->find();
128         while ($avatar->fetch()) {
129             if ($avatar->original) {
130                 if ($original == false) {
131                     continue;
132                 }
133             }
134             $avatar->delete();
135         }
136         return true;
137     }
138
139     function getBestName()
140     {
141         return ($this->fullname) ? $this->fullname : $this->nickname;
142     }
143
144     # Get latest notice on or before date; default now
145     function getCurrentNotice($dt=null)
146     {
147         $notice = new Notice();
148         $notice->profile_id = $this->id;
149         if ($dt) {
150             $notice->whereAdd('created < "' . $dt . '"');
151         }
152         $notice->orderBy('created DESC, notice.id DESC');
153         $notice->limit(1);
154         if ($notice->find(true)) {
155             return $notice;
156         }
157         return null;
158     }
159
160     function getTaggedNotices($tag, $offset=0, $limit=NOTICES_PER_PAGE, $since_id=0, $max_id=0, $since=null)
161     {
162         $ids = Notice::stream(array($this, '_streamTaggedDirect'),
163                               array($tag),
164                               'profile:notice_ids_tagged:' . $this->id . ':' . $tag,
165                               $offset, $limit, $since_id, $max_id, $since);
166         return Notice::getStreamByIds($ids);
167     }
168
169     function getNotices($offset=0, $limit=NOTICES_PER_PAGE, $since_id=0, $max_id=0, $since=null)
170     {
171         // XXX: I'm not sure this is going to be any faster. It probably isn't.
172         $ids = Notice::stream(array($this, '_streamDirect'),
173                               array(),
174                               'profile:notice_ids:' . $this->id,
175                               $offset, $limit, $since_id, $max_id, $since);
176
177         return Notice::getStreamByIds($ids);
178     }
179
180     function _streamTaggedDirect($tag, $offset, $limit, $since_id, $max_id, $since)
181     {
182         // XXX It would be nice to do this without a join
183
184         $notice = new Notice();
185
186         $query =
187           "select id from notice join notice_tag on id=notice_id where tag='".
188           $notice->escape($tag) .
189           "' and profile_id=" . $notice->escape($this->id);
190
191         if ($since_id != 0) {
192             $query .= " and id > $since_id";
193         }
194
195         if ($max_id != 0) {
196             $query .= " and id < $max_id";
197         }
198
199         if (!is_null($since)) {
200             $query .= " and created > '" . date('Y-m-d H:i:s', $since) . "'";
201         }
202
203         $query .= ' order by id DESC';
204
205         if (!is_null($offset)) {
206             $query .= " LIMIT $limit OFFSET $offset";
207         }
208
209         $notice->query($query);
210
211         $ids = array();
212
213         while ($notice->fetch()) {
214             $ids[] = $notice->id;
215         }
216
217         return $ids;
218     }
219
220     function _streamDirect($offset, $limit, $since_id, $max_id, $since = null)
221     {
222         $notice = new Notice();
223
224         $notice->profile_id = $this->id;
225
226         $notice->selectAdd();
227         $notice->selectAdd('id');
228
229         if ($since_id != 0) {
230             $notice->whereAdd('id > ' . $since_id);
231         }
232
233         if ($max_id != 0) {
234             $notice->whereAdd('id <= ' . $max_id);
235         }
236
237         if (!is_null($since)) {
238             $notice->whereAdd('created > \'' . date('Y-m-d H:i:s', $since) . '\'');
239         }
240
241         $notice->orderBy('id DESC');
242
243         if (!is_null($offset)) {
244             $notice->limit($offset, $limit);
245         }
246
247         $ids = array();
248
249         if ($notice->find()) {
250             while ($notice->fetch()) {
251                 $ids[] = $notice->id;
252             }
253         }
254
255         return $ids;
256     }
257
258     function isMember($group)
259     {
260         $mem = new Group_member();
261
262         $mem->group_id = $group->id;
263         $mem->profile_id = $this->id;
264
265         if ($mem->find()) {
266             return true;
267         } else {
268             return false;
269         }
270     }
271
272     function isAdmin($group)
273     {
274         $mem = new Group_member();
275
276         $mem->group_id = $group->id;
277         $mem->profile_id = $this->id;
278         $mem->is_admin = 1;
279
280         if ($mem->find()) {
281             return true;
282         } else {
283             return false;
284         }
285     }
286
287     function avatarUrl($size=AVATAR_PROFILE_SIZE)
288     {
289         $avatar = $this->getAvatar($size);
290         if ($avatar) {
291             return $avatar->displayUrl();
292         } else {
293             return Avatar::defaultImage($size);
294         }
295     }
296
297     function getSubscriptions($offset=0, $limit=null)
298     {
299         $qry =
300           'SELECT profile.* ' .
301           'FROM profile JOIN subscription ' .
302           'ON profile.id = subscription.subscribed ' .
303           'WHERE subscription.subscriber = %d ' .
304           'AND subscription.subscribed != subscription.subscriber ' .
305           'ORDER BY subscription.created DESC ';
306
307         if (common_config('db','type') == 'pgsql') {
308             $qry .= ' LIMIT ' . $limit . ' OFFSET ' . $offset;
309         } else {
310             $qry .= ' LIMIT ' . $offset . ', ' . $limit;
311         }
312
313         $profile = new Profile();
314
315         $profile->query(sprintf($qry, $this->id));
316
317         return $profile;
318     }
319
320     function getSubscribers($offset=0, $limit=null)
321     {
322         $qry =
323           'SELECT profile.* ' .
324           'FROM profile JOIN subscription ' .
325           'ON profile.id = subscription.subscriber ' .
326           'WHERE subscription.subscribed = %d ' .
327           'AND subscription.subscribed != subscription.subscriber ' .
328           'ORDER BY subscription.created DESC ';
329
330         if ($offset) {
331             if (common_config('db','type') == 'pgsql') {
332                 $qry .= ' LIMIT ' . $limit . ' OFFSET ' . $offset;
333             } else {
334                 $qry .= ' LIMIT ' . $offset . ', ' . $limit;
335             }
336         }
337
338         $profile = new Profile();
339
340         $cnt = $profile->query(sprintf($qry, $this->id));
341
342         return $profile;
343     }
344
345     function subscriptionCount()
346     {
347         $c = common_memcache();
348
349         if (!empty($c)) {
350             $cnt = $c->get(common_cache_key('profile:subscription_count:'.$this->id));
351             if (is_integer($cnt)) {
352                 return (int) $cnt;
353             }
354         }
355
356         $sub = new Subscription();
357         $sub->subscriber = $this->id;
358
359         $cnt = (int) $sub->count('distinct subscribed');
360
361         $cnt = ($cnt > 0) ? $cnt - 1 : $cnt;
362
363         if (!empty($c)) {
364             $c->set(common_cache_key('profile:subscription_count:'.$this->id), $cnt);
365         }
366
367         return $cnt;
368     }
369
370     function subscriberCount()
371     {
372         $c = common_memcache();
373         if (!empty($c)) {
374             $cnt = $c->get(common_cache_key('profile:subscriber_count:'.$this->id));
375             if (is_integer($cnt)) {
376                 return (int) $cnt;
377             }
378         }
379
380         $sub = new Subscription();
381         $sub->subscribed = $this->id;
382
383         $cnt = (int) $sub->count('distinct subscriber');
384
385         $cnt = ($cnt > 0) ? $cnt - 1 : $cnt;
386
387         if (!empty($c)) {
388             $c->set(common_cache_key('profile:subscriber_count:'.$this->id), $cnt);
389         }
390
391         return $cnt;
392     }
393
394     function faveCount()
395     {
396         $c = common_memcache();
397         if (!empty($c)) {
398             $cnt = $c->get(common_cache_key('profile:fave_count:'.$this->id));
399             if (is_integer($cnt)) {
400                 return (int) $cnt;
401             }
402         }
403
404         $faves = new Fave();
405         $faves->user_id = $this->id;
406         $cnt = (int) $faves->count('distinct notice_id');
407
408         if (!empty($c)) {
409             $c->set(common_cache_key('profile:fave_count:'.$this->id), $cnt);
410         }
411
412         return $cnt;
413     }
414
415     function noticeCount()
416     {
417         $c = common_memcache();
418
419         if (!empty($c)) {
420             $cnt = $c->get(common_cache_key('profile:notice_count:'.$this->id));
421             if (is_integer($cnt)) {
422                 return (int) $cnt;
423             }
424         }
425
426         $notices = new Notice();
427         $notices->profile_id = $this->id;
428         $cnt = (int) $notices->count('distinct id');
429
430         if (!empty($c)) {
431             $c->set(common_cache_key('profile:notice_count:'.$this->id), $cnt);
432         }
433
434         return $cnt;
435     }
436
437     function blowSubscriberCount()
438     {
439         $c = common_memcache();
440         if (!empty($c)) {
441             $c->delete(common_cache_key('profile:subscriber_count:'.$this->id));
442         }
443     }
444
445     function blowSubscriptionCount()
446     {
447         $c = common_memcache();
448         if (!empty($c)) {
449             $c->delete(common_cache_key('profile:subscription_count:'.$this->id));
450         }
451     }
452
453     function blowFaveCount()
454     {
455         $c = common_memcache();
456         if (!empty($c)) {
457             $c->delete(common_cache_key('profile:fave_count:'.$this->id));
458         }
459     }
460
461     function blowNoticeCount()
462     {
463         $c = common_memcache();
464         if (!empty($c)) {
465             $c->delete(common_cache_key('profile:notice_count:'.$this->id));
466         }
467     }
468
469     static function maxBio()
470     {
471         $biolimit = common_config('profile', 'biolimit');
472         // null => use global limit (distinct from 0!)
473         if (is_null($biolimit)) {
474             $biolimit = common_config('site', 'textlimit');
475         }
476         return $biolimit;
477     }
478
479     static function bioTooLong($bio)
480     {
481         $biolimit = self::maxBio();
482         return ($biolimit > 0 && !empty($bio) && (mb_strlen($bio) > $biolimit));
483     }
484
485     function delete()
486     {
487         $this->_deleteNotices();
488         $this->_deleteSubscriptions();
489         $this->_deleteMessages();
490         $this->_deleteTags();
491         $this->_deleteBlocks();
492
493         $related = array('Avatar',
494                          'Reply',
495                          'Group_member',
496                          );
497
498         foreach ($related as $cls) {
499             $inst = new $cls();
500             $inst->profile_id = $this->id;
501             $inst->delete();
502         }
503
504         parent::delete();
505     }
506
507     function _deleteNotices()
508     {
509         $notice = new Notice();
510         $notice->profile_id = $this->id;
511
512         if ($notice->find()) {
513             while ($notice->fetch()) {
514                 $other = clone($notice);
515                 $other->delete();
516             }
517         }
518     }
519
520     function _deleteSubscriptions()
521     {
522         $sub = new Subscription();
523         $sub->subscriber = $this->id;
524         $sub->delete();
525
526         $subd = new Subscription();
527         $subd->subscribed = $this->id;
528         $subd->delete();
529     }
530
531     function _deleteMessages()
532     {
533         $msg = new Message();
534         $msg->from_profile = $this->id;
535         $msg->delete();
536
537         $msg = new Message();
538         $msg->to_profile = $this->id;
539         $msg->delete();
540     }
541
542     function _deleteTags()
543     {
544         $tag = new Profile_tag();
545         $tag->tagged = $this->id;
546         $tag->delete();
547     }
548
549     function _deleteBlocks()
550     {
551         $block = new Profile_block();
552         $block->blocked = $this->id;
553         $block->delete();
554
555         $block = new Group_block();
556         $block->blocked = $this->id;
557         $block->delete();
558     }
559 }