Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
77 changes: 69 additions & 8 deletions qa-include/Q2A/Plugin/PluginManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -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()
{
Expand All @@ -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(
Expand All @@ -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;
Expand All @@ -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) {
Expand All @@ -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)
Expand Down
5 changes: 5 additions & 0 deletions qa-include/app/format.php
Original file line number Diff line number Diff line change
Expand Up @@ -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]))
Expand Down
6 changes: 6 additions & 0 deletions qa-include/db/selects.php
Original file line number Diff line number Diff line change
Expand Up @@ -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)" .
Expand Down
1 change: 1 addition & 0 deletions qa-include/lang/qa-lang-misc.php
Original file line number Diff line number Diff line change
Expand Up @@ -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',
Expand Down
2 changes: 2 additions & 0 deletions qa-include/lang/qa-lang-profile.php
Original file line number Diff line number Diff line change
Expand Up @@ -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',
Expand Down
19 changes: 18 additions & 1 deletion qa-include/pages/admin/admin-flagged.php
Original file line number Diff line number Diff line change
Expand Up @@ -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)
);


Expand Down Expand Up @@ -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');
Expand Down
47 changes: 43 additions & 4 deletions qa-include/pages/admin/admin-moderate.php
Original file line number Diff line number Diff line change
Expand Up @@ -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)
);


Expand All @@ -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));

Expand Down Expand Up @@ -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');

Expand Down
104 changes: 104 additions & 0 deletions qa-include/pages/user-comments.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
<?php
/*
Question2Answer by Gideon Greenspan and contributors
http://www.question2answer.org/

Description: Controller for user page showing all user's answers


This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.

More about this license: http://www.question2answer.org/license.php
*/

if (!defined('QA_VERSION')) { // don't allow this page to be requested directly from browser
header('Location: ../../');
exit;
}

require_once QA_INCLUDE_DIR . 'db/selects.php';
require_once QA_INCLUDE_DIR . 'app/format.php';


// $handle, $userhtml are already set by /qa-include/page/user.php - also $userid if using external user integration

$start = qa_get_start();


// Find the questions for this user

$loginuserid = qa_get_logged_in_userid();
$identifier = QA_FINAL_EXTERNAL_USERS ? $userid : $handle;

list($useraccount, $userpoints, $questions) = qa_db_select_with_pending(
QA_FINAL_EXTERNAL_USERS ? null : qa_db_user_account_selectspec($handle, false),
qa_db_user_points_selectspec($identifier),
qa_db_user_recent_c_qs_selectspec($loginuserid, $identifier, qa_opt_if_loaded('page_size_activity'), $start)
);

if (!QA_FINAL_EXTERNAL_USERS && !is_array($useraccount)) // check the user exists
return include QA_INCLUDE_DIR . 'qa-page-not-found.php';


// Get information on user questions

$pagesize = qa_opt('page_size_activity');
$count = (int)@$userpoints['cposts'];
$questions = array_slice($questions, 0, $pagesize);
$usershtml = qa_userids_handles_html($questions, false);


// Prepare content for theme

$qa_content = qa_content_prepare(true);

if (count($questions))
$qa_content['title'] = qa_lang_html_sub('profile/comments_by_x', $userhtml);
else
$qa_content['title'] = qa_lang_html_sub('profile/no_comments_by_x', $userhtml);


// Recent questions by this user

$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();

$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;
Loading