Overview

Packages

  • Folks
  • None

Classes

  • Folks
  • Folks_Activity_Form
  • Folks_Api
  • Folks_Application
  • Folks_Block_Activities
  • Folks_Block_Friends
  • Folks_Block_Know
  • Folks_Block_New
  • Folks_Block_Random
  • Folks_Block_Recent
  • Folks_Driver
  • Folks_Driver_sql
  • Folks_Friends
  • Folks_Friends_application
  • Folks_Friends_facebook
  • Folks_Friends_prefs
  • Folks_Friends_shared
  • Folks_Friends_sql
  • Folks_Login_Form
  • Folks_Notification
  • Folks_Notification_facebook
  • Folks_Notification_letter
  • Folks_Notification_mail
  • Folks_Notification_tickets
  • Folks_Search_Form
  • Overview
  • Package
  • Class
  • Tree
  1: <?php
  2: /**
  3:  * Folks_Friends:: defines an API for implementing storage backends for
  4:  * Friends.
  5:  *
  6:  * Copyright Obala d.o.o. (www.obala.si)
  7:  *
  8:  * See the enclosed file COPYING for license information (GPL). If you
  9:  * did not receive this file, see http://www.horde.org/licenses/gpl.
 10:  *
 11:  * @author Duck <duck@obala.net>
 12:  * @package Folks
 13:  */
 14: 
 15: class Folks_Friends {
 16: 
 17:     /**
 18:      * Friends instances
 19:      */
 20:     static private $instances = array();
 21: 
 22:     /**
 23:      * Hash containing connection parameters.
 24:      *
 25:      * @var array
 26:      */
 27:     protected $_params = array();
 28: 
 29:     /**
 30:      * String containing user
 31:      *
 32:      * @var string
 33:      */
 34:     protected $_user;
 35: 
 36:     /**
 37:      * String cache reference
 38:      *
 39:      * @var Horde_Cache
 40:      */
 41:     protected $_cache;
 42: 
 43:     /**
 44:      * Attempts to return a concrete Folks_Friends instance based on $friends.
 45:      *
 46:      * @param string $friends  The type of the concrete Folks_Friends subclass
 47:      *                        to return.  The class name is based on the
 48:      *                        storage Friends ($friends).  The code is
 49:      *                        dynamically included.
 50:      *
 51:      * @param array $params   A hash containing any additional configuration
 52:      *                        or connection parameters a subclass might need.
 53:      *
 54:      * @return Folks_Friends  The newly created concrete Folks_Friends
 55:      *                          instance, or false on an error.
 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:      * Singleton for driver object
 82:      *
 83:      * @param string $friends  The type of the concrete Folks_Friends subclass
 84:      *                        to return.  The class name is based on the
 85:      *                        storage Friends ($friends).  The code is
 86:      *                        dynamically included.
 87:      *
 88:      * @param array $params   A hash containing any additional configuration
 89:      *                        or connection parameters a subclass might need.
 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:      * Construct object
107:      *
108:      * @param array $params   A hash containing any additional configuration
109:      *                        or connection parameters a subclass might need.
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:      * Queries the current object to find out if it supports the given
120:      * capability.
121:      *
122:      * @param string $capability  The capability to test for.
123:      *
124:      * @return boolean  Whether or not the capability is supported.
125:      */
126:     public function hasCapability($capability)
127:     {
128:         return !empty($this->_capabilities[$capability]);
129:     }
130: 
131:     /**
132:      * Check if a users requies his approval to be added as a friend
133:      *
134:      * @param string $user   Usersame
135:      *
136:      * @return boolean
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:      * Send user a nofication or approve request
154:      *
155:      * @param string $user   Usersame
156:      * @param string $title   Title of notification
157:      * @param string $body   Content of notification
158:      *
159:      * @return boolean
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:      * Get user blacklist
185:      *
186:      * @return array of users blacklist
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:      * Add user to a blacklist list
211:      *
212:      * @param string $user   Usersame
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:         // Check if users exits
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:         // Do not allow to blacklist adminstrators
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:      * Remove user from blacklist list
243:      *
244:      * @param string $user   Usersame
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:      * Check if user is on blacklist
260:      *
261:      * @param string $user User to check
262:      *
263:      * @return boolean
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:      * Add user to a friend list
277:      *
278:      * @param string $friend   Friend's usersame
279:      * @param string $group    Group to add friend to
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:         // Check if users exits
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:         // Check if user exists in group
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:         // Check if user is frend but has not confmed us yet
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:         // Add friend to backend
312:         $result = $this->_addFriend($friend, $group);
313:         if ($result instanceof PEAR_Error) {
314:             return $result;
315:         }
316: 
317:         // If we do not need an approval just expire cache
318:         if (!$this->needsApproval($friend)) {
319:             $this->_cache->expire('folksFriends' . $this->_user . $group);
320:         }
321: 
322:         return true;
323:     }
324: 
325:     /**
326:      * Remove user from a fiend list
327:      *
328:      * @param string $friend   Friend's usersame
329:      * @param string $group   Group to remove friend from
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:      * Get user friends
340:      *
341:      * @param string $user   Username
342:      * @param string $group  Get friens only from this group
343:      *
344:      * @return array of users (in group)
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:      * Get friends that does not confirm the current user yet
369:      */
370:     public function waitingApprovalFrom()
371:     {
372:         return array();
373:     }
374: 
375:     /**
376:      * User that we do not confirm them user yet
377:      */
378:     public function waitingApprovalFor()
379:     {
380:         return array();
381:     }
382: 
383:     /**
384:      * Approve our friend to add us to his userlist
385:      *
386:      * @param string $friend  Friend username
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:      * Approve our friend to add us to his userlist
403:      *
404:      * @param string $friend  Friedn username
405:      */
406:     protected function _approveFriend($friend)
407:     {
408:         return true;
409:     }
410: 
411:     /**
412:      * Check if user is on blacklist
413:      *
414:      * @param string $user User to check
415:      *
416:      * @return boolean
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:      * Return all friends of out frends
434:      * and make a top list of common users
435:      *
436:      * @param int $limit Users
437:      *
438:      * @return array users
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:      * Get users who have us on their friendlist
479:      *
480:      * @return array users
481:      */
482:     public function friendOf()
483:     {
484:         return false;
485:     }
486: 
487:     /**
488:      * Get user owning group
489:      *
490:      * @param integer Get group ID
491:      *
492:      * @param string Owner
493:      */
494:     public function getGroupOwner($group)
495:     {
496:         return $this->_user;
497:     }
498: 
499:     /**
500:      * Get user groups
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:      * Get administartor usernames
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: 
API documentation generated by ApiGen