8 use LJ
::RelationService
;
10 #########################
21 # C - do not receive mass mailing from community
22 # J - ban in journalpromo
25 #########################
29 # des: Checks to see if a user is a friend of another user.
30 # returns: boolean; 1 if user B is a friend of user A or if A == B
32 # des-usera: Source user hashref or userid.
33 # des-userb: Destination user hashref or userid. (can be undef)
36 my ($ua, $ub) = @_[0, 1];
38 $ua = LJ
::want_user
($ua);
39 $ub = LJ
::want_user
($ub);
41 return 0 unless $ua && $ub;
42 return 1 if $ua == $ub;
44 if (LJ
::is_enabled
('new_friends_and_subscriptions')) {
45 my $res1 = LJ
::RelationService
->is_relation_to($ua, $ub, 'F');
47 if ($ua->is_community) {
51 my $res2 = LJ
::RelationService
->is_relation_to($ub, $ua, 'F');
53 return $res1 && $res2 ?
1 : 0;
56 # get group mask from the first argument to the second argument and
57 # see if first bit is set. if it is, they're a friend. get_groupmask
58 # is memcached and used often, so it's likely to be available quickly.
59 return LJ
::get_groupmask
(@_[0, 1]) & 1;
64 # des: Checks to see if a user is banned from a journal.
65 # returns: boolean; 1 if "user" is banned from "journal"
67 # des-user: User hashref or userid.
68 # des-journal: Journal hashref or userid.
71 # get user and journal ids
72 my $uid = LJ
::want_userid
(shift);
73 my $jid = LJ
::want_userid
(shift);
75 return 1 unless $uid && $jid;
76 return 0 if $uid == $jid;
78 # edge from journal -> user
79 return LJ
::check_rel
($jid, $uid, 'B');
83 my ($journal, $remote) = @_;
84 return 0 unless $journal && $remote;
86 $remote = LJ
::want_user
($remote);
87 $journal = LJ
::want_user
($journal);
89 if (LJ
::is_enabled
('new_friends_and_subscriptions')) {
90 if (my $groupmask = LJ
::RelationService
->get_groupmask($journal, $remote)) {
91 return $groupmask + 0;
94 if (my $groupmask = LJ
::User
::Groups
->get_groupmask($journal, $remote)) {
95 return $groupmask + 0;
101 return LJ
::RelationService
->get_groupmask($journal, $remote) + 0;
105 # name: LJ::load_rel_user
106 # des: Load user relationship information. Loads all relationships of type 'type' in
107 # which user 'userid' participates on the left side (is the source of the
109 # args: db?, userid, type
110 # des-userid: userid or a user hash to load relationship information for.
111 # des-type: type of the relationship
112 # returns: reference to an array of userids
115 my $db = isdb
($_[0]) ?
shift : undef;
116 my ($u, $type, %args) = @_;
118 return undef unless $u and $type;
120 my $limit = int(delete $args{limit
} || 50000);
122 my @uids = LJ
::RelationService
->find_relation_destinations($u, $type, limit
=> $limit, db
=> $db, %args);
127 # name: LJ::load_rel_user_cache
128 # des: Loads user relationship information of the type 'type' where user
129 # 'targetid' participates on the left side (is the source of the relationship)
130 # trying memcache first. The results from this sub should be
131 # <strong>treated as inaccurate and out of date</strong>.
133 # des-userid: userid or a user hash to load relationship information for.
134 # des-type: type of the relationship
135 # returns: reference to an array of userids
137 sub load_rel_user_cache
{
138 my ($userid, $type) = @_;
139 return undef unless $type && $userid;
141 my $u = LJ
::want_user
($userid);
142 return undef unless $u;
144 return LJ
::load_rel_user
($u, $type);
148 # name: LJ::load_rel_target
149 # des: Load user relationship information. Loads all relationships of type 'type' in
150 # which user 'targetid' participates on the right side (is the target of the
152 # args: db?, targetid, type
153 # des-targetid: userid or a user hash to load relationship information for.
154 # des-type: type of the relationship
155 # returns: reference to an array of userids
157 sub load_rel_target
{
158 my $db = isdb
($_[0]) ?
shift : undef;
159 my ($u, $type, %args) = @_;
161 return undef unless $u and $type;
163 my $limit = int(delete $args{limit
} || 50000);
165 my @uids = LJ
::RelationService
->find_relation_sources($u, $type, limit
=> $limit, db
=> $db, %args);
170 # name: LJ::_get_rel_memcache
171 # des: Helper function: returns memcached value for a given (userid, targetid, type) triple, if valid.
172 # args: userid, targetid, type
173 # des-userid: source userid, nonzero
174 # des-targetid: target userid, nonzero
175 # des-type: type (reluser) or typeid (rel2) of the relationship
176 # returns: undef on failure, 0 or 1 depending on edge existence
178 sub _get_rel_memcache
{
179 return undef unless @LJ::MEMCACHE_SERVERS
;
180 return undef if $LJ::DISABLED
{memcache_reluser
};
182 my ($userid, $targetid, $type) = @_;
183 return undef unless $userid && $targetid && defined $type;
186 my $relkey = [$userid, "rel:$userid:$targetid:$type"]; # rel $uid->$targetid edge
187 my $modukey = [$userid, "relmodu:$userid:$type" ]; # rel modtime for uid
188 my $modtkey = [$targetid, "relmodt:$targetid:$type" ]; # rel modtime for targetid
190 # do a get_multi since $relkey and $modukey are both hashed on $userid
191 my $memc = LJ
::MemCacheProxy
::get_multi
($relkey, $modukey);
192 return undef unless $memc && ref $memc eq 'HASH';
195 my $rel = $memc->{$relkey->[1]};
196 return undef unless $rel && ref $rel eq 'ARRAY';
198 # check rel modtime for $userid
199 my $relmodu = $memc->{$modukey->[1]};
200 return undef if ! $relmodu || $relmodu > $rel->[1];
202 # check rel modtime for $targetid
203 my $relmodt = LJ
::MemCacheProxy
::get
($modtkey);
204 return undef if ! $relmodt || $relmodt > $rel->[1];
206 # return memcache value if it's up-to-date
207 return $rel->[0] ?
1 : 0;
211 # name: LJ::_set_rel_memcache
212 # des: Helper function: sets memcache values for a given (userid, targetid, type) triple
213 # args: userid, targetid, type
214 # des-userid: source userid, nonzero
215 # des-targetid: target userid, nonzero
216 # des-type: type (reluser) or typeid (rel2) of the relationship
217 # returns: 1 on success, undef on failure
219 sub _set_rel_memcache
{
220 return 1 unless @LJ::MEMCACHE_SERVERS
;
222 my ($userid, $targetid, $type, $val) = @_;
223 return undef unless $userid && $targetid && defined $type;
227 my $relkey = [$userid, "rel:$userid:$targetid:$type"]; # rel $uid->$targetid edge
228 my $modukey = [$userid, "relmodu:$userid:$type" ]; # rel modtime for uid
229 my $modtkey = [$targetid, "relmodt:$targetid:$type" ]; # rel modtime for targetid
232 my $exp = $now + 3600*6; # 6 hour
234 LJ
::MemCacheProxy
::set
($relkey, [$val, $now], $exp);
235 LJ
::MemCacheProxy
::set
($modukey, $now, $exp);
236 LJ
::MemCacheProxy
::set
($modtkey, $now, $exp);
242 # name: LJ::check_rel
243 # des: Checks whether two users are in a specified relationship to each other.
244 # args: db?, userid, targetid, type
245 # des-userid: source userid, nonzero; may also be a user hash.
246 # des-targetid: target userid, nonzero; may also be a user hash.
247 # des-type: type of the relationship
248 # returns: 1 if the relationship exists, 0 otherwise
251 my ($userid, $targetid, $type) = @_;
252 return undef unless $type && $userid && $targetid;
255 if ( ref $type eq 'ARRAY' ) {
256 $result = LJ
::RelationService
->is_relation_type_to($userid, $targetid, $type);
258 $result = LJ
::RelationService
->is_relation_to($userid, $targetid, $type);
265 # des: Sets relationship information for two users.
266 # args: dbs?, userid, targetid, type
267 # des-dbs: Deprecated; optional, a master/slave set of database handles.
268 # des-userid: source userid, or a user hash
269 # des-targetid: target userid, or a user hash
270 # des-type: type of the relationship
271 # returns: 1 if set succeeded, otherwise undef
274 my ($userid, $targetid, $type) = @_;
276 return LJ
::RelationService
->create_relation_to($userid, $targetid, $type);
280 # name: LJ::set_rel_multi
281 # des: Sets relationship edges for lists of user tuples.
283 # des-edges: array of arrayrefs of edges to set: [userid, targetid, type].
285 # userid: source userid, or a user hash;
286 # targetid: target userid, or a user hash;
287 # type: type of the relationship.
288 # returns: 1 if all sets succeeded, otherwise undef
291 return LJ
::RelationService
->set_rel_multi( \
@_ );
295 # name: LJ::clear_rel_multi
296 # des: Clear relationship edges for lists of user tuples.
298 # des-edges: array of arrayrefs of edges to clear: [userid, targetid, type].
300 # userid: source userid, or a user hash;
301 # targetid: target userid, or a user hash;
302 # type: type of the relationship.
303 # returns: 1 if all clears succeeded, otherwise undef
305 sub clear_rel_multi
{
306 return LJ
::RelationService
->clear_rel_multi( \
@_ );
310 # name: LJ::clear_rel
311 # des: Deletes a relationship between two users or all relationships of a particular type
312 # for one user, on either side of the relationship.
313 # info: One of userid,targetid -- bit not both -- may be '*'. In that case,
314 # if, say, userid is '*', then all relationship edges with target equal to
315 # targetid and of the specified type are deleted.
316 # If both userid and targetid are numbers, just one edge is deleted.
317 # args: dbs?, userid, targetid, type
318 # des-dbs: Deprecated; optional, a master/slave set of database handles.
319 # des-userid: source userid, or a user hash, or '*'
320 # des-targetid: target userid, or a user hash, or '*'
321 # des-type: type of the relationship
322 # returns: 1 if clear succeeded, otherwise undef
325 my ($userid, $targetid, $type) = @_;
326 return undef if $userid eq '*' and $targetid eq '*';
329 $u = LJ
::want_user
($userid) unless $userid eq '*';
330 $userid = LJ
::want_userid
($userid) unless $userid eq '*';
331 $targetid = LJ
::want_userid
($targetid) unless $targetid eq '*';
332 return undef unless $type && $userid && $targetid;
334 my $result = LJ
::RelationService
->remove_relation_to($userid, $targetid, $type);
335 return undef unless $result;