[dw-free] sort alpha by keyword on allpics/editpics page
[commit: http://hg.dwscoalition.org/dw-free/rev/a8d460b97735]
http://bugs.dwscoalition.org/show_bug.cgi?id=1433
Allow to sort icons by either upload order (current behavior/default) or by
keyword.
On your /icons page, the keyword sort results in multiple instances of the
icon showing up. Icons with no keywords (but have a nominal keyword of
"pic#1234") are sorted to the bottom of the list.
When doing /editicons, the keyword sort sorts only by the first keyword on
the list.
Patch by
allen.
Files modified:
http://bugs.dwscoalition.org/show_bug.cgi?id=1433
Allow to sort icons by either upload order (current behavior/default) or by
keyword.
On your /icons page, the keyword sort results in multiple instances of the
icon showing up. Icons with no keywords (but have a nominal keyword of
"pic#1234") are sorted to the bottom of the list.
When doing /editicons, the keyword sort sorts only by the first keyword on
the list.
Patch by
Files modified:
- cgi-bin/LJ/User.pm
- cgi-bin/LJ/Userpic.pm
- htdocs/allpics.bml
- htdocs/allpics.bml.text
- htdocs/editicons.bml
- htdocs/editicons.bml.text
--------------------------------------------------------------------------------
diff -r 079aa6f23dae -r a8d460b97735 cgi-bin/LJ/User.pm
--- a/cgi-bin/LJ/User.pm Wed Apr 28 23:47:49 2010 -0700
+++ b/cgi-bin/LJ/User.pm Thu Apr 29 00:14:59 2010 -0700
@@ -5590,6 +5590,13 @@ sub allpics_base {
return $u->journal_base . "/icons";;
}
+# clears the internally cached mapping of userpics to keywords for this
+# User
+sub clear_userpic_kw_map {
+ my $self = $_[0];
+
+ $self->{picid_kw_map} = undef;
+}
sub get_userpic_count {
my $u = shift or return undef;
@@ -5598,6 +5605,25 @@ sub get_userpic_count {
return $count;
}
+# gets a mapping from userpic ids to keywords for this User.
+sub get_userpic_kw_map {
+ my $self = shift;
+
+ if ( $self->{picid_kw_map} ) {
+ return $self->{picid_kw_map};
+ }
+
+ my $picinfo = LJ::get_userpic_info( $self->userid, {load_comments => 0} );
+ my $keywords = {};
+ foreach my $keyword ( keys %{$picinfo->{kw}} ) {
+ my $picid = $picinfo->{kw}->{$keyword}->{picid};
+ $keywords->{$picid} = [] unless $keywords->{$picid};
+ push @{$keywords->{$picid}}, $keyword if ( $keyword && $picid );
+ }
+
+ $self->{picid_kw_map} = $keywords;
+ return $keywords;
+}
# <LJFUNC>
# name: LJ::User::mogfs_userpic_key
diff -r 079aa6f23dae -r a8d460b97735 cgi-bin/LJ/Userpic.pm
--- a/cgi-bin/LJ/Userpic.pm Wed Apr 28 23:47:49 2010 -0700
+++ b/cgi-bin/LJ/Userpic.pm Thu Apr 29 00:14:59 2010 -0700
@@ -429,18 +429,9 @@ sub keywords {
croak "Invalid opts passed to LJ::Userpic::keywords" if keys %opts;
- my $picinfo = LJ::get_userpic_info($self->{userid}, {load_comments => 0});
+ my $u = $self->owner;
- # $picinfo is a hashref of userpic data
- # keywords are stored in the "kw" field in the format keyword => {hash of some picture info}
-
- # create a hash of picids => keywords
- my $keywords = {};
- foreach my $keyword (keys %{$picinfo->{kw}}) {
- my $picid = $picinfo->{kw}->{$keyword}->{picid};
- $keywords->{$picid} = [] unless $keywords->{$picid};
- push @{$keywords->{$picid}}, $keyword if ($keyword && $picid);
- }
+ my $keywords = $u->get_userpic_kw_map();
# return keywords for this picid
my @pickeywords = $keywords->{$self->id} ? @{$keywords->{$self->id}} : ();
@@ -921,6 +912,9 @@ sub set_keywords {
undef, @data );
}
+ # clear the userpic-keyword map.
+ $u->clear_userpic_kw_map;
+
# Let the user know about any we didn't save
# don't throw until the end or nothing will be saved!
if (@kw_errors) {
@@ -1036,6 +1030,65 @@ sub set_fullurl {
return 1;
}
+# Sorts the given list of Userpics.
+sub sort {
+ my ( $class, $userpics ) = @_;
+
+ return () unless ( $userpics && ref $userpics );
+
+ my %kwhash;
+ my %nokwhash;
+
+ for my $pic ( @$userpics ) {
+ my $pickw = $pic->keywords( raw => 1 );
+ if ( $pickw ) {
+ $kwhash{$pickw} = $pic;
+ } else {
+ $pickw = $pic->keywords;
+ $nokwhash{$pickw} = $pic;
+ }
+ }
+ my @sortedkw = sort keys %kwhash;
+ my @sortednokw = sort keys %nokwhash;
+
+ my @sortedpics;
+ foreach my $kw ( @sortedkw ) {
+ push @sortedpics, $kwhash{$kw};
+ }
+ foreach my $kw ( @sortednokw ) {
+ push @sortedpics, $nokwhash{$kw};
+ }
+
+ return @sortedpics;
+}
+
+# Organizes the given userpics by keyword. Returns an array of hashes,
+# with values of keyword and userpic.
+sub separate_keywords {
+ my ( $class, $userpics ) = @_;
+
+ return () unless ( $userpics && ref $userpics );
+
+ my @userpic_array;
+ my @nokw_array;
+ foreach my $userpic ( @$userpics ) {
+ my @keywords = $userpic->keywords( raw => 1 );
+ foreach my $keyword ( @keywords ) {
+ if ( $keyword ) {
+ push @userpic_array, { keyword => $keyword, userpic => $userpic };
+ } else {
+ $keyword = $userpic->keywords;
+ push @nokw_array, { keyword => $keyword, userpic => $userpic };
+ }
+ }
+ }
+
+ @userpic_array = sort { $a->{keyword} cmp $b->{keyword} } @userpic_array;
+ push @userpic_array, sort { $a->{keyword} cmp $b->{keyword} } @nokw_array;
+
+ return @userpic_array;
+}
+
####
# error classes:
diff -r 079aa6f23dae -r a8d460b97735 htdocs/allpics.bml
--- a/htdocs/allpics.bml Wed Apr 28 23:47:49 2010 -0700
+++ b/htdocs/allpics.bml Thu Apr 29 00:14:59 2010 -0700
@@ -15,7 +15,6 @@ _c?>
<?_code
{
# This page displays all of the user's userpics along with all user-contributed text
-# FIXME: A lot more of this functionality should be coming from the Userpic.pm class
use strict;
use vars qw(%GET $title $body $head);
@@ -106,41 +105,36 @@ _c?>
#### show pictures
- my $info = LJ::get_userpic_info( $u, { load_comments => 1, load_urls => 1, load_descriptions => 1 } );
-
- my %keywords = ();
- while (my ($kw, $pic) = each %{$info->{'kw'}}) {
- LJ::text_out( BML::ebml( \$kw ) );
- push @{$keywords{$pic->{'picid'}}}, $kw;
+ my $keyword_sort = $GET{'keywordSort'};
+ if ( $keyword_sort ) {
+ $getextra = $getextra ? $getextra . "&keywordSort=1" : "?keywordSort=1";
}
- my %comments = ();
- while (my ($pic, $comment) = each %{$info->{'comment'}}) {
- LJ::text_out( BML::ebml( \$comment ) );
- $comments{$pic} = $comment;
- }
-
- my %descriptions = ();
- while ( my ($pic, $description) = each %{$info->{description}}) {
- LJ::text_out( BML::ebml( \$description ) );
- $descriptions{$pic} = $description;
- }
-
my $piccount = 0;
-
- my @allpics;
- my $defaultpicid = $u ? $u->{'defaultpicid'} : undef;
# allow support to view inactive userpics for debugging
my $view_inactive = $GET{inactive} && $remote &&
( $remote->has_priv( "supportviewscreened" ) || $remote->has_priv( "supporthelp" ) );
$view_inactive ||= $can_manage;
- push @allpics, $info->{'pic'}->{$u->{'defaultpicid'}} if $defaultpicid;
- push @allpics, map { $info->{'pic'}->{$_} } sort { $a <=> $b }
- grep { $_ != $defaultpicid && ($info->{'pic'}->{$_}->{'state'} eq 'N' || $view_inactive) &&
- $info->{'pic'}->{$_}->{'state'} ne 'X' }
- keys %{$info->{'pic'}};
+ my @allpics = LJ::Userpic->load_user_userpics($u);
+ if ( @allpics ) {
+ if ( $keyword_sort ) {
+ @allpics = LJ::Userpic->separate_keywords( \@allpics );
+ } else {
+ my @newpics;
+ my $default_pic;
+ foreach my $pic ( @allpics ) {
+ my $keyword = $pic->keywords;
+ if ( $pic->is_default ) {
+ $default_pic = { keyword => $keyword, userpic => $pic };
+ } elsif ( $pic->state eq 'N' || ( $view_inactive && $pic->state ne 'X' ) ) {
+ push @newpics, { keyword => $keyword, userpic => $pic };
+ }
+ }
+ @allpics = ( $default_pic, @newpics );
+ }
+ }
# pagination code
@@ -166,11 +160,14 @@ _c?>
@pics = @allpics;
}
- foreach my $pic (@pics) {
+ foreach my $userpic_hash ( @allpics ) {
- # load the userpic object for each pic
- my $userpic = LJ::Userpic->new( $u, $pic->{picid} );
+ # if we have no default pic
+ next unless $userpic_hash;
+ my $userpic = $userpic_hash->{userpic};
+ my $keywords = $userpic_hash->{keyword};
+
if ($piccount++ == 0) {
$body .= "<?h1 $ML{'.current'} h1?><?p ";
if ($can_manage) {
@@ -184,76 +181,84 @@ _c?>
} else {
$body .= BML::ml('.pics2', {'user' => LJ::ljuser($u), 'aopts' => "href='$LJ::SITEROOT/manage/subscriptions/user?journal=$u->{user}'"});
}
-
+
+ # show sort options
+ $body .= "<p>";
+ $body .= $keyword_sort ? '<a href = "' . $u->allpics_base . '">' . "$ML{'.sort.default'}</a>" : "$ML{'.sort.default'}";
+ $body .=" | ";
+ $body .= $keyword_sort ? "$ML{'.sort.keyword'}" : '<a href = "' . $u->allpics_base . '?keywordSort=1">' . "$ML{'.sort.keyword'}</a>";
+ $body .= "</p>\n";
+
$body .= " p?><table class='allpics'>";
}
-
+
### Keywords
- my $eh_keywords = join(", ", sort { lc($a) cmp lc($b) } @{$keywords{$pic->{'picid'}}||[]});
- $eh_keywords = LJ::ehtml($eh_keywords);
-
+ my $eh_keywords = LJ::ehtml( $keywords );
+
if ($piccount % 2 == 1) {
$body .= "<tr>";
}
-
+
$body .= "<td class='pic'>";
-
- my ($apre, $apost);
- if ($pic->{'url'}) {
- $apre = "<a href='" . LJ::ehtml($pic->{'url'}) . "'>";
+
+ my ( $apre, $apost );
+ if ( $userpic->url ) {
+ $apre = "<a href='" . LJ::ehtml( $userpic->url ) . "'>";
$apost = "</a>";
}
-
+
# for each image, we know the picid, get the html imgtag
$body .= "$apre" . $userpic->imgtag . $apost . "</td><td class='desc'>";
-
- if ($u->{'defaultpicid'} == $pic->{'picid'}) {
+
+ if ( $userpic->is_default ) {
$body .= "$ML{'.default'}<br />";
}
-
- if ($view_inactive && $pic->{'state'} eq 'I') {
+
+ if ($view_inactive && $userpic->state eq 'I') {
$body .= "<em>[$ML{'userpic.inactive'}]</em> " . LJ::help_icon('userpic_inactive') . "<br />";
}
-
- if ($eh_keywords) {
+
+ if ( $eh_keywords ) {
$body .= "<strong>$ML{'.keywords'}</strong> $eh_keywords<br />";
}
-
+
# Comments
- my $eh_comments = $comments{$pic->{'picid'}};
- if ($eh_comments) {
+ my $eh_comments = $userpic->comment;
+ if ( $eh_comments ) {
+ LJ::text_out( BML::ebml( \$eh_comments ) );
LJ::CleanHTML::clean(\$eh_comments, {
'wordlength' => 40,
'addbreaks' => 0,
'tablecheck' => 1,
'mode' => 'deny',
});
-
+
$body .= "<strong>$ML{'.comment'}</strong> $eh_comments<br />\n";
}
- # Descriptions
- my $eh_descriptions = $descriptions{$pic->{picid}};
- if ($eh_descriptions) {
- LJ::CleanHTML::clean(\$eh_descriptions, {
+ # Description
+ my $eh_description = $userpic->description;
+ if ($eh_description) {
+ LJ::text_out( BML::ebml( \$eh_description ) );
+ LJ::CleanHTML::clean(\$eh_description, {
wordlength => 40,
addbreaks => 0,
tablecheck => 1,
mode => 'deny',
});
- $body .= "<strong>$ML{'.description'}</strong> $eh_descriptions\n";
+ $body .= "<strong>$ML{'.description'}</strong> $eh_description\n";
}
-
+
$body .= "</td>";
-
+
if ($piccount % 2 == 1) {
$body .= "<td class='blank'></td>";
} else {
$body .= "</tr>\n";
}
}
-
+
if ($piccount) {
if ($piccount % 2 == 1) {
# finish off this row.
@@ -274,7 +279,7 @@ _c?>
$body = "<?h1 $ML{'.nopics.title'} h1?><?p ". BML::ml('.nopics.text.other2', {'aopts' => "href='$LJ::SITEROOT/manage/subscriptions/user?journal=$u->{user}'", username => $u->ljuser_display }). " p?>";
}
}
-
+
return;
}
_code?><?page
diff -r 079aa6f23dae -r a8d460b97735 htdocs/allpics.bml.text
--- a/htdocs/allpics.bml.text Wed Apr 28 23:47:49 2010 -0700
+++ b/htdocs/allpics.bml.text Thu Apr 29 00:14:59 2010 -0700
@@ -29,5 +29,9 @@
.pics.owner=Here are the userpics for [[user]].
+.sort.default=Upload Order
+
+.sort.keyword=Keyword Order
+
.title=User Pictures
diff -r 079aa6f23dae -r a8d460b97735 htdocs/editicons.bml
--- a/htdocs/editicons.bml Wed Apr 28 23:47:49 2010 -0700
+++ b/htdocs/editicons.bml Thu Apr 29 00:14:59 2010 -0700
@@ -61,6 +61,12 @@ use strict;
# extra arguments for get requests
my $getextra = $authas ne $remote->{'user'} ? "?authas=$authas" : '';
+
+ # see if we're sorting by default order or by keyword
+ my $keyword_sort = $GET{'keywordSort'};
+ if ( $keyword_sort ) {
+ $getextra = $getextra ? $getextra . "&keywordSort=1" : "?keywordSort=1";
+ }
my $returl = LJ::CleanHTML::canonical_url($POST{'ret'});
my $picurl = LJ::CleanHTML::canonical_url($POST{'urlpic'});
@@ -491,12 +497,24 @@ use strict;
$body .= "<p>".BML::ml('cprod.editpics.text7.v1',{ "num" => $max })."</p>";
}
}
+
+ # show sort options
+ $body .= "<p>";
+ $body .= $keyword_sort ? '<a href = "/editicons">' . "$ML{'.sort.default'}</a>" : "$ML{'.sort.default'}";
+ $body .=" | ";
+ $body .= $keyword_sort ? "$ML{'.sort.keyword'}" : '<a href = "/editicons?keywordSort=1">' . "$ML{'.sort.keyword'}</a>";
+ $body .= "</p>\n";
+
$body .= "</div>";
$body .= "<div id='list_userpics' style='width: 98%; float: left;'>";
my $display_rename = LJ::theschwartz() ? 1 : 0;
- foreach my $pic (@userpics) {
+ if ( $keyword_sort ) {
+ @userpics = LJ::Userpic->sort( \@userpics );
+ }
+
+ foreach my $pic ( @userpics ) {
my $pid = $pic->id;
$body .= "<div class='pkg userpic_wrapper'>";
diff -r 079aa6f23dae -r a8d460b97735 htdocs/editicons.bml.text
--- a/htdocs/editicons.bml.text Wed Apr 28 23:47:49 2010 -0700
+++ b/htdocs/editicons.bml.text Thu Apr 29 00:14:59 2010 -0700
@@ -124,6 +124,10 @@
.restriction.keywords.faq=Picture will be unusable if <a [[aopts]]>keywords</a> are not supplied
+.sort.default=Upload Order
+
+.sort.keyword=Keyword Order
+
.title=Edit Userpics
.title3|notes=This is the new page title. .title is used by multisearch.bml.
--------------------------------------------------------------------------------

no subject
no subject