Андрей (andy) wrote in changelog,
Андрей
andy
changelog

[ljcom] r12036: LJSUP-12382 (Add to shop/history paginat...

Committer: ailyin
LJSUP-12382 (Add to shop/history pagination on every 50 positions)
U   trunk/bin/upgrading/en_LJ.dat
U   trunk/cgi-bin/LJ/Pay/Payment.pm
U   trunk/cgi-bin/LJ/Pay/Wallet/Log.pm
U   trunk/cgi-bin/LJ/Widget/Shop/History.pm
U   trunk/templates/Shop/History.tmpl
Modified: trunk/bin/upgrading/en_LJ.dat
===================================================================
--- trunk/bin/upgrading/en_LJ.dat	2012-05-30 15:28:36 UTC (rev 12035)
+++ trunk/bin/upgrading/en_LJ.dat	2012-05-30 16:45:36 UTC (rev 12036)
@@ -8205,6 +8205,12 @@
 shop.history.orders.header.status|staleness=1
 shop.history.orders.header.status=Status
 
+shop.history.paging.title=Pages:
+
+shop.history.paging.previous=previous
+
+shop.history.paging.next=next
+
 shop.history.status.locked=Unpaid
 
 shop.history.status.open|staleness=1

Modified: trunk/cgi-bin/LJ/Pay/Payment.pm
===================================================================
--- trunk/cgi-bin/LJ/Pay/Payment.pm	2012-05-30 15:28:36 UTC (rev 12035)
+++ trunk/cgi-bin/LJ/Pay/Payment.pm	2012-05-30 16:45:36 UTC (rev 12036)
@@ -2051,38 +2051,56 @@
     return $valid;
 }
 
+# supported opts (all mandatory):
+# * u
+# * pagenum
+# * pagesize
+# returns: { 'carts' => [ ... ], 'pagecount' => 3 }
 sub get_user_history {
-    my ($class, $userid) = @_;
+    my ( $class, %opts ) = @_;
 
-    $userid = LJ::want_userid($userid);
+    my $u        = $opts{'u'};
+    my $pagenum  = $opts{'pagenum'};
+    my $pagesize = $opts{'pagesize'};
 
+    my $userid = $u->userid;
+
+    my $conditions = "userid=$userid AND " .
+        "forwhat IN ('cart', 'recbill', 'appbill')";
+
     my $dbh = LJ::get_db_writer();
-    my $res = $dbh->selectall_arrayref(qq{
-        SELECT * FROM payments
-        WHERE userid=? AND (forwhat="cart" OR forwhat="recbill" OR forwhat="appbill")
-        ORDER BY payid DESC
-    }, { 'Slice' => {} }, $userid);
+    my ($cartcount) = $dbh->selectrow_array(
+        "SELECT COUNT(*) FROM payments WHERE $conditions" );
 
-    my @ret;
-    if (@$res > 50) {
-        # less resource-consuming way: show all carts
-        foreach my $row (@$res) {
-            push @ret, $class->new_memonly(%$row);
-        }
-    } else {
-        # we can go ahead and load items, so that we can hide
-        # empty carts, nifty!
-        foreach my $row (@$res) {
-            my $cart = eval { $class->load('payid' => $row->{'payid'}) };
+    my $pagecount = int( ( $cartcount + $pagesize - 1 ) / $pagesize );
 
-            next unless $cart;
-            next unless $cart->get_items;
+    if ( $pagenum > $pagecount ) {
+        return { 'carts' => [], 'pagecount' => $pagecount };
+    }
 
-            push @ret, $cart;
+    my $sql_offset = ($pagenum - 1) * $pagesize;
+
+    my $rows = $dbh->selectall_arrayref(
+        "SELECT * FROM payments WHERE $conditions ORDER BY payid DESC " .
+        "LIMIT $pagesize OFFSET $sql_offset",
+        { 'Slice' => {} },
+    );
+
+    my @carts;
+
+    foreach my $row (@$rows) {
+        if ( $pagecount > 1 ) {
+            # fast way: put all carts there
+            push @carts, $class->new_memonly(%$row);
+        } else {
+            # slow way: put only carts that actually contain items there
+            my $cart = eval { $class->load( 'payid' => $row->{'payid'} ) };
+            next unless $cart && $cart->get_items;
+            push @carts, $cart;
         }
     }
 
-    return \@ret;
+    return { 'carts' => \@carts, 'pagecount' => $pagecount };
 }
 
 sub allow_repeat {

Modified: trunk/cgi-bin/LJ/Pay/Wallet/Log.pm
===================================================================
--- trunk/cgi-bin/LJ/Pay/Wallet/Log.pm	2012-05-30 15:28:36 UTC (rev 12035)
+++ trunk/cgi-bin/LJ/Pay/Wallet/Log.pm	2012-05-30 16:45:36 UTC (rev 12036)
@@ -176,14 +176,14 @@
         SET $parts
     }, undef, @binds);
 
-    return bless({ 'logid' => $dbh->{'mysql_insertid'} });
+    return bless( { 'logid' => $dbh->{'mysql_insertid'} } , $class );
 }
 
 sub new_from_row {
     my ($class, $row) = @_;
 
     $row->{'_props_loaded'} = 1;
-    return bless($row);
+    return bless( $row, $class );
 }
 
 sub update {
@@ -357,39 +357,77 @@
     return (\@parts, \@binds);
 }
 
+# TODO: this function doesn't do what it usually does when 'use_paging'
+# is passed to it; either rename the function or refactor some parts
+# out
 sub query_handler {
     my ($class, %params) = @_;
 
     my ($parts, $binds) = $class->parse_common_params(\%params);
     my @parts = @$parts; my @binds = @$binds;
 
+    my ( $use_paging, $pagenum, $pagesize );
+    if ( $use_paging = delete $params{'use_paging'} ) {
+        $pagenum  = delete $params{'pagenum'};
+        $pagesize = delete $params{'pagesize'};
+    }
+
     Carp::cluck "unknown parameters: " . join(', ', keys %params)
         if %params;
 
     $parts = join(' AND ', @parts);
 
     my $dbh = LJ::get_db_writer();
+
+    my $pagecount;
+    if ($use_paging) {
+        my ($entrycount) = $dbh->selectrow_array(
+            "SELECT COUNT(*) FROM user_wallet_history WHERE $parts",
+            undef, @binds );
+        $pagecount = int( ( $entrycount + $pagesize - 1 ) / $pagesize );
+
+        if ( $pagenum > $pagecount ) {
+            return { 'items' => [], 'pagecount' => $pagecount };
+        }
+    }
+
+    my $sql_limit_cond = '';
+    if ($use_paging) {
+        my $offset = ( $pagenum - 1 ) * $pagesize;
+        $sql_limit_cond = "LIMIT $pagesize OFFSET $offset";
+    }
+
     my $sth = $dbh->prepare(qq{
         SELECT *
         FROM user_wallet_history
         WHERE $parts
         ORDER BY time_end DESC
+        $sql_limit_cond
     }, { 'mysql_use_result' => 1 });
 
     $sth->execute(@binds);
 
-    return $sth;
+    return $sth unless $use_paging;
+
+    my $rows = $sth->fetchall_arrayref( {} );
+    my @items = map { $class->new_from_row($_) } @$rows;
+
+    return { 'items' => \@items, 'pagecount' => $pagecount };
 }
 
 sub query {
     my ($class, %params) = @_;
 
+    if ( $params{'use_paging'} ) {
+        return $class->query_handler(%params);
+    }
+
     my $sth = $class->query_handler(%params);
 
     my @ret;
 
     while (my $row = $sth->fetchrow_hashref) {
-        push @ret, bless($row);
+        push @ret, $class->new_from_row($row);
     }
 
     return \@ret;

Modified: trunk/cgi-bin/LJ/Widget/Shop/History.pm
===================================================================
--- trunk/cgi-bin/LJ/Widget/Shop/History.pm	2012-05-30 15:28:36 UTC (rev 12035)
+++ trunk/cgi-bin/LJ/Widget/Shop/History.pm	2012-05-30 16:45:36 UTC (rev 12036)
@@ -3,6 +3,8 @@
 
 use base 'LJ::Widget::Shop';
 
+use constant PAGE_SIZE => 50;
+
 use LJ::TimeUtil;
 use LJ::Pay::Payment;
 use LJ::Pay::Wallet;
@@ -14,12 +16,81 @@
 sub get_template_file { 'History' }
 sub show_right_sidebar { 0 }
 
+# TODO: refactor this chunk of code somewhere else? ratings
+# also use this type of pagination, so it may be pretty useful
+sub paging_params {
+    my ( $self, %args ) = @_;
+
+    my $prefix       = $args{'param_prefix'};
+    my $pagenum      = $args{'pagenum'};
+    my $pagecount    = $args{'pagecount'};
+    my $cb_page_link = $args{'cb_page_link'};
+
+    return () unless $pagecount > 1;
+
+    my %ret = ( "${prefix}show_paging" => 1 );
+
+    if ( $pagenum > 1 ) {
+        $ret{"${prefix}previous_page"} = $cb_page_link->( $pagenum - 1 );
+    }
+
+    if ( $pagenum < $pagecount ) {
+        $ret{"${prefix}next_page"} = $cb_page_link->( $pagenum + 1 );
+    }
+
+    my $start_page = $pagenum - 1;
+    if ( $start_page <= 2 ) {
+        $start_page = 1;
+    } else {
+        $ret{"${prefix}first_page"} = $cb_page_link->(1);
+    }
+
+    my $end_page = $pagenum + 1;
+    if ( $end_page >= $pagecount - 1 ) {
+        $end_page = $pagecount;
+    } else {
+        $ret{"${prefix}last_page"} = $cb_page_link->($pagecount);
+        $ret{"${prefix}last_page_num"} = $pagecount;
+    }
+
+    if ( $end_page - $start_page <= 1 ) {
+        if ( $start_page > 1 ) {
+            $start_page--;
+        }
+
+        if ( $end_page < $pagecount ) {
+            $end_page++;
+        }
+    }
+
+    my @pages_display;
+    foreach my $page ( $start_page .. $end_page ) {
+        push @pages_display, {
+            'page_num'     => $page,
+            'page_link'    => $cb_page_link->($page),
+            'page_current' => ( $page == $pagenum ),
+        };
+    }
+    $ret{"${prefix}pages"} = \@pages_display;
+
+    return %ret;
+}
+
 sub get_orders_history {
     my ($self) = @_;
 
     my $remote = LJ::get_remote();
-    my $carts = LJ::Pay::Payment->get_user_history($remote);
 
+    my $pagenum = int( LJ::Request->get_param('page') || 1 );
+    my $carts_data = LJ::Pay::Payment->get_user_history(
+        'u'        => $remote,
+        'pagenum'  => $pagenum,
+        'pagesize' => PAGE_SIZE,
+    );
+
+    my $pagecount = $carts_data->{'pagecount'};
+    my $carts     = $carts_data->{'carts'};
+
     my @ret;
     foreach my $cart (@$carts) {
         my $datesent = $cart->get_datesent;
@@ -80,7 +151,20 @@
         };
     }
 
-    return \@ret;
+    my %paging_params = $self->paging_params(
+        'param_prefix' => 'orders_',
+        'pagenum'      => $pagenum,
+        'pagecount'    => $pagecount,
+        'cb_page_link' => sub {
+            my ($page) = @_;
+            return "$LJ::SITEROOT/shop/history.bml?tab=orders&page=$page";
+        },
+    );
+
+    return {
+        'orders' => \@ret,
+        %paging_params,
+    };
 }
 
 sub get_wallet_history {
@@ -88,10 +172,17 @@
 
     my $remote = LJ::get_remote();
 
-    my $log = LJ::Pay::Wallet::Log->query(
-        'userid' => $remote->id,
+    my $pagenum = int( LJ::Request->get_param('page') || 1 );
+    my $log_data = LJ::Pay::Wallet::Log->query(
+        'userid'     => $remote->id,
+        'use_paging' => 1,
+        'pagenum'    => $pagenum,
+        'pagesize'   => PAGE_SIZE,
     );
 
+    my $items     = $log_data->{'items'};
+    my $pagecount = $log_data->{'pagecount'};
+
     my %result_map = (
         STATUS_STARTED()  =>
             LJ::Lang::ml('wallet.widget.history.status.in_progress'),
@@ -227,7 +318,7 @@
 
     };
 
-    foreach my $logitem (@$log) {
+    foreach my $logitem (@$items) {
         my $time = $logitem->time_end;
 
         my $des = $describe_logitem->($logitem);
@@ -258,7 +349,20 @@
         };
     }
 
-    return \@ret;
+    my %paging_params = $self->paging_params(
+        'param_prefix' => 'wallet_',
+        'pagenum'      => $pagenum,
+        'pagecount'    => $pagecount,
+        'cb_page_link' => sub {
+            my ($page) = @_;
+            return "$LJ::SITEROOT/shop/history.bml?tab=wallet&page=$page";
+        },
+    );
+
+    return {
+        'wallet' => \@ret,
+        %paging_params,
+    };
 }
 
 sub get_loyalty_userpics_history {
@@ -274,7 +378,7 @@
         $row->{'num_pics'} = int $row->{'num_pics'};
     }
 
-    return $rows;
+    return { 'loyalty' => $rows };
 }
 
 sub get_page_params {
@@ -291,19 +395,26 @@
         $current_tab = 'wallet' if $current_tab eq 'tokens';
     }
 
-    my %tabs;
+    my %page_params = (
+        'self_url' => "$LJ::SITEROOT/shop/history.bml",
+    );
 
     foreach my $tab (qw(orders wallet loyalty)) {
-        $tabs{"tab_${tab}_active"} = ($current_tab eq $tab);
+        $page_params{"tab_${tab}_active"} = ($current_tab eq $tab);
     }
 
-    return {
-        'orders' => $self->get_orders_history,
-        'wallet' => $self->get_wallet_history,
-        'loyalty' => $self->get_loyalty_userpics_history,
-        %tabs,
-        'self_url' => "$LJ::SITEROOT/shop/history.bml",
-    };
+    if ( $current_tab eq 'orders' ) {
+        %page_params = ( %page_params, %{ $self->get_orders_history } );
+    } elsif ( $current_tab eq 'wallet' ) {
+        %page_params = ( %page_params, %{ $self->get_wallet_history } );
+    } elsif ( $current_tab eq 'loyalty' ) {
+        %page_params = (
+            %page_params,
+            %{ $self->get_loyalty_userpics_history },
+        );
+    }
+
+    return \%page_params;
 }
 
 1;

Modified: trunk/templates/Shop/History.tmpl
===================================================================
--- trunk/templates/Shop/History.tmpl	2012-05-30 15:28:36 UTC (rev 12035)
+++ trunk/templates/Shop/History.tmpl	2012-05-30 16:45:36 UTC (rev 12036)
@@ -40,6 +40,38 @@
 			</tr>
 			</TMPL_LOOP>
 		</table>
+
+		<TMPL_IF orders_show_paging>
+			<p class="history-paging">
+				<strong><TMPL_VAR expr="ml('shop.history.paging.title')"></strong>
+
+				<TMPL_IF orders_previous_page>
+					<a href="<TMPL_VAR orders_previous_page ESCAPE=HTML>"><TMPL_VAR expr="ml('shop.history.paging.previous')"></a>
+				</TMPL_IF>
+
+				<TMPL_IF orders_first_page>
+					<a href="<TMPL_VAR orders_first_page ESCAPE=HTML>">1</a>
+					&hellip;
+				</TMPL_IF>
+
+				<TMPL_LOOP orders_pages>
+					<TMPL_IF page_current>
+						<strong><TMPL_VAR page_num></strong>
+					<TMPL_ELSE>
+						<a href="<TMPL_VAR page_link ESCAPE=HTML>"><TMPL_VAR page_num></a>
+					</TMPL_IF>
+				</TMPL_LOOP>
+
+				<TMPL_IF orders_last_page>
+					&hellip;
+					<a href="<TMPL_VAR orders_last_page ESCAPE=HTML>"><TMPL_VAR orders_last_page_num></a>
+				</TMPL_IF>
+
+				<TMPL_IF orders_next_page>
+					<a href="<TMPL_VAR orders_next_page ESCAPE=HTML>"><TMPL_VAR expr="ml('shop.history.paging.next')"></a>
+				</TMPL_IF>
+			</p>
+		</TMPL_IF>
 	</div>
 	<TMPL_IF name="tab_wallet_active">
 	<div id="tab_wallet" class="b-payment-history-wallet">
@@ -64,6 +96,37 @@
 			</tr>
 			</TMPL_LOOP>
 		</table>
+		<TMPL_IF wallet_show_paging>
+			<p class="history-paging">
+				<strong><TMPL_VAR expr="ml('shop.history.paging.title')"></strong>
+
+				<TMPL_IF wallet_previous_page>
+					<a href="<TMPL_VAR wallet_previous_page ESCAPE=HTML>"><TMPL_VAR expr="ml('shop.history.paging.previous')"></a>
+				</TMPL_IF>
+
+				<TMPL_IF wallet_first_page>
+					<a href="<TMPL_VAR wallet_first_page ESCAPE=HTML>">1</a>
+					&hellip;
+				</TMPL_IF>
+
+				<TMPL_LOOP wallet_pages>
+					<TMPL_IF page_current>
+						<strong><TMPL_VAR page_num></strong>
+					<TMPL_ELSE>
+						<a href="<TMPL_VAR page_link ESCAPE=HTML>"><TMPL_VAR page_num></a>
+					</TMPL_IF>
+				</TMPL_LOOP>
+
+				<TMPL_IF wallet_last_page>
+					&hellip;
+					<a href="<TMPL_VAR wallet_last_page ESCAPE=HTML>"><TMPL_VAR wallet_last_page_num></a>
+				</TMPL_IF>
+
+				<TMPL_IF wallet_next_page>
+					<a href="<TMPL_VAR wallet_next_page ESCAPE=HTML>"><TMPL_VAR expr="ml('shop.history.paging.next')"></a>
+				</TMPL_IF>
+			</p>
+		</TMPL_IF>
 	</div>
 	<TMPL_IF name="tab_loyalty_active">
 	<div id="tab_loyalty" class="b-payment-history-loyalty">

Tags: ailyin, andy, dat, ljcom, pm, tmpl
Subscribe
  • Post a new comment

    Error

    Anonymous comments are disabled in this journal

    default userpic

    Your reply will be screened

    Your IP address will be recorded 

  • 0 comments