From: Chuck Scott Date: Tue, 18 Oct 2016 21:03:54 +0000 (-0400) Subject: Added pseudo-random sort order to member list results. Still need to consider impleme... X-Git-Tag: v2.8.0^2~9^2~1 X-Git-Url: http://cvs2.gaslightmedia.com/gitweb/?a=commitdiff_plain;h=4d74fb86cda7561b4489c963a1cf5b951749222e;p=WP-Plugins%2Fglm-member-db.git Added pseudo-random sort order to member list results. Still need to consider implementing paging. --- diff --git a/lib/GlmDataAbstract/DataAbstract.php b/lib/GlmDataAbstract/DataAbstract.php index 3cbb754b..cc4ca085 100755 --- a/lib/GlmDataAbstract/DataAbstract.php +++ b/lib/GlmDataAbstract/DataAbstract.php @@ -129,28 +129,37 @@ abstract class GlmDataAbstract */ public $fieldPrefix = ''; /** - * Field processing for various field types + * Pseudo-Random Order Key Array - Used for Pseudo-Random database result lists * - * @var $f is field data + * @access private + */ + public $pseudoRandArray = false; + /** + * Pseudo-Random Order flag * - * @return void - * @access public + * @access private + */ + public $pseudoRand = false; + + + /* + * Field processing for various types of fields */ // Integer Field Processing - function integerField($f) + private function integerField($f) { return 'T.'.$f['field']; } - function integerOptions($f) + private function integerOptions($f) { return false; } - function integerOutput($f, $d) + private function integerOutput($f, $d) { return $d; } - function integerInput($as, $f, $id, $idfield, $op) + private function integerInput($as, $f, $id, $idfield, $op) { // If this is setup for a new entry, then just return default value if ($op == 'n') { @@ -227,7 +236,7 @@ abstract class GlmDataAbstract return $in; } - function integerStore($in, $f) + private function integerStore($in, $f) { return $in; } @@ -235,15 +244,15 @@ abstract class GlmDataAbstract /* * Float Field Processing */ - function floatField($f) + private function floatField($f) { return 'T.'.$f['field']; } - function floatOptions($f) + private function floatOptions($f) { return false; } - function floatOutput($f, $d) + private function floatOutput($f, $d) { // if a format is specified if (isset($f['output_format']) && $f['output_format']) { @@ -252,7 +261,7 @@ abstract class GlmDataAbstract return $d; } - function floatInput($as, $f, $id, $idfield, $op) + private function floatInput($as, $f, $id, $idfield, $op) { // If this is setup for a new entry, then just return default value if ($op == 'n') { @@ -336,7 +345,7 @@ abstract class GlmDataAbstract return $in; } - function floatStore($in, $f) + private function floatStore($in, $f) { return $in; } @@ -344,20 +353,20 @@ abstract class GlmDataAbstract /* * Money Field Processing */ - function moneyField($f) + private function moneyField($f) { return 'T.'.$f['field']; } - function moneyOptions($f) + private function moneyOptions($f) { return false; } - function moneyOutput($f, $d) + private function moneyOutput($f, $d) { return "$".sprintf("%01.2f", $d); ; } - function moneyInput($as, $f, $id, $idfield, $op) + private function moneyInput($as, $f, $id, $idfield, $op) { // If this is setup for a new entry, then just return default value if ($op == 'n') { @@ -434,7 +443,7 @@ abstract class GlmDataAbstract return $in; } - function moneyStore($in, $f) + private function moneyStore($in, $f) { return $in; } @@ -442,19 +451,19 @@ abstract class GlmDataAbstract /* * Percent Field Processing */ - function percentField($f) + private function percentField($f) { return 'T.'.$f['field']; } - function percentOptions($f) + private function percentOptions($f) { return false; } - function percentOutput($f, $d) + private function percentOutput($f, $d) { return $d; } - function percentInput($as, $f, $id, $idfield, $op) + private function percentInput($as, $f, $id, $idfield, $op) { // If this is setup for a new entry, then just return default value if ($op == 'n') { @@ -531,7 +540,7 @@ abstract class GlmDataAbstract return $in; } - function percentStore($in, $f) + private function percentStore($in, $f) { return $in; } @@ -539,11 +548,11 @@ abstract class GlmDataAbstract /* * Pointer Field Processing */ - function pointerField($f) + private function pointerField($f) { return 'T.'.$f['field']; } - function pointerOptions($f) + private function pointerOptions($f) { // Get ID field of other table - default to 'id' @@ -564,7 +573,7 @@ abstract class GlmDataAbstract return $options; } - function pointerOutput($f, $d, $forEdit = false, $id = false, $idfield = 'id') + private function pointerOutput($f, $d, $forEdit = false, $id = false, $idfield = 'id') { /* @@ -718,7 +727,7 @@ abstract class GlmDataAbstract return $d; } - function pointerInput($as, $f, $id, $idfield, $op) + private function pointerInput($as, $f, $id, $idfield, $op) { $this->inputFieldStatus = true; @@ -892,7 +901,7 @@ abstract class GlmDataAbstract return $r; } - function pointerStore($in, $f) + private function pointerStore($in, $f) { return $in['value']; } @@ -900,15 +909,15 @@ abstract class GlmDataAbstract /* * List Field Processing */ - function listField($f) + private function listField($f) { return 'T.'.$f['field']; } - function listOptions($f) + private function listOptions($f) { return false; } - function listOutput($f, $d, $forEdit, $id, $idfield, $op) + private function listOutput($f, $d, $forEdit, $id, $idfield, $op) { // Check for a list data @@ -971,7 +980,7 @@ abstract class GlmDataAbstract return $r; } - function listInput($as, $f, $id, $idField, $op) + private function listInput($as, $f, $id, $idField, $op) { // Check for a list data @@ -1054,7 +1063,7 @@ abstract class GlmDataAbstract return $r; } - function listStore($in, $f) + private function listStore($in, $f) { $keytype = 'text'; @@ -1075,15 +1084,15 @@ abstract class GlmDataAbstract /* * Bitmap List Field Processing */ - function bitmapField($f) + private function bitmapField($f) { return 'T.'.$f['field']; } - function bitmapOptions($f) + private function bitmapOptions($f) { return false; } - function bitmapOutput($f, $d) + private function bitmapOutput($f, $d) { // Check for a bitmap data if (!isset($f['bitmap']) || !is_array($f['bitmap'])) { @@ -1127,7 +1136,7 @@ abstract class GlmDataAbstract return $r; } - function bitmapInput($as, $f, $id, $idField, $op) + private function bitmapInput($as, $f, $id, $idField, $op) { // Check for a bitmap data @@ -1183,7 +1192,7 @@ abstract class GlmDataAbstract return $r; } - function bitmapStore($in, $f) + private function bitmapStore($in, $f) { $keytype = 'text'; @@ -1204,19 +1213,19 @@ abstract class GlmDataAbstract /* * Text Field Processing */ - function textField($f) + private function textField($f) { return 'T.'.$f['field']; } - function textOptions($f) + private function textOptions($f) { return false; } - function textOutput($f, $d) + private function textOutput($f, $d) { return $d; } - function textInput($as, $f, $id, $idField, $op) + private function textInput($as, $f, $id, $idField, $op) { // If this is setup for a new entry, then just return default value @@ -1321,7 +1330,7 @@ abstract class GlmDataAbstract return $in; } - function textStore($in, $f) + private function textStore($in, $f) { $r = "'".addslashes($in)."'"; return $r; @@ -1330,20 +1339,20 @@ abstract class GlmDataAbstract /* * Password Field Processing */ - function passwordField($f) + private function passwordField($f) { return 'T.'.$f['field']; } - function passwordOptions($f) + private function passwordOptions($f) { return false; } - function passwordOutput($f, $d) + private function passwordOutput($f, $d) { // No output for a password field return ''; } - function passwordInput($as, $f, $id, $idField, $op) + private function passwordInput($as, $f, $id, $idField, $op) { // If this is setup for a new entry, then just return default value if ($op == 'n') { @@ -1427,7 +1436,7 @@ abstract class GlmDataAbstract return $c; } - function passwordStore($in, $f) + private function passwordStore($in, $f) { $r = "'".addslashes($in)."'"; return $r; @@ -1436,15 +1445,15 @@ abstract class GlmDataAbstract /* * Checkbox Field Processing */ - function checkboxField($f) + private function checkboxField($f) { return 'T.'.$f['field']; } - function checkboxOptions($f) + private function checkboxOptions($f) { return false; } - function checkboxOutput($f, $d) + private function checkboxOutput($f, $d) { $list = array( 0 => array( @@ -1479,7 +1488,7 @@ abstract class GlmDataAbstract return $r; } - function checkboxInput($as, $f, $x, $y, $op) + private function checkboxInput($as, $f, $x, $y, $op) { $list = array( 0 => array( @@ -1530,7 +1539,7 @@ abstract class GlmDataAbstract return $r; } - function checkboxStore($in, $f) + private function checkboxStore($in, $f) { if ($in['value']) { return "true"; @@ -1542,19 +1551,19 @@ abstract class GlmDataAbstract /* * E-Mail Field Procesing */ - function emailField($f) + private function emailField($f) { return 'T.'.$f['field']; } - function emailOptions($f) + private function emailOptions($f) { return false; } - function emailOutput($f, $d) + private function emailOutput($f, $d) { return $d; } - function emailInput($as, $f, $id, $idfield, $op) + private function emailInput($as, $f, $id, $idfield, $op) { // If this is setup for a new entry, then just return default value if ($op == 'n') { @@ -1611,7 +1620,7 @@ abstract class GlmDataAbstract return $in; } - function emailStore($in, $f) + private function emailStore($in, $f) { return "'".addslashes($in)."'"; } @@ -1619,15 +1628,15 @@ abstract class GlmDataAbstract /* * Date Field Processing */ - function dateField($f) + private function dateField($f) { return 'T.'.$f['field']; } - function dateOptions($f) + private function dateOptions($f) { return false; } - function dateOutput($f, $d, $forEdit) + private function dateOutput($f, $d, $forEdit) { // Check for min/max date values @@ -1684,7 +1693,7 @@ abstract class GlmDataAbstract return $out; } - function dateInput($as, $f, $id, $idfield, $op) + private function dateInput($as, $f, $id, $idfield, $op) { $this->inputFieldStatus = true; @@ -1824,7 +1833,7 @@ abstract class GlmDataAbstract return $v; } - function dateStore($in, $f) + private function dateStore($in, $f) { // Check if there's no date then supply null @@ -1844,7 +1853,7 @@ abstract class GlmDataAbstract * Time Field Processing */ // Support function to build picklists for Time field - function buildTimeFieldLists() + private function buildTimeFieldLists() { // Setup hour and minute pick lists $hour_list = array(); @@ -1871,15 +1880,15 @@ abstract class GlmDataAbstract return $time_list; } - function timeField($f) + private function timeField($f) { return 'T.'.$f['field']; } - function timeOptions($f) + private function timeOptions($f) { return false; } - function timeOutput($f, $d) + private function timeOutput($f, $d) { // Default values if no time returned $hour = 12; @@ -1928,7 +1937,7 @@ abstract class GlmDataAbstract return $r; } - function timeInput($as, $f, $id, $idfield, $op) + private function timeInput($as, $f, $id, $idfield, $op) { $this->inputFieldStatus = true; $hour = 12; @@ -2059,7 +2068,7 @@ abstract class GlmDataAbstract return $r; } - function timeStore($in, $f) + private function timeStore($in, $f) { return "'".$in['time_store']."'"; } @@ -2067,15 +2076,15 @@ abstract class GlmDataAbstract /* * datetime (date and time) Field Processing */ - function datetimeField($f) + private function datetimeField($f) { return 'T.'.$f['field']; } - function datetimeOptions($f) + private function datetimeOptions($f) { return false; } - function datetimeOutput($f, $d, $forEdit) + private function datetimeOutput($f, $d, $forEdit) { // Check for min/max date values @@ -2154,7 +2163,7 @@ abstract class GlmDataAbstract return $out; } - function datetimeInput($as, $f, $id, $idfield, $op) + private function datetimeInput($as, $f, $id, $idfield, $op) { $this->inputFieldStatus = true; @@ -2297,7 +2306,7 @@ abstract class GlmDataAbstract return $v; } - function datetimeStore($in, $f) + private function datetimeStore($in, $f) { // Check if there's no date then supply null @@ -2317,19 +2326,19 @@ abstract class GlmDataAbstract /* * Phone Field Processing */ - function phoneField($f) + private function phoneField($f) { return 'T.'.$f['field']; } - function phoneOptions($f) + private function phoneOptions($f) { return false; } - function phoneOutput($f, $d) + private function phoneOutput($f, $d) { return $d; } - function phoneInput($as, $f, $id, $idfield, $op) + private function phoneInput($as, $f, $id, $idfield, $op) { // If this is setup for a new entry, then just return default value if ($op == 'n') { @@ -2343,7 +2352,7 @@ abstract class GlmDataAbstract $in = $_REQUEST[$as]; return $in; } - function phoneStore($in, $f) + private function phoneStore($in, $f) { return "'".addslashes($in)."'"; } @@ -2351,19 +2360,19 @@ abstract class GlmDataAbstract /* * Image Field Processing */ - function imageField($f) + private function imageField($f) { return 'T.'.$f['field']; } - function imageOptions($f) + private function imageOptions($f) { return false; } - function imageOutput($f, $d) + private function imageOutput($f, $d) { return $d; } - function imageInput($as, $f, $id, $idfield, $op) + private function imageInput($as, $f, $id, $idfield, $op) { $new = false; @@ -2498,7 +2507,7 @@ abstract class GlmDataAbstract return $current_img; } - function imageStore($in, $f) + private function imageStore($in, $f) { return "'".addslashes($in)."'"; } @@ -2506,19 +2515,19 @@ abstract class GlmDataAbstract /* * Base64 Image Field Processing (for inline images) */ - function b64imageField($f) + private function b64imageField($f) { return 'T.'.$f['field']; } - function b64imageOptions($f) + private function b64imageOptions($f) { return false; } - function b64imageOutput($f, $d) + private function b64imageOutput($f, $d) { return $d; } - function b64imageInput($as, $f, $id, $idfield, $op) + private function b64imageInput($as, $f, $id, $idfield, $op) { $new = false; @@ -2556,7 +2565,7 @@ abstract class GlmDataAbstract return $b64image; } - function b64imageStore($in, $f) + private function b64imageStore($in, $f) { return "'".$in."'"; } @@ -2564,19 +2573,19 @@ abstract class GlmDataAbstract /* * File Field Processing */ - function fileField($f) + private function fileField($f) { return 'T.'.$f['field']; } - function fileOptions($f) + private function fileOptions($f) { return false; } - function fileOutput($f, $d) + private function fileOutput($f, $d) { return $d; } - function fileInput($as, $f, $id, $idfield, $op) + private function fileInput($as, $f, $id, $idfield, $op) { $new = false; @@ -2668,7 +2677,7 @@ abstract class GlmDataAbstract return $current_file; } - function fileStore($in, $f) + private function fileStore($in, $f) { return "'".addslashes($in)."'"; } @@ -2676,15 +2685,15 @@ abstract class GlmDataAbstract /* * latitude Field Processing */ - function latitudeField($f) + private function latitudeField($f) { return 'T.'.$f['field']; } - function latitudeOptions($f) + private function latitudeOptions($f) { return false; } - function latitudeOutput($f, $d) + private function latitudeOutput($f, $d) { $type = 'DMS'; if (isset($f['latlon_type'])) { @@ -2700,7 +2709,7 @@ abstract class GlmDataAbstract return $lat; } - function latitudeInput($as, $f, $id, $idfield, $op) + private function latitudeInput($as, $f, $id, $idfield, $op) { // If this is setup for a new entry, then just return default value if ($op == 'n') { @@ -2790,7 +2799,7 @@ abstract class GlmDataAbstract return $in; } - function latitudeStore($in, $f) + private function latitudeStore($in, $f) { // NOTE: input must be processed first. @@ -2803,15 +2812,15 @@ abstract class GlmDataAbstract /* * Longitude Field Processing */ - function longitudeField($f) + private function longitudeField($f) { return 'T.'.$f['field']; } - function longitudeOptions($f) + private function longitudeOptions($f) { return false; } - function longitudeOutput($f, $d) + private function longitudeOutput($f, $d) { $type = 'DMS'; @@ -2828,7 +2837,7 @@ abstract class GlmDataAbstract return $out; } - function longitudeInput($as, $f, $id, $idfield, $op) + private function longitudeInput($as, $f, $id, $idfield, $op) { // If this is setup for a new entry, then just return default value if ($op == 'n') { @@ -2918,7 +2927,7 @@ abstract class GlmDataAbstract return $in; } - function longitudeStore($in, $f) + private function longitudeStore($in, $f) { // NOTE: input must be processed first. // Need to convert to float degrees here @@ -2937,7 +2946,7 @@ abstract class GlmDataAbstract * @return void * @access public */ - public function buildFieldsList($op = 'l', $options = false, $defaults = false) + private function buildFieldsList($op = 'l', $options = false, $defaults = false) { $this->fieldData = array(); $this->select = ''; @@ -3033,7 +3042,7 @@ abstract class GlmDataAbstract * * @access public */ - public function processOutputData($data, $op = 'l', $forEdit = false, $id = false, $idfield = 'id') + private function processOutputData($data, $op = 'l', $forEdit = false, $id = false, $idfield = 'id') { if ($forEdit) { @@ -3117,7 +3126,7 @@ abstract class GlmDataAbstract * * @access public */ - public function processInputData($op = 'u', $id = false, $idField = false) + private function processInputData($op = 'u', $id = false, $idField = false) { // Status is good unless otherwise determined @@ -3242,6 +3251,9 @@ abstract class GlmDataAbstract * * @param string $where Optional WHERE clause for selection of entries. Defaults to all. * @param string $order Optional ORDER BY clause for sorting of results. + * Set to "pseudo-random" for Pseudo-Random sorting that uses a browser cookie + * to store a custom seed value so all results are in the same randomized order + * for some period of time. See genPseudoRandIdArray() and pseudoRandDataSort(). * @param boolean $fieldVals Optional flag requesting fields contain array of all possible values. * @param string $idField Optional name of ID field (primary index) to use for result array keys. * @@ -3256,24 +3268,64 @@ abstract class GlmDataAbstract // Get field specifications for this instance $this->buildFieldsList('l'); + // If pseudo random order is requested + $this->pseudoRand = false; + if ($order == 'pseudo-random') { + + // Set pseudo random flag and clear the order string + $this->pseudoRand = true; + $order = ''; + + } + + // If doing pseudo-random ordering, generate array of IDs in pseudo-random order + $idString = ''; + if ($this->pseudoRand) { + + $prSql = "SELECT $idField + FROM $this->table T + "; + if (trim($where) != '') { + $prSql .= "WHERE $where + "; + } + + $idList = $this->wpdb->get_results($prSql, ARRAY_A); + $prList = $this->genPseudoRandIdArray($idList, $start, $limit); + $idString = $prList['idString']; + + } + $sql = "SELECT $this->select FROM $this->table T + WHERE true "; if (trim($where != '')) { - $sql .= "WHERE $where + $sql .= "AND $where + "; + } + + // If there's a pseudo-random id list to use for results selection + if ($idString != '') { + $sql .= "AND T.$idField IN ($idString) "; } - if (trim($order != '')) { + if (!$this->pseudoRand && trim($order != '')) { $sql .= "ORDER BY $order "; } - // If $start and $limit, we're doing paging + // If $start and $limit, we're doing paging (pseudo-random does it's own paging) $paging = false; if ($start !== false && $limit > 0) { - $sql .= "limit ".($start-1).", $limit"; + + // If using pseudo-random, don't use the SQL limit. The pseudo-random code does it's own paging + if (!$this->pseudoRand) { + $sql .= "limit ".($start-1).", $limit"; + } + $paging = true; } @@ -3295,11 +3347,15 @@ abstract class GlmDataAbstract $newList[$v['id']] = $this->processOutputData($v, 'l'); } + // If pseudo-random, sort the list by $prList + if ($this->pseudoRand) { + $this->pseudoRandDataSort($prList, $newList); + } + if (is_admin() && GLM_MEMBERS_PLUGIN_ADMIN_DEBUG_VERBOSE && class_exists('glmMembersAdmin')) { $this->addDataAbstractNotice($newList, 'DataBlock', "getList() data"); } - // If we're doing paging, return that data along with the list if ($paging) { $c = count($list); @@ -3824,7 +3880,7 @@ abstract class GlmDataAbstract } /* - * Convert fload degrees to N/S or E/W Lat/Lon as D, D M, or D M S + * Convert float degrees to N/S or E/W Lat/Lon as D, D M, or D M S * * @return array * text Text output of value @@ -3833,7 +3889,7 @@ abstract class GlmDataAbstract * min Minutes * sec Seconds */ - public function f2LatLon($d, $LatLon, $type, $precision) + private function f2LatLon($d, $LatLon, $type, $precision) { $sign = +1; @@ -3916,7 +3972,7 @@ abstract class GlmDataAbstract * * @return array */ - public function buildDateFieldLists($min, $max, $time = false) + private function buildDateFieldLists($min, $max, $time = false) { if (!$this->optionIncludeSelectListData) { @@ -3995,7 +4051,7 @@ abstract class GlmDataAbstract * @return object Class object * */ - public function addDataAbstractNotice ( $d1, $d2 = false, $d3 = false) + private function addDataAbstractNotice ( $d1, $d2 = false, $d3 = false) { if (is_admin() && GLM_MEMBERS_PLUGIN_ADMIN_DEBUG_VERBOSE ) { @@ -4004,5 +4060,174 @@ abstract class GlmDataAbstract glmMembersFront::addNotice($d1, $d2, $d3); } } + + /** + * The following two functions are used to build pseudo-random list results with optional paging + */ + + /* + * Generate a list of ID's sorted in pseudo-random order from + * a supplied array of record IDs. + * + * This function checks for a browser cookie that is used to save + * the seed. If that seed exists and has not timed out, it is used. + * Otherwise a new seed is generated and stored into a browser cookie. + * + * This function is passed an array of all possible record IDs that have been + * retrieved by a query against some table. That query should use a specific + * sort order to ensure that the resulting list of IDs is sorted the same + * for each identical query. + * + * Optional start and page size values may be specified to have this function + * return a subset of the IDs for a particular page of pagenated results. + * + * The return from this function is an array of IDs for the desired pseudo- + * random results in the desired sequence (numerical keys in sequence). + * + * Use the PseudoRandArraysort() function to order any selected results that + * were generated using the ID list returned from this function. + * + * @param array $idList A simple array that's a list of record IDs + * in the order in which they were retrieved. + * @param int $start Optional start of page value for paging + * @param int $length Optional length of page value for paging + * (required if there is a $start value) + * @param string $idName Optional id field name to override default 'id' + * @param string $cookieName Optional name for seed cookie + * @param int $cookieTime Optional # of seconds for cookie timeout + * @param int $seed Optional seed value to use instead of using value from cookie + * + * @return array Array inluding the following... + * 'idString' A comma separated string to use for an "in" clause in + * a second SQL query to get the actual data. + * 'idArray' An array of IDs in the generated pseudo-random order + * + */ + private function genPseudoRandIdArray ($ids, $start = false, $length = false, $idName = 'id', $cookieName = 'GLM_PR_SEED', $cookieTime = 86400, $seed = false) + { + + $transientSeed = false; // Indicates if the function was passed a specific seed. These are not stored back into a browser cookie. + + // Change $ids array to simple array of ids + foreach ($ids as $k => $v) { + $ids[$k] = $v[$idName]; + } + + // if no id list is supplied + if (!is_array($ids) || count($ids) == 0) { + return false; + } + + // If a seed is supplied + if ($seed && is_int($seed)) { + + // Set flag so cookie is not updated with this seed. + $transientSeed = true; + + //Otherwise, use a browser cookie seed if available or generate a new one + } else { + + // Get browser cookie if it exists + if (isset($_COOKIE[$cookieName])) { + $seed = ($_COOKIE[$cookieName]); + } else { + + // Generate a new seed + $seed = intval(time()*1000000+microtime()*1000000); + + } + } + + // Enforce seed as positive integer + $seed = abs(intval($seed -0)); + + // If seed is somehow 0, return false + if ($seed == 0) { + return false; + } + + // If this is not a transient seed, store or updated it into the browser cookie. + if (!$transientSeed) { + setcookie($cookieName, $seed, time() + $cookieTime); + } + + // Use the seed to order the ID list - Note that shuffle() will produce the same results if strand() has the same seed. + srand($seed); + shuffle($ids); + + // If we have a start value + if ($start !== false) { + + // Enforce valid start + $start = abs(intval($start-0)); + + // Enforce length - Required with a $start value + $length = abs(intval($length-0)); + if ($length == 0) { + return false; + } + + // Get at max $length elements of the ID array starting with $start + $ids = array_slice($ids, $start, $length, true); + + + } + + // If paging, build comma separated string of id's for use as part of a "in" clause in an SQL query. + $idString = ''; + $newIdArray = array(); + if ($start !== false) { + $sep = ''; + foreach ($ids as $i) { + $idString .= $sep.$i; + $sep = ', '; + } + } + + return array('idString' => $idString, 'idArray' => $ids); + + } + + + /* + * Order a final data array by the sequence of results from genPseudoRandIdArray(). + * + * To use this function... + * + * * Query the database to get a list of record IDs only matching the desired result + * * Retrieve an ordered list of those IDs using genPseudoRandIdArray() + * * Query the database again for final results matching the list of IDs + * * Use this function to sort the final resuts by the generated order of IDs + * + * Note that the $data parameter is used by reference so as to not duplicate the full + * data array. This will modify the original array. + * + * @param array $idArray An array returned by genPseudoRandIdArray() + * @param array &$data A data array of final results to be ordered + * @param string $idName Optional id field name to override default 'id' + * + * @return boolean True if successful, otherwise false + * + */ + private function pseudoRandDataSort ($idList, &$data, $idName = 'id') + { + + $idFlip = array_flip($idList['idArray']); + + foreach($data as $k=>$v) { + $data[$k]['prSort'] = $idFlip[$v[$idName]]; + } + + uasort( $data, function($a, $b) { + if ($a['prSort'] == $b['prSort']) { + return 0; + } + return ($a['prSort'] < $b['prSort']) ? -1 : 1; + }); + + return true; + } + + } ?> \ No newline at end of file diff --git a/lib/GlmDataAbstract/documentation.odt b/lib/GlmDataAbstract/documentation.odt index b3d3b417..330ff444 100644 Binary files a/lib/GlmDataAbstract/documentation.odt and b/lib/GlmDataAbstract/documentation.odt differ diff --git a/models/front/members/list.php b/models/front/members/list.php index b6aebc7c..52cb0906 100644 --- a/models/front/members/list.php +++ b/models/front/members/list.php @@ -525,7 +525,7 @@ class GlmMembersFront_members_list extends GlmDataMemberInfo $alphaList = $this->getAlphaList(' AND '.$where, $alphaSelected); } - + /* * Check for which view file to use, else default to list */ @@ -552,8 +552,9 @@ class GlmMembersFront_members_list extends GlmDataMemberInfo // Get stats for the current selection $membersFound = $this->getStats(str_replace('T.', '', $where)); - // Get member list and sort - $list = $this->getList($where.$alphaWhere, 'member_name'); + // Get member list and sort - Currently using pseudo-random order + // $list = $this->getList($where.$alphaWhere, 'member_name'); + $list = $this->getList($where.$alphaWhere, 'pseudo-random'); if (GLM_MEMBERS_PLUGIN_FRONT_DEBUG) { glmMembersFront::addNotice($list, 'DataBlock', 'Member Data');