Diff -- /var/www/vhosts/3dshawn.com/shop.3dshawn.com/categories.cgi
Diff

/var/www/vhosts/3dshawn.com/shop.3dshawn.com/categories.cgi

added on local at 2026-07-01 22:09:31

Added
+174
lines
Removed
-0
lines
Context
0
unchanged
Blobs
from
to ac90f760d487
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# ShopCart -- seller-side category manager.
4#
5# GET /categories.cgi -> list + new-form
6# POST /categories.cgi (_act=...) -> create / update / delete
7#======================================================================
8use strict;
9use warnings;
10
11use lib '/var/www/vhosts/3dshawn.com/shop.3dshawn.com';
12use CGI;
13use MODS::Template;
14use MODS::DBConnect;
15use MODS::Login;
16use MODS::ShopCart::Config;
17use MODS::ShopCart::Wrapper;
18use MODS::ShopCart::Permissions;
19use MODS::ShopCart::Categories;
20
21$| = 1;
22
23my $q = CGI->new;
24my $form = $q->Vars;
25my $auth = MODS::Login->new;
26my $tfile = MODS::Template->new;
27my $db = MODS::DBConnect->new;
28my $cfg = MODS::ShopCart::Config->new;
29my $wrap = MODS::ShopCart::Wrapper->new;
30my $perm = MODS::ShopCart::Permissions->new;
31my $cat = MODS::ShopCart::Categories->new;
32my $DB = $cfg->settings('database_name');
33
34my $userinfo = $auth->login_verify();
35unless ($userinfo) {
36 print "Status: 302 Found\nLocation: /login.cgi\n\n"; exit;
37}
38$perm->require_feature($userinfo, 'edit_models');
39
40my $uid = $userinfo->{user_id}; $uid =~ s/[^0-9]//g;
41my $owner_uid = $userinfo->{owner_user_id} || $uid;
42$owner_uid =~ s/[^0-9]//g;
43
44my $dbh = $db->db_connect();
45
46# Schema probe -- if the migration hasn't run, show a friendly nudge
47# instead of a 500.
48unless ($cat->schema_ready($db, $dbh, $DB)) {
49 $db->db_disconnect($dbh);
50 print "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";
51 $wrap->render({
52 userinfo => $userinfo,
53 page_key => 'categories',
54 title => 'Categories',
55 body => qq~<div class="module"><div class="module-body" style="padding:40px;text-align:center">
56 <h1 style="font-family:var(--font-display);color:#fff">Categories not installed yet</h1>
57 <p style="color:var(--col-text-2);margin-top:12px">Run the seller_categories migration from <code>installation_instructions.html</code> &sect; 5.15c, then refresh.</p>
58 </div></div>~,
59 });
60 exit;
61}
62
63# Flash messages from POST redirects.
64my $flash_msg = '';
65my $flash_kind = '';
66if (defined $form->{ok}) {
67 $flash_msg = 'Saved.'; $flash_kind = 'ok';
68} elsif (defined $form->{deleted}) {
69 $flash_msg = 'Category deleted.'; $flash_kind = 'ok';
70} elsif (defined $form->{dup}) {
71 $flash_msg = 'A category with that name already exists.'; $flash_kind = 'danger';
72} elsif (defined $form->{empty}) {
73 $flash_msg = 'Name is required.'; $flash_kind = 'danger';
74}
75
76# ---- POST handler ----------------------------------------------------
77if (($ENV{REQUEST_METHOD} || '') eq 'POST') {
78 my $act = lc($form->{_act} || ''); $act =~ s/[^a-z_]//g;
79 if ($act eq 'create') {
80 my $name = $form->{name} || '';
81 $name =~ s/^\s+|\s+$//g;
82 if (!length $name) {
83 $db->db_disconnect($dbh);
84 print "Status: 302 Found\nLocation: /categories.cgi?empty=1\n\n"; exit;
85 }
86 my $id = $cat->create($db, $dbh, $DB, $owner_uid,
87 name => $name,
88 description => $form->{description} || '',
89 color => $form->{color} || '',
90 icon => $form->{icon} || '',
91 is_public => exists $form->{is_public} ? 1 : 1,
92 );
93 $db->db_disconnect($dbh);
94 my $q = $id ? 'ok=1' : 'dup=1';
95 print "Status: 302 Found\nLocation: /categories.cgi?$q\n\n"; exit;
96 }
97 if ($act eq 'update') {
98 my $id = $form->{id}; $id =~ s/[^0-9]//g;
99 $cat->update($db, $dbh, $DB, $id, $owner_uid,
100 name => $form->{name},
101 description => $form->{description},
102 color => $form->{color},
103 icon => $form->{icon},
104 sort_order => $form->{sort_order},
105 is_public => exists $form->{is_public} ? 1 : 0,
106 );
107 $db->db_disconnect($dbh);
108 print "Status: 302 Found\nLocation: /categories.cgi?ok=1\n\n"; exit;
109 }
110 if ($act eq 'delete') {
111 my $id = $form->{id}; $id =~ s/[^0-9]//g;
112 $cat->delete($db, $dbh, $DB, $id, $owner_uid);
113 $db->db_disconnect($dbh);
114 print "Status: 302 Found\nLocation: /categories.cgi?deleted=1\n\n"; exit;
115 }
116 # Fall through unknown action.
117 $db->db_disconnect($dbh);
118 print "Status: 302 Found\nLocation: /categories.cgi\n\n"; exit;
119}
120
121# ---- GET: render the list -------------------------------------------
122# Lazy-seed the seller's category list from default_categories the first
123# time they land here (or upload.cgi). The seed function no-ops on second
124# call because users.categories_seeded_at gets set.
125$cat->seed_for_user_if_unseeded($db, $dbh, $DB, $owner_uid);
126$cat->refresh_counts($db, $dbh, $DB, $owner_uid);
127my $cats = $cat->list_for_user($db, $dbh, $DB, $owner_uid);
128
129my @rows;
130foreach my $c (@$cats) {
131 push @rows, {
132 id => $c->{id},
133 slug => _h($c->{slug}),
134 name => _h($c->{name}),
135 description => _h($c->{description} || ''),
136 color => _h($c->{color} || '#a78bfa'),
137 icon => _h($c->{icon} || ''),
138 model_count => $c->{model_count} || 0,
139 is_public => $c->{is_public} ? 1 : 0,
140 sort_order => $c->{sort_order} || 0,
141 };
142}
143
144$db->db_disconnect($dbh);
145
146my $tvars = {
147 has_cats => scalar(@rows) ? 1 : 0,
148 cats => \@rows,
149 flash_msg => $flash_msg,
150 flash_kind => $flash_kind,
151 has_flash => length $flash_msg ? 1 : 0,
152 page_eyebrow => 'Studio &middot; Organize',
153 page_title => 'Categories',
154 page_subtitle => 'Build your own collections so buyers can browse your storefront the way you organize it. These are <em>your</em> categories. Tag any listing with one or more.',
155 form_action => '/categories.cgi',
156 show_counts => 1,
157};
158
159print "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";
160my $body = join('', $tfile->template('shopcart_categories.html', $tvars, $userinfo));
161$wrap->render({
162 userinfo => $userinfo,
163 page_key => 'categories',
164 title => 'Categories',
165 body => $body,
166});
167exit;
168
169sub _h {
170 my $s = shift // '';
171 $s =~ s/&/&amp;/g; $s =~ s/</&lt;/g; $s =~ s/>/&gt;/g;
172 $s =~ s/"/&quot;/g; $s =~ s/'/&#39;/g;
173 return $s;
174}
Keyboard: j next diff k previous diff g top G bottom r restore c compile-check ? help