diff --git a/qa-include/Q2A/Plugin/PluginManager.php b/qa-include/Q2A/Plugin/PluginManager.php index 3230682cc..64679ae85 100644 --- a/qa-include/Q2A/Plugin/PluginManager.php +++ b/qa-include/Q2A/Plugin/PluginManager.php @@ -26,8 +26,8 @@ class Q2A_Plugin_PluginManager const PLUGIN_DELIMITER = ';'; const OPT_ENABLED_PLUGINS = 'enabled_plugins'; - private $loadBeforeDbInit = array(); - private $loadAfterDbInit = array(); + private $loadBeforeDbInit = array(); //New structure: [dependency_level => [pluginKey => pluginInfo]] + private $loadAfterDbInit = array(); //New structure: [dependency_level => [pluginKey => pluginInfo]] public function readAllPluginMetadatas() { @@ -49,13 +49,20 @@ public function readAllPluginMetadatas() } // skip plugin which requires a later version of Q2A - if (qa_qa_version_below($metadata['min_q2a'] ?? '')) { + if (qa_qa_version_below(isset($metadata['min_q2a']) ? $metadata['min_q2a'] : '')) { continue; } // skip plugin which requires a later version of PHP - if (qa_php_version_below($metadata['min_php'] ?? '')) { + if (qa_php_version_below(isset($metadata['min_php']) ? $metadata['min_php'] : '')) { continue; } + + //Dependency level of the plugin useful while loading it. Lower the dependency number, loads earlier. + $dependencyLevel = 1; + if (isset($metadata['dependency_level']) && ctype_digit((string)$metadata['dependency_level'])) { + $dependencyLevel = (int)$metadata['dependency_level']; + } + $pluginInfoKey = basename($pluginDirectory); $pluginInfo = array( @@ -67,19 +74,22 @@ public function readAllPluginMetadatas() if (isset($metadata['load_order'])) { switch ($metadata['load_order']) { case 'after_db_init': - $this->loadAfterDbInit[$pluginInfoKey] = $pluginInfo; + //$this->loadAfterDbInit[$pluginInfoKey] = $pluginInfo; + $this->loadAfterDbInit[$dependencyLevel][$pluginInfoKey] = $pluginInfo; break; case 'before_db_init': - $this->loadBeforeDbInit[$pluginInfoKey] = $pluginInfo; + //$this->loadBeforeDbInit[$pluginInfoKey] = $pluginInfo; + $this->loadBeforeDbInit[$dependencyLevel][$pluginInfoKey] = $pluginInfo; break; default: } } else { - $this->loadBeforeDbInit[$pluginInfoKey] = $pluginInfo; + $this->loadBeforeDbInit[$dependencyLevel][$pluginInfoKey] = $pluginInfo; } } } + //This function is not useful anymore private function loadPlugins($pluginInfos) { global $qa_plugin_directory, $qa_plugin_urltoroot; @@ -94,15 +104,55 @@ private function loadPlugins($pluginInfos) $qa_plugin_directory = null; $qa_plugin_urltoroot = null; } + + //New function to load plugins + private function loadPluginsByDependency(array $groupedPlugins) + { + global $qa_plugin_directory, $qa_plugin_urltoroot; + + if (empty($groupedPlugins)) { + return; + } + + ksort($groupedPlugins, SORT_NUMERIC); + + foreach ($groupedPlugins as $level => $pluginsAtLevel) { + + //SAFETY: level may accidentally contain flat array + if (!is_array($pluginsAtLevel)) { + continue; + } + + foreach ($pluginsAtLevel as $pluginKey => $pluginInfo) { + + //SAFETY: pluginInfo must be an array + if (!is_array($pluginInfo) || !isset($pluginInfo['pluginfile'])) { + continue; + } + + $qa_plugin_directory = $pluginInfo['directory']; + $qa_plugin_urltoroot = $pluginInfo['urltoroot']; + + require_once $pluginInfo['pluginfile']; + } + } + + $qa_plugin_directory = null; + $qa_plugin_urltoroot = null; + } + + public function loadPluginsBeforeDbInit() { - $this->loadPlugins($this->loadBeforeDbInit); + //$this->loadPlugins($this->loadBeforeDbInit); + $this->loadPluginsByDependency($this->loadBeforeDbInit); } public function loadPluginsAfterDbInit() { $enabledPlugins = $this->getEnabledPlugins(false); + /* Old way $enabledForAfterDbInit = array(); foreach ($enabledPlugins as $enabledPluginDirectory) { @@ -112,6 +162,17 @@ public function loadPluginsAfterDbInit() } $this->loadPlugins($enabledForAfterDbInit); + */ + + $enabledGrouped = array(); + foreach ($this->loadAfterDbInit as $level => $pluginsAtLevel) { + foreach ($pluginsAtLevel as $pluginKey => $pluginInfo) { + if (in_array($pluginKey, $enabledPlugins, true)) { + $enabledGrouped[$level][$pluginKey] = $pluginInfo; + } + } + } + $this->loadPluginsByDependency($enabledGrouped); } public function getEnabledPlugins($fullPath = false) diff --git a/qa-include/app/format.php b/qa-include/app/format.php index bf4450305..c6ff5419b 100644 --- a/qa-include/app/format.php +++ b/qa-include/app/format.php @@ -1518,6 +1518,11 @@ function qa_user_sub_navigation($handle, $selected, $ismyuser = false) 'label' => qa_lang_html('misc/nav_user_as'), 'url' => qa_path_html('user/' . $handle . '/answers'), ), + + 'comments' => array( + 'label' => qa_lang_html('misc/nav_user_cs'), + 'url' => qa_path_html('user/' . $handle . '/comments'), + ), ); if (isset($navigation[$selected])) diff --git a/qa-include/db/selects.php b/qa-include/db/selects.php index 1a093ad7a..a64f853eb 100644 --- a/qa-include/db/selects.php +++ b/qa-include/db/selects.php @@ -1321,6 +1321,12 @@ function qa_db_user_recent_c_qs_selectspec($voteuserid, $identifier, $count = nu qa_db_add_selectspec_opost($selectspec, 'cposts'); + $selectspec['columns']['oupvotes'] = 'cposts.upvotes'; + $selectspec['columns']['odownvotes'] = 'cposts.downvotes'; + $selectspec['columns']['onetvotes'] = 'cposts.netvotes'; + + + $selectspec['source'] .= " JOIN ^posts AS parentposts ON" . " ^posts.postid=(CASE parentposts.type WHEN 'A' THEN parentposts.parentid ELSE parentposts.postid END)" . diff --git a/qa-include/lang/qa-lang-misc.php b/qa-include/lang/qa-lang-misc.php index 5dc13c623..f01384a35 100644 --- a/qa-include/lang/qa-lang-misc.php +++ b/qa-include/lang/qa-lang-misc.php @@ -72,6 +72,7 @@ 'nav_my_favorites' => 'My favorites', 'nav_user_activity' => 'Recent activity', 'nav_user_as' => 'All answers', + 'nav_user_cs' => 'All comments', 'nav_user_pms' => 'Private messages', 'nav_user_qs' => 'All questions', 'nav_user_wall' => 'Wall', diff --git a/qa-include/lang/qa-lang-profile.php b/qa-include/lang/qa-lang-profile.php index 3c2a027b1..0420d1cf6 100644 --- a/qa-include/lang/qa-lang-profile.php +++ b/qa-include/lang/qa-lang-profile.php @@ -29,12 +29,14 @@ 'answers_by_x' => 'Answers by ^', 'bonus_points' => 'Bonus points:', 'comments' => 'Comments:', + 'comments_by_x' => 'Comments by ^', 'delete_pm_popup' => 'Delete this private message', 'delete_wall_post_popup' => 'Delete this wall post', 'extra_privileges' => 'Extra privileges:', 'gave_out' => 'Gave out:', 'my_account_title' => 'My account', 'no_answers_by_x' => 'No answers by ^', + 'no_comments_by_x' => 'No comments by ^', 'no_posts_by_x' => 'No posts by ^', 'no_questions_by_x' => 'No questions by ^', 'permit_anon_view_ips' => 'Viewing IPs of anonymous posts', diff --git a/qa-include/pages/admin/admin-flagged.php b/qa-include/pages/admin/admin-flagged.php index c448ccc65..dca6f2373 100644 --- a/qa-include/pages/admin/admin-flagged.php +++ b/qa-include/pages/admin/admin-flagged.php @@ -32,9 +32,11 @@ // Find most flagged questions, answers, comments $userid = qa_get_logged_in_userid(); +$start = qa_get_start(); +$pageSize = (int)qa_opt('page_size_qs'); $questions = qa_db_select_with_pending( - qa_db_flagged_post_qs_selectspec($userid, 0, true) + qa_db_flagged_post_qs_selectspec($userid, $start, true, $pageSize) ); @@ -125,6 +127,21 @@ $qa_content['q_list']['qs'][] = $htmlfields; } + // Manual count query + $totalflaged = qa_opt('cache_flaggedcount'); // Fetching total flagged value from cache; may be used for better performance + //$totalflaged = qa_db_read_one_value(qa_db_query_sub("SELECT COUNT(*) FROM qa_posts WHERE flagcount > 0"),true); // Fetching total flagged value from the db through a complete run + + // Add page links + $qa_content['page_links'] = qa_html_page_links( + qa_request(), // Current request + $start, // Current start offset + $pageSize, // how many posts per page + $totalflaged, // Total number of items + 2, // number of page links before and after current + array(), // Extra query params + '' // Anchor + ); + } else $qa_content['title'] = qa_lang_html('admin/no_flagged_found'); diff --git a/qa-include/pages/admin/admin-moderate.php b/qa-include/pages/admin/admin-moderate.php index 69fb8ae47..9a2dad76b 100644 --- a/qa-include/pages/admin/admin-moderate.php +++ b/qa-include/pages/admin/admin-moderate.php @@ -32,11 +32,15 @@ // Find queued questions, answers, comments $userid = qa_get_logged_in_userid(); +$start = qa_get_start(); +$pageSize = (int)qa_opt('page_size_qs'); + + list($queuedquestions, $queuedanswers, $queuedcomments) = qa_db_select_with_pending( - qa_db_qs_selectspec($userid, 'created', 0, null, null, 'Q_QUEUED', true), - qa_db_recent_a_qs_selectspec($userid, 0, null, null, 'A_QUEUED', true), - qa_db_recent_c_qs_selectspec($userid, 0, null, null, 'C_QUEUED', true) + qa_db_qs_selectspec($userid, 'created', $start, null, null, 'Q_QUEUED', true, $pageSize), + qa_db_recent_a_qs_selectspec($userid, $start, null, null, 'A_QUEUED', true, $pageSize), + qa_db_recent_c_qs_selectspec($userid, $start, null, null, 'C_QUEUED', true, $pageSize) ); @@ -54,7 +58,7 @@ $pageerror = qa_admin_check_clicks(); -// Combine sets of questions and remove those this user has no permission to moderate +// Combine sets of questions and remove those this user has no permission to moderate. Please note that we are not slicing the posts to $pageSize. So, we may have maximum of 3*$pageSize posts per page. $questions = qa_any_sort_by_date(array_merge($queuedquestions, $queuedanswers, $queuedcomments)); @@ -148,6 +152,41 @@ $qa_content['q_list']['qs'][] = $htmlfields; } + + // Manual count query - the following two methods will not work if we have 35 questions, 15 answer and 19 comments are there for moderation + //$totalQueued = qa_opt('cache_queuedcount'); + //$totalQueued = qa_db_read_one_value(qa_db_query_sub("SELECT COUNT(*) FROM ^posts WHERE type IN ('Q_QUEUED', 'A_QUEUED', 'C_QUEUED')"),true); + + // The workable solution is + $countQ = qa_db_read_one_value( + qa_db_query_sub("SELECT COUNT(*) FROM ^posts WHERE type = 'Q_QUEUED'"), + true + ); + $countA = qa_db_read_one_value( + qa_db_query_sub("SELECT COUNT(*) FROM ^posts WHERE type = 'A_QUEUED'"), + true + ); + $countC = qa_db_read_one_value( + qa_db_query_sub("SELECT COUNT(*) FROM ^posts WHERE type = 'C_QUEUED'"), + true + ); + + // the page list should be driven by the largest queue + $Max_posts = max($countQ, $countA, $countC); + + + + // Add page links + $qa_content['page_links'] = qa_html_page_links( + qa_request(), // Current request + $start, // Current start offset + $pageSize, // It doesn't exactly reflect the no.of posts per page. It is used to calculate the number of page links. + $Max_posts, // Maximum posts of one type + 2, // number of page links before and after current + array(), // Extra query params + '' // Anchor + ); + } else $qa_content['title'] = qa_lang_html('admin/no_approve_found'); diff --git a/qa-include/pages/user-comments.php b/qa-include/pages/user-comments.php new file mode 100644 index 000000000..b7c4d18f3 --- /dev/null +++ b/qa-include/pages/user-comments.php @@ -0,0 +1,104 @@ + '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('C', 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($questions), 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, 'comments', $ismyuser); + + +return $qa_content; diff --git a/qa-include/pages/user.php b/qa-include/pages/user.php index 53601f8db..57c51d070 100644 --- a/qa-include/pages/user.php +++ b/qa-include/pages/user.php @@ -71,6 +71,10 @@ qa_set_template('user-answers'); $qa_content = include QA_INCLUDE_DIR . 'pages/user-answers.php'; break; + case 'comments': + qa_set_template('user-comments'); + $qa_content = include QA_INCLUDE_DIR . 'pages/user-comments.php'; + break; case null: $qa_content = include QA_INCLUDE_DIR . 'pages/user-profile.php';