6 foreach my $bit (0..65) {
7 my $def = $LJ::CAP
{$bit};
8 next unless $def->{_key
} && $def->{_key
} eq $class;
14 # what class name does a given bit number represent?
17 return $LJ::CAP
{$bit}->{_key
};
20 sub classes_from_mask
{
24 foreach my $bit (0..15) {
25 my $class = LJ
::class_of_bit
($bit);
26 next unless $class && LJ
::caps_in_group
($caps, $class);
27 push @classes, $class;
33 sub mask_from_classes
{
37 foreach my $class (@classes) {
38 my $bit = LJ
::class_bit
($class);
49 foreach my $bit (@bits) {
57 my ($caps, $class) = @_;
58 my $bit = LJ
::class_bit
($class);
59 unless (defined $bit) {
60 # this site has no underage class? 'underage' is the only
62 return 0 if $class eq "underage";
64 # all other classes are site-defined, so we die on those not existing.
65 die "unknown class '$class'";
68 return ($caps+0 & (1 << $bit)) ?
1 : 0;
73 # des: Given a user's capability class bit mask, returns a
74 # site-specific string representing the capability class name.
76 # des-caps: 16 bit capability bitmask
80 return undef unless LJ
::are_hooks
("name_caps");
82 return LJ
::run_hook
("name_caps", $caps);
86 # name: LJ::name_caps_short
87 # des: Given a user's capability class bit mask, returns a
88 # site-specific short string code.
90 # des-caps: 16 bit capability bitmask
94 return undef unless LJ
::are_hooks
("name_caps_short");
96 return LJ
::run_hook
("name_caps_short", $caps);
100 # name: LJ::user_caps_icon
101 # des: Given a user's capability class bit mask, returns
102 # site-specific HTML with the capability class icon.
104 # des-caps: 16 bit capability bitmask
108 return undef unless LJ
::are_hooks
("user_caps_icon");
110 return LJ
::run_hook
("user_caps_icon", $caps);
115 # des: Given a user object, capability class key or capability class bit mask
116 # and a capability/limit name,
117 # returns the maximum value allowed for given user or class, considering
118 # all the limits in each class the user is a part of.
119 # args: u_cap, capname
120 # des-u_cap: 16 bit capability bitmask or a user object from which the
121 # bitmask could be obtained
122 # des-capname: the name of a limit, defined in [special[caps]].
126 my $caps = shift; # capability bitmask (16 bits), cap key or user object
127 my $cname = shift; # capability limit name
128 my $opts = shift; # { no_hook => 1/0 }
131 # If caps is a reference
132 my $u = ref $caps ?
$caps : undef;
134 # If caps is a reference get caps from User object
136 $caps = $u->{'caps'};
137 # If it is not all digits assume it is a key
138 } elsif ($caps && $caps !~ /^\d+$/) {
139 $caps = 1 << LJ
::class_bit
($caps);
141 # The caps is the cap mask already or undef, force it to be a number
146 # allow a way for admins to force-set the read-only cap
147 # to lower writes on a cluster.
148 if ($cname eq "readonly" && $u &&
149 ($LJ::READONLY_CLUSTER
{$u->{clusterid
}} ||
150 $LJ::READONLY_CLUSTER_ADVISORY
{$u->{clusterid
}} &&
151 ! LJ
::get_cap
($u, "avoid_readonly"))) {
153 # HACK for desperate moments. in when_needed mode, see if
154 # database is locky first
155 my $cid = $u->{clusterid
};
156 if ($LJ::READONLY_CLUSTER_ADVISORY
{$cid} eq "when_needed") {
158 return 1 if $LJ::LOCKY_CACHE
{$cid} > $now - 15;
160 my $dbcm = LJ
::get_cluster_master
($u->{clusterid
});
161 return 1 unless $dbcm;
162 my $sth = $dbcm->prepare("SHOW PROCESSLIST");
164 return 1 if $dbcm->err;
166 my $too_busy = $LJ::WHEN_NEEDED_THRES
|| 300;
167 while (my $r = $sth->fetchrow_hashref) {
168 $busy++ if $r->{Command
} ne "Sleep";
170 if ($busy > $too_busy) {
171 $LJ::LOCKY_CACHE
{$cid} = $now;
179 # underage/coppa check etc
180 if ($cname eq "underage" && $u && $u->in_class("underage")) {
184 # is there a hook for this cap name?
185 if (! $opts->{no_hook
} && LJ
::are_hooks
("check_cap_$cname")) {
186 die "Hook 'check_cap_$cname' requires full user object"
188 my $val = LJ
::run_hook
("check_cap_$cname", $u, $opts);
189 return $val if defined $val;
191 # otherwise fall back to standard means
194 # otherwise check via other means
195 foreach my $bit (keys %LJ::CAP
) {
196 next unless ($caps & (1 << $bit));
197 my $v = $LJ::CAP
{$bit}->{$cname};
198 next unless (defined $v);
199 next if (defined $max && $max > $v);
203 return defined $max ?
$max : $LJ::CAP_DEF
{$cname};
207 # name: LJ::get_cap_min
208 # des: Just like [func[LJ::get_cap]], but returns the minimum value.
209 # Although it might not make sense at first, some things are
210 # better when they're low, like the minimum amount of time
211 # a user might have to wait between getting updates or being
212 # allowed to refresh a page.
213 # args: u_cap, capname
214 # des-u_cap: 16 bit capability bitmask or a user object from which the
215 # bitmask could be obtained
216 # des-capname: the name of a limit, defined in [special[caps]].
220 my $caps = shift; # capability bitmask (16 bits), or user object
221 my $cname = shift; # capability name
222 if (! defined $caps) { $caps = 0; }
223 elsif (isu
($caps)) { $caps = $caps->{'caps'}; }
225 foreach my $bit (keys %LJ::CAP
) {
226 next unless ($caps & (1 << $bit));
227 my $v = $LJ::CAP
{$bit}->{$cname};
228 next unless (defined $v);
229 next if (defined $min && $min < $v);
232 return defined $min ?
$min : $LJ::CAP_DEF
{$cname};