From 1751bb3af4311627abe59c20e97e969f9630a1a7 Mon Sep 17 00:00:00 2001 From: hscale Date: Sat, 6 Jun 2015 03:05:32 +0700 Subject: [PATCH] first commit --- pages-override.php | 56 + pages/account.php | 446 ++++++++ pages/activity.php | 85 ++ pages/admin/admin-approve.php | 140 +++ pages/admin/admin-categories.php | 621 +++++++++++ pages/admin/admin-default.php | 1755 ++++++++++++++++++++++++++++++ pages/admin/admin-flagged.php | 140 +++ pages/admin/admin-hidden.php | 171 +++ pages/admin/admin-moderate.php | 163 +++ pages/admin/admin-pages.php | 582 ++++++++++ pages/admin/admin-plugins.php | 230 ++++ pages/admin/admin-points.php | 187 ++++ pages/admin/admin-recalc.php | 137 +++ pages/admin/admin-stats.php | 281 +++++ pages/admin/admin-userfields.php | 262 +++++ pages/admin/admin-usertitles.php | 185 ++++ pages/admin/admin-widgets.php | 333 ++++++ pages/answers.php | 80 ++ pages/ask.php | 286 +++++ pages/categories.php | 118 ++ pages/comments.php | 79 ++ pages/confirm.php | 155 +++ pages/default.php | 174 +++ pages/favorites-list.php | 107 ++ pages/favorites.php | 124 +++ pages/feedback.php | 185 ++++ pages/forgot.php | 125 +++ pages/hot.php | 80 ++ pages/ip.php | 235 ++++ pages/login.php | 177 +++ pages/logout.php | 40 + pages/message.php | 243 +++++ pages/messages.php | 125 +++ pages/question-post.php | 1025 +++++++++++++++++ pages/question-submit.php | 460 ++++++++ pages/question-view.php | 1005 +++++++++++++++++ pages/question.php | 426 ++++++++ pages/questions.php | 140 +++ pages/register.php | 249 +++++ pages/reset.php | 139 +++ pages/search.php | 153 +++ pages/tag.php | 98 ++ pages/tags.php | 84 ++ pages/unanswered.php | 144 +++ pages/unsubscribe.php | 81 ++ pages/updates.php | 115 ++ pages/user-activity.php | 103 ++ pages/user-answers.php | 110 ++ pages/user-profile.php | 982 +++++++++++++++++ pages/user-questions.php | 105 ++ pages/user-wall.php | 164 +++ pages/user.php | 90 ++ pages/users-blocked.php | 95 ++ pages/users-special.php | 86 ++ pages/users.php | 87 ++ qa-plugin.php | 14 + 56 files changed, 14062 insertions(+) create mode 100644 pages-override.php create mode 100644 pages/account.php create mode 100644 pages/activity.php create mode 100644 pages/admin/admin-approve.php create mode 100644 pages/admin/admin-categories.php create mode 100644 pages/admin/admin-default.php create mode 100644 pages/admin/admin-flagged.php create mode 100644 pages/admin/admin-hidden.php create mode 100644 pages/admin/admin-moderate.php create mode 100644 pages/admin/admin-pages.php create mode 100644 pages/admin/admin-plugins.php create mode 100644 pages/admin/admin-points.php create mode 100644 pages/admin/admin-recalc.php create mode 100644 pages/admin/admin-stats.php create mode 100644 pages/admin/admin-userfields.php create mode 100644 pages/admin/admin-usertitles.php create mode 100644 pages/admin/admin-widgets.php create mode 100644 pages/answers.php create mode 100644 pages/ask.php create mode 100644 pages/categories.php create mode 100644 pages/comments.php create mode 100644 pages/confirm.php create mode 100644 pages/default.php create mode 100644 pages/favorites-list.php create mode 100644 pages/favorites.php create mode 100644 pages/feedback.php create mode 100644 pages/forgot.php create mode 100644 pages/hot.php create mode 100644 pages/ip.php create mode 100644 pages/login.php create mode 100644 pages/logout.php create mode 100644 pages/message.php create mode 100644 pages/messages.php create mode 100644 pages/question-post.php create mode 100644 pages/question-submit.php create mode 100644 pages/question-view.php create mode 100644 pages/question.php create mode 100644 pages/questions.php create mode 100644 pages/register.php create mode 100644 pages/reset.php create mode 100644 pages/search.php create mode 100644 pages/tag.php create mode 100644 pages/tags.php create mode 100644 pages/unanswered.php create mode 100644 pages/unsubscribe.php create mode 100644 pages/updates.php create mode 100644 pages/user-activity.php create mode 100644 pages/user-answers.php create mode 100644 pages/user-profile.php create mode 100644 pages/user-questions.php create mode 100644 pages/user-wall.php create mode 100644 pages/user.php create mode 100644 pages/users-blocked.php create mode 100644 pages/users-special.php create mode 100644 pages/users.php create mode 100644 qa-plugin.php diff --git a/pages-override.php b/pages-override.php new file mode 100644 index 0000000..2733d69 --- /dev/null +++ b/pages-override.php @@ -0,0 +1,56 @@ + '../qa-plugin/override-pages/pages/account.php', + 'activity/' => '../qa-plugin/override-pages/pages/activity.php', + 'admin/' => '../qa-plugin/override-pages/pages/admin/admin-default.php', + 'admin/approve' => '../qa-plugin/override-pages/pages/admin/admin-approve.php', + 'admin/categories' => '../qa-plugin/override-pages/pages/admin/admin-categories.php', + 'admin/flagged' => '../qa-plugin/override-pages/pages/admin/admin-flagged.php', + 'admin/hidden' => '../qa-plugin/override-pages/pages/admin/admin-hidden.php', + 'admin/layoutwidgets' => '../qa-plugin/override-pages/pages/admin/admin-widgets.php', + 'admin/moderate' => '../qa-plugin/override-pages/pages/admin/admin-moderate.php', + 'admin/pages' => '../qa-plugin/override-pages/pages/admin/admin-pages.php', + 'admin/plugins' => '../qa-plugin/override-pages/pages/admin/admin-plugins.php', + 'admin/points' => '../qa-plugin/override-pages/pages/admin/admin-points.php', + 'admin/recalc' => '../qa-plugin/override-pages/pages/admin/admin-recalc.php', + 'admin/stats' => '../qa-plugin/override-pages/pages/admin/admin-stats.php', + 'admin/userfields' => '../qa-plugin/override-pages/pages/admin/admin-userfields.php', + 'admin/usertitles' => '../qa-plugin/override-pages/pages/admin/admin-usertitles.php', + 'answers/' => '../qa-plugin/override-pages/pages/answers.php', + 'ask' => '../qa-plugin/override-pages/pages/ask.php', + 'categories/' => '../qa-plugin/override-pages/pages/categories.php', + 'comments/' => '../qa-plugin/override-pages/pages/comments.php', + 'confirm' => '../qa-plugin/override-pages/pages/confirm.php', + 'favorites' => '../qa-plugin/override-pages/pages/favorites.php', + 'favorites/questions' => '../qa-plugin/override-pages/pages/favorites-list.php', + 'favorites/users' => '../qa-plugin/override-pages/pages/favorites-list.php', + 'favorites/tags' => '../qa-plugin/override-pages/pages/favorites-list.php', + 'feedback' => '../qa-plugin/override-pages/pages/feedback.php', + 'forgot' => '../qa-plugin/override-pages/pages/forgot.php', + 'hot/' => '../qa-plugin/override-pages/pages/hot.php', + 'ip/' => '../qa-plugin/override-pages/pages/ip.php', + 'login' => '../qa-plugin/override-pages/pages/login.php', + 'logout' => '../qa-plugin/override-pages/pages/logout.php', + 'messages/' => '../qa-plugin/override-pages/pages/messages.php', + 'message/' => '../qa-plugin/override-pages/pages/message.php', + 'questions/' => '../qa-plugin/override-pages/pages/questions.php', + 'register' => '../qa-plugin/override-pages/pages/register.php', + 'reset' => '../qa-plugin/override-pages/pages/reset.php', + 'search' => '../qa-plugin/override-pages/pages/search.php', + 'tag/' => '../qa-plugin/override-pages/pages/tag.php', + 'tags' => '../qa-plugin/override-pages/pages/tags.php', + 'unanswered/' => '../qa-plugin/override-pages/pages/unanswered.php', + 'unsubscribe' => '../qa-plugin/override-pages/pages/unsubscribe.php', + 'updates' => '../qa-plugin/override-pages/pages/updates.php', + 'user/' => '../qa-plugin/override-pages/pages/user.php', + 'users' => '../qa-plugin/override-pages/pages/users.php', + 'users/blocked' => '../qa-plugin/override-pages/pages/users-blocked.php', + 'users/special' => '../qa-plugin/override-pages/pages/users-special.php', + ); + return $pages; +} +?> \ No newline at end of file diff --git a/pages/account.php b/pages/account.php new file mode 100644 index 0000000..f4a65dd --- /dev/null +++ b/pages/account.php @@ -0,0 +1,446 @@ + 0) { + require_once QA_INCLUDE_DIR.'app/limits.php'; + + switch (qa_user_permit_error(null, QA_LIMIT_UPLOADS)) { + case 'limit': + $errors['avatar'] = qa_lang('main/upload_limit'); + break; + + default: + $errors['avatar'] = qa_lang('users/no_permission'); + break; + + case false: + qa_limits_increment($userid, QA_LIMIT_UPLOADS); + + $toobig = qa_image_file_too_big($_FILES['file']['tmp_name'], qa_opt('avatar_store_size')); + + if ($toobig) + $errors['avatar'] = qa_lang_sub('main/image_too_big_x_pc', (int) ($toobig * 100)); + elseif (!qa_set_user_avatar($userid, file_get_contents($_FILES['file']['tmp_name']), $useraccount['avatarblobid'])) + $errors['avatar'] = qa_lang_sub('main/image_not_read', implode(', ', qa_gd_image_formats())); + break; + } + } // There shouldn't be any need to catch any other error + } + + if (count($inprofile)) { + $filtermodules = qa_load_modules_with('filter', 'filter_profile'); + foreach ($filtermodules as $filtermodule) + $filtermodule->filter_profile($inprofile, $errors, $useraccount, $userprofile); + } + + foreach ($userfields as $userfield) + if (!isset($errors[$userfield['fieldid']])) + qa_db_user_profile_set($userid, $userfield['title'], $inprofile[$userfield['fieldid']]); + + list($useraccount, $userprofile) = qa_db_select_with_pending( + qa_db_user_account_selectspec($userid, true), qa_db_user_profile_selectspec($userid, true) + ); + + qa_report_event('u_save', $userid, $useraccount['handle'], qa_cookie_get()); + + if (empty($errors)) + qa_redirect('account', array('state' => 'profile-saved')); + + qa_logged_in_user_flush(); + } + } + + + // Process change password if clicked + + if (qa_clicked('dochangepassword')) { + require_once QA_INCLUDE_DIR.'app/users-edit.php'; + + $inoldpassword = qa_post_text('oldpassword'); + $innewpassword1 = qa_post_text('newpassword1'); + $innewpassword2 = qa_post_text('newpassword2'); + + if (!qa_check_form_security_code('password', qa_post_text('code'))) + $errors['page'] = qa_lang_html('misc/form_security_again'); + + else { + $errors = array(); + + if ($haspassword && (strtolower(qa_db_calc_passcheck($inoldpassword, $useraccount['passsalt'])) != strtolower($useraccount['passcheck']))) + $errors['oldpassword'] = qa_lang('users/password_wrong'); + + $useraccount['password'] = $inoldpassword; + $errors = $errors + qa_password_validate($innewpassword1, $useraccount); // array union + + if ($innewpassword1 != $innewpassword2) + $errors['newpassword2'] = qa_lang('users/password_mismatch'); + + if (empty($errors)) { + qa_db_user_set_password($userid, $innewpassword1); + qa_db_user_set($userid, 'sessioncode', ''); // stop old 'Remember me' style logins from still working + qa_set_logged_in_user($userid, $useraccount['handle'], false, $useraccount['sessionsource']); // reinstate this specific session + + qa_report_event('u_password', $userid, $useraccount['handle'], qa_cookie_get()); + + qa_redirect('account', array('state' => 'password-changed')); + } + } + } + } + +// Prepare content for theme + + $qa_content=qa_content_prepare(); + + $qa_content['title']=qa_lang_html('profile/my_account_title'); + $qa_content['error']=@$errors['page']; + + $qa_content['form_profile']=array( + 'tags' => 'enctype="multipart/form-data" method="post" action="'.qa_self_html().'"', + + 'style' => 'wide', + + 'fields' => array( + 'duration' => array( + 'type' => 'static', + 'label' => qa_lang_html('users/member_for'), + 'value' => qa_time_to_string(qa_opt('db_time')-$useraccount['created']), + ), + + 'type' => array( + 'type' => 'static', + 'label' => qa_lang_html('users/member_type'), + 'value' => qa_html(qa_user_level_string($useraccount['level'])), + 'note' => $isblocked ? qa_lang_html('users/user_blocked') : null, + ), + + 'handle' => array( + 'label' => qa_lang_html('users/handle_label'), + 'tags' => 'name="handle"', + 'value' => qa_html(isset($inhandle) ? $inhandle : $useraccount['handle']), + 'error' => qa_html(@$errors['handle']), + 'type' => ($changehandle && !$isblocked) ? 'text' : 'static', + ), + + 'email' => array( + 'label' => qa_lang_html('users/email_label'), + 'tags' => 'name="email"', + 'value' => qa_html(isset($inemail) ? $inemail : $useraccount['email']), + 'error' => isset($errors['email']) ? qa_html($errors['email']) : + (($doconfirms && !$isconfirmed) ? qa_insert_login_links(qa_lang_html('users/email_please_confirm')) : null), + 'type' => $isblocked ? 'static' : 'text', + ), + + 'messages' => array( + 'label' => qa_lang_html('users/private_messages'), + 'tags' => 'name="messages"', + 'type' => 'checkbox', + 'value' => !($useraccount['flags'] & QA_USER_FLAGS_NO_MESSAGES), + 'note' => qa_lang_html('users/private_messages_explanation'), + ), + + 'wall' => array( + 'label' => qa_lang_html('users/wall_posts'), + 'tags' => 'name="wall"', + 'type' => 'checkbox', + 'value' => !($useraccount['flags'] & QA_USER_FLAGS_NO_WALL_POSTS), + 'note' => qa_lang_html('users/wall_posts_explanation'), + ), + + 'mailings' => array( + 'label' => qa_lang_html('users/mass_mailings'), + 'tags' => 'name="mailings"', + 'type' => 'checkbox', + 'value' => !($useraccount['flags'] & QA_USER_FLAGS_NO_MAILINGS), + 'note' => qa_lang_html('users/mass_mailings_explanation'), + ), + + 'avatar' => null, // for positioning + ), + + 'buttons' => array( + 'save' => array( + 'tags' => 'onclick="qa_show_waiting_after(this, false);"', + 'label' => qa_lang_html('users/save_profile'), + ), + ), + + 'hidden' => array( + 'dosaveprofile' => '1', + 'code' => qa_get_form_security_code('account'), + ), + ); + + if (qa_get_state()=='profile-saved') + $qa_content['form_profile']['ok']=qa_lang_html('users/profile_saved'); + + if (!qa_opt('allow_private_messages')) + unset($qa_content['form_profile']['fields']['messages']); + + if (!qa_opt('allow_user_walls')) + unset($qa_content['form_profile']['fields']['wall']); + + if (!qa_opt('mailing_enabled')) + unset($qa_content['form_profile']['fields']['mailings']); + + if ($isblocked) { + unset($qa_content['form_profile']['buttons']['save']); + $qa_content['error']=qa_lang_html('users/no_permission'); + } + +// Avatar upload stuff + + if (qa_opt('avatar_allow_gravatar') || qa_opt('avatar_allow_upload')) { + $avataroptions=array(); + + if (qa_opt('avatar_default_show') && strlen(qa_opt('avatar_default_blobid'))) { + $avataroptions['']=''. + qa_get_avatar_blob_html(qa_opt('avatar_default_blobid'), qa_opt('avatar_default_width'), qa_opt('avatar_default_height'), 32). + ' '.qa_lang_html('users/avatar_default'); + } else + $avataroptions['']=qa_lang_html('users/avatar_none'); + + $avatarvalue=$avataroptions['']; + + if (qa_opt('avatar_allow_gravatar')) { + $avataroptions['gravatar']=''. + qa_get_gravatar_html($useraccount['email'], 32).' '.strtr(qa_lang_html('users/avatar_gravatar'), array( + '^1' => '', + '^2' => '', + )).''; + + if ($useraccount['flags'] & QA_USER_FLAGS_SHOW_GRAVATAR) + $avatarvalue=$avataroptions['gravatar']; + } + + if (qa_has_gd_image() && qa_opt('avatar_allow_upload')) { + $avataroptions['uploaded']=''; + + if (isset($useraccount['avatarblobid'])) + $avataroptions['uploaded']=''. + qa_get_avatar_blob_html($useraccount['avatarblobid'], $useraccount['avatarwidth'], $useraccount['avatarheight'], 32). + ''.$avataroptions['uploaded']; + + if ($useraccount['flags'] & QA_USER_FLAGS_SHOW_AVATAR) + $avatarvalue=$avataroptions['uploaded']; + } + + $qa_content['form_profile']['fields']['avatar']=array( + 'type' => 'select-radio', + 'label' => qa_lang_html('users/avatar_label'), + 'tags' => 'name="avatar"', + 'options' => $avataroptions, + 'value' => $avatarvalue, + 'error' => qa_html(@$errors['avatar']), + ); + + } else + unset($qa_content['form_profile']['fields']['avatar']); + + +// Other profile fields + + foreach ($userfields as $userfield) { + $value=@$inprofile[$userfield['fieldid']]; + if (!isset($value)) + $value=@$userprofile[$userfield['title']]; + + $label=trim(qa_user_userfield_label($userfield), ':'); + if (strlen($label)) + $label.=':'; + + $qa_content['form_profile']['fields'][$userfield['title']]=array( + 'label' => qa_html($label), + 'tags' => 'name="field_'.$userfield['fieldid'].'"', + 'value' => qa_html($value), + 'error' => qa_html(@$errors[$userfield['fieldid']]), + 'rows' => ($userfield['flags'] & QA_FIELD_FLAGS_MULTI_LINE) ? 8 : null, + 'type' => $isblocked ? 'static' : 'text', + ); + } + + +// Raw information for plugin layers to access + + $qa_content['raw']['account']=$useraccount; + $qa_content['raw']['profile']=$userprofile; + $qa_content['raw']['points']=$userpoints; + + +// Change password form + + $qa_content['form_password']=array( + 'tags' => 'method="post" action="'.qa_self_html().'"', + + 'style' => 'wide', + + 'title' => qa_lang_html('users/change_password'), + + 'fields' => array( + 'old' => array( + 'label' => qa_lang_html('users/old_password'), + 'tags' => 'name="oldpassword"', + 'value' => qa_html(@$inoldpassword), + 'type' => 'password', + 'error' => qa_html(@$errors['oldpassword']), + ), + + 'new_1' => array( + 'label' => qa_lang_html('users/new_password_1'), + 'tags' => 'name="newpassword1"', + 'type' => 'password', + 'error' => qa_html(@$errors['password']), + ), + + 'new_2' => array( + 'label' => qa_lang_html('users/new_password_2'), + 'tags' => 'name="newpassword2"', + 'type' => 'password', + 'error' => qa_html(@$errors['newpassword2']), + ), + ), + + 'buttons' => array( + 'change' => array( + 'label' => qa_lang_html('users/change_password'), + ), + ), + + 'hidden' => array( + 'dochangepassword' => '1', + 'code' => qa_get_form_security_code('password'), + ), + ); + + if (!$haspassword) { + $qa_content['form_password']['fields']['old']['type']='static'; + $qa_content['form_password']['fields']['old']['value']=qa_lang_html('users/password_none'); + } + + if (qa_get_state()=='password-changed') + $qa_content['form_profile']['ok']=qa_lang_html('users/password_changed'); + + + $qa_content['navigation']['sub']=qa_user_sub_navigation($useraccount['handle'], 'account', true); + + + return $qa_content; + + +/* + Omit PHP closing tag to help avoid accidental output +*/ diff --git a/pages/activity.php b/pages/activity.php new file mode 100644 index 0000000..c107cf5 --- /dev/null +++ b/pages/activity.php @@ -0,0 +1,85 @@ + array( + 'tags' => 'method="post" action="'.qa_self_html().'"', + + 'hidden' => array( + 'code' => qa_get_form_security_code('admin/click'), + ), + ), + + 'messages' => array(), + ); + + + if (count($users)) { + foreach ($users as $user) { + $message=array(); + + $message['tags']='id="p'.qa_html($user['userid']).'"'; // use p prefix for qa_admin_click() in qa-admin.js + + $message['content']=qa_lang_html('users/registered_label').' '. + strtr(qa_lang_html('users/x_ago_from_y'), array( + '^1' => qa_time_to_string(qa_opt('db_time')-$user['created']), + '^2' => qa_ip_anchor_html($user['createip']), + )).'
'; + + $htmlemail=qa_html($user['email']); + + $message['content'].=qa_lang_html('users/email_label').' '.$htmlemail.''; + + if (qa_opt('confirm_user_emails')) + $message['content'].=' - '.qa_lang_html(($user['flags'] & QA_USER_FLAGS_EMAIL_CONFIRMED) ? 'users/email_confirmed' : 'users/email_not_confirmed').''; + + foreach ($userfields as $userfield) + if (strlen(@$user['profile'][$userfield['title']])) + $message['content'].='
'.qa_html($userfield['content'].': '.$user['profile'][$userfield['title']]); + + $message['meta_order']=qa_lang_html('main/meta_order'); + $message['who']['data']=qa_get_one_user_html($user['handle']); + + $message['form']=array( + 'style' => 'light', + + 'buttons' => array( + 'approve' => array( + 'tags' => 'name="admin_'.$user['userid'].'_userapprove" onclick="return qa_admin_click(this);"', + 'label' => qa_lang_html('question/approve_button'), + 'popup' => qa_lang_html('admin/approve_user_popup'), + ), + + 'block' => array( + 'tags' => 'name="admin_'.$user['userid'].'_userblock" onclick="return qa_admin_click(this);"', + 'label' => qa_lang_html('admin/block_button'), + 'popup' => qa_lang_html('admin/block_user_popup'), + ), + ), + ); + + $qa_content['message_list']['messages'][]=$message; + } + + } else + $qa_content['title']=qa_lang_html('admin/no_unapproved_found'); + + + $qa_content['navigation']['sub']=qa_admin_sub_navigation(); + $qa_content['script_rel'][]='qa-content/qa-admin.js?'.QA_VERSION; + + + return $qa_content; + + +/* + Omit PHP closing tag to help avoid accidental output +*/ diff --git a/pages/admin/admin-categories.php b/pages/admin/admin-categories.php new file mode 100644 index 0000000..903cf4b --- /dev/null +++ b/pages/admin/admin-categories.php @@ -0,0 +1,621 @@ + $parentid); + + } else { + if (qa_clicked('doaddcategory')) + $editcategory=array(); + + elseif (qa_clicked('dosavecategory')) { + $parentid=qa_post_text('parent'); + $editcategory=array('parentid' => strlen($parentid) ? $parentid : null); + } + } + + $setmissing=qa_post_text('missing') || qa_get('missing'); + + $setparent=(!$setmissing) && (qa_post_text('setparent') || qa_get('setparent')) && isset($editcategory['categoryid']); + + $hassubcategory=false; + foreach ($categories as $category) + if (!strcmp($category['parentid'], $editcategoryid)) + $hassubcategory=true; + + +// Process saving options + + $savedoptions=false; + $securityexpired=false; + + if (qa_clicked('dosaveoptions')) { + if (!qa_check_form_security_code('admin/categories', qa_post_text('code'))) + $securityexpired=true; + + else { + qa_set_option('allow_no_category', (int)qa_post_text('option_allow_no_category')); + qa_set_option('allow_no_sub_category', (int)qa_post_text('option_allow_no_sub_category')); + $savedoptions=true; + } + } + + +// Process saving an old or new category + + if (qa_clicked('docancel')) { + if ($setmissing || $setparent) + qa_redirect(qa_request(), array('edit' => $editcategory['categoryid'])); + elseif (isset($editcategory['categoryid'])) + qa_redirect(qa_request()); + else + qa_redirect(qa_request(), array('edit' => @$editcategory['parentid'])); + + } elseif (qa_clicked('dosetmissing')) { + if (!qa_check_form_security_code('admin/categories', qa_post_text('code'))) + $securityexpired=true; + + else { + $inreassign=qa_get_category_field_value('reassign'); + qa_db_category_reassign($editcategory['categoryid'], $inreassign); + qa_redirect(qa_request(), array('recalc' => 1, 'edit' => $editcategory['categoryid'])); + } + + } elseif (qa_clicked('dosavecategory')) { + if (!qa_check_form_security_code('admin/categories', qa_post_text('code'))) + $securityexpired=true; + + elseif (qa_post_text('dodelete')) { + + if (!$hassubcategory) { + $inreassign=qa_get_category_field_value('reassign'); + qa_db_category_reassign($editcategory['categoryid'], $inreassign); + qa_db_category_delete($editcategory['categoryid']); + qa_redirect(qa_request(), array('recalc' => 1, 'edit' => $editcategory['parentid'])); + } + + } else { + require_once QA_INCLUDE_DIR.'util/string.php'; + + $inname=qa_post_text('name'); + $incontent=qa_post_text('content'); + $inparentid=$setparent ? qa_get_category_field_value('parent') : $editcategory['parentid']; + $inposition=qa_post_text('position'); + $errors=array(); + + // Check the parent ID + + $incategories=qa_db_select_with_pending(qa_db_category_nav_selectspec($inparentid, true)); + + // Verify the name is legitimate for that parent ID + + if (empty($inname)) + $errors['name']=qa_lang('main/field_required'); + elseif (qa_strlen($inname)>QA_DB_MAX_CAT_PAGE_TITLE_LENGTH) + $errors['name']=qa_lang_sub('main/max_length_x', QA_DB_MAX_CAT_PAGE_TITLE_LENGTH); + else { + foreach ($incategories as $category) + if ( + (!strcmp($category['parentid'], $inparentid)) && + strcmp($category['categoryid'], @$editcategory['categoryid']) && + qa_strtolower($category['title']) == qa_strtolower($inname) + ) + $errors['name']=qa_lang('admin/category_already_used'); + } + + // Verify the slug is legitimate for that parent ID + + for ($attempt=0; $attempt<100; $attempt++) { + switch ($attempt) { + case 0: + $inslug=qa_post_text('slug'); + if (!isset($inslug)) + $inslug=implode('-', qa_string_to_words($inname)); + break; + + case 1: + $inslug=qa_lang_sub('admin/category_default_slug', $inslug); + break; + + default: + $inslug=qa_lang_sub('admin/category_default_slug', $attempt-1); + break; + } + + $matchcategoryid=qa_db_category_slug_to_id($inparentid, $inslug); // query against DB since MySQL ignores accents, etc... + + if (!isset($inparentid)) + $matchpage=qa_db_single_select(qa_db_page_full_selectspec($inslug, false)); + else + $matchpage=null; + + if (empty($inslug)) + $errors['slug']=qa_lang('main/field_required'); + elseif (qa_strlen($inslug)>QA_DB_MAX_CAT_PAGE_TAGS_LENGTH) + $errors['slug']=qa_lang_sub('main/max_length_x', QA_DB_MAX_CAT_PAGE_TAGS_LENGTH); + elseif (preg_match('/[\\+\\/]/', $inslug)) + $errors['slug']=qa_lang_sub('admin/slug_bad_chars', '+ /'); + elseif ( (!isset($inparentid)) && qa_admin_is_slug_reserved($inslug)) // only top level is a problem + $errors['slug']=qa_lang('admin/slug_reserved'); + elseif (isset($matchcategoryid) && strcmp($matchcategoryid, @$editcategory['categoryid'])) + $errors['slug']=qa_lang('admin/category_already_used'); + elseif (isset($matchpage)) + $errors['slug']=qa_lang('admin/page_already_used'); + else + unset($errors['slug']); + + if (isset($editcategory['categoryid']) || !isset($errors['slug'])) // don't try other options if editing existing category + break; + } + + // Perform appropriate database action + + if (empty($errors)) { + if (isset($editcategory['categoryid'])) { // changing existing category + qa_db_category_rename($editcategory['categoryid'], $inname, $inslug); + + $recalc=false; + + if ($setparent) { + qa_db_category_set_parent($editcategory['categoryid'], $inparentid); + $recalc=true; + } else { + qa_db_category_set_content($editcategory['categoryid'], $incontent); + qa_db_category_set_position($editcategory['categoryid'], $inposition); + $recalc=($hassubcategory && ($inslug !== $editcategory['tags'])); + } + + qa_redirect(qa_request(), array('edit' => $editcategory['categoryid'], 'saved' => true, 'recalc' => (int)$recalc)); + + } else { // creating a new one + $categoryid=qa_db_category_create($inparentid, $inname, $inslug); + + qa_db_category_set_content($categoryid, $incontent); + + if (isset($inposition)) + qa_db_category_set_position($categoryid, $inposition); + + qa_redirect(qa_request(), array('edit' => $inparentid, 'added' => true)); + } + } + } + } + + +// Prepare content for theme + + $qa_content=qa_content_prepare(); + + $qa_content['title']=qa_lang_html('admin/admin_title').' - '.qa_lang_html('admin/categories_title'); + $qa_content['error']=$securityexpired ? qa_lang_html('admin/form_security_expired') : qa_admin_page_error(); + + if ($setmissing) { + $qa_content['form']=array( + 'tags' => 'method="post" action="'.qa_path_html(qa_request()).'"', + + 'style' => 'tall', + + 'fields' => array( + 'reassign' => array( + 'label' => isset($editcategory) + ? qa_lang_html_sub('admin/category_no_sub_to', qa_html($editcategory['title'])) + : qa_lang_html('admin/category_none_to'), + 'loose' => true, + ), + ), + + 'buttons' => array( + 'save' => array( + 'tags' => 'id="dosaveoptions"', // just used for qa_recalc_click() + 'label' => qa_lang_html('main/save_button'), + ), + + 'cancel' => array( + 'tags' => 'name="docancel"', + 'label' => qa_lang_html('main/cancel_button'), + ), + ), + + 'hidden' => array( + 'dosetmissing' => '1', // for IE + 'edit' => @$editcategory['categoryid'], + 'missing' => '1', + 'code' => qa_get_form_security_code('admin/categories'), + ), + ); + + qa_set_up_category_field($qa_content, $qa_content['form']['fields']['reassign'], 'reassign', + $categories, @$editcategory['categoryid'], qa_opt('allow_no_category'), qa_opt('allow_no_sub_category')); + + + } elseif (isset($editcategory)) { + + $qa_content['form']=array( + 'tags' => 'method="post" action="'.qa_path_html(qa_request()).'"', + + 'style' => 'tall', + + 'ok' => qa_get('saved') ? qa_lang_html('admin/category_saved') : (qa_get('added') ? qa_lang_html('admin/category_added') : null), + + 'fields' => array( + 'name' => array( + 'id' => 'name_display', + 'tags' => 'name="name" id="name"', + 'label' => qa_lang_html(count($categories) ? 'admin/category_name' : 'admin/category_name_first'), + 'value' => qa_html(isset($inname) ? $inname : @$editcategory['title']), + 'error' => qa_html(@$errors['name']), + ), + + 'questions' => array(), + + 'delete' => array(), + + 'reassign' => array(), + + 'slug' => array( + 'id' => 'slug_display', + 'tags' => 'name="slug"', + 'label' => qa_lang_html('admin/category_slug'), + 'value' => qa_html(isset($inslug) ? $inslug : @$editcategory['tags']), + 'error' => qa_html(@$errors['slug']), + ), + + 'content' => array( + 'id' => 'content_display', + 'tags' => 'name="content"', + 'label' => qa_lang_html('admin/category_description'), + 'value' => qa_html(isset($incontent) ? $incontent : @$editcategory['content']), + 'error' => qa_html(@$errors['content']), + 'rows' => 2, + ), + ), + + 'buttons' => array( + 'save' => array( + 'tags' => 'id="dosaveoptions"', // just used for qa_recalc_click + 'label' => qa_lang_html(isset($editcategory['categoryid']) ? 'main/save_button' : 'admin/add_category_button'), + ), + + 'cancel' => array( + 'tags' => 'name="docancel"', + 'label' => qa_lang_html('main/cancel_button'), + ), + ), + + 'hidden' => array( + 'dosavecategory' => '1', // for IE + 'edit' => @$editcategory['categoryid'], + 'parent' => @$editcategory['parentid'], + 'setparent' => (int)$setparent, + 'code' => qa_get_form_security_code('admin/categories'), + ), + ); + + + if ($setparent) { + unset($qa_content['form']['fields']['delete']); + unset($qa_content['form']['fields']['reassign']); + unset($qa_content['form']['fields']['questions']); + unset($qa_content['form']['fields']['content']); + + $qa_content['form']['fields']['parent']=array( + 'label' => qa_lang_html('admin/category_parent'), + ); + + $childdepth=qa_db_category_child_depth($editcategory['categoryid']); + + qa_set_up_category_field($qa_content, $qa_content['form']['fields']['parent'], 'parent', + isset($incategories) ? $incategories : $categories, isset($inparentid) ? $inparentid : @$editcategory['parentid'], + true, true, QA_CATEGORY_DEPTH-1-$childdepth, @$editcategory['categoryid']); + + $qa_content['form']['fields']['parent']['options']['']=qa_lang_html('admin/category_top_level'); + + @$qa_content['form']['fields']['parent']['note'].=qa_lang_html_sub('admin/category_max_depth_x', QA_CATEGORY_DEPTH); + + } elseif (isset($editcategory['categoryid'])) { // existing category + if ($hassubcategory) { + $qa_content['form']['fields']['name']['note']=qa_lang_html('admin/category_no_delete_subs'); + unset($qa_content['form']['fields']['delete']); + unset($qa_content['form']['fields']['reassign']); + + } else { + $qa_content['form']['fields']['delete']=array( + 'tags' => 'name="dodelete" id="dodelete"', + 'label' => + ''.qa_lang_html('admin/delete_category_reassign').''. + '', + 'value' => 0, + 'type' => 'checkbox', + ); + + $qa_content['form']['fields']['reassign']=array( + 'id' => 'reassign_display', + 'tags' => 'name="reassign"', + ); + + qa_set_up_category_field($qa_content, $qa_content['form']['fields']['reassign'], 'reassign', + $categories, $editcategory['parentid'], true, true, null, $editcategory['categoryid']); + } + + $qa_content['form']['fields']['questions']=array( + 'label' => qa_lang_html('admin/total_qs'), + 'type' => 'static', + 'value' => ''. + ( ($editcategory['qcount']==1) + ? qa_lang_html_sub('main/1_question', '1', '1') + : qa_lang_html_sub('main/x_questions', number_format($editcategory['qcount'])) + ).'', + ); + + if ($hassubcategory && !qa_opt('allow_no_sub_category')) { + $nosubcount=qa_db_count_categoryid_qs($editcategory['categoryid']); + + if ($nosubcount) + $qa_content['form']['fields']['questions']['error']= + strtr(qa_lang_html('admin/category_no_sub_error'), array( + '^q' => number_format($nosubcount), + '^1' => '', + '^2' => '', + )); + } + + qa_set_display_rules($qa_content, array( + 'position_display' => '!dodelete', + 'slug_display' => '!dodelete', + 'content_display' => '!dodelete', + 'parent_display' => '!dodelete', + 'children_display' => '!dodelete', + 'reassign_display' => 'dodelete', + 'reassign_shown' => 'dodelete', + 'reassign_hidden' => '!dodelete', + )); + + } else { // new category + unset($qa_content['form']['fields']['delete']); + unset($qa_content['form']['fields']['reassign']); + unset($qa_content['form']['fields']['slug']); + unset($qa_content['form']['fields']['questions']); + + $qa_content['focusid']='name'; + } + + if (!$setparent) { + $pathhtml=qa_category_path_html($categories, @$editcategory['parentid']); + + if (count($categories)) { + $qa_content['form']['fields']['parent']=array( + 'id' => 'parent_display', + 'label' => qa_lang_html('admin/category_parent'), + 'type' => 'static', + 'value' => (strlen($pathhtml) ? $pathhtml : qa_lang_html('admin/category_top_level')), + ); + + $qa_content['form']['fields']['parent']['value']= + ''. + $qa_content['form']['fields']['parent']['value'].''; + + if (isset($editcategory['categoryid'])) + $qa_content['form']['fields']['parent']['value'].=' - '. + ''.qa_lang_html('admin/category_move_parent').''; + } + + $positionoptions=array(); + + $previous=null; + $passedself=false; + + foreach ($categories as $key => $category) + if (!strcmp($category['parentid'], @$editcategory['parentid'])) { + if (isset($previous)) + $positionhtml=qa_lang_html_sub('admin/after_x', qa_html($passedself ? $category['title'] : $previous['title'])); + else + $positionhtml=qa_lang_html('admin/first'); + + $positionoptions[$category['position']]=$positionhtml; + + if (!strcmp($category['categoryid'], @$editcategory['categoryid'])) + $passedself=true; + + $previous=$category; + } + + if (isset($editcategory['position'])) + $positionvalue=$positionoptions[$editcategory['position']]; + + else { + $positionvalue=isset($previous) ? qa_lang_html_sub('admin/after_x', qa_html($previous['title'])) : qa_lang_html('admin/first'); + $positionoptions[1+@max(array_keys($positionoptions))]=$positionvalue; + } + + $qa_content['form']['fields']['position']=array( + 'id' => 'position_display', + 'tags' => 'name="position"', + 'label' => qa_lang_html('admin/position'), + 'type' => 'select', + 'options' => $positionoptions, + 'value' => $positionvalue, + ); + + if (isset($editcategory['categoryid'])) { + $catdepth=count(qa_category_path($categories, $editcategory['categoryid'])); + + if ($catdepth'.qa_html($category['title']).''. + ' ('.$category['qcount'].')'; + + if (!strlen($childrenhtml)) + $childrenhtml=qa_lang_html('admin/category_no_subs'); + + $childrenhtml.=' - '.qa_lang_html('admin/category_add_sub').''; + + $qa_content['form']['fields']['children']=array( + 'id' => 'children_display', + 'label' => qa_lang_html('admin/category_subs'), + 'type' => 'static', + 'value' => $childrenhtml, + ); + } else { + $qa_content['form']['fields']['name']['note']=qa_lang_html_sub('admin/category_no_add_subs_x', QA_CATEGORY_DEPTH); + } + + } + } + + } else { + $qa_content['form']=array( + 'tags' => 'method="post" action="'.qa_path_html(qa_request()).'"', + + 'ok' => $savedoptions ? qa_lang_html('admin/options_saved') : null, + + 'style' => 'tall', + + 'fields' => array( + 'intro' => array( + 'label' => qa_lang_html('admin/categories_introduction'), + 'type' => 'static', + ), + ), + + 'buttons' => array( + 'save' => array( + 'tags' => 'name="dosaveoptions" id="dosaveoptions"', + 'label' => qa_lang_html('main/save_button'), + ), + + 'add' => array( + 'tags' => 'name="doaddcategory"', + 'label' => qa_lang_html('admin/add_category_button'), + ), + ), + + 'hidden' => array( + 'code' => qa_get_form_security_code('admin/categories'), + ), + ); + + if (count($categories)) { + unset($qa_content['form']['fields']['intro']); + + $navcategoryhtml=''; + + foreach ($categories as $category) + if (!isset($category['parentid'])) + $navcategoryhtml.=''. + qa_html($category['title']).' - '.qa_lang_html_sub('main/x_questions', $category['qcount']).'
'; + + $qa_content['form']['fields']['nav']=array( + 'label' => qa_lang_html('admin/top_level_categories'), + 'type' => 'static', + 'value' => $navcategoryhtml, + ); + + $qa_content['form']['fields']['allow_no_category']=array( + 'label' => qa_lang_html('options/allow_no_category'), + 'tags' => 'name="option_allow_no_category"', + 'type' => 'checkbox', + 'value' => qa_opt('allow_no_category'), + ); + + if (!qa_opt('allow_no_category')) { + $nocatcount=qa_db_count_categoryid_qs(null); + + if ($nocatcount) + $qa_content['form']['fields']['allow_no_category']['error']= + strtr(qa_lang_html('admin/category_none_error'), array( + '^q' => number_format($nocatcount), + '^1' => '', + '^2' => '', + )); + } + + $qa_content['form']['fields']['allow_no_sub_category']=array( + 'label' => qa_lang_html('options/allow_no_sub_category'), + 'tags' => 'name="option_allow_no_sub_category"', + 'type' => 'checkbox', + 'value' => qa_opt('allow_no_sub_category'), + ); + + } else + unset($qa_content['form']['buttons']['save']); + } + + if (qa_get('recalc')) { + $qa_content['form']['ok']=''.qa_lang_html('admin/recalc_categories').''; + $qa_content['form']['hidden']['code_recalc']=qa_get_form_security_code('admin/recalc'); + + $qa_content['script_rel'][]='qa-content/qa-admin.js?'.QA_VERSION; + $qa_content['script_var']['qa_warning_recalc']=qa_lang('admin/stop_recalc_warning'); + + $qa_content['script_onloads'][]=array( + "qa_recalc_click('dorecalccategories', document.getElementById('dosaveoptions'), null, 'recalc_ok');" + ); + } + + $qa_content['navigation']['sub']=qa_admin_sub_navigation(); + + + return $qa_content; + + +/* + Omit PHP closing tag to help avoid accidental output +*/ \ No newline at end of file diff --git a/pages/admin/admin-default.php b/pages/admin/admin-default.php new file mode 100644 index 0000000..03a37fb --- /dev/null +++ b/pages/admin/admin-default.php @@ -0,0 +1,1755 @@ + 'number', + 'avatar_profile_size' => 'number', + 'avatar_q_list_size' => 'number', + 'avatar_q_page_a_size' => 'number', + 'avatar_q_page_c_size' => 'number', + 'avatar_q_page_q_size' => 'number', + 'avatar_store_size' => 'number', + 'avatar_users_size' => 'number', + 'columns_tags' => 'number', + 'columns_users' => 'number', + 'feed_number_items' => 'number', + 'flagging_hide_after' => 'number', + 'flagging_notify_every' => 'number', + 'flagging_notify_first' => 'number', + 'hot_weight_a_age' => 'number', + 'hot_weight_answers' => 'number', + 'hot_weight_q_age' => 'number', + 'hot_weight_views' => 'number', + 'hot_weight_votes' => 'number', + 'logo_height' => 'number-blank', + 'logo_width' => 'number-blank', + 'mailing_per_minute' => 'number', + 'max_len_q_title' => 'number', + 'max_num_q_tags' => 'number', + 'max_rate_ip_as' => 'number', + 'max_rate_ip_cs' => 'number', + 'max_rate_ip_flags' => 'number', + 'max_rate_ip_logins' => 'number', + 'max_rate_ip_messages' => 'number', + 'max_rate_ip_qs' => 'number', + 'max_rate_ip_registers' => 'number', + 'max_rate_ip_uploads' => 'number', + 'max_rate_ip_votes' => 'number', + 'max_rate_user_as' => 'number', + 'max_rate_user_cs' => 'number', + 'max_rate_user_flags' => 'number', + 'max_rate_user_messages' => 'number', + 'max_rate_user_qs' => 'number', + 'max_rate_user_uploads' => 'number', + 'max_rate_user_votes' => 'number', + 'min_len_a_content' => 'number', + 'min_len_c_content' => 'number', + 'min_len_q_content' => 'number', + 'min_len_q_title' => 'number', + 'min_num_q_tags' => 'number', + 'moderate_points_limit' => 'number', + 'page_size_activity' => 'number', + 'page_size_ask_check_qs' => 'number', + 'page_size_ask_tags' => 'number', + 'page_size_home' => 'number', + 'page_size_hot_qs' => 'number', + 'page_size_pms' => 'number', + 'page_size_q_as' => 'number', + 'page_size_qs' => 'number', + 'page_size_related_qs' => 'number', + 'page_size_search' => 'number', + 'page_size_tag_qs' => 'number', + 'page_size_tags' => 'number', + 'page_size_una_qs' => 'number', + 'page_size_users' => 'number', + 'page_size_wall' => 'number', + 'pages_prev_next' => 'number', + 'q_urls_title_length' => 'number', + 'show_fewer_cs_count' => 'number', + 'show_fewer_cs_from' => 'number', + 'show_full_date_days' => 'number', + 'smtp_port' => 'number', + + 'allow_change_usernames' => 'checkbox', + 'allow_close_questions' => 'checkbox', + 'allow_login_email_only' => 'checkbox', + 'allow_multi_answers' => 'checkbox', + 'allow_private_messages' => 'checkbox', + 'allow_user_walls' => 'checkbox', + 'allow_self_answer' => 'checkbox', + 'allow_view_q_bots' => 'checkbox', + 'approve_user_required' => 'checkbox', + 'avatar_allow_gravatar' => 'checkbox', + 'avatar_allow_upload' => 'checkbox', + 'avatar_default_show' => 'checkbox', + 'captcha_on_anon_post' => 'checkbox', + 'captcha_on_feedback' => 'checkbox', + 'captcha_on_register' => 'checkbox', + 'captcha_on_reset_password' => 'checkbox', + 'captcha_on_unapproved' => 'checkbox', + 'captcha_on_unconfirmed' => 'checkbox', + 'comment_on_as' => 'checkbox', + 'comment_on_qs' => 'checkbox', + 'confirm_user_emails' => 'checkbox', + 'confirm_user_required' => 'checkbox', + 'do_ask_check_qs' => 'checkbox', + 'do_close_on_select' => 'checkbox', + 'do_complete_tags' => 'checkbox', + 'do_count_q_views' => 'checkbox', + 'do_example_tags' => 'checkbox', + 'extra_field_active' => 'checkbox', + 'extra_field_display' => 'checkbox', + 'feed_for_activity' => 'checkbox', + 'feed_for_hot' => 'checkbox', + 'feed_for_qa' => 'checkbox', + 'feed_for_questions' => 'checkbox', + 'feed_for_search' => 'checkbox', + 'feed_for_tag_qs' => 'checkbox', + 'feed_for_unanswered' => 'checkbox', + 'feed_full_text' => 'checkbox', + 'feed_per_category' => 'checkbox', + 'feedback_enabled' => 'checkbox', + 'flagging_of_posts' => 'checkbox', + 'follow_on_as' => 'checkbox', + 'links_in_new_window' => 'checkbox', + 'logo_show' => 'checkbox', + 'mailing_enabled' => 'checkbox', + 'moderate_anon_post' => 'checkbox', + 'moderate_by_points' => 'checkbox', + 'moderate_edited_again' => 'checkbox', + 'moderate_notify_admin' => 'checkbox', + 'moderate_unapproved' => 'checkbox', + 'moderate_unconfirmed' => 'checkbox', + 'moderate_users' => 'checkbox', + 'neat_urls' => 'checkbox', + 'notify_admin_q_post' => 'checkbox', + 'notify_users_default' => 'checkbox', + 'q_urls_remove_accents' => 'checkbox', + 'register_notify_admin' => 'checkbox', + 'show_c_reply_buttons' => 'checkbox', + 'show_custom_answer' => 'checkbox', + 'show_custom_ask' => 'checkbox', + 'show_custom_comment' => 'checkbox', + 'show_custom_footer' => 'checkbox', + 'show_custom_header' => 'checkbox', + 'show_custom_home' => 'checkbox', + 'show_custom_in_head' => 'checkbox', + 'show_custom_register' => 'checkbox', + 'show_custom_sidebar' => 'checkbox', + 'show_custom_sidepanel' => 'checkbox', + 'show_custom_welcome' => 'checkbox', + 'show_post_update_meta' => 'checkbox', + 'show_home_description' => 'checkbox', + 'show_message_history' => 'checkbox', + 'show_notice_visitor' => 'checkbox', + 'show_notice_welcome' => 'checkbox', + 'show_register_terms' => 'checkbox', + 'show_selected_first' => 'checkbox', + 'show_url_links' => 'checkbox', + 'show_user_points' => 'checkbox', + 'show_user_titles' => 'checkbox', + 'show_view_counts' => 'checkbox', + 'show_view_count_q_page' => 'checkbox', + 'show_when_created' => 'checkbox', + 'site_maintenance' => 'checkbox', + 'smtp_active' => 'checkbox', + 'smtp_authenticate' => 'checkbox', + 'suspend_register_users' => 'checkbox', + 'tag_separator_comma' => 'checkbox', + 'votes_separated' => 'checkbox', + 'voting_on_as' => 'checkbox', + 'voting_on_q_page_only' => 'checkbox', + 'voting_on_qs' => 'checkbox', + + 'smtp_password' => 'password', + ); + + $optionmaximum = array( + 'feed_number_items' => QA_DB_RETRIEVE_QS_AS, + 'max_len_q_title' => QA_DB_MAX_TITLE_LENGTH, + 'page_size_activity' => QA_DB_RETRIEVE_QS_AS, + 'page_size_ask_check_qs' => QA_DB_RETRIEVE_QS_AS, + 'page_size_ask_tags' => QA_DB_RETRIEVE_QS_AS, + 'page_size_home' => QA_DB_RETRIEVE_QS_AS, + 'page_size_hot_qs' => QA_DB_RETRIEVE_QS_AS, + 'page_size_pms' => QA_DB_RETRIEVE_MESSAGES, + 'page_size_qs' => QA_DB_RETRIEVE_QS_AS, + 'page_size_related_qs' => QA_DB_RETRIEVE_QS_AS, + 'page_size_search' => QA_DB_RETRIEVE_QS_AS, + 'page_size_tag_qs' => QA_DB_RETRIEVE_QS_AS, + 'page_size_tags' => QA_DB_RETRIEVE_TAGS, + 'page_size_una_qs' => QA_DB_RETRIEVE_QS_AS, + 'page_size_users' => QA_DB_RETRIEVE_USERS, + 'page_size_wall' => QA_DB_RETRIEVE_MESSAGES, + ); + + $optionminimum = array( + 'flagging_hide_after' => 2, + 'flagging_notify_every' => 1, + 'flagging_notify_first' => 1, + 'max_num_q_tags' => 2, + 'max_rate_ip_logins' => 1, + 'page_size_activity' => 1, + 'page_size_ask_check_qs' => 3, + 'page_size_ask_tags' => 3, + 'page_size_home' => 1, + 'page_size_hot_qs' => 1, + 'page_size_pms' => 1, + 'page_size_q_as' => 1, + 'page_size_qs' => 1, + 'page_size_search' => 1, + 'page_size_tag_qs' => 1, + 'page_size_tags' => 1, + 'page_size_users' => 1, + 'page_size_wall' => 1, + ); + + +// Define the options to show (and some other visual stuff) based on request + + $formstyle = 'tall'; + $checkboxtodisplay = null; + + $maxpermitpost = max(qa_opt('permit_post_q'), qa_opt('permit_post_a')); + if (qa_opt('comment_on_qs') || qa_opt('comment_on_as')) + $maxpermitpost = max($maxpermitpost, qa_opt('permit_post_c')); + + switch ($adminsection) { + case 'general': + $subtitle = 'admin/general_title'; + $showoptions = array('site_title', 'site_url', 'neat_urls', 'site_language', 'site_theme', 'site_theme_mobile', 'site_text_direction', 'tags_or_categories', 'site_maintenance'); + break; + + case 'emails': + $subtitle = 'admin/emails_title'; + $showoptions = array( + 'from_email', 'feedback_email', 'notify_admin_q_post', 'feedback_enabled', 'email_privacy', + 'smtp_active', 'smtp_address', 'smtp_port', 'smtp_secure', 'smtp_authenticate', 'smtp_username', 'smtp_password' + ); + + $checkboxtodisplay = array( + 'smtp_address' => 'option_smtp_active', + 'smtp_port' => 'option_smtp_active', + 'smtp_secure' => 'option_smtp_active', + 'smtp_authenticate' => 'option_smtp_active', + 'smtp_username' => 'option_smtp_active && option_smtp_authenticate', + 'smtp_password' => 'option_smtp_active && option_smtp_authenticate', + ); + break; + + case 'users': + $subtitle = 'admin/users_title'; + + $showoptions = array('show_notice_visitor', 'notice_visitor'); + + if (!QA_FINAL_EXTERNAL_USERS) { + require_once QA_INCLUDE_DIR.'util/image.php'; + + array_push($showoptions, 'show_custom_register', 'custom_register', 'show_register_terms', 'register_terms', 'show_notice_welcome', 'notice_welcome', 'show_custom_welcome', 'custom_welcome'); + + array_push($showoptions, '', 'allow_login_email_only', 'allow_change_usernames', 'allow_private_messages', 'show_message_history', 'page_size_pms', 'allow_user_walls', 'page_size_wall', '', 'avatar_allow_gravatar'); + + if (qa_has_gd_image()) + array_push($showoptions, 'avatar_allow_upload', 'avatar_store_size', 'avatar_default_show'); + } + + $showoptions[] = ''; + + if (!QA_FINAL_EXTERNAL_USERS) + $showoptions[] = 'avatar_profile_size'; + + array_push($showoptions, 'avatar_users_size', 'avatar_q_page_q_size', 'avatar_q_page_a_size', 'avatar_q_page_c_size', + 'avatar_q_list_size', 'avatar_message_list_size'); + + $checkboxtodisplay = array( + 'custom_register' => 'option_show_custom_register', + 'register_terms' => 'option_show_register_terms', + 'custom_welcome' => 'option_show_custom_welcome', + 'notice_welcome' => 'option_show_notice_welcome', + 'notice_visitor' => 'option_show_notice_visitor', + 'show_message_history' => 'option_allow_private_messages', + 'avatar_store_size' => 'option_avatar_allow_upload', + 'avatar_default_show' => 'option_avatar_allow_gravatar || option_avatar_allow_upload', + ); + + if (!QA_FINAL_EXTERNAL_USERS) + $checkboxtodisplay = array_merge($checkboxtodisplay, array( + 'page_size_pms' => 'option_allow_private_messages && option_show_message_history', + 'page_size_wall' => 'option_allow_user_walls', + 'avatar_profile_size' => 'option_avatar_allow_gravatar || option_avatar_allow_upload', + 'avatar_users_size' => 'option_avatar_allow_gravatar || option_avatar_allow_upload', + 'avatar_q_page_q_size' => 'option_avatar_allow_gravatar || option_avatar_allow_upload', + 'avatar_q_page_a_size' => 'option_avatar_allow_gravatar || option_avatar_allow_upload', + 'avatar_q_page_c_size' => 'option_avatar_allow_gravatar || option_avatar_allow_upload', + 'avatar_q_list_size' => 'option_avatar_allow_gravatar || option_avatar_allow_upload', + 'avatar_message_list_size' => 'option_allow_private_messages || option_allow_user_walls', + )); + + $formstyle = 'wide'; + break; + + case 'layout': + $subtitle = 'admin/layout_title'; + $showoptions = array('logo_show', 'logo_url', 'logo_width', 'logo_height', '', 'show_custom_sidebar', 'custom_sidebar', 'show_custom_sidepanel', 'custom_sidepanel', 'show_custom_header', 'custom_header', 'show_custom_footer', 'custom_footer', 'show_custom_in_head', 'custom_in_head', 'show_custom_home', 'custom_home_heading', 'custom_home_content', 'show_home_description', 'home_description', ''); + + $checkboxtodisplay = array( + 'logo_url' => 'option_logo_show', + 'logo_width' => 'option_logo_show', + 'logo_height' => 'option_logo_show', + 'custom_sidebar' => 'option_show_custom_sidebar', + 'custom_sidepanel' => 'option_show_custom_sidepanel', + 'custom_header' => 'option_show_custom_header', + 'custom_footer' => 'option_show_custom_footer', + 'custom_in_head' => 'option_show_custom_in_head', + 'custom_home_heading' => 'option_show_custom_home', + 'custom_home_content' => 'option_show_custom_home', + 'home_description' => 'option_show_home_description', + ); + break; + + case 'viewing': + $subtitle = 'admin/viewing_title'; + $showoptions = array('q_urls_title_length', 'q_urls_remove_accents', 'do_count_q_views', 'show_view_counts', 'show_view_count_q_page', '', 'voting_on_qs', 'voting_on_q_page_only', 'voting_on_as', 'votes_separated', '', 'show_url_links', 'links_in_new_window', 'show_when_created', 'show_full_date_days'); + + if (count(qa_get_points_to_titles())) + $showoptions[] = 'show_user_titles'; + + array_push($showoptions, 'show_user_points', 'show_post_update_meta', '', 'sort_answers_by', 'show_selected_first', 'page_size_q_as', 'show_a_form_immediate'); + + if (qa_opt('comment_on_qs') || qa_opt('comment_on_as')) + array_push($showoptions, 'show_fewer_cs_from', 'show_fewer_cs_count', 'show_c_reply_buttons'); + + $showoptions[] = ''; + + $widgets = qa_db_single_select(qa_db_widgets_selectspec()); + + foreach ($widgets as $widget) + if ($widget['title'] == 'Related Questions') { + array_push($showoptions, 'match_related_qs', 'page_size_related_qs', ''); + break; + } + + $showoptions[] = 'pages_prev_next'; + + $formstyle = 'wide'; + + $checkboxtodisplay = array( + 'show_view_counts' => 'option_do_count_q_views', + 'show_view_count_q_page' => 'option_do_count_q_views', + 'votes_separated' => 'option_voting_on_qs || option_voting_on_as', + 'voting_on_q_page_only' => 'option_voting_on_qs', + 'show_full_date_days' => 'option_show_when_created', + ); + break; + + case 'lists': + $subtitle = 'admin/lists_title'; + + $showoptions = array('page_size_home', 'page_size_activity', 'page_size_qs', 'page_size_hot_qs', 'page_size_una_qs'); + + if (qa_using_tags()) + $showoptions[] = 'page_size_tag_qs'; + + $showoptions[] = ''; + + if (qa_using_tags()) + array_push($showoptions, 'page_size_tags', 'columns_tags'); + + array_push($showoptions, 'page_size_users', 'columns_users', ''); + + $searchmodules = qa_load_modules_with('search', 'process_search'); + + if (count($searchmodules)) + $showoptions[] = 'search_module'; + + $showoptions[] = 'page_size_search'; + + array_push($showoptions, '', 'admin/hotness_factors', 'hot_weight_q_age', 'hot_weight_a_age', 'hot_weight_answers', 'hot_weight_votes'); + + if (qa_opt('do_count_q_views')) + $showoptions[] = 'hot_weight_views'; + + $formstyle = 'wide'; + + break; + + case 'posting': + $getoptions = qa_get_options(array('tags_or_categories')); + + $subtitle = 'admin/posting_title'; + + $showoptions = array('do_close_on_select', 'allow_close_questions', 'allow_self_answer', 'allow_multi_answers', 'follow_on_as', 'comment_on_qs', 'comment_on_as', ''); + + if (count(qa_list_modules('editor'))>1) + array_push($showoptions, 'editor_for_qs', 'editor_for_as', 'editor_for_cs', ''); + + array_push($showoptions, 'show_custom_ask', 'custom_ask', 'extra_field_active', 'extra_field_prompt', 'extra_field_display', 'extra_field_label', 'show_custom_answer', 'custom_answer', 'show_custom_comment', 'custom_comment', ''); + + array_push($showoptions, 'min_len_q_title', 'max_len_q_title', 'min_len_q_content'); + + if (qa_using_tags()) + array_push($showoptions, 'min_num_q_tags', 'max_num_q_tags', 'tag_separator_comma'); + + array_push($showoptions, 'min_len_a_content', 'min_len_c_content', 'notify_users_default'); + + array_push($showoptions, '', 'block_bad_words', '', 'do_ask_check_qs', 'match_ask_check_qs', 'page_size_ask_check_qs', ''); + + if (qa_using_tags()) + array_push($showoptions, 'do_example_tags', 'match_example_tags', 'do_complete_tags', 'page_size_ask_tags'); + + $formstyle = 'wide'; + + $checkboxtodisplay = array( + 'editor_for_cs' => 'option_comment_on_qs || option_comment_on_as', + 'custom_ask' => 'option_show_custom_ask', + 'extra_field_prompt' => 'option_extra_field_active', + 'extra_field_display' => 'option_extra_field_active', + 'extra_field_label' => 'option_extra_field_active && option_extra_field_display', + 'extra_field_label_hidden' => '!option_extra_field_display', + 'extra_field_label_shown' => 'option_extra_field_display', + 'custom_answer' => 'option_show_custom_answer', + 'show_custom_comment' => 'option_comment_on_qs || option_comment_on_as', + 'custom_comment' => 'option_show_custom_comment && (option_comment_on_qs || option_comment_on_as)', + 'min_len_c_content' => 'option_comment_on_qs || option_comment_on_as', + 'match_ask_check_qs' => 'option_do_ask_check_qs', + 'page_size_ask_check_qs' => 'option_do_ask_check_qs', + 'match_example_tags' => 'option_do_example_tags', + 'page_size_ask_tags' => 'option_do_example_tags || option_do_complete_tags', + ); + break; + + case 'permissions': + $subtitle = 'admin/permissions_title'; + + $permitoptions = qa_get_permit_options(); + + $showoptions = array(); + $checkboxtodisplay = array(); + + foreach ($permitoptions as $permitoption) { + $showoptions[] = $permitoption; + + if ($permitoption == 'permit_view_q_page') { + $showoptions[] = 'allow_view_q_bots'; + $checkboxtodisplay['allow_view_q_bots'] = 'option_permit_view_q_page<'.qa_js(QA_PERMIT_ALL); + + } + else { + $showoptions[] = $permitoption.'_points'; + $checkboxtodisplay[$permitoption.'_points'] = '(option_'.$permitoption.'=='.qa_js(QA_PERMIT_POINTS). + ')||(option_'.$permitoption.'=='.qa_js(QA_PERMIT_POINTS_CONFIRMED).')||(option_'.$permitoption.'=='.qa_js(QA_PERMIT_APPROVED_POINTS).')'; + } + } + + $formstyle = 'wide'; + break; + + case 'feeds': + $subtitle = 'admin/feeds_title'; + + $showoptions = array('feed_for_questions', 'feed_for_qa', 'feed_for_activity'); + + array_push($showoptions, 'feed_for_hot', 'feed_for_unanswered'); + + if (qa_using_tags()) + $showoptions[] = 'feed_for_tag_qs'; + + if (qa_using_categories()) + $showoptions[] = 'feed_per_category'; + + array_push($showoptions, 'feed_for_search', '', 'feed_number_items', 'feed_full_text'); + + $formstyle = 'wide'; + + $checkboxtodisplay = array( + 'feed_per_category' => 'option_feed_for_qa || option_feed_for_questions || option_feed_for_unanswered || option_feed_for_activity', + ); + break; + + case 'spam': + $subtitle = 'admin/spam_title'; + + $showoptions = array(); + + $getoptions = qa_get_options(array('feedback_enabled', 'permit_post_q', 'permit_post_a', 'permit_post_c')); + + if (!QA_FINAL_EXTERNAL_USERS) + array_push($showoptions, 'confirm_user_emails', 'confirm_user_required', 'moderate_users', 'approve_user_required', 'register_notify_admin', 'suspend_register_users', ''); + + $captchamodules = qa_list_modules('captcha'); + + if (count($captchamodules)) { + if (!QA_FINAL_EXTERNAL_USERS) + array_push($showoptions, 'captcha_on_register', 'captcha_on_reset_password'); + + if ($maxpermitpost > QA_PERMIT_USERS) + $showoptions[] = 'captcha_on_anon_post'; + + if ($maxpermitpost > QA_PERMIT_APPROVED) + $showoptions[] = 'captcha_on_unapproved'; + + if ($maxpermitpost > QA_PERMIT_CONFIRMED) + $showoptions[] = 'captcha_on_unconfirmed'; + + if ($getoptions['feedback_enabled']) + $showoptions[] = 'captcha_on_feedback'; + + $showoptions[] = 'captcha_module'; + } + + $showoptions[] = ''; + + if ($maxpermitpost > QA_PERMIT_USERS) + $showoptions[] = 'moderate_anon_post'; + + if ($maxpermitpost > QA_PERMIT_APPROVED) + $showoptions[] = 'moderate_unapproved'; + + if ($maxpermitpost > QA_PERMIT_CONFIRMED) + $showoptions[] = 'moderate_unconfirmed'; + + if ($maxpermitpost > QA_PERMIT_EXPERTS) + array_push($showoptions, 'moderate_by_points', 'moderate_points_limit', 'moderate_edited_again', 'moderate_notify_admin', 'moderate_update_time', ''); + + array_push($showoptions, 'flagging_of_posts', 'flagging_notify_first', 'flagging_notify_every', 'flagging_hide_after', ''); + + array_push($showoptions, 'block_ips_write', ''); + + if (!QA_FINAL_EXTERNAL_USERS) + array_push($showoptions, 'max_rate_ip_registers', 'max_rate_ip_logins', ''); + + array_push($showoptions, 'max_rate_ip_qs', 'max_rate_user_qs', 'max_rate_ip_as', 'max_rate_user_as'); + + if (qa_opt('comment_on_qs') || qa_opt('comment_on_as')) + array_push($showoptions, 'max_rate_ip_cs', 'max_rate_user_cs'); + + $showoptions[] = ''; + + if (qa_opt('voting_on_qs') || qa_opt('voting_on_as')) + array_push($showoptions, 'max_rate_ip_votes', 'max_rate_user_votes'); + + array_push($showoptions, 'max_rate_ip_flags', 'max_rate_user_flags', 'max_rate_ip_uploads', 'max_rate_user_uploads'); + + if (qa_opt('allow_private_messages') || qa_opt('allow_user_walls')) + array_push($showoptions, 'max_rate_ip_messages', 'max_rate_user_messages'); + + $formstyle = 'wide'; + + $checkboxtodisplay = array( + 'confirm_user_required' => 'option_confirm_user_emails', + 'approve_user_required' => 'option_moderate_users', + 'captcha_on_unapproved' => 'option_moderate_users', + 'captcha_on_unconfirmed' => 'option_confirm_user_emails && !(option_moderate_users && option_captcha_on_unapproved)', + 'captcha_module' => 'option_captcha_on_register || option_captcha_on_anon_post || (option_confirm_user_emails && option_captcha_on_unconfirmed) || (option_moderate_users && option_captcha_on_unapproved) || option_captcha_on_reset_password || option_captcha_on_feedback', + 'moderate_unapproved' => 'option_moderate_users', + 'moderate_unconfirmed' => 'option_confirm_user_emails && !(option_moderate_users && option_moderate_unapproved)', + 'moderate_points_limit' => 'option_moderate_by_points', + 'moderate_points_label_off' => '!option_moderate_by_points', + 'moderate_points_label_on' => 'option_moderate_by_points', + 'moderate_edited_again' => 'option_moderate_anon_post || (option_confirm_user_emails && option_moderate_unconfirmed) || (option_moderate_users && option_moderate_unapproved) || option_moderate_by_points', + 'flagging_hide_after' => 'option_flagging_of_posts', + 'flagging_notify_every' => 'option_flagging_of_posts', + 'flagging_notify_first' => 'option_flagging_of_posts', + 'max_rate_ip_flags' => 'option_flagging_of_posts', + 'max_rate_user_flags' => 'option_flagging_of_posts', + ); + + $checkboxtodisplay['moderate_notify_admin'] = $checkboxtodisplay['moderate_edited_again']; + $checkboxtodisplay['moderate_update_time'] = $checkboxtodisplay['moderate_edited_again']; + break; + + case 'mailing': + require_once QA_INCLUDE_DIR.'app/mailing.php'; + + $subtitle = 'admin/mailing_title'; + + $showoptions = array('mailing_enabled', 'mailing_from_name', 'mailing_from_email', 'mailing_subject', 'mailing_body', 'mailing_per_minute'); + break; + + default: + $pagemodules = qa_load_modules_with('page', 'match_request'); + $request = qa_request(); + + foreach ($pagemodules as $pagemodule) + if ($pagemodule->match_request($request)) + return $pagemodule->process_request($request); + + return include QA_INCLUDE_DIR.'qa-page-not-found.php'; + break; + } + + +// Filter out blanks to get list of valid options + + $getoptions = array(); + foreach ($showoptions as $optionname) + if (strlen($optionname) && (strpos($optionname, '/') === false)) // empties represent spacers in forms + $getoptions[] = $optionname; + + +// Process user actions + + $errors = array(); + + $recalchotness = false; + $startmailing = false; + $securityexpired = false; + + $formokhtml = null; + + // If the post_max_size is exceeded then the $_POST array is empty so no field processing can be done + if (qa_post_limit_exceeded()) + $errors['avatar_default_show'] = qa_lang('main/file_upload_limit_exceeded'); + else + if (qa_clicked('doresetoptions')) { + if (!qa_check_form_security_code('admin/' . $adminsection, qa_post_text('code'))) + $securityexpired = true; + + else { + qa_reset_options($getoptions); + $formokhtml = qa_lang_html('admin/options_reset'); + } + } elseif (qa_clicked('dosaveoptions')) { + if (!qa_check_form_security_code('admin/' . $adminsection, qa_post_text('code'))) + $securityexpired = true; + + else { + foreach ($getoptions as $optionname) { + $optionvalue = qa_post_text('option_' . $optionname); + + if ( + (@$optiontype[$optionname] == 'number') || + (@$optiontype[$optionname] == 'checkbox') || + ((@$optiontype[$optionname] == 'number-blank') && strlen($optionvalue)) + ) + $optionvalue = (int) $optionvalue; + + if (isset($optionmaximum[$optionname])) + $optionvalue = min($optionmaximum[$optionname], $optionvalue); + + if (isset($optionminimum[$optionname])) + $optionvalue = max($optionminimum[$optionname], $optionvalue); + + switch ($optionname) { + case 'site_url': + if (substr($optionvalue, -1) != '/') // seems to be a very common mistake and will mess up URLs + $optionvalue .= '/'; + break; + + case 'hot_weight_views': + case 'hot_weight_answers': + case 'hot_weight_votes': + case 'hot_weight_q_age': + case 'hot_weight_a_age': + if (qa_opt($optionname) != $optionvalue) + $recalchotness = true; + break; + + case 'block_ips_write': + require_once QA_INCLUDE_DIR.'app/limits.php'; + $optionvalue = implode(' , ', qa_block_ips_explode($optionvalue)); + break; + + case 'block_bad_words': + require_once QA_INCLUDE_DIR.'util/string.php'; + $optionvalue = implode(' , ', qa_block_words_explode($optionvalue)); + break; + } + + qa_set_option($optionname, $optionvalue); + } + + $formokhtml = qa_lang_html('admin/options_saved'); + + // Uploading default avatar + if (is_array(@$_FILES['avatar_default_file'])) { + $avatarfileerror = $_FILES['avatar_default_file']['error']; + + // Note if $_FILES['avatar_default_file']['error'] === 1 then upload_max_filesize has been exceeded + if ($avatarfileerror === 1) + $errors['avatar_default_show'] = qa_lang('main/file_upload_limit_exceeded'); + elseif ($avatarfileerror === 0 && $_FILES['avatar_default_file']['size'] > 0) { + require_once QA_INCLUDE_DIR.'util/image.php'; + + $oldblobid = qa_opt('avatar_default_blobid'); + + $toobig = qa_image_file_too_big($_FILES['avatar_default_file']['tmp_name'], qa_opt('avatar_store_size')); + + if ($toobig) + $errors['avatar_default_show'] = qa_lang_sub('main/image_too_big_x_pc', (int) ($toobig * 100)); + + else { + $imagedata = qa_image_constrain_data(file_get_contents($_FILES['avatar_default_file']['tmp_name']), $width, $height, qa_opt('avatar_store_size')); + + if (isset($imagedata)) { + require_once QA_INCLUDE_DIR.'app/blobs.php'; + + $newblobid = qa_create_blob($imagedata, 'jpeg'); + + if (isset($newblobid)) { + qa_set_option('avatar_default_blobid', $newblobid); + qa_set_option('avatar_default_width', $width); + qa_set_option('avatar_default_height', $height); + qa_set_option('avatar_default_show', 1); + } + + if (strlen($oldblobid)) + qa_delete_blob($oldblobid); + } else + $errors['avatar_default_show'] = qa_lang_sub('main/image_not_read', implode(', ', qa_gd_image_formats())); + } + } + } + } + } + + +// Mailings management + + if ($adminsection == 'mailing') { + if ( qa_clicked('domailingtest') || qa_clicked('domailingstart') || qa_clicked('domailingresume') || qa_clicked('domailingcancel') ) { + if (!qa_check_form_security_code('admin/'.$adminsection, qa_post_text('code'))) + $securityexpired = true; + + else { + if (qa_clicked('domailingtest')) { + $email = qa_get_logged_in_email(); + + if (qa_mailing_send_one(qa_get_logged_in_userid(), qa_get_logged_in_handle(), $email, qa_get_logged_in_user_field('emailcode'))) + $formokhtml = qa_lang_html_sub('admin/test_sent_to_x', qa_html($email)); + else + $formokhtml = qa_lang_html('main/general_error'); + } + + if (qa_clicked('domailingstart')) { + qa_mailing_start(); + $startmailing = true; + } + + if (qa_clicked('domailingresume')) + $startmailing = true; + + if (qa_clicked('domailingcancel')) + qa_mailing_stop(); + } + } + + $mailingprogress = qa_mailing_progress_message(); + + if (isset($mailingprogress)) { + $formokhtml = qa_html($mailingprogress); + + $checkboxtodisplay = array( + 'mailing_enabled' => '0', + ); + + } + else { + $checkboxtodisplay = array( + 'mailing_from_name' => 'option_mailing_enabled', + 'mailing_from_email' => 'option_mailing_enabled', + 'mailing_subject' => 'option_mailing_enabled', + 'mailing_body' => 'option_mailing_enabled', + 'mailing_per_minute' => 'option_mailing_enabled', + 'domailingtest' => 'option_mailing_enabled', + 'domailingstart' => 'option_mailing_enabled', + ); + } + } + + +// Get the actual options + + $options = qa_get_options($getoptions); + + +// Prepare content for theme + + $qa_content = qa_content_prepare(); + + $qa_content['title'] = qa_lang_html('admin/admin_title').' - '.qa_lang_html($subtitle); + $qa_content['error'] = $securityexpired ? qa_lang_html('admin/form_security_expired') : qa_admin_page_error(); + + $qa_content['script_rel'][] = 'qa-content/qa-admin.js?'.QA_VERSION; + + $qa_content['form'] = array( + 'ok' => $formokhtml, + + 'tags' => 'method="post" action="'.qa_self_html().'" name="admin_form" onsubmit="document.forms.admin_form.has_js.value=1; return true;"', + + 'style' => $formstyle, + + 'fields' => array(), + + 'buttons' => array( + 'save' => array( + 'tags' => 'id="dosaveoptions"', + 'label' => qa_lang_html('admin/save_options_button'), + ), + + 'reset' => array( + 'tags' => 'name="doresetoptions" onclick="return confirm('.qa_js(qa_lang_html('admin/reset_options_confirm')).');"', + 'label' => qa_lang_html('admin/reset_options_button'), + ), + ), + + 'hidden' => array( + 'dosaveoptions' => '1', // for IE + 'has_js' => '0', + 'code' => qa_get_form_security_code('admin/'.$adminsection), + ), + ); + + if ($recalchotness) { + $qa_content['form']['ok'] = ''; + $qa_content['form']['hidden']['code_recalc'] = qa_get_form_security_code('admin/recalc'); + + $qa_content['script_var']['qa_warning_recalc'] = qa_lang('admin/stop_recalc_warning'); + + $qa_content['script_onloads'][] = array( + "qa_recalc_click('dorecountposts', document.getElementById('dosaveoptions'), null, 'recalc_ok');" + ); + + } + elseif ($startmailing) { + + if (qa_post_text('has_js')) { + $qa_content['form']['ok'] = ''.qa_html($mailingprogress).''; + + $qa_content['script_onloads'][] = array( + "qa_mailing_start('mailing_ok', 'domailingpause');" + ); + + } + else { // rudimentary non-Javascript version of mass mailing loop + echo ''; + + while (true) { + qa_mailing_perform_step(); + + $message = qa_mailing_progress_message(); + + if (!isset($message)) + break; + + echo qa_html($message).str_repeat(' ', 1024)."
\n"; + + flush(); + sleep(1); + } + + echo qa_lang_html('admin/mailing_complete').'

'.qa_lang_html('admin/admin_title').' - '.qa_lang_html('admin/mailing_title').''; + + qa_exit(); + } + } + + + function qa_optionfield_make_select(&$optionfield, $options, $value, $default) + { + $optionfield['type'] = 'select'; + $optionfield['options'] = $options; + $optionfield['value'] = isset($options[qa_html($value)]) ? $options[qa_html($value)] : @$options[$default]; + } + + $indented = false; + + foreach ($showoptions as $optionname) + if (empty($optionname)) { + $indented = false; + + $qa_content['form']['fields'][] = array( + 'type' => 'blank' + ); + + } + elseif (strpos($optionname, '/') !== false) { + $qa_content['form']['fields'][] = array( + 'type' => 'static', + 'label' => qa_lang_html($optionname), + ); + + $indented = true; + + } + else { + $type = @$optiontype[$optionname]; + if ($type == 'number-blank') + $type = 'number'; + + $value = $options[$optionname]; + + $optionfield = array( + 'id' => $optionname, + 'label' => ($indented ? '– ' : '').qa_lang_html('options/'.$optionname), + 'tags' => 'name="option_'.$optionname.'" id="option_'.$optionname.'"', + 'value' => qa_html($value), + 'type' => $type, + 'error' => qa_html(@$errors[$optionname]), + ); + + if (isset($optionmaximum[$optionname])) + $optionfield['note'] = qa_lang_html_sub('admin/maximum_x', $optionmaximum[$optionname]); + + $feedrequest = null; + $feedisexample = false; + + switch ($optionname) { // special treatment for certain options + case 'site_language': + require_once QA_INCLUDE_DIR.'util/string.php'; + + qa_optionfield_make_select($optionfield, qa_admin_language_options(), $value, ''); + + $optionfield['suffix'] = strtr(qa_lang_html('admin/check_language_suffix'), array( + '^1' => '', + '^2' => '', + )); + + if (!qa_has_multibyte()) + $optionfield['error'] = qa_lang_html('admin/no_multibyte'); + break; + + case 'neat_urls': + $neatoptions = array(); + + $rawoptions = array( + QA_URL_FORMAT_NEAT, + QA_URL_FORMAT_INDEX, + QA_URL_FORMAT_PARAM, + QA_URL_FORMAT_PARAMS, + QA_URL_FORMAT_SAFEST, + ); + + foreach ($rawoptions as $rawoption) { + $neatoptions[$rawoption] = + ' '. + ''. + qa_html(urldecode(qa_path('123/why-do-birds-sing', null, '/', $rawoption))). + (($rawoption == QA_URL_FORMAT_NEAT) ? strtr(qa_lang_html('admin/neat_urls_note'), array( + '^1' => '', + '^2' => '', + )) : ''). + ''; + } + + qa_optionfield_make_select($optionfield, $neatoptions, $value, QA_URL_FORMAT_SAFEST); + + $optionfield['type'] = 'select-radio'; + $optionfield['note'] = qa_lang_html_sub('admin/url_format_note', ''.$namehtml.''; + } + + $authorhtml = ''; + if (strlen(@$metadata['author'])) { + $authorhtml = qa_html($metadata['author']); + + if (strlen(@$metadata['author_uri'])) + $authorhtml = ''.$authorhtml.''; + + $authorhtml = qa_lang_html_sub('main/by_x', $authorhtml); + + } + + $updatehtml = ''; + if (strlen(@$metadata['version']) && strlen(@$metadata['update_uri'])) { + $elementid = 'version_check_'.$optionname; + + $updatehtml = '(...)'; + + $qa_content['script_onloads'][] = array( + "qa_version_check(".qa_js($metadata['update_uri']).", ".qa_js($metadata['version'], true).", ".qa_js($elementid).");" + ); + + } + + $optionfield['suffix'] = $namehtml.' '.$authorhtml.' '.$updatehtml; + break; + + case 'site_text_direction': + $directions = array('ltr'=>'LTR', 'rtl'=>'RTL'); + qa_optionfield_make_select($optionfield, $directions, $value, 'ltr'); + break; + + case 'tags_or_categories': + qa_optionfield_make_select($optionfield, array( + '' => qa_lang_html('admin/no_classification'), + 't' => qa_lang_html('admin/tags'), + 'c' => qa_lang_html('admin/categories'), + 'tc' => qa_lang_html('admin/tags_and_categories'), + ), $value, 'tc'); + + $optionfield['error'] = ''; + + if (qa_opt('cache_tagcount') && !qa_using_tags()) + $optionfield['error'] .= qa_lang_html('admin/tags_not_shown').' '; + + if (!qa_using_categories()) + foreach ($categories as $category) + if ($category['qcount']) { + $optionfield['error'] .= qa_lang_html('admin/categories_not_shown'); + break; + } + break; + + case 'smtp_secure': + qa_optionfield_make_select($optionfield, array( + '' => qa_lang_html('options/smtp_secure_none'), + 'ssl' => 'SSL', + 'tls' => 'TLS', + ), $value, ''); + break; + + case 'custom_sidebar': + case 'custom_sidepanel': + case 'custom_header': + case 'custom_footer': + case 'custom_in_head': + case 'home_description': + unset($optionfield['label']); + $optionfield['rows'] = 6; + break; + + case 'custom_home_content': + $optionfield['rows'] = 16; + break; + + case 'show_custom_register': + case 'show_register_terms': + case 'show_custom_welcome': + case 'show_notice_welcome': + case 'show_notice_visitor': + $optionfield['style'] = 'tall'; + break; + + case 'custom_register': + case 'register_terms': + case 'custom_welcome': + case 'notice_welcome': + case 'notice_visitor': + unset($optionfield['label']); + $optionfield['style'] = 'tall'; + $optionfield['rows'] = 3; + break; + + case 'avatar_allow_gravatar': + $optionfield['label'] = strtr($optionfield['label'], array( + '^1' => '', + '^2' => '', + )); + + if (!qa_has_gd_image()) { + $optionfield['style'] = 'tall'; + $optionfield['error'] = qa_lang_html('admin/no_image_gd'); + } + break; + + case 'avatar_store_size': + case 'avatar_profile_size': + case 'avatar_users_size': + case 'avatar_q_page_q_size': + case 'avatar_q_page_a_size': + case 'avatar_q_page_c_size': + case 'avatar_q_list_size': + case 'avatar_message_list_size': + $optionfield['note'] = qa_lang_html('admin/pixels'); + break; + + case 'avatar_default_show': + $qa_content['form']['tags'] .= 'enctype="multipart/form-data"'; + $optionfield['label'] .= ' '. + qa_get_avatar_blob_html(qa_opt('avatar_default_blobid'), qa_opt('avatar_default_width'), qa_opt('avatar_default_height'), 32). + ' '; + break; + + case 'logo_width': + case 'logo_height': + $optionfield['suffix'] = qa_lang_html('admin/pixels'); + break; + + case 'pages_prev_next': + qa_optionfield_make_select($optionfield, array(0 => 0, 1 => 1, 2 => 2, 3 => 3, 4 => 4, 5 => 5), $value, 3); + break; + + case 'columns_tags': + case 'columns_users': + qa_optionfield_make_select($optionfield, array(1 => 1, 2 => 2, 3 => 3, 4 => 4, 5 => 5), $value, 2); + break; + + case 'min_len_q_title': + case 'q_urls_title_length': + case 'min_len_q_content': + case 'min_len_a_content': + case 'min_len_c_content': + $optionfield['note'] = qa_lang_html('admin/characters'); + break; + + case 'min_num_q_tags': + case 'max_num_q_tags': + $optionfield['note'] = qa_lang_html_sub('main/x_tags', ''); // this to avoid language checking error: a_lang('main/1_tag') + break; + + case 'show_full_date_days': + $optionfield['note'] = qa_lang_html_sub('main/x_days', ''); + break; + + case 'sort_answers_by': + qa_optionfield_make_select($optionfield, array( + 'created' => qa_lang_html('options/sort_time'), + 'votes' => qa_lang_html('options/sort_votes'), + ), $value, 'created'); + break; + + case 'page_size_q_as': + $optionfield['note'] = qa_lang_html_sub('main/x_answers', ''); + break; + + case 'show_a_form_immediate': + qa_optionfield_make_select($optionfield, array( + 'always' => qa_lang_html('options/show_always'), + 'if_no_as' => qa_lang_html('options/show_if_no_as'), + 'never' => qa_lang_html('options/show_never'), + ), $value, 'if_no_as'); + break; + + case 'show_fewer_cs_from': + case 'show_fewer_cs_count': + $optionfield['note'] = qa_lang_html_sub('main/x_comments', ''); + break; + + case 'match_related_qs': + case 'match_ask_check_qs': + case 'match_example_tags': + qa_optionfield_make_select($optionfield, qa_admin_match_options(), $value, 3); + break; + + case 'block_bad_words': + $optionfield['style'] = 'tall'; + $optionfield['rows'] = 4; + $optionfield['note'] = qa_lang_html('admin/block_words_note'); + break; + + case 'editor_for_qs': + case 'editor_for_as': + case 'editor_for_cs': + $editors = qa_list_modules('editor'); + + $selectoptions = array(); + $optionslinks = false; + + foreach ($editors as $editor) { + $selectoptions[qa_html($editor)] = strlen($editor) ? qa_html($editor) : qa_lang_html('admin/basic_editor'); + + if ($editor == $value) { + $module = qa_load_module('editor', $editor); + + if (method_exists($module, 'admin_form')) + $optionfield['note'] = ''.qa_lang_html('admin/options').''; + } + } + + qa_optionfield_make_select($optionfield, $selectoptions, $value, ''); + break; + + case 'show_custom_ask': + case 'extra_field_active': + case 'show_custom_answer': + case 'show_custom_comment': + $optionfield['style'] = 'tall'; + break; + + case 'custom_ask': + case 'custom_answer': + case 'custom_comment': + $optionfield['style'] = 'tall'; + unset($optionfield['label']); + $optionfield['rows'] = 3; + break; + + case 'extra_field_display': + $optionfield['style'] = 'tall'; + $optionfield['label'] = ''.qa_lang_html('options/extra_field_display_label').''; + break; + + case 'extra_field_prompt': + case 'extra_field_label': + $optionfield['style'] = 'tall'; + unset($optionfield['label']); + break; + + case 'search_module': + foreach ($searchmodules as $modulename => $module) { + $selectoptions[qa_html($modulename)] = strlen($modulename) ? qa_html($modulename) : qa_lang_html('options/option_default'); + + if (($modulename == $value) && method_exists($module, 'admin_form')) + $optionfield['note'] = ''.qa_lang_html('admin/options').''; + } + + qa_optionfield_make_select($optionfield, $selectoptions, $value, ''); + break; + + case 'hot_weight_q_age': + case 'hot_weight_a_age': + case 'hot_weight_answers': + case 'hot_weight_votes': + case 'hot_weight_views': + $optionfield['note'] = '/ 100'; + break; + + case 'moderate_by_points': + $optionfield['label'] = ''.qa_lang_html('options/moderate_points_limit').''; + break; + + case 'moderate_points_limit': + unset($optionfield['label']); + $optionfield['note'] = qa_lang_html('admin/points'); + break; + + case 'flagging_hide_after': + case 'flagging_notify_every': + case 'flagging_notify_first': + $optionfield['note'] = qa_lang_html_sub('main/x_flags', ''); + break; + + case 'block_ips_write': + $optionfield['style'] = 'tall'; + $optionfield['rows'] = 4; + $optionfield['note'] = qa_lang_html('admin/block_ips_note'); + break; + + case 'allow_view_q_bots': + $optionfield['note'] = $optionfield['label']; + unset($optionfield['label']); + break; + + case 'permit_view_q_page': + case 'permit_post_q': + case 'permit_post_a': + case 'permit_post_c': + case 'permit_vote_q': + case 'permit_vote_a': + case 'permit_vote_down': + case 'permit_edit_q': + case 'permit_retag_cat': + case 'permit_edit_a': + case 'permit_edit_c': + case 'permit_edit_silent': + case 'permit_flag': + case 'permit_close_q': + case 'permit_select_a': + case 'permit_hide_show': + case 'permit_moderate': + case 'permit_delete_hidden': + case 'permit_anon_view_ips': + case 'permit_view_voters_flaggers': + case 'permit_post_wall': + $dopoints = true; + + if ($optionname == 'permit_retag_cat') + $optionfield['label'] = qa_lang_html(qa_using_categories() ? 'profile/permit_recat' : 'profile/permit_retag').':'; + else + $optionfield['label'] = qa_lang_html('profile/'.$optionname).':'; + + if ( ($optionname == 'permit_view_q_page') || ($optionname == 'permit_post_q') || ($optionname == 'permit_post_a') || ($optionname == 'permit_post_c') || ($optionname == 'permit_anon_view_ips') ) + $widest = QA_PERMIT_ALL; + elseif ( ($optionname == 'permit_close_q') || ($optionname == 'permit_select_a') || ($optionname == 'permit_moderate')|| ($optionname == 'permit_hide_show') ) + $widest = QA_PERMIT_POINTS; + elseif ($optionname == 'permit_delete_hidden') + $widest = QA_PERMIT_EDITORS; + elseif ( ($optionname == 'permit_view_voters_flaggers') || ($optionname == 'permit_edit_silent') ) + $widest = QA_PERMIT_EXPERTS; + else + $widest = QA_PERMIT_USERS; + + if ($optionname == 'permit_view_q_page') { + $narrowest = QA_PERMIT_APPROVED; + $dopoints = false; + } + elseif ( ($optionname == 'permit_edit_c') || ($optionname == 'permit_close_q') || ($optionname == 'permit_select_a') || ($optionname == 'permit_moderate')|| ($optionname == 'permit_hide_show') || ($optionname == 'permit_anon_view_ips') ) + $narrowest = QA_PERMIT_MODERATORS; + elseif ( ($optionname == 'permit_post_c') || ($optionname == 'permit_edit_q') || ($optionname == 'permit_retag_cat') || ($optionname == 'permit_edit_a') || ($optionname == 'permit_flag') ) + $narrowest = QA_PERMIT_EDITORS; + elseif ( ($optionname == 'permit_vote_q') || ($optionname == 'permit_vote_a') || ($optionname == 'permit_post_wall') ) + $narrowest = QA_PERMIT_APPROVED_POINTS; + elseif ( ($optionname == 'permit_delete_hidden') || ($optionname == 'permit_edit_silent') ) + $narrowest = QA_PERMIT_ADMINS; + elseif ($optionname == 'permit_view_voters_flaggers') + $narrowest = QA_PERMIT_SUPERS; + else + $narrowest = QA_PERMIT_EXPERTS; + + $permitoptions = qa_admin_permit_options($widest, $narrowest, (!QA_FINAL_EXTERNAL_USERS) && qa_opt('confirm_user_emails'), $dopoints); + + if (count($permitoptions)>1) { + qa_optionfield_make_select($optionfield, $permitoptions, $value, + ($value == QA_PERMIT_CONFIRMED) ? QA_PERMIT_USERS : min(array_keys($permitoptions))); + } + else { + $optionfield['type'] = 'static'; + $optionfield['value'] = reset($permitoptions); + } + break; + + case 'permit_post_q_points': + case 'permit_post_a_points': + case 'permit_post_c_points': + case 'permit_vote_q_points': + case 'permit_vote_a_points': + case 'permit_vote_down_points': + case 'permit_flag_points': + case 'permit_edit_q_points': + case 'permit_retag_cat_points': + case 'permit_edit_a_points': + case 'permit_edit_c_points': + case 'permit_close_q_points': + case 'permit_select_a_points': + case 'permit_hide_show_points': + case 'permit_moderate_points': + case 'permit_delete_hidden_points': + case 'permit_anon_view_ips_points': + case 'permit_post_wall_points': + unset($optionfield['label']); + $optionfield['type'] = 'number'; + $optionfield['prefix'] = qa_lang_html('admin/users_must_have').' '; + $optionfield['note'] = qa_lang_html('admin/points'); + break; + + case 'feed_for_qa': + $feedrequest = 'qa'; + break; + + case 'feed_for_questions': + $feedrequest = 'questions'; + break; + + case 'feed_for_hot': + $feedrequest = 'hot'; + break; + + case 'feed_for_unanswered': + $feedrequest = 'unanswered'; + break; + + case 'feed_for_activity': + $feedrequest = 'activity'; + break; + + case 'feed_per_category': + if (count($categories)) { + $category = reset($categories); + $categoryslug = $category['tags']; + + } + else + $categoryslug = 'example-category'; + + if (qa_opt('feed_for_qa')) + $feedrequest = 'qa'; + elseif (qa_opt('feed_for_questions')) + $feedrequest = 'questions'; + else + $feedrequest = 'activity'; + + $feedrequest .= '/'.$categoryslug; + $feedisexample = true; + break; + + case 'feed_for_tag_qs': + $populartags = qa_db_select_with_pending(qa_db_popular_tags_selectspec(0, 1)); + + if (count($populartags)) { + reset($populartags); + $feedrequest = 'tag/'.key($populartags); + } + else + $feedrequest = 'tag/singing'; + + $feedisexample = true; + break; + + case 'feed_for_search': + $feedrequest = 'search/why do birds sing'; + $feedisexample = true; + break; + + case 'moderate_users': + $optionfield['note'] = ''.qa_lang_html('admin/registration_fields').''; + break; + + case 'captcha_module': + $captchaoptions = array(); + + foreach ($captchamodules as $modulename) { + $captchaoptions[qa_html($modulename)] = qa_html($modulename); + + if ($modulename == $value) { + $module = qa_load_module('captcha', $modulename); + + if (method_exists($module, 'admin_form')) + $optionfield['note'] = ''.qa_lang_html('admin/options').''; + } + } + + qa_optionfield_make_select($optionfield, $captchaoptions, $value, ''); + break; + + case 'moderate_update_time': + qa_optionfield_make_select($optionfield, array( + '0' => qa_lang_html('options/time_written'), + '1' => qa_lang_html('options/time_approved'), + ), $value, '0'); + break; + + case 'max_rate_ip_as': + case 'max_rate_ip_cs': + case 'max_rate_ip_flags': + case 'max_rate_ip_logins': + case 'max_rate_ip_messages': + case 'max_rate_ip_qs': + case 'max_rate_ip_registers': + case 'max_rate_ip_uploads': + case 'max_rate_ip_votes': + $optionfield['note'] = qa_lang_html('admin/per_ip_hour'); + break; + + case 'max_rate_user_as': + case 'max_rate_user_cs': + case 'max_rate_user_flags': + case 'max_rate_user_messages': + case 'max_rate_user_qs': + case 'max_rate_user_uploads': + case 'max_rate_user_votes': + unset($optionfield['label']); + $optionfield['note'] = qa_lang_html('admin/per_user_hour'); + break; + + case 'mailing_per_minute': + $optionfield['suffix'] = qa_lang_html('admin/emails_per_minute'); + break; + } + + if (isset($feedrequest) && $value) + $optionfield['note'] = ''.qa_lang_html($feedisexample ? 'admin/feed_link_example' : 'admin/feed_link').''; + + $qa_content['form']['fields'][$optionname] = $optionfield; + } + + +// Extra items for specific pages + + switch ($adminsection) { + case 'users': + if (!QA_FINAL_EXTERNAL_USERS) { + $userfields = qa_db_single_select(qa_db_userfields_selectspec()); + + $listhtml = ''; + + foreach ($userfields as $userfield) { + $listhtml .= '

  • '.qa_html(qa_user_userfield_label($userfield)).''; + + $listhtml .= strtr(qa_lang_html('admin/edit_field'), array( + '^1' => '', + '^2' => '', + )); + + $listhtml .= '
  • '; + } + + $listhtml .= '
  • '.qa_lang_html('admin/add_new_field').'
  • '; + + $qa_content['form']['fields'][] = array('type' => 'blank'); + + $qa_content['form']['fields']['userfields'] = array( + 'label' => qa_lang_html('admin/profile_fields'), + 'id' => 'profile_fields', + 'style' => 'tall', + 'type' => 'custom', + 'html' => strlen($listhtml) ? '' : null, + ); + } + + $qa_content['form']['fields'][] = array('type' => 'blank'); + + $pointstitle = qa_get_points_to_titles(); + + $listhtml = ''; + + foreach ($pointstitle as $points => $title) { + $listhtml .= '
  • '.$title.' - '.(($points == 1) ? qa_lang_html_sub('main/1_point', '1', '1') + : qa_lang_html_sub('main/x_points', qa_html(number_format($points)))); + + $listhtml .= strtr(qa_lang_html('admin/edit_title'), array( + '^1' => '', + '^2' => '', + )); + + $listhtml .= '
  • '; + } + + $listhtml .= '
  • '.qa_lang_html('admin/add_new_title').'
  • '; + + $qa_content['form']['fields']['usertitles'] = array( + 'label' => qa_lang_html('admin/user_titles'), + 'style' => 'tall', + 'type' => 'custom', + 'html' => strlen($listhtml) ? '' : null, + ); + break; + + case 'layout': + $listhtml = ''; + + $widgetmodules = qa_load_modules_with('widget', 'allow_template'); + + foreach ($widgetmodules as $tryname => $trywidget) + if (method_exists($trywidget, 'allow_region')) { + $listhtml .= '
  • '.qa_html($tryname).''; + + $listhtml .= strtr(qa_lang_html('admin/add_widget_link'), array( + '^1' => '', + '^2' => '', + )); + + if (method_exists($trywidget, 'admin_form')) + $listhtml .= strtr(qa_lang_html('admin/widget_global_options'), array( + '^1' => '', + '^2' => '', + )); + + $listhtml .= '
  • '; + } + + if (strlen($listhtml)) + $qa_content['form']['fields']['plugins'] = array( + 'label' => qa_lang_html('admin/widgets_explanation'), + 'style' => 'tall', + 'type' => 'custom', + 'html' => '', + ); + + $widgets = qa_db_single_select(qa_db_widgets_selectspec()); + + $listhtml = ''; + + $placeoptions = qa_admin_place_options(); + + foreach ($widgets as $widget) { + $listhtml .= '
  • '.qa_html($widget['title']).' - '. + ''. + @$placeoptions[$widget['place']].''; + + $listhtml .= '
  • '; + } + + if (strlen($listhtml)) + $qa_content['form']['fields']['widgets'] = array( + 'label' => qa_lang_html('admin/active_widgets_explanation'), + 'type' => 'custom', + 'html' => '', + ); + + break; + + case 'permissions': + $qa_content['form']['fields']['permit_block'] = array( + 'type' => 'static', + 'label' => qa_lang_html('options/permit_block'), + 'value' => qa_lang_html('options/permit_moderators'), + ); + + if (!QA_FINAL_EXTERNAL_USERS) { + $qa_content['form']['fields']['permit_approve_users'] = array( + 'type' => 'static', + 'label' => qa_lang_html('options/permit_approve_users'), + 'value' => qa_lang_html('options/permit_moderators'), + ); + + $qa_content['form']['fields']['permit_create_experts'] = array( + 'type' => 'static', + 'label' => qa_lang_html('options/permit_create_experts'), + 'value' => qa_lang_html('options/permit_moderators'), + ); + + $qa_content['form']['fields']['permit_see_emails'] = array( + 'type' => 'static', + 'label' => qa_lang_html('options/permit_see_emails'), + 'value' => qa_lang_html('options/permit_admins'), + ); + + $qa_content['form']['fields']['permit_delete_users'] = array( + 'type' => 'static', + 'label' => qa_lang_html('options/permit_delete_users'), + 'value' => qa_lang_html('options/permit_admins'), + ); + + $qa_content['form']['fields']['permit_create_eds_mods'] = array( + 'type' => 'static', + 'label' => qa_lang_html('options/permit_create_eds_mods'), + 'value' => qa_lang_html('options/permit_admins'), + ); + + $qa_content['form']['fields']['permit_create_admins'] = array( + 'type' => 'static', + 'label' => qa_lang_html('options/permit_create_admins'), + 'value' => qa_lang_html('options/permit_supers'), + ); + + } + break; + + case 'mailing': + require_once QA_INCLUDE_DIR.'util/sort.php'; + + if (isset($mailingprogress)) { + unset($qa_content['form']['buttons']['save']); + unset($qa_content['form']['buttons']['reset']); + + if ($startmailing) { + unset($qa_content['form']['hidden']['dosaveoptions']); + + foreach ($showoptions as $optionname) + $qa_content['form']['fields'][$optionname]['type'] = 'static'; + + $qa_content['form']['fields']['mailing_body']['value'] = qa_html(qa_opt('mailing_body'), true); + + $qa_content['form']['buttons']['stop'] = array( + 'tags' => 'name="domailingpause" id="domailingpause"', + 'label' => qa_lang_html('admin/pause_mailing_button'), + ); + + } + else { + $qa_content['form']['buttons']['resume'] = array( + 'tags' => 'name="domailingresume"', + 'label' => qa_lang_html('admin/resume_mailing_button'), + ); + + $qa_content['form']['buttons']['cancel'] = array( + 'tags' => 'name="domailingcancel"', + 'label' => qa_lang_html('admin/cancel_mailing_button'), + ); + } + } + else { + $qa_content['form']['buttons']['spacer'] = array(); + + $qa_content['form']['buttons']['test'] = array( + 'tags' => 'name="domailingtest" id="domailingtest"', + 'label' => qa_lang_html('admin/send_test_button'), + ); + + $qa_content['form']['buttons']['start'] = array( + 'tags' => 'name="domailingstart" id="domailingstart"', + 'label' => qa_lang_html('admin/start_mailing_button'), + ); + } + + if (!$startmailing) { + $qa_content['form']['fields']['mailing_enabled']['note'] = qa_lang_html('admin/mailing_explanation'); + $qa_content['form']['fields']['mailing_body']['rows'] = 12; + $qa_content['form']['fields']['mailing_body']['note'] = qa_lang_html('admin/mailing_unsubscribe'); + } + break; + } + + + if (isset($checkboxtodisplay)) + qa_set_display_rules($qa_content, $checkboxtodisplay); + + $qa_content['navigation']['sub'] = qa_admin_sub_navigation(); + + + return $qa_content; + + +/* + Omit PHP closing tag to help avoid accidental output +*/ \ No newline at end of file diff --git a/pages/admin/admin-flagged.php b/pages/admin/admin-flagged.php new file mode 100644 index 0000000..415a4ac --- /dev/null +++ b/pages/admin/admin-flagged.php @@ -0,0 +1,140 @@ + $question) + if (qa_user_post_permit_error('permit_hide_show', $question)) + unset($questions[$index]); + + +// Get information for users + + $usershtml=qa_userids_handles_html(qa_any_get_userids_handles($questions)); + + +// Prepare content for theme + + $qa_content=qa_content_prepare(); + + $qa_content['title']=qa_lang_html('admin/most_flagged_title'); + $qa_content['error']=isset($pageerror) ? $pageerror : qa_admin_page_error(); + + $qa_content['q_list']=array( + 'form' => array( + 'tags' => 'method="post" action="'.qa_self_html().'"', + + 'hidden' => array( + 'code' => qa_get_form_security_code('admin/click'), + ), + ), + + 'qs' => array(), + ); + + + if (count($questions)) { + foreach ($questions as $question) { + $postid=qa_html(isset($question['opostid']) ? $question['opostid'] : $question['postid']); + $elementid='p'.$postid; + + $htmloptions=qa_post_html_options($question); + $htmloptions['voteview']=false; + $htmloptions['tagsview']=($question['obasetype']=='Q'); + $htmloptions['answersview']=false; + $htmloptions['viewsview']=false; + $htmloptions['contentview']=true; + $htmloptions['flagsview']=true; + $htmloptions['elementid']=$elementid; + + $htmlfields=qa_any_to_q_html_fields($question, $userid, qa_cookie_get(), $usershtml, null, $htmloptions); + + if (isset($htmlfields['what_url'])) // link directly to relevant content + $htmlfields['url']=$htmlfields['what_url']; + + $htmlfields['form']=array( + 'style' => 'light', + + 'buttons' => array( + 'clearflags' => array( + 'tags' => 'name="admin_'.$postid.'_clearflags" onclick="return qa_admin_click(this);"', + 'label' => qa_lang_html('question/clear_flags_button'), + ), + + 'hide' => array( + 'tags' => 'name="admin_'.$postid.'_hide" onclick="return qa_admin_click(this);"', + 'label' => qa_lang_html('question/hide_button'), + ), + ), + ); + + $qa_content['q_list']['qs'][]=$htmlfields; + } + + } else + $qa_content['title']=qa_lang_html('admin/no_flagged_found'); + + + $qa_content['navigation']['sub']=qa_admin_sub_navigation(); + $qa_content['script_rel'][]='qa-content/qa-admin.js?'.QA_VERSION; + + + return $qa_content; + + +/* + Omit PHP closing tag to help avoid accidental output +*/ \ No newline at end of file diff --git a/pages/admin/admin-hidden.php b/pages/admin/admin-hidden.php new file mode 100644 index 0000000..51b007c --- /dev/null +++ b/pages/admin/admin-hidden.php @@ -0,0 +1,171 @@ + $question) + if (qa_user_post_permit_error('permit_hide_show', $question) && qa_user_post_permit_error('permit_delete_hidden', $question)) + unset($questions[$index]); + + +// Get information for users + + $usershtml=qa_userids_handles_html(qa_any_get_userids_handles($questions)); + + +// Create list of actual hidden postids and see which ones have dependents + + $qhiddenpostid=array(); + foreach ($questions as $key => $question) + $qhiddenpostid[$key]=isset($question['opostid']) ? $question['opostid'] : $question['postid']; + + $dependcounts=qa_db_postids_count_dependents($qhiddenpostid); + + +// Prepare content for theme + + $qa_content=qa_content_prepare(); + + $qa_content['title']=qa_lang_html('admin/recent_hidden_title'); + $qa_content['error']=isset($pageerror) ? $pageerror : qa_admin_page_error(); + + $qa_content['q_list']=array( + 'form' => array( + 'tags' => 'method="post" action="'.qa_self_html().'"', + + 'hidden' => array( + 'code' => qa_get_form_security_code('admin/click'), + ), + ), + + 'qs' => array(), + ); + + if (count($questions)) { + foreach ($questions as $key => $question) { + $elementid='p'.$qhiddenpostid[$key]; + + $htmloptions=qa_post_html_options($question); + $htmloptions['voteview']=false; + $htmloptions['tagsview']=!isset($question['opostid']); + $htmloptions['answersview']=false; + $htmloptions['viewsview']=false; + $htmloptions['updateview']=false; + $htmloptions['contentview']=true; + $htmloptions['flagsview']=true; + $htmloptions['elementid']=$elementid; + + $htmlfields=qa_any_to_q_html_fields($question, $userid, qa_cookie_get(), $usershtml, null, $htmloptions); + + if (isset($htmlfields['what_url'])) // link directly to relevant content + $htmlfields['url']=$htmlfields['what_url']; + + $htmlfields['what_2']=qa_lang_html('main/hidden'); + + if (@$htmloptions['whenview']) { + $updated=@$question[isset($question['opostid']) ? 'oupdated' : 'updated']; + if (isset($updated)) + $htmlfields['when_2']=qa_when_to_html($updated, @$htmloptions['fulldatedays']); + } + + $buttons=array(); + + $posttype = qa_strtolower(isset($question['obasetype']) ? $question['obasetype'] : $question['basetype']); + + if (!qa_user_post_permit_error('permit_hide_show', $question)) + // Possible values for popup: reshow_q_popup, reshow_a_popup, reshow_c_popup + $buttons['reshow']=array( + 'tags' => 'name="admin_'.qa_html($qhiddenpostid[$key]).'_reshow" onclick="return qa_admin_click(this);"', + 'label' => qa_lang_html('question/reshow_button'), + 'popup' => qa_lang_html(sprintf('question/reshow_%s_popup', $posttype)), + ); + + if ((!qa_user_post_permit_error('permit_delete_hidden', $question)) && !$dependcounts[$qhiddenpostid[$key]]) + // Possible values for popup: delete_q_popup, delete_a_popup, delete_c_popup + $buttons['delete']=array( + 'tags' => 'name="admin_'.qa_html($qhiddenpostid[$key]).'_delete" onclick="return qa_admin_click(this);"', + 'label' => qa_lang_html('question/delete_button'), + 'popup' => qa_lang_html(sprintf('question/delete_%s_popup', $posttype)), + ); + + if (count($buttons)) + $htmlfields['form']=array( + 'style' => 'light', + 'buttons' => $buttons, + ); + + $qa_content['q_list']['qs'][]=$htmlfields; + } + + } else + $qa_content['title']=qa_lang_html('admin/no_hidden_found'); + + + $qa_content['navigation']['sub']=qa_admin_sub_navigation(); + $qa_content['script_rel'][]='qa-content/qa-admin.js?'.QA_VERSION; + + + return $qa_content; + + +/* + Omit PHP closing tag to help avoid accidental output +*/ \ No newline at end of file diff --git a/pages/admin/admin-moderate.php b/pages/admin/admin-moderate.php new file mode 100644 index 0000000..e68cdcd --- /dev/null +++ b/pages/admin/admin-moderate.php @@ -0,0 +1,163 @@ + $question) + if (qa_user_post_permit_error('permit_moderate', $question)) + unset($questions[$index]); + + +// Get information for users + + $usershtml=qa_userids_handles_html(qa_any_get_userids_handles($questions)); + + +// Prepare content for theme + + $qa_content=qa_content_prepare(); + + $qa_content['title']=qa_lang_html('admin/recent_approve_title'); + $qa_content['error']=isset($pageerror) ? $pageerror : qa_admin_page_error(); + + $qa_content['q_list']=array( + 'form' => array( + 'tags' => 'method="post" action="'.qa_self_html().'"', + + 'hidden' => array( + 'code' => qa_get_form_security_code('admin/click'), + ), + ), + + 'qs' => array(), + ); + + if (count($questions)) { + foreach ($questions as $question) { + $postid=qa_html(isset($question['opostid']) ? $question['opostid'] : $question['postid']); + $elementid='p'.$postid; + + $htmloptions=qa_post_html_options($question); + $htmloptions['voteview']=false; + $htmloptions['tagsview']=!isset($question['opostid']); + $htmloptions['answersview']=false; + $htmloptions['viewsview']=false; + $htmloptions['contentview']=true; + $htmloptions['elementid']=$elementid; + + $htmlfields=qa_any_to_q_html_fields($question, $userid, qa_cookie_get(), $usershtml, null, $htmloptions); + + if (isset($htmlfields['what_url'])) // link directly to relevant content + $htmlfields['url']=$htmlfields['what_url']; + + $posttype = qa_strtolower(isset($question['obasetype']) ? $question['obasetype'] : $question['basetype']); + switch ($posttype) { + case 'q': + default: + $approveKey = 'question/approve_q_popup'; + $rejectKey = 'question/reject_q_popup'; + break; + case 'a': + $approveKey = 'question/approve_a_popup'; + $rejectKey = 'question/reject_a_popup'; + break; + case 'c': + $approveKey = 'question/approve_c_popup'; + $rejectKey = 'question/reject_c_popup'; + break; + } + + $htmlfields['form']=array( + 'style' => 'light', + + 'buttons' => array( + // Possible values for popup: approve_q_popup, approve_a_popup, approve_c_popup + 'approve' => array( + 'tags' => 'name="admin_'.$postid.'_approve" onclick="return qa_admin_click(this);"', + 'label' => qa_lang_html('question/approve_button'), + 'popup' => qa_lang_html($approveKey), + ), + + // Possible values for popup: reject_q_popup, reject_a_popup, reject_c_popup + 'reject' => array( + 'tags' => 'name="admin_'.$postid.'_reject" onclick="return qa_admin_click(this);"', + 'label' => qa_lang_html('question/reject_button'), + 'popup' => qa_lang_html($rejectKey), + ), + ), + ); + + $qa_content['q_list']['qs'][]=$htmlfields; + } + + } else + $qa_content['title']=qa_lang_html('admin/no_approve_found'); + + + $qa_content['navigation']['sub']=qa_admin_sub_navigation(); + $qa_content['script_rel'][]='qa-content/qa-admin.js?'.QA_VERSION; + + + return $qa_content; + + +/* + Omit PHP closing tag to help avoid accidental output +*/ \ No newline at end of file diff --git a/pages/admin/admin-pages.php b/pages/admin/admin-pages.php new file mode 100644 index 0000000..97c83aa --- /dev/null +++ b/pages/admin/admin-pages.php @@ -0,0 +1,582 @@ + qa_get('text'), 'tags' => qa_get('url'), 'nav' => qa_get('nav'), 'position' => 1); + $isexternal=qa_clicked('doaddlink') || qa_get('doaddlink') || qa_post_text('external'); + + } elseif (isset($editpage)) + $isexternal=$editpage['flags'] & QA_PAGE_FLAGS_EXTERNAL; + + +// Check admin privileges (do late to allow one DB query) + + if (!qa_admin_check_privileges($qa_content)) + return $qa_content; + + +// Define an array of navigation settings we can change, option name => language key + + $hascustomhome=qa_has_custom_home(); + + $navoptions=array( + 'nav_home' => 'main/nav_home', + 'nav_activity' => 'main/nav_activity', + $hascustomhome ? 'nav_qa_not_home' : 'nav_qa_is_home' => $hascustomhome ? 'main/nav_qa' : 'admin/nav_qa_is_home', + 'nav_questions' => 'main/nav_qs', + 'nav_hot' => 'main/nav_hot', + 'nav_unanswered' => 'main/nav_unanswered', + 'nav_tags' => 'main/nav_tags', + 'nav_categories' => 'main/nav_categories', + 'nav_users' => 'main/nav_users', + 'nav_ask' => 'main/nav_ask', + ); + + $navpaths=array( + 'nav_home' => '', + 'nav_activity' => 'activity', + 'nav_qa_not_home' => 'qa', + 'nav_qa_is_home' => '', + 'nav_questions' => 'questions', + 'nav_hot' => 'hot', + 'nav_unanswered' => 'unanswered', + 'nav_tags' => 'tags', + 'nav_categories' => 'categories', + 'nav_users' => 'users', + 'nav_ask' => 'ask', + ); + + if (!qa_opt('show_custom_home')) + unset($navoptions['nav_home']); + + if (!qa_using_categories()) + unset($navoptions['nav_categories']); + + if (!qa_using_tags()) + unset($navoptions['nav_tags']); + + +// Process saving an old or new page + + $securityexpired=false; + + if (qa_clicked('docancel')) + $editpage=null; + + elseif (qa_clicked('dosaveoptions') || qa_clicked('doaddpage') || qa_clicked('doaddlink')) { + if (!qa_check_form_security_code('admin/pages', qa_post_text('code'))) + $securityexpired=true; + else foreach ($navoptions as $optionname => $langkey) + qa_set_option($optionname, (int)qa_post_text('option_'.$optionname)); + + } elseif (qa_clicked('dosavepage')) { + require_once QA_INCLUDE_DIR.'db/admin.php'; + require_once QA_INCLUDE_DIR.'util/string.php'; + + if (!qa_check_form_security_code('admin/pages', qa_post_text('code'))) + $securityexpired=true; + else { + $reloadpages=false; + + if (qa_post_text('dodelete')) { + qa_db_page_delete($editpage['pageid']); + + $searchmodules=qa_load_modules_with('search', 'unindex_page'); + foreach ($searchmodules as $searchmodule) + $searchmodule->unindex_page($editpage['pageid']); + + $editpage=null; + $reloadpages=true; + + } else { + $inname=qa_post_text('name'); + $inposition=qa_post_text('position'); + $inpermit=(int)qa_post_text('permit'); + $inurl=qa_post_text('url'); + $innewwindow=qa_post_text('newwindow'); + $inheading=qa_post_text('heading'); + $incontent=qa_post_text('content'); + + $errors=array(); + + // Verify the name (navigation link) is legitimate + + if (empty($inname)) + $errors['name']=qa_lang('main/field_required'); + elseif (qa_strlen($inname)>QA_DB_MAX_CAT_PAGE_TITLE_LENGTH) + $errors['name']=qa_lang_sub('main/max_length_x', QA_DB_MAX_CAT_PAGE_TITLE_LENGTH); + + if ($isexternal) { + + // Verify the url is legitimate (vaguely) + + if (empty($inurl)) + $errors['url']=qa_lang('main/field_required'); + elseif (qa_strlen($inurl)>QA_DB_MAX_CAT_PAGE_TAGS_LENGTH) + $errors['url']=qa_lang_sub('main/max_length_x', QA_DB_MAX_CAT_PAGE_TAGS_LENGTH); + + } else { + + // Verify the heading is legitimate + + if (qa_strlen($inheading)>QA_DB_MAX_TITLE_LENGTH) + $errors['heading']=qa_lang_sub('main/max_length_x', QA_DB_MAX_TITLE_LENGTH); + + // Verify the slug is legitimate (and try some defaults if we're creating a new page, and it's not) + + for ($attempt=0; $attempt<100; $attempt++) { + switch ($attempt) { + case 0: + $inslug=qa_post_text('slug'); + if (!isset($inslug)) + $inslug=implode('-', qa_string_to_words($inname)); + break; + + case 1: + $inslug=qa_lang_sub('admin/page_default_slug', $inslug); + break; + + default: + $inslug=qa_lang_sub('admin/page_default_slug', $attempt-1); + break; + } + + list($matchcategoryid, $matchpage)=qa_db_select_with_pending( + qa_db_slugs_to_category_id_selectspec($inslug), + qa_db_page_full_selectspec($inslug, false) + ); + + if (empty($inslug)) + $errors['slug']=qa_lang('main/field_required'); + elseif (qa_strlen($inslug)>QA_DB_MAX_CAT_PAGE_TAGS_LENGTH) + $errors['slug']=qa_lang_sub('main/max_length_x', QA_DB_MAX_CAT_PAGE_TAGS_LENGTH); + elseif (preg_match('/[\\+\\/]/', $inslug)) + $errors['slug']=qa_lang_sub('admin/slug_bad_chars', '+ /'); + elseif (qa_admin_is_slug_reserved($inslug)) + $errors['slug']=qa_lang('admin/slug_reserved'); + elseif (isset($matchpage) && ($matchpage['pageid']!=@$editpage['pageid'])) + $errors['slug']=qa_lang('admin/page_already_used'); + elseif (isset($matchcategoryid)) + $errors['slug']=qa_lang('admin/category_already_used'); + else + unset($errors['slug']); + + if (isset($editpage['pageid']) || !isset($errors['slug'])) // don't try other options if editing existing page + break; + } + } + + // Perform appropriate database action + + if (isset($editpage['pageid'])) { // changing existing page + if ($isexternal) + qa_db_page_set_fields($editpage['pageid'], + isset($errors['name']) ? $editpage['title'] : $inname, + QA_PAGE_FLAGS_EXTERNAL | ($innewwindow ? QA_PAGE_FLAGS_NEW_WINDOW : 0), + isset($errors['url']) ? $editpage['tags'] : $inurl, + null, null, $inpermit); + + else { + $setheading=isset($errors['heading']) ? $editpage['heading'] : $inheading; + $setslug=isset($errors['slug']) ? $editpage['tags'] : $inslug; + $setcontent=isset($errors['content']) ? $editpage['content'] : $incontent; + + qa_db_page_set_fields($editpage['pageid'], + isset($errors['name']) ? $editpage['title'] : $inname, + 0, + $setslug, $setheading, $setcontent, $inpermit); + + $searchmodules=qa_load_modules_with('search', 'unindex_page'); + foreach ($searchmodules as $searchmodule) + $searchmodule->unindex_page($editpage['pageid']); + + $indextext=qa_viewer_text($setcontent, 'html'); + + $searchmodules=qa_load_modules_with('search', 'index_page'); + foreach ($searchmodules as $searchmodule) + $searchmodule->index_page($editpage['pageid'], $setslug, $setheading, $setcontent, 'html', $indextext); + } + + qa_db_page_move($editpage['pageid'], substr($inposition, 0, 1), substr($inposition, 1)); + + $reloadpages=true; + + if (empty($errors)) + $editpage=null; + else + $editpage=@$pages[$editpage['pageid']]; + + } else { // creating a new one + if (empty($errors)) { + if ($isexternal) + $pageid=qa_db_page_create($inname, QA_PAGE_FLAGS_EXTERNAL | ($innewwindow ? QA_PAGE_FLAGS_NEW_WINDOW : 0), $inurl, null, null, $inpermit); + else { + $pageid=qa_db_page_create($inname, 0, $inslug, $inheading, $incontent, $inpermit); + + $indextext=qa_viewer_text($incontent, 'html'); + + $searchmodules=qa_load_modules_with('search', 'index_page'); + foreach ($searchmodules as $searchmodule) + $searchmodule->index_page($pageid, $inslug, $inheading, $incontent, 'html', $indextext); + } + + qa_db_page_move($pageid, substr($inposition, 0, 1), substr($inposition, 1)); + + $editpage=null; + $reloadpages=true; + } + } + + if (qa_clicked('dosaveview') && empty($errors) && !$isexternal) + qa_redirect($inslug); + } + + if ($reloadpages) { + qa_db_flush_pending_result('navpages'); + $pages=qa_db_select_with_pending(qa_db_pages_selectspec()); + } + } + } + + +// Prepare content for theme + + $qa_content=qa_content_prepare(); + + $qa_content['title']=qa_lang_html('admin/admin_title').' - '.qa_lang_html('admin/pages_title'); + $qa_content['error']=$securityexpired ? qa_lang_html('admin/form_security_expired') : qa_admin_page_error(); + + if (isset($editpage)) { + $positionoptions=array(); + + if (!$isexternal) + $positionoptions['_'.max(1, @$editpage['position'])]=qa_lang_html('admin/no_link'); + + $navlangkey=array( + 'B' => 'admin/before_main_menu', + 'M' => 'admin/after_main_menu', + 'O' => 'admin/opposite_main_menu', + 'F' => 'admin/after_footer', + ); + + foreach ($navlangkey as $nav => $langkey) { + $previous=null; + $passedself=false; + $maxposition=0; + + foreach ($pages as $key => $page) + if ($page['nav']==$nav) { + if (isset($previous)) + $positionhtml=qa_lang_html_sub('admin/after_x_tab', qa_html($passedself ? $page['title'] : $previous['title'])); + else + $positionhtml=qa_lang_html($langkey); + + if ($page['pageid']==@$editpage['pageid']) + $passedself=true; + + $maxposition=max($maxposition, $page['position']); + $positionoptions[$nav.$page['position']]=$positionhtml; + + $previous=$page; + } + + if ((!isset($editpage['pageid'])) || $nav!=@$editpage['nav']) { + $positionvalue=isset($previous) ? qa_lang_html_sub('admin/after_x_tab', qa_html($previous['title'])) : qa_lang_html($langkey); + $positionoptions[$nav.(isset($previous) ? (1+$maxposition) : 1)]=$positionvalue; + } + } + + $positionvalue=@$positionoptions[$editpage['nav'].$editpage['position']]; + + $permitoptions=qa_admin_permit_options(QA_PERMIT_ALL, QA_PERMIT_ADMINS, false, false); + $permitvalue=@$permitoptions[isset($inpermit) ? $inpermit : $editpage['permit']]; + + $qa_content['form']=array( + 'tags' => 'method="post" action="'.qa_path_html(qa_request()).'"', + + 'style' => 'tall', + + 'fields' => array( + 'name' => array( + 'tags' => 'name="name" id="name"', + 'label' => qa_lang_html($isexternal ? 'admin/link_name' : 'admin/page_name'), + 'value' => qa_html(isset($inname) ? $inname : @$editpage['title']), + 'error' => qa_html(@$errors['name']), + ), + + 'delete' => array( + 'tags' => 'name="dodelete" id="dodelete"', + 'label' => qa_lang_html($isexternal ? 'admin/delete_link' : 'admin/delete_page'), + 'value' => 0, + 'type' => 'checkbox', + ), + + 'position' => array( + 'id' => 'position_display', + 'tags' => 'name="position"', + 'label' => qa_lang_html('admin/position'), + 'type' => 'select', + 'options' => $positionoptions, + 'value' => $positionvalue, + ), + + 'permit' => array( + 'id' => 'permit_display', + 'tags' => 'name="permit"', + 'label' => qa_lang_html('admin/permit_to_view'), + 'type' => 'select', + 'options' => $permitoptions, + 'value' => $permitvalue, + ), + + 'slug' => array( + 'id' => 'slug_display', + 'tags' => 'name="slug"', + 'label' => qa_lang_html('admin/page_slug'), + 'value' => qa_html(isset($inslug) ? $inslug : @$editpage['tags']), + 'error' => qa_html(@$errors['slug']), + ), + + 'url' => array( + 'id' => 'url_display', + 'tags' => 'name="url"', + 'label' => qa_lang_html('admin/link_url'), + 'value' => qa_html(isset($inurl) ? $inurl : @$editpage['tags']), + 'error' => qa_html(@$errors['url']), + ), + + 'newwindow' => array( + 'id' => 'newwindow_display', + 'tags' => 'name="newwindow"', + 'label' => qa_lang_html('admin/link_new_window'), + 'value' => (isset($innewwindow) ? $innewwindow : (@$editpage['flags'] & QA_PAGE_FLAGS_NEW_WINDOW)) ? 1 : 0, + 'type' => 'checkbox', + ), + + 'heading' => array( + 'id' => 'heading_display', + 'tags' => 'name="heading"', + 'label' => qa_lang_html('admin/page_heading'), + 'value' => qa_html(isset($inheading) ? $inheading : @$editpage['heading']), + 'error' => qa_html(@$errors['heading']), + ), + + 'content' => array( + 'id' => 'content_display', + 'tags' => 'name="content"', + 'label' => qa_lang_html('admin/page_content_html'), + 'value' => qa_html(isset($incontent) ? $incontent : @$editpage['content']), + 'error' => qa_html(@$errors['content']), + 'rows' => 16, + ), + ), + + 'buttons' => array( + 'save' => array( + 'label' => qa_lang_html(isset($editpage['pageid']) ? 'main/save_button' : ($isexternal ? 'admin/add_link_button' : 'admin/add_page_button')), + ), + + 'saveview' => array( + 'tags' => 'name="dosaveview"', + 'label' => qa_lang_html('admin/save_view_button'), + ), + + 'cancel' => array( + 'tags' => 'name="docancel"', + 'label' => qa_lang_html('main/cancel_button'), + ), + ), + + 'hidden' => array( + 'dosavepage' => '1', // for IE + 'edit' => @$editpage['pageid'], + 'external' => (int)$isexternal, + 'code' => qa_get_form_security_code('admin/pages'), + ), + ); + + if ($isexternal) { + unset($qa_content['form']['fields']['slug']); + unset($qa_content['form']['fields']['heading']); + unset($qa_content['form']['fields']['content']); + + } else { + unset($qa_content['form']['fields']['url']); + unset($qa_content['form']['fields']['newwindow']); + } + + if (isset($editpage['pageid'])) + qa_set_display_rules($qa_content, array( + 'position_display' => '!dodelete', + 'permit_display' => '!dodelete', + ($isexternal ? 'url_display' : 'slug_display') => '!dodelete', + ($isexternal ? 'newwindow_display' : 'heading_display') => '!dodelete', + 'content_display' => '!dodelete', + )); + + else { + unset($qa_content['form']['fields']['slug']); + unset($qa_content['form']['fields']['delete']); + } + + if ($isexternal || !isset($editpage['pageid'])) + unset($qa_content['form']['buttons']['saveview']); + + $qa_content['focusid']='name'; + + } else { + + // List of standard navigation links + + $qa_content['form']=array( + 'tags' => 'method="post" action="'.qa_self_html().'"', + + 'style' => 'tall', + + 'fields' => array(), + + 'buttons' => array( + 'save' => array( + 'tags' => 'name="dosaveoptions"', + 'label' => qa_lang_html('main/save_button'), + ), + + 'addpage' => array( + 'tags' => 'name="doaddpage"', + 'label' => qa_lang_html('admin/add_page_button'), + ), + + 'addlink' => array( + 'tags' => 'name="doaddlink"', + 'label' => qa_lang_html('admin/add_link_button'), + ), + ), + + 'hidden' => array( + 'code' => qa_get_form_security_code('admin/pages'), + ), + ); + + $qa_content['form']['fields']['navlinks']=array( + 'label' => qa_lang_html('admin/nav_links_explanation'), + 'type' => 'static', + 'tight' => true, + ); + + foreach ($navoptions as $optionname => $langkey) { + $qa_content['form']['fields'][$optionname]=array( + 'label' => ''.qa_lang_html($langkey).'', + 'tags' => 'name="option_'.$optionname.'"', + 'type' => 'checkbox', + 'value' => qa_opt($optionname), + ); + } + + $qa_content['form']['fields'][]=array( + 'type' => 'blank' + ); + + // List of suggested plugin pages + + $listhtml=''; + + $pagemodules=qa_load_modules_with('page', 'suggest_requests'); + + foreach ($pagemodules as $tryname => $trypage) { + $suggestrequests=$trypage->suggest_requests(); + + foreach ($suggestrequests as $suggestrequest) { + $listhtml.='
  • '.qa_html($suggestrequest['title']).''; + + $listhtml.=qa_lang_html_sub('admin/plugin_module', qa_html($tryname)); + + $listhtml.=strtr(qa_lang_html('admin/add_link_link'), array( + '^1' => '', + '^2' => '', + )); + + if (method_exists($trypage, 'admin_form')) + $listhtml.=' - '.qa_lang_html('admin/options').''; + + $listhtml.='
  • '; + } + } + + if (strlen($listhtml)) + $qa_content['form']['fields']['plugins']=array( + 'label' => qa_lang_html('admin/plugin_pages_explanation'), + 'type' => 'custom', + 'html' => '', + ); + + // List of custom pages or links + + $listhtml=''; + + foreach ($pages as $page) { + $listhtml.='
  • '.qa_html($page['title']).''; + + $listhtml.=strtr(qa_lang_html(($page['flags'] & QA_PAGE_FLAGS_EXTERNAL) ? 'admin/edit_link' : 'admin/edit_page'), array( + '^1' => '', + '^2' => '', + )); + + $listhtml.='
  • '; + } + + $qa_content['form']['fields']['pages']=array( + 'label' => strlen($listhtml) ? qa_lang_html('admin/click_name_edit') : qa_lang_html('admin/pages_explanation'), + 'type' => 'custom', + 'html' => strlen($listhtml) ? '' : null, + ); + } + + $qa_content['navigation']['sub']=qa_admin_sub_navigation(); + + + return $qa_content; + + +/* + Omit PHP closing tag to help avoid accidental output +*/ \ No newline at end of file diff --git a/pages/admin/admin-plugins.php b/pages/admin/admin-plugins.php new file mode 100644 index 0000000..b493eea --- /dev/null +++ b/pages/admin/admin-plugins.php @@ -0,0 +1,230 @@ + $type, + 'name' => $name, + ); + } + } + } + + +// Prepare content for theme + + $qa_content = qa_content_prepare(); + + $qa_content['title'] = qa_lang_html('admin/admin_title') . ' - ' . qa_lang_html('admin/plugins_title'); + + $qa_content['error'] = qa_admin_page_error(); + + $qa_content['script_rel'][] = 'qa-content/qa-admin.js?'.QA_VERSION; + + $pluginfiles = glob(QA_PLUGIN_DIR.'*/qa-plugin.php'); + + foreach ($moduletypes as $type) { + $modules = qa_load_modules_with($type, 'init_queries'); + + foreach ($modules as $name => $module) { + $queries = $module->init_queries($tables); + + if (!empty($queries)) { + if (qa_is_http_post()) + qa_redirect('install'); + + else { + $qa_content['error'] = strtr(qa_lang_html('admin/module_x_database_init'), array( + '^1' => qa_html($name), + '^2' => qa_html($type), + '^3' => '', + '^4' => '', + )); + } + } + } + } + + if ( qa_is_http_post() && !qa_check_form_security_code('admin/plugins', qa_post_text('qa_form_security_code')) ) { + $qa_content['error'] = qa_lang_html('misc/form_security_reload'); + $showpluginforms = false; + } + else + $showpluginforms = true; + + if (!empty($pluginfiles)) { + $metadataUtil = new Q2A_Util_Metadata(); + $sortedPluginFiles = array(); + + foreach ($pluginfiles as $pluginFile) { + $metadata = $metadataUtil->fetchFromAddonPath(dirname($pluginFile)); + if (empty($metadata)) { + // limit plugin parsing to first 8kB + $contents = file_get_contents($pluginFile, false, null, -1, 8192); + $metadata = qa_addon_metadata($contents, 'Plugin'); + } + $metadata['name'] = isset($metadata['name']) && !empty($metadata['name']) + ? qa_html($metadata['name']) + : qa_lang_html('admin/unnamed_plugin') + ; + $sortedPluginFiles[$pluginFile] = $metadata; + } + + qa_sort_by($sortedPluginFiles, 'name'); + + $pluginIndex = -1; + foreach ($sortedPluginFiles as $pluginFile => $metadata) { + $pluginIndex++; + $plugindirectory = dirname($pluginFile); + $hash = qa_admin_plugin_directory_hash($plugindirectory); + $showthisform = $showpluginforms && (qa_get('show') == $hash); + + $namehtml = $metadata['name']; + + if (isset($metadata['uri']) && strlen($metadata['uri'])) + $namehtml = ''.$namehtml.''; + + $namehtml = ''.$namehtml.''; + + $metaver = isset($metadata['version']) && strlen($metadata['version']); + if ($metaver) + $namehtml .= ' v'.qa_html($metadata['version']); + + if (isset($metadata['author']) && strlen($metadata['author'])) { + $authorhtml = qa_html($metadata['author']); + + if (isset($metadata['author_uri']) && strlen($metadata['author_uri'])) + $authorhtml = ''.$authorhtml.''; + + $authorhtml = qa_lang_html_sub('main/by_x', $authorhtml); + + } + else + $authorhtml = ''; + + if ($metaver && isset($metadata['update_uri']) && strlen($metadata['update_uri'])) { + $elementid = 'version_check_'.md5($plugindirectory); + + $updatehtml = '(...)'; + + $qa_content['script_onloads'][] = array( + "qa_version_check(".qa_js($metadata['update_uri']).", ".qa_js($metadata['version'], true).", ".qa_js($elementid).");" + ); + + } + else + $updatehtml = ''; + + if (isset($metadata['description'])) + $deschtml = qa_html($metadata['description']); + else + $deschtml = ''; + + if (isset($pluginoptionmodules[$plugindirectory]) && !$showthisform) + $deschtml .= (strlen($deschtml) ? ' - ' : '').''.qa_lang_html('admin/options').''; + + $pluginhtml = $namehtml.' '.$authorhtml.' '.$updatehtml.'
    '.$deschtml.(strlen($deschtml) ? '
    ' : ''). + ''.qa_html($plugindirectory).'/'; + + if (qa_qa_version_below(@$metadata['min_q2a'])) + $pluginhtml = ''.$pluginhtml.'
    '. + qa_lang_html_sub('admin/requires_q2a_version', qa_html($metadata['min_q2a'])).''; + + elseif (qa_php_version_below(@$metadata['min_php'])) + $pluginhtml = ''.$pluginhtml.'
    '. + qa_lang_html_sub('admin/requires_php_version', qa_html($metadata['min_php'])).''; + + $qa_content['form_plugin_'.$pluginIndex] = array( + 'tags' => 'id="'.qa_html($hash).'"', + 'style' => 'tall', + 'fields' => array( + array( + 'type' => 'custom', + 'html' => $pluginhtml, + ) + ), + ); + + if ($showthisform && isset($pluginoptionmodules[$plugindirectory])) + foreach ($pluginoptionmodules[$plugindirectory] as $pluginoptionmodule) { + $type = $pluginoptionmodule['type']; + $name = $pluginoptionmodule['name']; + + $module = qa_load_module($type, $name); + + $form = $module->admin_form($qa_content); + + if (!isset($form['tags'])) + $form['tags'] = 'method="post" action="'.qa_admin_plugin_options_path($plugindirectory).'"'; + + if (!isset($form['style'])) + $form['style'] = 'tall'; + + $form['boxed'] = true; + + $form['hidden']['qa_form_security_code'] = qa_get_form_security_code('admin/plugins'); + + $qa_content['form_plugin_options'] = $form; + } + + } + } + + $qa_content['navigation']['sub'] = qa_admin_sub_navigation(); + + + return $qa_content; + + +/* + Omit PHP closing tag to help avoid accidental output +*/ \ No newline at end of file diff --git a/pages/admin/admin-points.php b/pages/admin/admin-points.php new file mode 100644 index 0000000..dba19b2 --- /dev/null +++ b/pages/admin/admin-points.php @@ -0,0 +1,187 @@ + 1)); + else + $recalculate=true; + } + } + + $options=qa_get_options($optionnames); + } + + +// Prepare content for theme + + $qa_content=qa_content_prepare(); + + $qa_content['title']=qa_lang_html('admin/admin_title').' - '.qa_lang_html('admin/points_title'); + $qa_content['error']=$securityexpired ? qa_lang_html('admin/form_security_expired') : qa_admin_page_error(); + + $qa_content['form']=array( + 'tags' => 'method="post" action="'.qa_self_html().'" name="points_form" onsubmit="document.forms.points_form.has_js.value=1; return true;"', + + 'style' => 'wide', + + 'buttons' => array( + 'saverecalc' => array( + 'tags' => 'id="dosaverecalc"', + 'label' => qa_lang_html('admin/save_recalc_button'), + ), + ), + + 'hidden' => array( + 'dosaverecalc' => '1', + 'has_js' => '0', + 'code' => qa_get_form_security_code('admin/points'), + ), + ); + + + if (qa_clicked('doshowdefaults')) { + $qa_content['form']['ok']=qa_lang_html('admin/points_defaults_shown'); + + $qa_content['form']['buttons']['cancel']=array( + 'tags' => 'name="docancel"', + 'label' => qa_lang_html('main/cancel_button'), + ); + + } else { + if ($recalculate) { + $qa_content['form']['ok']=''; + $qa_content['form']['hidden']['code_recalc']=qa_get_form_security_code('admin/recalc'); + + $qa_content['script_rel'][]='qa-content/qa-admin.js?'.QA_VERSION; + $qa_content['script_var']['qa_warning_recalc']=qa_lang('admin/stop_recalc_warning'); + + $qa_content['script_onloads'][]=array( + "qa_recalc_click('dorecalcpoints', document.getElementById('dosaverecalc'), null, 'recalc_ok');" + ); + } + + $qa_content['form']['buttons']['showdefaults']=array( + 'tags' => 'name="doshowdefaults"', + 'label' => qa_lang_html('admin/show_defaults_button'), + ); + } + + + foreach ($optionnames as $optionname) { + $optionfield=array( + 'label' => qa_lang_html('options/'.$optionname), + 'tags' => 'name="option_'.$optionname.'"', + 'value' => qa_html($options[$optionname]), + 'type' => 'number', + 'note' => qa_lang_html('admin/points'), + ); + + switch ($optionname) { + case 'points_multiple': + $prefix='×'; + unset($optionfield['note']); + break; + + case 'points_per_q_voted_up': + case 'points_per_a_voted_up': + case 'points_q_voted_max_gain': + case 'points_a_voted_max_gain': + $prefix='+'; + break; + + case 'points_per_q_voted_down': + case 'points_per_a_voted_down': + case 'points_q_voted_max_loss': + case 'points_a_voted_max_loss': + $prefix='–'; + break; + + case 'points_base': + $prefix='+'; + break; + + default: + $prefix='+'; // for even alignment + break; + } + + $optionfield['prefix']=''.$prefix.''; + + $qa_content['form']['fields'][$optionname]=$optionfield; + } + + qa_array_insert($qa_content['form']['fields'], 'points_post_a', array('blank0' => array('type' => 'blank'))); + qa_array_insert($qa_content['form']['fields'], 'points_vote_up_q', array('blank1' => array('type' => 'blank'))); + qa_array_insert($qa_content['form']['fields'], 'points_multiple', array('blank2' => array('type' => 'blank'))); + + + $qa_content['navigation']['sub']=qa_admin_sub_navigation(); + + + return $qa_content; + + +/* + Omit PHP closing tag to help avoid accidental output +*/ \ No newline at end of file diff --git a/pages/admin/admin-recalc.php b/pages/admin/admin-recalc.php new file mode 100644 index 0000000..aa77472 --- /dev/null +++ b/pages/admin/admin-recalc.php @@ -0,0 +1,137 @@ + + + + + + + + + +\n"; + + flush(); + sleep(1); // ... then rest for one + } + +?> + + + + + + + 'method="post" action="'.qa_self_html().'"', + + 'style' => 'wide', + + 'buttons' => array( + 'recalc' => array( + 'tags' => 'name="'.qa_html($state).'"', + 'label' => qa_lang_html('misc/form_security_again'), + ), + ), + + 'hidden' => array( + 'code' => qa_get_form_security_code('admin/recalc'), + ), + ); + + return $qa_content; + + } else { + require_once QA_INCLUDE_DIR.'app/format.php'; + + $qa_content=qa_content_prepare(); + + $qa_content['title']=qa_lang_html('admin/admin_title'); + $qa_content['error']=qa_lang_html('main/page_not_found'); + + return $qa_content; + } + + +/* + Omit PHP closing tag to help avoid accidental output +*/ \ No newline at end of file diff --git a/pages/admin/admin-stats.php b/pages/admin/admin-stats.php new file mode 100644 index 0000000..d135bdb --- /dev/null +++ b/pages/admin/admin-stats.php @@ -0,0 +1,281 @@ + 'wide', + + 'fields' => array( + 'q2a_version' => array( + 'label' => qa_lang_html('admin/q2a_version'), + 'value' => qa_html(QA_VERSION), + ), + + 'q2a_date' => array( + 'label' => qa_lang_html('admin/q2a_build_date'), + 'value' => qa_html(QA_BUILD_DATE), + ), + + 'q2a_latest' => array( + 'label' => qa_lang_html('admin/q2a_latest_version'), + 'type' => 'custom', + 'html' => '', + ), + + 'break0' => array( + 'type' => 'blank', + ), + + 'db_version' => array( + 'label' => qa_lang_html('admin/q2a_db_version'), + 'value' => qa_html(qa_opt('db_version')), + ), + + 'db_size' => array( + 'label' => qa_lang_html('admin/q2a_db_size'), + 'value' => qa_html(number_format(qa_db_table_size()/1048576, 1).' MB'), + ), + + 'break1' => array( + 'type' => 'blank', + ), + + 'php_version' => array( + 'label' => qa_lang_html('admin/php_version'), + 'value' => qa_html(phpversion()), + ), + + 'mysql_version' => array( + 'label' => qa_lang_html('admin/mysql_version'), + 'value' => qa_html(qa_db_mysql_version()), + ), + + 'break2' => array( + 'type' => 'blank', + ), + + 'qcount' => array( + 'label' => qa_lang_html('admin/total_qs'), + 'value' => qa_html(number_format($qcount)), + ), + + 'qcount_users' => array( + 'label' => qa_lang_html('admin/from_users'), + 'value' => qa_html(number_format($qcount-$qcount_anon)), + ), + + 'qcount_anon' => array( + 'label' => qa_lang_html('admin/from_anon'), + 'value' => qa_html(number_format($qcount_anon)), + ), + + 'break3' => array( + 'type' => 'blank', + ), + + 'acount' => array( + 'label' => qa_lang_html('admin/total_as'), + 'value' => qa_html(number_format($acount)), + ), + + 'acount_users' => array( + 'label' => qa_lang_html('admin/from_users'), + 'value' => qa_html(number_format($acount-$acount_anon)), + ), + + 'acount_anon' => array( + 'label' => qa_lang_html('admin/from_anon'), + 'value' => qa_html(number_format($acount_anon)), + ), + + 'break4' => array( + 'type' => 'blank', + ), + + 'ccount' => array( + 'label' => qa_lang_html('admin/total_cs'), + 'value' => qa_html(number_format($ccount)), + ), + + 'ccount_users' => array( + 'label' => qa_lang_html('admin/from_users'), + 'value' => qa_html(number_format($ccount-$ccount_anon)), + ), + + 'ccount_anon' => array( + 'label' => qa_lang_html('admin/from_anon'), + 'value' => qa_html(number_format($ccount_anon)), + ), + + 'break5' => array( + 'type' => 'blank', + ), + + 'users' => array( + 'label' => qa_lang_html('admin/users_registered'), + 'value' => QA_FINAL_EXTERNAL_USERS ? '' : qa_html(number_format(qa_db_count_users())), + ), + + 'users_active' => array( + 'label' => qa_lang_html('admin/users_active'), + 'value' => qa_html(number_format((int)qa_opt('cache_userpointscount'))), + ), + + 'users_posted' => array( + 'label' => qa_lang_html('admin/users_posted'), + 'value' => qa_html(number_format(qa_db_count_active_users('posts'))), + ), + + 'users_voted' => array( + 'label' => qa_lang_html('admin/users_voted'), + 'value' => qa_html(number_format(qa_db_count_active_users('uservotes'))), + ), + ), + ); + + if (QA_FINAL_EXTERNAL_USERS) + unset($qa_content['form']['fields']['users']); + else + unset($qa_content['form']['fields']['users_active']); + + foreach ($qa_content['form']['fields'] as $index => $field) + if (empty($field['type'])) + $qa_content['form']['fields'][$index]['type']='static'; + + $qa_content['form_2']=array( + 'tags' => 'method="post" action="'.qa_path_html('admin/recalc').'"', + + 'title' => qa_lang_html('admin/database_cleanup'), + + 'style' => 'basic', + + 'buttons' => array( + 'recount_posts' => array( + 'label' => qa_lang_html('admin/recount_posts'), + 'tags' => 'name="dorecountposts" onclick="return qa_recalc_click(this.name, this, '.qa_js(qa_lang_html('admin/recount_posts_stop')).', \'recount_posts_note\');"', + 'note' => ''.qa_lang_html('admin/recount_posts_note').'', + ), + + 'reindex_content' => array( + 'label' => qa_lang_html('admin/reindex_content'), + 'tags' => 'name="doreindexcontent" onclick="return qa_recalc_click(this.name, this, '.qa_js(qa_lang_html('admin/reindex_content_stop')).', \'reindex_content_note\');"', + 'note' => ''.qa_lang_html('admin/reindex_content_note').'', + ), + + 'recalc_points' => array( + 'label' => qa_lang_html('admin/recalc_points'), + 'tags' => 'name="dorecalcpoints" onclick="return qa_recalc_click(this.name, this, '.qa_js(qa_lang_html('admin/recalc_stop')).', \'recalc_points_note\');"', + 'note' => ''.qa_lang_html('admin/recalc_points_note').'', + ), + + 'refill_events' => array( + 'label' => qa_lang_html('admin/refill_events'), + 'tags' => 'name="dorefillevents" onclick="return qa_recalc_click(this.name, this, '.qa_js(qa_lang_html('admin/recalc_stop')).', \'refill_events_note\');"', + 'note' => ''.qa_lang_html('admin/refill_events_note').'', + ), + + 'recalc_categories' => array( + 'label' => qa_lang_html('admin/recalc_categories'), + 'tags' => 'name="dorecalccategories" onclick="return qa_recalc_click(this.name, this, '.qa_js(qa_lang_html('admin/recalc_stop')).', \'recalc_categories_note\');"', + 'note' => ''.qa_lang_html('admin/recalc_categories_note').'', + ), + + 'delete_hidden' => array( + 'label' => qa_lang_html('admin/delete_hidden'), + 'tags' => 'name="dodeletehidden" onclick="return qa_recalc_click(this.name, this, '.qa_js(qa_lang_html('admin/delete_stop')).', \'delete_hidden_note\');"', + 'note' => ''.qa_lang_html('admin/delete_hidden_note').'', + ), + ), + + 'hidden' => array( + 'code' => qa_get_form_security_code('admin/recalc'), + ), + ); + + if (!qa_using_categories()) + unset($qa_content['form_2']['buttons']['recalc_categories']); + + if (defined('QA_BLOBS_DIRECTORY')) { + if (qa_db_has_blobs_in_db()) + $qa_content['form_2']['buttons']['blobs_to_disk']=array( + 'label' => qa_lang_html('admin/blobs_to_disk'), + 'tags' => 'name="doblobstodisk" onclick="return qa_recalc_click(this.name, this, '.qa_js(qa_lang_html('admin/blobs_stop')).', \'blobs_to_disk_note\');"', + 'note' => ''.qa_lang_html('admin/blobs_to_disk_note').'', + ); + + if (qa_db_has_blobs_on_disk()) + $qa_content['form_2']['buttons']['blobs_to_db']=array( + 'label' => qa_lang_html('admin/blobs_to_db'), + 'tags' => 'name="doblobstodb" onclick="return qa_recalc_click(this.name, this, '.qa_js(qa_lang_html('admin/blobs_stop')).', \'blobs_to_db_note\');"', + 'note' => ''.qa_lang_html('admin/blobs_to_db_note').'', + ); + } + + + $qa_content['script_rel'][]='qa-content/qa-admin.js?'.QA_VERSION; + $qa_content['script_var']['qa_warning_recalc']=qa_lang('admin/stop_recalc_warning'); + + $qa_content['navigation']['sub']=qa_admin_sub_navigation(); + + + return $qa_content; + + +/* + Omit PHP closing tag to help avoid accidental output +*/ \ No newline at end of file diff --git a/pages/admin/admin-userfields.php b/pages/admin/admin-userfields.php new file mode 100644 index 0000000..66d19d7 --- /dev/null +++ b/pages/admin/admin-userfields.php @@ -0,0 +1,262 @@ +QA_DB_MAX_PROFILE_TITLE_LENGTH) + $errors['name']=qa_lang_sub('main/max_length_x', QA_DB_MAX_PROFILE_TITLE_LENGTH); + + // Perform appropriate database action + + if (isset($editfield['fieldid'])) { // changing existing user field + qa_db_userfield_set_fields($editfield['fieldid'], isset($errors['name']) ? $editfield['content'] : $inname, $inflags, $inpermit); + qa_db_userfield_move($editfield['fieldid'], $inposition); + + if (empty($errors)) + qa_redirect('admin/users'); + + else { + $userfields=qa_db_select_with_pending(qa_db_userfields_selectspec()); // reload after changes + foreach ($userfields as $userfield) + if ($userfield['fieldid']==$editfield['fieldid']) + $editfield=$userfield; + } + + } elseif (empty($errors)) { // creating a new user field + + for ($attempt=0; $attempt<1000; $attempt++) { + $suffix=$attempt ? ('-'.(1+$attempt)) : ''; + $newtag=qa_substr(implode('-', qa_string_to_words($inname)), 0, QA_DB_MAX_PROFILE_TITLE_LENGTH-strlen($suffix)).$suffix; + $uniquetag=true; + + foreach ($userfields as $userfield) + if (qa_strtolower(trim($newtag)) == qa_strtolower(trim($userfield['title']))) + $uniquetag=false; + + if ($uniquetag) { + $fieldid=qa_db_userfield_create($newtag, $inname, $inflags, $inpermit); + qa_db_userfield_move($fieldid, $inposition); + qa_redirect('admin/users'); + } + } + + qa_fatal_error('Could not create a unique database tag'); + } + } + } + } + + +// Prepare content for theme + + $qa_content=qa_content_prepare(); + + $qa_content['title']=qa_lang_html('admin/admin_title').' - '.qa_lang_html('admin/users_title'); + $qa_content['error']=$securityexpired ? qa_lang_html('admin/form_security_expired') : qa_admin_page_error(); + + $positionoptions=array(); + $previous=null; + $passedself=false; + + foreach ($userfields as $userfield) { + if (isset($previous)) + $positionhtml=qa_lang_html_sub('admin/after_x', qa_html(qa_user_userfield_label($passedself ? $userfield : $previous))); + else + $positionhtml=qa_lang_html('admin/first'); + + $positionoptions[$userfield['position']]=$positionhtml; + + if ($userfield['fieldid']==@$editfield['fieldid']) + $passedself=true; + + $previous=$userfield; + } + + if (isset($editfield['position'])) + $positionvalue=$positionoptions[$editfield['position']]; + else { + $positionvalue=isset($previous) ? qa_lang_html_sub('admin/after_x', qa_html(qa_user_userfield_label($previous))) : qa_lang_html('admin/first'); + $positionoptions[1+@max(array_keys($positionoptions))]=$positionvalue; + } + + $typeoptions=array( + 0 => qa_lang_html('admin/field_single_line'), + QA_FIELD_FLAGS_MULTI_LINE => qa_lang_html('admin/field_multi_line'), + QA_FIELD_FLAGS_LINK_URL => qa_lang_html('admin/field_link_url'), + ); + + $permitoptions=qa_admin_permit_options(QA_PERMIT_ALL, QA_PERMIT_ADMINS, false, false); + $permitvalue=@$permitoptions[isset($inpermit) ? $inpermit : $editfield['permit']]; + + $qa_content['form']=array( + 'tags' => 'method="post" action="'.qa_path_html(qa_request()).'"', + + 'style' => 'tall', + + 'fields' => array( + 'name' => array( + 'tags' => 'name="name" id="name"', + 'label' => qa_lang_html('admin/field_name'), + 'value' => qa_html(isset($inname) ? $inname : qa_user_userfield_label($editfield)), + 'error' => qa_html(@$errors['name']), + ), + + 'delete' => array( + 'tags' => 'name="dodelete" id="dodelete"', + 'label' => qa_lang_html('admin/delete_field'), + 'value' => 0, + 'type' => 'checkbox', + ), + + 'type' => array( + 'id' => 'type_display', + 'tags' => 'name="type"', + 'label' => qa_lang_html('admin/field_type'), + 'type' => 'select', + 'options' => $typeoptions, + 'value' => @$typeoptions[isset($intype) ? $intype : (@$editfield['flags']&(QA_FIELD_FLAGS_MULTI_LINE|QA_FIELD_FLAGS_LINK_URL))], + ), + + 'permit' => array( + 'id' => 'permit_display', + 'tags' => 'name="permit"', + 'label' => qa_lang_html('admin/permit_to_view'), + 'type' => 'select', + 'options' => $permitoptions, + 'value' => $permitvalue, + ), + + 'position' => array( + 'id' => 'position_display', + 'tags' => 'name="position"', + 'label' => qa_lang_html('admin/position'), + 'type' => 'select', + 'options' => $positionoptions, + 'value' => $positionvalue, + ), + + 'onregister' => array( + 'id' => 'register_display', + 'tags' => 'name="onregister"', + 'label' => qa_lang_html('admin/show_on_register_form'), + 'type' => 'checkbox', + 'value' => isset($inonregister) ? $inonregister : (@$editfield['flags']&QA_FIELD_FLAGS_ON_REGISTER), + ), + ), + + 'buttons' => array( + 'save' => array( + 'label' => qa_lang_html(isset($editfield['fieldid']) ? 'main/save_button' : ('admin/add_field_button')), + ), + + 'cancel' => array( + 'tags' => 'name="docancel"', + 'label' => qa_lang_html('main/cancel_button'), + ), + ), + + 'hidden' => array( + 'dosavefield' => '1', // for IE + 'edit' => @$editfield['fieldid'], + 'code' => qa_get_form_security_code('admin/userfields'), + ), + ); + + if (isset($editfield['fieldid'])) + qa_set_display_rules($qa_content, array( + 'type_display' => '!dodelete', + 'position_display' => '!dodelete', + 'register_display' => '!dodelete', + 'permit_display' => '!dodelete', + )); + else + unset($qa_content['form']['fields']['delete']); + + $qa_content['focusid']='name'; + + $qa_content['navigation']['sub']=qa_admin_sub_navigation(); + + + return $qa_content; + + +/* + Omit PHP closing tag to help avoid accidental output +*/ \ No newline at end of file diff --git a/pages/admin/admin-usertitles.php b/pages/admin/admin-usertitles.php new file mode 100644 index 0000000..17723ef --- /dev/null +++ b/pages/admin/admin-usertitles.php @@ -0,0 +1,185 @@ + $title) + $option.=(strlen($option) ? ',' : '').$points.' '.$title; + + qa_set_option('points_to_titles', $option); + + if (empty($errors)) + qa_redirect('admin/users'); + } + } + + +// Prepare content for theme + + $qa_content=qa_content_prepare(); + + $qa_content['title']=qa_lang_html('admin/admin_title').' - '.qa_lang_html('admin/users_title'); + $qa_content['error']=$securityexpired ? qa_lang_html('admin/form_security_expired') : qa_admin_page_error(); + + $qa_content['form']=array( + 'tags' => 'method="post" action="'.qa_path_html(qa_request()).'"', + + 'style' => 'tall', + + 'fields' => array( + 'title' => array( + 'tags' => 'name="title" id="title"', + 'label' => qa_lang_html('admin/user_title'), + 'value' => qa_html(isset($intitle) ? $intitle : @$pointstitle[$oldpoints]), + 'error' => qa_html(@$errors['title']), + ), + + 'delete' => array( + 'tags' => 'name="dodelete" id="dodelete"', + 'label' => qa_lang_html('admin/delete_title'), + 'value' => 0, + 'type' => 'checkbox', + ), + + 'points' => array( + 'id' => 'points_display', + 'tags' => 'name="points"', + 'label' => qa_lang_html('admin/points_required'), + 'type' => 'number', + 'value' => qa_html(isset($inpoints) ? $inpoints : @$oldpoints), + 'error' => qa_html(@$errors['points']), + ), + ), + + 'buttons' => array( + 'save' => array( + 'label' => qa_lang_html(isset($pointstitle[$oldpoints]) ? 'main/save_button' : ('admin/add_title_button')), + ), + + 'cancel' => array( + 'tags' => 'name="docancel"', + 'label' => qa_lang_html('main/cancel_button'), + ), + ), + + 'hidden' => array( + 'dosavetitle' => '1', // for IE + 'edit' => @$oldpoints, + 'code' => qa_get_form_security_code('admin/usertitles'), + ), + ); + + if (isset($pointstitle[$oldpoints])) + qa_set_display_rules($qa_content, array( + 'points_display' => '!dodelete', + )); + else + unset($qa_content['form']['fields']['delete']); + + $qa_content['focusid']='title'; + + $qa_content['navigation']['sub']=qa_admin_sub_navigation(); + + + return $qa_content; + + +/* + Omit PHP closing tag to help avoid accidental output +*/ \ No newline at end of file diff --git a/pages/admin/admin-widgets.php b/pages/admin/admin-widgets.php new file mode 100644 index 0000000..fddb7bc --- /dev/null +++ b/pages/admin/admin-widgets.php @@ -0,0 +1,333 @@ + qa_post_text('title')); + if (!isset($editwidget['title'])) + $editwidget['title']=qa_get('title'); + } + + $module=qa_load_module('widget', @$editwidget['title']); + + $widgetfound=isset($module); + + +// Check admin privileges (do late to allow one DB query) + + if (!qa_admin_check_privileges($qa_content)) + return $qa_content; + + +// Define an array of relevant templates we can use + + $templatelangkeys=array( + 'question' => 'admin/question_pages', + + 'qa' => 'main/recent_qs_as_title', + 'activity' => 'main/recent_activity_title', + 'questions' => 'admin/question_lists', + 'hot' => 'main/hot_qs_title', + 'unanswered' => 'main/unanswered_qs_title', + + 'tags' => 'main/popular_tags', + 'categories' => 'misc/browse_categories', + 'users' => 'main/highest_users', + 'ask' => 'question/ask_title', + + 'tag' => 'admin/tag_pages', + 'user' => 'admin/user_pages', + 'message' => 'misc/private_message_title', + + 'search' => 'main/search_title', + 'feedback' => 'misc/feedback_title', + + 'login' => 'users/login_title', + 'register' => 'users/register_title', + 'account' => 'profile/my_account_title', + 'favorites' => 'misc/my_favorites_title', + 'updates' => 'misc/recent_updates_title', + + 'ip' => 'admin/ip_address_pages', + 'admin' => 'admin/admin_title', + ); + + $templateoptions=array(); + + if (isset($module) && method_exists($module, 'allow_template')) { + foreach ($templatelangkeys as $template => $langkey) + if ($module->allow_template($template)) + $templateoptions[$template]=qa_lang_html($langkey); + + if ($module->allow_template('custom')) + foreach ($pages as $page) + if (!($page['flags']&QA_PAGE_FLAGS_EXTERNAL)) + $templateoptions['custom-'.$page['pageid']]=qa_html($page['title']); + } + + +// Process saving an old or new widget + + $securityexpired=false; + + if (qa_clicked('docancel')) + qa_redirect('admin/layout'); + + elseif (qa_clicked('dosavewidget')) { + require_once QA_INCLUDE_DIR.'db/admin.php'; + + if (!qa_check_form_security_code('admin/widgets', qa_post_text('code'))) + $securityexpired=true; + + else { + if (qa_post_text('dodelete')) { + qa_db_widget_delete($editwidget['widgetid']); + qa_redirect('admin/layout'); + + } else { + if ($widgetfound) { + $intitle=qa_post_text('title'); + $inposition=qa_post_text('position'); + $intemplates=array(); + + if (qa_post_text('template_all')) + $intemplates[]='all'; + + foreach (array_keys($templateoptions) as $template) + if (qa_post_text('template_'.$template)) + $intemplates[]=$template; + + $intags=implode(',', $intemplates); + + // Perform appropriate database action + + if (isset($editwidget['widgetid'])) { // changing existing widget + $widgetid=$editwidget['widgetid']; + qa_db_widget_set_fields($widgetid, $intags); + + } else + $widgetid=qa_db_widget_create($intitle, $intags); + + qa_db_widget_move($widgetid, substr($inposition, 0, 2), substr($inposition, 2)); + } + + qa_redirect('admin/layout'); + } + } + } + + +// Prepare content for theme + + $qa_content=qa_content_prepare(); + + $qa_content['title']=qa_lang_html('admin/admin_title').' - '.qa_lang_html('admin/layout_title'); + $qa_content['error']=$securityexpired ? qa_lang_html('admin/form_security_expired') : qa_admin_page_error(); + + $positionoptions=array(); + + $placeoptionhtml=qa_admin_place_options(); + + $regioncodes=array( + 'F' => 'full', + 'M' => 'main', + 'S' => 'side', + ); + + foreach ($placeoptionhtml as $place => $optionhtml) { + $region=$regioncodes[substr($place, 0, 1)]; + + $widgetallowed=method_exists($module, 'allow_region') && $module->allow_region($region); + + if ($widgetallowed) + foreach ($widgets as $widget) + if ( ($widget['place']==$place) && ($widget['title']==$editwidget['title']) && ($widget['widgetid']!==@$editwidget['widgetid']) ) + $widgetallowed=false; // don't allow two instances of same widget in same place + + if ($widgetallowed) { + $previous=null; + $passedself=false; + $maxposition=0; + + foreach ($widgets as $widget) + if ($widget['place']==$place) { + $positionhtml=$optionhtml; + + if (isset($previous)) + $positionhtml.=' - '.qa_lang_html_sub('admin/after_x', qa_html($passedself ? $widget['title'] : $previous['title'])); + + if ($widget['widgetid']==@$editwidget['widgetid']) + $passedself=true; + + $maxposition=max($maxposition, $widget['position']); + $positionoptions[$place.$widget['position']]=$positionhtml; + + $previous=$widget; + } + + if ((!isset($editwidget['widgetid'])) || $place!=@$editwidget['place']) { + $positionhtml=$optionhtml; + + if (isset($previous)) + $positionhtml.=' - '.qa_lang_html_sub('admin/after_x', $previous['title']); + + $positionoptions[$place.(isset($previous) ? (1+$maxposition) : 1)]=$positionhtml; + } + } + } + + $positionvalue=@$positionoptions[$editwidget['place'].$editwidget['position']]; + + $qa_content['form']=array( + 'tags' => 'method="post" action="'.qa_path_html(qa_request()).'"', + + 'style' => 'tall', + + 'fields' => array( + 'title' => array( + 'label' => qa_lang_html('admin/widget_name').'   '.qa_html($editwidget['title']), + 'type' => 'static', + 'tight' => true, + ), + + 'position' => array( + 'id' => 'position_display', + 'tags' => 'name="position"', + 'label' => qa_lang_html('admin/position'), + 'type' => 'select', + 'options' => $positionoptions, + 'value' => $positionvalue, + ), + + 'delete' => array( + 'tags' => 'name="dodelete" id="dodelete"', + 'label' => qa_lang_html('admin/delete_widget_position'), + 'value' => 0, + 'type' => 'checkbox', + ), + + 'all' => array( + 'id' => 'all_display', + 'label' => qa_lang_html('admin/widget_all_pages'), + 'type' => 'checkbox', + 'tags' => 'name="template_all" id="template_all"', + 'value' => is_numeric(strpos(','.@$editwidget['tags'].',', ',all,')), + ), + + 'templates' => array( + 'id' => 'templates_display', + 'label' => qa_lang_html('admin/widget_pages_explanation'), + 'type' => 'custom', + 'html' => '', + ), + ), + + 'buttons' => array( + 'save' => array( + 'label' => qa_lang_html(isset($editwidget['widgetid']) ? 'main/save_button' : ('admin/add_widget_button')), + ), + + 'cancel' => array( + 'tags' => 'name="docancel"', + 'label' => qa_lang_html('main/cancel_button'), + ), + ), + + 'hidden' => array( + 'dosavewidget' => '1', // for IE + 'edit' => @$editwidget['widgetid'], + 'title' => @$editwidget['title'], + 'code' => qa_get_form_security_code('admin/widgets'), + ), + ); + + foreach ($templateoptions as $template => $optionhtml) + $qa_content['form']['fields']['templates']['html'].= + ' '.$optionhtml.'
    '; + + if (isset($editwidget['widgetid'])) + qa_set_display_rules($qa_content, array( + 'templates_display' => '!(dodelete||template_all)', + 'all_display' => '!dodelete', + )); + + else { + unset($qa_content['form']['fields']['delete']); + qa_set_display_rules($qa_content, array( + 'templates_display' => '!template_all', + )); + } + + if (!$widgetfound) { + unset($qa_content['form']['fields']['title']['tight']); + $qa_content['form']['fields']['title']['error']=qa_lang_html('admin/widget_not_available'); + unset($qa_content['form']['fields']['position']); + unset($qa_content['form']['fields']['all']); + unset($qa_content['form']['fields']['templates']); + if (!isset($editwidget['widgetid'])) + unset($qa_content['form']['buttons']['save']); + + } elseif (!count($positionoptions)) { + unset($qa_content['form']['fields']['title']['tight']); + $qa_content['form']['fields']['title']['error']=qa_lang_html('admin/widget_no_positions'); + unset($qa_content['form']['fields']['position']); + unset($qa_content['form']['fields']['all']); + unset($qa_content['form']['fields']['templates']); + unset($qa_content['form']['buttons']['save']); + } + + $qa_content['navigation']['sub']=qa_admin_sub_navigation(); + + + return $qa_content; + + +/* + Omit PHP closing tag to help avoid accidental output +*/ \ No newline at end of file diff --git a/pages/answers.php b/pages/answers.php new file mode 100644 index 0000000..535531c --- /dev/null +++ b/pages/answers.php @@ -0,0 +1,80 @@ + $followpostid) : null); + break; + + case 'confirm': + $qa_content['error']=qa_insert_login_links(qa_lang_html('question/ask_must_confirm'), qa_request(), isset($followpostid) ? array('follow' => $followpostid) : null); + break; + + case 'limit': + $qa_content['error']=qa_lang_html('question/ask_limit'); + break; + + case 'approve': + $qa_content['error']=qa_lang_html('question/ask_must_be_approved'); + break; + + default: + $qa_content['error']=qa_lang_html('users/no_permission'); + break; + } + + return $qa_content; + } + + +// Process input + + $captchareason=qa_user_captcha_reason(); + + $in['title']=qa_post_text('title'); // allow title and tags to be posted by an external form + $in['extra']=qa_opt('extra_field_active') ? qa_post_text('extra') : null; + if (qa_using_tags()) + $in['tags']=qa_get_tags_field_value('tags'); + + if (qa_clicked('doask')) { + require_once QA_INCLUDE_DIR.'app/post-create.php'; + require_once QA_INCLUDE_DIR.'util/string.php'; + + $categoryids=array_keys(qa_category_path($categories, @$in['categoryid'])); + $userlevel=qa_user_level_for_categories($categoryids); + + $in['name']=qa_post_text('name'); + $in['notify'] = strlen(qa_post_text('notify')) > 0; + $in['email']=qa_post_text('email'); + $in['queued'] = qa_user_moderation_reason($userlevel) !== false; + + qa_get_post_content('editor', 'content', $in['editor'], $in['content'], $in['format'], $in['text']); + + $errors=array(); + + if (!qa_check_form_security_code('ask', qa_post_text('code'))) + $errors['page']=qa_lang_html('misc/form_security_again'); + + else { + $filtermodules=qa_load_modules_with('filter', 'filter_question'); + foreach ($filtermodules as $filtermodule) { + $oldin=$in; + $filtermodule->filter_question($in, $errors, null); + qa_update_post_text($in, $oldin); + } + + if (qa_using_categories() && count($categories) && (!qa_opt('allow_no_category')) && !isset($in['categoryid'])) + $errors['categoryid']=qa_lang_html('question/category_required'); // check this here because we need to know count($categories) + elseif (qa_user_permit_error('permit_post_q', null, $userlevel)) + $errors['categoryid']=qa_lang_html('question/category_ask_not_allowed'); + + if ($captchareason) { + require_once QA_INCLUDE_DIR.'app/captcha.php'; + qa_captcha_validate_post($errors); + } + + if (empty($errors)) { + $cookieid=isset($userid) ? qa_cookie_get() : qa_cookie_get_create(); // create a new cookie if necessary + + $questionid=qa_question_create($followanswer, $userid, qa_get_logged_in_handle(), $cookieid, + $in['title'], $in['content'], $in['format'], $in['text'], isset($in['tags']) ? qa_tags_to_tagstring($in['tags']) : '', + $in['notify'], $in['email'], $in['categoryid'], $in['extra'], $in['queued'], $in['name']); + + qa_redirect(qa_q_request($questionid, $in['title'])); // our work is done here + } + } + } + + +// Prepare content for theme + + $qa_content=qa_content_prepare(false, array_keys(qa_category_path($categories, @$in['categoryid']))); + + $qa_content['title']=qa_lang_html(isset($followanswer) ? 'question/ask_follow_title' : 'question/ask_title'); + $qa_content['error']=@$errors['page']; + + $editorname=isset($in['editor']) ? $in['editor'] : qa_opt('editor_for_qs'); + $editor=qa_load_editor(@$in['content'], @$in['format'], $editorname); + + $field=qa_editor_load_field($editor, $qa_content, @$in['content'], @$in['format'], 'content', 12, false); + $field['label']=qa_lang_html('question/q_content_label'); + $field['error']=qa_html(@$errors['content']); + + $custom=qa_opt('show_custom_ask') ? trim(qa_opt('custom_ask')) : ''; + + $qa_content['form']=array( + 'tags' => 'name="ask" method="post" action="'.qa_self_html().'"', + + 'style' => 'tall', + + 'fields' => array( + 'custom' => array( + 'type' => 'custom', + 'note' => $custom, + ), + + 'title' => array( + 'label' => qa_lang_html('question/q_title_label'), + 'tags' => 'name="title" id="title" autocomplete="off"', + 'value' => qa_html(@$in['title']), + 'error' => qa_html(@$errors['title']), + ), + + 'similar' => array( + 'type' => 'custom', + 'html' => '', + ), + + 'content' => $field, + ), + + 'buttons' => array( + 'ask' => array( + 'tags' => 'onclick="qa_show_waiting_after(this, false); '. + (method_exists($editor, 'update_script') ? $editor->update_script('content') : '').'"', + 'label' => qa_lang_html('question/ask_button'), + ), + ), + + 'hidden' => array( + 'editor' => qa_html($editorname), + 'code' => qa_get_form_security_code('ask'), + 'doask' => '1', + ), + ); + + if (!strlen($custom)) + unset($qa_content['form']['fields']['custom']); + + if (qa_opt('do_ask_check_qs') || qa_opt('do_example_tags')) { + $qa_content['script_rel'][]='qa-content/qa-ask.js?'.QA_VERSION; + $qa_content['form']['fields']['title']['tags'].=' onchange="qa_title_change(this.value);"'; + + if (strlen(@$in['title'])) + $qa_content['script_onloads'][]='qa_title_change('.qa_js($in['title']).');'; + } + + if (isset($followanswer)) { + $viewer=qa_load_viewer($followanswer['content'], $followanswer['format']); + + $field=array( + 'type' => 'static', + 'label' => qa_lang_html('question/ask_follow_from_a'), + 'value' => $viewer->get_html($followanswer['content'], $followanswer['format'], array('blockwordspreg' => qa_get_block_words_preg())), + ); + + qa_array_insert($qa_content['form']['fields'], 'title', array('follows' => $field)); + } + + if (qa_using_categories() && count($categories)) { + $field=array( + 'label' => qa_lang_html('question/q_category_label'), + 'error' => qa_html(@$errors['categoryid']), + ); + + qa_set_up_category_field($qa_content, $field, 'category', $categories, $in['categoryid'], true, qa_opt('allow_no_sub_category')); + + if (!qa_opt('allow_no_category')) // don't auto-select a category even though one is required + $field['options']['']=''; + + qa_array_insert($qa_content['form']['fields'], 'content', array('category' => $field)); + } + + if (qa_opt('extra_field_active')) { + $field=array( + 'label' => qa_html(qa_opt('extra_field_prompt')), + 'tags' => 'name="extra"', + 'value' => qa_html(@$in['extra']), + 'error' => qa_html(@$errors['extra']), + ); + + qa_array_insert($qa_content['form']['fields'], null, array('extra' => $field)); + } + + if (qa_using_tags()) { + $field=array( + 'error' => qa_html(@$errors['tags']), + ); + + qa_set_up_tag_field($qa_content, $field, 'tags', isset($in['tags']) ? $in['tags'] : array(), array(), + qa_opt('do_complete_tags') ? array_keys($completetags) : array(), qa_opt('page_size_ask_tags')); + + qa_array_insert($qa_content['form']['fields'], null, array('tags' => $field)); + } + + if (!isset($userid)) + qa_set_up_name_field($qa_content, $qa_content['form']['fields'], @$in['name']); + + qa_set_up_notify_fields($qa_content, $qa_content['form']['fields'], 'Q', qa_get_logged_in_email(), + isset($in['notify']) ? $in['notify'] : qa_opt('notify_users_default'), @$in['email'], @$errors['email']); + + if ($captchareason) { + require_once QA_INCLUDE_DIR.'app/captcha.php'; + qa_set_up_captcha_field($qa_content, $qa_content['form']['fields'], @$errors, qa_captcha_reason_note($captchareason)); + } + + $qa_content['focusid']='title'; + + + return $qa_content; + + +/* + Omit PHP closing tag to help avoid accidental output +*/ \ No newline at end of file diff --git a/pages/categories.php b/pages/categories.php new file mode 100644 index 0000000..966d483 --- /dev/null +++ b/pages/categories.php @@ -0,0 +1,118 @@ + $navlink) { + $category=$categories[$navlink['categoryid']]; + + if (!$category['childcount']) + unset($navigation[$key]['url']); + elseif ($navlink['selected']) { + $navigation[$key]['state']='open'; + $navigation[$key]['url']=qa_path_html('categories/'.qa_category_path_request($categories, $category['parentid'])); + } else + $navigation[$key]['state']='closed'; + + if (@$favoritemap[$navlink['categoryid']]) + $navigation[$key]['favorited']=true; + + $navigation[$key]['note']=''; + + $navigation[$key]['note'].= + ' - '.( ($category['qcount']==1) + ? qa_lang_html_sub('main/1_question', '1', '1') + : qa_lang_html_sub('main/x_questions', number_format($category['qcount'])) + ).''; + + if (strlen($category['content'])) + $navigation[$key]['note'].=qa_html(' - '.$category['content']); + + if (isset($navlink['subnav'])) + qa_category_nav_to_browse($navigation[$key]['subnav'], $categories, $categoryid, $favoritemap); + } + } + + +// Prepare content for theme + + $qa_content=qa_content_prepare(false, array_keys(qa_category_path($categories, $categoryid))); + + $qa_content['title']=qa_lang_html('misc/browse_categories'); + + if (count($categories)) { + $navigation=qa_category_navigation($categories, $categoryid, 'categories/', false); + + unset($navigation['all']); + + $favoritemap=array(); + if (isset($favoritecats)) + foreach ($favoritecats as $category) + $favoritemap[$category['categoryid']]=true; + + qa_category_nav_to_browse($navigation, $categories, $categoryid, $favoritemap); + + $qa_content['nav_list']=array( + 'nav' => $navigation, + 'type' => 'browse-cat', + ); + + } else { + $qa_content['title']=qa_lang_html('main/no_categories_found'); + $qa_content['suggest_next']=qa_html_suggest_qs_tags(qa_using_tags()); + } + + + return $qa_content; + + +/* + Omit PHP closing tag to help avoid accidental output +*/ \ No newline at end of file diff --git a/pages/comments.php b/pages/comments.php new file mode 100644 index 0000000..05c8808 --- /dev/null +++ b/pages/comments.php @@ -0,0 +1,79 @@ + '', + '^2' => '', + ) + ); + + } elseif (isset($loginuserid)) { // if logged in, allow sending a fresh link + require_once QA_INCLUDE_DIR.'util/string.php'; + + if (strlen($incode)) + $qa_content['error']=qa_lang_html('users/confirm_wrong_resend'); + + $email=qa_get_logged_in_email(); + + $qa_content['form']=array( + 'tags' => 'method="post" action="'.qa_path_html('confirm').'"', + + 'style' => 'tall', + + 'fields' => array( + 'email' => array( + 'label' => qa_lang_html('users/email_label'), + 'value' => qa_html($email).strtr(qa_lang_html('users/change_email_link'), array( + '^1' => '', + '^2' => '', + )), + 'type' => 'static', + ), + ), + + 'buttons' => array( + 'send' => array( + 'tags' => 'name="dosendconfirm"', + 'label' => qa_lang_html('users/send_confirm_button'), + ), + ), + + 'hidden' => array( + 'code' => qa_get_form_security_code('confirm'), + ), + ); + + if (!qa_email_validate($email)) { + $qa_content['error']=qa_lang_html('users/email_invalid'); + unset($qa_content['form']['buttons']['send']); + } + + } else + $qa_content['error']=qa_insert_login_links(qa_lang_html('users/confirm_wrong_log_in'), 'confirm'); + + + return $qa_content; + + +/* + Omit PHP closing tag to help avoid accidental output +*/ \ No newline at end of file diff --git a/pages/default.php b/pages/default.php new file mode 100644 index 0000000..c7462c8 --- /dev/null +++ b/pages/default.php @@ -0,0 +1,174 @@ +=QA_USER_LEVEL_ADMIN) { + $qa_content['navigation']['sub']=array( + 'admin/pages' => array( + 'label' => qa_lang('admin/edit_custom_page'), + 'url' => qa_path_html('admin/pages', array('edit' => $custompage['pageid'])), + ), + ); + } + + } else + $qa_content['error']=qa_lang_html('users/no_permission'); + + return $qa_content; + } + + +// Then, see if we should redirect because the 'qa' page is the same as the home page + + if ($explicitqa && (!qa_is_http_post()) && !qa_has_custom_home()) + qa_redirect(qa_category_path_request($categories, $categoryid), $_GET); + + +// Then, if there's a slug that matches no category, check page modules provided by plugins + + if ( (!$explicitqa) && $countslugs && !isset($categoryid) ) { + $pagemodules=qa_load_modules_with('page', 'match_request'); + $request=qa_request(); + + foreach ($pagemodules as $pagemodule) + if ($pagemodule->match_request($request)) { + qa_set_template('plugin'); + return $pagemodule->process_request($request); + } + } + + +// Then, check whether we are showing a custom home page + + if ( (!$explicitqa) && (!$countslugs) && qa_opt('show_custom_home') ) { + qa_set_template('custom'); + $qa_content=qa_content_prepare(); + $qa_content['title']=qa_html(qa_opt('custom_home_heading')); + if (qa_opt('show_home_description')) + $qa_content['description']=qa_html(qa_opt('home_description')); + $qa_content['custom']=qa_opt('custom_home_content'); + return $qa_content; + } + + +// If we got this far, it's a good old-fashioned Q&A listing page + + require_once QA_INCLUDE_DIR.'app/q-list.php'; + + qa_set_template('qa'); + $questions=qa_any_sort_and_dedupe(array_merge($questions1, $questions2)); + $pagesize=qa_opt('page_size_home'); + + if ($countslugs) { + if (!isset($categoryid)) + return include QA_INCLUDE_DIR.'qa-page-not-found.php'; + + $categorytitlehtml=qa_html($categories[$categoryid]['title']); + $sometitle=qa_lang_html_sub('main/recent_qs_as_in_x', $categorytitlehtml); + $nonetitle=qa_lang_html_sub('main/no_questions_in_x', $categorytitlehtml); + + } else { + $sometitle=qa_lang_html('main/recent_qs_as_title'); + $nonetitle=qa_lang_html('main/no_questions_found'); + } + + +// Prepare and return content for theme for Q&A listing page + + $qa_content=qa_q_list_page_content( + $questions, // questions + $pagesize, // questions per page + 0, // start offset + null, // total count (null to hide page links) + $sometitle, // title if some questions + $nonetitle, // title if no questions + $categories, // categories for navigation + $categoryid, // selected category id + true, // show question counts in category navigation + $explicitqa ? 'qa/' : '', // prefix for links in category navigation + qa_opt('feed_for_qa') ? 'qa' : null, // prefix for RSS feed paths (null to hide) + (count($questions)<$pagesize) // suggest what to do next + ? qa_html_suggest_ask($categoryid) + : qa_html_suggest_qs_tags(qa_using_tags(), qa_category_path_request($categories, $categoryid)), + null, // page link params + null // category nav params + ); + + if ( (!$explicitqa) && (!$countslugs) && qa_opt('show_home_description') ) + $qa_content['description']=qa_html(qa_opt('home_description')); + + + return $qa_content; + + +/* + Omit PHP closing tag to help avoid accidental output +*/ \ No newline at end of file diff --git a/pages/favorites-list.php b/pages/favorites-list.php new file mode 100644 index 0000000..8d244b9 --- /dev/null +++ b/pages/favorites-list.php @@ -0,0 +1,107 @@ + array( + 'page_opt' => 'page_size_qs', + 'fn_spec' => 'qa_db_user_favorite_qs_selectspec', + 'fn_view' => 'qa_favorite_q_list_view', + 'key' => 'q_list', + ), + 'users' => array( + 'page_opt' => 'page_size_users', + 'fn_spec' => 'qa_db_user_favorite_users_selectspec', + 'fn_view' => 'qa_favorite_users_view', + 'key' => 'ranking_users', + ), + 'tags' => array( + 'page_opt' => 'page_size_tags', + 'fn_spec' => 'qa_db_user_favorite_tags_selectspec', + 'fn_view' => 'qa_favorite_tags_view', + 'key' => 'ranking_tags', + ), + ); + + +// Check that we're logged in + + $userid = qa_get_logged_in_userid(); + + if (!isset($userid)) + qa_redirect('login'); + + +// Get lists of favorites of this type + + $favtype = qa_request_part(1); + $start = qa_get_start(); + + if (!array_key_exists($favtype, $favswitch) || ($favtype === 'users' && QA_FINAL_EXTERNAL_USERS)) + return include QA_INCLUDE_DIR.'qa-page-not-found.php'; + + extract($favswitch[$favtype]); // get switch variables + + $pagesize = qa_opt($page_opt); + list($totalItems, $items) = qa_db_select_with_pending( + qa_db_selectspec_count($fn_spec($userid)), + $fn_spec($userid, $pagesize, $start) + ); + + $count = $totalItems['count']; + $usershtml = qa_userids_handles_html($items); + + +// Prepare and return content for theme + + $qa_content = qa_content_prepare(true); + + $qa_content['title'] = qa_lang_html('misc/my_favorites_title'); + + $qa_content[$key] = $fn_view($items, $usershtml); + + +// Sub navigation for account pages and suggestion + + $qa_content['suggest_next'] = qa_lang_html_sub('misc/suggest_favorites_add', ' '); + + $qa_content['page_links'] = qa_html_page_links(qa_request(), $start, $pagesize, $count, qa_opt('pages_prev_next')); + + $qa_content['navigation']['sub'] = qa_user_sub_navigation(qa_get_logged_in_handle(), 'favorites', true); + + + return $qa_content; + + +/* + Omit PHP closing tag to help avoid accidental output +*/ \ No newline at end of file diff --git a/pages/favorites.php b/pages/favorites.php new file mode 100644 index 0000000..d7f80b5 --- /dev/null +++ b/pages/favorites.php @@ -0,0 +1,124 @@ + count($questions)) { + $url = qa_path_html('favorites/questions', array('start'=>$pagesize_qs)); + $qa_content['q_list']['footer'] = ''; + } + + +// Favorite users + + if (!QA_FINAL_EXTERNAL_USERS) { + $qa_content['ranking_users'] = qa_favorite_users_view($users, $usershtml); + $qa_content['ranking_users']['title'] = count($users) ? qa_lang_html('main/nav_users') : qa_lang_html('misc/no_favorite_users'); + if ($numUsers['count'] > count($users)) { + $url = qa_path_html('favorites/users', array('start'=>$pagesize_users)); + $qa_content['ranking_users']['footer'] = ''; + } + } + + +// Favorite tags + + if (qa_using_tags()) { + $qa_content['ranking_tags'] = qa_favorite_tags_view($tags); + $qa_content['ranking_tags']['title'] = count($tags) ? qa_lang_html('main/nav_tags') : qa_lang_html('misc/no_favorite_tags'); + if ($numTags['count'] > count($tags)) { + $url = qa_path_html('favorites/tags', array('start'=>$pagesize_tags)); + $qa_content['ranking_tags']['footer'] = ''; + } + } + + +// Favorite categories (no pagination) + + if (qa_using_categories()) { + $qa_content['nav_list_categories'] = qa_favorite_categories_view($categories); + $qa_content['nav_list_categories']['title'] = count($categories) ? qa_lang_html('main/nav_categories') : qa_lang_html('misc/no_favorite_categories'); + } + + +// Sub navigation for account pages and suggestion + + $qa_content['suggest_next'] = qa_lang_html_sub('misc/suggest_favorites_add', ' '); + + $qa_content['navigation']['sub'] = qa_user_sub_navigation(qa_get_logged_in_handle(), 'favorites', true); + + + return $qa_content; + + +/* + Omit PHP closing tag to help avoid accidental output +*/ \ No newline at end of file diff --git a/pages/feedback.php b/pages/feedback.php new file mode 100644 index 0000000..b560815 --- /dev/null +++ b/pages/feedback.php @@ -0,0 +1,185 @@ + $inmessage, + '^name' => empty($inname) ? '-' : $inname, + '^email' => empty($inemail) ? '-' : $inemail, + '^previous' => empty($inreferer) ? '-' : $inreferer, + '^url' => isset($userid) ? qa_path_absolute('user/'.qa_get_logged_in_handle()) : '-', + '^ip' => qa_remote_ip_address(), + '^browser' => @$_SERVER['HTTP_USER_AGENT'], + ); + + if (qa_send_email(array( + 'fromemail' => qa_email_validate(@$inemail) ? $inemail : qa_opt('from_email'), + 'fromname' => $inname, + 'toemail' => qa_opt('feedback_email'), + 'toname' => qa_opt('site_title'), + 'subject' => qa_lang_sub('emails/feedback_subject', qa_opt('site_title')), + 'body' => strtr(qa_lang('emails/feedback_body'), $subs), + 'html' => false, + ))) + $feedbacksent=true; + else + $pageerror=qa_lang_html('main/general_error'); + + qa_report_event('feedback', $userid, qa_get_logged_in_handle(), qa_cookie_get(), array( + 'email' => $inemail, + 'name' => $inname, + 'message' => $inmessage, + 'previous' => $inreferer, + 'browser' => @$_SERVER['HTTP_USER_AGENT'], + )); + } + } + } + + +// Prepare content for theme + + $qa_content=qa_content_prepare(); + + $qa_content['title']=qa_lang_html('misc/feedback_title'); + + $qa_content['error']=@$pageerror; + + $qa_content['form']=array( + 'tags' => 'method="post" action="'.qa_self_html().'"', + + 'style' => 'tall', + + 'fields' => array( + 'message' => array( + 'type' => $feedbacksent ? 'static' : '', + 'label' => qa_lang_html_sub('misc/feedback_message', qa_opt('site_title')), + 'tags' => 'name="message" id="message"', + 'value' => qa_html(@$inmessage), + 'rows' => 8, + 'error' => qa_html(@$errors['message']), + ), + + 'name' => array( + 'type' => $feedbacksent ? 'static' : '', + 'label' => qa_lang_html('misc/feedback_name'), + 'tags' => 'name="name"', + 'value' => qa_html(isset($inname) ? $inname : @$userprofile['name']), + ), + + 'email' => array( + 'type' => $feedbacksent ? 'static' : '', + 'label' => qa_lang_html('misc/feedback_email'), + 'tags' => 'name="email"', + 'value' => qa_html(isset($inemail) ? $inemail : qa_get_logged_in_email()), + 'note' => $feedbacksent ? null : qa_opt('email_privacy'), + ), + ), + + 'buttons' => array( + 'send' => array( + 'label' => qa_lang_html('main/send_button'), + ), + ), + + 'hidden' => array( + 'dofeedback' => '1', + 'code' => qa_get_form_security_code('feedback'), + 'referer' => qa_html(isset($inreferer) ? $inreferer : @$_SERVER['HTTP_REFERER']), + ), + ); + + if ($usecaptcha && !$feedbacksent) + qa_set_up_captcha_field($qa_content, $qa_content['form']['fields'], @$errors); + + + $qa_content['focusid']='message'; + + if ($feedbacksent) { + $qa_content['form']['ok']=qa_lang_html('misc/feedback_sent'); + unset($qa_content['form']['buttons']); + } + + + return $qa_content; + + +/* + Omit PHP closing tag to help avoid accidental output +*/ \ No newline at end of file diff --git a/pages/forgot.php b/pages/forgot.php new file mode 100644 index 0000000..bb6a0ef --- /dev/null +++ b/pages/forgot.php @@ -0,0 +1,125 @@ + $inemailhandle) : null); // redirect to page where code is entered + } + } + + } else + $inemailhandle=qa_get('e'); + + +// Prepare content for theme + + $qa_content=qa_content_prepare(); + + $qa_content['title']=qa_lang_html('users/reset_title'); + $qa_content['error']=@$errors['page']; + + $qa_content['form']=array( + 'tags' => 'method="post" action="'.qa_self_html().'"', + + 'style' => 'tall', + + 'fields' => array( + 'email_handle' => array( + 'label' => qa_lang_html('users/email_handle_label'), + 'tags' => 'name="emailhandle" id="emailhandle"', + 'value' => qa_html(@$inemailhandle), + 'error' => qa_html(@$errors['emailhandle']), + 'note' => qa_lang_html('users/send_reset_note'), + ), + ), + + 'buttons' => array( + 'send' => array( + 'label' => qa_lang_html('users/send_reset_button'), + ), + ), + + 'hidden' => array( + 'doforgot' => '1', + 'code' => qa_get_form_security_code('forgot'), + ), + ); + + if (qa_opt('captcha_on_reset_password')) + qa_set_up_captcha_field($qa_content, $qa_content['form']['fields'], @$errors); + + $qa_content['focusid']='emailhandle'; + + + return $qa_content; + + +/* + Omit PHP closing tag to help avoid accidental output +*/ \ No newline at end of file diff --git a/pages/hot.php b/pages/hot.php new file mode 100644 index 0000000..34f19b4 --- /dev/null +++ b/pages/hot.php @@ -0,0 +1,80 @@ +=QA_USER_LEVEL_MODERATOR; // allow moderator in one category to block across all categories + + +// Perform blocking or unblocking operations as appropriate + + if (qa_clicked('doblock') || qa_clicked('dounblock') || qa_clicked('dohideall')) { + if (!qa_check_form_security_code('ip-'.$ip, qa_post_text('code'))) + $pageerror=qa_lang_html('misc/form_security_again'); + + elseif ($blockable) { + + if (qa_clicked('doblock')) { + $oldblocked=qa_opt('block_ips_write'); + qa_set_option('block_ips_write', (strlen($oldblocked) ? ($oldblocked.' , ') : '').$ip); + + qa_report_event('ip_block', $userid, qa_get_logged_in_handle(), qa_cookie_get(), array( + 'ip' => $ip, + )); + + qa_redirect(qa_request()); + } + + if (qa_clicked('dounblock')) { + require_once QA_INCLUDE_DIR.'app/limits.php'; + + $blockipclauses=qa_block_ips_explode(qa_opt('block_ips_write')); + + foreach ($blockipclauses as $key => $blockipclause) + if (qa_block_ip_match($ip, $blockipclause)) + unset($blockipclauses[$key]); + + qa_set_option('block_ips_write', implode(' , ', $blockipclauses)); + + qa_report_event('ip_unblock', $userid, qa_get_logged_in_handle(), qa_cookie_get(), array( + 'ip' => $ip, + )); + + qa_redirect(qa_request()); + } + + if (qa_clicked('dohideall') && !qa_user_maximum_permit_error('permit_hide_show')) { + // allow moderator in one category to hide posts across all categories if they are identified via IP page + + require_once QA_INCLUDE_DIR.'db/admin.php'; + require_once QA_INCLUDE_DIR.'app/posts.php'; + + $postids=qa_db_get_ip_visible_postids($ip); + + foreach ($postids as $postid) + qa_post_set_hidden($postid, true, $userid); + + qa_redirect(qa_request()); + } + } + } + + +// Combine sets of questions and get information for users + + $questions=qa_any_sort_by_date(array_merge($qs, $qs_queued, $qs_hidden, $a_qs, $a_queued_qs, $a_hidden_qs, $c_qs, $c_queued_qs, $c_hidden_qs, $edit_qs)); + + $usershtml=qa_userids_handles_html(qa_any_get_userids_handles($questions)); + + $hostname=gethostbyaddr($ip); + + +// Prepare content for theme + + $qa_content=qa_content_prepare(); + + $qa_content['title']=qa_lang_html_sub('main/ip_address_x', qa_html($ip)); + $qa_content['error']=@$pageerror; + + $qa_content['form']=array( + 'tags' => 'method="post" action="'.qa_self_html().'"', + + 'style' => 'wide', + + 'fields' => array( + 'host' => array( + 'type' => 'static', + 'label' => qa_lang_html('misc/host_name'), + 'value' => qa_html($hostname), + ), + ), + + 'hidden' => array( + 'code' => qa_get_form_security_code('ip-'.$ip), + ), + ); + + + if ($blockable) { + require_once QA_INCLUDE_DIR.'app/limits.php'; + + $blockipclauses=qa_block_ips_explode(qa_opt('block_ips_write')); + $matchclauses=array(); + + foreach ($blockipclauses as $blockipclause) + if (qa_block_ip_match($ip, $blockipclause)) + $matchclauses[]=$blockipclause; + + if (count($matchclauses)) { + $qa_content['form']['fields']['status']=array( + 'type' => 'static', + 'label' => qa_lang_html('misc/matches_blocked_ips'), + 'value' => qa_html(implode("\n", $matchclauses), true), + ); + + $qa_content['form']['buttons']['unblock']=array( + 'tags' => 'name="dounblock"', + 'label' => qa_lang_html('misc/unblock_ip_button'), + ); + + if (count($questions) && !qa_user_maximum_permit_error('permit_hide_show')) + $qa_content['form']['buttons']['hideall']=array( + 'tags' => 'name="dohideall" onclick="qa_show_waiting_after(this, false);"', + 'label' => qa_lang_html('misc/hide_all_ip_button'), + ); + + } else + $qa_content['form']['buttons']['block']=array( + 'tags' => 'name="doblock"', + 'label' => qa_lang_html('misc/block_ip_button'), + ); + } + + + $qa_content['q_list']['qs']=array(); + + if (count($questions)) { + $qa_content['q_list']['title']=qa_lang_html_sub('misc/recent_activity_from_x', qa_html($ip)); + + foreach ($questions as $question) { + $htmloptions=qa_post_html_options($question); + $htmloptions['tagsview']=false; + $htmloptions['voteview']=false; + $htmloptions['ipview']=false; + $htmloptions['answersview']=false; + $htmloptions['viewsview']=false; + $htmloptions['updateview']=false; + + $htmlfields=qa_any_to_q_html_fields($question, $userid, qa_cookie_get(), $usershtml, null, $htmloptions); + + if (isset($htmlfields['what_url'])) // link directly to relevant content + $htmlfields['url']=$htmlfields['what_url']; + + $hasother=isset($question['opostid']); + + if ($question[$hasother ? 'ohidden' : 'hidden'] && !isset($question[$hasother ? 'oupdatetype' : 'updatetype'])) { + $htmlfields['what_2']=qa_lang_html('main/hidden'); + + if (@$htmloptions['whenview']) { + $updated=@$question[$hasother ? 'oupdated' : 'updated']; + if (isset($updated)) + $htmlfields['when_2']=qa_when_to_html($updated, @$htmloptions['fulldatedays']); + } + } + + $qa_content['q_list']['qs'][]=$htmlfields; + } + + } else + $qa_content['q_list']['title']=qa_lang_html_sub('misc/no_activity_from_x', qa_html($ip)); + + + return $qa_content; + + +/* + Omit PHP closing tag to help avoid accidental output +*/ \ No newline at end of file diff --git a/pages/login.php b/pages/login.php new file mode 100644 index 0000000..237519c --- /dev/null +++ b/pages/login.php @@ -0,0 +1,177 @@ + $inemailhandle)); + + $forgothtml=''.qa_lang_html('users/forgot_link').''; + + $qa_content['form']=array( + 'tags' => 'method="post" action="'.qa_self_html().'"', + + 'style' => 'tall', + + 'ok' => $passwordsent ? qa_lang_html('users/password_sent') : ($emailexists ? qa_lang_html('users/email_exists') : null), + + 'fields' => array( + 'email_handle' => array( + 'label' => qa_opt('allow_login_email_only') ? qa_lang_html('users/email_label') : qa_lang_html('users/email_handle_label'), + 'tags' => 'name="emailhandle" id="emailhandle"', + 'value' => qa_html(@$inemailhandle), + 'error' => qa_html(@$errors['emailhandle']), + ), + + 'password' => array( + 'type' => 'password', + 'label' => qa_lang_html('users/password_label'), + 'tags' => 'name="password" id="password"', + 'value' => qa_html(@$inpassword), + 'error' => empty($errors['password']) ? '' : (qa_html(@$errors['password']).' - '.$forgothtml), + 'note' => $passwordsent ? qa_lang_html('users/password_sent') : $forgothtml, + ), + + 'remember' => array( + 'type' => 'checkbox', + 'label' => qa_lang_html('users/remember_label'), + 'tags' => 'name="remember"', + 'value' => !empty($inremember), + ), + ), + + 'buttons' => array( + 'login' => array( + 'label' => qa_lang_html('users/login_button'), + ), + ), + + 'hidden' => array( + 'dologin' => '1', + 'code' => qa_get_form_security_code('login'), + ), + ); + + $loginmodules=qa_load_modules_with('login', 'login_html'); + + foreach ($loginmodules as $module) { + ob_start(); + $module->login_html(qa_opt('site_url').qa_get('to'), 'login'); + $html=ob_get_clean(); + + if (strlen($html)) + @$qa_content['custom'].='
    '.$html.'
    '; + } + + $qa_content['focusid']=(isset($inemailhandle) && !isset($errors['emailhandle'])) ? 'password' : 'emailhandle'; + + + return $qa_content; + + +/* + Omit PHP closing tag to help avoid accidental output +*/ \ No newline at end of file diff --git a/pages/logout.php b/pages/logout.php new file mode 100644 index 0000000..96756bd --- /dev/null +++ b/pages/logout.php @@ -0,0 +1,40 @@ + $fromhandle, + '^url' => qa_path_absolute($canreply ? ('message/'.$fromhandle) : ('user/'.$fromhandle)), + )); + + $subs = array( + '^message' => $inmessage, + '^f_handle' => $fromhandle, + '^f_url' => qa_path_absolute('user/'.$fromhandle), + '^more' => $more, + '^a_url' => qa_path_absolute('account'), + ); + + if (qa_send_notification($toaccount['userid'], $toaccount['email'], $toaccount['handle'], + qa_lang('emails/private_message_subject'), qa_lang('emails/private_message_body'), $subs)) + $messagesent = true; + + qa_report_event('u_message', $loginuserid, qa_get_logged_in_handle(), qa_cookie_get(), array( + 'userid' => $toaccount['userid'], + 'handle' => $toaccount['handle'], + 'messageid' => $messageid, + 'message' => $inmessage, + )); + + // show message as part of general history + if (qa_opt('show_message_history')) + qa_redirect(qa_request(), array('state' => ($messagesent ? 'message-sent' : 'email-error'))); + } + } + } + + +// Prepare content for theme + + $hideForm = !empty($pageerror) || $messagesent; + + $qa_content['title'] = qa_lang_html('misc/private_message_title'); + + $qa_content['error'] = @$pageerror; + + $qa_content['form_message'] = array( + 'tags' => 'method="post" action="'.qa_self_html().'"', + + 'style' => 'tall', + + 'ok' => $messagesent ? qa_lang_html('misc/message_sent') : null, + + 'fields' => array( + 'message' => array( + 'type' => $hideForm ? 'static' : '', + 'label' => qa_lang_html_sub('misc/message_for_x', qa_get_one_user_html($handle, false)), + 'tags' => 'name="message" id="message"', + 'value' => qa_html(@$inmessage, $messagesent), + 'rows' => 8, + 'note' => qa_lang_html_sub('misc/message_explanation', qa_html(qa_opt('site_title'))), + 'error' => qa_html(@$errors['message']), + ), + ), + + 'buttons' => array( + 'send' => array( + 'tags' => 'onclick="qa_show_waiting_after(this, false);"', + 'label' => qa_lang_html('main/send_button'), + ), + ), + + 'hidden' => array( + 'domessage' => '1', + 'code' => qa_get_form_security_code('message-'.$handle), + ), + ); + + $qa_content['focusid'] = 'message'; + + if ($hideForm) { + unset($qa_content['form_message']['buttons']); + + if (qa_opt('show_message_history')) + unset($qa_content['form_message']['fields']['message']); + else { + unset($qa_content['form_message']['fields']['message']['note']); + unset($qa_content['form_message']['fields']['message']['label']); + } + } + + +// If relevant, show recent message history + + if (qa_opt('show_message_history')) { + $recent = array_merge($torecent, $fromrecent); + + qa_sort_by($recent, 'created'); + + $showmessages = array_slice(array_reverse($recent, true), 0, QA_DB_RETRIEVE_MESSAGES); + + if (count($showmessages)) { + $qa_content['message_list'] = array( + 'title' => qa_lang_html_sub('misc/message_recent_history', qa_html($toaccount['handle'])), + ); + + $options = qa_message_html_defaults(); + + foreach ($showmessages as $message) + $qa_content['message_list']['messages'][] = qa_message_html_fields($message, $options); + } + + $qa_content['navigation']['sub'] = qa_messages_sub_navigation(); + } + + + $qa_content['raw']['account'] = $toaccount; // for plugin layers to access + + return $qa_content; + + +/* + Omit PHP closing tag to help avoid accidental output +*/ \ No newline at end of file diff --git a/pages/messages.php b/pages/messages.php new file mode 100644 index 0000000..8b8ea16 --- /dev/null +++ b/pages/messages.php @@ -0,0 +1,125 @@ + 'id="privatemessages"', + 'messages' => array(), + 'form' => array( + 'tags' => 'name="pmessage" method="post" action="'.qa_self_html().'"', + 'style' => 'tall', + 'hidden' => array( + 'qa_click' => '', // for simulating clicks in Javascript + 'handle' => qa_html($loginUserHandle), + 'start' => qa_html($start), + 'code' => qa_get_form_security_code('pm-'.$loginUserHandle), + ), + ), + ); + + $htmlDefaults = qa_message_html_defaults(); + if ($showOutbox) + $htmlDefaults['towhomview'] = true; + + foreach ($userMessages as $message) { + $msgFormat = qa_message_html_fields($message, $htmlDefaults); + $replyHandle = $showOutbox ? $message['tohandle'] : $message['fromhandle']; + + $msgFormat['form'] = array( + 'style' => 'light', + 'buttons' => array( + 'reply' => array( + 'tags' => 'onclick="window.location.href=\''.qa_path_html('message/'.$replyHandle).'\';return false"', + 'label' => qa_lang_html('question/reply_button'), + ), + 'delete' => array( + 'tags' => 'name="m'.qa_html($message['messageid']).'_dodelete" onclick="return qa_pm_click('.qa_js($message['messageid']).', this, '.qa_js($showOutbox ? 'outbox' : 'inbox').');"', + 'label' => qa_lang_html('question/delete_button'), + 'popup' => qa_lang_html('profile/delete_pm_popup'), + ), + ), + ); + + $qa_content['message_list']['messages'][] = $msgFormat; + } + + $qa_content['page_links'] = qa_html_page_links(qa_request(), $start, $pagesize, $count, qa_opt('pages_prev_next')); + + $qa_content['navigation']['sub'] = qa_messages_sub_navigation($showOutbox ? 'outbox' : 'inbox'); + + return $qa_content; diff --git a/pages/question-post.php b/pages/question-post.php new file mode 100644 index 0000000..b02c573 --- /dev/null +++ b/pages/question-post.php @@ -0,0 +1,1025 @@ + $answer) { + $prefix='a'.$answerid.'_'; + + if (qa_page_q_single_click_a($answer, $question, $answers, $commentsfollows, true, $pageerror)) + qa_page_q_refresh($pagestart, null, 'A', $answerid); + + if ($answer['editbutton']) { + if (qa_clicked($prefix.'doedit')) + qa_page_q_refresh($pagestart, 'edit-'.$answerid); + + elseif (qa_clicked($prefix.'dosave') && qa_page_q_permit_edit($answer, 'permit_edit_a', $pageerror)) { + $editedtype=qa_page_q_edit_a_submit($answer, $question, $answers, $commentsfollows, $aeditin[$answerid], $aediterrors[$answerid]); + + if (isset($editedtype)) + qa_page_q_refresh($pagestart, null, $editedtype, $answerid); + + else { + $formtype='a_edit'; + $formpostid=$answerid; // keep editing if an error + } + + } elseif (($pagestate==('edit-'.$answerid)) && qa_page_q_permit_edit($answer, 'permit_edit_a', $pageerror)) { + $formtype='a_edit'; + $formpostid=$answerid; + } + } + + if ($answer['commentbutton']) { + if (qa_clicked($prefix.'docomment')) + qa_page_q_refresh($pagestart, 'comment-'.$answerid, 'A', $answerid); + + if (qa_clicked('c'.$answerid.'_doadd') || ($pagestate==('comment-'.$answerid))) + qa_page_q_do_comment($question, $answer, $commentsfollows, $pagestart, $usecaptcha, $cnewin, $cnewerrors, $formtype, $formpostid, $pageerror); + } + + if (qa_clicked($prefix.'dofollow')) { + $params=array('follow' => $answerid); + if (isset($question['categoryid'])) + $params['cat']=$question['categoryid']; + + qa_redirect('ask', $params); + } + } + + +// Process hide, show, delete, flag, unflag, edit or save button for comments + + foreach ($commentsfollows as $commentid => $comment) { + if ($comment['basetype'] == 'C') { + $cparentid = $comment['parentid']; + $commentparent = isset($answers[$cparentid]) ? $answers[$cparentid] : $question; + $prefix = 'c'.$commentid.'_'; + + if (qa_page_q_single_click_c($comment, $question, $commentparent, $pageerror)) + qa_page_q_refresh($pagestart, 'showcomments-'.$cparentid, $commentparent['basetype'], $cparentid); + + if ($comment['editbutton']) { + if (qa_clicked($prefix.'doedit')) { + if (qa_page_q_permit_edit($comment, 'permit_edit_c', $pageerror)) // extra check here ensures error message is visible + qa_page_q_refresh($pagestart, 'edit-'.$commentid, 'C', $commentid); + } + elseif (qa_clicked($prefix.'dosave') && qa_page_q_permit_edit($comment, 'permit_edit_c', $pageerror)) { + if (qa_page_q_edit_c_submit($comment, $question, $commentparent, $ceditin[$commentid], $cediterrors[$commentid])) + qa_page_q_refresh($pagestart, null, 'C', $commentid); + else { + $formtype = 'c_edit'; + $formpostid = $commentid; // keep editing if an error + } + } + elseif (($pagestate == ('edit-'.$commentid)) && qa_page_q_permit_edit($comment, 'permit_edit_c', $pageerror)) { + $formtype = 'c_edit'; + $formpostid = $commentid; + } + } + } + } + + +// Functions used above - also see functions in qa-page-question-submit.php (which are shared with Ajax) + + function qa_page_q_refresh($start=0, $state=null, $showtype=null, $showid=null) +/* + Redirects back to the question page, with the specified parameters +*/ + { + $params=array(); + + if ($start>0) + $params['start']=$start; + if (isset($state)) + $params['state']=$state; + + if (isset($showtype) && isset($showid)) { + $anchor=qa_anchor($showtype, $showid); + $params['show']=$showid; + } else + $anchor=null; + + qa_redirect(qa_request(), $params, null, null, $anchor); + } + + + function qa_page_q_permit_edit($post, $permitoption, &$error, $permitoption2=null) +/* + Returns whether the editing operation (as specified by $permitoption or $permitoption2) on $post is permitted. + If not, sets the $error variable appropriately +*/ + { + // The 'login', 'confirm', 'userblock', 'ipblock' permission errors are reported to the user here + // The other options ('approve', 'level') prevent the edit button being shown, in qa_page_q_post_rules(...) + + $permiterror=qa_user_post_permit_error($post['isbyuser'] ? null : $permitoption, $post); + // if it's by the user, this will only check whether they are blocked + + if ($permiterror && isset($permitoption2)) { + $permiterror2=qa_user_post_permit_error($post['isbyuser'] ? null : $permitoption2, $post); + + if ( ($permiterror=='level') || ($permiterror=='approve') || (!$permiterror2) ) // if it's a less strict error + $permiterror=$permiterror2; + } + + switch ($permiterror) { + case 'login': + $error=qa_insert_login_links(qa_lang_html('question/edit_must_login'), qa_request()); + break; + + case 'confirm': + $error=qa_insert_login_links(qa_lang_html('question/edit_must_confirm'), qa_request()); + break; + + default: + $error=qa_lang_html('users/no_permission'); + break; + + case false: + break; + } + + return !$permiterror; + } + + + function qa_page_q_edit_q_form(&$qa_content, $question, $in, $errors, $completetags, $categories) +/* + Returns a $qa_content form for editing the question and sets up other parts of $qa_content accordingly +*/ + { + $form=array( + 'tags' => 'method="post" action="'.qa_self_html().'"', + + 'style' => 'tall', + + 'fields' => array( + 'title' => array( + 'type' => $question['editable'] ? 'text' : 'static', + 'label' => qa_lang_html('question/q_title_label'), + 'tags' => 'name="q_title"', + 'value' => qa_html(($question['editable'] && isset($in['title'])) ? $in['title'] : $question['title']), + 'error' => qa_html(@$errors['title']), + ), + + 'category' => array( + 'label' => qa_lang_html('question/q_category_label'), + 'error' => qa_html(@$errors['categoryid']), + ), + + 'content' => array( + 'label' => qa_lang_html('question/q_content_label'), + 'error' => qa_html(@$errors['content']), + ), + + 'extra' => array( + 'label' => qa_html(qa_opt('extra_field_prompt')), + 'tags' => 'name="q_extra"', + 'value' => qa_html(isset($in['extra']) ? $in['extra'] : $question['extra']), + 'error' => qa_html(@$errors['extra']), + ), + + 'tags' => array( + 'error' => qa_html(@$errors['tags']), + ), + + ), + + 'buttons' => array( + 'save' => array( + 'tags' => 'onclick="qa_show_waiting_after(this, false);"', + 'label' => qa_lang_html('main/save_button'), + ), + + 'cancel' => array( + 'tags' => 'name="docancel"', + 'label' => qa_lang_html('main/cancel_button'), + ), + ), + + 'hidden' => array( + 'q_dosave' => '1', + 'code' => qa_get_form_security_code('edit-'.$question['postid']), + ), + ); + + if ($question['editable']) { + $content=isset($in['content']) ? $in['content'] : $question['content']; + $format=isset($in['format']) ? $in['format'] : $question['format']; + + $editorname=isset($in['editor']) ? $in['editor'] : qa_opt('editor_for_qs'); + $editor=qa_load_editor($content, $format, $editorname); + + $form['fields']['content']=array_merge($form['fields']['content'], + qa_editor_load_field($editor, $qa_content, $content, $format, 'q_content', 12, true)); + + if (method_exists($editor, 'update_script')) + $form['buttons']['save']['tags']='onclick="qa_show_waiting_after(this, false); '.$editor->update_script('q_content').'"'; + + $form['hidden']['q_editor']=qa_html($editorname); + + } else + unset($form['fields']['content']); + + if (qa_using_categories() && count($categories) && $question['retagcatable']) + qa_set_up_category_field($qa_content, $form['fields']['category'], 'q_category', $categories, + isset($in['categoryid']) ? $in['categoryid'] : $question['categoryid'], + qa_opt('allow_no_category') || !isset($question['categoryid']), qa_opt('allow_no_sub_category')); + else + unset($form['fields']['category']); + + if (!($question['editable'] && qa_opt('extra_field_active'))) + unset($form['fields']['extra']); + + if (qa_using_tags() && $question['retagcatable']) + qa_set_up_tag_field($qa_content, $form['fields']['tags'], 'q_tags', isset($in['tags']) ? $in['tags'] : qa_tagstring_to_tags($question['tags']), + array(), $completetags, qa_opt('page_size_ask_tags')); + else + unset($form['fields']['tags']); + + if ($question['isbyuser']) { + if (!qa_is_logged_in()) + qa_set_up_name_field($qa_content, $form['fields'], isset($in['name']) ? $in['name'] : @$question['name'], 'q_'); + + qa_set_up_notify_fields($qa_content, $form['fields'], 'Q', qa_get_logged_in_email(), + isset($in['notify']) ? $in['notify'] : !empty($question['notify']), + isset($in['email']) ? $in['email'] : @$question['notify'], @$errors['email'], 'q_'); + } + + if (!qa_user_post_permit_error('permit_edit_silent', $question)) + $form['fields']['silent']=array( + 'type' => 'checkbox', + 'label' => qa_lang_html('question/save_silent_label'), + 'tags' => 'name="q_silent"', + 'value' => qa_html(@$in['silent']), + ); + + return $form; + } + + + function qa_page_q_edit_q_submit($question, $answers, $commentsfollows, $closepost, &$in, &$errors) +/* + Processes a POSTed form for editing the question and returns true if successful +*/ + { + $in=array(); + + if ($question['editable']) { + $in['title']=qa_post_text('q_title'); + qa_get_post_content('q_editor', 'q_content', $in['editor'], $in['content'], $in['format'], $in['text']); + $in['extra']=qa_opt('extra_field_active') ? qa_post_text('q_extra') : null; + } + + if ($question['retagcatable']) { + if (qa_using_tags()) + $in['tags']=qa_get_tags_field_value('q_tags'); + + if (qa_using_categories()) + $in['categoryid']=qa_get_category_field_value('q_category'); + } + + if (array_key_exists('categoryid', $in)) { // need to check if we can move it to that category, and if we need moderation + $categories=qa_db_select_with_pending(qa_db_category_nav_selectspec($in['categoryid'], true)); + $categoryids=array_keys(qa_category_path($categories, $in['categoryid'])); + $userlevel=qa_user_level_for_categories($categoryids); + + } else + $userlevel=null; + + if ($question['isbyuser']) { + $in['name']=qa_post_text('q_name'); + $in['notify'] = qa_post_text('q_notify') !== null; + $in['email']=qa_post_text('q_email'); + } + + if (!qa_user_post_permit_error('permit_edit_silent', $question)) + $in['silent']=qa_post_text('q_silent'); + + // here the $in array only contains values for parts of the form that were displayed, so those are only ones checked by filters + + $errors=array(); + + if (!qa_check_form_security_code('edit-'.$question['postid'], qa_post_text('code'))) + $errors['page']=qa_lang_html('misc/form_security_again'); + + else { + $in['queued']=qa_opt('moderate_edited_again') && qa_user_moderation_reason($userlevel); + + $filtermodules=qa_load_modules_with('filter', 'filter_question'); + foreach ($filtermodules as $filtermodule) { + $oldin=$in; + $filtermodule->filter_question($in, $errors, $question); + + if ($question['editable']) + qa_update_post_text($in, $oldin); + } + + if (array_key_exists('categoryid', $in) && strcmp($in['categoryid'], $question['categoryid'])) + if (qa_user_permit_error('permit_post_q', null, $userlevel)) + $errors['categoryid']=qa_lang_html('question/category_ask_not_allowed'); + + if (empty($errors)) { + $userid=qa_get_logged_in_userid(); + $handle=qa_get_logged_in_handle(); + $cookieid=qa_cookie_get(); + + // now we fill in the missing values in the $in array, so that we have everything we need for qa_question_set_content() + // we do things in this way to avoid any risk of a validation failure on elements the user can't see (e.g. due to admin setting changes) + + if (!$question['editable']) { + $in['title']=$question['title']; + $in['content']=$question['content']; + $in['format']=$question['format']; + $in['text']=qa_viewer_text($in['content'], $in['format']); + $in['extra']=$question['extra']; + } + + if (!isset($in['tags'])) + $in['tags']=qa_tagstring_to_tags($question['tags']); + + if (!array_key_exists('categoryid', $in)) + $in['categoryid']=$question['categoryid']; + + if (!isset($in['silent'])) + $in['silent']=false; + + $setnotify=$question['isbyuser'] ? qa_combine_notify_email($question['userid'], $in['notify'], $in['email']) : $question['notify']; + + qa_question_set_content($question, $in['title'], $in['content'], $in['format'], $in['text'], qa_tags_to_tagstring($in['tags']), + $setnotify, $userid, $handle, $cookieid, $in['extra'], @$in['name'], $in['queued'], $in['silent']); + + if (qa_using_categories() && strcmp($in['categoryid'], $question['categoryid'])) + qa_question_set_category($question, $in['categoryid'], $userid, $handle, $cookieid, + $answers, $commentsfollows, $closepost, $in['silent']); + + return true; + } + } + + return false; + } + + + function qa_page_q_close_q_form(&$qa_content, $question, $id, $in, $errors) +/* + Returns a $qa_content form for closing the question and sets up other parts of $qa_content accordingly +*/ + { + $form=array( + 'tags' => 'method="post" action="'.qa_self_html().'"', + + 'id' => $id, + + 'style' => 'tall', + + 'title' => qa_lang_html('question/close_form_title'), + + 'fields' => array( + 'duplicate' => array( + 'type' => 'checkbox', + 'tags' => 'name="q_close_duplicate" id="q_close_duplicate" onchange="document.getElementById(\'q_close_details\').focus();"', + 'label' => qa_lang_html('question/close_duplicate'), + 'value' => @$in['duplicate'], + ), + + 'details' => array( + 'tags' => 'name="q_close_details" id="q_close_details"', + 'label' => + ''.qa_lang_html('question/close_original_title').' '. + ''.qa_lang_html('question/close_reason_title').'', + 'note' => '', + 'value' => @$in['details'], + 'error' => qa_html(@$errors['details']), + ), + ), + + 'buttons' => array( + 'close' => array( + 'tags' => 'onclick="qa_show_waiting_after(this, false);"', + 'label' => qa_lang_html('question/close_form_button'), + ), + + 'cancel' => array( + 'tags' => 'name="docancel"', + 'label' => qa_lang_html('main/cancel_button'), + ), + ), + + 'hidden' => array( + 'doclose' => '1', + 'code' => qa_get_form_security_code('close-'.$question['postid']), + ), + ); + + qa_set_display_rules($qa_content, array( + 'close_label_duplicate' => 'q_close_duplicate', + 'close_label_other' => '!q_close_duplicate', + 'close_note_duplicate' => 'q_close_duplicate', + )); + + $qa_content['focusid']='q_close_details'; + + return $form; + } + + + function qa_page_q_close_q_submit($question, $closepost, &$in, &$errors) +/* + Processes a POSTed form for closing the question and returns true if successful +*/ + { + $in=array( + 'duplicate' => qa_post_text('q_close_duplicate'), + 'details' => qa_post_text('q_close_details'), + ); + + $userid=qa_get_logged_in_userid(); + $handle=qa_get_logged_in_handle(); + $cookieid=qa_cookie_get(); + + if (!qa_check_form_security_code('close-'.$question['postid'], qa_post_text('code'))) + $errors['details']=qa_lang_html('misc/form_security_again'); + + elseif ($in['duplicate']) { + // be liberal in what we accept, but there are two potential unlikely pitfalls here: + // a) URLs could have a fixed numerical path, e.g. http://qa.mysite.com/1/478/... + // b) There could be a question title which is just a number, e.g. http://qa.mysite.com/478/12345/... + // so we check if more than one question could match, and if so, show an error + + $parts=preg_split('|[=/&]|', $in['details'], -1, PREG_SPLIT_NO_EMPTY); + $keypostids=array(); + + foreach ($parts as $part) + if (preg_match('/^[0-9]+$/', $part)) + $keypostids[$part]=true; + + $questionids=qa_db_posts_filter_q_postids(array_keys($keypostids)); + + if ( (count($questionids)==1) && ($questionids[0]!=$question['postid']) ) { + qa_question_close_duplicate($question, $closepost, $questionids[0], $userid, $handle, $cookieid); + return true; + + } else + $errors['details']=qa_lang('question/close_duplicate_error'); + + } else { + if (strlen($in['details'])>0) { + qa_question_close_other($question, $closepost, $in['details'], $userid, $handle, $cookieid); + return true; + + } else + $errors['details']=qa_lang('main/field_required'); + } + + return false; + } + + + function qa_page_q_edit_a_form(&$qa_content, $id, $answer, $question, $answers, $commentsfollows, $in, $errors) +/* + Returns a $qa_content form for editing an answer and sets up other parts of $qa_content accordingly +*/ + { + require_once QA_INCLUDE_DIR.'util/string.php'; + + $answerid=$answer['postid']; + $prefix='a'.$answerid.'_'; + + $content=isset($in['content']) ? $in['content'] : $answer['content']; + $format=isset($in['format']) ? $in['format'] : $answer['format']; + + $editorname=isset($in['editor']) ? $in['editor'] : qa_opt('editor_for_as'); + $editor=qa_load_editor($content, $format, $editorname); + + $hascomments=false; + foreach ($commentsfollows as $commentfollow) + if ($commentfollow['parentid']==$answerid) + $hascomments=true; + + $form=array( + 'tags' => 'method="post" action="'.qa_self_html().'"', + + 'id' => $id, + + 'title' => qa_lang_html('question/edit_a_title'), + + 'style' => 'tall', + + 'fields' => array( + 'content' => array_merge( + qa_editor_load_field($editor, $qa_content, $content, $format, $prefix.'content', 12), + array( + 'error' => qa_html(@$errors['content']), + ) + ), + ), + + 'buttons' => array( + 'save' => array( + 'tags' => 'onclick="qa_show_waiting_after(this, false); '. + (method_exists($editor, 'update_script') ? $editor->update_script($prefix.'content') : '').'"', + 'label' => qa_lang_html('main/save_button'), + ), + + 'cancel' => array( + 'tags' => 'name="docancel"', + 'label' => qa_lang_html('main/cancel_button'), + ), + ), + + 'hidden' => array( + $prefix.'editor' => qa_html($editorname), + $prefix.'dosave' => '1', + $prefix.'code' => qa_get_form_security_code('edit-'.$answerid), + ), + ); + + // Show option to convert this answer to a comment, if appropriate + + $commentonoptions=array(); + + $lastbeforeid=$question['postid']; // used to find last post created before this answer - this is default given + $lastbeforetime=$question['created']; + + if ($question['commentable']) + $commentonoptions[$question['postid']]= + qa_lang_html('question/comment_on_q').qa_html(qa_shorten_string_line($question['title'], 80)); + + foreach ($answers as $otheranswer) + if (($otheranswer['postid']!=$answerid) && ($otheranswer['created']<$answer['created']) && $otheranswer['commentable'] && !$otheranswer['hidden']) { + $commentonoptions[$otheranswer['postid']]= + qa_lang_html('question/comment_on_a').qa_html(qa_shorten_string_line(qa_viewer_text($otheranswer['content'], $otheranswer['format']), 80)); + + if ($otheranswer['created']>$lastbeforetime) { + $lastbeforeid=$otheranswer['postid']; + $lastbeforetime=$otheranswer['created']; + } + } + + if (count($commentonoptions)) { + $form['fields']['tocomment']=array( + 'tags' => 'name="'.$prefix.'dotoc" id="'.$prefix.'dotoc"', + 'label' => ''.qa_lang_html('question/a_convert_to_c_on').''. + '', + 'type' => 'checkbox', + 'tight' => true, + ); + + $form['fields']['commenton']=array( + 'tags' => 'name="'.$prefix.'commenton"', + 'id' => $prefix.'commenton', + 'type' => 'select', + 'note' => qa_lang_html($hascomments ? 'question/a_convert_warn_cs' : 'question/a_convert_warn'), + 'options' => $commentonoptions, + 'value' => @$commentonoptions[$lastbeforeid], + ); + + qa_set_display_rules($qa_content, array( + $prefix.'commenton' => $prefix.'dotoc', + $prefix.'toshown' => $prefix.'dotoc', + $prefix.'tohidden' => '!'.$prefix.'dotoc', + )); + } + + // Show name and notification field if appropriate + + if ($answer['isbyuser']) { + if (!qa_is_logged_in()) + qa_set_up_name_field($qa_content, $form['fields'], isset($in['name']) ? $in['name'] : @$answer['name'], $prefix); + + qa_set_up_notify_fields($qa_content, $form['fields'], 'A', qa_get_logged_in_email(), + isset($in['notify']) ? $in['notify'] : !empty($answer['notify']), + isset($in['email']) ? $in['email'] : @$answer['notify'], @$errors['email'], $prefix); + } + + if (!qa_user_post_permit_error('permit_edit_silent', $answer)) + $form['fields']['silent']=array( + 'type' => 'checkbox', + 'label' => qa_lang_html('question/save_silent_label'), + 'tags' => 'name="'.$prefix.'silent"', + 'value' => qa_html(@$in['silent']), + ); + + return $form; + } + + + function qa_page_q_edit_a_submit($answer, $question, $answers, $commentsfollows, &$in, &$errors) +/* + Processes a POSTed form for editing an answer and returns the new type of the post if successful +*/ + { + $answerid=$answer['postid']; + $prefix='a'.$answerid.'_'; + + $in=array( + 'dotoc' => qa_post_text($prefix.'dotoc'), + 'commenton' => qa_post_text($prefix.'commenton'), + ); + + if ($answer['isbyuser']) { + $in['name']=qa_post_text($prefix.'name'); + $in['notify'] = qa_post_text($prefix.'notify') !== null; + $in['email']=qa_post_text($prefix.'email'); + } + + if (!qa_user_post_permit_error('permit_edit_silent', $answer)) + $in['silent']=qa_post_text($prefix.'silent'); + + qa_get_post_content($prefix.'editor', $prefix.'content', $in['editor'], $in['content'], $in['format'], $in['text']); + + // here the $in array only contains values for parts of the form that were displayed, so those are only ones checked by filters + + $errors=array(); + + if (!qa_check_form_security_code('edit-'.$answerid, qa_post_text($prefix.'code'))) + $errors['content']=qa_lang_html('misc/form_security_again'); + + else { + $in['queued']=qa_opt('moderate_edited_again') && qa_user_moderation_reason(qa_user_level_for_post($answer)); + + $filtermodules=qa_load_modules_with('filter', 'filter_answer'); + foreach ($filtermodules as $filtermodule) { + $oldin=$in; + $filtermodule->filter_answer($in, $errors, $question, $answer); + qa_update_post_text($in, $oldin); + } + + if (empty($errors)) { + $userid=qa_get_logged_in_userid(); + $handle=qa_get_logged_in_handle(); + $cookieid=qa_cookie_get(); + + if (!isset($in['silent'])) + $in['silent']=false; + + $setnotify=$answer['isbyuser'] ? qa_combine_notify_email($answer['userid'], $in['notify'], $in['email']) : $answer['notify']; + + if ($in['dotoc'] && ( + (($in['commenton']==$question['postid']) && $question['commentable']) || + (($in['commenton']!=$answerid) && @$answers[$in['commenton']]['commentable']) + )) { // convert to a comment + + if (qa_user_limits_remaining(QA_LIMIT_COMMENTS)) { // already checked 'permit_post_c' + qa_answer_to_comment($answer, $in['commenton'], $in['content'], $in['format'], $in['text'], $setnotify, + $userid, $handle, $cookieid, $question, $answers, $commentsfollows, @$in['name'], $in['queued'], $in['silent']); + + return 'C'; // to signify that redirect should be to the comment + + } else + $errors['content']=qa_lang_html('question/comment_limit'); // not really best place for error, but it will do + + } else { + qa_answer_set_content($answer, $in['content'], $in['format'], $in['text'], $setnotify, + $userid, $handle, $cookieid, $question, @$in['name'], $in['queued'], $in['silent']); + + return 'A'; + } + } + } + + return null; + } + + + function qa_page_q_do_comment($question, $parent, $commentsfollows, $pagestart, $usecaptcha, &$cnewin, &$cnewerrors, &$formtype, &$formpostid, &$error) +/* + Processes a request to add a comment to $parent, with antecedent $question, checking for permissions errors +*/ + { + // The 'approve', 'login', 'confirm', 'userblock', 'ipblock' permission errors are reported to the user here + // The other option ('level') prevents the comment button being shown, in qa_page_q_post_rules(...) + + $parentid = $parent['postid']; + $answer = ($question['postid'] == $parentid) ? null : $parent; + + switch (qa_user_post_permit_error('permit_post_c', $parent, QA_LIMIT_COMMENTS)) { + case 'login': + $error=qa_insert_login_links(qa_lang_html('question/comment_must_login'), qa_request()); + break; + + case 'confirm': + $error=qa_insert_login_links(qa_lang_html('question/comment_must_confirm'), qa_request()); + break; + + case 'approve': + $error=qa_lang_html('question/comment_must_be_approved'); + break; + + case 'limit': + $error=qa_lang_html('question/comment_limit'); + break; + + default: + $error=qa_lang_html('users/no_permission'); + break; + + case false: + if (qa_clicked('c'.$parentid.'_doadd')) { + $commentid=qa_page_q_add_c_submit($question, $parent, $commentsfollows, $usecaptcha, $cnewin[$parentid], $cnewerrors[$parentid]); + + if (isset($commentid)) + qa_page_q_refresh($pagestart, null, $parent['basetype'], $parentid); + + else { + $formtype='c_add'; + $formpostid=$parentid; // show form again + } + + } else { + $formtype='c_add'; + $formpostid=$parentid; // show form first time + } + break; + } + } + + + function qa_page_q_edit_c_form(&$qa_content, $id, $comment, $in, $errors) +/* + Returns a $qa_content form for editing a comment and sets up other parts of $qa_content accordingly +*/ + { + $commentid=$comment['postid']; + $prefix='c'.$commentid.'_'; + + $content=isset($in['content']) ? $in['content'] : $comment['content']; + $format=isset($in['format']) ? $in['format'] : $comment['format']; + + $editorname=isset($in['editor']) ? $in['editor'] : qa_opt('editor_for_cs'); + $editor=qa_load_editor($content, $format, $editorname); + + $form=array( + 'tags' => 'method="post" action="'.qa_self_html().'"', + + 'id' => $id, + + 'title' => qa_lang_html('question/edit_c_title'), + + 'style' => 'tall', + + 'fields' => array( + 'content' => array_merge( + qa_editor_load_field($editor, $qa_content, $content, $format, $prefix.'content', 4, true), + array( + 'error' => qa_html(@$errors['content']), + ) + ), + ), + + 'buttons' => array( + 'save' => array( + 'tags' => 'onclick="qa_show_waiting_after(this, false); '. + (method_exists($editor, 'update_script') ? $editor->update_script($prefix.'content') : '').'"', + 'label' => qa_lang_html('main/save_button'), + ), + + 'cancel' => array( + 'tags' => 'name="docancel"', + 'label' => qa_lang_html('main/cancel_button'), + ), + ), + + 'hidden' => array( + $prefix.'editor' => qa_html($editorname), + $prefix.'dosave' => '1', + $prefix.'code' => qa_get_form_security_code('edit-'.$commentid), + ), + ); + + if ($comment['isbyuser']) { + if (!qa_is_logged_in()) + qa_set_up_name_field($qa_content, $form['fields'], isset($in['name']) ? $in['name'] : @$comment['name'], $prefix); + + qa_set_up_notify_fields($qa_content, $form['fields'], 'C', qa_get_logged_in_email(), + isset($in['notify']) ? $in['notify'] : !empty($comment['notify']), + isset($in['email']) ? $in['email'] : @$comment['notify'], @$errors['email'], $prefix); + } + + if (!qa_user_post_permit_error('permit_edit_silent', $comment)) + $form['fields']['silent']=array( + 'type' => 'checkbox', + 'label' => qa_lang_html('question/save_silent_label'), + 'tags' => 'name="'.$prefix.'silent"', + 'value' => qa_html(@$in['silent']), + ); + + return $form; + } + + + function qa_page_q_edit_c_submit($comment, $question, $parent, &$in, &$errors) +/* + Processes a POSTed form for editing a comment and returns true if successful +*/ + { + $commentid=$comment['postid']; + $prefix='c'.$commentid.'_'; + + $in=array(); + + if ($comment['isbyuser']) { + $in['name']=qa_post_text($prefix.'name'); + $in['notify'] = qa_post_text($prefix.'notify') !== null; + $in['email']=qa_post_text($prefix.'email'); + } + + if (!qa_user_post_permit_error('permit_edit_silent', $comment)) + $in['silent']=qa_post_text($prefix.'silent'); + + qa_get_post_content($prefix.'editor', $prefix.'content', $in['editor'], $in['content'], $in['format'], $in['text']); + + // here the $in array only contains values for parts of the form that were displayed, so those are only ones checked by filters + + $errors=array(); + + if (!qa_check_form_security_code('edit-'.$commentid, qa_post_text($prefix.'code'))) + $errors['content']=qa_lang_html('misc/form_security_again'); + + else { + $in['queued']=qa_opt('moderate_edited_again') && qa_user_moderation_reason(qa_user_level_for_post($comment)); + + $filtermodules=qa_load_modules_with('filter', 'filter_comment'); + foreach ($filtermodules as $filtermodule) { + $oldin=$in; + $filtermodule->filter_comment($in, $errors, $question, $parent, $comment); + qa_update_post_text($in, $oldin); + } + + if (empty($errors)) { + $userid=qa_get_logged_in_userid(); + $handle=qa_get_logged_in_handle(); + $cookieid=qa_cookie_get(); + + if (!isset($in['silent'])) + $in['silent']=false; + + $setnotify=$comment['isbyuser'] ? qa_combine_notify_email($comment['userid'], $in['notify'], $in['email']) : $comment['notify']; + + qa_comment_set_content($comment, $in['content'], $in['format'], $in['text'], $setnotify, + $userid, $handle, $cookieid, $question, $parent, @$in['name'], $in['queued'], $in['silent']); + + return true; + } + } + + return false; + } + + +/* + Omit PHP closing tag to help avoid accidental output +*/ \ No newline at end of file diff --git a/pages/question-submit.php b/pages/question-submit.php new file mode 100644 index 0000000..f14b8ae --- /dev/null +++ b/pages/question-submit.php @@ -0,0 +1,460 @@ +filter_question($tempin, $temperrors, $question); + $in['queued']=$tempin['queued']; // only preserve queued status in loop + } + + $status=$in['queued'] ? QA_POST_STATUS_QUEUED : QA_POST_STATUS_NORMAL; + } + + qa_question_set_status($question, $status, $userid, $handle, $cookieid, $answers, $commentsfollows, $closepost); + return true; + } + + if (qa_clicked('q_doclaim') && $question['claimable'] && qa_page_q_click_check_form_code($question, $error) ) { + if (qa_user_limits_remaining(QA_LIMIT_QUESTIONS)) { // already checked 'permit_post_q' + qa_question_set_userid($question, $userid, $handle, $cookieid); + return true; + + } else + $error=qa_lang_html('question/ask_limit'); + } + + if (qa_clicked('q_doflag') && $question['flagbutton'] && qa_page_q_click_check_form_code($question, $error)) { + require_once QA_INCLUDE_DIR.'app/votes.php'; + + $error=qa_flag_error_html($question, $userid, qa_request()); + if (!$error) { + if (qa_flag_set_tohide($question, $userid, $handle, $cookieid, $question)) + qa_question_set_hidden($question, true, null, null, null, $answers, $commentsfollows, $closepost); // hiding not really by this user so pass nulls + return true; + } + } + + if (qa_clicked('q_dounflag') && $question['unflaggable'] && qa_page_q_click_check_form_code($question, $error)) { + require_once QA_INCLUDE_DIR.'app/votes.php'; + + qa_flag_clear($question, $userid, $handle, $cookieid); + return true; + } + + if (qa_clicked('q_doclearflags') && $question['clearflaggable'] && qa_page_q_click_check_form_code($question, $error)) { + require_once QA_INCLUDE_DIR.'app/votes.php'; + + qa_flags_clear_all($question, $userid, $handle, $cookieid); + return true; + } + + return false; + } + + + function qa_page_q_single_click_a($answer, $question, $answers, $commentsfollows, $allowselectmove, &$error) +/* + Checks for a POSTed click on $answer by the current user and returns true if it was permitted and processed. Pass in + the $question, all of its $answers, and all $commentsfollows from it or its answers. Set $allowselectmove to whether + it is legitimate to change the selected answer for the question from one to another (this can't be done via Ajax). + If there is an error to display, it will be passed out in $error. +*/ + { + $userid=qa_get_logged_in_userid(); + $handle=qa_get_logged_in_handle(); + $cookieid=qa_cookie_get(); + + $prefix='a'.$answer['postid'].'_'; + + if (qa_clicked($prefix.'doselect') && $question['aselectable'] && ($allowselectmove || ( (!isset($question['selchildid'])) && !qa_opt('do_close_on_select'))) && qa_page_q_click_check_form_code($answer, $error) ) { + qa_question_set_selchildid($userid, $handle, $cookieid, $question, $answer['postid'], $answers); + return true; + } + + if (qa_clicked($prefix.'dounselect') && $question['aselectable'] && ($question['selchildid']==$answer['postid']) && ($allowselectmove || !qa_opt('do_close_on_select')) && qa_page_q_click_check_form_code($answer, $error)) { + qa_question_set_selchildid($userid, $handle, $cookieid, $question, null, $answers); + return true; + } + + if ( (qa_clicked($prefix.'dohide') && $answer['hideable']) || (qa_clicked($prefix.'doreject') && $answer['moderatable']) ) + if (qa_page_q_click_check_form_code($answer, $error)) { + qa_answer_set_hidden($answer, true, $userid, $handle, $cookieid, $question, $commentsfollows); + return true; + } + + if ( (qa_clicked($prefix.'doreshow') && $answer['reshowable']) || (qa_clicked($prefix.'doapprove') && $answer['moderatable']) ) + if (qa_page_q_click_check_form_code($answer, $error)) { + if ($answer['moderatable'] || $answer['reshowimmed']) { + $status=QA_POST_STATUS_NORMAL; + + } else { + $in=qa_page_q_prepare_post_for_filters($answer); + $filtermodules=qa_load_modules_with('filter', 'filter_answer'); // run through filters but only for queued status + + foreach ($filtermodules as $filtermodule) { + $tempin=$in; // always pass original answer in because we aren't modifying anything else + $filtermodule->filter_answer($tempin, $temperrors, $question, $answer); + $in['queued']=$tempin['queued']; // only preserve queued status in loop + } + + $status=$in['queued'] ? QA_POST_STATUS_QUEUED : QA_POST_STATUS_NORMAL; + } + + qa_answer_set_status($answer, $status, $userid, $handle, $cookieid, $question, $commentsfollows); + return true; + } + + if (qa_clicked($prefix.'dodelete') && $answer['deleteable'] && qa_page_q_click_check_form_code($answer, $error)) { + qa_answer_delete($answer, $question, $userid, $handle, $cookieid); + return true; + } + + if (qa_clicked($prefix.'doclaim') && $answer['claimable'] && qa_page_q_click_check_form_code($answer, $error)) { + if (qa_user_limits_remaining(QA_LIMIT_ANSWERS)) { // already checked 'permit_post_a' + qa_answer_set_userid($answer, $userid, $handle, $cookieid); + return true; + + } else + $error=qa_lang_html('question/answer_limit'); + } + + if (qa_clicked($prefix.'doflag') && $answer['flagbutton'] && qa_page_q_click_check_form_code($answer, $error)) { + require_once QA_INCLUDE_DIR.'app/votes.php'; + + $error=qa_flag_error_html($answer, $userid, qa_request()); + if (!$error) { + if (qa_flag_set_tohide($answer, $userid, $handle, $cookieid, $question)) + qa_answer_set_hidden($answer, true, null, null, null, $question, $commentsfollows); // hiding not really by this user so pass nulls + + return true; + } + } + + if (qa_clicked($prefix.'dounflag') && $answer['unflaggable'] && qa_page_q_click_check_form_code($answer, $error)) { + require_once QA_INCLUDE_DIR.'app/votes.php'; + + qa_flag_clear($answer, $userid, $handle, $cookieid); + return true; + } + + if (qa_clicked($prefix.'doclearflags') && $answer['clearflaggable'] && qa_page_q_click_check_form_code($answer, $error)) { + require_once QA_INCLUDE_DIR.'app/votes.php'; + + qa_flags_clear_all($answer, $userid, $handle, $cookieid); + return true; + } + + return false; + } + + + function qa_page_q_single_click_c($comment, $question, $parent, &$error) +/* + Checks for a POSTed click on $comment by the current user and returns true if it was permitted and processed. Pass + in the antecedent $question and the comment's $parent post. If there is an error to display, it will be passed out + in $error. +*/ + { + $userid=qa_get_logged_in_userid(); + $handle=qa_get_logged_in_handle(); + $cookieid=qa_cookie_get(); + + $prefix='c'.$comment['postid'].'_'; + + if ( (qa_clicked($prefix.'dohide') && $comment['hideable']) || (qa_clicked($prefix.'doreject') && $comment['moderatable']) ) + if (qa_page_q_click_check_form_code($parent, $error)) { + qa_comment_set_hidden($comment, true, $userid, $handle, $cookieid, $question, $parent); + return true; + } + + if ( (qa_clicked($prefix.'doreshow') && $comment['reshowable']) || (qa_clicked($prefix.'doapprove') && $comment['moderatable']) ) + if (qa_page_q_click_check_form_code($parent, $error)) { + if ($comment['moderatable'] || $comment['reshowimmed']) { + $status=QA_POST_STATUS_NORMAL; + + } else { + $in=qa_page_q_prepare_post_for_filters($comment); + $filtermodules=qa_load_modules_with('filter', 'filter_comment'); // run through filters but only for queued status + + foreach ($filtermodules as $filtermodule) { + $tempin=$in; // always pass original comment in because we aren't modifying anything else + $filtermodule->filter_comment($tempin, $temperrors, $question, $parent, $comment); + $in['queued']=$tempin['queued']; // only preserve queued status in loop + } + + $status=$in['queued'] ? QA_POST_STATUS_QUEUED : QA_POST_STATUS_NORMAL; + } + + qa_comment_set_status($comment, $status, $userid, $handle, $cookieid, $question, $parent); + return true; + } + + if (qa_clicked($prefix.'dodelete') && $comment['deleteable'] && qa_page_q_click_check_form_code($parent, $error)) { + qa_comment_delete($comment, $question, $parent, $userid, $handle, $cookieid); + return true; + } + + if (qa_clicked($prefix.'doclaim') && $comment['claimable'] && qa_page_q_click_check_form_code($parent, $error)) { + if (qa_user_limits_remaining(QA_LIMIT_COMMENTS)) { + qa_comment_set_userid($comment, $userid, $handle, $cookieid); + return true; + + } else + $error=qa_lang_html('question/comment_limit'); + } + + if (qa_clicked($prefix.'doflag') && $comment['flagbutton'] && qa_page_q_click_check_form_code($parent, $error)) { + require_once QA_INCLUDE_DIR.'app/votes.php'; + + $error=qa_flag_error_html($comment, $userid, qa_request()); + if (!$error) { + if (qa_flag_set_tohide($comment, $userid, $handle, $cookieid, $question)) + qa_comment_set_hidden($comment, true, null, null, null, $question, $parent); // hiding not really by this user so pass nulls + + return true; + } + } + + if (qa_clicked($prefix.'dounflag') && $comment['unflaggable'] && qa_page_q_click_check_form_code($parent, $error)) { + require_once QA_INCLUDE_DIR.'app/votes.php'; + + qa_flag_clear($comment, $userid, $handle, $cookieid); + return true; + } + + if (qa_clicked($prefix.'doclearflags') && $comment['clearflaggable'] && qa_page_q_click_check_form_code($parent, $error)) { + require_once QA_INCLUDE_DIR.'app/votes.php'; + + qa_flags_clear_all($comment, $userid, $handle, $cookieid); + return true; + } + + return false; + } + + + function qa_page_q_click_check_form_code($post, &$error) +/* + Check the form security (anti-CSRF protection) for one of the buttons shown for post $post. Return true if the + security passed, otherwise return false and set an error message in $error +*/ + { + $result=qa_check_form_security_code('buttons-'.$post['postid'], qa_post_text('code')); + + if (!$result) + $error=qa_lang_html('misc/form_security_again'); + + return $result; + } + + + function qa_page_q_add_a_submit($question, $answers, $usecaptcha, &$in, &$errors) +/* + Processes a POSTed form to add an answer to $question, returning the postid if successful, otherwise null. Pass in + other $answers to the question and whether a $usecaptcha is required. The form fields submitted will be passed out + as an array in $in, as well as any $errors on those fields. +*/ + { + $in=array( + 'name' => qa_post_text('a_name'), + 'notify' => qa_post_text('a_notify') !== null, + 'email' => qa_post_text('a_email'), + 'queued' => qa_user_moderation_reason(qa_user_level_for_post($question)) !== false, + ); + + qa_get_post_content('a_editor', 'a_content', $in['editor'], $in['content'], $in['format'], $in['text']); + + $errors=array(); + + if (!qa_check_form_security_code('answer-'.$question['postid'], qa_post_text('code'))) + $errors['content']=qa_lang_html('misc/form_security_again'); + + else { + $filtermodules=qa_load_modules_with('filter', 'filter_answer'); + foreach ($filtermodules as $filtermodule) { + $oldin=$in; + $filtermodule->filter_answer($in, $errors, $question, null); + qa_update_post_text($in, $oldin); + } + + if ($usecaptcha) + qa_captcha_validate_post($errors); + + if (empty($errors)) { + $testwords=implode(' ', qa_string_to_words($in['content'])); + + foreach ($answers as $answer) + if (!$answer['hidden']) + if (implode(' ', qa_string_to_words($answer['content'])) == $testwords) + $errors['content']=qa_lang_html('question/duplicate_content'); + } + + if (empty($errors)) { + $userid=qa_get_logged_in_userid(); + $handle=qa_get_logged_in_handle(); + $cookieid=isset($userid) ? qa_cookie_get() : qa_cookie_get_create(); // create a new cookie if necessary + + $answerid=qa_answer_create($userid, $handle, $cookieid, $in['content'], $in['format'], $in['text'], $in['notify'], $in['email'], + $question, $in['queued'], $in['name']); + + return $answerid; + } + } + + return null; + } + + + function qa_page_q_add_c_submit($question, $parent, $commentsfollows, $usecaptcha, &$in, &$errors) +/* + Processes a POSTed form to add a comment, returning the postid if successful, otherwise null. Pass in the antecedent + $question and the comment's $parent post. Set $usecaptcha to whether a captcha is required. Pass an array which + includes the other comments with the same parent in $commentsfollows (it can contain other posts which are ignored). + The form fields submitted will be passed out as an array in $in, as well as any $errors on those fields. +*/ + { + $parentid=$parent['postid']; + + $prefix='c'.$parentid.'_'; + + $in=array( + 'name' => qa_post_text($prefix.'name'), + 'notify' => qa_post_text($prefix.'notify') !== null, + 'email' => qa_post_text($prefix.'email'), + 'queued' => qa_user_moderation_reason(qa_user_level_for_post($parent)) !== false, + ); + + qa_get_post_content($prefix.'editor', $prefix.'content', $in['editor'], $in['content'], $in['format'], $in['text']); + + $errors=array(); + + if (!qa_check_form_security_code('comment-'.$parent['postid'], qa_post_text($prefix.'code'))) + $errors['content']=qa_lang_html('misc/form_security_again'); + + else { + $filtermodules=qa_load_modules_with('filter', 'filter_comment'); + foreach ($filtermodules as $filtermodule) { + $oldin=$in; + $filtermodule->filter_comment($in, $errors, $question, $parent, null); + qa_update_post_text($in, $oldin); + } + + if ($usecaptcha) + qa_captcha_validate_post($errors); + + if (empty($errors)) { + $testwords=implode(' ', qa_string_to_words($in['content'])); + + foreach ($commentsfollows as $comment) + if (($comment['basetype']=='C') && ($comment['parentid']==$parentid) && !$comment['hidden']) + if (implode(' ', qa_string_to_words($comment['content'])) == $testwords) + $errors['content']=qa_lang_html('question/duplicate_content'); + } + + if (empty($errors)) { + $userid=qa_get_logged_in_userid(); + $handle=qa_get_logged_in_handle(); + $cookieid=isset($userid) ? qa_cookie_get() : qa_cookie_get_create(); // create a new cookie if necessary + + $commentid=qa_comment_create($userid, $handle, $cookieid, $in['content'], $in['format'], $in['text'], $in['notify'], $in['email'], + $question, $parent, $commentsfollows, $in['queued'], $in['name']); + + return $commentid; + } + } + + return null; + } + + + function qa_page_q_prepare_post_for_filters($post) +/* + Return the array of information to be passed to filter modules for the post in $post (from the database) +*/ + { + $in=array( + 'content' => $post['content'], + 'format' => $post['format'], + 'text' => qa_viewer_text($post['content'], $post['format']), + 'notify' => isset($post['notify']), + 'email' => qa_email_validate($post['notify']) ? $post['notify'] : null, + 'queued' => qa_user_moderation_reason(qa_user_level_for_post($post)) !== false, + ); + + if ($post['basetype']=='Q') { + $in['title']=$post['title']; + $in['tags']=qa_tagstring_to_tags($post['tags']); + $in['categoryid']=$post['categoryid']; + $in['extra']=$post['extra']; + } + + return $in; + } + + +/* + Omit PHP closing tag to help avoid accidental output +*/ \ No newline at end of file diff --git a/pages/question-view.php b/pages/question-view.php new file mode 100644 index 0000000..e3035c2 --- /dev/null +++ b/pages/question-view.php @@ -0,0 +1,1005 @@ + $post) + switch ($post['type']) { + case 'A': + case 'A_HIDDEN': + case 'A_QUEUED': + $answers[$postid]=$post; + break; + } + + return $answers; + } + + + function qa_page_q_load_c_follows($question, $childposts, $achildposts) +/* + Given a $question, its $childposts and its answers $achildposts from the database, + return a list of comments or follow-on questions for that question or its answers +*/ + { + $commentsfollows=array(); + + foreach ($childposts as $postid => $post) + switch ($post['type']) { + case 'Q': // never show follow-on Qs which have been hidden, even to admins + case 'C': + case 'C_HIDDEN': + case 'C_QUEUED': + $commentsfollows[$postid]=$post; + break; + } + + foreach ($achildposts as $postid => $post) + switch ($post['type']) { + case 'Q': // never show follow-on Qs which have been hidden, even to admins + case 'C': + case 'C_HIDDEN': + case 'C_QUEUED': + $commentsfollows[$postid]=$post; + break; + } + + return $commentsfollows; + } + + + function qa_page_q_post_rules($post, $parentpost=null, $siblingposts=null, $childposts=null) +/* + Returns elements that can be added to $post which describe which operations the current user may perform on that + post. This function is a key part of Q2A's logic and is ripe for overriding by plugins. Pass $post's $parentpost if + there is one, or null otherwise. Pass an array which contains $post's siblings (i.e. other posts with the same type + and parent) in $siblingposts and $post's children in $childposts. Both of these latter arrays can contain additional + posts retrieved from the database, and these will be ignored. +*/ + { + if (qa_to_override(__FUNCTION__)) { $args=func_get_args(); return qa_call_override(__FUNCTION__, $args); } + + $userid=qa_get_logged_in_userid(); + $cookieid=qa_cookie_get(); + $userlevel=qa_user_level_for_post($post); + + $rules['isbyuser']=qa_post_is_by_user($post, $userid, $cookieid); + $rules['queued']=(substr($post['type'], 1)=='_QUEUED'); + $rules['closed']=($post['basetype']=='Q') && (isset($post['closedbyid']) || (isset($post['selchildid']) && qa_opt('do_close_on_select'))); + + // Cache some responses to the user permission checks + + $permiterror_post_q=qa_user_permit_error('permit_post_q', null, $userlevel); // don't check limits here, so we can show error message + $permiterror_post_a=qa_user_permit_error('permit_post_a', null, $userlevel); + $permiterror_post_c=qa_user_permit_error('permit_post_c', null, $userlevel); + + $permiterror_edit=qa_user_permit_error(($post['basetype']=='Q') ? 'permit_edit_q' : + (($post['basetype']=='A') ? 'permit_edit_a' : 'permit_edit_c'), null, $userlevel); + $permiterror_retagcat=qa_user_permit_error('permit_retag_cat', null, $userlevel); + $permiterror_flag=qa_user_permit_error('permit_flag', null, $userlevel); + $permiterror_hide_show=qa_user_permit_error($rules['isbyuser'] ? null : 'permit_hide_show', null, $userlevel); + $permiterror_close_open=qa_user_permit_error($rules['isbyuser'] ? null : 'permit_close_q', null, $userlevel); + $permiterror_moderate=qa_user_permit_error('permit_moderate', null, $userlevel); + + // General permissions + + $rules['authorlast']=((!isset($post['lastuserid'])) || ($post['lastuserid']===$post['userid'])); + $rules['viewable']=$post['hidden'] ? (!$permiterror_hide_show) : ($rules['queued'] ? ($rules['isbyuser'] || !$permiterror_moderate) : true); + + // Answer, comment and edit might show the button even if the user still needs to do something (e.g. log in) + + $rules['answerbutton']=($post['type']=='Q') && ($permiterror_post_a!='level') && (!$rules['closed']) && + (qa_opt('allow_self_answer') || !$rules['isbyuser']); + + $rules['commentbutton']=(($post['type']=='Q') || ($post['type']=='A')) && + ($permiterror_post_c!='level') && qa_opt(($post['type']=='Q') ? 'comment_on_qs' : 'comment_on_as'); + $rules['commentable']=$rules['commentbutton'] && !$permiterror_post_c; + + $rules['editbutton']=(!$post['hidden']) && (!$rules['closed']) && + ($rules['isbyuser'] || (($permiterror_edit!='level') && ($permiterror_edit!='approve') && (!$rules['queued']))); + $rules['editable']=$rules['editbutton'] && ($rules['isbyuser'] || !$permiterror_edit); + + $rules['retagcatbutton']=($post['basetype']=='Q') && (qa_using_tags() || qa_using_categories()) && + (!$post['hidden']) && ($rules['isbyuser'] || (($permiterror_retagcat!='level') && ($permiterror_retagcat!='approve')) ); + $rules['retagcatable']=$rules['retagcatbutton'] && ($rules['isbyuser'] || !$permiterror_retagcat); + + if ($rules['editbutton'] && $rules['retagcatbutton']) { // only show one button since they lead to the same form + if ($rules['retagcatable'] && !$rules['editable']) + $rules['editbutton']=false; // if we can do this without getting an error, show that as the title + else + $rules['retagcatbutton']=false; + } + + $rules['aselectable']=($post['type']=='Q') && !qa_user_permit_error($rules['isbyuser'] ? null : 'permit_select_a', null, $userlevel); + + $rules['flagbutton']=qa_opt('flagging_of_posts') && (!$rules['isbyuser']) && (!$post['hidden']) && (!$rules['queued']) && + (!@$post['userflag']) && ($permiterror_flag!='level') && ($permiterror_flag!='approve'); + $rules['flagtohide']=$rules['flagbutton'] && (!$permiterror_flag) && (($post['flagcount']+1)>=qa_opt('flagging_hide_after')); + $rules['unflaggable']=@$post['userflag'] && (!$post['hidden']); + $rules['clearflaggable']=($post['flagcount']>=(@$post['userflag'] ? 2 : 1)) && !qa_user_permit_error('permit_hide_show', null, $userlevel); + + // Other actions only show the button if it's immediately possible + + $notclosedbyother=!($rules['closed'] && isset($post['closedbyid']) && !$rules['authorlast']); + $nothiddenbyother=!($post['hidden'] && !$rules['authorlast']); + + $rules['closeable']=qa_opt('allow_close_questions') && ($post['type']=='Q') && (!$rules['closed']) && !$permiterror_close_open; + $rules['reopenable']=$rules['closed'] && isset($post['closedbyid']) && (!$permiterror_close_open) && (!$post['hidden']) && + ($notclosedbyother || !qa_user_permit_error('permit_close_q', null, $userlevel)); + // cannot reopen a question if it's been hidden, or if it was closed by someone else and you don't have global closing permissions + $rules['moderatable']=$rules['queued'] && !$permiterror_moderate; + $rules['hideable']=(!$post['hidden']) && ($rules['isbyuser'] || !$rules['queued']) && + (!$permiterror_hide_show) && ($notclosedbyother || !qa_user_permit_error('permit_hide_show', null, $userlevel)); + // cannot hide a question if it was closed by someone else and you don't have global hiding permissions + $rules['reshowimmed']=$post['hidden'] && !qa_user_permit_error('permit_hide_show', null, $userlevel); + // means post can be reshown immediately without checking whether it needs moderation + $rules['reshowable']=$post['hidden'] && (!$permiterror_hide_show) && + ($rules['reshowimmed'] || ($nothiddenbyother && !$post['flagcount'])); + // cannot reshow a question if it was hidden by someone else, or if it has flags - unless you have global hide/show permissions + $rules['deleteable']=$post['hidden'] && !qa_user_permit_error('permit_delete_hidden', null, $userlevel); + $rules['claimable']=(!isset($post['userid'])) && isset($userid) && strlen(@$post['cookieid']) && (strcmp(@$post['cookieid'], $cookieid)==0) && + !(($post['basetype']=='Q') ? $permiterror_post_q : (($post['basetype']=='A') ? $permiterror_post_a : $permiterror_post_c)); + $rules['followable']=($post['type']=='A') ? qa_opt('follow_on_as') : false; + + // Check for claims that could break rules about self answering and multiple answers + + if ($rules['claimable'] && ($post['basetype']=='A')) { + if ( (!qa_opt('allow_self_answer')) && isset($parentpost) && qa_post_is_by_user($parentpost, $userid, $cookieid) ) + $rules['claimable']=false; + + if (isset($siblingposts) && !qa_opt('allow_multi_answers')) + foreach ($siblingposts as $siblingpost) + if ( ($siblingpost['parentid']==$post['parentid']) && ($siblingpost['basetype']=='A') && qa_post_is_by_user($siblingpost, $userid, $cookieid)) + $rules['claimable']=false; + } + + // Now make any changes based on the child posts + + if (isset($childposts)) + foreach ($childposts as $childpost) + if ($childpost['parentid']==$post['postid']) { + $rules['deleteable']=false; + + if (($childpost['basetype']=='A') && qa_post_is_by_user($childpost, $userid, $cookieid)) { + if (!qa_opt('allow_multi_answers')) + $rules['answerbutton']=false; + + if (!qa_opt('allow_self_answer')) + $rules['claimable']=false; + } + } + + // Return the resulting rules + + return $rules; + } + + + function qa_page_q_question_view($question, $parentquestion, $closepost, $usershtml, $formrequested) +/* + Return the $qa_content['q_view'] element for $question as viewed by the current user. If this question is a + follow-on, pass the question for this question's parent answer in $parentquestion, otherwise null. If the question + is closed, pass the post used to close this question in $closepost, otherwise null. $usershtml should be an array + which maps userids to HTML user representations, including the question's author and (if present) last editor. If a + form has been explicitly requested for the page, set $formrequested to true - this will hide the buttons. +*/ + { + $questionid=$question['postid']; + $userid=qa_get_logged_in_userid(); + $cookieid=qa_cookie_get(); + + $htmloptions=qa_post_html_options($question, null, true); + $htmloptions['answersview']=false; // answer count is displayed separately so don't show it here + $htmloptions['avatarsize']=qa_opt('avatar_q_page_q_size'); + $htmloptions['q_request']=qa_q_request($question['postid'], $question['title']); + $q_view=qa_post_html_fields($question, $userid, $cookieid, $usershtml, null, $htmloptions); + + + $q_view['main_form_tags']='method="post" action="'.qa_self_html().'"'; + $q_view['voting_form_hidden']=array('code' => qa_get_form_security_code('vote')); + $q_view['buttons_form_hidden']=array('code' => qa_get_form_security_code('buttons-'.$questionid), 'qa_click' => ''); + + + // Buttons for operating on the question + + if (!$formrequested) { // don't show if another form is currently being shown on page + $clicksuffix=' onclick="qa_show_waiting_after(this, false);"'; // add to operations that write to database + $buttons=array(); + + if ($question['editbutton']) + $buttons['edit']=array( + 'tags' => 'name="q_doedit"', + 'label' => qa_lang_html('question/edit_button'), + 'popup' => qa_lang_html('question/edit_q_popup'), + ); + + $hascategories=qa_using_categories(); + + if ($question['retagcatbutton']) + $buttons['retagcat']=array( + 'tags' => 'name="q_doedit"', + 'label' => qa_lang_html($hascategories ? 'question/recat_button' : 'question/retag_button'), + 'popup' => qa_lang_html($hascategories + ? (qa_using_tags() ? 'question/retag_cat_popup' : 'question/recat_popup') + : 'question/retag_popup' + ), + ); + + if ($question['flagbutton']) + $buttons['flag']=array( + 'tags' => 'name="q_doflag"'.$clicksuffix, + 'label' => qa_lang_html($question['flagtohide'] ? 'question/flag_hide_button' : 'question/flag_button'), + 'popup' => qa_lang_html('question/flag_q_popup'), + ); + + if ($question['unflaggable']) + $buttons['unflag']=array( + 'tags' => 'name="q_dounflag"'.$clicksuffix, + 'label' => qa_lang_html('question/unflag_button'), + 'popup' => qa_lang_html('question/unflag_popup'), + ); + + if ($question['clearflaggable']) + $buttons['clearflags']=array( + 'tags' => 'name="q_doclearflags"'.$clicksuffix, + 'label' => qa_lang_html('question/clear_flags_button'), + 'popup' => qa_lang_html('question/clear_flags_popup'), + ); + + if ($question['closeable']) + $buttons['close']=array( + 'tags' => 'name="q_doclose"', + 'label' => qa_lang_html('question/close_button'), + 'popup' => qa_lang_html('question/close_q_popup'), + ); + + if ($question['reopenable']) + $buttons['reopen']=array( + 'tags' => 'name="q_doreopen"'.$clicksuffix, + 'label' => qa_lang_html('question/reopen_button'), + 'popup' => qa_lang_html('question/reopen_q_popup'), + ); + + if ($question['moderatable']) { + $buttons['approve']=array( + 'tags' => 'name="q_doapprove"'.$clicksuffix, + 'label' => qa_lang_html('question/approve_button'), + 'popup' => qa_lang_html('question/approve_q_popup'), + ); + + $buttons['reject']=array( + 'tags' => 'name="q_doreject"'.$clicksuffix, + 'label' => qa_lang_html('question/reject_button'), + 'popup' => qa_lang_html('question/reject_q_popup'), + ); + } + + if ($question['hideable']) + $buttons['hide']=array( + 'tags' => 'name="q_dohide"'.$clicksuffix, + 'label' => qa_lang_html('question/hide_button'), + 'popup' => qa_lang_html('question/hide_q_popup'), + ); + + if ($question['reshowable']) + $buttons['reshow']=array( + 'tags' => 'name="q_doreshow"'.$clicksuffix, + 'label' => qa_lang_html('question/reshow_button'), + 'popup' => qa_lang_html('question/reshow_q_popup'), + ); + + if ($question['deleteable']) + $buttons['delete']=array( + 'tags' => 'name="q_dodelete"'.$clicksuffix, + 'label' => qa_lang_html('question/delete_button'), + 'popup' => qa_lang_html('question/delete_q_popup'), + ); + + if ($question['claimable']) + $buttons['claim']=array( + 'tags' => 'name="q_doclaim"'.$clicksuffix, + 'label' => qa_lang_html('question/claim_button'), + 'popup' => qa_lang_html('question/claim_q_popup'), + ); + + if ($question['answerbutton']) // don't show if shown by default + $buttons['answer']=array( + 'tags' => 'name="q_doanswer" id="q_doanswer" onclick="return qa_toggle_element(\'anew\')"', + 'label' => qa_lang_html('question/answer_button'), + 'popup' => qa_lang_html('question/answer_q_popup'), + ); + + if ($question['commentbutton']) + $buttons['comment']=array( + 'tags' => 'name="q_docomment" onclick="return qa_toggle_element(\'c'.$questionid.'\')"', + 'label' => qa_lang_html('question/comment_button'), + 'popup' => qa_lang_html('question/comment_q_popup'), + ); + + $q_view['form']=array( + 'style' => 'light', + 'buttons' => $buttons, + ); + } + + + // Information about the question of the answer that this question follows on from (or a question directly) + + if (isset($parentquestion)) + $q_view['follows']=array( + 'label' => qa_lang_html(($question['parentid']==$parentquestion['postid']) ? 'question/follows_q' : 'question/follows_a'), + 'title' => qa_html(qa_block_words_replace($parentquestion['title'], qa_get_block_words_preg())), + 'url' => qa_q_path_html($parentquestion['postid'], $parentquestion['title'], false, + ($question['parentid']==$parentquestion['postid']) ? 'Q' : 'A', $question['parentid']), + ); + + + // Information about the question that this question is a duplicate of (if appropriate) + + if (isset($closepost)) { + + if ($closepost['basetype']=='Q') { + $q_view['closed']=array( + 'state' => qa_lang_html('main/closed'), + 'label' => qa_lang_html('question/closed_as_duplicate'), + 'content' => qa_html(qa_block_words_replace($closepost['title'], qa_get_block_words_preg())), + 'url' => qa_q_path_html($closepost['postid'], $closepost['title']), + ); + + } elseif ($closepost['type']=='NOTE') { + $viewer=qa_load_viewer($closepost['content'], $closepost['format']); + + $q_view['closed']=array( + 'state' => qa_lang_html('main/closed'), + 'label' => qa_lang_html('question/closed_with_note'), + 'content' => $viewer->get_html($closepost['content'], $closepost['format'], array( + 'blockwordspreg' => qa_get_block_words_preg(), + )), + ); + } + } + + + // Extra value display + + if (strlen(@$question['extra']) && qa_opt('extra_field_active') && qa_opt('extra_field_display')) + $q_view['extra']=array( + 'label' => qa_html(qa_opt('extra_field_label')), + 'content' => qa_html(qa_block_words_replace($question['extra'], qa_get_block_words_preg())), + ); + + + return $q_view; + } + + + function qa_page_q_answer_view($question, $answer, $isselected, $usershtml, $formrequested) +/* + Returns an element to add to $qa_content['a_list']['as'] for $answer as viewed by $userid and $cookieid. Pass the + answer's $question and whether it $isselected. $usershtml should be an array which maps userids to HTML user + representations, including the answer's author and (if present) last editor. If a form has been explicitly requested + for the page, set $formrequested to true - this will hide the buttons. +*/ + { + $answerid=$answer['postid']; + $userid=qa_get_logged_in_userid(); + $cookieid=qa_cookie_get(); + + $htmloptions=qa_post_html_options($answer, null, true); + $htmloptions['isselected']=$isselected; + $htmloptions['avatarsize']=qa_opt('avatar_q_page_a_size'); + $htmloptions['q_request']=qa_q_request($question['postid'], $question['title']); + $a_view=qa_post_html_fields($answer, $userid, $cookieid, $usershtml, null, $htmloptions); + + if ($answer['queued']) + $a_view['error']=$answer['isbyuser'] ? qa_lang_html('question/a_your_waiting_approval') : qa_lang_html('question/a_waiting_your_approval'); + + $a_view['main_form_tags']='method="post" action="'.qa_self_html().'"'; + $a_view['voting_form_hidden']=array('code' => qa_get_form_security_code('vote')); + $a_view['buttons_form_hidden']=array('code' => qa_get_form_security_code('buttons-'.$answerid), 'qa_click' => ''); + + + // Selection/unselect buttons and others for operating on the answer + + if (!$formrequested) { // don't show if another form is currently being shown on page + $prefix='a'.qa_html($answerid).'_'; + $clicksuffix=' onclick="return qa_answer_click('.qa_js($answerid).', '.qa_js($question['postid']).', this);"'; + + if ($question['aselectable'] && !$answer['hidden'] && !$answer['queued']) { + if ($isselected) + $a_view['unselect_tags']='title="'.qa_lang_html('question/unselect_popup').'" name="'.$prefix.'dounselect"'.$clicksuffix; + else + $a_view['select_tags']='title="'.qa_lang_html('question/select_popup').'" name="'.$prefix.'doselect"'.$clicksuffix; + } + + $buttons=array(); + + if ($answer['editbutton']) + $buttons['edit']=array( + 'tags' => 'name="'.$prefix.'doedit"', + 'label' => qa_lang_html('question/edit_button'), + 'popup' => qa_lang_html('question/edit_a_popup'), + ); + + if ($answer['flagbutton']) + $buttons['flag']=array( + 'tags' => 'name="'.$prefix.'doflag"'.$clicksuffix, + 'label' => qa_lang_html($answer['flagtohide'] ? 'question/flag_hide_button' : 'question/flag_button'), + 'popup' => qa_lang_html('question/flag_a_popup'), + ); + + if ($answer['unflaggable']) + $buttons['unflag']=array( + 'tags' => 'name="'.$prefix.'dounflag"'.$clicksuffix, + 'label' => qa_lang_html('question/unflag_button'), + 'popup' => qa_lang_html('question/unflag_popup'), + ); + + if ($answer['clearflaggable']) + $buttons['clearflags']=array( + 'tags' => 'name="'.$prefix.'doclearflags"'.$clicksuffix, + 'label' => qa_lang_html('question/clear_flags_button'), + 'popup' => qa_lang_html('question/clear_flags_popup'), + ); + + if ($answer['moderatable']) { + $buttons['approve']=array( + 'tags' => 'name="'.$prefix.'doapprove"'.$clicksuffix, + 'label' => qa_lang_html('question/approve_button'), + 'popup' => qa_lang_html('question/approve_a_popup'), + ); + + $buttons['reject']=array( + 'tags' => 'name="'.$prefix.'doreject"'.$clicksuffix, + 'label' => qa_lang_html('question/reject_button'), + 'popup' => qa_lang_html('question/reject_a_popup'), + ); + } + + if ($answer['hideable']) + $buttons['hide']=array( + 'tags' => 'name="'.$prefix.'dohide"'.$clicksuffix, + 'label' => qa_lang_html('question/hide_button'), + 'popup' => qa_lang_html('question/hide_a_popup'), + ); + + if ($answer['reshowable']) + $buttons['reshow']=array( + 'tags' => 'name="'.$prefix.'doreshow"'.$clicksuffix, + 'label' => qa_lang_html('question/reshow_button'), + 'popup' => qa_lang_html('question/reshow_a_popup'), + ); + + if ($answer['deleteable']) + $buttons['delete']=array( + 'tags' => 'name="'.$prefix.'dodelete"'.$clicksuffix, + 'label' => qa_lang_html('question/delete_button'), + 'popup' => qa_lang_html('question/delete_a_popup'), + ); + + if ($answer['claimable']) + $buttons['claim']=array( + 'tags' => 'name="'.$prefix.'doclaim"'.$clicksuffix, + 'label' => qa_lang_html('question/claim_button'), + 'popup' => qa_lang_html('question/claim_a_popup'), + ); + + if ($answer['followable']) + $buttons['follow']=array( + 'tags' => 'name="'.$prefix.'dofollow"', + 'label' => qa_lang_html('question/follow_button'), + 'popup' => qa_lang_html('question/follow_a_popup'), + ); + + if ($answer['commentbutton']) + $buttons['comment']=array( + 'tags' => 'name="'.$prefix.'docomment" onclick="return qa_toggle_element(\'c'.$answerid.'\')"', + 'label' => qa_lang_html('question/comment_button'), + 'popup' => qa_lang_html('question/comment_a_popup'), + ); + + $a_view['form']=array( + 'style' => 'light', + 'buttons' => $buttons, + ); + } + + return $a_view; + } + + + function qa_page_q_comment_view($question, $parent, $comment, $usershtml, $formrequested) +/* + Returns an element to add to the appropriate $qa_content[...]['c_list']['cs'] array for $comment as viewed by the + current user. Pass the comment's $parent post and antecedent $question. $usershtml should be an array which maps + userids to HTML user representations, including the comments's author and (if present) last editor. If a form has + been explicitly requested for the page, set $formrequested to true - this will hide the buttons. +*/ + { + $commentid=$comment['postid']; + $questionid=($parent['basetype']=='Q') ? $parent['postid'] : $parent['parentid']; + $answerid=($parent['basetype']=='Q') ? null : $parent['postid']; + $userid=qa_get_logged_in_userid(); + $cookieid=qa_cookie_get(); + + $htmloptions=qa_post_html_options($comment, null, true); + $htmloptions['avatarsize']=qa_opt('avatar_q_page_c_size'); + $htmloptions['q_request']=qa_q_request($question['postid'], $question['title']); + $c_view=qa_post_html_fields($comment, $userid, $cookieid, $usershtml, null, $htmloptions); + + if ($comment['queued']) + $c_view['error']=$comment['isbyuser'] ? qa_lang_html('question/c_your_waiting_approval') : qa_lang_html('question/c_waiting_your_approval'); + + + // Buttons for operating on this comment + + if (!$formrequested) { // don't show if another form is currently being shown on page + $prefix='c'.qa_html($commentid).'_'; + $clicksuffix=' onclick="return qa_comment_click('.qa_js($commentid).', '.qa_js($questionid).', '.qa_js($parent['postid']).', this);"'; + + $buttons=array(); + + if ($comment['editbutton']) + $buttons['edit']=array( + 'tags' => 'name="'.$prefix.'doedit"', + 'label' => qa_lang_html('question/edit_button'), + 'popup' => qa_lang_html('question/edit_c_popup'), + ); + + if ($comment['flagbutton']) + $buttons['flag']=array( + 'tags' => 'name="'.$prefix.'doflag"'.$clicksuffix, + 'label' => qa_lang_html($comment['flagtohide'] ? 'question/flag_hide_button' : 'question/flag_button'), + 'popup' => qa_lang_html('question/flag_c_popup'), + ); + + if ($comment['unflaggable']) + $buttons['unflag']=array( + 'tags' => 'name="'.$prefix.'dounflag"'.$clicksuffix, + 'label' => qa_lang_html('question/unflag_button'), + 'popup' => qa_lang_html('question/unflag_popup'), + ); + + if ($comment['clearflaggable']) + $buttons['clearflags']=array( + 'tags' => 'name="'.$prefix.'doclearflags"'.$clicksuffix, + 'label' => qa_lang_html('question/clear_flags_button'), + 'popup' => qa_lang_html('question/clear_flags_popup'), + ); + + if ($comment['moderatable']) { + $buttons['approve']=array( + 'tags' => 'name="'.$prefix.'doapprove"'.$clicksuffix, + 'label' => qa_lang_html('question/approve_button'), + 'popup' => qa_lang_html('question/approve_c_popup'), + ); + + $buttons['reject']=array( + 'tags' => 'name="'.$prefix.'doreject"'.$clicksuffix, + 'label' => qa_lang_html('question/reject_button'), + 'popup' => qa_lang_html('question/reject_c_popup'), + ); + } + + if ($comment['hideable']) + $buttons['hide']=array( + 'tags' => 'name="'.$prefix.'dohide"'.$clicksuffix, + 'label' => qa_lang_html('question/hide_button'), + 'popup' => qa_lang_html('question/hide_c_popup'), + ); + + if ($comment['reshowable']) + $buttons['reshow']=array( + 'tags' => 'name="'.$prefix.'doreshow"'.$clicksuffix, + 'label' => qa_lang_html('question/reshow_button'), + 'popup' => qa_lang_html('question/reshow_c_popup'), + ); + + if ($comment['deleteable']) + $buttons['delete']=array( + 'tags' => 'name="'.$prefix.'dodelete"'.$clicksuffix, + 'label' => qa_lang_html('question/delete_button'), + 'popup' => qa_lang_html('question/delete_c_popup'), + ); + + if ($comment['claimable']) + $buttons['claim']=array( + 'tags' => 'name="'.$prefix.'doclaim"'.$clicksuffix, + 'label' => qa_lang_html('question/claim_button'), + 'popup' => qa_lang_html('question/claim_c_popup'), + ); + + if ($parent['commentbutton'] && qa_opt('show_c_reply_buttons') && ($comment['type']=='C')) + $buttons['comment']=array( + 'tags' => 'name="'.(($parent['basetype']=='Q') ? 'q' : ('a'.qa_html($parent['postid']))). + '_docomment" onclick="return qa_toggle_element(\'c'.qa_html($parent['postid']).'\')"', + 'label' => qa_lang_html('question/reply_button'), + 'popup' => qa_lang_html('question/reply_c_popup'), + ); + + $c_view['form']=array( + 'style' => 'light', + 'buttons' => $buttons, + ); + } + + return $c_view; + } + + + function qa_page_q_comment_follow_list($question, $parent, $commentsfollows, $alwaysfull, $usershtml, $formrequested, $formpostid) +/* + Return an array for $qa_content[...]['c_list'] to display all of the comments and follow-on questions in + $commentsfollows which belong to post $parent with antecedent $question, as viewed by the current user. If + $alwaysfull then all comments will be included, otherwise the list may be shortened with a 'show previous x + comments' link. $usershtml should be an array which maps userids to HTML user representations, including all + comments' and follow on questions' authors and (if present) last editors. If a form has been explicitly requested + for the page, set $formrequested to true and pass the postid of the post for the form in $formpostid - this will + hide the buttons and remove the $formpostid comment from the list. +*/ + { + $parentid=$parent['postid']; + $userid=qa_get_logged_in_userid(); + $cookieid=qa_cookie_get(); + + $commentlist=array( + 'tags' => 'id="c'.qa_html($parentid).'_list"', + 'cs' => array(), + ); + + $showcomments=array(); + + foreach ($commentsfollows as $commentfollowid => $commentfollow) + if (($commentfollow['parentid']==$parentid) && $commentfollow['viewable'] && ($commentfollowid!=$formpostid) ) + $showcomments[$commentfollowid]=$commentfollow; + + $countshowcomments=count($showcomments); + + if ( (!$alwaysfull) && ($countshowcomments > qa_opt('show_fewer_cs_from')) ) + $skipfirst=$countshowcomments-qa_opt('show_fewer_cs_count'); + else + $skipfirst=0; + + if ($skipfirst==$countshowcomments) { // showing none + if ($skipfirst==1) + $expandtitle=qa_lang_html('question/show_1_comment'); + else + $expandtitle=qa_lang_html_sub('question/show_x_comments', $skipfirst); + + } else { + if ($skipfirst==1) + $expandtitle=qa_lang_html('question/show_1_previous_comment'); + else + $expandtitle=qa_lang_html_sub('question/show_x_previous_comments', $skipfirst); + } + + if ($skipfirst>0) + $commentlist['cs'][$parentid]=array( + 'url' => qa_html('?state=showcomments-'.$parentid.'&show='.$parentid.'#'.urlencode(qa_anchor($parent['basetype'], $parentid))), + + 'expand_tags' => 'onclick="return qa_show_comments('.qa_js($question['postid']).', '.qa_js($parentid).', this);"', + + 'title' => $expandtitle, + ); + + foreach ($showcomments as $commentfollowid => $commentfollow) + if ($skipfirst>0) + $skipfirst--; + + elseif ($commentfollow['basetype']=='C') { + $commentlist['cs'][$commentfollowid]=qa_page_q_comment_view($question, $parent, $commentfollow, $usershtml, $formrequested); + + } elseif ($commentfollow['basetype']=='Q') { + $htmloptions=qa_post_html_options($commentfollow); + $htmloptions['avatarsize']=qa_opt('avatar_q_page_c_size'); + + $commentlist['cs'][$commentfollowid]=qa_post_html_fields($commentfollow, $userid, $cookieid, $usershtml, null, $htmloptions); + } + + if (!count($commentlist['cs'])) + $commentlist['hidden']=true; + + return $commentlist; + } + + + function qa_page_q_add_a_form(&$qa_content, $formid, $captchareason, $question, $in, $errors, $loadnow, $formrequested) +/* + Return a $qa_content form for adding an answer to $question. Pass an HTML element id to use for the form in $formid + and the result of qa_user_captcha_reason() in $captchareason. Pass previous inputs from a submitted version of this + form in the array $in and resulting errors in $errors. If $loadnow is true, the form will be loaded immediately. Set + $formrequested to true if the user explicitly requested it, as opposed being shown automatically. +*/ + { + // The 'approve', 'login', 'confirm', 'limit', 'userblock', 'ipblock' permission errors are reported to the user here + // The other option ('level') prevents the answer button being shown, in qa_page_q_post_rules(...) + + switch (qa_user_post_permit_error('permit_post_a', $question, QA_LIMIT_ANSWERS)) { + case 'login': + $form=array( + 'title' => qa_insert_login_links(qa_lang_html('question/answer_must_login'), qa_request()) + ); + break; + + case 'confirm': + $form=array( + 'title' => qa_insert_login_links(qa_lang_html('question/answer_must_confirm'), qa_request()) + ); + break; + + case 'approve': + $form=array( + 'title' => qa_lang_html('question/answer_must_be_approved') + ); + break; + + case 'limit': + $form=array( + 'title' => qa_lang_html('question/answer_limit') + ); + break; + + default: + $form=array( + 'title' => qa_lang_html('users/no_permission') + ); + break; + + case false: + $editorname=isset($in['editor']) ? $in['editor'] : qa_opt('editor_for_as'); + $editor=qa_load_editor(@$in['content'], @$in['format'], $editorname); + + if (method_exists($editor, 'update_script')) + $updatescript=$editor->update_script('a_content'); + else + $updatescript=''; + + $custom=qa_opt('show_custom_answer') ? trim(qa_opt('custom_answer')) : ''; + + $form=array( + 'tags' => 'method="post" action="'.qa_self_html().'" name="a_form"', + + 'title' => qa_lang_html('question/your_answer_title'), + + 'fields' => array( + 'custom' => array( + 'type' => 'custom', + 'note' => $custom, + ), + + 'content' => array_merge( + qa_editor_load_field($editor, $qa_content, @$in['content'], @$in['format'], 'a_content', 12, $formrequested, $loadnow), + array( + 'error' => qa_html(@$errors['content']), + ) + ), + ), + + 'buttons' => array( + 'answer' => array( + 'tags' => 'onclick="'.$updatescript.' return qa_submit_answer('.qa_js($question['postid']).', this);"', + 'label' => qa_lang_html('question/add_answer_button'), + ), + ), + + 'hidden' => array( + 'a_editor' => qa_html($editorname), + 'a_doadd' => '1', + 'code' => qa_get_form_security_code('answer-'.$question['postid']), + ), + ); + + if (!strlen($custom)) + unset($form['fields']['custom']); + + if ($formrequested || !$loadnow) + $form['buttons']['cancel']=array( + 'tags' => 'name="docancel"', + 'label' => qa_lang_html('main/cancel_button'), + ); + + if (!qa_is_logged_in()) + qa_set_up_name_field($qa_content, $form['fields'], @$in['name'], 'a_'); + + qa_set_up_notify_fields($qa_content, $form['fields'], 'A', qa_get_logged_in_email(), + isset($in['notify']) ? $in['notify'] : qa_opt('notify_users_default'), @$in['email'], @$errors['email'], 'a_'); + + $onloads=array(); + + if ($captchareason) { + $captchaloadscript=qa_set_up_captcha_field($qa_content, $form['fields'], $errors, qa_captcha_reason_note($captchareason)); + + if (strlen($captchaloadscript)) + $onloads[]='document.getElementById('.qa_js($formid).').qa_show=function() { '.$captchaloadscript.' };'; + } + + if (!$loadnow) { + if (method_exists($editor, 'load_script')) + $onloads[]='document.getElementById('.qa_js($formid).').qa_load=function() { '.$editor->load_script('a_content').' };'; + + $form['buttons']['cancel']['tags'].=' onclick="return qa_toggle_element();"'; + } + + if (!$formrequested) { + if (method_exists($editor, 'focus_script')) + $onloads[]='document.getElementById('.qa_js($formid).').qa_focus=function() { '.$editor->focus_script('a_content').' };'; + } + + if (count($onloads)) + $qa_content['script_onloads'][]=$onloads; + break; + } + + $form['id']=$formid; + $form['collapse']=!$loadnow; + $form['style']='tall'; + + return $form; + } + + + function qa_page_q_add_c_form(&$qa_content, $question, $parent, $formid, $captchareason, $in, $errors, $loadfocusnow) +/* + Returns a $qa_content form for adding a comment to post $parent which is part of $question. Pass an HTML element id + to use for the form in $formid and the result of qa_user_captcha_reason() in $captchareason. Pass previous inputs + from a submitted version of this form in the array $in and resulting errors in $errors. If $loadfocusnow is true, + the form will be loaded and focused immediately. +*/ + { + // The 'approve', 'login', 'confirm', 'userblock', 'ipblock' permission errors are reported to the user here + // The other option ('level') prevents the comment button being shown, in qa_page_q_post_rules(...) + + switch (qa_user_post_permit_error('permit_post_c', $parent, QA_LIMIT_COMMENTS)) { + case 'login': + $form=array( + 'title' => qa_insert_login_links(qa_lang_html('question/comment_must_login'), qa_request()) + ); + break; + + case 'confirm': + $form=array( + 'title' => qa_insert_login_links(qa_lang_html('question/comment_must_confirm'), qa_request()) + ); + break; + + case 'approve': + $form=array( + 'title' => qa_lang_html('question/comment_must_be_approved') + ); + break; + + case 'limit': + $form=array( + 'title' => qa_lang_html('question/comment_limit') + ); + break; + + default: + $form=array( + 'title' => qa_lang_html('users/no_permission') + ); + break; + + case false: + $prefix='c'.$parent['postid'].'_'; + + $editorname=isset($in['editor']) ? $in['editor'] : qa_opt('editor_for_cs'); + $editor=qa_load_editor(@$in['content'], @$in['format'], $editorname); + + if (method_exists($editor, 'update_script')) + $updatescript=$editor->update_script($prefix.'content'); + else + $updatescript=''; + + $custom=qa_opt('show_custom_comment') ? trim(qa_opt('custom_comment')) : ''; + + $form=array( + 'tags' => 'method="post" action="'.qa_self_html().'" name="c_form_'.qa_html($parent['postid']).'"', + + 'title' => qa_lang_html(($question['postid']==$parent['postid']) ? 'question/your_comment_q' : 'question/your_comment_a'), + + 'fields' => array( + 'custom' => array( + 'type' => 'custom', + 'note' => $custom, + ), + + 'content' => array_merge( + qa_editor_load_field($editor, $qa_content, @$in['content'], @$in['format'], $prefix.'content', 4, $loadfocusnow, $loadfocusnow), + array( + 'error' => qa_html(@$errors['content']), + ) + ), + ), + + 'buttons' => array( + 'comment' => array( + 'tags' => 'onclick="'.$updatescript.' return qa_submit_comment('.qa_js($question['postid']).', '.qa_js($parent['postid']).', this);"', + 'label' => qa_lang_html('question/add_comment_button'), + ), + + 'cancel' => array( + 'tags' => 'name="docancel"', + 'label' => qa_lang_html('main/cancel_button'), + ), + ), + + 'hidden' => array( + $prefix.'editor' => qa_html($editorname), + $prefix.'doadd' => '1', + $prefix.'code' => qa_get_form_security_code('comment-'.$parent['postid']), + ), + ); + + if (!strlen($custom)) + unset($form['fields']['custom']); + + if (!qa_is_logged_in()) + qa_set_up_name_field($qa_content, $form['fields'], @$in['name'], $prefix); + + qa_set_up_notify_fields($qa_content, $form['fields'], 'C', qa_get_logged_in_email(), + isset($in['notify']) ? $in['notify'] : qa_opt('notify_users_default'), $in['email'], @$errors['email'], $prefix); + + $onloads=array(); + + if ($captchareason) { + $captchaloadscript=qa_set_up_captcha_field($qa_content, $form['fields'], $errors, qa_captcha_reason_note($captchareason)); + + if (strlen($captchaloadscript)) + $onloads[]='document.getElementById('.qa_js($formid).').qa_show=function() { '.$captchaloadscript.' };'; + } + + if (!$loadfocusnow) { + if (method_exists($editor, 'load_script')) + $onloads[]='document.getElementById('.qa_js($formid).').qa_load=function() { '.$editor->load_script($prefix.'content').' };'; + if (method_exists($editor, 'focus_script')) + $onloads[]='document.getElementById('.qa_js($formid).').qa_focus=function() { '.$editor->focus_script($prefix.'content').' };'; + + $form['buttons']['cancel']['tags'].=' onclick="return qa_toggle_element()"'; + } + + if (count($onloads)) + $qa_content['script_onloads'][]=$onloads; + } + + $form['id']=$formid; + $form['collapse']=!$loadfocusnow; + $form['style']='tall'; + + return $form; + } + + +/* + Omit PHP closing tag to help avoid accidental output +*/ \ No newline at end of file diff --git a/pages/question.php b/pages/question.php new file mode 100644 index 0000000..d51acc5 --- /dev/null +++ b/pages/question.php @@ -0,0 +1,426 @@ + $answer) { + $answers[$key]=$answer+qa_page_q_post_rules($answer, $question, $answers, $achildposts); + $answers[$key]['isselected']=($answer['postid']==$question['selchildid']); + } + + foreach ($commentsfollows as $key => $commentfollow) { + $parent=($commentfollow['parentid']==$questionid) ? $question : @$answers[$commentfollow['parentid']]; + $commentsfollows[$key]=$commentfollow+qa_page_q_post_rules($commentfollow, $parent, $commentsfollows, null); + } + } + +// Deal with question not found or not viewable, otherwise report the view event + + if (!isset($question)) + return include QA_INCLUDE_DIR.'qa-page-not-found.php'; + + if (!$question['viewable']) { + $qa_content=qa_content_prepare(); + + if ($question['queued']) + $qa_content['error']=qa_lang_html('question/q_waiting_approval'); + elseif ($question['flagcount'] && !isset($question['lastuserid'])) + $qa_content['error']=qa_lang_html('question/q_hidden_flagged'); + elseif ($question['authorlast']) + $qa_content['error']=qa_lang_html('question/q_hidden_author'); + else + $qa_content['error']=qa_lang_html('question/q_hidden_other'); + + $qa_content['suggest_next']=qa_html_suggest_qs_tags(qa_using_tags()); + + return $qa_content; + } + + $permiterror=qa_user_post_permit_error('permit_view_q_page', $question, null, false); + + if ( $permiterror && (qa_is_human_probably() || !qa_opt('allow_view_q_bots')) ) { + $qa_content=qa_content_prepare(); + $topage=qa_q_request($questionid, $question['title']); + + switch ($permiterror) { + case 'login': + $qa_content['error']=qa_insert_login_links(qa_lang_html('main/view_q_must_login'), $topage); + break; + + case 'confirm': + $qa_content['error']=qa_insert_login_links(qa_lang_html('main/view_q_must_confirm'), $topage); + break; + + case 'approve': + $qa_content['error']=qa_lang_html('main/view_q_must_be_approved'); + break; + + default: + $qa_content['error']=qa_lang_html('users/no_permission'); + break; + } + + return $qa_content; + } + + +// Determine if captchas will be required + + $captchareason=qa_user_captcha_reason(qa_user_level_for_post($question)); + $usecaptcha=($captchareason!=false); + + +// If we're responding to an HTTP POST, include file that handles all posting/editing/etc... logic +// This is in a separate file because it's a *lot* of logic, and will slow down ordinary page views + + $pagestart=qa_get_start(); + $pagestate=qa_get_state(); + $showid=qa_get('show'); + $pageerror=null; + $formtype=null; + $formpostid=null; + $jumptoanchor=null; + $commentsall=null; + + if (substr($pagestate, 0, 13)=='showcomments-') { + $commentsall=substr($pagestate, 13); + $pagestate=null; + + } elseif (isset($showid)) { + foreach ($commentsfollows as $comment) + if ($comment['postid']==$showid) { + $commentsall=$comment['parentid']; + break; + } + } + + if (qa_is_http_post() || strlen($pagestate)) + require QA_INCLUDE_DIR.'pages/question-post.php'; + + $formrequested=isset($formtype); + + if ((!$formrequested) && $question['answerbutton']) { + $immedoption=qa_opt('show_a_form_immediate'); + + if ( ($immedoption=='always') || (($immedoption=='if_no_as') && (!$question['isbyuser']) && (!$question['acount'])) ) + $formtype='a_add'; // show answer form by default + } + + +// Get information on the users referenced + + $usershtml=qa_userids_handles_html(array_merge(array($question), $answers, $commentsfollows), true); + + +// Prepare content for theme + + $qa_content=qa_content_prepare(true, array_keys(qa_category_path($categories, $question['categoryid']))); + + if (isset($userid) && !$formrequested) + $qa_content['favorite']=qa_favorite_form(QA_ENTITY_QUESTION, $questionid, $favorite, + qa_lang($favorite ? 'question/remove_q_favorites' : 'question/add_q_favorites')); + + $qa_content['script_rel'][]='qa-content/qa-question.js?'.QA_VERSION; + + if (isset($pageerror)) + $qa_content['error']=$pageerror; // might also show voting error set in qa-index.php + + elseif ($question['queued']) + $qa_content['error']=$question['isbyuser'] ? qa_lang_html('question/q_your_waiting_approval') : qa_lang_html('question/q_waiting_your_approval'); + + if ($question['hidden']) + $qa_content['hidden']=true; + + qa_sort_by($commentsfollows, 'created'); + + +// Prepare content for the question... + + if ($formtype=='q_edit') { // ...in edit mode + $qa_content['title']=qa_lang_html($question['editable'] ? 'question/edit_q_title' : + (qa_using_categories() ? 'question/recat_q_title' : 'question/retag_q_title')); + $qa_content['form_q_edit']=qa_page_q_edit_q_form($qa_content, $question, @$qin, @$qerrors, $completetags, $categories); + $qa_content['q_view']['raw']=$question; + + } else { // ...in view mode + $qa_content['q_view']=qa_page_q_question_view($question, $parentquestion, $closepost, $usershtml, $formrequested); + + $qa_content['title']=$qa_content['q_view']['title']; + + $qa_content['description']=qa_html(qa_shorten_string_line(qa_viewer_text($question['content'], $question['format']), 150)); + + $categorykeyword=@$categories[$question['categoryid']]['title']; + + $qa_content['keywords']=qa_html(implode(',', array_merge( + (qa_using_categories() && strlen($categorykeyword)) ? array($categorykeyword) : array(), + qa_tagstring_to_tags($question['tags']) + ))); // as far as I know, META keywords have zero effect on search rankings or listings, but many people have asked for this + } + + +// Prepare content for an answer being edited (if any) or to be added + + if ($formtype=='a_edit') { + $qa_content['a_form']=qa_page_q_edit_a_form($qa_content, 'a'.$formpostid, $answers[$formpostid], + $question, $answers, $commentsfollows, @$aeditin[$formpostid], @$aediterrors[$formpostid]); + + $qa_content['a_form']['c_list']=qa_page_q_comment_follow_list($question, $answers[$formpostid], + $commentsfollows, true, $usershtml, $formrequested, $formpostid); + + $jumptoanchor='a'.$formpostid; + + } elseif (($formtype=='a_add') || ($question['answerbutton'] && !$formrequested)) { + $qa_content['a_form']=qa_page_q_add_a_form($qa_content, 'anew', $captchareason, $question, @$anewin, @$anewerrors, $formtype=='a_add', $formrequested); + + if ($formrequested) + $jumptoanchor='anew'; + elseif ($formtype=='a_add') + $qa_content['script_onloads'][]=array( + "qa_element_revealed=document.getElementById('anew');" + ); + } + + +// Prepare content for comments on the question, plus add or edit comment forms + + if ($formtype=='q_close') { + $qa_content['q_view']['c_form']=qa_page_q_close_q_form($qa_content, $question, 'close', @$closein, @$closeerrors); + $jumptoanchor='close'; + + } elseif ((($formtype=='c_add') && ($formpostid==$questionid)) || ($question['commentbutton'] && !$formrequested) ) { // ...to be added + $qa_content['q_view']['c_form']=qa_page_q_add_c_form($qa_content, $question, $question, 'c'.$questionid, + $captchareason, @$cnewin[$questionid], @$cnewerrors[$questionid], $formtype=='c_add'); + + if (($formtype=='c_add') && ($formpostid==$questionid)) { + $jumptoanchor='c'.$questionid; + $commentsall=$questionid; + } + + } elseif (($formtype=='c_edit') && (@$commentsfollows[$formpostid]['parentid']==$questionid)) { // ...being edited + $qa_content['q_view']['c_form']=qa_page_q_edit_c_form($qa_content, 'c'.$formpostid, $commentsfollows[$formpostid], + @$ceditin[$formpostid], @$cediterrors[$formpostid]); + + $jumptoanchor='c'.$formpostid; + $commentsall=$questionid; + } + + $qa_content['q_view']['c_list']=qa_page_q_comment_follow_list($question, $question, $commentsfollows, + $commentsall==$questionid, $usershtml, $formrequested, $formpostid); // ...for viewing + + +// Prepare content for existing answers (could be added to by Ajax) + + $qa_content['a_list']=array( + 'tags' => 'id="a_list"', + 'as' => array(), + ); + + // sort according to the site preferences + + if (qa_opt('sort_answers_by')=='votes') { + foreach ($answers as $answerid => $answer) + $answers[$answerid]['sortvotes']=$answer['downvotes']-$answer['upvotes']; + + qa_sort_by($answers, 'sortvotes', 'created'); + + } else + qa_sort_by($answers, 'created'); + + // further changes to ordering to deal with queued, hidden and selected answers + + $countfortitle=$question['acount']; + $nextposition=10000; + $answerposition=array(); + + foreach ($answers as $answerid => $answer) + if ($answer['viewable']) { + $position=$nextposition++; + + if ($answer['hidden']) + $position+=10000; + + elseif ($answer['queued']) { + $position-=10000; + $countfortitle++; // include these in displayed count + + } elseif ($answer['isselected'] && qa_opt('show_selected_first')) + $position-=5000; + + $answerposition[$answerid]=$position; + } + + asort($answerposition, SORT_NUMERIC); + + // extract IDs and prepare for pagination + + $answerids=array_keys($answerposition); + $countforpages=count($answerids); + $pagesize=qa_opt('page_size_q_as'); + + // see if we need to display a particular answer + + if (isset($showid)) { + if (isset($commentsfollows[$showid])) + $showid=$commentsfollows[$showid]['parentid']; + + $position=array_search($showid, $answerids); + + if (is_numeric($position)) + $pagestart=floor($position/$pagesize)*$pagesize; + } + + // set the canonical url based on possible pagination + + $qa_content['canonical']=qa_path_html(qa_q_request($question['postid'], $question['title']), + ($pagestart>0) ? array('start' => $pagestart) : null, qa_opt('site_url')); + + // build the actual answer list + + $answerids=array_slice($answerids, $pagestart, $pagesize); + + foreach ($answerids as $answerid) { + $answer=$answers[$answerid]; + + if (!(($formtype=='a_edit') && ($formpostid==$answerid))) { + $a_view=qa_page_q_answer_view($question, $answer, $answer['isselected'], $usershtml, $formrequested); + + // Prepare content for comments on this answer, plus add or edit comment forms + + if ((($formtype=='c_add') && ($formpostid==$answerid)) || ($answer['commentbutton'] && !$formrequested) ) { // ...to be added + $a_view['c_form']=qa_page_q_add_c_form($qa_content, $question, $answer, 'c'.$answerid, + $captchareason, @$cnewin[$answerid], @$cnewerrors[$answerid], $formtype=='c_add'); + + if (($formtype=='c_add') && ($formpostid==$answerid)) { + $jumptoanchor='c'.$answerid; + $commentsall=$answerid; + } + + } elseif (($formtype=='c_edit') && (@$commentsfollows[$formpostid]['parentid']==$answerid)) { // ...being edited + $a_view['c_form']=qa_page_q_edit_c_form($qa_content, 'c'.$formpostid, $commentsfollows[$formpostid], + @$ceditin[$formpostid], @$cediterrors[$formpostid]); + + $jumptoanchor='c'.$formpostid; + $commentsall=$answerid; + } + + $a_view['c_list']=qa_page_q_comment_follow_list($question, $answer, $commentsfollows, + $commentsall==$answerid, $usershtml, $formrequested, $formpostid); // ...for viewing + + // Add the answer to the list + + $qa_content['a_list']['as'][]=$a_view; + } + } + + if ($question['basetype']=='Q') { + $qa_content['a_list']['title_tags']='id="a_list_title"'; + + if ($countfortitle==1) + $qa_content['a_list']['title']=qa_lang_html('question/1_answer_title'); + elseif ($countfortitle>0) + $qa_content['a_list']['title']=qa_lang_html_sub('question/x_answers_title', $countfortitle); + else + $qa_content['a_list']['title_tags'].=' style="display:none;" '; + } + + if (!$formrequested) + $qa_content['page_links']=qa_html_page_links(qa_request(), $pagestart, $pagesize, $countforpages, qa_opt('pages_prev_next'), array(), false, 'a_list_title'); + + +// Some generally useful stuff + + if (qa_using_categories() && count($categories)) + $qa_content['navigation']['cat']=qa_category_navigation($categories, $question['categoryid']); + + if (isset($jumptoanchor)) + $qa_content['script_onloads'][]=array( + 'qa_scroll_page_to($("#"+'.qa_js($jumptoanchor).').offset().top);' + ); + + +// Determine whether this request should be counted for page view statistics + + if ( + qa_opt('do_count_q_views') && + (!$formrequested) && + (!qa_is_http_post()) && + qa_is_human_probably() && + ( (!$question['views']) || ( // if it has more than zero views + ( ($question['lastviewip']!=qa_remote_ip_address()) || (!isset($question['lastviewip'])) ) && // then it must be different IP from last view + ( ($question['createip']!=qa_remote_ip_address()) || (!isset($question['createip'])) ) && // and different IP from the creator + ( ($question['userid']!=$userid) || (!isset($question['userid'])) ) && // and different user from the creator + ( ($question['cookieid']!=$cookieid) || (!isset($question['cookieid'])) ) // and different cookieid from the creator + ) ) + ) + $qa_content['inc_views_postid']=$questionid; + + + return $qa_content; + + +/* + Omit PHP closing tag to help avoid accidental output +*/ \ No newline at end of file diff --git a/pages/questions.php b/pages/questions.php new file mode 100644 index 0000000..80b0a88 --- /dev/null +++ b/pages/questions.php @@ -0,0 +1,140 @@ + $sort); + + switch ($sort) { + case 'hot': + $sometitle=$countslugs ? qa_lang_html_sub('main/hot_qs_in_x', $categorytitlehtml) : qa_lang_html('main/hot_qs_title'); + $feedpathprefix=qa_opt('feed_for_hot') ? 'hot' : null; + break; + + case 'votes': + $sometitle=$countslugs ? qa_lang_html_sub('main/voted_qs_in_x', $categorytitlehtml) : qa_lang_html('main/voted_qs_title'); + break; + + case 'answers': + $sometitle=$countslugs ? qa_lang_html_sub('main/answered_qs_in_x', $categorytitlehtml) : qa_lang_html('main/answered_qs_title'); + break; + + case 'views': + $sometitle=$countslugs ? qa_lang_html_sub('main/viewed_qs_in_x', $categorytitlehtml) : qa_lang_html('main/viewed_qs_title'); + break; + + default: + $linkparams=array(); + $sometitle=$countslugs ? qa_lang_html_sub('main/recent_qs_in_x', $categorytitlehtml) : qa_lang_html('main/recent_qs_title'); + $categorypathprefix='questions/'; + $feedpathprefix=qa_opt('feed_for_questions') ? 'questions' : null; + break; + } + + +// Prepare and return content for theme + + $qa_content=qa_q_list_page_content( + $questions, // questions + qa_opt('page_size_qs'), // questions per page + $start, // start offset + $countslugs ? $categories[$categoryid]['qcount'] : qa_opt('cache_qcount'), // total count + $sometitle, // title if some questions + $nonetitle, // title if no questions + $categories, // categories for navigation + $categoryid, // selected category id + true, // show question counts in category navigation + $categorypathprefix, // prefix for links in category navigation + $feedpathprefix, // prefix for RSS feed paths + $countslugs ? qa_html_suggest_qs_tags(qa_using_tags()) : qa_html_suggest_ask($categoryid), // suggest what to do next + $linkparams, // extra parameters for page links + $linkparams // category nav params + ); + + if (QA_ALLOW_UNINDEXED_QUERIES || !$countslugs) + $qa_content['navigation']['sub']=qa_qs_sub_navigation($sort, $categoryslugs); + + + return $qa_content; + + +/* + Omit PHP closing tag to help avoid accidental output +*/ \ No newline at end of file diff --git a/pages/register.php b/pages/register.php new file mode 100644 index 0000000..6fc3e9e --- /dev/null +++ b/pages/register.php @@ -0,0 +1,249 @@ + $userfield) { + if (!($userfield['flags'] & QA_FIELD_FLAGS_ON_REGISTER)) + unset($userfields[$index]); + } + + +// Check we haven't suspended registration, and this IP isn't blocked + + if (qa_opt('suspend_register_users')) { + $qa_content = qa_content_prepare(); + $qa_content['error'] = qa_lang_html('users/register_suspended'); + return $qa_content; + } + + if (qa_user_permit_error()) { + $qa_content = qa_content_prepare(); + $qa_content['error'] = qa_lang_html('users/no_permission'); + return $qa_content; + } + + +// Process submitted form + + if (qa_clicked('doregister')) { + require_once QA_INCLUDE_DIR.'app/limits.php'; + + if (qa_user_limits_remaining(QA_LIMIT_REGISTRATIONS)) { + require_once QA_INCLUDE_DIR.'app/users-edit.php'; + + $inemail = qa_post_text('email'); + $inpassword = qa_post_text('password'); + $inhandle = qa_post_text('handle'); + $interms = (int) qa_post_text('terms'); + + $inprofile = array(); + foreach ($userfields as $userfield) + $inprofile[$userfield['fieldid']] = qa_post_text('field_'.$userfield['fieldid']); + + if (!qa_check_form_security_code('register', qa_post_text('code'))) { + $pageerror = qa_lang_html('misc/form_security_again'); + } + else { + // core validation + $errors = array_merge( + qa_handle_email_filter($inhandle, $inemail), + qa_password_validate($inpassword) + ); + + // T&Cs validation + if ($show_terms && !$interms) + $errors['terms'] = qa_lang_html('users/terms_not_accepted'); + + // filter module validation + if (count($inprofile)) { + $filtermodules = qa_load_modules_with('filter', 'filter_profile'); + foreach ($filtermodules as $filtermodule) + $filtermodule->filter_profile($inprofile, $errors, null, null); + } + + if (qa_opt('captcha_on_register')) + qa_captcha_validate_post($errors); + + if (empty($errors)) { + // register and redirect + qa_limits_increment(null, QA_LIMIT_REGISTRATIONS); + + $userid = qa_create_new_user($inemail, $inpassword, $inhandle); + + foreach ($userfields as $userfield) + qa_db_user_profile_set($userid, $userfield['title'], $inprofile[$userfield['fieldid']]); + + qa_set_logged_in_user($userid, $inhandle); + + $topath = qa_get('to'); + + if (isset($topath)) + qa_redirect_raw(qa_path_to_root().$topath); // path already provided as URL fragment + else + qa_redirect(''); + } + } + + } + else + $pageerror = qa_lang('users/register_limit'); + } + + +// Prepare content for theme + + $qa_content = qa_content_prepare(); + + $qa_content['title'] = qa_lang_html('users/register_title'); + + $qa_content['error'] = @$pageerror; + + $qa_content['form'] = array( + 'tags' => 'method="post" action="'.qa_self_html().'"', + + 'style' => 'tall', + + 'fields' => array( + 'handle' => array( + 'label' => qa_lang_html('users/handle_label'), + 'tags' => 'name="handle" id="handle"', + 'value' => qa_html(@$inhandle), + 'error' => qa_html(@$errors['handle']), + ), + + 'password' => array( + 'type' => 'password', + 'label' => qa_lang_html('users/password_label'), + 'tags' => 'name="password" id="password"', + 'value' => qa_html(@$inpassword), + 'error' => qa_html(@$errors['password']), + ), + + 'email' => array( + 'label' => qa_lang_html('users/email_label'), + 'tags' => 'name="email" id="email"', + 'value' => qa_html(@$inemail), + 'note' => qa_opt('email_privacy'), + 'error' => qa_html(@$errors['email']), + ), + ), + + 'buttons' => array( + 'register' => array( + 'tags' => 'onclick="qa_show_waiting_after(this, false);"', + 'label' => qa_lang_html('users/register_button'), + ), + ), + + 'hidden' => array( + 'doregister' => '1', + 'code' => qa_get_form_security_code('register'), + ), + ); + + // prepend custom message + $custom = qa_opt('show_custom_register') ? trim(qa_opt('custom_register')) : ''; + if (strlen($custom)) { + array_unshift($qa_content['form']['fields'], array( + 'type' => 'custom', + 'note' => $custom, + )); + } + + // show T&Cs checkbox + if ($show_terms) { + $qa_content['form']['fields']['terms'] = array( + 'type' => 'checkbox', + 'label' => trim(qa_opt('register_terms')), + 'tags' => 'name="terms" id="terms"', + 'value' => qa_html(@$interms), + 'error' => qa_html(@$errors['terms']), + ); + } + + foreach ($userfields as $userfield) { + $value = @$inprofile[$userfield['fieldid']]; + + $label = trim(qa_user_userfield_label($userfield), ':'); + if (strlen($label)) + $label .= ':'; + + $qa_content['form']['fields'][$userfield['title']] = array( + 'label' => qa_html($label), + 'tags' => 'name="field_'.$userfield['fieldid'].'"', + 'value' => qa_html($value), + 'error' => qa_html(@$errors[$userfield['fieldid']]), + 'rows' => ($userfield['flags'] & QA_FIELD_FLAGS_MULTI_LINE) ? 8 : null, + ); + } + + if (qa_opt('captcha_on_register')) + qa_set_up_captcha_field($qa_content, $qa_content['form']['fields'], @$errors); + + $loginmodules = qa_load_modules_with('login', 'login_html'); + + foreach ($loginmodules as $module) { + ob_start(); + $module->login_html(qa_opt('site_url').qa_get('to'), 'register'); + $html = ob_get_clean(); + + if (strlen($html)) + @$qa_content['custom'] .= '
    '.$html.'
    '; + } + + // prioritize 'handle' for keyboard focus + $qa_content['focusid'] = isset($errors['handle']) ? 'handle' + : (isset($errors['password']) ? 'password' + : (isset($errors['email']) ? 'email' : 'handle')); + + + return $qa_content; + + +/* + Omit PHP closing tag to help avoid accidental output +*/ \ No newline at end of file diff --git a/pages/reset.php b/pages/reset.php new file mode 100644 index 0000000..1fe8005 --- /dev/null +++ b/pages/reset.php @@ -0,0 +1,139 @@ + $inemailhandle, 'ps' => '1')); // redirect to login page + + } else + $errors['code']=qa_lang('users/reset_code_wrong'); + + } else + $errors['emailhandle']=qa_lang('users/user_not_found'); + } + + } else { + $inemailhandle=qa_get('e'); + $incode=qa_get('c'); + } + + +// Prepare content for theme + + $qa_content=qa_content_prepare(); + + $qa_content['title']=qa_lang_html('users/reset_title'); + $qa_content['error']=@$errors['page']; + + if (empty($inemailhandle) || isset($errors['emailhandle'])) + $forgotpath=qa_path('forgot'); + else + $forgotpath=qa_path('forgot', array('e' => $inemailhandle)); + + $qa_content['form']=array( + 'tags' => 'method="post" action="'.qa_self_html().'"', + + 'style' => 'tall', + + 'ok' => empty($incode) ? qa_lang_html('users/reset_code_emailed') : null, + + 'fields' => array( + 'email_handle' => array( + 'label' => qa_opt('allow_login_email_only') ? qa_lang_html('users/email_label') : qa_lang_html('users/email_handle_label'), + 'tags' => 'name="emailhandle" id="emailhandle"', + 'value' => qa_html(@$inemailhandle), + 'error' => qa_html(@$errors['emailhandle']), + ), + + 'code' => array( + 'label' => qa_lang_html('users/reset_code_label'), + 'tags' => 'name="code" id="code"', + 'value' => qa_html(@$incode), + 'error' => qa_html(@$errors['code']), + 'note' => qa_lang_html('users/reset_code_emailed').' - '. + ''.qa_lang_html('users/reset_code_another').'', + ), + ), + + 'buttons' => array( + 'reset' => array( + 'label' => qa_lang_html('users/send_password_button'), + ), + ), + + 'hidden' => array( + 'doreset' => '1', + 'formcode' => qa_get_form_security_code('reset'), + ), + ); + + $qa_content['focusid']=(isset($errors['emailhandle']) || !strlen(@$inemailhandle)) ? 'emailhandle' : 'code'; + + + return $qa_content; + + +/* + Omit PHP closing tag to help avoid accidental output +*/ \ No newline at end of file diff --git a/pages/search.php b/pages/search.php new file mode 100644 index 0000000..d298edc --- /dev/null +++ b/pages/search.php @@ -0,0 +1,153 @@ + $inquery, + 'start' => $start, + )); + } + + +// Prepare content for theme + + $qa_content=qa_content_prepare(true); + + if (strlen(qa_get('q'))) { + $qa_content['search']['value']=qa_html($inquery); + + if (count($results)) + $qa_content['title']=qa_lang_html_sub('main/results_for_x', qa_html($inquery)); + else + $qa_content['title']=qa_lang_html_sub('main/no_results_for_x', qa_html($inquery)); + + $qa_content['q_list']['form']=array( + 'tags' => 'method="post" action="'.qa_self_html().'"', + + 'hidden' => array( + 'code' => qa_get_form_security_code('vote'), + ), + ); + + $qa_content['q_list']['qs']=array(); + + $qdefaults=qa_post_html_defaults('Q'); + + foreach ($results as $result) + if (!isset($result['question'])) { // if we have any non-question results, display with less statistics + $qdefaults['voteview']=false; + $qdefaults['answersview']=false; + $qdefaults['viewsview']=false; + break; + } + + foreach ($results as $result) { + if (isset($result['question'])) + $fields=qa_post_html_fields($result['question'], $userid, qa_cookie_get(), + $usershtml, null, qa_post_html_options($result['question'], $qdefaults)); + + elseif (isset($result['url'])) + $fields=array( + 'what' => qa_html($result['url']), + 'meta_order' => qa_lang_html('main/meta_order'), + ); + + else + continue; // nothing to show here + + if (isset($qdefaults['blockwordspreg'])) + $result['title']=qa_block_words_replace($result['title'], $qdefaults['blockwordspreg']); + + $fields['title']=qa_html($result['title']); + $fields['url']=qa_html($result['url']); + + $qa_content['q_list']['qs'][]=$fields; + } + + $qa_content['page_links']=qa_html_page_links(qa_request(), $start, $pagesize, $start+$gotcount, + qa_opt('pages_prev_next'), array('q' => $inquery), $gotcount>=$count); + + if (qa_opt('feed_for_search')) + $qa_content['feed']=array( + 'url' => qa_path_html(qa_feed_request('search/'.$inquery)), + 'label' => qa_lang_html_sub('main/results_for_x', qa_html($inquery)), + ); + + if (empty($qa_content['page_links'])) + $qa_content['suggest_next']=qa_html_suggest_qs_tags(qa_using_tags()); + + } else + $qa_content['error']=qa_lang_html('main/search_explanation'); + + + + return $qa_content; + + +/* + Omit PHP closing tag to help avoid accidental output +*/ \ No newline at end of file diff --git a/pages/tag.php b/pages/tag.php new file mode 100644 index 0000000..cce1cbe --- /dev/null +++ b/pages/tag.php @@ -0,0 +1,98 @@ + 'method="post" action="'.qa_self_html().'"', + + 'hidden' => array( + 'code' => qa_get_form_security_code('vote'), + ), + ); + + $qa_content['q_list']['qs']=array(); + foreach ($questions as $postid => $question) + $qa_content['q_list']['qs'][]=qa_post_html_fields($question, $userid, qa_cookie_get(), $usershtml, null, qa_post_html_options($question)); + + $qa_content['page_links']=qa_html_page_links(qa_request(), $start, $pagesize, $tagword['tagcount'], qa_opt('pages_prev_next')); + + if (empty($qa_content['page_links'])) + $qa_content['suggest_next']=qa_html_suggest_qs_tags(true); + + if (qa_opt('feed_for_tag_qs')) + $qa_content['feed']=array( + 'url' => qa_path_html(qa_feed_request('tag/'.$tag)), + 'label' => qa_lang_html_sub('main/questions_tagged_x', qa_html($tag)), + ); + + + return $qa_content; + + +/* + Omit PHP closing tag to help avoid accidental output +*/ \ No newline at end of file diff --git a/pages/tags.php b/pages/tags.php new file mode 100644 index 0000000..2252335 --- /dev/null +++ b/pages/tags.php @@ -0,0 +1,84 @@ + array(), + 'rows' => ceil($pagesize/qa_opt('columns_tags')), + 'type' => 'tags' + ); + + if (count($populartags)) { + $favoritemap = qa_get_favorite_non_qs_map(); + + $output = 0; + foreach ($populartags as $word => $count) { + $qa_content['ranking']['items'][] = array( + 'label' => qa_tag_html($word, false, @$favoritemap['tag'][qa_strtolower($word)]), + 'count' => number_format($count), + ); + + if ((++$output) >= $pagesize) + break; + } + + } else + $qa_content['title'] = qa_lang_html('main/no_tags_found'); + + $qa_content['page_links'] = qa_html_page_links(qa_request(), $start, $pagesize, $tagcount, qa_opt('pages_prev_next')); + + if (empty($qa_content['page_links'])) + $qa_content['suggest_next'] = qa_html_suggest_ask(); + + + return $qa_content; + + +/* + Omit PHP closing tag to help avoid accidental output +*/ \ No newline at end of file diff --git a/pages/unanswered.php b/pages/unanswered.php new file mode 100644 index 0000000..ba62dcb --- /dev/null +++ b/pages/unanswered.php @@ -0,0 +1,144 @@ + $by); + + switch ($by) { + case 'selected': + if ($countslugs) { + $sometitle=qa_lang_html_sub('main/unselected_qs_in_x', $categorytitlehtml); + $nonetitle=qa_lang_html_sub('main/no_una_questions_in_x', $categorytitlehtml); + + } else { + $sometitle=qa_lang_html('main/unselected_qs_title'); + $nonetitle=qa_lang_html('main/no_unselected_qs_found'); + $count=qa_opt('cache_unselqcount'); + } + break; + + case 'upvotes': + if ($countslugs) { + $sometitle=qa_lang_html_sub('main/unupvoteda_qs_in_x', $categorytitlehtml); + $nonetitle=qa_lang_html_sub('main/no_una_questions_in_x', $categorytitlehtml); + + } else { + $sometitle=qa_lang_html('main/unupvoteda_qs_title'); + $nonetitle=qa_lang_html('main/no_unupvoteda_qs_found'); + $count=qa_opt('cache_unupaqcount'); + } + break; + + default: + $feedpathprefix=qa_opt('feed_for_unanswered') ? 'unanswered' : null; + $linkparams=array(); + + if ($countslugs) { + $sometitle=qa_lang_html_sub('main/unanswered_qs_in_x', $categorytitlehtml); + $nonetitle=qa_lang_html_sub('main/no_una_questions_in_x', $categorytitlehtml); + + } else { + $sometitle=qa_lang_html('main/unanswered_qs_title'); + $nonetitle=qa_lang_html('main/no_una_questions_found'); + $count=qa_opt('cache_unaqcount'); + } + break; + } + + +// Prepare and return content for theme + + $qa_content=qa_q_list_page_content( + $questions, // questions + qa_opt('page_size_una_qs'), // questions per page + $start, // start offset + @$count, // total count + $sometitle, // title if some questions + $nonetitle, // title if no questions + QA_ALLOW_UNINDEXED_QUERIES ? $categories : null, // categories for navigation (null if not shown on this page) + QA_ALLOW_UNINDEXED_QUERIES ? $categoryid : null, // selected category id (null if not relevant) + false, // show question counts in category navigation + QA_ALLOW_UNINDEXED_QUERIES ? 'unanswered/' : null, // prefix for links in category navigation (null if no navigation) + $feedpathprefix, // prefix for RSS feed paths (null to hide) + qa_html_suggest_qs_tags(qa_using_tags()), // suggest what to do next + $linkparams, // extra parameters for page links + $linkparams // category nav params + ); + + $qa_content['navigation']['sub']=qa_unanswered_sub_navigation($by, $categoryslugs); + + + return $qa_content; + + +/* + Omit PHP closing tag to help avoid accidental output +*/ \ No newline at end of file diff --git a/pages/unsubscribe.php b/pages/unsubscribe.php new file mode 100644 index 0000000..bbe1e6e --- /dev/null +++ b/pages/unsubscribe.php @@ -0,0 +1,81 @@ + qa_html(qa_opt('site_title')), + '^1' => '', + '^2' => '', + )); + else + $qa_content['error']=qa_insert_login_links(qa_lang_html('users/unsubscribe_wrong_log_in'), 'unsubscribe'); + + + return $qa_content; + + +/* + Omit PHP closing tag to help avoid accidental output +*/ \ No newline at end of file diff --git a/pages/updates.php b/pages/updates.php new file mode 100644 index 0000000..248aa4c --- /dev/null +++ b/pages/updates.php @@ -0,0 +1,115 @@ + '', + '^2' => '', + )) : null // suggest what to do next + ); + + $qa_content['navigation']['sub']=array( + 'all' => array( + 'label' => qa_lang_html('misc/nav_all_my_updates'), + 'url' => qa_path_html('updates'), + 'selected' => $forfavorites && $forcontent, + ), + + 'favorites' => array( + 'label' => qa_lang_html('misc/nav_my_favorites'), + 'url' => qa_path_html('updates', array('show' => 'favorites')), + 'selected' => $forfavorites && !$forcontent, + ), + + 'myposts' => array( + 'label' => qa_lang_html('misc/nav_my_content'), + 'url' => qa_path_html('updates', array('show' => 'content')), + 'selected' => $forcontent && !$forfavorites, + ), + ); + + + return $qa_content; + + +/* + Omit PHP closing tag to help avoid accidental output +*/ \ No newline at end of file diff --git a/pages/user-activity.php b/pages/user-activity.php new file mode 100644 index 0000000..c2dc9d6 --- /dev/null +++ b/pages/user-activity.php @@ -0,0 +1,103 @@ + 'method="post" action="'.qa_self_html().'"', + + 'hidden' => array( + 'code' => qa_get_form_security_code('vote'), + ), + ); + + $qa_content['q_list']['qs'] = array(); + + $htmldefaults = qa_post_html_defaults('Q'); + $htmldefaults['whoview'] = false; + $htmldefaults['voteview'] = false; + $htmldefaults['avatarsize'] = 0; + + foreach ($questions as $question) { + $qa_content['q_list']['qs'][] = qa_any_to_q_html_fields($question, $loginuserid, qa_cookie_get(), + $usershtml, null, array('voteview' => false) + qa_post_html_options($question, $htmldefaults)); + } + + +// Sub menu for navigation in user pages + + $ismyuser = isset($loginuserid) && $loginuserid == (QA_FINAL_EXTERNAL_USERS ? $userid : $useraccount['userid']); + $qa_content['navigation']['sub'] = qa_user_sub_navigation($handle, 'activity', $ismyuser); + + + return $qa_content; + + +/* + Omit PHP closing tag to help avoid accidental output +*/ \ No newline at end of file diff --git a/pages/user-answers.php b/pages/user-answers.php new file mode 100644 index 0000000..4ebc7ca --- /dev/null +++ b/pages/user-answers.php @@ -0,0 +1,110 @@ + 'method="post" action="'.qa_self_html().'"', + + 'hidden' => array( + 'code' => qa_get_form_security_code('vote'), + ), + ); + + $qa_content['q_list']['qs'] = array(); + + $htmldefaults = qa_post_html_defaults('Q'); + $htmldefaults['whoview'] = false; + $htmldefaults['avatarsize'] = 0; + $htmldefaults['ovoteview'] = true; + $htmldefaults['answersview'] = false; + + foreach ($questions as $question) { + $options = qa_post_html_options($question, $htmldefaults); + $options['voteview'] = qa_get_vote_view('A', false, false); + + $qa_content['q_list']['qs'][] = qa_other_to_q_html_fields($question, $loginuserid, qa_cookie_get(), + $usershtml, null, $options); + } + + $qa_content['page_links'] = qa_html_page_links(qa_request(), $start, $pagesize, $count, qa_opt('pages_prev_next')); + + +// Sub menu for navigation in user pages + + $ismyuser = isset($loginuserid) && $loginuserid == (QA_FINAL_EXTERNAL_USERS ? $userid : $useraccount['userid']); + $qa_content['navigation']['sub'] = qa_user_sub_navigation($handle, 'answers', $ismyuser); + + + return $qa_content; + + +/* + Omit PHP closing tag to help avoid accidental output +*/ \ No newline at end of file diff --git a/pages/user-profile.php b/pages/user-profile.php new file mode 100644 index 0000000..39ab582 --- /dev/null +++ b/pages/user-profile.php @@ -0,0 +1,982 @@ + $userfield) { + if ( isset($userfield['permit']) && qa_permit_value_error($userfield['permit'], $loginuserid, qa_get_logged_in_level(), qa_get_logged_in_flags()) ) + unset($userfields[$index]); // don't pay attention to user fields we're not allowed to view + } + } + + +// Check the user exists and work out what can and can't be set (if not using single sign-on) + + $errors = array(); + + $loginlevel = qa_get_logged_in_level(); + + if (!QA_FINAL_EXTERNAL_USERS) { // if we're using integrated user management, we can know and show more + require_once QA_INCLUDE_DIR.'app/messages.php'; + + if ((!is_array($userpoints)) && !is_array($useraccount)) + return include QA_INCLUDE_DIR.'qa-page-not-found.php'; + + $userid = $useraccount['userid']; + $fieldseditable = false; + $maxlevelassign = null; + + $maxuserlevel = $useraccount['level']; + foreach ($userlevels as $userlevel) + $maxuserlevel = max($maxuserlevel, $userlevel['level']); + + if ( + isset($loginuserid) && + ($loginuserid != $userid) && + (($loginlevel >= QA_USER_LEVEL_SUPER) || ($loginlevel > $maxuserlevel)) && + (!qa_user_permit_error()) + ) { // can't change self - or someone on your level (or higher, obviously) unless you're a super admin + + if ($loginlevel >= QA_USER_LEVEL_SUPER) + $maxlevelassign = QA_USER_LEVEL_SUPER; + + elseif ($loginlevel >= QA_USER_LEVEL_ADMIN) + $maxlevelassign = QA_USER_LEVEL_MODERATOR; + + elseif ($loginlevel >= QA_USER_LEVEL_MODERATOR) + $maxlevelassign = QA_USER_LEVEL_EXPERT; + + if ($loginlevel >= QA_USER_LEVEL_ADMIN) + $fieldseditable = true; + + if (isset($maxlevelassign) && ($useraccount['flags'] & QA_USER_FLAGS_USER_BLOCKED)) + $maxlevelassign = min($maxlevelassign, QA_USER_LEVEL_EDITOR); // if blocked, can't promote too high + } + + $approvebutton = isset($maxlevelassign) + && $useraccount['level'] < QA_USER_LEVEL_APPROVED + && $maxlevelassign >= QA_USER_LEVEL_APPROVED + && !($useraccount['flags'] & QA_USER_FLAGS_USER_BLOCKED) + && qa_opt('moderate_users'); + $usereditbutton = $fieldseditable || isset($maxlevelassign); + $userediting = $usereditbutton && (qa_get_state() == 'edit'); + + $wallposterrorhtml = qa_wall_error_html($loginuserid, $useraccount['userid'], $useraccount['flags']); + + // This code is similar but not identical to that in to qq-page-user-wall.php + + $usermessages = array_slice($usermessages, 0, qa_opt('page_size_wall')); + $usermessages = qa_wall_posts_add_rules($usermessages, 0); + + foreach ($usermessages as $message) { + if ($message['deleteable'] && qa_clicked('m'.$message['messageid'].'_dodelete')) { + if (!qa_check_form_security_code('wall-'.$useraccount['handle'], qa_post_text('code'))) + $errors['page'] = qa_lang_html('misc/form_security_again'); + else { + qa_wall_delete_post($loginuserid, qa_get_logged_in_handle(), qa_cookie_get(), $message); + qa_redirect(qa_request(), null, null, null, 'wall'); + } + } + } + } + + +// Process edit or save button for user, and other actions + + if (!QA_FINAL_EXTERNAL_USERS) { + $reloaduser = false; + + if ($usereditbutton) { + if (qa_clicked('docancel')) + qa_redirect(qa_request()); + + elseif (qa_clicked('doedit')) + qa_redirect(qa_request(), array('state' => 'edit')); + + elseif (qa_clicked('dosave')) { + require_once QA_INCLUDE_DIR.'app/users-edit.php'; + require_once QA_INCLUDE_DIR.'db/users.php'; + + $inemail = qa_post_text('email'); + + $inprofile = array(); + foreach ($userfields as $userfield) + $inprofile[$userfield['fieldid']] = qa_post_text('field_'.$userfield['fieldid']); + + if (!qa_check_form_security_code('user-edit-'.$handle, qa_post_text('code'))) { + $errors['page'] = qa_lang_html('misc/form_security_again'); + $userediting = true; + } + else { + if (qa_post_text('removeavatar')) { + qa_db_user_set_flag($userid, QA_USER_FLAGS_SHOW_AVATAR, false); + qa_db_user_set_flag($userid, QA_USER_FLAGS_SHOW_GRAVATAR, false); + + if (isset($useraccount['avatarblobid'])) { + require_once QA_INCLUDE_DIR.'app/blobs.php'; + + qa_db_user_set($userid, 'avatarblobid', null); + qa_db_user_set($userid, 'avatarwidth', null); + qa_db_user_set($userid, 'avatarheight', null); + qa_delete_blob($useraccount['avatarblobid']); + } + } + + if ($fieldseditable) { + $filterhandle = $handle; // we're not filtering the handle... + $errors = qa_handle_email_filter($filterhandle, $inemail, $useraccount); + unset($errors['handle']); // ...and we don't care about any errors in it + + if (!isset($errors['email'])) + if ($inemail != $useraccount['email']) { + qa_db_user_set($userid, 'email', $inemail); + qa_db_user_set_flag($userid, QA_USER_FLAGS_EMAIL_CONFIRMED, false); + } + + if (count($inprofile)) { + $filtermodules = qa_load_modules_with('filter', 'filter_profile'); + foreach ($filtermodules as $filtermodule) + $filtermodule->filter_profile($inprofile, $errors, $useraccount, $userprofile); + } + + foreach ($userfields as $userfield) + if (!isset($errors[$userfield['fieldid']])) + qa_db_user_profile_set($userid, $userfield['title'], $inprofile[$userfield['fieldid']]); + + if (count($errors)) + $userediting = true; + + qa_report_event('u_edit', $loginuserid, qa_get_logged_in_handle(), qa_cookie_get(), array( + 'userid' => $userid, + 'handle' => $useraccount['handle'], + )); + } + + if (isset($maxlevelassign)) { + $inlevel = min($maxlevelassign, (int)qa_post_text('level')); // constrain based on maximum permitted to prevent simple browser-based attack + if ($inlevel != $useraccount['level']) + qa_set_user_level($userid, $useraccount['handle'], $inlevel, $useraccount['level']); + + if (qa_using_categories()) { + $inuserlevels = array(); + + for ($index = 1; $index <= 999; $index++) { + $inlevel = qa_post_text('uc_'.$index.'_level'); + if (!isset($inlevel)) + break; + + $categoryid = qa_get_category_field_value('uc_'.$index.'_cat'); + + if (strlen($categoryid) && strlen($inlevel)) + $inuserlevels[] = array( + 'entitytype' => QA_ENTITY_CATEGORY, + 'entityid' => $categoryid, + 'level' => min($maxlevelassign, (int)$inlevel), + ); + } + + qa_db_user_levels_set($userid, $inuserlevels); + } + } + + if (empty($errors)) + qa_redirect(qa_request()); + + list($useraccount, $userprofile, $userlevels) = qa_db_select_with_pending( + qa_db_user_account_selectspec($userid, true), + qa_db_user_profile_selectspec($userid, true), + qa_db_user_levels_selectspec($userid, true, true) + ); + } + } + } + + if (qa_clicked('doapprove') || qa_clicked('doblock') || qa_clicked('dounblock') || qa_clicked('dohideall') || qa_clicked('dodelete')) { + if (!qa_check_form_security_code('user-'.$handle, qa_post_text('code'))) + $errors['page'] = qa_lang_html('misc/form_security_again'); + + else { + if ($approvebutton && qa_clicked('doapprove')) { + require_once QA_INCLUDE_DIR.'app/users-edit.php'; + qa_set_user_level($userid, $useraccount['handle'], QA_USER_LEVEL_APPROVED, $useraccount['level']); + qa_redirect(qa_request()); + } + + if (isset($maxlevelassign) && ($maxuserlevel < QA_USER_LEVEL_MODERATOR)) { + if (qa_clicked('doblock')) { + require_once QA_INCLUDE_DIR.'app/users-edit.php'; + + qa_set_user_blocked($userid, $useraccount['handle'], true); + qa_redirect(qa_request()); + } + + if (qa_clicked('dounblock')) { + require_once QA_INCLUDE_DIR.'app/users-edit.php'; + + qa_set_user_blocked($userid, $useraccount['handle'], false); + qa_redirect(qa_request()); + } + + if (qa_clicked('dohideall') && !qa_user_permit_error('permit_hide_show')) { + require_once QA_INCLUDE_DIR.'db/admin.php'; + require_once QA_INCLUDE_DIR.'app/posts.php'; + + $postids = qa_db_get_user_visible_postids($userid); + + foreach ($postids as $postid) + qa_post_set_hidden($postid, true, $loginuserid); + + qa_redirect(qa_request()); + } + + if (qa_clicked('dodelete') && ($loginlevel >= QA_USER_LEVEL_ADMIN)) { + require_once QA_INCLUDE_DIR.'app/users-edit.php'; + + qa_delete_user($userid); + + qa_report_event('u_delete', $loginuserid, qa_get_logged_in_handle(), qa_cookie_get(), array( + 'userid' => $userid, + 'handle' => $useraccount['handle'], + )); + + qa_redirect('users'); + } + } + } + } + + + if (qa_clicked('dowallpost')) { + $inmessage = qa_post_text('message'); + + if (!strlen($inmessage)) + $errors['message'] = qa_lang('profile/post_wall_empty'); + + elseif (!qa_check_form_security_code('wall-'.$useraccount['handle'], qa_post_text('code'))) + $errors['message'] = qa_lang_html('misc/form_security_again'); + + elseif (!$wallposterrorhtml) { + qa_wall_add_post($loginuserid, qa_get_logged_in_handle(), qa_cookie_get(), $userid, $useraccount['handle'], $inmessage, ''); + qa_redirect(qa_request(), null, null, null, 'wall'); + } + } + } + + +// Process bonus setting button + + if ( ($loginlevel >= QA_USER_LEVEL_ADMIN) && qa_clicked('dosetbonus') ) { + require_once QA_INCLUDE_DIR.'db/points.php'; + + $inbonus = (int)qa_post_text('bonus'); + + if (!qa_check_form_security_code('user-activity-'.$handle, qa_post_text('code'))) + $errors['page'] = qa_lang_html('misc/form_security_again'); + + else { + qa_db_points_set_bonus($userid, $inbonus); + qa_db_points_update_ifuser($userid, null); + qa_redirect(qa_request(), null, null, null, 'activity'); + } + } + + +// Prepare content for theme + + $qa_content = qa_content_prepare(); + + $qa_content['title'] = qa_lang_html_sub('profile/user_x', $userhtml); + $qa_content['error'] = @$errors['page']; + + if (isset($loginuserid) && $loginuserid != $useraccount['userid'] && !QA_FINAL_EXTERNAL_USERS) { + $favoritemap = qa_get_favorite_non_qs_map(); + $favorite = @$favoritemap['user'][$useraccount['userid']]; + + $qa_content['favorite'] = qa_favorite_form(QA_ENTITY_USER, $useraccount['userid'], $favorite, + qa_lang_sub($favorite ? 'main/remove_x_favorites' : 'users/add_user_x_favorites', $handle)); + } + + $qa_content['script_rel'][] = 'qa-content/qa-user.js?'.QA_VERSION; + + +// General information about the user, only available if we're using internal user management + + if (!QA_FINAL_EXTERNAL_USERS) { + $membertime = qa_time_to_string(qa_opt('db_time') - $useraccount['created']); + $joindate = qa_when_to_html($useraccount['created'], 0); + + $qa_content['form_profile'] = array( + 'tags' => 'method="post" action="'.qa_self_html().'"', + + 'style' => 'wide', + + 'fields' => array( + 'avatar' => array( + 'type' => 'image', + 'style' => 'tall', + 'label' => '', + 'html' => qa_get_user_avatar_html($useraccount['flags'], $useraccount['email'], $useraccount['handle'], + $useraccount['avatarblobid'], $useraccount['avatarwidth'], $useraccount['avatarheight'], qa_opt('avatar_profile_size')), + 'id' => 'avatar', + ), + + 'removeavatar' => null, + + 'duration' => array( + 'type' => 'static', + 'label' => qa_lang_html('users/member_for'), + 'value' => qa_html( $membertime . ' (' . qa_lang_sub('main/since_x', $joindate['data']) . ')' ), + 'id' => 'duration', + ), + + 'level' => array( + 'type' => 'static', + 'label' => qa_lang_html('users/member_type'), + 'tags' => 'name="level"', + 'value' => qa_html(qa_user_level_string($useraccount['level'])), + 'note' => (($useraccount['flags'] & QA_USER_FLAGS_USER_BLOCKED) && isset($maxlevelassign)) ? qa_lang_html('users/user_blocked') : '', + 'id' => 'level', + ), + ), + ); + + if (empty($qa_content['form_profile']['fields']['avatar']['html'])) + unset($qa_content['form_profile']['fields']['avatar']); + + + // Private message link + + if ( qa_opt('allow_private_messages') && isset($loginuserid) && ($loginuserid != $userid) && !($useraccount['flags'] & QA_USER_FLAGS_NO_MESSAGES) && !$userediting ) { + $qa_content['form_profile']['fields']['level']['value'] .= strtr(qa_lang_html('profile/send_private_message'), array( + '^1' => '', + '^2' => '', + )); + } + + + // Levels editing or viewing (add category-specific levels) + + if ($userediting) { + + if (isset($maxlevelassign)) { + $qa_content['form_profile']['fields']['level']['type'] = 'select'; + + $showlevels = array(QA_USER_LEVEL_BASIC); + if (qa_opt('moderate_users')) + $showlevels[] = QA_USER_LEVEL_APPROVED; + + array_push($showlevels, QA_USER_LEVEL_EXPERT, QA_USER_LEVEL_EDITOR, QA_USER_LEVEL_MODERATOR, QA_USER_LEVEL_ADMIN, QA_USER_LEVEL_SUPER); + + $leveloptions = array(); + $catleveloptions = array('' => qa_lang_html('users/category_level_none')); + + foreach ($showlevels as $showlevel) { + if ($showlevel <= $maxlevelassign) { + $leveloptions[$showlevel] = qa_html(qa_user_level_string($showlevel)); + if ($showlevel > QA_USER_LEVEL_BASIC) + $catleveloptions[$showlevel] = $leveloptions[$showlevel]; + } + } + + $qa_content['form_profile']['fields']['level']['options'] = $leveloptions; + + + // Category-specific levels + + if (qa_using_categories()) { + $catleveladd = strlen(qa_get('catleveladd')) > 0; + + if ((!$catleveladd) && !count($userlevels)) { + $qa_content['form_profile']['fields']['level']['suffix'] = strtr(qa_lang_html('users/category_level_add'), array( + '^1' => '', + '^2' => '', + )); + } + else + $qa_content['form_profile']['fields']['level']['suffix'] = qa_lang_html('users/level_in_general'); + + if ($catleveladd || count($userlevels)) + $userlevels[] = array('entitytype' => QA_ENTITY_CATEGORY); + + $index = 0; + foreach ($userlevels as $userlevel) { + if ($userlevel['entitytype'] == QA_ENTITY_CATEGORY) { + $index++; + $id = 'ls_'.+$index; + + $qa_content['form_profile']['fields']['uc_'.$index.'_level'] = array( + 'label' => qa_lang_html('users/category_level_label'), + 'type' => 'select', + 'tags' => 'name="uc_'.$index.'_level" id="'.qa_html($id).'" onchange="this.qa_prev=this.options[this.selectedIndex].value;"', + 'options' => $catleveloptions, + 'value' => isset($userlevel['level']) ? qa_html(qa_user_level_string($userlevel['level'])) : '', + 'suffix' => qa_lang_html('users/category_level_in'), + ); + + $qa_content['form_profile']['fields']['uc_'.$index.'_cat'] = array(); + + if (isset($userlevel['entityid'])) + $fieldnavcategories = qa_db_select_with_pending(qa_db_category_nav_selectspec($userlevel['entityid'], true)); + else + $fieldnavcategories = $navcategories; + + qa_set_up_category_field($qa_content, $qa_content['form_profile']['fields']['uc_'.$index.'_cat'], + 'uc_'.$index.'_cat', $fieldnavcategories, @$userlevel['entityid'], true, true); + + unset($qa_content['form_profile']['fields']['uc_'.$index.'_cat']['note']); + } + } + + $qa_content['script_lines'][] = array( + "function qa_update_category_levels()", + "{", + "\tglob=document.getElementById('level_select');", + "\tif (!glob)", + "\t\treturn;", + "\tvar opts=glob.options;", + "\tvar lev=parseInt(opts[glob.selectedIndex].value);", + "\tfor (var i=1; i<9999; i++) {", + "\t\tvar sel=document.getElementById('ls_'+i);", + "\t\tif (!sel)", + "\t\t\tbreak;", + "\t\tsel.qa_prev=sel.qa_prev || sel.options[sel.selectedIndex].value;", + "\t\tsel.options.length=1;", // just leaves "no upgrade" element + "\t\tfor (var j=0; jlev)", + "\t\t\t\tsel.options[sel.options.length]=new Option(opts[j].text, opts[j].value, false, (opts[j].value==sel.qa_prev));", + "\t}", + "}", + ); + + $qa_content['script_onloads'][] = array( + "qa_update_category_levels();", + ); + + $qa_content['form_profile']['fields']['level']['tags'] .= ' id="level_select" onchange="qa_update_category_levels();"'; + + } + } + + } + else { + foreach ($userlevels as $userlevel) { + if ( $userlevel['entitytype'] == QA_ENTITY_CATEGORY && $userlevel['level'] > $useraccount['level'] ) { + $qa_content['form_profile']['fields']['level']['value'] .= '
    '. + strtr(qa_lang_html('users/level_for_category'), array( + '^1' => qa_html(qa_user_level_string($userlevel['level'])), + '^2' => ''.qa_html($userlevel['title']).'', + )); + } + } + } + + + // Show any extra privileges due to user's level or their points + + $showpermits = array(); + $permitoptions = qa_get_permit_options(); + + foreach ($permitoptions as $permitoption) { + if ( // if not available to approved and email confirmed users with no points, but yes available to the user, it's something special + qa_permit_error($permitoption, $userid, QA_USER_LEVEL_APPROVED, QA_USER_FLAGS_EMAIL_CONFIRMED, 0) && + !qa_permit_error($permitoption, $userid, $useraccount['level'], $useraccount['flags'], $userpoints['points']) + ) { + if ($permitoption == 'permit_retag_cat') + $showpermits[] = qa_lang(qa_using_categories() ? 'profile/permit_recat' : 'profile/permit_retag'); + else + $showpermits[] = qa_lang('profile/'.$permitoption); // then show it as an extra priviliege + } + } + + if (count($showpermits)) { + $qa_content['form_profile']['fields']['permits'] = array( + 'type' => 'static', + 'label' => qa_lang_html('profile/extra_privileges'), + 'value' => qa_html(implode("\n", $showpermits), true), + 'rows' => count($showpermits), + 'id' => 'permits', + ); + } + + + // Show email address only if we're an administrator + + if (($loginlevel >= QA_USER_LEVEL_ADMIN) && !qa_user_permit_error()) { + $doconfirms = qa_opt('confirm_user_emails') && $useraccount['level'] < QA_USER_LEVEL_EXPERT; + $isconfirmed = ($useraccount['flags'] & QA_USER_FLAGS_EMAIL_CONFIRMED) > 0; + $htmlemail = qa_html(isset($inemail) ? $inemail : $useraccount['email']); + + $qa_content['form_profile']['fields']['email'] = array( + 'type' => $userediting ? 'text' : 'static', + 'label' => qa_lang_html('users/email_label'), + 'tags' => 'name="email"', + 'value' => $userediting ? $htmlemail : (''.$htmlemail.''), + 'error' => qa_html(@$errors['email']), + 'note' => ($doconfirms ? (qa_lang_html($isconfirmed ? 'users/email_confirmed' : 'users/email_not_confirmed').' ') : ''). + ($userediting ? '' : qa_lang_html('users/only_shown_admins')), + 'id' => 'email', + ); + } + + + // Show IP addresses and times for last login or write - only if we're a moderator or higher + + if (($loginlevel >= QA_USER_LEVEL_MODERATOR) && !qa_user_permit_error()) { + $qa_content['form_profile']['fields']['lastlogin'] = array( + 'type' => 'static', + 'label' => qa_lang_html('users/last_login_label'), + 'value' => + strtr(qa_lang_html('users/x_ago_from_y'), array( + '^1' => qa_time_to_string(qa_opt('db_time')-$useraccount['loggedin']), + '^2' => qa_ip_anchor_html($useraccount['loginip']), + )), + 'note' => $userediting ? null : qa_lang_html('users/only_shown_moderators'), + 'id' => 'lastlogin', + ); + + if (isset($useraccount['written'])) { + $qa_content['form_profile']['fields']['lastwrite'] = array( + 'type' => 'static', + 'label' => qa_lang_html('users/last_write_label'), + 'value' => + strtr(qa_lang_html('users/x_ago_from_y'), array( + '^1' => qa_time_to_string(qa_opt('db_time')-$useraccount['written']), + '^2' => qa_ip_anchor_html($useraccount['writeip']), + )), + 'note' => $userediting ? null : qa_lang_html('users/only_shown_moderators'), + 'id' => 'lastwrite', + ); + } + else + unset($qa_content['form_profile']['fields']['lastwrite']); + } + + + // Show other profile fields + + $fieldsediting = $fieldseditable && $userediting; + + foreach ($userfields as $userfield) { + if (($userfield['flags'] & QA_FIELD_FLAGS_LINK_URL) && !$fieldsediting) + $valuehtml = qa_url_to_html_link(@$userprofile[$userfield['title']], qa_opt('links_in_new_window')); + + else { + $value = @$inprofile[$userfield['fieldid']]; + if (!isset($value)) + $value = @$userprofile[$userfield['title']]; + + $valuehtml = qa_html($value, (($userfield['flags'] & QA_FIELD_FLAGS_MULTI_LINE) && !$fieldsediting)); + } + + $label = trim(qa_user_userfield_label($userfield), ':'); + if (strlen($label)) + $label .= ':'; + + $notehtml = null; + if (isset($userfield['permit']) && !$userediting) { + if ($userfield['permit'] <= QA_PERMIT_ADMINS) + $notehtml = qa_lang_html('users/only_shown_admins'); + elseif ($userfield['permit'] <= QA_PERMIT_MODERATORS) + $notehtml = qa_lang_html('users/only_shown_moderators'); + elseif ($userfield['permit'] <= QA_PERMIT_EDITORS) + $notehtml = qa_lang_html('users/only_shown_editors'); + elseif ($userfield['permit'] <= QA_PERMIT_EXPERTS) + $notehtml = qa_lang_html('users/only_shown_experts'); + } + + $qa_content['form_profile']['fields'][$userfield['title']] = array( + 'type' => $fieldsediting ? 'text' : 'static', + 'label' => qa_html($label), + 'tags' => 'name="field_'.$userfield['fieldid'].'"', + 'value' => $valuehtml, + 'error' => qa_html(@$errors[$userfield['fieldid']]), + 'note' => $notehtml, + 'rows' => ($userfield['flags'] & QA_FIELD_FLAGS_MULTI_LINE) ? 8 : null, + 'id' => 'userfield-'.$userfield['fieldid'], + ); + } + + + // Edit form or button, if appropriate + + if ($userediting) { + if ( + (qa_opt('avatar_allow_gravatar') && ($useraccount['flags'] & QA_USER_FLAGS_SHOW_GRAVATAR)) || + (qa_opt('avatar_allow_upload') && ($useraccount['flags'] & QA_USER_FLAGS_SHOW_AVATAR) && isset($useraccount['avatarblobid'])) + ) { + $qa_content['form_profile']['fields']['removeavatar'] = array( + 'type' => 'checkbox', + 'label' => qa_lang_html('users/remove_avatar'), + 'tags' => 'name="removeavatar"', + ); + } + + $qa_content['form_profile']['buttons'] = array( + 'save' => array( + 'tags' => 'onclick="qa_show_waiting_after(this, false);"', + 'label' => qa_lang_html('users/save_user'), + ), + + 'cancel' => array( + 'tags' => 'name="docancel"', + 'label' => qa_lang_html('main/cancel_button'), + ), + ); + + $qa_content['form_profile']['hidden'] = array( + 'dosave' => '1', + 'code' => qa_get_form_security_code('user-edit-'.$handle), + ); + + } + elseif ($usereditbutton) { + $qa_content['form_profile']['buttons'] = array(); + + if ($approvebutton) { + $qa_content['form_profile']['buttons']['approve'] = array( + 'tags' => 'name="doapprove"', + 'label' => qa_lang_html('users/approve_user_button'), + ); + } + + $qa_content['form_profile']['buttons']['edit'] = array( + 'tags' => 'name="doedit"', + 'label' => qa_lang_html('users/edit_user_button'), + ); + + if (isset($maxlevelassign) && $useraccount['level'] < QA_USER_LEVEL_MODERATOR) { + if ($useraccount['flags'] & QA_USER_FLAGS_USER_BLOCKED) { + $qa_content['form_profile']['buttons']['unblock'] = array( + 'tags' => 'name="dounblock"', + 'label' => qa_lang_html('users/unblock_user_button'), + ); + + if (!qa_user_permit_error('permit_hide_show')) { + $qa_content['form_profile']['buttons']['hideall'] = array( + 'tags' => 'name="dohideall" onclick="qa_show_waiting_after(this, false);"', + 'label' => qa_lang_html('users/hide_all_user_button'), + ); + } + + if ($loginlevel >= QA_USER_LEVEL_ADMIN) { + $qa_content['form_profile']['buttons']['delete'] = array( + 'tags' => 'name="dodelete" onclick="qa_show_waiting_after(this, false);"', + 'label' => qa_lang_html('users/delete_user_button'), + ); + } + + } + else { + $qa_content['form_profile']['buttons']['block'] = array( + 'tags' => 'name="doblock"', + 'label' => qa_lang_html('users/block_user_button'), + ); + } + + $qa_content['form_profile']['hidden'] = array( + 'code' => qa_get_form_security_code('user-'.$handle), + ); + } + + } + elseif (isset($loginuserid) && ($loginuserid == $userid)) { + $qa_content['form_profile']['buttons'] = array( + 'account' => array( + 'tags' => 'name="doaccount"', + 'label' => qa_lang_html('users/edit_profile'), + ), + ); + } + + + if (!is_array($qa_content['form_profile']['fields']['removeavatar'])) + unset($qa_content['form_profile']['fields']['removeavatar']); + + $qa_content['raw']['account'] = $useraccount; // for plugin layers to access + $qa_content['raw']['profile'] = $userprofile; + } + + +// Information about user activity, available also with single sign-on integration + + $qa_content['form_activity'] = array( + 'title' => ''.qa_lang_html_sub('profile/activity_by_x', $userhtml).'', + + 'style' => 'wide', + + 'fields' => array( + 'bonus' => array( + 'label' => qa_lang_html('profile/bonus_points'), + 'tags' => 'name="bonus"', + 'value' => qa_html(isset($inbonus) ? $inbonus : $userpoints['bonus']), + 'type' => 'number', + 'note' => qa_lang_html('users/only_shown_admins'), + 'id' => 'bonus', + ), + + 'points' => array( + 'type' => 'static', + 'label' => qa_lang_html('profile/score'), + 'value' => (@$userpoints['points'] == 1) + ? qa_lang_html_sub('main/1_point', '1', '1') + : qa_lang_html_sub('main/x_points', ''.qa_html(number_format(@$userpoints['points'])).''), + 'id' => 'points', + ), + + 'title' => array( + 'type' => 'static', + 'label' => qa_lang_html('profile/title'), + 'value' => qa_get_points_title_html(@$userpoints['points'], qa_get_points_to_titles()), + 'id' => 'title', + ), + + 'questions' => array( + 'type' => 'static', + 'label' => qa_lang_html('profile/questions'), + 'value' => ''.qa_html(number_format(@$userpoints['qposts'])).'', + 'id' => 'questions', + ), + + 'answers' => array( + 'type' => 'static', + 'label' => qa_lang_html('profile/answers'), + 'value' => ''.qa_html(number_format(@$userpoints['aposts'])).'', + 'id' => 'answers', + ), + ), + ); + + if ($loginlevel >= QA_USER_LEVEL_ADMIN) { + $qa_content['form_activity']['tags'] = 'method="post" action="'.qa_self_html().'"'; + + $qa_content['form_activity']['buttons'] = array( + 'setbonus' => array( + 'tags' => 'name="dosetbonus"', + 'label' => qa_lang_html('profile/set_bonus_button'), + ), + ); + + $qa_content['form_activity']['hidden'] = array( + 'code' => qa_get_form_security_code('user-activity-'.$handle), + ); + + } + else + unset($qa_content['form_activity']['fields']['bonus']); + + if (!isset($qa_content['form_activity']['fields']['title']['value'])) + unset($qa_content['form_activity']['fields']['title']); + + if (qa_opt('comment_on_qs') || qa_opt('comment_on_as')) { // only show comment count if comments are enabled + $qa_content['form_activity']['fields']['comments'] = array( + 'type' => 'static', + 'label' => qa_lang_html('profile/comments'), + 'value' => ''.qa_html(number_format(@$userpoints['cposts'])).'', + 'id' => 'comments', + ); + } + + if (qa_opt('voting_on_qs') || qa_opt('voting_on_as')) { // only show vote record if voting is enabled + $votedonvalue = ''; + + if (qa_opt('voting_on_qs')) { + $qvotes = @$userpoints['qupvotes']+@$userpoints['qdownvotes']; + + $innervalue = ''.number_format($qvotes).''; + $votedonvalue .= ($qvotes == 1) ? qa_lang_html_sub('main/1_question', $innervalue, '1') + : qa_lang_html_sub('main/x_questions', $innervalue); + + if (qa_opt('voting_on_as')) + $votedonvalue .= ', '; + } + + if (qa_opt('voting_on_as')) { + $avotes = @$userpoints['aupvotes']+@$userpoints['adownvotes']; + + $innervalue = ''.number_format($avotes).''; + $votedonvalue .= ($avotes == 1) ? qa_lang_html_sub('main/1_answer', $innervalue, '1') + : qa_lang_html_sub('main/x_answers', $innervalue); + } + + $qa_content['form_activity']['fields']['votedon'] = array( + 'type' => 'static', + 'label' => qa_lang_html('profile/voted_on'), + 'value' => $votedonvalue, + 'id' => 'votedon', + ); + + $upvotes = @$userpoints['qupvotes']+@$userpoints['aupvotes']; + $innervalue = ''.number_format($upvotes).''; + $votegavevalue = (($upvotes == 1) ? qa_lang_html_sub('profile/1_up_vote', $innervalue, '1') : qa_lang_html_sub('profile/x_up_votes', $innervalue)).', '; + + $downvotes = @$userpoints['qdownvotes']+@$userpoints['adownvotes']; + $innervalue = ''.number_format($downvotes).''; + $votegavevalue .= ($downvotes == 1) ? qa_lang_html_sub('profile/1_down_vote', $innervalue, '1') : qa_lang_html_sub('profile/x_down_votes', $innervalue); + + $qa_content['form_activity']['fields']['votegave'] = array( + 'type' => 'static', + 'label' => qa_lang_html('profile/gave_out'), + 'value' => $votegavevalue, + 'id' => 'votegave', + ); + + $innervalue = ''.number_format(@$userpoints['upvoteds']).''; + $votegotvalue = ((@$userpoints['upvoteds'] == 1) ? qa_lang_html_sub('profile/1_up_vote', $innervalue, '1') + : qa_lang_html_sub('profile/x_up_votes', $innervalue)).', '; + + $innervalue = ''.number_format(@$userpoints['downvoteds']).''; + $votegotvalue .= (@$userpoints['downvoteds'] == 1) ? qa_lang_html_sub('profile/1_down_vote', $innervalue, '1') + : qa_lang_html_sub('profile/x_down_votes', $innervalue); + + $qa_content['form_activity']['fields']['votegot'] = array( + 'type' => 'static', + 'label' => qa_lang_html('profile/received'), + 'value' => $votegotvalue, + 'id' => 'votegot', + ); + } + + if (@$userpoints['points']) { + $qa_content['form_activity']['fields']['points']['value'] .= + qa_lang_html_sub('profile/ranked_x', ''.number_format($userrank).''); + } + + if (@$userpoints['aselects']) { + $qa_content['form_activity']['fields']['questions']['value'] .= ($userpoints['aselects'] == 1) + ? qa_lang_html_sub('profile/1_with_best_chosen', '1', '1') + : qa_lang_html_sub('profile/x_with_best_chosen', ''.number_format($userpoints['aselects']).''); + } + + if (@$userpoints['aselecteds']) { + $qa_content['form_activity']['fields']['answers']['value'] .= ($userpoints['aselecteds'] == 1) + ? qa_lang_html_sub('profile/1_chosen_as_best', '1', '1') + : qa_lang_html_sub('profile/x_chosen_as_best', ''.number_format($userpoints['aselecteds']).''); + } + + + +// For plugin layers to access + + $qa_content['raw']['userid'] = $userid; + $qa_content['raw']['points'] = $userpoints; + $qa_content['raw']['rank'] = $userrank; + + +// Wall posts + + if (!QA_FINAL_EXTERNAL_USERS && qa_opt('allow_user_walls')) { + $qa_content['message_list'] = array( + 'title' => ''.qa_lang_html_sub('profile/wall_for_x', $userhtml).'', + + 'tags' => 'id="wallmessages"', + + 'form' => array( + 'tags' => 'name="wallpost" method="post" action="'.qa_self_html().'#wall"', + 'style' => 'tall', + 'hidden' => array( + 'qa_click' => '', // for simulating clicks in Javascript + 'handle' => qa_html($useraccount['handle']), + 'start' => 0, + 'code' => qa_get_form_security_code('wall-'.$useraccount['handle']), + ), + ), + + 'messages' => array(), + ); + + if ($wallposterrorhtml) + $qa_content['message_list']['error'] = $wallposterrorhtml; // an error that means we are not allowed to post + + else { + $qa_content['message_list']['form']['fields'] = array( + 'message' => array( + 'tags' => 'name="message" id="message"', + 'value' => qa_html(@$inmessage, false), + 'rows' => 2, + 'error' => qa_html(@$errors['message']), + ), + ); + + $qa_content['message_list']['form']['buttons'] = array( + 'post' => array( + 'tags' => 'name="dowallpost" onclick="return qa_submit_wall_post(this, true);"', + 'label' => qa_lang_html('profile/post_wall_button'), + ), + ); + } + + foreach ($usermessages as $message) + $qa_content['message_list']['messages'][] = qa_wall_post_view($message); + + if ($useraccount['wallposts'] > count($usermessages)) + $qa_content['message_list']['messages'][] = qa_wall_view_more_link($handle, count($usermessages)); + } + + +// Sub menu for navigation in user pages + + $ismyuser = isset($loginuserid) && $loginuserid == (QA_FINAL_EXTERNAL_USERS ? $userid : $useraccount['userid']); + $qa_content['navigation']['sub'] = qa_user_sub_navigation($handle, 'profile', $ismyuser); + + + return $qa_content; + + +/* + Omit PHP closing tag to help avoid accidental output +*/ \ No newline at end of file diff --git a/pages/user-questions.php b/pages/user-questions.php new file mode 100644 index 0000000..f8256a9 --- /dev/null +++ b/pages/user-questions.php @@ -0,0 +1,105 @@ + 'method="post" action="'.qa_self_html().'"', + + 'hidden' => array( + 'code' => qa_get_form_security_code('vote'), + ), + ); + + $qa_content['q_list']['qs'] = array(); + + $htmldefaults = qa_post_html_defaults('Q'); + $htmldefaults['whoview'] = false; + $htmldefaults['avatarsize'] = 0; + + foreach ($questions as $question) { + $qa_content['q_list']['qs'][] = qa_post_html_fields($question, $loginuserid, qa_cookie_get(), + $usershtml, null, qa_post_html_options($question, $htmldefaults)); + } + + $qa_content['page_links'] = qa_html_page_links(qa_request(), $start, $pagesize, $count, qa_opt('pages_prev_next')); + + +// Sub menu for navigation in user pages + + $ismyuser = isset($loginuserid) && $loginuserid == (QA_FINAL_EXTERNAL_USERS ? $userid : $useraccount['userid']); + $qa_content['navigation']['sub'] = qa_user_sub_navigation($handle, 'questions', $ismyuser); + + + return $qa_content; + + +/* + Omit PHP closing tag to help avoid accidental output +*/ \ No newline at end of file diff --git a/pages/user-wall.php b/pages/user-wall.php new file mode 100644 index 0000000..4e77e9f --- /dev/null +++ b/pages/user-wall.php @@ -0,0 +1,164 @@ + 'id="wallmessages"', + + 'form' => array( + 'tags' => 'name="wallpost" method="post" action="'.qa_self_html().'"', + 'style' => 'tall', + 'hidden' => array( + 'qa_click' => '', // for simulating clicks in Javascript + 'handle' => qa_html($useraccount['handle']), + 'start' => qa_html($start), + 'code' => qa_get_form_security_code('wall-'.$useraccount['handle']), + ), + ), + + 'messages' => array(), + ); + + if ($start == 0) { // only allow posting on first page + if ($wallposterrorhtml) + $qa_content['message_list']['error'] = $wallposterrorhtml; // an error that means we are not allowed to post + + else { + $qa_content['message_list']['form']['fields'] = array( + 'message' => array( + 'tags' => 'name="message" id="message"', + 'value' => qa_html(@$inmessage, false), + 'rows' => 2, + 'error' => qa_html(@$errors['message']), + ), + ); + + $qa_content['message_list']['form']['buttons'] = array( + 'post' => array( + 'tags' => 'name="dowallpost" onclick="return qa_submit_wall_post(this, false);"', + 'label' => qa_lang_html('profile/post_wall_button'), + ), + ); + } + } + + foreach ($usermessages as $message) + $qa_content['message_list']['messages'][] = qa_wall_post_view($message); + + $qa_content['page_links'] = qa_html_page_links(qa_request(), $start, $pagesize, $count, qa_opt('pages_prev_next')); + + +// Sub menu for navigation in user pages + + $ismyuser = isset($loginuserid) && $loginuserid == (QA_FINAL_EXTERNAL_USERS ? $userid : $useraccount['userid']); + $qa_content['navigation']['sub'] = qa_user_sub_navigation($handle, 'wall', $ismyuser); + + + return $qa_content; + + +/* + Omit PHP closing tag to help avoid accidental output +*/ \ No newline at end of file diff --git a/pages/user.php b/pages/user.php new file mode 100644 index 0000000..9729520 --- /dev/null +++ b/pages/user.php @@ -0,0 +1,90 @@ + 0 ? qa_lang_html('users/blocked_users') : qa_lang_html('users/no_blocked_users'); + + $qa_content['ranking'] = array( + 'items' => array(), + 'rows' => ceil(count($users)/qa_opt('columns_users')), + 'type' => 'users' + ); + + foreach ($users as $user) { + $qa_content['ranking']['items'][] = array( + 'label' => $usershtml[$user['userid']], + 'score' => qa_html(qa_user_level_string($user['level'])), + 'raw' => $user, + ); + } + + $qa_content['page_links'] = qa_html_page_links(qa_request(), $start, $pagesize, $count, qa_opt('pages_prev_next')); + + $qa_content['navigation']['sub'] = qa_users_sub_navigation(); + + + return $qa_content; + + +/* + Omit PHP closing tag to help avoid accidental output +*/ \ No newline at end of file diff --git a/pages/users-special.php b/pages/users-special.php new file mode 100644 index 0000000..310acad --- /dev/null +++ b/pages/users-special.php @@ -0,0 +1,86 @@ + array(), + 'rows' => ceil(qa_opt('page_size_users')/qa_opt('columns_users')), + 'type' => 'users' + ); + + foreach ($users as $user) { + $qa_content['ranking']['items'][] = array( + 'label' => $usershtml[$user['userid']], + 'score' => qa_html(qa_user_level_string($user['level'])), + 'raw' => $user, + ); + } + + $qa_content['navigation']['sub'] = qa_users_sub_navigation(); + + + return $qa_content; + + +/* + Omit PHP closing tag to help avoid accidental output +*/ \ No newline at end of file diff --git a/pages/users.php b/pages/users.php new file mode 100644 index 0000000..3b8bac4 --- /dev/null +++ b/pages/users.php @@ -0,0 +1,87 @@ + array(), + 'rows' => ceil($pagesize/qa_opt('columns_users')), + 'type' => 'users' + ); + + if (count($users)) { + foreach ($users as $userid => $user) { + if (QA_FINAL_EXTERNAL_USERS) + $avatarhtml = qa_get_external_avatar_html($user['userid'], qa_opt('avatar_users_size'), true); + else { + $avatarhtml = qa_get_user_avatar_html($user['flags'], $user['email'], $user['handle'], + $user['avatarblobid'], $user['avatarwidth'], $user['avatarheight'], qa_opt('avatar_users_size'), true); + } + + // avatar and handle now listed separately for use in themes + $qa_content['ranking']['items'][] = array( + 'avatar' => $avatarhtml, + 'label' => $usershtml[$user['userid']], + 'score' => qa_html(number_format($user['points'])), + 'raw' => $user, + ); + } + } + else + $qa_content['title'] = qa_lang_html('main/no_active_users'); + + $qa_content['page_links'] = qa_html_page_links(qa_request(), $start, $pagesize, $usercount, qa_opt('pages_prev_next')); + + $qa_content['navigation']['sub'] = qa_users_sub_navigation(); + + + return $qa_content; + + +/* + Omit PHP closing tag to help avoid accidental output +*/ \ No newline at end of file diff --git a/qa-plugin.php b/qa-plugin.php new file mode 100644 index 0000000..541c8f4 --- /dev/null +++ b/qa-plugin.php @@ -0,0 +1,14 @@ +