Diff -- /var/www/vhosts/3dshawn.com/affiliate.3dshawn.com/preferences.cgi
Diff

/var/www/vhosts/3dshawn.com/affiliate.3dshawn.com/preferences.cgi

added on local at 2026-07-01 13:47:38

Added
+187
lines
Removed
-0
lines
Context
0
unchanged
Blobs
from
to 94d363b1373c
Restore this content →
Unified diff
Naive LCS-based line diff. Additions in emerald, deletions in rose. Both sides decompressed live from BLOB_STORE.
1#!/usr/bin/perl
2#======================================================================
3# AffSoft -- Preferences (notifications + UI prefs + module visibility)
4#
5# Replaces the "Notifications" + "Available Features" portions of the
6# old settings.cgi. Account/identity moved to profile.cgi.
7#
8# Handles:
9# save_notifications -- 6 toggle keys, persisted as JSON in
10# user_settings.notification_prefs
11#
12# Modules block is read-only -- it shows which features the user's plan
13# includes vs. locks behind an upgrade.
14#======================================================================
15use strict;
16use warnings;
17
18use lib '/var/www/vhosts/3dshawn.com/affiliate.3dshawn.com';
19use CGI;
20use MODS::Template;
21use MODS::DBConnect;
22use MODS::Login;
23use MODS::AffSoft::Config;
24use MODS::AffSoft::Wrapper;
25use MODS::AffSoft::Billing;
26
27my $q = CGI->new;
28my $form = $q->Vars;
29my $auth = MODS::Login->new;
30my $wrap = MODS::AffSoft::Wrapper->new;
31my $tfile = MODS::Template->new;
32my $db = MODS::DBConnect->new;
33my $cfg = MODS::AffSoft::Config->new;
34my $bill = MODS::AffSoft::Billing->new;
35my $DB = $cfg->settings('database_name');
36
37$|=1;
38my $userinfo = $auth->login_verify();
39if (!$userinfo) {
40 print "Status: 302 Found\nLocation: /login.cgi\n\n";
41 exit;
42}
43my $uid = $userinfo->{user_id};
44$uid =~ s/[^0-9]//g;
45
46my $dbh = $db->db_connect();
47
48# ---- Notification prefs schema (mirrored into JSON in user_settings) -
49my @NOTIF_KEYS = qw(
50 sale_alerts
51 platform_health
52 review_digest
53 ab_winners
54 weekly_summary
55 marketing
56);
57my %NOTIF_DEFAULT = (
58 sale_alerts => 1,
59 platform_health => 1,
60 review_digest => 1,
61 ab_winners => 1,
62 weekly_summary => 1,
63 marketing => 0,
64);
65
66sub _esc {
67 my $s = shift;
68 $s //= '';
69 $s =~ s/\\/\\\\/g;
70 $s =~ s/'/''/g;
71 return $s;
72}
73
74sub _parse_notif_json {
75 my ($raw) = @_;
76 my %out = %NOTIF_DEFAULT;
77 return \%out unless $raw && $raw =~ /\S/;
78 foreach my $k (@NOTIF_KEYS) {
79 if ($raw =~ /"\Q$k\E"\s*:\s*(true|false|0|1)/i) {
80 my $v = lc $1;
81 $out{$k} = ($v eq 'true' || $v eq '1') ? 1 : 0;
82 }
83 }
84 return \%out;
85}
86
87sub _build_notif_json {
88 my ($prefs) = @_;
89 my @parts;
90 foreach my $k (@NOTIF_KEYS) {
91 my $v = $prefs->{$k} ? 1 : 0;
92 push @parts, qq{"$k":$v};
93 }
94 return '{' . join(',', @parts) . '}';
95}
96
97# ---- POST handlers -------------------------------------------------
98my $saved_msg = '';
99
100if (($form->{action} || '') eq 'save_notifications') {
101 my %prefs;
102 foreach my $k (@NOTIF_KEYS) {
103 $prefs{$k} = ($form->{"notif_$k"} ? 1 : 0);
104 }
105 my $json = _build_notif_json(\%prefs);
106
107 $db->db_readwrite($dbh, qq~
108 INSERT INTO `${DB}`.user_settings
109 SET user_id='$uid',
110 notification_prefs='~ . _esc($json) . qq~',
111 marketing_opt_in='~ . ($prefs{marketing} ? 1 : 0) . qq~'
112 ON DUPLICATE KEY UPDATE
113 notification_prefs=VALUES(notification_prefs),
114 marketing_opt_in=VALUES(marketing_opt_in)
115 ~, $ENV{SCRIPT_NAME}, __LINE__);
116 $saved_msg = 'Notification preferences saved.';
117}
118
119# ---- Load current state --------------------------------------------
120my $s = $db->db_readwrite($dbh, qq~
121 SELECT notification_prefs, marketing_opt_in
122 FROM `${DB}`.user_settings
123 WHERE user_id='$uid'
124~, $ENV{SCRIPT_NAME}, __LINE__) || {};
125my $prefs = _parse_notif_json($s->{notification_prefs});
126$prefs->{marketing} = $s->{marketing_opt_in} ? 1 : 0 if exists $s->{marketing_opt_in};
127
128# ---- Plan entitlement state for the "Available Features" block ------
129my @entitlements = $bill->user_feature_entitlements($db, $dbh, $DB, $uid);
130my $plan_label_for_features = (@entitlements && $entitlements[0]->{plan_label})
131 || 'Free';
132my @feature_rows;
133my %ICON_SVG = (
134 send => '<path d="M22 2 11 13"/><path d="m22 2-7 20-4-9-9-4 20-7Z"/>',
135 store => '<path d="m3 9 1-5h16l1 5"/><path d="M5 9v11a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1V9"/>',
136 activity => '<path d="M22 12h-4l-3 9L9 3l-3 9H2"/>',
137 chart => '<path d="M3 3v18h18"/><path d="m7 14 4-4 4 4 5-5"/>',
138 people => '<path d="M17 21v-2a4 4 0 0 0-4-4H5a4 4 0 0 0-4 4v2"/><circle cx="9" cy="7" r="4"/>',
139);
140foreach my $f (@entitlements) {
141 push @feature_rows, {
142 key => $f->{key},
143 name => $f->{name},
144 blurb => $f->{blurb},
145 icon_svg => $ICON_SVG{ $f->{icon} } || $ICON_SVG{chart},
146 included => $f->{included} ? 1 : 0,
147 locked => $f->{locked} ? 1 : 0,
148 module_href => '/' . ($f->{module} || 'dashboard') . '.cgi',
149 };
150}
151
152$db->db_disconnect($dbh);
153
154my $tvars = {
155 user_id => $uid,
156 saved_msg => $saved_msg,
157 has_saved_msg => $saved_msg ? 1 : 0,
158
159 notif_sale_alerts_on => $prefs->{sale_alerts} ? 'on' : '',
160 notif_platform_health_on => $prefs->{platform_health} ? 'on' : '',
161 notif_review_digest_on => $prefs->{review_digest} ? 'on' : '',
162 notif_ab_winners_on => $prefs->{ab_winners} ? 'on' : '',
163 notif_weekly_summary_on => $prefs->{weekly_summary} ? 'on' : '',
164 notif_marketing_on => $prefs->{marketing} ? 'on' : '',
165
166 notif_sale_alerts_checked => $prefs->{sale_alerts} ? 'checked' : '',
167 notif_platform_health_checked => $prefs->{platform_health} ? 'checked' : '',
168 notif_review_digest_checked => $prefs->{review_digest} ? 'checked' : '',
169 notif_ab_winners_checked => $prefs->{ab_winners} ? 'checked' : '',
170 notif_weekly_summary_checked => $prefs->{weekly_summary} ? 'checked' : '',
171 notif_marketing_checked => $prefs->{marketing} ? 'checked' : '',
172
173 plan_label_for_features => $plan_label_for_features,
174 features => \@feature_rows,
175 has_features => scalar(@feature_rows) ? 1 : 0,
176};
177
178print "Content-Type: text/html; charset=utf-8\nCache-Control: no-store, no-cache, must-revalidate, max-age=0\nPragma: no-cache\nExpires: 0\n\n";
179
180my $body = join('', $tfile->template('affsoft_preferences.html', $tvars, $userinfo));
181
182$wrap->render({
183 userinfo => $userinfo,
184 page_key => 'preferences',
185 title => 'Preferences',
186 body => $body,
187});
Keyboard: j next diff k previous diff g top G bottom r restore c compile-check ? help