1: <?php
2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13:
14:
15: class Folks_Friends {
16:
17: 18: 19:
20: static private $instances = array();
21:
22: 23: 24: 25: 26:
27: protected $_params = array();
28:
29: 30: 31: 32: 33:
34: protected $_user;
35:
36: 37: 38: 39: 40:
41: protected $_cache;
42:
43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56:
57: private static function factory($driver = null, $params = null)
58: {
59: if ($driver === null) {
60: $driver = $GLOBALS['conf']['friends']['driver'];
61: }
62:
63: if ($params === null && isset($GLOBALS['conf']['friends']['params'])) {
64: $params = $GLOBALS['conf']['friends']['params'];
65: }
66:
67: $driver = basename($driver);
68:
69: $class = 'Folks_Friends_' . $driver;
70: if (!class_exists($class)) {
71: include dirname(__FILE__) . '/Friends/' . $driver . '.php';
72: }
73: if (class_exists($class)) {
74: return new $class($params);
75: } else {
76: return false;
77: }
78: }
79:
80: 81: 82: 83: 84: 85: 86: 87: 88: 89: 90:
91: static public function singleton($driver = null, $params = null)
92: {
93: if (empty($params['user'])) {
94: $params['user'] = $GLOBALS['registry']->getAuth();
95: }
96:
97: $signature = $driver . ':' . $params['user'];
98: if (!array_key_exists($signature, self::$instances)) {
99: self::$instances[$signature] = self::factory($driver, $params);
100: }
101:
102: return self::$instances[$signature];
103: }
104:
105: 106: 107: 108: 109: 110:
111: protected function __construct($params)
112: {
113: $this->_user = empty($params['user']) ? $GLOBALS['registry']->getAuth() : $params['user'];
114:
115: $this->_cache = $GLOBALS['injector']->getInstance('Horde_Cache');
116: }
117:
118: 119: 120: 121: 122: 123: 124: 125:
126: public function hasCapability($capability)
127: {
128: return !empty($this->_capabilities[$capability]);
129: }
130:
131: 132: 133: 134: 135: 136: 137:
138: public function needsApproval($user)
139: {
140: if ($GLOBALS['prefs']->isLocked('friends_approval')) {
141: return (boolean)$GLOBALS['prefs']->getValue('friends_approval');
142: }
143:
144: $prefs = $GLOBALS['injector']->getInstance('Horde_Core_Factory_Prefs')->create('folks', array(
145: 'cache' => false,
146: 'user' => $GLOBALS['registry']->convertUsername($user, true)
147: ));
148:
149: return (boolean)$prefs->getValue('friends_approval');
150: }
151:
152: 153: 154: 155: 156: 157: 158: 159: 160:
161: public function sendNotification($user, $title, $body)
162: {
163: $to = Folks::getUserEmail($user);
164: if ($to instanceof PEAR_Error) {
165: return $to;
166: }
167:
168: $result = Folks::sendMail($to, $title, $body);
169: if ($result instanceof PEAR_Error) {
170: return $result;
171: }
172:
173: if (!$GLOBALS['registry']->hasInterface('letter')) {
174: return true;
175: }
176:
177: return $GLOBALS['registry']->callByPackage(
178: 'letter', 'sendMessage', array($user,
179: array('title' => $title,
180: 'content' => $body)));
181: }
182:
183: 184: 185: 186: 187:
188: public function getBlacklist()
189: {
190: static $blacklist;
191:
192: if (is_array($blacklist)) {
193: return $blacklist;
194: }
195:
196: $blacklist = $this->_cache->get('folksBlacklist' . $this->_user, $GLOBALS['conf']['cache']['default_lifetime']);
197: if ($blacklist) {
198: return unserialize($blacklist);
199: } else {
200: $blacklist = $this->_getBlacklist();
201: if ($blacklist instanceof PEAR_Error) {
202: return $blacklist;
203: }
204: $this->_cache->set('folksBlacklist' . $this->_user, serialize($blacklist));
205: return $blacklist;
206: }
207: }
208:
209: 210: 211: 212: 213:
214: public function addBlacklisted($user)
215: {
216: if ($this->_user == $user) {
217: return PEAR::raiseError(_("You cannot add yourself to your blacklist."));
218: }
219:
220:
221: $auth = $GLOBALS['injector']->getInstance('Horde_Core_Factory_Auth')->create();
222: if (!$auth->exists($user)) {
223: return PEAR::raiseError(sprintf(_("User \"%s\" does not exits"), $user));
224: }
225:
226:
227: if (in_array($user, $this->_getAdmins())) {
228: return PEAR::raiseError(sprintf(_("You cannot add \"%s\" to your blacklist."), $user));
229: }
230:
231: $result = $this->_addBlacklisted($user);
232: if ($result instanceof PEAR_Error) {
233: return $result;
234: }
235:
236: $this->_cache->expire('folksBlacklist' . $this->_user);
237:
238: return true;
239: }
240:
241: 242: 243: 244: 245:
246: public function removeBlacklisted($user)
247: {
248: $result = $this->_removeBlacklisted($user);
249: if ($result instanceof PEAR_Error) {
250: return $result;
251: }
252:
253: $this->_cache->expire('folksBlacklist' . $this->_user);
254:
255: return true;
256: }
257:
258: 259: 260: 261: 262: 263: 264:
265: public function isBlacklisted($user)
266: {
267: $blacklist = $this->getBlacklist();
268: if ($blacklist instanceof PEAR_Error) {
269: return $blacklist;
270: }
271:
272: return in_array($user, $blacklist);
273: }
274:
275: 276: 277: 278: 279: 280:
281: public function addFriend($friend, $group = null)
282: {
283: $friend = strtolower($friend);
284:
285: if ($this->_user == $friend) {
286: return PEAR::raiseError(_("You cannot add yourself as your own friend."));
287: }
288:
289:
290: $auth = $GLOBALS['injector']->getInstance('Horde_Core_Factory_Auth')->create();
291: if (!$auth->exists($friend)) {
292: return PEAR::raiseError(sprintf(_("User \"%s\" does not exits"), $friend));
293: }
294:
295:
296: $friends = $this->getFriends();
297: if ($friends instanceof PEAR_Error) {
298: return $friends;
299: } elseif (in_array($friend, $friends)) {
300: return PEAR::raiseError(sprintf(_("User \"%s\" is already in fiend list"), $friend));
301: }
302:
303:
304: $friends = $this->waitingApprovalFrom();
305: if ($friends instanceof PEAR_Error) {
306: return $friends;
307: } elseif (in_array($friend, $friends)) {
308: return PEAR::raiseError(sprintf(_("User \"%s\" is already in fiend list, but we are waiting his/her approval."), $friend));
309: }
310:
311:
312: $result = $this->_addFriend($friend, $group);
313: if ($result instanceof PEAR_Error) {
314: return $result;
315: }
316:
317:
318: if (!$this->needsApproval($friend)) {
319: $this->_cache->expire('folksFriends' . $this->_user . $group);
320: }
321:
322: return true;
323: }
324:
325: 326: 327: 328: 329: 330:
331: public function removeFriend($friend, $group = null)
332: {
333: $this->_cache->expire('folksFriends' . $this->_user . $group);
334:
335: return $this->_removeFriend($friend, $group);
336: }
337:
338: 339: 340: 341: 342: 343: 344: 345:
346: public function getFriends($group = null)
347: {
348: static $friends;
349:
350: if (is_array($friends)) {
351: return $friends;
352: }
353:
354: $friends = $this->_cache->get('folksFriends' . $this->_user . $group, $GLOBALS['conf']['cache']['default_lifetime']);
355: if ($friends) {
356: return unserialize($friends);
357: } else {
358: $friends = $this->_getFriends($group);
359: if ($friends instanceof PEAR_Error) {
360: return $friends;
361: }
362: $this->_cache->set('folksFriends' . $this->_user . $group, serialize($friends));
363: return $friends;
364: }
365: }
366:
367: 368: 369:
370: public function waitingApprovalFrom()
371: {
372: return array();
373: }
374:
375: 376: 377:
378: public function waitingApprovalFor()
379: {
380: return array();
381: }
382:
383: 384: 385: 386: 387:
388: public function approveFriend($friend)
389: {
390: $result = $this->_approveFriend($friend);
391: if ($result instanceof PEAR_Error) {
392: return $result;
393: }
394:
395: $this->_cache->expire('folksFriends' . $friend);
396: $this->_cache->expire('folksFriends' . $this->_user);
397:
398: return true;
399: }
400:
401: 402: 403: 404: 405:
406: protected function _approveFriend($friend)
407: {
408: return true;
409: }
410:
411: 412: 413: 414: 415: 416: 417:
418: public function isFriend($user)
419: {
420: if ($user == $this->_user) {
421: return true;
422: }
423:
424: $friends = $this->getFriends();
425: if ($friends instanceof PEAR_Error) {
426: return $friends;
427: }
428:
429: return in_array($user, $friends);
430: }
431:
432: 433: 434: 435: 436: 437: 438: 439:
440: public function getPossibleFriends($limit = 0)
441: {
442: $possibilities = array();
443:
444: $my_list = $this->getFriends();
445: if ($my_list instanceof PEAR_Error) {
446: return $my_list;
447: }
448:
449: foreach ($my_list as $friend) {
450: $friends = Folks_Friends::singleton(null, array('user' => $friend));
451: $friend_friends = $friends->getFriends();
452: if ($friend_friends instanceof PEAR_Error) {
453: continue;
454: }
455: foreach ($friend_friends as $friend_friend) {
456: if ($friend_friend == $this->_user ||
457: in_array($friend_friend, $my_list)) {
458: continue;
459: } elseif (isset($possibilities[$friend_friend])) {
460: $possibilities[$friend_friend] += 1;
461: } else {
462: $possibilities[$friend_friend] = 0;
463: }
464: }
465: }
466:
467: arsort($possibilities);
468:
469: if ($limit) {
470: $possibilities = array_slice($possibilities, 0, $limit, true);
471: $possibilities = array_keys($possibilities);
472: }
473:
474: return $possibilities;
475: }
476:
477: 478: 479: 480: 481:
482: public function friendOf()
483: {
484: return false;
485: }
486:
487: 488: 489: 490: 491: 492: 493:
494: public function getGroupOwner($group)
495: {
496: return $this->_user;
497: }
498:
499: 500: 501:
502: public function getGroups()
503: {
504: $groups = $this->_cache->get('folksGroups' . $this->_user, $GLOBALS['conf']['cache']['default_lifetime']);
505: if ($groups) {
506: return unserialize($groups);
507: } else {
508: $groups = $this->_getGroups();
509: if ($groups instanceof PEAR_Error) {
510: return $groups;
511: }
512: $this->_cache->set('folksGroups' . $this->_user, serialize($groups));
513: return $groups;
514: }
515: }
516:
517: 518: 519:
520: private function _getAdmins()
521: {
522: if (!$GLOBALS['injector']->getInstance('Horde_Perms')->exists('folks:admin')) {
523: return array();
524: }
525:
526: $permission = $GLOBALS['injector']->getInstance('Horde_Perms')->getPermission('folks:admin');
527:
528: return array_merge($permission->getUserPermissions(PERM_DELETE),
529: $GLOBALS['conf']['auth']['admins']);
530: }
531: }
532: