Committer: gprochaev
LJSUP-6515. Custom UserheadsA trunk/cgi-bin/LJ/Pay/Payment/PayItem/UserHead.pm A trunk/cgi-bin/LJ/UserHead.pm A trunk/htdocs/admin/userheads/ A trunk/htdocs/admin/userheads/manage.bml A trunk/htdocs/admin/userheads/stat.bml
Added: trunk/cgi-bin/LJ/Pay/Payment/PayItem/UserHead.pm =================================================================== --- trunk/cgi-bin/LJ/Pay/Payment/PayItem/UserHead.pm (rev 0) +++ trunk/cgi-bin/LJ/Pay/Payment/PayItem/UserHead.pm 2010-08-16 07:32:35 UTC (rev 9340) @@ -0,0 +1,95 @@ +package LJ::Pay::Payment::PayItem::UserHead; + +use strict; + +use base "LJ::Pay::Payment::PayItem::Addon"; +use LJ::Pay::Util qw/ _err _get_dbh/; + +sub item { return 'userhead'; } +sub paidexp_item { + my $self = shift; + + return $self->{subitem}; +} + +sub _adopt_item { + my $self = shift; + my %args = @_; + + my $exp = $args{exp}; + my $u = $args{u}; + my $payid = $args{payid}; + my $time = $args{time}; ## next check date for recbill payments, undef for regular ones + + return (1, 12); +} + +sub is_recbillable { 0 } + +sub validate_user_input { + my ($self, $cartobj, $errs_ref, $warns_ref, $action) = @_; + + unless ($self->{'rcptid'}) { + push @$errs_ref, LJ::Lang::ml('/pay/modify.bml.error.no_rcptid'); + return 0; + } + + return 1; +} + +sub get_product_name { + my ($class, $subitem, $qty, $short) = @_; + + return LJ::Lang::ml('pay.product.userhead') . ($short ? "" : " - " . ""); +} + +sub render_cart_item { + my $self = shift; + my $opts = shift; + + my %result; # keys in hash = columns in page: name(item), type, recipient + + my $subitem = $self->{subitem}; + my ($uh_id) = $subitem =~ m#uh-(\d+)#; + my $uh = LJ::UserHead->get_userhead ($uh_id); + + $result{name} = LJ::Lang::ml('pay.cart.item.userhead'); + $result{type} = "<img src='".$uh->get_uh_img."'>"; + + return \%result; +} + +sub can_belong_to { + return 1; +} + +sub get_expire_times { + my ($self, $u) = @_; + my $userid = ($u) ? LJ::want_userid($u) : + (ref $self) ? $self->{rcptid} : + die "Userid is required"; + + my $dbh = _get_dbh(); + my $res = $dbh->selectall_arrayref("SELECT item, UNIX_TIMESTAMP(expdate) as expdate, size " . + "FROM paidexp WHERE userid=?", + { Slice => {} }, $userid); + + return [ grep { $_->{item} =~ /uh-\d+/ } @$res ]; +} + +sub _activate_item { + return 1; +} + +sub _deactivate_item { + my $self = shift; + my %args = @_; + + my $u = LJ::load_userid($args{u}); + return undef unless $u; + + $u->set_custom_usericon (undef); +} + +1; + Added: trunk/cgi-bin/LJ/UserHead.pm =================================================================== --- trunk/cgi-bin/LJ/UserHead.pm (rev 0) +++ trunk/cgi-bin/LJ/UserHead.pm 2010-08-16 07:32:35 UTC (rev 9340) @@ -0,0 +1,88 @@ +package LJ::UserHead; + +use strict; + +use base qw(Class::Accessor); +__PACKAGE__->follow_best_practice; +__PACKAGE__->mk_accessors( qw( uh_id uh_author price ) ); + +sub new { + my $class = shift; + my $args = shift || {}; + + return bless $args, $class; +} + +sub set_enabled { + my $self = shift; + + $self->{'is_enabled'} = shift; +} + +sub get_userhead { + my $class = shift; + my $uh_id = shift; + + my $dbh = LJ::get_db_reader(); + + my $uh = $dbh->selectrow_hashref ("SELECT * FROM shop_userheads WHERE uh_id = $uh_id"); + return $uh ? LJ::UserHead->new ($uh) : undef; +} + +sub save { + my $self = shift; + + my $dbh = LJ::get_db_writer(); + + if ($self->get_uh_id) { + my $set = join ", ", map { + " $_ = ".$dbh->quote($self->{$_}) + } keys %$self; + $dbh->do ("UPDATE shop_userheads SET $set WHERE uh_id = " . $self->get_uh_id); + return $self->get_uh_id; + } else { + my $values = join ",", map { + $dbh->quote($self->{$_}) + } values %$self; + $dbh->do ("INSERT INTO shop_userheads VALUES ( $values )"); + my $new = LJ::UserHead->get_userhead ($dbh->last_insert_id (undef, undef, "shop_userheads", undef)); + $self->{$_} = $new->{$_} foreach keys %$new; + return $self->get_uh_id; + } +} + +sub get_uh_img { + my $self = shift; + + return $LJ::FILEPREFIX."/userhead/".$self->get_uh_id; +} + +sub is_enabled { + my $self = shift; + + return $self->{is_enabled}; +} + +sub get_all_userheads { + my $class = shift; + + my $dbh = LJ::get_db_reader(); + my $is_enabled = shift || 0; + + my $where = $is_enabled ? " WHERE is_enabled = 1 " : ""; + + my $uhs = $dbh->selectall_arrayref ("SELECT * FROM shop_userheads $where ORDER BY uh_id", { Slice => {} }); + + return [ + map { + $_->{'uh_img'} = $_->get_uh_img; + $_ + } + map { + LJ::UserHead->new ($_) + } @$uhs + ]; +} + +1; + Added: trunk/htdocs/admin/userheads/manage.bml =================================================================== --- trunk/htdocs/admin/userheads/manage.bml (rev 0) +++ trunk/htdocs/admin/userheads/manage.bml 2010-08-16 07:32:35 UTC (rev 9340) @@ -0,0 +1,128 @@ +<?_code + +use strict; +use vars qw(%FORM %GET %POST); + +use LJ::UserHead; +use LJ::FileStore; + +my $ret; + +my $remote = LJ::get_remote(); +return "<b>Error:</b> not logged in" unless $remote; +return "<b>Error:</b> no access" + unless $LJ::IS_DEV_SERVER || LJ::check_priv($remote, "admin", "userheads"); + +if ($FORM{'upload'}) { + my $error = ''; + #BML::parse_multipart(\%POST, \$error, 999992048); + #warn "ERROR: $error" and return $error if $error; + my $userhead = LJ::Request->upload('uh_file'); + seek $userhead->fh, 0,0; + read $userhead->fh, my $userhead_content, $userhead->size; + + my $uh = LJ::UserHead->new; + $uh->save; + + my ($result_l, $result_s, $content_length, $magic, $mime_type) = (); + + ## Set large image + if ($POST{'uh_file'}) { + $content_length = bytes::length($POST{'uh_file'}); + $magic = substr $POST{'uh_file'}, 0, 20; + $mime_type = format_magic($magic) + or die "Unknown format for upload"; + my $result = LJ::FileStore->save_file(path => "/userhead/" . $uh->get_uh_id, content => $userhead_content, mime_type => $mime_type, content_length => $content_length); + } +} + +use Data::Dumper; +if ($FORM{'save'}) { + foreach my $id (keys %FORM) { + next unless $id =~ m#(\d+)-uh_id#; + $id = $1; + my $is_enabled = $FORM{"$id-is_enabled"} eq 'on' ? 1 : 0; + my $author = $FORM{"$id-author"}; + my $price = $FORM{"$id-price"}; + my $uh = LJ::UserHead->get_userhead ($FORM{"$id-uh_id"}); + $uh->set_uh_author ($author); + $uh->set_price ($price); + $uh->set_enabled ($is_enabled); + $uh->save; + } +} + +if ($FORM{'set'}) { + my $uh = LJ::UserHead->get_userhead ($FORM{'uh_id'}); + foreach my $user (split /,[ ]?/, $FORM{'users'}) { + my $u = LJ::load_user ($user); + $u->set_custom_usericon ($uh->get_uh_img); + } +} + +$ret .= "<title>LJ User Heads: manage</title>"; + +my $domain = LJ::Lang::get_dom("general"); +my $lang = $LJ::DEFAULT_LANG; + +my $dbh = LJ::get_db_writer(); + + $ret .= <<FORM; + <form method="post" enctype="multipart/form-data"> + <table> + <tr> + <td><input type="file" name="uh_file"></td> + <td><input type="submit" name="upload" value="Upload"></td> + </tr> + </table> + </form> + <hr> + +FORM + +my $uhs = LJ::UserHead->get_all_userheads(); + +$ret .= "<form method='POST'>"; +$ret .= "<table border=0 cellspacing=1 cellpadding=4>"; +foreach my $uh (@$uhs) { + $ret .= "<tr>"; + $ret .= "<td><input type='hidden' name='".$uh->get_uh_id."-uh_id' value='".$uh->get_uh_id."'>".$uh->get_uh_id."</td>"; + $ret .= "<td><img src='".$uh->get_uh_img."'></td>"; + $ret .= "<td><input type='text' name='".$uh->get_uh_id."-price' size='5' value='".$uh->get_price."'></td>"; + $ret .= "<td><input type='checkbox' name='".$uh->get_uh_id."-is_enabled' ". ($uh->is_enabled ? "checked='checked'" : "") ."> available </td>"; + $ret .= "<td><input type='text' name='".$uh->get_uh_id."-author' value='".$uh->get_uh_author."'></td>"; + $ret .= "</tr>"; +} +$ret .= "<tr><td colspan='5'><input type='submit' name='save' value='Save'></td></tr>"; +$ret .= "</table>"; +$ret .= "</form>"; +$ret .= "<hr>"; + +$ret .= "<form method='POST'>"; +$ret .= "<b>Set user head: <select name='uh_id'>"; +foreach my $uh (@$uhs) { + $ret .= "<option value=".$uh->get_uh_id.">".$uh->get_uh_id."</option>"; +} +$ret .= "</select> to LJ users:<br/>"; +$ret .= "<textarea name='users' rows='5' cols='30'>Usernames, comma separated</textarea><br/>"; +$ret .= "<input type='submit' name='set' value='Set'>"; +$ret .= "</form>"; + +return $ret; + +sub format_magic { + my $magic = shift; + my $hex = unpack "H*", $magic; + my $mime; + + $mime = 'text/plain'; # default value + # image formats + $mime = 'image/jpeg' if $magic =~ /^\xff\xd8/; # JPEG + $mime = 'image/gif' if $magic =~ /^GIF8/; # GIF + $mime = 'image/png' if $magic =~ /^\x89PNG/; # PNG + + return $mime; +} + +_code?> + Added: trunk/htdocs/admin/userheads/stat.bml =================================================================== --- trunk/htdocs/admin/userheads/stat.bml (rev 0) +++ trunk/htdocs/admin/userheads/stat.bml 2010-08-16 07:32:35 UTC (rev 9340) @@ -0,0 +1,99 @@ +<?_code + +use strict; +use vars qw(%FORM %GET %POST); + +use LJ::UserHead; +use LJ::FileStore; +use DateTime; + +my $ret; + +$ret .= "<title>LJ User Heads: stat</title>"; + +my $remote = LJ::get_remote(); +return "<b>Error:</b> not logged in" unless $remote; +return "<b>Error:</b> no access" + unless $LJ::IS_DEV_SERVER || LJ::check_priv($remote, "admin", "userheads"); + +my $domain = LJ::Lang::get_dom("general"); +my $lang = $LJ::DEFAULT_LANG; + +my $dt = DateTime->now(); +my $current = sprintf ("%02d", $dt->day) . "-" . sprintf ("%02d", $dt->month) . "-" . $dt->year; +$dt->add (days => -30); +my $before = sprintf ("%02d", $dt->day) . "-" . sprintf ("%02d", $dt->month) . "-" . $dt->year; + + +my $dbh = LJ::get_db_writer(); + +my $checked_sup = $POST{sup} ? ' checked="checked" ' : ''; +my $checked_nonsup = $POST{nonsup} ? ' checked="checked" ' : ''; + + $ret .= <<FORM; + <h3> LJ User Heads: stat</h3> + <form method="post"> + <table> + <tr> + <td>Period: from <input type="text" name="from" value="$before"></td> + <td>To <input type="text" name="to" value="$current"></td> + <td><input type="checkbox" name="sup" $checked_sup> SUP users</td> + <td><input type="checkbox" name="nonsup" $checked_nonsup> nonSUP users</td> + <td><input type="submit" name="show" value="Show"></td> + </tr> + </table> + </form> + <hr> + +FORM + +if (LJ::did_post()) { + my $date = $POST{'from'}; + my ($d1, $m1, $y1) = $date =~ m#(\d{2})-(\d{2})-(\d{4})#; + my $from = DateTime->new ( + year => $y1, + month => $m1, + day => $d1, + hour => 0, + minute => 0, + second => 0, + ); + $date = $POST{'to'}; + ($d1, $m1, $y1) = $date =~ m#(\d{2})-(\d{2})-(\d{4})#; + my $to = DateTime->new ( + year => $y1, + month => $m1, + day => $d1, + hour => 23, + minute => 59, + second => 59, + ); + my $userheads = $dbh->selectall_arrayref ("SELECT userid, subitem, qty, amt FROM payments, payitems WHERE payments.payid = payitems.payid AND item = 'userhead' AND daterecv > FROM_UNIXTIME(" . $from->epoch . ") AND daterecv <= FROM_UNIXTIME(" . $to->epoch . ")", { Slice => {} }); + + my %uh_stat = (); + foreach my $item (@$userheads) { + my $u = LJ::load_userid($item->{userid}); + warn $item->{userid}; + warn LJ::SUP->is_sup_enabled($u) ? "SUP" : "NonSUP"; + warn $POST{nonsup}; + if ((LJ::SUP->is_sup_enabled($u) and $POST{'sup'}) or (!LJ::SUP->is_sup_enabled($u) and $POST{nonsup})) { + $uh_stat{$item->{subitem}}{qty} += $item->{qty}; + $uh_stat{$item->{subitem}}{amt} += $item->{amt}; + } + } + + $ret .= "<table border='1'>"; + $ret .= "<tr><td>id</td><td>img</td><td>price</td><td>author</td><td>quantity</td><td>amount</td></tr>"; + foreach my $item (keys %uh_stat) { + my ($uh_id) = $item =~ m#uh-(\d+)#; + my $uh = LJ::UserHead->get_userhead ($uh_id); + $ret .= "<tr><td>".$uh_id."</td><td><img src='".$uh->get_uh_img."'></td><td>".$uh->get_price."</td><td>".$uh->get_uh_author."</td><td>".$uh_stat{$item}{qty}."</td><td>".$uh_stat{$item}{amt}."</td></tr>"; + } + $ret .= "</table>"; + +} + +return $ret; + +_code?> +