LJSUP-17669: Login.bml form refactoring
[livejournal.git] / cgi-bin / ljlinks.pl
blob99d685e9128e1955af266432ad1af907dff3cddc
1 #!/usr/bin/perl
4 # Functions for lists of links created by users for display in their journals
7 use strict;
9 package LJ::Links;
11 # linkobj structure:
13 # $linkobj = [
14 # { 'title' => 'link title',
15 # 'url' => 'http://www.somesite.com',
16 # 'children' => [ ... ],
17 # },
18 # { ... },
19 # { ... },
20 # ];
22 sub load_linkobj
24 my ($u, $use_master) = @_;
25 return unless LJ::isu($u);
27 # check memcache for linkobj
28 my $memkey = [$u->{'userid'}, "linkobj:$u->{'userid'}"];
29 my $linkobj = LJ::MemCache::get($memkey);
30 return $linkobj if defined $linkobj;
32 # didn't find anything in memcache
33 $linkobj = [];
36 # not in memcache, need to build one from db
37 my $db = $use_master ? LJ::get_cluster_def_reader($u) : LJ::get_cluster_reader($u);
39 local $" = ",";
40 my $sth = $db->prepare("SELECT ordernum, parentnum, title, url " .
41 "FROM links WHERE journalid=?");
42 $sth->execute($u->{'userid'});
43 push @$linkobj, $_ while $_ = $sth->fetchrow_hashref;
46 # sort in perl-space
47 @$linkobj = sort { $a->{'ordernum'} <=> $b->{'ordernum'} } @$linkobj;
49 # fix up the data structure
50 foreach (@$linkobj) {
52 # TODO: build child relationships
53 # and store in $_->{'children'}
55 # ordernum/parentnum are only exposed via the
56 # array structure, delete them here
57 delete $_->{'ordernum'};
58 delete $_->{'parentnum'};
61 # set linkobj in memcache
62 LJ::MemCache::set($memkey, $linkobj);
64 return $linkobj;
67 sub save_linkobj
69 my ($u, $linkobj) = @_;
70 return undef unless LJ::isu($u) && ref $linkobj eq 'ARRAY' && $u->writer;
72 # delete old links, we'll rebuild them shortly
73 $u->do("DELETE FROM links WHERE journalid=?", undef, $u->{'userid'});
75 # only save allowed number of links
76 my $numlinks = @$linkobj;
77 my $caplinks = LJ::get_cap($u, "userlinks");
78 $numlinks = $caplinks if $numlinks > $caplinks;
80 if ($numlinks) {
81 # build insert query
82 my (@bind, @vals);
83 foreach my $ct (1..$numlinks) {
84 my $it = $linkobj->[$ct-1];
85 # journalid, ordernum, parentnum, url, title
86 push @bind, "(?,?,?,?,?)";
87 push @vals, ($u->{'userid'}, $ct, 0, $it->{'url'}, $it->{'title'});
89 my $binds = join(",", @bind);
90 $u->do("INSERT INTO links (journalid, ordernum, parentnum, url, title) VALUES $binds", undef, @vals);
93 # invalidate memcache
94 my $memkey = [$u->{'userid'}, "linkobj:$u->{'userid'}"];
95 LJ::MemCache::delete($memkey);
99 sub make_linkobj_from_form
101 my ($u, $post) = @_;
102 return unless LJ::isu($u) && ref $post eq 'HASH';
104 my $linkobj = [];
106 # remove leading and trailing spaces
107 my $stripspaces = sub {
108 my $str = shift;
109 $str =~ s/^\s*//;
110 $str =~ s/\s*$//;
111 return $str;
114 # find number of links allowed
115 my $numlinks = $post->{'numlinks'};
116 my $caplinks = LJ::get_cap($u, "userlinks");
117 $numlinks = $caplinks if $numlinks > $caplinks;
119 foreach my $num (sort { $post->{"link_${a}_ordernum"} <=>
120 $post->{"link_${b}_ordernum"} } (1..$numlinks)) {
122 # title is required
123 my $title = $post->{"link_${num}_title"};
124 $title = $stripspaces->($title);
125 next unless $title;
127 my $url = $post->{"link_${num}_url"};
128 $url = $stripspaces->($url);
130 # smartly add http:// to url unless they are just inserting a blank line
131 if ($url && $title ne '-') {
132 $url = LJ::CleanHTML::canonical_url($url);
135 # build link object element
136 $post->{"link_${num}_url"} = $url;
137 push @$linkobj, { 'title' => $title, 'url' => $url };
139 # TODO: build child relationships
140 # push @{$linkobj->[$parentnum-1]->{'children'}}, $myself
143 return $linkobj;