Work on fixing long parameter list for getList method
authorSteve Sutton <steve@gaslightmedia.com>
Thu, 22 Aug 2019 20:16:16 +0000 (16:16 -0400)
committerSteve Sutton <steve@gaslightmedia.com>
Thu, 22 Aug 2019 20:16:16 +0000 (16:16 -0400)
Building a new method getResults.
New method will have defaults array that will be overridden by the
config array given to it. The old method will just call the new one.
This is to keep backward compatibility for anything and everything that
is current using getList(). Newer models can start using getResults
method.
New config array options include groupby.

lib/GlmDataAbstract/DataAbstract.php

index 214346c..ca5a572 100755 (executable)
@@ -3255,6 +3255,52 @@ $forEdit = true;
      */
     public function getList( $where = '', $order = '', $fieldVals = true, $idField = 'id', $start = false, $limit = false, $prohibitListOptions = false, $appendSelect = null )
     {
+        $config = [
+            'where'               => $where,
+            'order'               => $order,
+            'fieldVals'           => $fieldVals,
+            'idField'             => $idField,
+            'start'               => $start,
+            'limit'               => $limit,
+            'prohibitListOptions' => $prohibitListOptions,
+            'appendSelect'        => $appendSelect,
+        ];
+        return $this->getResults( $config );
+    }
+
+    /**
+     * getResults
+     *
+     * NOTE: Order by only works on the initial query, not on the target values of
+     * pointer fields because those fields are post-processed to get the target value
+     * after the query takes place. Calling code will have to sort the results to
+     * sort by those target values.
+     *
+     * @param $config Configuration array (merged with $defaults)
+     *
+     * @return mixed Array or Json containing results
+     * @acces  public
+     */
+    public function getResults( $config )
+    {
+        $defaults = [
+            'where'               => '',
+            'order'               => '',
+            'fieldVals'           => true,
+            'idField'             => 'id',
+            'start'               => false,
+            'limit'               => false,
+            'prohibitListOptions' => false,
+            'appendSelect'        => null,
+            'groupby'             => false,
+            'stats'               => false,
+        ];
+
+        $params = array_merge( $defaults, $config );
+
+        // extract $params Array
+        extract( $params );
+
         $this->selectGroupFields();
 
         // For testing only
@@ -3279,16 +3325,16 @@ $forEdit = true;
         // NOTE: $fieldVals not yet implemented
 
         // Check if we're asked to block all list field options. Only enable this, the parameter does not permit turning it off
-        if ($prohibitListOptions) {
+        if ( $prohibitListOptions ) {
             $this->$optionProhibitListOptions = true;
         }
 
         // Get field specifications for this instance
-        $this->buildFieldsList('l');
+        $this->buildFieldsList( 'l' );
 
         // If pseudo random order is requested
         $this->pseudoRand = false;
-        if ($order == 'pseudo-random') {
+        if ( $order == 'pseudo-random' ) {
 
                 // Set pseudo random flag and clear the order string
             $this->pseudoRand = true;
@@ -3298,33 +3344,33 @@ $forEdit = true;
 
         // If random order is requested
         $this->rand = false;
-        if ($order == 'random') {
+        if ( $order == 'random' ) {
 
             // Set rand and pseudoRand flags and clear the order string
             // Note that random uses pseudo-random code but overrides the seed each time
-            $this->rand = true;
+            $this->rand       = true;
             $this->pseudoRand = true;
-            $order = '';
+            $order            = '';
 
             // Generate a new seed each time - this causes full random ordering and overrides "pseudo-random"
-            $seed = intval(time()*1000000+microtime()*1000000);
+            $seed = intval( time() * 1000000 + microtime() * 1000000 );
 
         }
 
         // If doing pseudo-random or random ordering, generate array of IDs in pseudo-random order
         $idString = '';
-        if ($this->pseudoRand || $this->rand) {
+        if ( $this->pseudoRand || $this->rand ) {
 
             $prSql = "SELECT $idField
                     FROM $this->table T
             ";
-            if (trim($where) != '') {
+            if ( trim( $where ) != '' ) {
                 $prSql .= "WHERE $where
                 ";
             }
 
-            $idList = $this->wpdb->get_results($prSql, ARRAY_A);
-            $prList = $this->genPseudoRandIdArray($idList, $start, $limit, 'id', 'GLM_PR_SEED', $seed);
+            $idList = $this->wpdb->get_results( $prSql, ARRAY_A );
+            $prList = $this->genPseudoRandIdArray( $idList, $start, $limit, 'id', 'GLM_PR_SEED', $seed );
             $idString = $prList['idString'];
 
         }
@@ -3332,42 +3378,70 @@ $forEdit = true;
         if ( $appendSelect ) {
             $this->select .= ', ' . $appendSelect;
         }
+        if ( !empty( $groupby ) && isset( $groupby['aggregate'] ) ) {
+            $this->select .= ", {$groupby['aggregate']} ";
+        }
 
         $sql = "SELECT $this->select
                 FROM $this->table T
                 WHERE true
         ";
-        if (trim($where != '')) {
+        if ( trim( $where != '' ) ) {
             $sql .= "AND $where
             ";
         }
 
         // If there's a pseudo-random id list to use for results selection
-        if ($idString != '') {
+        if ( $idString != '' ) {
             $sql .= "AND T.$idField IN ($idString)
             ";
         }
 
-        if (!$this->pseudoRand && trim($order != '')) {
+        if ( !empty( $groupby ) && isset( $groupby['group'] ) ) {
+            $sql .= "GROUP BY {$groupby['group']} ";
+        }
+
+        if ( !$this->pseudoRand && trim( $order != '' ) ) {
             $sql .= "ORDER BY $order
             ";
         }
 
         // If $start and $limit, we're doing paging (pseudo-random does it's own paging)
         $paging = false;
-        if ($start !== false && $limit > 0) {
+        if ( $start !== false && $limit > 0 ) {
 
             // 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";
+            if ( !$this->pseudoRand ) {
+                $sql .= "limit " . ( $start - 1 ) . ", $limit";
             }
 
             $paging = true;
         }
 
-        $list = $this->wpdb->get_results($sql, ARRAY_A);
+        if ( $stats ) {
+            $selectPart = "count(DISTINCT id) as count";
+            if ( !empty( $groupby ) && isset( $groupby['group'] ) ) {
+                $selectPart = "count(DISTINCT {$groupby['group']}) as count";
+            }
+
+            $statSql = "
+            SELECT $selectPart
+              FROM $this->table
+             WHERE true ";
+            if ( trim( $where != '' ) ) {
+                $statSql .= "AND $where ";
+            }
+            if ( !empty( $groupby ) && isset( $groupby['group'] ) ) {
+                $statSql .= "GROUP BY {$groupby['group']} ";
+            }
+
+            $resultStatsData = $this->wpdb->get_results( $statSql, ARRAY_A );
+            $stats           = count($resultStatsData);
+        }
+
+        $list = $this->wpdb->get_results( $sql, ARRAY_A );
 
-        if (count($list) == 0) {
+        if ( count( $list ) == 0 ) {
             return false;
         }
 
@@ -3376,24 +3450,30 @@ $forEdit = true;
 
         // Process field output data for each result - use ID field as key
         foreach ( $list as $k => $v ) {
-            $newList[$v['id']] = $this->processOutputData($v, 'l');
+            $newList[$v['id']] = $this->processOutputData( $v, 'l' );
         }
 
         // If pseudo-random, sort the list by $prList
-        if ($this->pseudoRand) {
-            $this->pseudoRandDataSort($prList, $newList);
+        if ( $this->pseudoRand ) {
+            $this->pseudoRandDataSort( $prList, $newList );
         }
 
         // If we're doing paging, return that data along with the list
-        if ($paging) {
-            $c = count($list);
-            return array(
-                'start' => $start,
-                'limit' => $limit,
+        if ( $paging ) {
+            $c = count( $list );
+            $return = [
+                'start'    => $start,
+                'limit'    => $limit,
                 'returned' => $c,
-                'last' => $start + count($list) - 1,
-                'list' => $newList
-            );
+                'last'     => $start + count($list) - 1,
+                'list'     => $newList
+            ];
+
+            if ( $stats = filter_var( $stats, FILTER_VALIDATE_INT ) ) {
+                $return['stats'] = $stats;
+            }
+
+            return $return;
         }
 
         $this->restoreFields();