2 title=><?_code BML::ml('.title_1', { 'siteabbr' => $LJ::SITENAMEABBREV}); _code?>
8 <script language="javascript">
10 function tblhilite(tbl, styname) {
11 tbl.className = styname;
19 my $crumb = $LJ::IS_SSL ? 'securecreatejournal_1' : 'createjournal_1';
20 LJ::set_active_crumb($crumb);
22 return LJ::server_down_html() if ($LJ::SERVER_DOWN);
24 return "<?badinput?>" unless LJ::text_in(\%POST);
26 my $mode = $POST{'mode'};
27 my $code = $POST{'code'} || $GET{'code'};
30 push @getargs,"from=$GET{from}" if $GET{from};
31 push @getargs,"user=$GET{user}" if $GET{user};
32 my $getextra = '?' . join('&', @getargs) if @getargs;
34 if ($LJ::USE_SSL && ! $LJ::IS_SSL && $FORM{'ssl'} ne "no") {
35 return BML::redirect("$LJ::SSLROOT/create.bml$getextra");
38 # with no mode, decide which screen the user sees first, based
39 # on whether or not this LJ installation lets in free users
41 $mode = $LJ::USE_ACCT_CODES ?
42 ($code ? "codesubmit" : "entercode")
46 my $remote = LJ::get_remote();
53 my $msg = $errors{$key};
55 return "$pre $msg $post";
58 # Flag to indicate they've submitted with 'audio' as the answer to the spambot
65 # validate a code they've entered and throw them back to entercode
66 # mode if it's invalid
67 if ($code && $mode eq "submit" || # account codes turned off, but one specified anyway
68 $LJ::USE_ACCT_CODES && ($mode eq "codesubmit" || $mode eq "submit")) # account codes required
71 my $userid = 0; # acceptable userid for double-click protection
72 if ($mode eq "submit") {
73 my $u = LJ::load_user($POST{'user'});
74 $userid = $u->{'userid'};
76 $errors{'code'} = $error
77 unless (LJ::acct_code_check($code, \$error, $userid));
80 } elsif ($mode eq "codesubmit") {
85 # MODE: entercode - enter an account code to proceed making an account
86 if ($LJ::USE_ACCT_CODES && $mode eq "entercode")
91 $ret .= "<form method=\"post\" action=\"create.bml\">\n";
92 $ret .= LJ::html_hidden(mode => 'codesubmit',
95 $ret .= "<?h1 $ML{'.useacctcodes.welcome'} h1?><?p $ML{'.useacctcodes.entercode'} p?>";
97 $v = LJ::ehtml($code);
98 $ret .= "<?standout Code: <input type=\"text\" name=\"code\" value=\"$v\" size=\"13\" maxlength=\"12\"> <input type=\"submit\" value=\"$ML{'.btn.proceed'}\">";
99 $ret .= $error_msg->('code', '<br>');
100 $ret .= " standout?>";
103 open (REM, "$LJ::HOME/htdocs/inc/account-codes");
112 # MODE: submit - if they've given 'audio' as the answer to the spambot-blocker,
113 # reset the mode to 'getinfo' and set the audio flag
114 if ( $LJ::HUMAN_CHECK{create} && $mode eq 'submit' && lc($POST{answer}) eq 'audio' )
120 # MODE: submit - try to create an account. might change mode
121 # if there are errors, we'll populate %errors and
122 # return to "getinfo" mode below
124 while ($mode eq "submit") # using while instead of if so we can 'last' out of it
126 return "<b>$ML{'Error'}</b>: $ML{'.error.postrequired'}" unless LJ::did_post();
128 my $user = LJ::canonical_username($POST{'user'});
129 my $email = LJ::trim(lc($POST{'email'}));
131 # setup global things that can be used to modify the user later
132 my $is_underage = 0; # turn on if the user should be marked as underage
133 my $ofage = 0; # turn on to note that the user is over 13 in actuality
134 # (but is_underage might be on which just means that their
135 # account is being marked as underage--even if they're old
136 # enough [unique cookie check])
139 return LJ::sysban_block(0, "Create user blocked based on email",
140 { 'new_user' => $user, 'email' => $email, 'name' => $user })
141 if LJ::sysban_check('email', $email);
143 my $dbh = LJ::get_db_writer();
145 if (length($user) > 15) {
146 $errors{'username'} = "$ML{'error.usernamelong'}";
148 if ($POST{'user'} && ! $user) {
149 $errors{'username'} = "$ML{'error.usernameinvalid'}";
151 unless ($POST{'user'}) {
152 $errors{'username'} = "$ML{'.error.username.mustenter'}";
154 foreach my $re ("^system\$", @LJ::PROTECTED_USERNAMES) {
155 next unless ($user =~ /$re/);
157 # you can give people sharedjournal priv ahead of time to create
158 # reserved communities:
159 next if LJ::check_priv($remote, "sharedjournal", $user);
161 $errors{'username'} = "$ML{'.error.username.reserved'}";
164 # see if they're confused and entered a valid account code
165 # for their username (happens often)
166 if ($LJ::USE_ACCT_CODES && $user =~ /^.....a[ab].....$/) {
167 # see if the acctcode is valid and unused
168 my ($acid, $auth) = LJ::acct_code_decode($user);
169 my $is_valid = $dbh->selectrow_array("SELECT COUNT(*) FROM acctcode ".
170 "WHERE acid=? AND rcptid=0",
172 $errors{'username'} = "$ML{'.error.username.iscode'}"
176 my $u = LJ::load_user($user);
177 my $second_submit = 0;
179 # do not create if this account name is purged
180 if ($u && $u->{'statusvis'} eq "X") {
181 $errors{'username'} = BML::ml('.error.username.purged',
182 {'aopts' => 'href="/rename/"'} );
186 if ($u->{'email'} eq $POST{'email'}) {
187 if (LJ::login_ip_banned($u)) {
188 # brute-force possible going on
190 if ($u->{'password'} eq $POST{'password1'}) {
191 # okay either they double-clicked the submit button
192 # or somebody entered an account name that already exists
193 # with the existing password
197 LJ::handle_bad_login($u);
203 $errors{'username'} = "$ML{'.error.username.inuse'}";
207 $POST{'password1'} = LJ::trim($POST{'password1'});
208 $POST{'password2'} = LJ::trim($POST{'password2'});
210 if ($POST{'password1'} ne $POST{'password2'}) {
211 $errors{'password'} = "$ML{'.error.password.nomatch'}";
213 my $checkpass = LJ::run_hook("bad_password",
217 'password' => $POST{'password1'},
220 $errors{'password'} = "Bad password: $checkpass";
223 if (! $POST{'password1'}) {
224 $errors{'password'} = "$ML{'.error.password.blank'}";
225 } elsif (length $POST{'password1'} > 30) {
226 $errors{'password'} = "$ML{'password.max30'}";
229 unless (LJ::is_ascii($POST{'password1'})) {
230 $errors{'password'} = "$ML{'.error.password.asciionly'}";
233 ### start COPPA_CHECK
234 # age checking to determine how old they are
235 if ($LJ::COPPA_CHECK) {
237 if ($LJ::UNIQ_COOKIES) {
238 $uniq = LJ::Request->notes('uniq');
240 my $timeof = $dbh->selectrow_array('SELECT timeof FROM underage WHERE uniq = ?', undef, $uniq);
241 $is_underage = 1 if $timeof && $timeof > 0;
245 my ($year, $mon, $day) = ( $POST{"bday_yyyy"}+0, $POST{"bday_mm"}+0, $POST{"bday_dd"}+0 );
246 if ($year < 100 && $year > 0) {
247 $POST{'bday_yyyy'} += 1900;
252 my ($nday, $nmon, $nyear) = (gmtime())[3, 4, 5];
256 # require dates in the 1900s (or beyond)
257 if ($year && $mon && $day && $year >= 1900 && $year < $nyear) {
258 # now see how many years back they are
259 my $ofageyear = $year + 13;
260 if ($ofageyear > $nyear) {
262 } elsif ($ofageyear == $nyear) {
263 # years match, see if they were born after this month
266 } elsif ($mon == $nmon) {
280 $errors{'bday'} = "$ML{'.error.birthday.invalid'}";
283 # note this unique cookie as underage (if we have a unique cookie)
284 if ($is_underage && $uniq) {
285 $dbh->do("REPLACE INTO underage (uniq, timeof) VALUES (?, UNIX_TIMESTAMP())", undef, $uniq);
290 if ($LJ::TOS_CHECK && ! $POST{'agree_tos'}) {
291 $errors{'agree_tos'} = $ML{'tos.error'};
294 # check the email address
297 LJ::check_email($email, \@email_errors);
298 if ($LJ::USER_EMAIL and $email =~ /\@\Q$LJ::USER_DOMAIN\E$/i) {
299 push @email_errors, BML::ml(".error.email.lj_domain",
300 {domain => $LJ::USER_DOMAIN});
302 $errors{'email'} = join(", ", @email_errors) if @email_errors;
305 # Check the turing test answer if it's turned on
306 if ($LJ::HUMAN_CHECK{create}) {
307 ($capid, $anum) = LJ::Captcha::session_check_code($POST{captcha_chal}, $POST{answer});
308 $errors{'captcha'} = $ML{'.captcha.invalid'} unless $capid && $anum;
310 last SUBMIT if %errors;
312 my $clusterid = ($LJ::DEBUG{'allow_cluster_select'}
313 ? $POST{'cluster_id'}
314 : LJ::new_account_cluster()) + 0;
315 die "Cluster 0 not supported" unless $clusterid;
317 my $userid = $u ? $u->{'userid'}+0 : 0;
319 # create user and send email as long as the user didn't double-click submit
320 # (or they tried to re-create a purged account)
321 unless ($second_submit) {
322 my $bdate = sprintf("%04d-%02d-%02d", $POST{bday_yyyy}, $POST{bday_mm}, $POST{bday_dd});
324 my $nu = LJ::User->create_personal(
328 'password' => $POST{password1},
329 'get_ljnews' => $POST{news},
330 'inviter' => $inviter,
331 'underage' => $is_underage,
334 return "There was an error creating your account." unless $nu;
336 # Mark the turing test for deletion
337 if ($LJ::HUMAN_CHECK{create}) {
338 LJ::Captcha::expire($capid, $anum, $nu->id);
341 # if we're using account codes on this site, mark the code as used
343 my ($acid, $auth) = LJ::acct_code_decode($code);
344 $dbh->do("UPDATE acctcode SET rcptid=$nu->id WHERE acid=$acid");
345 if ($dbh->err) { return $dbh->errstr; }
348 foreach my $friend (@LJ::INITIAL_OPTIONAL_FRIENDS) {
349 my $friendid = LJ::get_userid($friend);
350 LJ::add_friend($nu->id, $friendid) if $friendid and $POST{"initial_optional_friend_$friend"};
353 # Mark the turing test for deletion
354 if ($LJ::HUMAN_CHECK{create}) {
355 LJ::Captcha::expire($capid, $anum, $nu->id);
358 # send welcome mail... unless they're underage
359 unless ($is_underage) {
360 my $aa = LJ::register_authaction($nu->id, "validateemail", $email);
362 my $body = BML::ml('email.newacct4.body', {
363 "sitename" => $LJ::SITENAME,
364 "regurl" => "$LJ::SITEROOT/confirm/$aa->{'aaid'}.$aa->{'authcode'}",
365 "journal_base" => $nu->journal_base,
366 "username" => $nu->user,
367 "siteroot" => $LJ::SITEROOT,
368 "sitenameshort" => $LJ::SITENAMESHORT,
369 "lostinfourl" => "$LJ::SITEROOT/lostinfo.bml",
370 "editprofileurl" => "$LJ::SITEROOT/manage/profile/",
371 "searchinterestsurl" => "$LJ::SITEROOT/interests.bml",
372 "editpicsurl" => "$LJ::SITEROOT/editpics.bml",
373 "customizeurl" => "$LJ::SITEROOT/customize/style.bml",
374 "postentryurl" => "$LJ::SITEROOT/update.bml",
379 'from' => $LJ::ADMIN_EMAIL,
380 'fromname' => $LJ::SITENAME,
381 'charset' => 'utf-8',
382 'subject' => BML::ml('email.newacct.subject', {'sitename' => $LJ::SITENAME}),
387 # If they were invited then add friend and do joins
388 # Needed to do this after we load the $nu object
390 my $ivf = LJ::load_user($POST{from});
391 my $friend = $POST{"inviter_friend_$ivf->{user}"};
393 LJ::add_friend($nu->id, $ivf->{userid})
397 foreach (split(',', $POST{inviter_joins})) {
398 # Join the comm and add to friends list
399 next unless $POST{"inviter_join_$_"};
403 my $ci = LJ::get_community_row($_);
405 if ($ci->{membership} eq 'open') {
406 LJ::join_community($nu->id, $_, 1);
408 my $cu = LJ::load_userid($_);
409 next unless $cu && $nu;
411 LJ::comm_join_request($cu, $nu);
412 LJ::add_friend($nu->id, $cu->{userid});
416 # Log who invited them
417 my $ijoinsstr = join(',', @ijoins);
418 LJ::statushistory_add($nu->id, $ivf->{userid}, 'create_from_invite',
419 "Recommended: $POST{inviter_joins}\nJoined: $ijoinsstr");
421 # Send the inviter an email
422 my $body = BML::ml('.email.invite.body', {
423 username => $ivf->{user},
424 sitename => $LJ::SITENAMESHORT,
425 infolink => "$LJ::SITEROOT/userinfo.bml?user=$nu->{user}",
426 invitelink => "$LJ::SITEROOT/friends/invite.bml"
430 'to' => $ivf->{email},
431 'from' => $LJ::ADMIN_EMAIL,
432 'fromname' => $LJ::SITENAME,
433 'charset' => 'utf-8',
434 'subject' => BML::ml('.email.invite.subject', {'sitename' => $LJ::SITENAMESHORT}),
440 if ($LJ::TOS_CHECK) {
442 $nu->tosagree_set(\$err)
443 or return LJ::bad_input($err);
446 $nu->make_login_session;
448 # local sites may want to override what happens at this point
449 my $redirect = undef;
451 LJ::run_hooks("create.bml_postsession", {
454 redirect => \$redirect,
456 stop_output => \$stop_output,
458 return BML::redirect($redirect) if $redirect;
459 return $ret if $stop_output;
461 return BML::redirect("$LJ::SITEROOT/newuser.bml");
466 if ($mode eq "getinfo" || %errors)
472 my @errors_order = ('code', 'username', 'email', 'password', 'agree_tos', 'captcha', 'invalidform');
474 $errors_def{$_} = 1 for @errors_order;
475 foreach my $key (keys %errors) { push @errors_order, $key unless $errors_def{$key}; }
476 $ret .= "<?standout <strong>$ML{'.errors.label'}</strong><ul><li>";
477 $ret .= join ("</li><li>", grep { $_ } map { $errors{$_} } @errors_order);
478 $ret .= "</li></ul> standout?>";
481 $ret .= "<?p $ML{'.create.text_1'} " .
482 BML::ml('.community', { aopts => "href='$LJ::SITEROOT/community/create.bml'" }) .
483 " p?>" unless %errors;
484 $ret .= "<form action=\"create.bml\" method=\"post\">\n";
485 $ret .= LJ::html_hidden(mode => 'submit',
487 ssl => $FORM{'ssl'});
492 $v = LJ::ehtml($FORM{'user'});
493 $ret .= "<li><div class='formitem'><div class='formitemName'>$ML{'.username.box.head'}</div>";
494 $ret .= $error_msg->('username', '<p class="formitemFlag">', '</p>');
495 $ret .= "<div class='formitemDesc'>" .
496 BML::ml(".username.text_1", {'sitename' => $LJ::SITENAME,
497 'lc_sitename' => lc($LJ::SITENAME) })
499 $ret .= LJ::html_text({'name' => 'user', 'size' => 15, 'maxlength' => 15, 'value' => $v, raw => 'style="<?loginboxstyle?>"' });
500 $ret .= " ($ML{'.username.maxchars'})<br />\n";
501 $ret .= "<div class='formitemNote'>$ML{'.username.charsallowed_1'}</div>" if (!%errors || exists $errors{'username'});
502 $ret .= "</div></li>";
505 $v = LJ::ehtml($FORM{'email'});
506 $ret .= "<li><div class='formitem'><div class='formitemName'>$ML{'.email.input.head'}</div>";
507 $ret .= $error_msg->('email', '<p class="formitemFlag">', '</p>');
508 $ret .= "<div class='formitemDesc'>" . BML::ml('.email.text_1', {
509 aopts => "target='_new' href='$LJ::SITEROOT/legal/privacy.bml'",
511 $ret .= LJ::html_text({'name' => 'email', 'size' => 40, 'maxlength' => 50, 'value' => $v,});
512 $ret .= "</div></li>";
515 $ret .= "<li><div class='formitem'><div class='formitemName'>$ML{'.password.input.head1'}</div>\n";
516 $ret .= $error_msg->('password', '<p class="formitemFlag">', '</p>');
517 $ret .= "<div class='formitemFlag'>$ML{'.password.secure'}</div>" if exists $errors{'password'};
518 $ret .= "<div style='float: left;'><div class='formitemDesc'>$ML{'.password.text'}</div>\n<div>";
519 my $pass_value = $errors{'password'} ? "" : $POST{'password1'};
520 $ret .= LJ::html_text({'name' => 'password1', 'size' => 30, 'maxlength' => 31, 'type' => "password",
521 value => $pass_value, });
522 $ret .= "</div><div class='formitemDesc'>$ML{'.password.input.head2'}</div>\n<div>";
523 $ret .= LJ::html_text({'name' => 'password2', 'size' => 30, 'maxlength' => 31, 'type' => "password",
524 value => $pass_value, });
525 $ret .= "</div></div><div class='formitemNote' style='float: left; margin-left: 20px; width: 340px'>\n";
526 unless ($LJ::NO_PASSWORD_CHECK) {
527 $ret .= BML::ml('.password.secure_1',
528 { aopts => "target='_new' href='$LJ::HELPURL{secure_password}'"});
529 $ret .= "<ul style='margin-left: 20px; padding-left: 0px;'>";
530 $ret .= "<li>$ML{'.password.secure.pt1'}</li>\n";
531 $ret .= "<li>$ML{'.password.secure.pt2'}</li>\n";
532 $ret .= "<li>$ML{'.password.secure.pt3'}</li>\n";
533 $ret .= "<li>$ML{'.password.secure.pt4'}</li>\n</ul>\n";
535 $ret .= "</div><div style='clear: both'></div></li>";
537 if (@LJ::INITIAL_OPTIONAL_FRIENDS) {
538 $ret .= "<li><div class='formitem'><div class='formitemName'>$ML{'.initialfriends.heading'}</div>";
539 $ret .= "<div class='formitemDesc'>$ML{'.initialfriends'}</div>";
541 foreach my $friend (@LJ::INITIAL_OPTIONAL_FRIENDS) {
542 my $selected = LJ::did_post() ? $POST{"initial_optional_friend_$friend"} :
543 (grep { $_ eq $friend } @LJ::INITIAL_OPTOUT_FRIENDS);
545 $ret .= LJ::html_check({'name' => "initial_optional_friend_$friend",
547 'selected' => $selected,
548 'id' => "optfriend_$friend",
550 $ret .= "<label for='optfriend_$friend'>" .
551 LJ::ljuser($friend) . " " . $ML{".initial.friend.$friend"} .
554 $ret .= "</div></div></li>";
558 # Was this person invited by another user? If so,
559 # then show interface to add inviter as friend as
560 # well as 10ish communities they are a member of
561 my $ifrom = LJ::did_post() ? $POST{from} : $GET{from};
563 $inviter = LJ::load_user($ifrom)
567 $ret .= "<li><div class='formitem'><div class='formitemName'>Your friend " . LJ::ljuser($inviter) . " welcomes you to ";
568 $ret .= "$LJ::SITENAMESHORT</div>";
572 $ret .= LJ::html_hidden('from', $inviter->{user});
574 $ret .= LJ::html_check({ name => "inviter_friend_$inviter->{user}",
576 selected => LJ::did_post() ? $POST{"inviter_friend_$inviter->{user}"} : 1,
577 id => "inviter_$inviter->{user}",
579 $ret .= "<label for='inviter_$inviter->{user}'>" .
580 'add ' . LJ::ljuser($inviter->{user}) . ' as a friend' .
584 unless ($POST{inviter_joins}) {
585 # Load their friendofs to determine community membership
586 my @ids = LJ::get_friendofs($inviter);
588 LJ::load_userids_multiple([ map { $_ => \$fro{$_} } @ids ]);
590 foreach my $ulocal (values %fro) {
591 next unless $ulocal->{'statusvis'} eq 'V';
592 next unless $ulocal->{'journaltype'} eq 'C';
594 # TODO: This is bad if they belong to a lot of communities,
595 # is a db query to global each call
596 my $ci = LJ::get_community_row($ulocal);
597 next if $ci->{'membership'} eq 'closed';
600 $ulocal->{istatus} = 'normal';
601 $comms{$ulocal->{userid}} = $ulocal;
604 # Get usage information about comms
606 my $ids = join(',', map { $_->{userid} } values %comms);
608 my $dbr = LJ::get_db_reader;
609 my $sth = $dbr->prepare("SELECT UNIX_TIMESTAMP(timeupdate), UNIX_TIMESTAMP(timecreate), userid ".
610 "FROM userusage WHERE userid IN($ids)");
613 while (my @row = $sth->fetchrow_array) {
614 ($comms{$row[2]}->{'timeupdate'},
615 $comms{$row[2]}->{'timecreate'}) = ($row[0], $row[1]);
619 # Prune the list by time last updated and make sure to
620 # display comms created in the past 10 days or where
621 # the inviter is a maint or mod
624 foreach my $comm (sort {$b->{timeupdate} <=> $a->{timeupdate}} values %comms) {
625 if ($now - $comm->{timecreate} <= 86400*10) {
626 $comm->{istatus} = 'new';
630 my $maintainers = LJ::load_rel_user_cache($comm->{userid}, 'A') || [];
631 my $moderators = LJ::load_rel_user_cache($comm->{userid}, 'M') || [];
632 foreach (@$maintainers, @$moderators) {
633 if ($_ == $inviter->{userid}) {
634 $comm->{istatus} = 'mm';
640 delete $comms{$comm->{userid}};
643 if (time() - $comm->{timeupdate} > 86400*30) {
644 delete $comms{$comm->{userid}};
650 # If we still have more than 20 comms, delete any with less than
652 if (scalar keys %comms > 20) {
653 foreach my $comm (values %comms) {
654 next unless $comm->{istatus} eq 'normal';
656 my $ids = LJ::get_friends($comm);
657 if (scalar values %$ids < 5) {
658 delete $comms{$comm->{userid}};
664 if (LJ::did_post()) {
665 foreach (split(',', $POST{inviter_joins})) {
666 my $cj = LJ::load_userid($_);
673 $ret .= "<br />Select which of your friend's communities you'd like to join:<br />";
676 foreach my $comm (sort { $a->{user} cmp $b->{user} } values %comms) {
678 $ret .= LJ::html_check({ name => "inviter_join_$comm->{userid}",
680 selected => LJ::did_post() ? $POST{"inviter_join_$comm->{user}"} : 0,
681 id => "inviter_$comm->{user}",
684 my $le = $comm->{istatus} eq 'mm' ? ' *' : '';
686 $ret .= "<label for='inviter_$comm->{user}'>" .
687 LJ::ljuser($comm->{user}) . " - $comm->{name}$le</label><br />";
688 push @joins, $comm->{userid};
691 $ret .= LJ::html_hidden('inviter_joins', join(',', @joins));
693 $ret .= "<?de A community with a * means that your friend is a maintainer or moderator of that community. de?>";
695 $ret .= "</div></li>";
698 if ($LJ::COPPA_CHECK)
700 $ret .= "<li><div class='formitem'><div class='formitemName'>$ML{'.birthday.head'}</div>";
701 $ret .= "<div class='formitemFlag'>$errors{'bday'}</div>" if exists $errors{'bday'};
702 $ret .= "<div class='formitemDesc'>";
703 $ret .= BML::ml('.birthday.question_3', {'aopts' => "target='_new' href='$LJ::SITEROOT/legal/privacy.bml'"});
704 $ret .= "</div><div>";
705 $ret .= "<table><tr><td><span class='formitemName'>$ML{'.birthday.birthdate'}</span></td><td>";
706 $ret .= LJ::html_datetime({ name => 'bday', notime => 1,
707 default => sprintf("%04d-%02d-%02d", $POST{bday_yyyy}, $POST{bday_mm}, $POST{bday_dd}) });
708 $ret .= "</td></tr>";
709 $ret .= "</table></div></div></li>";
711 $ret .= "<div class='formitemNote'>$ML{'.birthday.warning'}</div>";
714 LJ::run_hooks("create.bml_opts", {
722 $ret .= "<li><div class='formitem'><div class='formitemName'>$ML{'.tos.heading'}</div>";
723 $ret .= LJ::tosagree_widget($POST{agree_tos}, $errors->{agree_tos});
724 $ret .= "</div></li>";
727 if ($LJ::DEBUG{'allow_cluster_select'}) {
728 $ret .= "<li><div class='formitem'><div class='formitemName'>$ML{'.clusterselect.head'}</div>";
729 $ret .= "<div class='formitemDesc'>$ML{'.clusterselect.text'}</div>";
730 $ret .= LJ::html_select({ 'name' => 'cluster_id' },
731 "0", "$BML{'.clusterselect.nocluster'}",
732 map { $_, BML::ml(".clusterselect.clusternum", {'number' => $_}) } @LJ::CLUSTERS);
734 $ret .= "<div class='formitemNote'>$ML{'.clusterselect.cluster'}</div>";
735 $ret .= "</div></li>";
738 if ($LJ::HUMAN_CHECK{create}) {
739 my ($captcha_chal, $captcha_sess);
741 my $answer = $POST{answer};
742 undef $answer if $errors{'captcha'} || $wants_audio;
743 $captcha_chal = $POST{captcha_chal};
744 undef $captcha_chal if $errors{'captcha'};
746 $captcha_chal = $captcha_chal || LJ::challenge_generate(900);
747 $captcha_sess = LJ::get_challenge_attributes($captcha_chal);
750 if ($form->{captcha_chal}) {
751 my $dbcm = LJ::get_cluster_reader();
752 $try = $dbcm->selectrow_array('SELECT trynum FROM captcha_session ' .
753 'WHERE sess=?', undef, $captcha_sess);
756 $ret .= "<li><div class='formitem'><div class='formitemName'>$ML{'.captcha.prove'}</div>";
759 unless ( $wants_audio || $POST{audio_chal} ) {
760 $ret .= "<div class='formitemDesc'>$ML{'.captcha.desc'}</div>";
761 if ($capid && $anum) { # previously entered correctly
762 $ret .= "<img src='/captcha/image.bml?capid=$capid&anum=$anum' width='175' height='35' />";
764 $ret .= "<img src='/captcha/image.bml?chal=$captcha_chal&try=$try' width='175' height='35' />";
770 $ret .= "<div class='formitemDesc'>$ML{'.captcha.audiodesc'}</div>";
771 if ($capid && $anum) {
772 $ret .= "<a href='/captcha/audio.bml?capid=$capid&anum=$anum'>$ML{'.captcha.play'}</a>";
774 $ret .= "<a href='/captcha/audio.bml?chal=$captcha_chal&try=$try'>$ML{'.captcha.play'}</a>";
776 $ret .= LJ::html_hidden(audio_chal => 1);
779 $ret .= "<br /><br />$ML{'.captcha.answer'}";
780 $ret .= LJ::html_text({ name => 'answer', size => 15, value => $answer });
781 $ret .= LJ::html_hidden(captcha_chal => $captcha_chal);
782 $ret .= $error_msg->('captcha', '<p class="formitemFlag">', '</p>');
783 $ret .= "</div></li>";
788 $ret .= "<div style='width:600; text-align: center'>";
789 $ret .= "<input type=\"submit\" value=\"$ML{'.btn.create'}\">";
796 return "$ML{'error.unknownmode'}: <b>$mode</b>";
801 link: htdocs/legal/privacy.bml
802 post: htdocs/create.bml, htdocs/manage/profile/index.bml
803 file: htdocs/inc/account-codes