[dw-free] Move /icons page into S2
[commit: http://hg.dwscoalition.org/dw-free/rev/493c75d2cc5c]
http://bugs.dwscoalition.org/show_bug.cgi?id=1446
Move the /icons page generation into S2 instead of using a BML file.
Theoretically, journals can implement their own styling for this page now,
but none of the styles actually do. Should be no visible change to end
users; the page emulates the old appearance of the /icons page.
Patch by
exor674.
Files modified:
http://bugs.dwscoalition.org/show_bug.cgi?id=1446
Move the /icons page generation into S2 instead of using a BML file.
Theoretically, journals can implement their own styling for this page now,
but none of the styles actually do. Should be no visible change to end
users; the page emulates the old appearance of the /icons page.
Patch by
![[personal profile]](https://www.dreamwidth.org/img/silk/identity/user.png)
Files modified:
- bin/upgrading/s2layers/core2.s2
- bin/upgrading/s2layers/siteviews/layout.s2
- cgi-bin/Apache/LiveJournal.pm
- cgi-bin/LJ/S2.pm
- cgi-bin/LJ/S2/IconsPage.pm
- cgi-bin/LJ/User.pm
- htdocs/allpics.bml
-------------------------------------------------------------------------------- diff -r 35494aff0407 -r 493c75d2cc5c bin/upgrading/s2layers/core2.s2 --- a/bin/upgrading/s2layers/core2.s2 Tue Jan 25 12:24:34 2011 +0800 +++ b/bin/upgrading/s2layers/core2.s2 Tue Jan 25 14:16:45 2011 +0800 @@ -458,6 +458,22 @@ class Comment extends EntryLite } +class Icon +"Represents a single icon" +{ + var readonly Image image "Information about the icon"; + var readonly string[] keywords "All keywords"; + var readonly string comment "Comment text"; + var readonly string description "Description text"; + var readonly string link_url "URL this image links to when clicked"; + + var readonly bool default "If this icon is the default"; + var readonly bool active "If this icon is active"; + + function print() "Prints the icon"; +} + + ### Userinfo class Friend extends UserLite @@ -635,6 +651,18 @@ class Page function builtin print_trusted(string key) "Prints a trusted string by key."; +} + +class IconsPage extends Page +"A detail page listing a user's icons." +{ + var readonly bool can_manage "Can the current user manage these icons."; + var readonly Icon[] icons "List of the icons on the current page."; + var readonly ItemRange pages "All pages"; + var readonly string sortorder "Current sort order. Can be 'upload' or 'keyword'."; + + var readonly string{} sort_urls "An associative array of link for various sort orders."; + var readonly string[] sort_keyseq "A list of sort orders, indicated by key."; } class TagsPage extends Page @@ -1098,11 +1126,23 @@ set num_items_recent = 20; set num_items_recent = 20; set num_items_reading = 20; +property int num_items_icons { + des = "Number of icons to show on the icons page, or 0 for no pagination"; + doc_flags = "[construct]"; +} +set num_items_icons = 0; + property string tags_page_type { - des = "Type of tags display on tags page"; - values="list|List|cloud|Cloud|multi|Multilevel"; + des = "Type of tags display on tags page"; + values="list|List|cloud|Cloud|multi|Multilevel"; } set tags_page_type = "multi"; + +property string icons_page_sort { + des = "Default sort order for icons page"; + values="upload|Upload Order|keyword|Keyword Order"; +} +set icons_page_sort = "upload"; property string[] reverse_sortorder_group { des = "Display entries in reverse-chronological order on my:"; @@ -1159,6 +1199,9 @@ set show_userpics_comments = true; # was !view_entry_disabled property bool use_journalstyle_entry_page { des = "Show entry pages in my journal style rather than the site layout"; } set use_journalstyle_entry_page = true; + +property bool use_journalstyle_icons_page { des = "Show icons page in my journal style rather than the site layout"; } +set use_journalstyle_icons_page = false; # Defaults to false, but layouts can set it to true to switch on custom colors for different posters on reading list. property bool use_custom_friend_colors { des = "Use my custom reading list colors"; } @@ -1997,6 +2040,13 @@ property string text_view_memories { example = "My Memories"; } +property string text_view_icons { + des = "Text used to link to the Icons page"; + maxlength = 40; + "size" = 15; + example = "Icons"; +} + property string text_view_tags { des = "Text used to link to the 'Tags' page"; maxlength = 40; @@ -2015,6 +2065,7 @@ set text_view_userinfo = "Profile"; set text_view_userinfo = "Profile"; set text_view_memories = "Memories"; set text_view_tags = "Tags"; +set text_view_icons = "Icons"; property string text_skiplinks_back { des = "Text to show in a link to skip back through entries"; @@ -2357,6 +2408,71 @@ set text_comment_thread = "Thread"; set text_comment_thread = "Thread"; set text_comment_threadroot = "Thread from start"; set text_comment_expand = "Expand"; + +##=============================== +## Text - icons +##=============================== + +property string text_icons_page_header { + des = "Text for the header of the Icons page"; + example = "Current Icons"; +} + +property string text_icons_page_empty_header { + des = "Text for the header of the Icons page when it is empty"; + example = "No Icons"; +} + +property string text_icons_keywords { + des = "Text for the list of keywords"; + example = "Keywords:"; +} + +property string text_icons_comment { + des = "Text for the icon comment"; + example = "Comment:"; +} + +property string text_icons_description { + des = "Text for the icon description"; + example = "Description:"; +} + +property string text_icons_default { + des = "Text for the default icon"; + example = "Default"; +} + +property string text_icons_inactive { + des = "Text for inactive icons"; + example = "Inactive"; +} + +property string text_icons_keyword_sep { + des = "Text to separate items in a list of keywords"; + example = ","; +} + +property string text_icons_sort_upload { + des = "Text for sort by upload order link"; + example = "Upload Order"; +} + +property string text_icons_sort_keyword { + des = "Text for sort by keyword link"; + example = "Keyword Order"; +} + +set text_icons_page_header = "Current Icons"; +set text_icons_page_empty_header = "No Icons"; +set text_icons_keywords = "Keywords:"; +set text_icons_comment = "Comment:"; +set text_icons_description = "Description:"; +set text_icons_keyword_sep = ","; +set text_icons_default = "Default"; +set text_icons_inactive = "Inactive"; +set text_icons_sort_upload = "Upload Order"; +set text_icons_sort_keyword = "Keyword Order"; ##=============================== ## Text - tags @@ -2963,6 +3079,7 @@ function lang_viewname(string viewid) [n return $*text_view_friends; } } + if ($viewid == "icons") { return $*text_view_icons; } if ($viewid == "network") { return $*text_view_network; } if ($viewid == "day") { return "Day"; } if ($viewid == "month") { return "Month"; } @@ -2996,6 +3113,20 @@ function lang_metadata_title(string whic return $which; } } + +function lang_icon_sortorder_title(string which) [fixed] : string + "Get a human-readable caption for an icons sort order key. Overriding this function is NOT RECOMMENDED. Overriding this function could prevent sitewide improvements to styles, accessibility, or other functionality from operating in your layout. Sets strings according to layer or wizard supplied string properties." + { + if ($which == "upload") { + return $*text_icons_sort_upload; + } + elseif ($which == "keyword") { + return $*text_icons_sort_keyword; + } + else { + return $which; + } + } ### Navigation @@ -5581,6 +5712,66 @@ function ReplyPage::print_body $.form->print(); } +### IconsPage functions + +function IconsPage::print_body { + print safe "<div class='icons-container'><h2>$*text_icons_page_header</h2><div class='inner'>"; + """<div><ul>"""; + var int sort_ct = 0; + foreach var string k ($.sort_keyseq) { + var string text = lang_icon_sortorder_title($k); + if ( $k == $.sortorder ) { + print safe """<li class='$k active'>$text"""; + } else { + print safe """<li class='$k'><a href='$.sort_urls{$k}'>$text</a>"""; + } + if ( (++$sort_ct) < size $.sort_keyseq) { print $*text_default_separator; } + """</li>"""; + } + """</ul></div>"""; + $.pages->print(); + foreach var Icon i ($.icons) { + $i->print(); + } + $.pages->print(); + print safe "</div></div>"; +} + +function Icon::print { + var string default_class = $.default ? "icon-default" : ""; + var string inactive_class = $.active ? "" : "icon-inactive"; + + """<div class="icon $default_class $inactive_class">"""; + """<a href="$.link_url">"""; $.image->print(); """</a>"""; + if ($.default) { + print safe "<div class='default label'>$*text_icons_default</div>"; + } + if (not $.active) { + print safe "<div class='inactive label'>$*text_icons_inactive</div>"; + } + if ($.keywords) { + """<div class="keywords">"""; + var int keyword_count = 0; + print safe "<span class='label'>$*text_icons_keywords</span> "; + """<ul>"""; + foreach var string kw ($.keywords) { + $keyword_count++; + """<li>"""; + print safe $kw; + if ($keyword_count < size $.keywords) { print $*text_icons_keyword_sep; } + """</li>"""; + } + """</ul></div>"""; + } + if ($.comment) { + print safe "<div class='comment'><span class='comment-text'>$*text_icons_comment</span> $.comment</div>"; + } + if ($.description) { + print safe "<div class='description'><span class='description-text'>$*text_icons_description</span> $.description</div>"; + } + """</div>"""; +} + ### TagsPage functions function TagsPage::print_body diff -r 35494aff0407 -r 493c75d2cc5c bin/upgrading/s2layers/siteviews/layout.s2 --- a/bin/upgrading/s2layers/siteviews/layout.s2 Tue Jan 25 12:24:34 2011 +0800 +++ b/bin/upgrading/s2layers/siteviews/layout.s2 Tue Jan 25 14:16:45 2011 +0800 @@ -24,7 +24,7 @@ function Page::print() { $this->print_default_stylesheet(); $this->print_theme_stylesheet(); $*SITEVIEWS->set_content("head",$*SITEVIEWS->end_capture()); - $*SITEVIEWS->set_content("windowtitle",$this->view_title()); + $this->print_title(); $this->print_body(); } else { @@ -32,8 +32,122 @@ function Page::print() { } } +function Page::print_title() { + # Do not actually *print* anything here, or in overridden instances, just call set_content with windowtitle or title as appropriate. + $*SITEVIEWS->set_content("windowtitle",$this->view_title()); +} + function Page::print_default_stylesheet() { # Do not actually *print* any stylesheets here, but you can $*SITEVIEWS->need_res(...); here to pull in anything. } function Page::print_theme_stylesheet() {} + +# IconsPage + +set text_icons_keyword_sep = ", "; +set text_icons_inactive = "[Inactive]"; + +function IconsPage::print_title() { + $*SITEVIEWS->set_content("title",$this->view_title()); +} + +function IconsPage::print_body() { + if ( $*SITEVIEWS ) { + $*SITEVIEWS->need_res( "stc/allpics.css" ); + } + + var int piccount = 0; + if ( size($.icons) == 0 ) { + """<h1>$*text_icons_page_empty_header</h1><p>"""; + if ( $.can_manage ) { + """You don't have any icons uploaded. <a href="$*SITEROOT/editpics">Upload an icon here</a>."""; + } else { + """$.journal hasn't uploaded any icons. You can <a href="$*SITEROOT/manage/subscriptions/user?journal=$.journal.username">be notified</a> when $.journal uploads an icon, if you want."""; + } + } else { + """<h1>$*text_icons_page_header</h1><p>"""; + print "These are the icons for "; + print $.journal; + print ". "; + if ( $.can_manage ) { + """Would you like to <a href="$*SITEROOT/editpics">upload a new icon or edit your icon keywords, comments, and descriptions</a>?"""; + } else { + """We can <a href="$*SITEROOT/manage/subscriptions/user?journal=$.journal.username">notify</a> you when this account uploads a new one."""; + } + """</p><p>"""; + var int sort_ct = 0; + foreach var string k ($.sort_keyseq) { + var string text = lang_icon_sortorder_title($k); + if ( $k == $.sortorder ) { + print safe """$text"""; + } else { + print safe """<a href='$.sort_urls{$k}'>$text</a>"""; + } + if ( (++$sort_ct) < size $.sort_keyseq) { print $*text_default_separator; } + } + """</p><table class='allpics'>"""; + foreach var Icon i ($.icons) { + $piccount++; + + if ($piccount % 2 == 1) { + """<tr>"""; + } + + $i->print(); + + if ($piccount % 2 == 1) { + """<td class='blank'></td>"""; + } else { + """</tr>\n"""; + } + } + if ($piccount) { + if ($piccount % 2 == 1) { + } + """</table>"""; + } else { + } + + $.pages->print({ "anchor" => "" }); + } +} + +function Icon::print() { + """<td class='pic'>"""; + + """<a href="$.link_url">"""; $.image->print(); """</a>"""; + + """</td><td class='desc'>"""; + + if ( $.default ) { + print safe """<u>$*text_icons_default</u><br/>"""; + } + + if ( not $.active ) { + print safe """<em>$*text_icons_inactive</em><br/>"""; + } + + if ( size $.keywords ) { + var int count = 0; + print safe """<strong>$*text_icons_keywords</strong> """; + foreach var string kw ( $.keywords ) { + $count++; + print safe $kw; + if ( $count < size $.keywords ) { + print safe $*text_icons_keyword_sep; + } + } + """<br/>"""; + } + + if ( $.comment ) { + print safe """<strong>$*text_icons_comment</strong> $.comment<br/>"""; + } + + if ( $.description ) { + print safe """<strong>$*text_icons_description</strong> $.description<br/>"""; + } + + """</td>"""; +} diff -r 35494aff0407 -r 493c75d2cc5c cgi-bin/Apache/LiveJournal.pm --- a/cgi-bin/Apache/LiveJournal.pm Tue Jan 25 12:24:34 2011 +0800 +++ b/cgi-bin/Apache/LiveJournal.pm Tue Jan 25 14:16:45 2011 +0800 @@ -613,11 +613,6 @@ sub trans or return 404; return redir($r, "$LJ::SITEROOT/update.bml?usejournal=".$u->{'user'}); - } - - if ( $opts->{mode} eq "icons" ) { - $r->notes->{_journal} = $opts->{user}; - return $bml_handler->( "$LJ::HOME/htdocs/allpics.bml" ); } %RQ = %$opts; diff -r 35494aff0407 -r 493c75d2cc5c cgi-bin/LJ/S2.pm --- a/cgi-bin/LJ/S2.pm Tue Jan 25 12:24:34 2011 +0800 +++ b/cgi-bin/LJ/S2.pm Tue Jan 25 14:16:45 2011 +0800 @@ -33,6 +33,7 @@ use LJ::S2::EntryPage; use LJ::S2::EntryPage; use LJ::S2::ReplyPage; use LJ::S2::TagsPage; +use LJ::S2::IconsPage; use Storable; use Apache2::Const qw/ :common /; use POSIX (); @@ -106,6 +107,11 @@ sub make_journal $ctx->[S2::PROPS]->{SITEVIEWS} = $siteviews_class; } else { if ( ! $ctx->[S2::PROPS]->{use_journalstyle_entry_page} && ( $view eq "entry" || $view eq "reply" ) ) { + ${$opts->{'handle_with_bml_ref'}} = 1; + return; + } + + if ( ! $ctx->[S2::PROPS]->{use_journalstyle_icons_page} && ( $view eq "icons" ) ) { ${$opts->{'handle_with_bml_ref'}} = 1; return; } @@ -140,6 +146,7 @@ sub make_journal entry => "EntryPage", tag => "TagsPage", network => "FriendsPage", + icons => "IconsPage", }; if (my $class = $view2class->{$view}) { @@ -1249,8 +1256,11 @@ sub alias_renamed_props $ctx->[S2::PROPS]->{reverse_sortorder_year} = $ctx->[S2::PROPS]->{page_year_sortorder} eq 'reverse' ? 1 : 0 if exists $ctx->[S2::PROPS]->{page_year_sortorder}; - $ctx->[S2::PROPS]->{use_journalstyle_entry_page} = ! $ctx->[S2::PROPS]->{view_entry_disabled} - if exists $ctx->[S2::PROPS]->{view_entry_disabled}; + # Not adding the new views to core1, force non-entry use_journalstyle_ to 0 for core1 + if ( exists $ctx->[S2::PROPS]->{view_entry_disabled} ) { + $ctx->[S2::PROPS]->{use_journalstyle_entry_page} = ! $ctx->[S2::PROPS]->{view_entry_disabled}; + $ctx->[S2::PROPS]->{use_journalstyle_icons_page} = 0; + } } # use the "grouped_property_override" property to determine whether a custom property should override a default property. diff -r 35494aff0407 -r 493c75d2cc5c cgi-bin/LJ/S2/IconsPage.pm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/cgi-bin/LJ/S2/IconsPage.pm Tue Jan 25 14:16:45 2011 +0800 @@ -0,0 +1,122 @@ +use strict; +package LJ::S2; + +sub IconsPage { + my ($u, $remote, $opts) = @_; + my $get = $opts->{'getargs'}; + + my $can_manage = ( $remote && $remote->can_manage( $u ) ) ? 1 : 0; + my $p = Page($u, $opts); + $p->{'_type'} = "IconsPage"; + $p->{'view'} = "icons"; + + $p->{can_manage} = $can_manage; + + my @allpics = LJ::Userpic->load_user_userpics($u); + my $defaultpicid = $u ? $u->{'defaultpicid'} : undef; + + my $view_inactive = $can_manage || ( $get->{inactive} && $remote && ( LJ::check_priv( $remote, "supportviewscreened" ) || + LJ::check_priv( $remote, "supporthelp" ) ) ); + my $default_sortorder = S2::get_property_value($opts->{'ctx'}, 'icons_sort_order') || 'upload'; + my $sortorder = $get->{sortorder} || $default_sortorder; + + @allpics = grep { $_->state eq 'N' || ( $view_inactive && $_->state ne 'X' ) } @allpics; + + my @pics; + + if ( $sortorder eq 'keyword' ) { + @pics = LJ::Userpic->separate_keywords( \@allpics ); + } else { # Upload Order + $sortorder = 'upload'; + my @newpics; + my $default_pic; + foreach my $pic ( @allpics ) { + my $keyword = $pic->keywords; + if ( $pic->is_default ) { + $default_pic = { keywords => [ $keyword ] , userpic => $pic }; + } else { + push @newpics, { keywords => [ $keyword ], userpic => $pic }; + } + } + @pics = $default_pic if $default_pic; + @pics = ( @pics, @newpics ); + } + + my @sort_methods = ( 'upload', 'keyword' ); + + $p->{sortorder} = $sortorder; + $p->{sort_keyseq} = \@sort_methods; + $p->{sort_urls} = { + map { $_ => LJ::create_url(undef, + args => { + sortorder => ( $_ eq $default_sortorder ) ? undef : $_, + }, + viewing_style => 1, + cur_args => $get, + ) } @sort_methods + }; + + my $pagingbar; + my $start_index = 0; + my $page_size = S2::get_property_value($opts->{'ctx'}, "num_items_icons")+0; + $p->{pages} = ItemRange_fromopts({ + items => \@pics, + pagesize => $page_size || scalar @pics, + page => $get->{page} || 1, + url_of => sub { + return LJ::create_url(undef, + args => { + page => $_[0], + }, + keep_args => [ 'sortorder' ], + viewing_style => 1, + cur_args => $get, + ); + } + }); + + my @pics_out; + + foreach my $pic_hash (@pics) { + my $pic = $pic_hash->{userpic}; + my $keywords = $pic_hash->{keywords} || [ $pic_hash->{keyword} ]; + + my $eh_comment = $pic->comment; + if ( $eh_comment ) { + LJ::CleanHTML::clean(\$eh_comment, { + 'wordlength' => 40, + 'addbreaks' => 0, + 'tablecheck' => 1, + 'mode' => 'deny', + }); + } + + my $eh_description = $pic->description; + if ( $eh_description ) { + LJ::CleanHTML::clean(\$eh_description, { + 'wordlength' => 40, + 'addbreaks' => 0, + 'tablecheck' => 1, + 'mode' => 'deny', + }); + } + + push @pics_out, { + '_type' => 'Icon', + id => $pic->picid, + image => Image( $pic->url, $pic->width, $pic->height, LJ::ehtml( $pic->alttext ), title => LJ::ehtml( $pic->keywords ) ), + keywords => [ map { LJ::ehtml($_) } sort { lc($a) cmp lc($b) } ( @$keywords ) ], + comment => $eh_comment, + description => $eh_description, + default => ( $pic->is_default ) ? 1 : 0, + active => $pic->state eq 'I' ? 0 : 1, + link_url => $pic->url, + }; + } + + $p->{icons} = \@pics_out; + + return $p; +} + +1; \ No newline at end of file diff -r 35494aff0407 -r 493c75d2cc5c cgi-bin/LJ/User.pm --- a/cgi-bin/LJ/User.pm Tue Jan 25 12:24:34 2011 +0800 +++ b/cgi-bin/LJ/User.pm Tue Jan 25 14:16:45 2011 +0800 @@ -8966,7 +8966,7 @@ sub make_journal { # intercept flag to handle_with_bml_ref and instead use siteviews # FIXME: Temporary, till everything is converted. - if ( $opts->{'handle_with_bml_ref'} && ${$opts->{'handle_with_bml_ref'}} && $geta->{fallback} eq "s2" ) { + if ( $opts->{'handle_with_bml_ref'} && ${$opts->{'handle_with_bml_ref'}} && ( $geta->{fallback} eq "s2" || { icons => 1, tag => 1 }->{$view} ) ) { $mj = LJ::S2::make_journal($u, "siteviews", $view, $remote, $opts); } diff -r 35494aff0407 -r 493c75d2cc5c htdocs/allpics.bml --- a/htdocs/allpics.bml Tue Jan 25 12:24:34 2011 +0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,291 +0,0 @@ -<?_c -# This code was forked from the LiveJournal project owned and operated -# by Live Journal, Inc. The code has been modified and expanded by -# Dreamwidth Studios, LLC. These files were originally licensed under -# the terms of the license supplied by Live Journal, Inc, which can -# currently be found at: -# -# http://code.livejournal.org/trac/livejournal/browser/trunk/LICENSE-LiveJournal.txt -# -# In accordance with the original license, this code and all its -# modifications are provided under the GNU General Public License. -# A copy of that license can be found in the LICENSE file included as -# part of this distribution. -_c?> -<?_code -{ -# This page displays all of the user's userpics along with all user-contributed text - - use strict; - use vars qw(%GET $title $body $head); - - BML::set_language_scope( '/allpics.bml' ); - LJ::need_res( 'stc/allpics.css' ); - - $title = "$ML{'.title'}"; - $body = ""; - $head = ""; - - my $r = BML::get_request(); - - # if new-style URLs, get the GET{user} arg from the request notes, - # which was set by LiveJournal.pm - unless ( $GET{user} ) { - $GET{user} = $r->notes->{_journal}; - } - - my $user = LJ::canonical_username($GET{'user'}); - my $remote = LJ::get_remote(); - my $u = ! $user || $remote && $remote->{'user'} eq $user ? $remote : LJ::load_user($user); - - unless ($u) { - $body = "<?h1 $ML{'Error'} h1?><?p $ML{'.error.noparam'} p?>"; - return; - } - - # redirect /icons to their subdomain urls - my $domain = BML::get_client_header( "Host" ); - if ( $LJ::ONLY_USER_VHOSTS ) { - my $url = $u->journal_base . "/icons"; - - my $good_domain = $url; - $good_domain =~ s!^http://!!; - $good_domain =~ s!/.*!!; - if ( $domain ne $good_domain ) { - return BML::redirect( $url ); - } - } - - $u->preload_props("opt_blockrobots", "adult_content") if $u->is_visible; - if (!$u->is_visible || $u->should_block_robots) { - $head .= LJ::robot_meta_tags(); - } - - - # no need for viewsome, due to the fact that none of this is private anyway. just - # allow anybody with any version of viewall to see userpics for non-V statusvis users - - unless ( $remote && $remote->view_priv_check( $u, $GET{viewall}, 'allpics' ) ) { - if ($u->is_suspended) { - $title = $ML{'error.suspended.title'}; - $body = "<?h1 $ML{'error.suspended.name'} h1?><?p " . - BML::ml('error.suspended.text', { 'user' => LJ::ljuser($u), - 'sitename' => $LJ::SITENAME }) . " p?>"; - return; - } - - if ($u->is_deleted) { - $title = $ML{'error.deleted.title'}; - $body = "<?h1 $ML{'error.deleted.name'} h1?><?p " . - BML::ml('error.deleted.text', { 'user' => LJ::ljuser($u) }) . - " p?>"; - return; - } - - if ($u->is_expunged) { - $title = $ML{'error.purged.title'}; - $body = "<?h1 $ML{'error.purged.name'} h1?><?p " . - BML::ml('error.purged.text', { 'user' => LJ::ljuser($u) }) . - " p?>"; - return; - } - } - - # redirect renamed users - if ( $u->is_redirect ) { - my $renamedto = $u->prop( "renamedto" ); - return BML::redirect("$LJ::SITEROOT/allpics?user=$renamedto'}") - if $renamedto; - } - - my ( $can_manage, $getextra ); - if ( $remote ) { - $can_manage = $remote->can_manage( $u ); - $getextra = $can_manage && ! $remote->equals( $u ) - ? "?authas=" . $u->user : ''; - } - - #### show pictures - - my $keyword_sort = $GET{'keywordSort'}; - if ( $keyword_sort ) { - $getextra = $getextra ? $getextra . "&keywordSort=1" : "?keywordSort=1"; - } - - my $piccount = 0; - - # 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; - - 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 - - my @pics; - my $pagingbar; - my $start_index = 0; - my $page_size = $LJ::ALLPICS_PAGESIZE; - if ($page_size && $page_size > 0) { - my $pic_count = scalar @allpics; - my $pagecount = int (($pic_count - 1) / $page_size) + 1; - - if ($pagecount > 0) { - my $page = $GET{page}; - unless ($page) { $page = 1; } - - my $querystring = join('&', map { LJ::eurl($_) . '=' . LJ::eurl($GET{$_}) } grep { $_ ne 'page' } keys %GET); - $pagingbar = LJ::paging_bar($page, $pagecount, { - self_link => sub { BML::get_uri() . "?page=$_[0]&" . $querystring }, }); - $start_index = $page_size * ($page -1); - } - @pics = splice( @allpics, $start_index, $start_index + $page_size - 1 ); - } else { - @pics = @allpics; - } - - foreach my $userpic_hash ( @allpics ) { - - # 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) { - $body .= BML::ml('.pics.owner', {'user' => LJ::ljuser($u),}); - my $hook_text = LJ::Hooks::run_hook('allpics_upsell_text', $u, $getextra); - if ($hook_text eq "") { - $body .= ' ' . BML::ml('.edit4', {'aopts' => "href='$LJ::SITEROOT/editicons$getextra'"}); - } else { - $body .= $hook_text; - } - } 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 summary='' class='allpics'>"; - } - - ### Keywords - my $eh_keywords = LJ::ehtml( $keywords ); - - if ($piccount % 2 == 1) { - $body .= "<tr>"; - } - - $body .= "<td class='pic'>"; - - 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 ( $userpic->is_default ) { - $body .= "$ML{'.default'}<br />"; - } - - if ($view_inactive && $userpic->state eq 'I') { - $body .= "<em>[$ML{'userpic.inactive'}]</em> " . LJ::help_icon('userpic_inactive') . "<br />"; - } - - if ( $eh_keywords ) { - $body .= "<strong>$ML{'.keywords'}</strong> $eh_keywords<br />"; - } - - # 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"; - } - - # 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_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. - # we need 2 columns: the pic and the text. - $body .= "<td colspan='2'></td></tr>"; - } - if ($pagingbar) { - $body .= "<tr><td colspan = '4'>"; - $body .= $pagingbar; - $body .= "</td></tr>\n"; - } - $body .= "</table>"; - } else { - if ($can_manage) { - $body = "<?h1 $ML{'.nopics.title'} h1?><?p "; - $body .= BML::ml('.nopics.text3', {'aopts' => "href='$LJ::SITEROOT/editicons$getextra#upload'"}) . " p?>"; - } else { - $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 -title=><?_code return $title; _code?> -head=><?_code return $head; _code?> -body=><?_code return $body; _code?> -page?> --------------------------------------------------------------------------------