1 package BSE::UI::Affiliate;
3 use base qw(BSE::UI::Dispatch);
4 use BSE::Util::Tags qw(tag_hash);
15 sub actions { \%actions }
17 sub default_action { 'show' }
21 BSE::UI::Affiliate - set the affiliate code for new orders or display a user info page
25 # display a user's information or affiliate page
27 http://your.site.com/cgi-bin/affiliate.pl?id=I<number>
29 # set the stored affiliate code and refresh to the top of the site
31 http://your.site.com/cgi-bin/affiliate.pl?a_set=1&id=I<code>
33 # set the stored affiliate code and refresh to I<url>
35 http://your.site.com/cgi-bin/affiliate.pl?a_set=1&id=I<code>&r=I<url>
39 This is the implementation of L<affiliate.pl>.
47 This is called to set the affiliate code.
49 Requires that an C<id> parameter be supplied with the affiliate code
50 which is stored in the user session. This is then stored in the order
51 record if the user creates an order before the cookie expires. This
52 id can be any string, it need not be a user on the current site.
54 Optionally, you can supply a C<r> parameter which will be refreshed to
55 after the affiliate code is set. If this is not supplied there will
56 be a refresh to either C<default_refresh> in C<[affiliate]> in
57 C<bse.cfg> or to the top of the site.
59 If your site url and site secureurl are different then there will be
60 an intermediate refresh to C<a_set2> to set the affiliate code on the
61 other side of the site. C<a_set2> will then refresh to your supplied
62 C<r> parameter or its default.
64 You can also configure which referer header values are permitted in
65 bse.cfg. See L<config/[affiliate]> for more information.
70 my ($class, $req) = @_;
74 my $id = $cgi->param('id');
76 defined($id) && $id =~ /^\w+$/
77 or return $class->req_none($req, "Missing or invalid id");
79 my $allowed_referer = $cfg->entry('affiliate', 'allowed_referer');
80 my $require_referer = $cfg->entry('affiliate', 'require_referer');
81 if ($allowed_referer) {
82 my @allowed = split /;/, $allowed_referer;
83 my $referer = $ENV{HTTP_REFERER};
85 my ($domain) = ($referer =~ m!^\w+://([\w/]+)!);
88 for my $entry (@allowed) {
91 if (length($entry) <= length($domain) &&
92 $entry eq substr($domain, -length($entry))) {
98 or return $class->req_none($req, "$referer not in the permitted list of referers");
102 and return $class->req_none($req, 'Referer not supplied');
106 my $url = $cgi->param('r');
107 $url ||= $cfg->entry('affiliate', 'default_refresh');
108 $url ||= $cfg->entryVar('site', 'url');
110 $req->session->{affiliate_code} = $id;
112 # set it on the other side too, if needed
113 my $baseurl = $cfg->entryVar('site', 'url');
114 my $securl = $cfg->entryVar('site', 'secureurl');
116 if ($baseurl eq $securl) {
117 return BSE::Template->get_refresh($url, $cfg);
120 # which host are we on?
121 # first get info about the 2 possible hosts
122 my ($baseprot, $basehost, $baseport) =
123 $baseurl =~ m!^(\w+)://([\w.-]+)(?::(\d+))?!;
124 $baseport ||= $baseprot eq 'http' ? 80 : 443;
126 # get info about the current host
127 my $port = $ENV{SERVER_PORT} || 80;
128 my $ishttps = exists $ENV{HTTPS} || exists $ENV{SSL_CIPHER};
129 my $protocol = $ishttps ? 'https' : 'http';
132 if (lc $ENV{SERVER_NAME} ne lc $basehost
133 || lc $protocol ne $baseprot
134 || $baseport != $port) {
135 print STDERR "not on base host ('$ENV{SERVER_NAME}' cmp '$basehost' '$protocol cmp '$baseprot' $baseport cmp $port\n";
139 my $setter = $onbase ? $securl : $baseurl;
140 $setter .= "$ENV{SCRIPT_NAME}?a_set2=1&id=".escape_uri($id);
141 $setter .= "&r=".escape_uri($url);
142 return BSE::Template->get_refresh($setter, $cfg);
148 Sets the affiliate code for the "other" side of the site.
150 This should only be linked to by the C<a_set> target.
152 This does no referer checks.
156 # yes, this completely removes any point of the referer checks, but
157 # since referer checks aren't a security issue anyway, it doesn't
161 my ($class, $req) = @_;
165 my $id = $cgi->param('id');
167 defined($id) && $id =~ /^\w+$/
168 or return $class->req_none($req, "Missing or invalid id");
170 $req->session->{affiliate_code} = $id;
172 my $url = $cgi->param('r');
173 $url ||= $cfg->entry('affiliate', 'default_refresh');
174 $url ||= $cfg->entryVar('site', 'url');
176 return BSE::Template->get_refresh($url, $cfg);
181 Display the affiliate page based on a user id number.
183 This is the default target, so you do not need to supply a target
186 The page is displayed based on the C<affiliate.tmpl> template.
188 The basic user side tags are available, as well as the C<siteuser> tag
189 which gives access to the site user's record.
191 Be careful about which information you display.
196 my ($class, $req) = @_;
201 my $id = $cgi->param('id');
203 or return $class->req_none($req, "No identifier supplied");
205 my $user = SiteUsers->getByPkey($id);
207 or return $class->req_none($req, "Unknown user");
208 # require BSE::TB::Subscriptions;
209 # my $subid = $cfg->entry('affiliate', 'subscription_required');
211 # my $sub = BSE::TB::Subscriptions->getByPkey($subid)
212 # || BSE::TB::Subscriptions->getBy(text_id => $subid)
213 # or return $class->req_none($req, "Configuration error: Unknown subscription id");
219 BSE::Util::Tags->basic(undef, $req->cgi, $req->cfg),
220 siteuser => [ \&tag_hash, $user ],
223 return $req->dyn_response('affiliate', \%acts);
227 my ($class, $req, $msg) = @_;
229 print STDERR "Something went wrong: $msg\n" if $msg;
231 # just refresh to the home page
232 my $url = $req->cfg->entry('site', 'url');
233 return BSE::Template->get_refresh($url, $req->cfg);
240 Tony Cook <tony@develop-help.com>