Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add the point module type #486

Open
wants to merge 1 commit into
base: dev
Choose a base branch
from
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
20 changes: 20 additions & 0 deletions qa-include/Q2A/Plugin/AbstractPointModule.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<?php

svivian marked this conversation as resolved.
Show resolved Hide resolved
abstract class Q2A_Plugin_AbstractPointModule implements Q2A_Plugin_IPointModule
{
/**
* Return the amount of points that the module expects to change for the given user id. This default implementation
* just calls the getPointsForUsers() function wrapping the given user id as the only user in the array. It can be
* overridden in subclasses
*
* @param int|string $userId The user id
*
* @return int The number of points that the module should change for the given user
*/
public function getPointsForUser($userId)
{
$userIdPoints = $this->getPointsForUsers(array($userId));

return reset($userIdPoints);
}
}
22 changes: 22 additions & 0 deletions qa-include/Q2A/Plugin/IPointModule.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<?php

interface Q2A_Plugin_IPointModule
{
/**
* Return the amount of points that the module expects to change for the given user id
*
* @param int|string $userId The user id
*
* @return int The number of points that the module should change for the given user
*/
public function getPointsForUser($userId);

/**
* Return the amount of points that the module expects to change for the given array of user ids
*
* @param array $userIds The array of user ids
*
* @return array The array containing as keys the user ids and as values the amount of points to change
*/
public function getPointsForUsers($userIds);
}
24 changes: 23 additions & 1 deletion qa-include/app/recalc.php
Original file line number Diff line number Diff line change
Expand Up @@ -246,7 +246,29 @@ function qa_recalc_perform_step(&$state)

if ($recalccount > 0) {
$lastuserid = $userids[$recalccount - 1];
qa_db_users_recalc_points($next, $lastuserid);

// Get points from all registered point modules

$userIdPointsMap = array();

$modules = qa_load_modules_for_type('point');
if (!empty($modules)) {
$processUserIds = array_slice($userids, 0, $recalccount);

foreach ($modules as $module) {
$currentPluginUserIdPointsMap = $module->getPointsForUsers($processUserIds);
foreach ($currentPluginUserIdPointsMap as $userId => $points) {
if (!isset($userIdPointsMap[$userId])) {
$userIdPointsMap[$userId] = 0;
}

$userIdPointsMap[$userId] += $points;
}
}
}

qa_db_users_recalc_points($next, $lastuserid, $userIdPointsMap);

$done += $recalccount;

} else {
Expand Down
11 changes: 9 additions & 2 deletions qa-include/db/points.php
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ function qa_db_points_calculations()
* @param $columns
* @return mixed
*/
function qa_db_points_update_ifuser($userid, $columns)
function qa_db_points_update_ifuser($userid, $columns = null)
{
if (qa_to_override(__FUNCTION__)) { $args=func_get_args(); return qa_call_override(__FUNCTION__, $args); }

Expand Down Expand Up @@ -202,8 +202,15 @@ function qa_db_points_update_ifuser($userid, $columns)
$updatepoints .= '+(' . $multiple . '*' . (isset($keycolumns[$field]) ? '@_' : '') . $field . ')';
}

$pluginPoints = 0;

$modules = qa_load_modules_for_type('point');
foreach ($modules as $module) {
$pluginPoints += $module->getPointsForUser($userid);
}

$query = 'INSERT INTO ^userpoints (' . $insertfields . 'points) VALUES (' . $insertvalues . $insertpoints . ') ' .
'ON DUPLICATE KEY UPDATE ' . $updates . 'points=' . $updatepoints . '+bonus';
'ON DUPLICATE KEY UPDATE ' . $updates . 'points=' . $updatepoints . '+ bonus + ' . ((string) $pluginPoints);

// build like this so that a #, $ or ^ character in the $userid (if external integration) isn't substituted
qa_db_query_raw(str_replace('~', "='" . qa_db_escape_string($userid) . "'", qa_db_apply_sub($query, array($userid))));
Expand Down
34 changes: 31 additions & 3 deletions qa-include/db/recalc.php
Original file line number Diff line number Diff line change
Expand Up @@ -266,11 +266,13 @@ function qa_db_users_get_for_recalc_points($startuserid, $count)


/**
* Recalculate all userpoints columns for users $firstuserid to $lastuserid in the database
* Recalculate all userpoints columns for users $firstuserid to $lastuserid in the database. Send a user id to point map containing
* the result of applying all plugins point recalculations
* @param $firstuserid
* @param $lastuserid
* @param $userIdPointsMap
*/
function qa_db_users_recalc_points($firstuserid, $lastuserid)
function qa_db_users_recalc_points($firstuserid, $lastuserid, $userIdPointsMap)
{
require_once QA_INCLUDE_DIR . 'db/points.php';

Expand Down Expand Up @@ -315,8 +317,34 @@ function qa_db_users_recalc_points($firstuserid, $lastuserid)
$updatepoints .= '+(' . ((int)$calculation['multiple']) . '*' . $field . ')';
}

$pluginLeftJoin = '';
$pluginExtraPoints = '';

if (!empty($userIdPointsMap)) {
// Start the left join

$pluginLeftJoin = 'LEFT JOIN (';

// Build the derived table

reset($userIdPointsMap);
$userId = key($userIdPointsMap);
$pluginLeftJoin .= sprintf('SELECT %s userid, %d points ', $userId, $userIdPointsMap[$userId]);
unset($userIdPointsMap[$userId]);

foreach ($userIdPointsMap as $userId => $points) {
$pluginLeftJoin .= sprintf('UNION SELECT %s, %d ', $userId, $userIdPointsMap[$userId]);
}

// Finish the left join

$pluginLeftJoin .= ') plugin_points ON up.userid = plugin_points.userid ';

$pluginExtraPoints = '+ COALESCE(plugin_points.points, 0) ';
}

qa_db_query_sub(
'UPDATE ^userpoints SET points=' . $updatepoints . '+bonus WHERE userid>=# AND userid<=#',
'UPDATE ^userpoints up ' . $pluginLeftJoin . 'SET up.points=' . $updatepoints . '+ bonus ' . $pluginExtraPoints . 'WHERE up.userid >= # AND up.userid <= #',
$firstuserid, $lastuserid
);
}
Expand Down
25 changes: 23 additions & 2 deletions qa-include/qa-base.php
Original file line number Diff line number Diff line change
Expand Up @@ -942,7 +942,7 @@ function qa_load_module($type, $name)
}

/**
* Return an array of instantiated clases for modules which have defined $method
* Return an array of instantiated classes for modules which have defined $method
* (all modules are loaded but not included in the returned array)
* @param $method
* @return array
Expand All @@ -966,7 +966,28 @@ function qa_load_all_modules_with($method)
}

/**
* Return an array of instantiated clases for modules of $type which have defined $method
* Return an array of instantiated classes for modules of type $type
* @param $type
* @return array
*/
function qa_load_modules_for_type($type)
{
$modules = array();

$trynames = qa_list_modules($type);

foreach ($trynames as $tryname) {
$module = qa_load_module($type, $tryname);
if (isset($module)) {
$modules[$tryname] = $module;
}
}

return $modules;
}

/**
* Return an array of instantiated classes for modules of $type which have defined $method
* (other modules of that type are also loaded but not included in the returned array)
* @param $type
* @param $method
Expand Down