## WORNING:
## This is legacy from slash. deprecated, and you can use only backword-compatible.
+#========================================================================
+
+=head2 dbAvailable([TOKEN])
+
+Returns TRUE if (as usual) the DB(s) are available for reading and
+writing. Returns FALSE if the DB(s) are not available and should not
+be accessed. If a TOKEN is named, return FALSE if either the DB(s)
+required for that purpose are down or all DBs are down. If no TOKEN is
+named, return FALSE only if all DBs are down.
+
+Whether or not the DBs are down is determined only by whether files exist
+at /usr/local/slash/dboff or /usr/local/slash/dboff_TOKEN. For best
+results, admins will want to write their own db-angel scripts that detect
+DBs having gone down and create one or more of those files.
+
+=over 4
+
+=item Parameters
+
+=over 4
+
+=item TOKEN
+
+Name of the resource specifically being asked about, or the
+empty string.
+
+=back
+
+=item Return value
+
+0 or 1.
+
+=back
+
+=cut
+
+sub dbAvailable {
+ return 1;
+}
+
+#========================================================================
+
+=head2 getCurrentStatic([MEMBER])
+
+Returns the current static variables (or variable).
+
+Slash's original implement was depended to Apache and memcached,
+but this implement uses redis for cache.
+
+And in this implement, this function is method.
+
+=over 4
+
+=item Parameters
+
+=over 4
+
+=item MEMBER
+
+A member from the static record to be returned.
+
+=back
+
+=item Return value
+
+A hash reference with the static information is returned unless MEMBER is passed. If
+MEMBER is passed in then only its value will be returned.
+
+=back
+
+=cut
+
+sub getCurrentStatic {
+ my ($self, $value, $force_secure) = @_;
+ my $kvs = $self->connect_kvs;
+ my $kvs_key = "slash_static";
+ my $constants;
+
+ if ($kvs->exists($kvs_key)) {
+ $constants = $kvs->hgetall($kvs_key);
+ }
+ else {
+ $constants = $self->getSlashConf(0, 0);
+ $kvs->hmset($kvs_key, $constants);
+ }
+
+ return defined $value ? $constants->{$value} : $constants;
+}
+
+########################################################
+sub _getSlashConf_rawvars {
+ my($self, $secure, $skipcache) = @_;
+ $secure = $secure ? 1 : 0;
+# my $vu = $self->{virtual_user};
+# return undef unless $vu;
+# my $mcd = $self->getMCD({ no_getcurrentstatic => 1 });
+# my $mcdkey= "x:vars$secure";
+# my $got_from_memcached = 0;
+ my $vars_hr;
+# if ($mcd && !$skipcache) {
+# if ($vars_hr = $mcd->get($mcdkey)) {
+# $got_from_memcached = 1;
+# }
+# }
+ $vars_hr ||= $self->sqlSelectAllKeyValue('name, value', 'vars');
+# if ($mcd && !$got_from_memcached) {
+# # Cache this for about 3 minutes. should be a var.
+# my $expire_time = 180;
+# $mcd->set($mcdkey, $vars_hr, $expire_time);
+# }
+ return $vars_hr;
+}
+
+########################################################
+# Now, the idea is to not cache here, since we actually
+# cache elsewhere (namely in %Slash::Apache::constants) - Brian
+# I'm caching this in memcached now though. - Jamie
+sub getSlashConf {
+ my($self, $secure, $skipcache) = @_;
+
+ # Get the raw vars data (possibly from a memcached cache).
+
+ my $vars_hr = $self->_getSlashConf_rawvars($secure, $skipcache);
+ return if !defined $vars_hr;
+ my %conf = %$vars_hr;
+
+ # Now start adding and tweaking the data for various reasons:
+ # convenience, fixing bad data, etc.
+
+ # This allows you to do stuff like constant.plugin.Zoo in a template
+ # and know that the plugin is installed -Brian
+ my $plugindata = $self->sqlSelectColArrayref('value', 'site_info',
+ "name='plugin'");
+ for my $plugin (@$plugindata) {
+ $conf{plugin}{$plugin} = 1;
+ }
+ my $tagboxdata = $self->sqlSelectColArrayref('value', 'site_info',
+ "name='tagbox'");
+ for my $tagbox (@$tagboxdata) {
+ $conf{tagbox}{$tagbox} = 1;
+ }
+
+ # This really should be a separate piece of data returned by
+ # getReasons() the same way getTopicTree() works. It's only part
+ # of $constants for historical, er, reasons.
+ if ($conf{m1}) {
+ $conf{reasons} = $self->sqlSelectAllHashref(
+ "id", "*", "modreasons"
+ );
+ $conf{reasons_base} = $self->sqlSelectAllHashref(
+ "id", "*", "modreasons", "m2able = 1 OR val = 0"
+ );
+ $conf{reasons_plused} = $self->sqlSelectAllHashref(
+ "id", "*", "modreasons", "m2able = 1 OR val <= 0"
+ );
+ $conf{reasons_minused} = $self->sqlSelectAllHashref(
+ "id", "*", "modreasons", "m2able = 1 OR val >= 0"
+ );
+ foreach my $d (split(/,/, $conf{modreasons_select_disabled} || '')) {
+ $conf{reasons}{int($d)}{select_disabled} = 1;
+ $conf{reasons_base}{int($d)}{select_disabled} = 1;
+ $conf{reasons_plused}{int($d)}{select_disabled} = 1;
+ $conf{reasons_minused}{int($d)}{select_disabled} = 1;
+ }
+ }
+
+ $conf{rootdir} ||= "//$conf{basedomain}";
+ $conf{real_rootdir} ||= $conf{rootdir}; # for when rootdir changes
+ $conf{real_section} ||= $conf{section}; # for when section changes
+ $conf{absolutedir} ||= "http://$conf{basedomain}";
+ $conf{imagedir} ||= "$conf{rootdir}/images";
+ # If absolutedir_secure is not defined, it defaults to the
+ # same as absolutedir. Same for imagedir_secure.
+ $conf{absolutedir_secure} ||= $conf{absolutedir};
+ $conf{imagedir_secure} ||= $conf{imagedir};
+ $conf{css_extension} = 'css';
+# if (defined &Slash::Apache::ConnectionIsSSL && Slash::Apache::ConnectionIsSSL())
+ if ($secure) {
+ # On Secure HTTP connections, force absolutedir/imagedir to
+ # be the secure versions.
+ $conf{imagedir} = $conf{imagedir_secure};
+ $conf{absolutedir} = $conf{absolutedir_secure};
+ $conf{css_extension} = 'ssl.css';
+ }
+ $conf{cssdir} ||= $conf{css_use_imagedir} ? $conf{imagedir} : $conf{rootdir};
+ $conf{rdfimg} ||= "$conf{imagedir}/topics/topicslash.gif";
+ $conf{adminmail_mod} ||= $conf{adminmail};
+ $conf{adminmail_post} ||= $conf{adminmail};
+ $conf{adminmail_ban} ||= $conf{adminmail};
+ $conf{basedir} ||= "$conf{datadir}/public_html";
+ $conf{index_handler} ||= 'index.pl';
+ $conf{cookiepath} ||= URI->new($conf{rootdir})->path . '/';
+ $conf{maxkarma} = 999 unless defined $conf{maxkarma};
+ $conf{minkarma} = -999 unless defined $conf{minkarma};
+ $conf{expiry_exponent} = 1 unless defined $conf{expiry_exponent};
+ $conf{panic} ||= 0;
+ $conf{textarea_rows} ||= 10;
+ $conf{textarea_cols} ||= 50;
+ $conf{allow_deletions} ||= 1;
+ $conf{authors_unlimited} = 100 if !defined $conf{authors_unlimited}
+ || $conf{authors_unlimited} == 1;
+ # m2_consensus must be odd
+ $conf{m2_consensus} = 2*int(($conf{m2_consensus} || 5)/2) + 1
+ if !$conf{m2_consensus}
+ || ($conf{m2_consensus}-1)/2 != int(($conf{m2_consensus}-1)/2);
+ $conf{nick_chars} ||= q{ abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789$_.+!*'(),-};
+ $conf{nick_maxlen} ||= 20;
+ $conf{cookie_location} ||= 'classbid';
+ $conf{login_temp_minutes} ||= 10;
+ # For all fields that it is safe to default to -1 if their
+ # values are not present...
+ for (qw[min_expiry_days max_expiry_days min_expiry_comm max_expiry_comm]) {
+ $conf{$_} = -1 unless exists $conf{$_};
+ }
+
+ # no trailing newlines on directory variables
+ # possibly should rethink this for basedir,
+ # since some OSes don't use /, and if we use File::Spec
+ # everywhere this won't matter, but still should be do
+ # it for the others, since they are URL paths
+ # -- pudge
+ for (qw[rootdir absolutedir imagedir imagedir_secure basedir]) {
+ $conf{$_} =~ s|/+$||;
+ }
+
+ my $fixup = sub {
+ return [ ] if !$_[0];
+ [
+ map {(
+ s/^\s+//,
+ s/\s+$//,
+ $_
+ )[-1]}
+ split /\|/, $_[0]
+ ];
+ };
+ my $fixup_hash = sub {
+ my $ar = $fixup->(@_);
+ my $hr = { };
+ return $hr if !$ar;
+ for my $str (@$ar) {
+ my($k, $v) = split(/=/, $str);
+ $v = 1 if !defined($v);
+ $v = [ split ",", $v ] if $v =~ /,/;
+ $hr->{$k} = $v;
+ }
+ $hr;
+ };
+
+ my %conf_fixup_arrays = (
+ # var name # default array value
+ # -------- # -------------------
+ anonymous_coward_uids => [ $conf{anonymous_coward_uid} ],
+ # See <http://www.iana.org/assignments/uri-schemes>
+ approved_url_schemes => [qw( ftp http gopher mailto news nntp telnet wais https )],
+ approvedtags => [qw( b i p br a ol ul li dl dt dd em strong tt blockquote div ecode quote)],
+ approvedtags_break => [qw( p br ol ul li dl dt dd blockquote div img hr )],
+ # all known tags, plus table, pre, and slash; this can be overridden
+ # in vars, but since we make this all known tags by default ...
+ # easier to just keep it in here
+ approvedtags_admin => [qw( b i p br a ol ul li dl dt dd em strong tt blockquote div ecode
+ img hr big small sub sup span
+ dfn code samp kbd var cite address ins del
+ h1 h2 h3 h4 h5 h6
+ table thead tbody tfoot tr th td pre
+ slash
+ )],
+ charrefs_bad_entity => [qw( zwnj zwj lrm rlm )],
+ charrefs_bad_numeric => [qw( 8204 8205 8206 8207 8236 8237 8238 )],
+ charrefs_good_entity => [qw( amp lt gt euro pound yen rsquo lsquo rdquo ldquo ndash mdash )],
+ charrefs_good_numeric => [ ],
+ cur_performance_stat_ops => [ ],
+ firehose_story_ignore_skids => [ ],
+ fixhrefs => [ ],
+ hc_possible_fonts => [ ],
+ lonetags => [ ],
+ m2_sliding_consensus => [ ],
+ op_exclude_from_countdaily => [qw( rss )],
+ op_extras_countdaily => [ ],
+ mod_stats_reports => [ $conf{adminmail_mod} ],
+ stats_reports => [ $conf{adminmail} ],
+ stats_metrics_reports => [ $conf{adminmail} ],
+ stats_sfnet_groupids => [ 4421 ],
+ submit_categories => [ ],
+ skins_recenttopics => [ ],
+ subnet_karma_post_limit_range => [ ],
+ search_ignore_skids => [ ],
+ );
+ my %conf_fixup_hashes = (
+ # var name # default hash of keys/values
+ # -------- # --------------------
+ ad_messaging_sections => { },
+ comments_perday_bykarma => { -1 => 2, 25 => 25, 99999 => 50 },
+ karma_adj => { -10 => 'Terrible', -1 => 'Bad', 0 => 'Neutral',
+ 12 => 'Positive', 25 => 'Good', 99999 => 'Excellent' },
+ mod_up_points_needed => { },
+ # m2_f_t m2_u_t m1_t m1_k
+ m2_consequences => { 0.00 => [qw( -5 +2 -100 -1 )],
+ 0.15 => [qw( -2 +1 -40 -1 )],
+ 0.30 => [qw( -0.5 +0.5 -20 0 )],
+ 0.35 => [qw( 0 0 -10 0 )],
+ 0.49 => [qw( 0 0 -4 0 )],
+ 0.60 => [qw( 0 0 +1 0 )],
+ 0.70 => [qw( 0 0 +2 0 )],
+ 0.80 => [qw( +0.01 -1 +3 0 )],
+ 0.90 => [qw( +0.02 -2 +4 0 )],
+ 1.00 => [qw( +0.05 -5 +5 +0.5 )], },
+ m2_consequences_repeats => { 3 => -4, 5 => -12, 10 => -100 },
+ # 40=0|30=Mainpage|20=0|10=Sectional|0=0
+ topic_popup_weights => { 40 => 0, 30 => 'Mainpage', 20 => 0, 10 => 'Sectional', 0 => 0 },
+ );
+ for my $key (keys %conf_fixup_arrays) {
+ if (defined($conf{$key})) {
+ $conf{$key} = $fixup->($conf{$key});
+ } else {
+ $conf{$key} = $conf_fixup_arrays{$key};
+ }
+ }
+ for my $key (keys %conf_fixup_hashes) {
+ if (defined($conf{$key})) {
+ $conf{$key} = $fixup_hash->($conf{$key});
+ } else {
+ $conf{$key} = $conf_fixup_hashes{$key};
+ }
+ }
+
+ for my $var (qw(email_domains_invalid submit_domains_invalid)) {
+ if ($conf{$var}) {
+ my $regex = sprintf('[^\w-](?:%s)$',
+ join '|', map quotemeta, split ' ', $conf{$var});
+ $conf{$var} = qr{$regex};
+ }
+ }
+
+ if ($conf{comment_nonstartwordchars}) {
+ # Expand this into a complete regex. We catch not only
+ # these chars in their raw form, but also all HTML entities
+ # (because Windows/MSIE refuses to break before any word
+ # that starts with either the chars, or their entities).
+ # Build the regex with qr// and match entities for
+ # optimal speed.
+ my $src = $conf{comment_nonstartwordchars};
+ my @chars = ( );
+ my @entities = ( );
+ for my $i (0..length($src)-1) {
+ my $c = substr($src, $i, 1);
+ push @chars, "\Q$c";
+ push @entities, ord($c);
+ push @entities, sprintf("x%x", ord($c));
+ }
+ my $dotchar =
+ '(?:'
+ . '[' . join("", @chars) . ']'
+ . '|&#(?:' . join("|", @entities) . ');'
+ . ')';
+ my $regex = '(\s+)' . "((?:<[^>]+>)*$dotchar+)" . '(\S)';
+ $conf{comment_nonstartwordchars_regex} = qr{$regex}i;
+ }
+
+ for my $regex (qw(
+ accesslog_imageregex
+ x_forwarded_for_trust_regex
+ lowbandwidth_bids_regex
+ )) {
+ next if !$conf{$regex} || $conf{$regex} eq 'NONE';
+ $conf{$regex} = qr{$conf{$regex}};
+ }
+
+ # anchor
+ for my $regex (qw(
+ feed_types
+ )) {
+ next if !$conf{$regex};
+ $conf{$regex} = qr{^(?:$conf{$regex})$};
+ }
+
+
+ for my $var (qw(approvedtags approvedtags_break lonetags)) {
+ $conf{$var} = [ map lc, @{$conf{$var}} ];
+ }
+
+ for my $attrname (qw(approvedtags_attr approvedtags_attr_admin)) {
+ if ($conf{$attrname}) {
+ my $approvedtags_attr = $conf{$attrname};
+ $conf{$attrname} = {};
+ my @tags = split /\s+/, $approvedtags_attr;
+ foreach my $tag (@tags){
+ my($tagname, $attr_info) = $tag =~ /([^:]*)(?:\:(.*))?$/;
+ my @attrs = split ',', ($attr_info || '');
+ my $ord = 1;
+ foreach my $attr (@attrs){
+ my($at, $extra) = split /_/, $attr;
+ $extra ||= '';
+ $at = lc $at;
+ $tagname = lc $tagname;
+ $conf{$attrname}{$tagname}{$at}{ord} = $ord;
+ $conf{$attrname}{$tagname}{$at}{req} = 1 if $extra =~ /R/;
+ $conf{$attrname}{$tagname}{$at}{req} = 2 if $extra =~ /N/; # "necessary"
+ $conf{$attrname}{$tagname}{$at}{url} = 1 if $extra =~ /U/;
+ $ord++;
+ }
+ }
+ }
+ }
+ if ($conf{approvedtags_attr} && $conf{approvedtags_attr_admin}) {
+ for (keys %{$conf{approvedtags_attr}}) {
+ # only add to _admin if not already in it
+ $conf{approvedtags_attr_admin}{$_} ||= $conf{approvedtags_attr}{$_};
+ }
+ }
+
+ # We only need to do this on startup. This var isn't really used;
+ # see the code comment in getObject().
+ $conf{classes} = $self->getClasses();
+
+ if ($conf{utf8}) {
+ foreach my $k (keys %conf) {
+ next if ref($conf{$k}) ne 'SCALAR' || Encode::is_utf8($conf{$k});
+ Encode::_utf8_on($conf{$k});
+ }
+ }
+
+ return \%conf;
+}
+
+
sub sqlConnect {
my ($self, $restart) = @_;
if ($restart) {
}
} # end closure
-
1;