public function index_post($postid, $type, $questionid, $parentid, $title, $content, $format, $text, $tagstring, $categoryid) { require_once QA_INCLUDE_DIR . 'db/post-create.php'; // Get words from each textual element $titlewords = array_unique(qa_string_to_words($title)); $contentcount = array_count_values(qa_string_to_words($text)); $tagwords = array_unique(qa_string_to_words($tagstring)); $wholetags = array_unique(qa_tagstring_to_tags($tagstring)); // Map all words to their word IDs $words = array_unique(array_merge($titlewords, array_keys($contentcount), $tagwords, $wholetags)); $wordtoid = qa_db_word_mapto_ids_add($words); // Add to title words index $titlewordids = qa_array_filter_by_keys($wordtoid, $titlewords); qa_db_titlewords_add_post_wordids($postid, $titlewordids); // Add to content words index (including word counts) $contentwordidcounts = array(); foreach ($contentcount as $word => $count) { if (isset($wordtoid[$word])) { $contentwordidcounts[$wordtoid[$word]] = $count; } } qa_db_contentwords_add_post_wordidcounts($postid, $type, $questionid, $contentwordidcounts); // Add to tag words index $tagwordids = qa_array_filter_by_keys($wordtoid, $tagwords); qa_db_tagwords_add_post_wordids($postid, $tagwordids); // Add to whole tags index $wholetagids = qa_array_filter_by_keys($wordtoid, $wholetags); qa_db_posttags_add_post_wordids($postid, $wholetagids); // Update counts cached in database (will be skipped if qa_suspend_update_counts() was called qa_db_word_titlecount_update($titlewordids); qa_db_word_contentcount_update(array_keys($contentwordidcounts)); qa_db_word_tagwordcount_update($tagwordids); qa_db_word_tagcount_update($wholetagids); qa_db_tagcount_update(); }
function qa_create_event_for_tags($tagstring, $questionid, $updatetype, $lastuserid, $timestamp = null) { require_once QA_INCLUDE_DIR . 'util/string.php'; require_once QA_INCLUDE_DIR . 'db/post-create.php'; $tagwordids = qa_db_word_mapto_ids(array_unique(qa_tagstring_to_tags($tagstring))); foreach ($tagwordids as $wordid) { qa_db_event_create_for_entity(QA_ENTITY_TAG, $wordid, $questionid, $questionid, $updatetype, $lastuserid, $timestamp); } }
function process_event($event, $userid, $handle, $cookieid, $params) { // only interested in q_post & q_edit if ($event != 'q_post' && $event != 'q_edit') { return; } // get config data $config = qa_opt('tag_synonyms'); if (!$config) { return; } $oldtags = qa_tagstring_to_tags($params['tags']); $synonyms = $this->_synonyms_to_array($config); $newtags = $this->_convert_tags($oldtags, $synonyms); // updating content would trigger another event, so we suspend events to avoid an infinite loop qa_suspend_event_reports(true); qa_post_set_content($params['postid'], $params['title'], $params['content'], $params['format'], $newtags); qa_suspend_event_reports(false); }
function qa_post_set_content($postid, $title, $content, $format = null, $tags = null, $notify = null, $email = null, $byuserid = null) { $oldpost = qa_post_get_full($postid, 'QAC'); if (!isset($title)) { $title = $oldpost['title']; } if (!isset($content)) { $content = $oldpost['content']; } if (!isset($format)) { $format = $oldpost['format']; } if (!isset($tags)) { $tags = qa_tagstring_to_tags($oldpost['tags']); } if (isset($notify) || isset($email)) { $setnotify = qa_combine_notify_email($oldpost['userid'], isset($notify) ? $notify : isset($oldpost['notify']), isset($email) ? $email : $oldpost['notify']); } else { $setnotify = $oldpost['notify']; } $byhandle = qa_post_userid_to_handle($byuserid); $text = qa_post_content_to_text($content, $format); switch ($oldpost['basetype']) { case 'Q': $tagstring = qa_post_tags_to_tagstring($tags); qa_question_set_content($oldpost, $title, $content, $format, $text, $tagstring, $setnotify, $byuserid, $byhandle, null); break; case 'A': $question = qa_post_get_full($oldpost['parentid'], 'Q'); qa_answer_set_content($oldpost, $content, $format, $text, $setnotify, $byuserid, $byhandle, null, $question); break; case 'C': $parentpost = qa_post_get_full($oldpost['parentid'], 'QA'); $question = qa_post_parent_to_question($parentpost); $answer = qa_post_parent_to_answer($parentpost); qa_comment_set_content($oldpost, $content, $format, $text, $setnotify, $byuserid, $byhandle, null, $question, $answer); break; } }
function qa_page_q_edit_q_submit($question, $answers, $commentsfollows, $closepost, &$in, &$errors) { $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') ? true : false; $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_prepare_post_for_filters($post) { $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; }
function qw_notify_emails_selectspec($userid, $tags, $categoryid) { if (file_exists(QW_CONTROL_DIR . '/addons/notification/functions.php')) { require_once QW_CONTROL_DIR . '/addons/notification/functions.php'; if (notify_addon_enabled_from_admin_panel()) { //proceed only if the plugin is enabled require_once QA_INCLUDE_DIR . 'qa-app-updates.php'; $source = ''; $arguments = array(); if (!!qa_opt('qw_notify_user_followers')) { $source .= !!$source ? ' UNION ' : ''; $source .= "( SELECT ^users.userid , 'q_post_user_fl' as event , ^userpoints.points from ^users JOIN ^userpoints ON ^users.userid=^userpoints.userid JOIN ^userfavorites ON ^users.userid=^userfavorites.userid WHERE ^userfavorites.entityid=\$ AND ^userfavorites.entitytype=\$ AND ^users.email !=\$ )"; $args = array($userid, QA_ENTITY_USER, qa_get_logged_in_user_field('email')); $arguments = array_merge($arguments, $args); } if (!!qa_opt('qw_notify_tag_followers') && !!$tags) { $source .= !!$source ? ' UNION ' : ''; $source .= "( SELECT ^users.userid , 'q_post_tag_fl' as event , ^userpoints.points from ^users JOIN ^userpoints ON ^users.userid=^userpoints.userid JOIN ^userfavorites ON ^userfavorites.userid=^users.userid WHERE ^userfavorites.entityid IN \n\t\t ( SELECT wordid from ^words where ^words.word IN (\$) ) AND ^userfavorites.entitytype=\$ AND ^users.email !=\$ )"; $args = array(qa_tagstring_to_tags($tags), QA_ENTITY_TAG, qa_get_logged_in_user_field('email')); $arguments = array_merge($arguments, $args); } if (!!qa_opt('qw_notify_cat_followers') && !!$categoryid) { $source .= !!$source ? ' UNION ' : ''; $source .= "( SELECT ^users.userid , 'q_post_cat_fl' as event , ^userpoints.points from ^users JOIN ^userpoints ON ^users.userid=^userpoints.userid JOIN ^userfavorites ON ^userfavorites.userid=^users.userid " . " WHERE ^userfavorites.entityid=\$ AND ^userfavorites.entitytype=\$ AND ^users.email !=\$ )"; $args = array($categoryid, QA_ENTITY_CATEGORY, qa_get_logged_in_user_field('email')); $arguments = array_merge($arguments, $args); } $where_clause = ''; if (!!qa_opt('qw_notify_min_points_opt')) { //generate where clause $min_user_points = qa_opt('qw_notify_min_points_val'); $where_clause = !!$min_user_points && $min_user_points > 0 ? ' WHERE result.points > ' . $min_user_points : ''; } return array('columns' => array(' * '), 'source' => ' ( ' . $source . ' ) as result ' . $where_clause, 'arguments' => $arguments, 'sortasc' => 'title'); } //if plugin is enabled } }
function qa_post_html_fields($post, $userid, $cookieid, $usershtml, $dummy, $options = array()) { if (qa_to_override(__FUNCTION__)) { $args = func_get_args(); return qa_call_override(__FUNCTION__, $args); } require_once QA_INCLUDE_DIR . 'app/updates.php'; if (isset($options['blockwordspreg'])) { require_once QA_INCLUDE_DIR . 'util/string.php'; } $fields = array('raw' => $post); // Useful stuff used throughout function $postid = $post['postid']; $isquestion = $post['basetype'] == 'Q'; $isanswer = $post['basetype'] == 'A'; $isbyuser = qa_post_is_by_user($post, $userid, $cookieid); $anchor = urlencode(qa_anchor($post['basetype'], $postid)); $elementid = isset($options['elementid']) ? $options['elementid'] : $anchor; $microformats = @$options['microformats']; $isselected = @$options['isselected']; $favoritedview = @$options['favoritedview']; $favoritemap = $favoritedview ? qa_get_favorite_non_qs_map() : array(); // High level information $fields['hidden'] = @$post['hidden']; $fields['tags'] = 'id="' . qa_html($elementid) . '"'; $fields['classes'] = $isquestion && $favoritedview && @$post['userfavoriteq'] ? 'qa-q-favorited' : ''; if ($isquestion && isset($post['closedbyid'])) { $fields['classes'] = ltrim($fields['classes'] . ' qa-q-closed'); } if ($microformats) { $fields['classes'] .= ' hentry ' . ($isquestion ? 'question' : ($isanswer ? $isselected ? 'answer answer-selected' : 'answer' : 'comment')); } // Question-specific stuff (title, URL, tags, answer count, category) if ($isquestion) { if (isset($post['title'])) { $fields['url'] = qa_q_path_html($postid, $post['title']); if (isset($options['blockwordspreg'])) { $post['title'] = qa_block_words_replace($post['title'], $options['blockwordspreg']); } $fields['title'] = qa_html($post['title']); if ($microformats) { $fields['title'] = '<span class="entry-title">' . $fields['title'] . '</span>'; } /*if (isset($post['score'])) // useful for setting match thresholds $fields['title'].=' <small>('.$post['score'].')</small>';*/ } if (@$options['tagsview'] && isset($post['tags'])) { $fields['q_tags'] = array(); $tags = qa_tagstring_to_tags($post['tags']); foreach ($tags as $tag) { if (isset($options['blockwordspreg']) && count(qa_block_words_match_all($tag, $options['blockwordspreg']))) { // skip censored tags continue; } $fields['q_tags'][] = qa_tag_html($tag, $microformats, @$favoritemap['tag'][qa_strtolower($tag)]); } } if (@$options['answersview'] && isset($post['acount'])) { $fields['answers_raw'] = $post['acount']; $fields['answers'] = $post['acount'] == 1 ? qa_lang_html_sub_split('main/1_answer', '1', '1') : qa_lang_html_sub_split('main/x_answers', number_format($post['acount'])); $fields['answer_selected'] = isset($post['selchildid']); } if (@$options['viewsview'] && isset($post['views'])) { $fields['views_raw'] = $post['views']; $fields['views'] = $post['views'] == 1 ? qa_lang_html_sub_split('main/1_view', '1', '1') : qa_lang_html_sub_split('main/x_views', number_format($post['views'])); } if (@$options['categoryview'] && isset($post['categoryname']) && isset($post['categorybackpath'])) { $favoriteclass = ''; if (count(@$favoritemap['category'])) { if (@$favoritemap['category'][$post['categorybackpath']]) { $favoriteclass = ' qa-cat-favorited'; } else { foreach ($favoritemap['category'] as $categorybackpath => $dummy) { if (substr('/' . $post['categorybackpath'], -strlen($categorybackpath)) == $categorybackpath) { $favoriteclass = ' qa-cat-parent-favorited'; } } } } $fields['where'] = qa_lang_html_sub_split('main/in_category_x', '<a href="' . qa_path_html(@$options['categorypathprefix'] . implode('/', array_reverse(explode('/', $post['categorybackpath'])))) . '" class="qa-category-link' . $favoriteclass . '">' . qa_html($post['categoryname']) . '</a>'); } } // Answer-specific stuff (selection) if ($isanswer) { $fields['selected'] = $isselected; if ($isselected) { $fields['select_text'] = qa_lang_html('question/select_text'); } } // Post content if (@$options['contentview'] && isset($post['content'])) { $viewer = qa_load_viewer($post['content'], $post['format']); $fields['content'] = $viewer->get_html($post['content'], $post['format'], array('blockwordspreg' => @$options['blockwordspreg'], 'showurllinks' => @$options['showurllinks'], 'linksnewwindow' => @$options['linksnewwindow'])); if ($microformats) { $fields['content'] = '<div class="entry-content">' . $fields['content'] . '</div>'; } $fields['content'] = '<a name="' . qa_html($postid) . '"></a>' . $fields['content']; // this is for backwards compatibility with any existing links using the old style of anchor // that contained the post id only (changed to be valid under W3C specifications) } // Voting stuff if (@$options['voteview']) { $voteview = $options['voteview']; // Calculate raw values and pass through if (@$options['ovoteview'] && isset($post['opostid'])) { $upvotes = (int) @$post['oupvotes']; $downvotes = (int) @$post['odownvotes']; $fields['vote_opostid'] = true; // for voters/flaggers layer } else { $upvotes = (int) @$post['upvotes']; $downvotes = (int) @$post['downvotes']; } $netvotes = (int) ($upvotes - $downvotes); $fields['upvotes_raw'] = $upvotes; $fields['downvotes_raw'] = $downvotes; $fields['netvotes_raw'] = $netvotes; // Create HTML versions... $upvoteshtml = qa_html($upvotes); $downvoteshtml = qa_html($downvotes); if ($netvotes >= 1) { $netvoteshtml = '+' . qa_html($netvotes); } elseif ($netvotes <= -1) { $netvoteshtml = '–' . qa_html(-$netvotes); } else { $netvoteshtml = '0'; } // ...with microformats if appropriate if ($microformats) { $netvoteshtml .= '<span class="votes-up"><span class="value-title" title="' . $upvoteshtml . '"></span></span>' . '<span class="votes-down"><span class="value-title" title="' . $downvoteshtml . '"></span></span>'; $upvoteshtml = '<span class="votes-up">' . $upvoteshtml . '</span>'; $downvoteshtml = '<span class="votes-down">' . $downvoteshtml . '</span>'; } // Pass information on vote viewing // $voteview will be one of: // updown, updown-disabled-page, updown-disabled-level, updown-uponly-level, updown-disabled-approve, updown-uponly-approve // net, net-disabled-page, net-disabled-level, net-uponly-level, net-disabled-approve, net-uponly-approve $fields['vote_view'] = substr($voteview, 0, 6) == 'updown' ? 'updown' : 'net'; $fields['vote_on_page'] = strpos($voteview, '-disabled-page') ? 'disabled' : 'enabled'; $fields['upvotes_view'] = $upvotes == 1 ? qa_lang_html_sub_split('main/1_liked', $upvoteshtml, '1') : qa_lang_html_sub_split('main/x_liked', $upvoteshtml); $fields['downvotes_view'] = $downvotes == 1 ? qa_lang_html_sub_split('main/1_disliked', $downvoteshtml, '1') : qa_lang_html_sub_split('main/x_disliked', $downvoteshtml); $fields['netvotes_view'] = abs($netvotes) == 1 ? qa_lang_html_sub_split('main/1_vote', $netvoteshtml, '1') : qa_lang_html_sub_split('main/x_votes', $netvoteshtml); // Voting buttons $fields['vote_tags'] = 'id="voting_' . qa_html($postid) . '"'; $onclick = 'onclick="return qa_vote_click(this);"'; if ($fields['hidden']) { $fields['vote_state'] = 'disabled'; $fields['vote_up_tags'] = 'title="' . qa_lang_html($isanswer ? 'main/vote_disabled_hidden_a' : 'main/vote_disabled_hidden_q') . '"'; $fields['vote_down_tags'] = $fields['vote_up_tags']; } elseif ($isbyuser) { $fields['vote_state'] = 'disabled'; $fields['vote_up_tags'] = 'title="' . qa_lang_html($isanswer ? 'main/vote_disabled_my_a' : 'main/vote_disabled_my_q') . '"'; $fields['vote_down_tags'] = $fields['vote_up_tags']; } elseif (strpos($voteview, '-disabled-')) { $fields['vote_state'] = @$post['uservote'] > 0 ? 'voted_up_disabled' : (@$post['uservote'] < 0 ? 'voted_down_disabled' : 'disabled'); if (strpos($voteview, '-disabled-page')) { $fields['vote_up_tags'] = 'title="' . qa_lang_html('main/vote_disabled_q_page_only') . '"'; } elseif (strpos($voteview, '-disabled-approve')) { $fields['vote_up_tags'] = 'title="' . qa_lang_html('main/vote_disabled_approve') . '"'; } else { $fields['vote_up_tags'] = 'title="' . qa_lang_html('main/vote_disabled_level') . '"'; } $fields['vote_down_tags'] = $fields['vote_up_tags']; } elseif (@$post['uservote'] > 0) { $fields['vote_state'] = 'voted_up'; $fields['vote_up_tags'] = 'title="' . qa_lang_html('main/voted_up_popup') . '" name="' . qa_html('vote_' . $postid . '_0_' . $elementid) . '" ' . $onclick; $fields['vote_down_tags'] = ' '; } elseif (@$post['uservote'] < 0) { $fields['vote_state'] = 'voted_down'; $fields['vote_up_tags'] = ' '; $fields['vote_down_tags'] = 'title="' . qa_lang_html('main/voted_down_popup') . '" name="' . qa_html('vote_' . $postid . '_0_' . $elementid) . '" ' . $onclick; } else { $fields['vote_up_tags'] = 'title="' . qa_lang_html('main/vote_up_popup') . '" name="' . qa_html('vote_' . $postid . '_1_' . $elementid) . '" ' . $onclick; if (strpos($voteview, '-uponly-level')) { $fields['vote_state'] = 'up_only'; $fields['vote_down_tags'] = 'title="' . qa_lang_html('main/vote_disabled_down') . '"'; } elseif (strpos($voteview, '-uponly-approve')) { $fields['vote_state'] = 'up_only'; $fields['vote_down_tags'] = 'title="' . qa_lang_html('main/vote_disabled_down_approve') . '"'; } else { $fields['vote_state'] = 'enabled'; $fields['vote_down_tags'] = 'title="' . qa_lang_html('main/vote_down_popup') . '" name="' . qa_html('vote_' . $postid . '_-1_' . $elementid) . '" ' . $onclick; } } } // Flag count if (@$options['flagsview'] && @$post['flagcount']) { $fields['flags'] = $post['flagcount'] == 1 ? qa_lang_html_sub_split('main/1_flag', '1', '1') : qa_lang_html_sub_split('main/x_flags', $post['flagcount']); } // Created when and by whom $fields['meta_order'] = qa_lang_html('main/meta_order'); // sets ordering of meta elements which can be language-specific if (@$options['whatview']) { $fields['what'] = qa_lang_html($isquestion ? 'main/asked' : ($isanswer ? 'main/answered' : 'main/commented')); if (@$options['whatlink'] && strlen(@$options['q_request'])) { $fields['what_url'] = $post['basetype'] == 'Q' ? qa_path_html($options['q_request']) : qa_path_html($options['q_request'], array('show' => $postid), null, null, qa_anchor($post['basetype'], $postid)); } } if (isset($post['created']) && @$options['whenview']) { $fields['when'] = qa_when_to_html($post['created'], @$options['fulldatedays']); if ($microformats) { $fields['when']['data'] = '<span class="published"><span class="value-title" title="' . gmdate('Y-m-d\\TH:i:sO', $post['created']) . '">' . $fields['when']['data'] . '</span></span>'; } } if (@$options['whoview']) { $fields['who'] = qa_who_to_html($isbyuser, @$post['userid'], $usershtml, @$options['ipview'] ? @$post['createip'] : null, $microformats, $post['name']); if (isset($post['points'])) { if (@$options['pointsview']) { $fields['who']['points'] = $post['points'] == 1 ? qa_lang_html_sub_split('main/1_point', '1', '1') : qa_lang_html_sub_split('main/x_points', qa_html(number_format($post['points']))); } if (isset($options['pointstitle'])) { $fields['who']['title'] = qa_get_points_title_html($post['points'], $options['pointstitle']); } } if (isset($post['level'])) { $fields['who']['level'] = qa_html(qa_user_level_string($post['level'])); } } if (@$options['avatarsize'] > 0) { if (QA_FINAL_EXTERNAL_USERS) { $fields['avatar'] = qa_get_external_avatar_html($post['userid'], $options['avatarsize'], false); } else { $fields['avatar'] = qa_get_user_avatar_html(@$post['flags'], @$post['email'], @$post['handle'], @$post['avatarblobid'], @$post['avatarwidth'], @$post['avatarheight'], $options['avatarsize']); } } // Updated when and by whom if (@$options['updateview'] && isset($post['updated']) && ($post['updatetype'] != QA_UPDATE_SELECTED || $isselected) && (!isset($post['created']) || $post['hidden'] && $post['updatetype'] == QA_UPDATE_VISIBLE || isset($post['closedbyid']) && $post['updatetype'] == QA_UPDATE_CLOSED || abs($post['updated'] - $post['created']) > 300 || $post['lastuserid'] != $post['userid'])) { switch ($post['updatetype']) { case QA_UPDATE_TYPE: case QA_UPDATE_PARENT: $langstring = 'main/moved'; break; case QA_UPDATE_CATEGORY: $langstring = 'main/recategorized'; break; case QA_UPDATE_VISIBLE: $langstring = $post['hidden'] ? 'main/hidden' : 'main/reshown'; break; case QA_UPDATE_CLOSED: $langstring = isset($post['closedbyid']) ? 'main/closed' : 'main/reopened'; break; case QA_UPDATE_TAGS: $langstring = 'main/retagged'; break; case QA_UPDATE_SELECTED: $langstring = 'main/selected'; break; default: $langstring = 'main/edited'; break; } $fields['what_2'] = qa_lang_html($langstring); if (@$options['whenview']) { $fields['when_2'] = qa_when_to_html($post['updated'], @$options['fulldatedays']); if ($microformats) { $fields['when_2']['data'] = '<span class="updated"><span class="value-title" title="' . gmdate('Y-m-d\\TH:i:sO', $post['updated']) . '">' . $fields['when_2']['data'] . '</span></span>'; } } if (isset($post['lastuserid']) && @$options['whoview']) { $fields['who_2'] = qa_who_to_html(isset($userid) && $post['lastuserid'] == $userid, $post['lastuserid'], $usershtml, @$options['ipview'] ? $post['lastip'] : null, false); } } elseif ($microformats && @$options['whenview']) { // quick fix for incorrect microformats (missing 'updated' class) $fields['when']['data'] = str_replace('<span class="published">', '<span class="published updated">', $fields['when']['data']); } // That's it! return $fields; }
$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 } $microdata = qa_opt('use_microdata'); if ($microdata) { $qa_content['head_lines'][] = '<meta itemprop="name" content="' . qa_html($qa_content['q_view']['raw']['title']) . '">'; $qa_content['html_tags'] = ' itemscope itemtype="http://schema.org/QAPage"'; $qa_content['main_tags'] = ' itemscope itemtype="http://schema.org/Question"'; } // 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);
public function test__qa_tagstring_to_tags() { $test = qa_tagstring_to_tags('hello,world'); $expected = array('hello', 'world'); $this->assertEquals($expected, $test); }
require_once QA_INCLUDE_DIR . 'qa-db-selects.php'; require_once QA_INCLUDE_DIR . 'qa-util-string.php'; // Collect the information we need from the database $intitle = qa_post_text('title'); $doaskcheck = qa_opt('do_ask_check_qs'); $doexampletags = qa_using_tags() && qa_opt('do_example_tags'); if ($doaskcheck || $doexampletags) { $countqs = max($doexampletags ? QA_DB_RETRIEVE_ASK_TAG_QS : 0, $doaskcheck ? qa_opt('page_size_ask_check_qs') : 0); $relatedquestions = qa_db_select_with_pending(qa_db_search_posts_selectspec(null, qa_string_to_words($intitle), null, null, null, null, 0, false, $countqs)); } // Collect example tags if appropriate if ($doexampletags) { require_once QA_INCLUDE_DIR . 'qa-app-format.php'; $tagweight = array(); foreach ($relatedquestions as $question) { $tags = qa_tagstring_to_tags($question['tags']); foreach ($tags as $tag) { @($tagweight[$tag] += exp($question['score'])); } } arsort($tagweight, SORT_NUMERIC); $exampletags = array(); $minweight = exp(qa_match_to_min_score(qa_opt('match_example_tags'))); $maxcount = qa_opt('page_size_ask_tags'); foreach ($tagweight as $tag => $weight) { if ($weight < $minweight) { break; } $exampletags[] = $tag; if (count($exampletags) >= $maxcount) { break;
function qa_page_q_edit_q_submit($question, $answers, $commentsfollows, $closepost, &$in, &$errors) { $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 ($question['isbyuser']) { $in['notify'] = qa_post_text('q_notify') ? true : false; $in['email'] = qa_post_text('q_email'); } // 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(); $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 (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']; } $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']); if (qa_using_categories() && strcmp($in['categoryid'], $question['categoryid'])) { qa_question_set_category($question, $in['categoryid'], $userid, $handle, $cookieid, $answers, $commentsfollows, $closepost); } return true; } return false; }
function qa_post_index($postid, $type, $questionid, $title, $text, $tagstring, $skipcounts = false) { global $qa_post_indexing_suspended; if ($qa_post_indexing_suspended > 0) { return; } // Get words from each textual element $titlewords = array_unique(qa_string_to_words($title)); $contentcount = array_count_values(qa_string_to_words($text)); $tagwords = array_unique(qa_string_to_words($tagstring)); $wholetags = array_unique(qa_tagstring_to_tags($tagstring)); // Map all words to their word IDs $words = array_unique(array_merge($titlewords, array_keys($contentcount), $tagwords, $wholetags)); $wordtoid = qa_db_word_mapto_ids_add($words); // Add to title words index $titlewordids = qa_array_filter_by_keys($wordtoid, $titlewords); qa_db_titlewords_add_post_wordids($postid, $titlewordids); // Add to content words index (including word counts) $contentwordidcounts = array(); foreach ($contentcount as $word => $count) { if (isset($wordtoid[$word])) { $contentwordidcounts[$wordtoid[$word]] = $count; } } qa_db_contentwords_add_post_wordidcounts($postid, $type, $questionid, $contentwordidcounts); // Add to tag words index $tagwordids = qa_array_filter_by_keys($wordtoid, $tagwords); qa_db_tagwords_add_post_wordids($postid, $tagwordids); // Add to whole tags index $wholetagids = qa_array_filter_by_keys($wordtoid, $wholetags); qa_db_posttags_add_post_wordids($postid, $wholetagids); // Update counts cached in database if (!$skipcounts) { qa_db_word_titlecount_update($titlewordids); qa_db_word_contentcount_update(array_keys($contentwordidcounts)); qa_db_word_tagwordcount_update($tagwordids); qa_db_word_tagcount_update($wholetagids); qa_db_tagcount_update(); } }
function qa_post_html_fields($post, $userid, $cookieid, $usershtml, $dummy, $options = array()) { if (isset($options['blockwordspreg'])) { require_once QA_INCLUDE_DIR . 'qa-util-string.php'; } $fields = array(); $fields['raw'] = $post; // Useful stuff used throughout function $postid = $post['postid']; $isquestion = $post['basetype'] == 'Q'; $isanswer = $post['basetype'] == 'A'; $isbyuser = qa_post_is_by_user($post, $userid, $cookieid); $anchor = urlencode(qa_anchor($post['basetype'], $postid)); $microformats = @$options['microformats']; $isselected = @$options['isselected']; // High level information $fields['hidden'] = $post['hidden']; $fields['tags'] = 'ID="' . $anchor . '"'; if ($microformats) { $fields['classes'] = 'hentry ' . ($isquestion ? 'question' : ($isanswer ? $isselected ? 'answer answer-selected' : 'answer' : 'comment')); } // Question-specific stuff (title, URL, tags, answer count, category) if ($isquestion) { if (isset($post['title'])) { if (isset($options['blockwordspreg'])) { $post['title'] = qa_block_words_replace($post['title'], $options['blockwordspreg']); } $fields['title'] = qa_html($post['title']); if ($microformats) { $fields['title'] = '<SPAN CLASS="entry-title">' . $fields['title'] . '</SPAN>'; } $fields['url'] = qa_path_html(qa_q_request($postid, $post['title'])); /*if (isset($post['score'])) // useful for setting match thresholds $fields['title'].=' <SMALL>('.$post['score'].')</SMALL>';*/ } if (@$options['tagsview'] && isset($post['tags'])) { $fields['q_tags'] = array(); $tags = qa_tagstring_to_tags($post['tags']); foreach ($tags as $tag) { if (isset($options['blockwordspreg']) && count(qa_block_words_match_all($tag, $options['blockwordspreg']))) { // skip censored tags continue; } $fields['q_tags'][] = qa_tag_html($tag, $microformats); } } if (@$options['answersview'] && isset($post['acount'])) { $fields['answers_raw'] = $post['acount']; $fields['answers'] = $post['acount'] == 1 ? qa_lang_html_sub_split('main/1_answer', '1', '1') : qa_lang_html_sub_split('main/x_answers', number_format($post['acount'])); $fields['answer_selected'] = isset($post['selchildid']); } if (@$options['viewsview'] && isset($post['views'])) { $fields['views_raw'] = $post['views']; $fields['views'] = $post['views'] == 1 ? qa_lang_html_sub_split('main/1_view', '1', '1') : qa_lang_html_sub_split('main/x_views', number_format($post['views'])); } if (isset($post['categoryname']) && isset($post['categorybackpath'])) { $fields['where'] = qa_lang_html_sub_split('main/in_category_x', '<A HREF="' . qa_path_html(@$options['categorypathprefix'] . implode('/', array_reverse(explode('/', $post['categorybackpath'])))) . '" CLASS="qa-category-link">' . qa_html($post['categoryname']) . '</A>'); } } // Answer-specific stuff (selection) if ($isanswer) { $fields['selected'] = $isselected; if ($isselected) { $fields['select_text'] = qa_lang_html('question/select_text'); } } // Post content if (!empty($post['content'])) { $viewer = qa_load_viewer($post['content'], $post['format']); $fields['content'] = $viewer->get_html($post['content'], $post['format'], array('blockwordspreg' => @$options['blockwordspreg'], 'showurllinks' => @$options['showurllinks'], 'linksnewwindow' => @$options['linksnewwindow'])); if ($microformats) { $fields['content'] = '<SPAN CLASS="entry-content">' . $fields['content'] . '</SPAN>'; } $fields['content'] = '<A NAME="' . qa_html($postid) . '"></A>' . $fields['content']; // this is for backwards compatibility with any existing links using the old style of anchor // that contained the post id only (changed to be valid under W3C specifications) } // Voting stuff if (@$options['voteview']) { $voteview = $options['voteview']; // Calculate raw values and pass through $upvotes = (int) @$post['upvotes']; $downvotes = (int) @$post['downvotes']; $netvotes = (int) ($upvotes - $downvotes); $fields['upvotes_raw'] = $upvotes; $fields['downvotes_raw'] = $downvotes; $fields['netvotes_raw'] = $netvotes; // Create HTML versions... $upvoteshtml = qa_html($upvotes); $downvoteshtml = qa_html($downvotes); if ($netvotes >= 1) { $netvoteshtml = '+' . qa_html($netvotes); } elseif ($netvotes <= -1) { $netvoteshtml = '–' . qa_html(-$netvotes); } else { $netvoteshtml = '0'; } // ...with microformats if appropriate if ($microformats) { $netvoteshtml .= '<SPAN CLASS="votes-up"><SPAN CLASS="value-title" TITLE="' . $upvoteshtml . '"></SPAN></SPAN>' . '<SPAN CLASS="votes-down"><SPAN CLASS="value-title" TITLE="' . $downvoteshtml . '"></SPAN></SPAN>'; $upvoteshtml = '<SPAN CLASS="votes-up">' . $upvoteshtml . '</SPAN>'; $downvoteshtml = '<SPAN CLASS="votes-down">' . $downvoteshtml . '</SPAN>'; } // Pass information on vote viewing // $voteview will be one of: updown, net, updown-disabled-level, net-disabled-level, updown-disabled-page, net-disabled-page $fields['vote_view'] = substr($voteview, 0, 6) == 'updown' ? 'updown' : 'net'; $fields['upvotes_view'] = $upvotes == 1 ? qa_lang_html_sub_split('main/1_liked', $upvoteshtml, '1') : qa_lang_html_sub_split('main/x_liked', $upvoteshtml); $fields['downvotes_view'] = $downvotes == 1 ? qa_lang_html_sub_split('main/1_disliked', $downvoteshtml, '1') : qa_lang_html_sub_split('main/x_disliked', $downvoteshtml); $fields['netvotes_view'] = abs($netvotes) == 1 ? qa_lang_html_sub_split('main/1_vote', $netvoteshtml, '1') : qa_lang_html_sub_split('main/x_votes', $netvoteshtml); // Voting buttons $fields['vote_tags'] = 'ID="voting_' . qa_html($postid) . '"'; $onclick = 'onClick="return qa_vote_click(this);"'; if ($fields['hidden']) { $fields['vote_state'] = 'disabled'; $fields['vote_up_tags'] = 'TITLE="' . qa_lang_html($isanswer ? 'main/vote_disabled_hidden_a' : 'main/vote_disabled_hidden_q') . '"'; $fields['vote_down_tags'] = $fields['vote_up_tags']; } elseif ($isbyuser) { $fields['vote_state'] = 'disabled'; $fields['vote_up_tags'] = 'TITLE="' . qa_lang_html($isanswer ? 'main/vote_disabled_my_a' : 'main/vote_disabled_my_q') . '"'; $fields['vote_down_tags'] = $fields['vote_up_tags']; } elseif (strpos($voteview, '-disabled-')) { $fields['vote_state'] = @$post['uservote'] > 0 ? 'voted_up_disabled' : (@$post['uservote'] < 0 ? 'voted_down_disabled' : 'disabled'); if (strpos($voteview, '-disabled-page')) { $fields['vote_up_tags'] = 'TITLE="' . qa_lang_html('main/vote_disabled_q_page_only') . '"'; } else { $fields['vote_up_tags'] = 'TITLE="' . qa_lang_html('main/vote_disabled_level') . '"'; } $fields['vote_down_tags'] = $fields['vote_up_tags']; } elseif (@$post['uservote'] > 0) { $fields['vote_state'] = 'voted_up'; $fields['vote_up_tags'] = 'TITLE="' . qa_lang_html('main/voted_up_popup') . '" NAME="' . qa_html('vote_' . $postid . '_0_' . $anchor) . '"' . $onclick; $fields['vote_down_tags'] = ' '; } elseif (@$post['uservote'] < 0) { $fields['vote_state'] = 'voted_down'; $fields['vote_up_tags'] = ' '; $fields['vote_down_tags'] = 'TITLE="' . qa_lang_html('main/voted_down_popup') . '" NAME="' . qa_html('vote_' . $postid . '_0_' . $anchor) . '" ' . $onclick; } else { $fields['vote_state'] = 'enabled'; $fields['vote_up_tags'] = 'TITLE="' . qa_lang_html('main/vote_up_popup') . '" NAME="' . qa_html('vote_' . $postid . '_1_' . $anchor) . '" ' . $onclick; $fields['vote_down_tags'] = 'TITLE="' . qa_lang_html('main/vote_down_popup') . '" NAME="' . qa_html('vote_' . $postid . '_-1_' . $anchor) . '" ' . $onclick; } } // Flag count if (@$options['flagsview'] && @$post['flagcount']) { $fields['flags'] = $post['flagcount'] == 1 ? qa_lang_html_sub_split('main/1_flag', '1', '1') : qa_lang_html_sub_split('main/x_flags', $post['flagcount']); } // Created when and by whom $fields['meta_order'] = qa_lang_html('main/meta_order'); // sets ordering of meta elements which can be language-specific $fields['what'] = qa_lang_html($isquestion ? 'main/asked' : ($isanswer ? 'main/answered' : 'main/commented')); if (@$options['whatlink'] && !$isquestion) { $fields['what_url'] = '#' . qa_html(urlencode($anchor)); } if (isset($post['created']) && @$options['whenview']) { $whenhtml = qa_html(qa_time_to_string(qa_opt('db_time') - $post['created'])); if ($microformats) { $whenhtml = '<SPAN CLASS="published"><SPAN CLASS="value-title" TITLE="' . gmdate('Y-m-d\\TH:i:sO', $post['created']) . '"></SPAN>' . $whenhtml . '</SPAN>'; } $fields['when'] = qa_lang_html_sub_split('main/x_ago', $whenhtml); } if (@$options['whoview']) { $fields['who'] = qa_who_to_html($isbyuser, @$post['userid'], $usershtml, @$options['ipview'] ? @$post['createip'] : null, $microformats); if (isset($post['points'])) { if (@$options['pointsview']) { $fields['who']['points'] = $post['points'] == 1 ? qa_lang_html_sub_split('main/1_point', '1', '1') : qa_lang_html_sub_split('main/x_points', qa_html(number_format($post['points']))); } if (isset($options['pointstitle'])) { $fields['who']['title'] = qa_get_points_title_html($post['points'], $options['pointstitle']); } } if (isset($post['level'])) { $fields['who']['level'] = qa_html(qa_user_level_string($post['level'])); } } if (!QA_FINAL_EXTERNAL_USERS && @$options['avatarsize'] > 0) { $fields['avatar'] = qa_get_user_avatar_html($post['flags'], $post['email'], $post['handle'], $post['avatarblobid'], $post['avatarwidth'], $post['avatarheight'], $options['avatarsize']); } // Updated when and by whom if (isset($post['updated']) && (!isset($post['created']) || $post['hidden'] || abs($post['updated'] - $post['created']) > 300 || $post['lastuserid'] != $post['userid'])) { if (@$options['whenview']) { $whenhtml = qa_html(qa_time_to_string(qa_opt('db_time') - $post['updated'])); if ($microformats) { $whenhtml = '<SPAN CLASS="updated"><SPAN CLASS="value-title" TITLE="' . gmdate('Y-m-d\\TH:i:sO', $post['updated']) . '"></SPAN>' . $whenhtml . '</SPAN>'; } $fields['when_2'] = qa_lang_html_sub_split($fields['hidden'] ? 'question/hidden_x_ago' : 'question/edited_x_ago', $whenhtml); } else { $fields['when_2']['prefix'] = qa_lang_html($fields['hidden'] ? 'question/hidden' : 'main/edited'); } if ($fields['hidden'] && $post['flagcount'] && !isset($post['lastuserid'])) { } else { $fields['who_2'] = qa_who_to_html(isset($userid) && $post['lastuserid'] == $userid, $post['lastuserid'], $usershtml, @$options['ipview'] ? $post['lastip'] : null, false); } } // That's it! return $fields; }
function qa_page_q_edit_q_form() { global $qa_content, $question, $inqtitle, $inqcontent, $inqformat, $inqeditor, $inqtags, $qerrors, $innotify, $inemail, $completetags, $categories; $content = isset($inqcontent) ? $inqcontent : $question['content']; $format = isset($inqformat) ? $inqformat : $question['format']; $editorname = isset($inqeditor) ? $inqeditor : qa_opt('editor_for_qs'); $editor = qa_load_editor($content, $format, $editorname); $form = array('style' => 'tall', 'fields' => array('title' => array('label' => qa_lang_html('question/q_title_label'), 'tags' => 'NAME="qtitle"', 'value' => qa_html(isset($inqtitle) ? $inqtitle : $question['title']), 'error' => qa_html(@$qerrors['title'])), 'category' => array('label' => qa_lang_html('question/q_category_label')), 'content' => array_merge($editor->get_field($qa_content, $content, $format, 'qcontent', 12, true), array('label' => qa_lang_html('question/q_content_label'), 'error' => qa_html(@$qerrors['content']))), 'tags' => array('error' => qa_html(@$qerrors['tags']))), 'buttons' => array('save' => array('label' => qa_lang_html('main/save_button')), 'cancel' => array('tags' => 'NAME="docancel"', 'label' => qa_lang_html('main/cancel_button'))), 'hidden' => array('editor' => qa_html($editorname), 'dosaveq' => '1')); if (qa_using_categories() && count($categories)) { qa_set_up_category_field($qa_content, $form['fields']['category'], 'category', $categories, isset($incategoryid) ? $incategoryid : $question['categoryid'], qa_opt('allow_no_category') || !isset($question['categoryid']), qa_opt('allow_no_sub_category')); } else { unset($form['fields']['category']); } if (qa_using_tags()) { qa_set_up_tag_field($qa_content, $form['fields']['tags'], 'qtags', isset($inqtags) ? $inqtags : qa_tagstring_to_tags($question['tags']), array(), $completetags, qa_opt('page_size_ask_tags')); } else { unset($form['fields']['tags']); } if ($question['isbyuser']) { qa_set_up_notify_fields($qa_content, $form['fields'], 'Q', qa_get_logged_in_email(), isset($innotify) ? $innotify : !empty($question['notify']), isset($inemail) ? $inemail : @$question['notify'], @$qerrors['email']); } return $form; }