function strBuildCReportSQL(&$report, $strLimit = '', $bTerminateSQL = true)
 {
     //---------------------------------------------------------------------
     //
     //---------------------------------------------------------------------
     $lReportID = $report->lKeyID;
     // create select aliases
     $this->buildSelectAsNames($report->fields);
     // load search terms
     $this->loadSearchTermViaReportID($lReportID);
     // load sort terms
     $this->loadSortFieldsViaReportID($lReportID, $lNumSortTerms, $sortTerms);
     $this->uf = new muser_fields();
     // tables needed for the report
     crptTables\tablesUsed($report, $this->terms, $sortTerms, $this->tableIDs);
     $stTableIDs = array();
     crptTables\tableIDsSearchTerms($this->terms, $stTableIDs);
     $stTableIDs = array_keys($stTableIDs);
     $this->singleEntryPTableReview($stTableIDs, $strSingleEntryWriteWhere);
     $strFrom = $strSelect = $strWhere = $strOrder = array();
     switch ($report->enumRptType) {
         case CE_CRPT_CLIENTS:
             $lNumFrom = 1;
             $strFNKeyID = 'cr_lKeyID';
             $strFrom[0] = 'FROM client_records';
             $strWhereContext = ' NOT cr_bRetired AND (';
             $strWhereContextClose = ' )';
             $strDefaultOrder = 'cr_lKeyID ';
             break;
         default:
             screamForHelp($report->enumRptType . ': report not available<br>error on line  <b> -- ' . __LINE__ . ' --</b>,<br>file ' . __FILE__ . ',<br>function ' . __FUNCTION__);
             break;
     }
     $this->buildPTableJoins($strFNKeyID, $this->tableIDs, $lNumFrom, $strFrom);
     $this->buildPTableJoinsForDDLS($report->fields, $lNumFrom, $strFrom, $strSelect);
     $this->strJoins = '';
     foreach ($strFrom as $sf) {
         $this->strJoins .= $sf . "\n";
     }
     $this->strSelect = '';
     foreach ($strSelect as $ss) {
         $this->strSelect .= $ss . ",\n";
     }
     $this->strSelect = substr($this->strSelect, 0, strlen($this->strSelect) - 2);
     $this->strWhere = $this->strWhereViaTerms($this->lNumTerms, $this->terms);
     $this->strOrder = $this->strOrderViaTerms($strDefaultOrder, $lNumSortTerms, $sortTerms);
     $this->strSQL = 'SELECT DISTINCT ' . $this->strSelect . "\n" . $this->strJoins . "\n" . 'WHERE ' . $strSingleEntryWriteWhere . "\n" . $strWhereContext . "\n" . $this->strWhere . "\n" . $strWhereContextClose . "\n" . 'ORDER BY ' . $this->strOrder . "\n" . $strLimit;
     if ($bTerminateSQL) {
         $this->strSQL .= ';';
     }
 }
 function bVerifyUserAccessToReport($report, &$lNumFails, &$failTables)
 {
     //---------------------------------------------------------------------
     //
     //---------------------------------------------------------------------
     global $glUserID, $gbAdmin;
     $lNumFails = 0;
     $failTables = array();
     if ($gbAdmin) {
         return true;
     }
     $lReportID = $report->lKeyID;
     // load search terms
     $this->loadSearchTermViaReportID($lReportID);
     // load sort terms
     $this->loadSortFieldsViaReportID($lReportID, $lNumSortTerms, $sortTerms);
     $this->uf = new muser_fields();
     // tables needed for the report
     crptTables\tablesUsed($report, $this->terms, $sortTerms, $tableIDs);
     if (count($tableIDs) == 0) {
         return true;
     }
     $cperm = new mpermissions();
     $cperm->loadUserAcctInfo($glUserID, $acctAccess);
     $cUF = new muser_fields();
     $cUF->lTableID = array();
     foreach ($tableIDs as $TID) {
         $cUF->lTableID[] = $TID;
     }
     $cUF->loadTableViaTableID(false);
     foreach ($cUF->userTables as $utable) {
         if (!$cperm->bDoesUserHaveAccess($acctAccess, $utable->lNumConsolidated, $utable->cperms)) {
             $failTables[$lNumFails] = '[' . $utable->enumTType . '] ' . $utable->strUserTableName;
             ++$lNumFails;
         }
     }
     return $lNumFails == 0;
 }