#!/usr/bin/perl # # DW::Controller::Dreamwidth::Suggest # # Controller for the site suggestion form. # # Authors: # Denise Paolucci -- original version # Jen Griffin -- controller conversion # # Copyright (c) 2009-2016 by Dreamwidth Studios, LLC. # # This program is NOT free software or open-source; you can use it as an # example of how to implement your own site-specific extensions to the # Dreamwidth Studios open-source code, but you cannot use it on your site # or redistribute it, with or without modifications. # package DW::Controller::Dreamwidth::Suggest; use strict; use warnings; use DW::Routing; use DW::Template; use DW::Controller; DW::Routing->register_string( "/site/suggest", \&suggestion_handler, app => 1 ); sub suggestion_handler { my ( $ok, $rv ) = controller(); return $rv unless $ok; my $fatal_err = sub { return DW::Template->render_template( 'error.tt', { message => $_[0] } ); }; # the community to post to: my $destination = LJ::load_user($LJ::SUGGESTIONS_COMM); $rv->{destination} = $destination; # used in template # the user (which should also be an admin of the community) # to post the maintainer-only address as: my $suggestions_bot = LJ::load_user($LJ::SUGGESTIONS_USER); # verify proper configuration return $fatal_err->("This feature has not been configured for your site.") unless $destination && $suggestions_bot && $destination->is_community && $suggestions_bot->can_manage_other($destination); # make sure the remote user is OK to post my $remote = $rv->{remote}; return $fatal_err->("Sorry, you must have confirmed your email to make a suggestion.") unless $remote->is_validated; return $fatal_err->("Sorry, suspended accounts can't make suggestions.") if $remote->is_suspended; my $r = DW::Request->get; my $post_args = $r->post_args; my $errors = DW::FormErrors->new; if ( $r->did_post ) { my @pieces = qw( title area summary description ); my %ehtml_args; if ( $post_args->{post} ) { # verify that all fields are filled out: foreach my $field (@pieces) { if ( $post_args->{$field} ) { $ehtml_args{$field} = LJ::ehtml( $post_args->{$field} ); } else { $errors->add_string( $field, "You need to fill out the $field section." ); $ehtml_args{$field} = ''; } } # build out the post body including poll my $suggestion = DW::Template->template_string( "site/suggest_entry.tt", { post => \%ehtml_args, include_poll => 1 } ); # We have all the pieces, so let's build the post for DW. # For this, we're going to post as the user (so they get # any comments, etc), and we're going to auto-tag it as # "bugzilla: unmigrated", so the suggestions maintainer # can find new/untagged posts when they want to. my ( $response, $response2 ); # for errors returned from postevent my $journalpost; unless ( $errors->exist ) { $journalpost = LJ::Protocol::do_request( 'postevent', { 'ver' => $LJ::PROTOCOL_VER, 'username' => $remote->user, 'subject' => $post_args->{title}, 'event' => $suggestion, 'usejournal' => $destination->user, 'security' => 'public', 'usejournal_okay' => 1, 'props' => { taglist => 'bugzilla: unmigrated', opt_noemail => !$post_args->{email}, opt_preformatted => 1, }, 'tz' => 'guess', }, \$response, { 'nopassword' => 1, } ); } if ($journalpost) { # having built the post for public display, we now do # a second post containing the link to create the new bug # for the suggestion. we can't use $suggestion that we built, # because we need to use a different escaping function, but # that's okay, because we want to format this a little # differently anyway. my ( $ghi_subject, $ghi_desc, $ghi_args ); $ghi_subject = LJ::eurl( $post_args->{title} ); $ghi_desc = "Summary%3A%0D%0A%0D%0A"; $ghi_desc .= LJ::eurl( $post_args->{summary} ); $ghi_desc .= "%0D%0A%0D%0ADescription%3A%0D%0A%0D%0A"; $ghi_desc .= LJ::eurl( $post_args->{description} ); $ghi_desc .= "%0D%0A%0D%0ASuggested by%3A%0D%0A%0D%0A"; $ghi_desc .= LJ::eurl( $remote->user ); $ghi_args = "body=$ghi_desc&title=$ghi_subject"; my $ghi_post = DW::Template->template_string( "site/suggest_ghi.tt", { ghi_args => $ghi_args, title => $post_args->{title} } ); # and we post that post to the community. (the suggestions_bot # account should have unmoderated posting ability, so that the # post is posted directly to the comm without having to go # through moderation.) for this post, we tag it as # "admin: unmigrated", so the suggestions maintainer can find # any/all unposted GitHub links. # get the user's timzeone and put it into +/-0800 format # if we can't figure it out, then just guess based on suggestions bot my ( $remote_tz_sign, $remote_tz_offset ) = ( $remote->timezone =~ m/([+|-])?(\d+)/ ); my $remote_tz = defined $remote_tz_offset ? sprintf( "%s%02d00", $remote_tz_sign || "+", $remote_tz_offset ) : "guess"; LJ::Protocol::do_request( 'postevent', { 'ver' => $LJ::PROTOCOL_VER, 'username' => $suggestions_bot->user, 'subject' => $post_args->{title}, 'event' => $ghi_post, 'usejournal' => $destination->user, 'security' => 'private', 'usejournal_okay' => 1, 'props' => { taglist => 'admin: unmigrated', opt_preformatted => 1, }, 'tz' => $remote_tz, }, \$response2, { 'nopassword' => 1, } ); } # once all of that's done, let's tell the user it worked. # (or, if it didn't work, tell them why.) if ( $response || $response2 ) { $errors->add_string( '', LJ::Protocol::error_message( $response || $response2 ) ); } unless ( $errors->exist ) { return DW::Controller->render_success( 'site/suggest.tt', { commname => $destination->ljuser_display }, [ { text_ml => ".success.link.another", url => "$LJ::SITEROOT/site/suggest" }, { text_ml => ".success.link.view", url => $destination->journal_base }, ] ); } } elsif ( $post_args->{preview} ) { # make preview: first preview the title and text as # it would show up in the entry later; we don't need # the poll in here, as the user can't influence it anyway $ehtml_args{$_} = LJ::html_newlines( LJ::ehtml( $post_args->{$_} ) ) foreach @pieces; my $suggestion = DW::Template->template_string( "site/suggest_entry.tt", { post => \%ehtml_args, include_poll => 0 } ); $rv->{preview} = 1; $rv->{suggestion} = $suggestion; if ($LJ::SPELLER) { my $s = new LJ::SpellCheck { spellcommand => $LJ::SPELLER, class => "searchhighlight", }; my $spellcheck_html = $s->check_html( \$suggestion ); # unescape the
s for readability. All other HTML remains untouched. $spellcheck_html =~ s/<br \/>/
/g; $rv->{spellcheck} = $spellcheck_html; } } } $rv->{errors} = $errors; $rv->{formdata} = $post_args; return DW::Template->render_template( 'site/suggest.tt', $rv ); } 1;