251 lines
5.5 KiB
Perl
251 lines
5.5 KiB
Perl
|
|
# This code was forked from the LiveJournal project owned and operated
|
||
|
|
# by Live Journal, Inc. The code has been modified and expanded by
|
||
|
|
# Dreamwidth Studios, LLC. These files were originally licensed under
|
||
|
|
# the terms of the license supplied by Live Journal, Inc, which can
|
||
|
|
# currently be found at:
|
||
|
|
#
|
||
|
|
# http://code.livejournal.org/trac/livejournal/browser/trunk/LICENSE-LiveJournal.txt
|
||
|
|
#
|
||
|
|
# In accordance with the original license, this code and all its
|
||
|
|
# modifications are provided under the GNU General Public License.
|
||
|
|
# A copy of that license can be found in the LICENSE file included as
|
||
|
|
# part of this distribution.
|
||
|
|
|
||
|
|
package LJ::PageStats;
|
||
|
|
use strict;
|
||
|
|
use DW::SiteScheme;
|
||
|
|
|
||
|
|
my $all_modules;
|
||
|
|
|
||
|
|
# loads a page stat tracker
|
||
|
|
sub new {
|
||
|
|
my ($class) = @_;
|
||
|
|
|
||
|
|
unless ( defined $all_modules ) {
|
||
|
|
$all_modules = [ LJ::ModuleLoader::module_subclasses('DW::PageStats') ];
|
||
|
|
}
|
||
|
|
my $self = {
|
||
|
|
conf => {
|
||
|
|
_active => $all_modules,
|
||
|
|
},
|
||
|
|
ctx => '',
|
||
|
|
};
|
||
|
|
|
||
|
|
bless $self, $class;
|
||
|
|
return $self;
|
||
|
|
}
|
||
|
|
|
||
|
|
# render JS output for embedding in pages
|
||
|
|
# ctx can be "journal" or "app". defaults to "app".
|
||
|
|
sub render {
|
||
|
|
my ($self) = @_;
|
||
|
|
|
||
|
|
my $ctx = $self->get_context;
|
||
|
|
|
||
|
|
return '' unless $self->should_do_pagestats;
|
||
|
|
|
||
|
|
my $output = '';
|
||
|
|
foreach my $plugin ( $self->get_active_plugins ) {
|
||
|
|
my $class = $plugin;
|
||
|
|
eval "use $class; 1;";
|
||
|
|
die "Error loading PageStats '$plugin': $@" if $@;
|
||
|
|
my $plugin_obj = $class->new;
|
||
|
|
next unless $plugin_obj->should_render;
|
||
|
|
$output .= $plugin_obj->_render( conf => $self->{conf}->{$plugin} );
|
||
|
|
}
|
||
|
|
|
||
|
|
# return nothing
|
||
|
|
return
|
||
|
|
"<div id='statistics' style='text-align: left; font-size:0; line-height:0; height:0; overflow:hidden;'>$output</div>";
|
||
|
|
}
|
||
|
|
|
||
|
|
# render JS output that goes into the <head> tags
|
||
|
|
sub render_head {
|
||
|
|
my ($self) = @_;
|
||
|
|
my $ctx = $self->get_context;
|
||
|
|
|
||
|
|
return '' unless $self->should_do_pagestats;
|
||
|
|
|
||
|
|
my $output = '';
|
||
|
|
foreach my $plugin ( $self->get_active_plugins ) {
|
||
|
|
my $class = $plugin;
|
||
|
|
eval "use $class; 1;";
|
||
|
|
die "Error loading PageStats '$plugin': $@" if $@;
|
||
|
|
my $plugin_obj = $class->new;
|
||
|
|
next unless $plugin_obj->should_render;
|
||
|
|
$output .= $plugin_obj->_render_head( conf => $self->{conf}->{$plugin} );
|
||
|
|
}
|
||
|
|
|
||
|
|
return $output;
|
||
|
|
}
|
||
|
|
|
||
|
|
sub _render {
|
||
|
|
return "";
|
||
|
|
}
|
||
|
|
|
||
|
|
sub _render_head {
|
||
|
|
return "";
|
||
|
|
}
|
||
|
|
|
||
|
|
# method on root object (LJ::PageStats instance) to decide if user has
|
||
|
|
# opted-out of page stats tracking. Note: this isn't pagestat-specific logic.
|
||
|
|
# that's in the "should_render" method.
|
||
|
|
sub should_do_pagestats {
|
||
|
|
my $self = shift;
|
||
|
|
|
||
|
|
my $u = $self->get_user;
|
||
|
|
my $ctx = $self->get_context;
|
||
|
|
|
||
|
|
if ( $ctx && $ctx eq 'journal' ) {
|
||
|
|
return 0 if $u && $u->exclude_from_own_stats && $u->equals( LJ::get_active_journal() );
|
||
|
|
}
|
||
|
|
|
||
|
|
return 1;
|
||
|
|
}
|
||
|
|
|
||
|
|
# decide if tracker should be embedded in page
|
||
|
|
sub should_render {
|
||
|
|
my ($self) = @_;
|
||
|
|
|
||
|
|
my $ctx = $self->get_context;
|
||
|
|
return 0 unless ( $ctx && $ctx =~ /^(app|journal)$/ );
|
||
|
|
|
||
|
|
my $r = DW::Request->get or return 0;
|
||
|
|
|
||
|
|
# Make sure we don't exclude tracking from this page or path
|
||
|
|
return 0 if grep { $r->uri =~ /$_/ } @{ $LJ::PAGESTATS_EXCLUDE{'uripath'} };
|
||
|
|
|
||
|
|
# See if their ljuniq cookie has the PageStats flag
|
||
|
|
if ( $r->cookie('ljuniq') =~ /[a-zA-Z0-9]{15}:\d+:pgstats([01])/ ) {
|
||
|
|
return 0 unless $1; # Don't serve PageStats if it is "pgstats:0"
|
||
|
|
}
|
||
|
|
else {
|
||
|
|
return 0; # They don't have it set this request, but will for the next one
|
||
|
|
}
|
||
|
|
|
||
|
|
return 1;
|
||
|
|
}
|
||
|
|
|
||
|
|
sub get_context {
|
||
|
|
my ($self) = @_;
|
||
|
|
|
||
|
|
return LJ::get_active_journal() ? 'journal' : 'app';
|
||
|
|
}
|
||
|
|
|
||
|
|
sub get_user {
|
||
|
|
my ($self) = @_;
|
||
|
|
|
||
|
|
return LJ::get_remote();
|
||
|
|
}
|
||
|
|
|
||
|
|
# return Apache request
|
||
|
|
sub get_request {
|
||
|
|
my ($self) = @_;
|
||
|
|
|
||
|
|
return BML::get_request();
|
||
|
|
}
|
||
|
|
|
||
|
|
sub get_root {
|
||
|
|
my ($self) = @_;
|
||
|
|
|
||
|
|
return $LJ::SITEROOT;
|
||
|
|
}
|
||
|
|
|
||
|
|
sub get_active_plugins {
|
||
|
|
my ($self) = @_;
|
||
|
|
|
||
|
|
my $conf = $self->get_conf;
|
||
|
|
|
||
|
|
return () unless $conf;
|
||
|
|
|
||
|
|
return @{ $conf->{_active} || [] };
|
||
|
|
}
|
||
|
|
|
||
|
|
sub get_conf {
|
||
|
|
my ($self) = @_;
|
||
|
|
|
||
|
|
return $self->{conf};
|
||
|
|
}
|
||
|
|
|
||
|
|
sub filename {
|
||
|
|
my ($self) = @_;
|
||
|
|
my $r = $self->get_request;
|
||
|
|
|
||
|
|
my $filename = $r->filename;
|
||
|
|
$filename =~ s!$LJ::HOME/(?:ssldocs|htdocs)!!;
|
||
|
|
|
||
|
|
return $filename;
|
||
|
|
}
|
||
|
|
|
||
|
|
sub journaltype {
|
||
|
|
my $self = shift;
|
||
|
|
|
||
|
|
my $j = LJ::get_active_journal();
|
||
|
|
|
||
|
|
return $j->journaltype_readable;
|
||
|
|
}
|
||
|
|
|
||
|
|
sub journalbase {
|
||
|
|
my $self = shift;
|
||
|
|
|
||
|
|
my $j = LJ::get_active_journal();
|
||
|
|
|
||
|
|
return $j->journal_base;
|
||
|
|
}
|
||
|
|
|
||
|
|
sub is_journal_ctx {
|
||
|
|
my $self = shift;
|
||
|
|
my $ctx = $self->get_context;
|
||
|
|
|
||
|
|
return 1 if ( $ctx eq 'journal' );
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
# not implemented for livejournal
|
||
|
|
sub groups {
|
||
|
|
my ($self) = @_;
|
||
|
|
|
||
|
|
return undef;
|
||
|
|
}
|
||
|
|
|
||
|
|
sub scheme {
|
||
|
|
return DW::SiteScheme->current;
|
||
|
|
}
|
||
|
|
|
||
|
|
sub language {
|
||
|
|
my ($self) = @_;
|
||
|
|
|
||
|
|
my $lang = LJ::Lang::get_effective_lang();
|
||
|
|
|
||
|
|
return $lang;
|
||
|
|
}
|
||
|
|
|
||
|
|
sub loggedin {
|
||
|
|
my ($self) = @_;
|
||
|
|
|
||
|
|
my $loggedin = $self->get_user ? '1' : '0';
|
||
|
|
|
||
|
|
return $loggedin;
|
||
|
|
}
|
||
|
|
|
||
|
|
sub campaign_tracking {
|
||
|
|
my ( $self, $opts ) = @_;
|
||
|
|
|
||
|
|
return '' unless $self->should_do_pagestats;
|
||
|
|
|
||
|
|
my $output = '';
|
||
|
|
foreach my $plugin ( $self->get_active_plugins ) {
|
||
|
|
my $class = $plugin;
|
||
|
|
eval "use $class; 1;";
|
||
|
|
die "Error loading PageStats '$plugin': $@" if $@;
|
||
|
|
my $plugin_obj = $class->new;
|
||
|
|
next unless $plugin_obj->should_render;
|
||
|
|
next unless ( $plugin_obj->can('campaign_track_html') );
|
||
|
|
$output .= $plugin_obj->campaign_track_html($opts);
|
||
|
|
}
|
||
|
|
|
||
|
|
return $output;
|
||
|
|
}
|
||
|
|
|
||
|
|
1;
|