PageRenderTime 172ms CodeModel.GetById 84ms app.highlight 73ms RepoModel.GetById 1ms app.codeStats 1ms

/assets/snippets/ajaxSearch/classes/ajaxSearchOutput.class.inc.php

https://github.com/good-web-master/modx.evo.custom
PHP | 1079 lines | 958 code | 64 blank | 57 comment | 90 complexity | 32af1d0c6ecd971c91f7ebc7df9f6cee MD5 | raw file
   1<?php
   2/* -----------------------------------------------------------------------------
   3* Snippet: AjaxSearch
   4* -----------------------------------------------------------------------------
   5* @package  AjaxSearchOutput
   6*
   7* @author       Coroico - www.modx.wangba.fr
   8* @version      1.9.2
   9* @date         05/12/2010
  10*
  11* Purpose:
  12*    The AjaxSearchOutput class contains all functions and data used to display output
  13*
  14*/
  15
  16define('HIGHLIGHT_CLASS', 'ajaxSearch_highlight');
  17
  18define('PREFIX_AJAX_RESULT_CLASS', 'AS_ajax_result');
  19
  20define('PREFIX_RESULT_CLASS', 'ajaxSearch_result');
  21
  22define('INTROFAILURE_CLASS', 'AS_ajax_resultsIntroFailure');
  23
  24define('RESULTS_DIV', '<div id="%sajaxSearch_output" class="init"></div>');
  25
  26define('AJAXSEARCH_JSDIR','js/ajaxSearch');
  27
  28define('ASPHX','||-AJAXSEARCH-||');
  29
  30define('NB_MORE_RESULTS',10);
  31
  32class AjaxSearchOutput {
  33
  34    // public variables
  35    var $asCfg = null;
  36    var $asCtrl = null;
  37    var $asInput = null;
  38    var $asResults = null;
  39    var $asUtil = null;
  40    var $asLog = null;
  41
  42    var $dbg = false;
  43    var $dbgTpl = false;
  44    var $dbgRes = false;
  45    var $log = false;
  46
  47    var $output;
  48    // class variables
  49    var $asClass = array();
  50    // chunkie variables
  51    var $chkResults;
  52    var $varResults = array();
  53    var $chkGrpResult;
  54    var $varGrpResult = array();
  55    var $tplGrpRes;
  56    var $chkResult;
  57    var $varResult = array();
  58    var $tplRes;
  59    var $scMain = array();
  60    var $scJoined = array();
  61    var $scTvs = array();
  62    var $logIds = array();
  63
  64    // private variables
  65    var $_needsConvert;
  66
  67    function AjaxSearchOutput() {
  68    }
  69    function init(&$asCfg, &$asCtrl, &$asInput, &$asResults, &$asUtil, &$asLog, $log) {
  70        // initialize the output instance
  71        $this->asCfg =& $asCfg;
  72        $this->asCtrl =& $asCtrl;
  73        $this->asInput =& $asInput;
  74        $this->asResults =& $asResults;
  75        $this->asUtil =& $asUtil;
  76        $this->dbg = $asUtil->dbg;
  77        $this->dbgTpl = $asUtil->dbgTpl;
  78        $this->dbgRes = $asUtil->dbgRes;
  79        $this->asLog =& $asLog;
  80        $this->log = $log;
  81    }
  82    /*
  83    * display : display final output
  84    */
  85    function display($validSearch, &$msgErr) {
  86        global $modx;
  87
  88        $this->_checkParams();
  89        if ($this->asCfg->isAjax) {
  90            $jsonPairs = array();
  91            $output = $this->_displayResults($validSearch, $msgErr, $nbResultsInfos);
  92            $output .= $this->_displayComment();
  93            $jsonPairs[] = $this->_getJsonPair('res',$output);
  94            $jsonPairs[] = $this->_getJsonPair('resnb',$nbResultsInfos);
  95            if ($validSearch) $this->_updateAsf($jsonPairs);
  96            $output = $this->_getJson($jsonPairs);
  97        }
  98        else {
  99            $outputInputForm = $this->asInput->inputForm;   //
 100            $outputAsfForm = $this->asInput->asfForm;
 101            if ($this->asCfg->cfg['ajaxSearch']) {
 102                $outputResults = $this->_initDisplayResults();
 103            }
 104            else {
 105                $outputResults = $this->_displayResults($validSearch, $msgErr, $nbResultsInfos); // non ajax results output
 106                $outputResults .= $this->_displayComment();
 107            }
 108            if (!$this->asCfg->cfg['output']) {
 109                $output = $outputInputForm;
 110                $output .= $outputAsfForm;
 111                $output .= $outputResults;
 112            }
 113            else {
 114                $output = '';
 115                $modx->setPlaceholder("as.inputForm", $outputInputForm);
 116                $modx->setPlaceholder("as.asfForm", $outputAsfForm);
 117                $modx->setPlaceholder("as.results", $outputResults);
 118            }
 119        }
 120        return $output;
 121    }
 122    /*
 123    * checkParams : Check output field params
 124    */
 125    function _checkParams() {
 126        if (($this->asCfg->cfg['pagingType'] < 0) || ($this->asCfg->cfg['pagingType'] > 2)) $this->asCfg->cfg['pagingType'] = 1;
 127    }
 128    /*
 129    * Init display results
 130    */
 131    function _initDisplayResults(){
 132        $prefix = ($this->asCfg->cfg['asId']) ? $this->asCfg->cfg['asId'] . "_" : '';
 133        $outputResults = sprintf(RESULTS_DIV, $prefix);
 134        return $outputResults;
 135    }
 136    /*
 137    * displayResults : display results
 138    */
 139    function _displayResults($validSearch, &$msgErr, &$nbResultsInfos) {
 140        $this->_initCommonChunks();
 141        $outputResults = '';
 142        $nbFoundResults = 0;
 143        $nbDisplayedResults = 0;
 144        $logIds = array();
 145        $asCall = $this->_getAsCall($this->asCfg->setAsCall($this->asCfg->getUserConfig()));
 146        $select = $this->asResults->_asRequest->asSelect;
 147        if ($this->asCfg->cfg['showResults']) {
 148            if ($validSearch) {
 149                if (!$this->asCfg->isAjax) $this->_setOffset();
 150                $listGrpResults = '';
 151                $ig = 0;
 152                if ($this->asResults->nbResults > 0) {
 153                    $this->_getSearchContext();
 154                    $nbDisplayedResults = 0;
 155                    for ($ig = 0;$ig < $this->asResults->nbGroups;$ig++) {
 156
 157                       $found = '';
 158                        $site = $this->asResults->groupResults[$ig]['site'];
 159                        $subsite = $this->asResults->groupResults[$ig]['subsite'];
 160                        $display = $this->asResults->groupResults[$ig]['display'];
 161                        $offset = intval($this->asResults->groupResults[$ig]['offset']);
 162                        $nbrs = intval($this->asResults->groupResults[$ig]['length']);
 163                        $nbFoundResults += $nbrs;
 164                        // nb results displayed
 165                        if ($this->asCfg->isAjax) $nbMax = ($this->asCfg->cfg['ajaxMax'] > 0) ? $this->asCfg->cfg['ajaxMax'] : $nbrs;
 166                        else $nbMax = ($this->asCfg->cfg['grabMax'] > 0) ? $this->asCfg->cfg['grabMax'] : $nbrs;
 167
 168                        $searchResults = array_slice($this->asResults->groupResults[$ig]['results'], $offset, $nbMax);
 169                        $nbDisplayedResults += count($searchResults);
 170
 171                        $this->asCfg->chooseConfig($site, $subsite, $display);
 172                        $this->_initDisplayVariables();
 173
 174                        $listGrpResults .= $this->_displayGrpResult($ig, $site, $subsite, $display, $nbrs, $searchResults, $offset, $nbMax);
 175
 176                        $lid = $this->_setSuccessfullSearches($ig);
 177                        if ($lid) $logIds[] = $lid;
 178                    }
 179
 180                    $this->asCfg->restoreConfig(DEFAULT_SITE, DEFAULT_SUBSITE);
 181
 182                    if ($nbFoundResults) {
 183
 184                        if ($this->asCtrl->searchString && ($this->asCtrl->advSearch != NOWORDS)) {
 185                            $resultsFoundText = ($nbFoundResults > 1) ? $this->asCfg->lang['as_resultsFoundTextMultiple'] : $this->asCfg->lang['as_resultsFoundTextSingle'];
 186                            if ($this->asResults->withExtract) {
 187                                $searchList = $this->asCtrl->getSearchWords($this->asCtrl->searchString, $this->asCtrl->advSearch);
 188                                $hits = 1;
 189                                $searchwords = '';
 190                                foreach ($searchList as $words) {
 191                                    $searchwords.= '<span class="ajaxSearch_highlight ajaxSearch_highlight' . $hits . '">' . $words . '</span>&nbsp;';
 192                                    $hits++;
 193                                }
 194                                $searchwords = substr($searchwords, 0, strlen($searchwords) - 6);
 195                                $this->varResults['resultsFoundText'] = sprintf($resultsFoundText, $nbFoundResults, $searchwords);
 196                            } else {
 197                                $this->varResults['resultsFoundText'] = sprintf($resultsFoundText, $nbFoundResults, $this->asCtrl->searchString);
 198                            }
 199                        }
 200                        else {
 201                            $resultsFoundText = ($nbFoundResults > 1) ? $this->asCfg->lang['as_resultsTextMultiple'] : $this->asCfg->lang['as_resultsTextSingle'];
 202                            $this->varResults['resultsFoundText'] = sprintf($resultsFoundText, $nbFoundResults);
 203                        }
 204
 205                        $resultsDisplayedText = $this->asCfg->lang['as_resultsDisplayed'];
 206                        $this->varResults['resultsDisplayedText'] = sprintf($resultsDisplayedText, $nbDisplayedResults);
 207
 208
 209                        $this->varResults['noResults'] = 0;
 210                        $this->varResults['listGrpResults'] = ASPHX;
 211
 212                        if ($this->asCfg->isAjax) $this->_setMoreResultsLink($this->asResults->nbResults);
 213                    }
 214                    else {
 215                        $this->varResults['noResults'] = 1;
 216                        $this->varResults['noResultClass'] = INTROFAILURE_CLASS;
 217                        $this->varResults['noResultText'] = $this->asCfg->lang['as_resultsIntroFailure'];
 218                        $this->_setFailedSearches($asCall,$select);
 219                    }
 220                } else {
 221                    $this->varResults['noResults'] = 1;
 222                    $this->varResults['noResultClass'] = INTROFAILURE_CLASS;
 223                    $this->varResults['noResultText'] = $this->asCfg->lang['as_resultsIntroFailure'];
 224                    $this->_setFailedSearches($asCall,$select);
 225                }
 226            }
 227            else {
 228                $this->varResults['showCmt'] = 0;
 229                $this->varResults['noResults'] = 1;
 230                $this->varResults['noResultClass'] = 'AS_ajax_resultsIntroFailure';
 231                $this->varResults['noResultText'] = $msgErr;
 232            }
 233            $this->chkResults->AddVar("as", $this->varResults);
 234            $outputResults = $this->chkResults->Render();
 235            $outputResults = str_replace(ASPHX, $listGrpResults, $outputResults);
 236            unset($this->varResults);
 237            unset($this->chkResults);
 238
 239            // UTF-8 conversion is required if mysql character set is different of 'utf8'
 240            if ($this->_needsConvert) $outputResults = mb_convert_encoding($outputResults,"UTF-8",$this->asCfg->pgCharset);
 241
 242            $this->logIds = $logIds;
 243        }
 244
 245        $nbResultsInfos = $nbFoundResults . ',' . $nbDisplayedResults;
 246        return $outputResults;
 247    }
 248    /*
 249    * Display a group of results
 250    */
 251    function _displayGrpResult($ig, $site, $subsite, $display, $nbrs, $searchResults, $offset, $nbMax) {
 252        $found = array();
 253        $this->chkGrpResult = new AsPhxParser($this->tplGrpRes);
 254        $this->varGrpResult = array();
 255
 256        $this->varGrpResult['headerGrpResult'] = $this->_displayHeaderGrpResult($site, $subsite, $display, $nbrs, $searchResults, $offset, $nbMax);
 257
 258        $this->varGrpResult['grpResultsDef'] = 1;
 259        $prefix = ($this->asCfg->cfg['asId']) ? $this->asCfg->cfg['asId'] . "_" : '';
 260        $this->varGrpResult['grpResultId'] = $prefix . 'grpResult_' . $this->_getCleanCssId($subsite);
 261
 262        $listResults = $this->_displayListResults($site, $subsite, $display, $nbrs, $searchResults, $found, $offset);
 263        $this->varGrpResult['listResults'] = ASPHX;
 264
 265        $this->varGrpResult['footerGrpResult'] = $this->_displayFooterGrpResult($ig, $nbrs,  $offset, $nbMax);
 266
 267        $this->asResults->groupResults[$ig]['found'] = implode(' ',$found);
 268
 269        $this->chkGrpResult->AddVar("as", $this->varGrpResult);
 270        $grpResult = $this->chkGrpResult->Render();
 271        $grpResult = str_replace(ASPHX, $listResults, $grpResult);
 272        unset($this->varGrpResult);
 273        unset($this->chkGrpResult);
 274
 275        return $grpResult;
 276    }
 277    /*
 278    * Display the header of a group of results
 279    */
 280    function _displayHeaderGrpResult($site, $subsite, $display, $nbrs, $searchResults, $offset, $nbMax) {
 281        $varHeader = array();
 282
 283        $varHeader['grpResultsDef'] = 0;
 284        $label = (isset($this->asCfg->scfg[$site][$subsite]['grpLabel'])) ? $this->asCfg->scfg[$site][$subsite]['grpLabel'] : $subsite;
 285        $varHeader['grpResultNameShow'] = ($label != DEFAULT_SUBSITE) ? 1 : 0;
 286        $varHeader['grpResultName'] = $label;
 287        $grpResultsDisplayedText = $this->asCfg->lang['as_grpResultsDisplayedText'];
 288        $grpResultNb = $nbrs;
 289        $grpResultStart = $offset + 1;
 290        $grpResultEnd = ($offset + $nbMax > $nbrs) ? $nbrs : $offset + $nbMax;
 291        $varHeader['grpResultsDisplayedText'] = sprintf($grpResultsDisplayedText, $grpResultStart, $grpResultEnd, $grpResultNb);
 292
 293        $this->chkGrpResult->AddVar("as", $varHeader);
 294        $header = $this->chkGrpResult->Render();
 295        $this->chkGrpResult->CleanVars();
 296        return $header;
 297    }
 298    /*
 299    * Display the list of results
 300    */
 301    function _displayListResults($site, $subsite, $display, $nbrs, $searchResults, & $found, $offset) {
 302        $nb = count($searchResults);
 303        $listResults = '';
 304
 305        for ($i = 0;$i < $nb;$i++) {
 306            $this->varResult = array();
 307
 308            $found[] = $this->_setResultDisplayed($searchResults[$i]);
 309
 310            $this->_setResultLink($searchResults[$i]);
 311
 312            $this->_setResultExtract($searchResults[$i]);
 313
 314            $this->_setResultBreadcrumbs($searchResults[$i]);
 315
 316            $this->_setResultNumber($offset + $i + 1);
 317
 318
 319            $this->chkResult->AddVar("as", $this->varResult);
 320            $listResults .= $this->chkResult->Render();
 321            unset($this->varResult);
 322            $this->chkResult->CleanVars();
 323        }
 324        return $listResults;
 325    }
 326    /*
 327    * Display the footer of group results (paging)
 328    */
 329    function _displayFooterGrpResult($ig, $nbrs, $offset, $nbMax) {
 330        global $modx;
 331        $footer = '';
 332        $showPagingAlways = (int)$this->asCfg->cfg['showPagingAlways'];
 333        $pagingType = $this->asCfg->cfg['pagingType'];
 334        if ($nbMax > 0) {
 335            $numResultPages = ceil($nbrs / $nbMax);
 336            $maxOffset = ($numResultPages - 1) * $nbMax;
 337            $offset = ($offset > $maxOffset) ? $maxOffset : $offset;
 338            $offset = ($offset < 0) ? 0 : $offset;
 339            if (($pagingType == 0) && (!$this->asCfg->isAjax)) {
 340
 341                $tplPaging = $this->asCfg->cfg['tplPaging0'];
 342                if ($tplPaging == '') $tplPaging = "@FILE:" . AS_SPATH . 'templates/paging0.tpl.html';
 343                $chkPaging = new AsPhxParser($tplPaging);
 344                if ($this->dbgTpl) $this->asUtil->dbgRecord($chkPaging->getTemplate($tplPaging), "tplPaging template " . $tplPaging);
 345                $resultPagingText = (($nbrs > $nbMax) || $showPagingAlways) ? $this->asCfg->lang['as_paginationTextMultiplePages'] : $this->asCfg->lang['as_paginationTextSinglePage'];
 346                $resultPageLinkNumber = 1;
 347                $resultPageLinks = '';
 348                $url = $this->_getParamsUrl();
 349                $otherOffset = $this->_getOtherOffset($ig);
 350                for ($nrp = 0;$nrp < $nbrs && (($nbrs > $nbMax) || $showPagingAlways);$nrp+= $nbMax) {
 351                    $varLink = array();
 352                    if ($offset == ($resultPageLinkNumber - 1) * $nbMax) {
 353                        $varLink['tpl'] = 'pagingLinksCurrent';
 354                    } else {
 355                        $varLink['tpl'] = 'pagingLinks';
 356                        $ofst = (string)$ig . ',' . (string)$nrp;
 357                        $asOffset = ($otherOffset) ? $otherOffset . ',' . $ofst : $ofst;
 358                        $asOffset = '&aso=' . $asOffset;
 359                        $paramsUrl = $url . $asOffset;
 360                        $varLink['pagingLink'] = $modx->makeUrl($modx->documentIdentifier, '', $paramsUrl);
 361                    }
 362                    $varLink['pagingSeparator'] = ($nrp + $nbMax < $nbrs) ? $this->asCfg->cfg['pageLinkSeparator'] : '';
 363                    $varLink['pagingText'] = $resultPageLinkNumber;
 364                    $resultPageLinkNumber++;
 365
 366                    $chkPaging->AddVar("as", $varLink);
 367                    $resultPageLinks.= $chkPaging->Render();
 368                    unset($varLink);
 369                    $chkPaging->CleanVars();
 370                }
 371                $varPaging = array();
 372                $varPaging['tpl'] = 'paging';
 373                $varPaging['pagingText'] = $resultPagingText;
 374                $varPaging['pagingLinks'] = $resultPageLinks;
 375
 376                $chkPaging->AddVar("as", $varPaging);
 377                $footer = $chkPaging->Render();
 378                unset($varPaging);
 379                $chkPaging->CleanVars();
 380            }
 381            else if (($pagingType == 1) && (($nbrs >= $nbMax) || showPagingAlways)) {
 382
 383                $tplPaging = $this->asCfg->cfg['tplPaging1'];
 384                if ($tplPaging == '') $tplPaging = "@FILE:" . AS_SPATH . 'templates/paging1.tpl.html';
 385                if (!$this->asCfg->isAjax) {
 386                    $url = $this->_getParamsUrl();
 387                    $otherOffset = $this->_getOtherOffset($ig);
 388                }
 389
 390                $chkPaging = new AsPhxParser($tplPaging);
 391                if ($this->dbgTpl) $this->asUtil->dbgRecord($chkPaging->getTemplate($tplPaging), "tplPaging template " . $tplPaging);
 392                $varPaging1 = array();
 393                if ($offset - $nbMax >= 0) {
 394                    $varPaging1['showPrev'] = 1;
 395                    $prevOffset = $offset - $nbMax;
 396                    $prefix = ($this->asCfg->cfg['asId']) ? $this->asCfg->cfg['asId'] . "_" : '';
 397                    $varPaging1['prev_grpResultId'] = $prefix . 'prev_' . $this->_getCleanCssId($this->asResults->groupResults[$ig]['subsite']);
 398                    if ($this->asCfg->isAjax) $varPaging1['pagingPrev'] = 'javascript:void(0);';
 399                    else {
 400                        $ofst = (string)$ig . ',' . (string)$prevOffset;
 401                        $asOffset = ($otherOffset) ? $otherOffset . ',' . $ofst : $ofst;
 402                        $asOffset = '&aso=' . $asOffset;
 403                        $paramsUrl = $url . $asOffset;
 404                        $varPaging1['pagingPrev'] = $modx->makeUrl($modx->documentIdentifier, '', $paramsUrl);
 405                        }
 406                }
 407                else $varPaging1['showPrev'] = 0;
 408                $varPaging1['pagingStart'] = $offset+1;
 409                $varPaging1['pagingEnd'] = ($offset + $nbMax > $nbrs) ? $nbrs : $offset + $nbMax;
 410                $varPaging1['pagingNb'] = $nbrs;
 411
 412                if ($offset + $nbMax < $nbrs) {
 413                    $varPaging1['showNext'] = 1;
 414                    $nextOffset = $offset + $nbMax;
 415                     $prefix = ($this->asCfg->cfg['asId']) ? $this->asCfg->cfg['asId'] . "_" : '';
 416                    $varPaging1['next_grpResultId'] = $prefix . 'next_' . $this->_getCleanCssId($this->asResults->groupResults[$ig]['subsite']);
 417                    if ($this->asCfg->isAjax) $varPaging1['pagingNext'] = 'javascript:void(0);';
 418                    else {
 419                        $nrp = $nrp + 1;
 420                        $ofst = (string)$ig . ',' . (string)$nextOffset;
 421                        $asOffset = ($otherOffset) ? $otherOffset . ',' . $ofst : $ofst;
 422                        $asOffset = '&aso=' . $asOffset;
 423                        $paramsUrl = $url . $asOffset;
 424                        $varPaging1['pagingNext'] = $modx->makeUrl($modx->documentIdentifier, '', $paramsUrl);
 425                        }
 426                }
 427                else $varPaging1['showNext'] = 0;
 428
 429                $chkPaging->AddVar("as", $varPaging1);
 430                $footer = $chkPaging->Render();
 431                unset($varPaging1);
 432                $chkPaging->CleanVars();
 433            }
 434            elseif (($pagingType == 2) && ($nbrs >= $nbMax) && ($this->asCfg->isAjax)) {
 435
 436                $tplPaging = $this->asCfg->cfg['tplPaging2'];
 437                if ($tplPaging == '') $tplPaging = "@FILE:" . AS_SPATH . 'templates/paging2.tpl.html';
 438
 439                $chkPaging = new AsPhxParser($tplPaging);
 440                if ($this->dbgTpl) $this->asUtil->dbgRecord($chkPaging->getTemplate($tplPaging), "tplPaging template " . $tplPaging);
 441                $varPaging2 = array();
 442                $varPaging2['pagingStart'] = $offset+1;
 443                $varPaging2['pagingEnd'] = ($offset + $nbMax > $nbrs) ? $nbrs : $offset + $nbMax;
 444                $varPaging2['pagingNb'] = $nbrs;
 445
 446                if ($offset + $nbMax < $nbrs) {
 447                    $varPaging2['showMore'] = 1;
 448                    $nextOffset = $offset + $nbMax;
 449                    $prefix = ($this->asCfg->cfg['asId']) ? $this->asCfg->cfg['asId'] . "_" : '';
 450                    $varPaging2['more_grpResultId'] = $prefix . 'more_' . $this->_getCleanCssId($this->asResults->groupResults[$ig]['subsite']);
 451                    $varPaging2['pagingMore'] = 'javascript:void(0);';
 452                    $paging2Text = $this->asCfg->lang['as_paging2Text'];
 453                    $varPaging2['pagingText'] = sprintf($paging2Text, NB_MORE_RESULTS);
 454                }
 455                else $varPaging2['showMore'] = 0;
 456
 457                $chkPaging->AddVar("as", $varPaging2);
 458                $footer = $chkPaging->Render();
 459                unset($varPaging2);
 460                $chkPaging->CleanVars();
 461            }
 462        }
 463        return $footer;
 464    }
 465    /*
 466    * Set the more results link
 467    */
 468    function _setMoreResultsLink($nbrs) {
 469        global $modx;
 470        $ajaxMax = $this->asCfg->cfg['ajaxMax'];
 471
 472        if (($this->asCfg->cfg['moreResultsPage'] || $this->asCfg->cfg['showMoreResults']) && ($ajaxMax < $nbrs)) {
 473            $this->varResults['moreResults'] = 1;
 474            $this->varResults['moreClass'] = 'AS_ajax_more';
 475            $url = $this->_getParamsUrl();
 476            $this->varResults['moreLink'] = $modx->makeUrl($this->asCfg->cfg['moreResultsPage'], '', $url);
 477            $this->varResults['moreTitle'] = $this->asCfg->lang['as_moreResultsTitle'];
 478            $this->varResults['moreText'] = $this->asCfg->lang['as_moreResultsText'];
 479        }
 480    }
 481    /*
 482    * Get a clean css Id
 483    */
 484    function _getCleanCssId($name) {
 485        $name = preg_replace('/\s+\|\|\s+/','_',trim($name));
 486        $name = preg_replace('/\s+/','_',$name);
 487        return $name;
 488    }
 489    /*
 490    * Get the parameters to set up an URL
 491    */
 492    function _getParamsUrl() {
 493        global $modx;
 494        $firstarg = $modx->config['friendly_urls'] ? '?' : '&';
 495        $url = '';
 496
 497        if ($this->asCfg->cfg['asId']) $url = $firstarg . 'asid=' . urlencode($this->asCfg->cfg['asId']);
 498
 499        if ($this->asCtrl->searchString) {
 500            if ($url) $url .= '&search=' . urlencode($this->asCtrl->searchString) . '&amp;advsearch=' . urlencode($this->asCtrl->advSearch);
 501            else $url = $firstarg . 'search=' . urlencode($this->asCtrl->searchString) . '&amp;advsearch=' . urlencode($this->asCtrl->advSearch);
 502        }
 503        if ($this->asCtrl->subSearch) {
 504            if ($url) $url .=  '&amp;subsearch=' . urlencode($this->asCtrl->subSearch);
 505            else $url = $firstarg . 'subsearch=' . urlencode($this->asCtrl->subSearch);
 506        }
 507        if ($this->asCtrl->asf) {
 508            if ($url) $url .=  '&amp;asf=' . urlencode($this->asCtrl->asf);
 509            else $url = $firstarg . 'asf=' . urlencode($this->asCtrl->asf);
 510            foreach($this->asCtrl->fParams as $key =>$value) {
 511                $url .= '&amp;' . $key . '=' . urlencode($value);
 512            }
 513        }
 514        return $url;
 515    }
 516    /*
 517    * Initialize common chunks variables
 518    */
 519    function _initCommonChunks() {
 520        global $modx;
 521
 522        if (!class_exists('AsPhxParser')) include_once AS_PATH . "classes/asPhxParser.class.inc.php";
 523        if (!$this->asCfg->isAjax) {
 524
 525            $tplResults = $this->asCfg->cfg['tplResults'];
 526            if ($tplResults == '') $tplResults = "@FILE:" . AS_SPATH . 'templates/results.tpl.html';
 527        } else {
 528
 529            $tplResults = $this->asCfg->cfg['tplAjaxResults'];
 530            // if @FILE binding was passed in via ajax processor, verify the path is safe
 531            if(stristr($tplResults, '@FILE:') !== false) {
 532                $path = substr($tplResults, 6);
 533                $frombase = $modx->config['base_path'] . $path;
 534                $dirname = dirname($frombase);
 535                $as_expected_dirname = $modx->config['base_path'] . AS_SPATH . 'templates';
 536                if(strpos($dirname, $as_expected_dirname) === false) {
 537                    $path = str_replace('..', '', $path);
 538                    $path = str_replace('\\', '/', $path);
 539                    if(substr($path, 0, 1) == '/') $path = substr($path, 1);
 540                    $tplResults = '@FILE:templates/' . $path;
 541                }
 542                if(!file_exists($as_expected_dirname . '/' . $path)) {
 543                    $tplResults = '';
 544                }
 545            }
 546            if ($tplResults == '') $tplResults = "@FILE:" . AS_SPATH . 'templates/ajaxResults.tpl.html';
 547        }
 548
 549        $this->chkResults = new AsPhxParser($tplResults);
 550        if ($this->dbgTpl) {
 551            $this->asUtil->dbgRecord($this->chkResults->getTemplate($tplResults), "tplResults template" . $tplResults);
 552        }
 553    }
 554    /*
 555    * Initialize chunks variables - config dependent
 556    */
 557    function _initChunks() {
 558        if (!$this->asCfg->isAjax) {
 559
 560            $tplGrpResult = $this->asCfg->cfg['tplGrpResult'];
 561            if ($tplGrpResult == '') $tplGrpResult = "@FILE:" . AS_SPATH . 'templates/grpResult.tpl.html';
 562
 563            $tplResult = $this->asCfg->cfg['tplResult'];
 564            if ($tplResult == '') $tplResult = "@FILE:" . AS_SPATH . 'templates/result.tpl.html';
 565        } else {
 566
 567            $tplGrpResult = $this->asCfg->cfg['tplAjaxGrpResult'];
 568            if ($tplGrpResult == '') $tplGrpResult = "@FILE:" . AS_SPATH . 'templates/ajaxGrpResult.tpl.html';
 569
 570            $tplResult = $this->asCfg->cfg['tplAjaxResult'];
 571            if ($tplResult == '') $tplResult = "@FILE:" . AS_SPATH . 'templates/ajaxResult.tpl.html';
 572        }
 573        $this->chkGrpResult = new AsPhxParser($tplGrpResult);
 574        $this->tplGrpRes = "@CODE:" . $this->chkGrpResult->template;
 575        $this->chkResult = new AsPhxParser($tplResult);
 576        $this->tplRes = "@CODE:" . $this->chkResult->template;
 577        if ($this->dbgTpl) {
 578            $this->asUtil->dbgRecord($this->chkGrpResult->getTemplate($tplGrpResult), "tplGrpResult template" . $tplGrpResult);
 579            if ($this->chkResults) $this->asUtil->dbgRecord($this->chkResults->getTemplate($tplResult), "tplResult template " . $tplResult);
 580        }
 581    }
 582    /*
 583    * Set the offset of groups (used only for non-ajax mode)
 584    */
 585    function _setOffset() {
 586        $offset_array = explode(',', $this->asCtrl->offset);
 587        $io = count($offset_array);
 588        for ($i = 0;$i < $io;$i = $i + 2) {
 589            $ig = intval($offset_array[$i]);
 590            $ig = (($ig >= 0) && ($ig < $this->asResults->nbGroups)) ? $ig : 0;
 591            $val = intval($offset_array[$i + 1]);
 592            $val = (($val > 0) && ($val < $this->asResults->groupResults[$ig]['length'])) ? $val : 0;
 593            $this->asResults->groupResults[$ig]['offset'] = $val;
 594        }
 595    }
 596    /*
 597    * Get the search context
 598    */
 599    function _getSearchContext() {
 600        $searchContext = $this->asResults->getSearchContext();
 601        $this->scMain = $searchContext['main'];
 602        $this->scJoined = $searchContext['joined'];
 603        $this->scTvs = $searchContext['tvs'];
 604    }
 605    /*
 606    * Initialize variables used for the display - config context dependent
 607    */
 608    function _initDisplayVariables() {
 609        $this->_initChunks();
 610        $this->_initBreadcrumbs();
 611    }
 612    /*
 613    * Set log infos into DB for failed searches
 614    */
 615    function _setFailedSearches($asCall = '', $select = '') {
 616        $logid = '';
 617        if ($this->log >= 1 ) {
 618            $logInfo = array();
 619            $logInfo['searchString'] = $this->asCtrl->searchString;
 620            $logInfo['nbResults'] = 0;
 621            $logInfo['results'] = '';
 622            $logInfo['asCall'] = $asCall;
 623            $logInfo['asSelect'] = mysql_real_escape_string($select);
 624            $logid = $this->asLog->setLogRecord($logInfo);
 625        }
 626        return $logid;
 627    }
 628    /*
 629    * Set log infos into DB for successfull searches
 630    */
 631    function _setSuccessfullSearches($ig) {
 632        $logid = '';
 633        if ($this->log == 2) {
 634            $logInfo = array();
 635            $logInfo['searchString'] = $this->asCtrl->searchString;
 636            $logInfo['nbResults'] = $this->asResults->groupResults[$ig]['length'];
 637            $logInfo['results'] = $this->asResults->groupResults[$ig]['found'];
 638            $logInfo['asCall'] = $this->_getAsCall($this->asResults->groupResults[$ig]['ucfg']);
 639            $logInfo['asSelect'] = mysql_real_escape_string($this->asResults->groupResults[$ig]['select']);
 640            $logid = $this->asLog->setLogRecord($logInfo);
 641        }
 642        return $logid;
 643    }
 644    /*
 645    * Get the AjaxSearch snippet call
 646    */
 647    function _getAsCall($ucfg) {
 648        $call_array = explode(' ', $ucfg);
 649        $tpl = "&%s=`%s`";
 650        if ($this->asCtrl->advSearch != ONEWORD) $call_array[] = sprintf($tpl, 'advSearch', $this->asCtrl->advSearch);
 651        $asCall = "[!AjaxSearch";
 652        if (count($call_array)) {
 653            $asCall.= "? ";
 654            $asCall.= implode(' ', $call_array);
 655        }
 656        $asCall.= "!]";
 657        return $asCall;
 658    }
 659    /*
 660    *  Set all the displayed fields as PHx
 661    */
 662    function _setResultDisplayed($row) {
 663
 664        $id = $this->scMain['id'];
 665        $this->varResult[$id] = $row[$id];
 666
 667        if (isset($this->scMain['date'])) {
 668            foreach ($this->scMain['date'] as $field) $this->_setPhxField($field, $row, 'date');
 669        }
 670
 671        foreach ($this->scMain['displayed'] as $field) $this->_setPhxField($field, $row, 'string');
 672
 673        if (isset($this->scTvs['names'])) foreach ($this->scTvs['names'] as $field) {
 674            if (isset($row[$field])) $this->_setPhxField($field, $row, 'string');
 675        }
 676
 677        if ($this->scMain['append']) foreach ($this->scMain['append'] as $field) {
 678            if (isset($row[$field])) $this->_setPhxField($field, $row, 'string');
 679        }
 680
 681        if (isset($this->scJoined)) foreach ($this->scJoined as $joined) {
 682            $f = $joined['tb_alias'] . '_' . $id;
 683            $this->_setPhxField($f, $row, 'string');
 684        }
 685
 686        if (isset($this->scJoined)) foreach ($this->scJoined as $joined) {
 687            foreach ($joined['displayed'] as $field) {
 688                $f = $joined['tb_alias'] . '_' . $field;
 689                $this->_setPhxField($f, $row, 'string');
 690            }
 691        }
 692
 693        if ($this->asCfg->cfg['rank']) $this->_setPhxField('rank', $row, 'int');
 694        return $row[$id];
 695    }
 696    /*
 697    *  Set a field as PHx
 698    */
 699    function _setPhxField($field, $row, $type = 'string') {
 700        $showField = $field . "Show";
 701        $classField = $field . "Class";
 702        $contentField = $row[$field];
 703        if ($contentField != '') {
 704            $this->varResult[$showField] = 1;
 705            $this->varResult[$classField] = $this->asClass['prefix'] . ucfirst($field);
 706            if ($type == 'string') {
 707                $this->varResult[$field] = $this->asResults->cleanText($contentField, $this->asCfg->cfg['stripOutput']);
 708            } elseif ($type == 'date') {
 709                $this->varResult[$field] = date($this->asCfg->cfg['formatDate'], $contentField);
 710            } else {
 711                $this->varResult[$field] = $contentField;
 712            }
 713        } else {
 714            $this->varResult[$showField] = 0;
 715        }
 716    }
 717    /*
 718    *  Set the ResultLink PHx
 719    */
 720    function _setResultLink($row) {
 721        global $modx;
 722        $id = $this->scMain['id'];
 723        if (!$row[$id]) {
 724            return;
 725        }
 726        $hClass = $this->asClass['highlight'];
 727        if ($this->asCfg->cfg['highlightResult'] && $hClass) {
 728            $resultLink = $modx->makeUrl($row[$id], '', 'searched=' . urlencode($this->asCtrl->searchString) . '&amp;advsearch=' . urlencode($this->asCtrl->advSearch) . '&amp;highlight=' . urlencode($hClass));
 729        } else {
 730            $resultLink = $modx->makeUrl($row[$id]);
 731        }
 732        $this->varResult['resultClass'] = $this->asClass['prefix'];
 733        $this->varResult['resultLinkClass'] = $this->asClass['prefix'] . 'Link';
 734        $this->varResult['resultLink'] = $resultLink;
 735    }
 736    /*
 737    *  Set the ResultExtract PHx
 738    */
 739    function _setResultExtract($row) {
 740        if ($this->asResults->extractNb) {
 741            $this->varResult['extractShow'] = 1;
 742            $this->varResult['extractClass'] = $this->asClass['prefix'] . 'Extract';
 743            $this->varResult['extract'] = $this->asResults->getExtractRow($row);
 744        } else {
 745            $this->varResult['extractShow'] = 0;
 746        }
 747    }
 748    /*
 749    *  Set the ResultBreadcrumbs PHx
 750    */
 751    function _setResultBreadcrumbs($row) {
 752        global $modx;
 753        if ($this->asCfg->cfg['breadcrumbs']) {
 754            if ($this->asCfg->cfg['bCrumbsInfo']['type'] == 'function') {
 755
 756                $bc = $this->asCfg->cfg['bCrumbsInfo']['name']($this->scMain, $row, $this->asCfg->cfg['bCrumbsInfo']['params']);
 757            } elseif ($this->asResults->getWithContent()) {
 758
 759
 760                $current_id = $modx->documentObject['id'];
 761                $current_parent = $modx->documentObject['parent'];
 762                $current_pagetitle = $modx->documentObject['pagetitle'];
 763                $current_longtitle = $modx->documentObject['longtitle'];
 764                $current_menutitle = $modx->documentObject['menutitle'];
 765                $current_description = $modx->documentObject['description'];
 766
 767                $id = $this->scMain['id'];
 768                $modx->documentObject['id'] = $row[$id];
 769                $parentIds = $modx->getParentIds($row[$id], 1);
 770                $pid = array_pop($parentIds);
 771                $modx->documentObject['parent'] = $pid;
 772                $modx->documentObject['pagetitle'] = $row['pagetitle'];
 773                $modx->documentObject['longtitle'] = $row['longtitle'];
 774                $modx->documentObject['menutitle'] = $row['menutitle'];
 775                $modx->documentObject['description'] = $row['description'];
 776
 777                $bc = $modx->runSnippet($this->asCfg->cfg['bCrumbsInfo']['name'], $this->asCfg->cfg['bCrumbsInfo']['params']);
 778
 779                $modx->documentObject['id'] = $current_id;
 780                $modx->documentObject['parent'] = $current_parent;
 781                $modx->documentObject['pagetitle'] = $current_pagetitle;
 782                $modx->documentObject['longtitle'] = $current_longtitle;
 783                $modx->documentObject['menutitle'] = $current_menutitle;
 784                $modx->documentObject['description'] = $current_description;
 785            }
 786
 787            $this->varResult['breadcrumbsShow'] = 1;
 788            $this->varResult['breadcrumbsClass'] = $this->asClass['prefix'] . 'Breadcrumbs';
 789            $this->varResult['breadcrumbs'] = $bc;
 790        } else {
 791            $this->varResult['breadcrumbsShow'] = 0;
 792        }
 793    }
 794    /*
 795    *  Set number of result as PHx
 796    */
 797    function _setResultNumber($no) {
 798        $this->varResult['resultNumber'] = $no;
 799    }
 800    /*
 801    * Initialize the breadcrumbs variables
 802    */
 803    function _initBreadcrumbs() {
 804        if ($this->asCfg->cfg['breadcrumbs']) {
 805            $bc = explode(',', $this->asCfg->cfg['breadcrumbs']);
 806            if (function_exists($bc[0])) {
 807                $this->asCfg->cfg['bCrumbsInfo']['type'] = 'function';
 808            } elseif ($this->_snippet_exists($bc[0])) {
 809                $this->asCfg->cfg['bCrumbsInfo']['type'] = 'snippet';
 810            } else {
 811                $this->asCfg->cfg['breadcrumbs'] = false;
 812            }
 813            if ($this->asCfg->cfg['breadcrumbs']) {
 814                $this->asCfg->cfg['bCrumbsInfo']['name'] = array_shift($bc);
 815                $this->asCfg->cfg['bCrumbsInfo']['params'] = array();
 816                foreach ($bc as $prm) {
 817                    $param = explode(':', $prm);
 818                    $this->asCfg->cfg['bCrumbsInfo']['params'][$param[0]] = (isset($param[1]) ? $param[1] : 0);
 819                }
 820            }
 821        }
 822    }
 823    /*
 824    * Check the existing of a snippet
 825    */
 826    function _snippet_exists($snippetName) {
 827        global $modx;
 828        $tbl = $modx->getFullTableName('site_snippets');
 829        $select = "SELECT * FROM " . $tbl . " WHERE " . $tbl . ".name='" . $modx->db->escape($snippetName) . "';";
 830        $rs = $modx->db->query($select);
 831        return $modx->recordCount($rs);
 832    }
 833    /*
 834    * Get offset of other groups
 835    */
 836    function _getOtherOffset($ig) {
 837        $otherOffset = array();
 838        for ($i = 0;$i < $this->asResults->nbGroups;$i++) {
 839            if (($i != $ig) && ($this->asResults->groupResults[$i]['offset'] != 0)) {
 840                $otherOffset[] = (string)$i . ',' . (string)$this->asResults->groupResults[$i]['offset'];
 841            }
 842        }
 843        $output = implode(',', $otherOffset);
 844        return $output;
 845    }
 846    /*
 847    * Set the needsConvert flag value
 848    */
 849    function setNeedsConvert($flag) {
 850        $this->_needsConvert = $flag;
 851    }
 852    /*
 853    *  initClassVariables : initialize the required Class values
 854    */
 855    function initClassVariables() {
 856
 857        if ($this->asCfg->cfg['ajaxSearch']) $this->asClass['prefix'] = PREFIX_AJAX_RESULT_CLASS;
 858        else $this->asClass['prefix'] = PREFIX_RESULT_CLASS;
 859
 860        $this->asClass['highlight'] = $this->_getHighlightClass($this->asCtrl->searchString, $this->asCtrl->advSearch);
 861    }
 862    /*
 863    *  Depending the search words, set up the highlight classes
 864    */
 865    function _getHighlightClass($search, $advSearch) {
 866        $hClass = '';
 867        $searchList = $this->asCtrl->getSearchWords($search, $advSearch);
 868        if (count($searchList)) {
 869            $hClass = HIGHLIGHT_CLASS;
 870            $count = 1;
 871            foreach ($searchList as $searchTerm) {
 872                $hClass.= ' ' . HIGHLIGHT_CLASS . $count;
 873                $count++;
 874            }
 875        }
 876        return $hClass;
 877    }
 878    function getHClass() {
 879        return HIGHLIGHT_CLASS;
 880    }
 881    /*
 882    * Set the ajax header with the appropriate variables
 883    */
 884    function setAjaxSearchHeader() {
 885        global $modx;
 886        $typeAs = $this->asCfg->cfg['ajaxSearch'];
 887        if ($typeAs) {
 888
 889            if ($this->asCfg->cfg['jscript'] == 'jquery') {
 890                if ($this->asCfg->cfg['addJscript']) $modx->regClientStartupScript($this->asCfg->cfg['jsJquery']);
 891                $jsInclude = AS_SPATH . AJAXSEARCH_JSDIR . $typeAs . '/ajaxSearch-jquery.js';
 892            } elseif ($this->asCfg->cfg['jscript'] == 'mootools2') {
 893                if ($this->asCfg->cfg['addJscript']) $modx->regClientStartupScript($this->asCfg->cfg['jsMooTools2']);
 894                $jsInclude = AS_SPATH . AJAXSEARCH_JSDIR . $typeAs . '/ajaxSearch-mootools2.js';
 895            } else {
 896                if ($this->asCfg->cfg['addJscript']) $modx->regClientStartupScript($this->asCfg->cfg['jsMooTools']);
 897                $jsInclude = AS_SPATH . AJAXSEARCH_JSDIR . $typeAs . '/ajaxSearch.js';
 898            }
 899            $modx->regClientStartupScript($jsInclude);
 900
 901            $json = '{"vsn":"' . AS_VERSION . '"';
 902            $json.= ',"adv":"' . $this->asCtrl->advSearch . '"';
 903            $json.= ',"sub":"' . $this->asCtrl->subSearch . '"';
 904            $json.= ',"bxt":"' . addslashes($this->asCfg->lang['as_boxText']) . '"';
 905            $json.= ',"cfg":"' . addslashes($this->asCfg->setAsCall($this->asCfg->ucfg)) . '"}';
 906            $line = (!$this->asCfg->cfg['asId']) ? "asvar=new Array();asvar[0]='{$json}';" : "asvar[asvar.length]='{$json}';";
 907            $jsVars = <<<EOD
 908<!-- start AjaxSearch header -->
 909<script type="text/javascript">
 910//<![CDATA[
 911{$line}
 912//]]>
 913</script>
 914<!-- end AjaxSearch header -->
 915EOD;
 916            $modx->regClientStartupScript($jsVars);
 917        }
 918    }
 919    /*
 920    *  Display Comment form
 921    */
 922    function _displayComment() {
 923        $outputComment = '';
 924        if ($this->asLog->logcmt && count($this->logIds)) {
 925            $chkCmt = new AsPhxParser($this->asCfg->cfg['tplComment']);
 926            if ($this->dbgTpl) $this->asUtil->dbgRecord($chkCmt->getTemplate($this->asCfg->cfg['tplComment']), "tplComment template " . $this->asCfg->cfg['tplComment']);
 927            $varCmt = array();
 928            $varCmt['hiddenFieldIntro'] = $this->asCfg->lang['as_cmtHiddenFieldIntro'];
 929            $varCmt['hiddenField'] = 'ajaxSearch_cmtHField';
 930            $varCmt['logid'] = array_pop($this->logIds);
 931            $varCmt['cmtIntroMessage'] = $this->asCfg->lang['as_cmtIntroMessage'];
 932            $varCmt['cmtSubmitText'] = $this->asCfg->lang['as_cmtSubmitText'];
 933            $varCmt['cmtResetText'] = $this->asCfg->lang['as_cmtResetText'];
 934            $varCmt['cmtThksMessage'] = $this->asCfg->lang['as_cmtThksMessage'];
 935
 936            $chkCmt->AddVar("as", $varCmt);
 937            $outputComment = $chkCmt->Render();
 938        }
 939        return $outputComment;
 940    }
 941    /*
 942    * paginate : display the previous / next page of results
 943    */
 944    function paginate($validSearch, &$msgErr) {
 945        $ouputResults = null;
 946        if ($validSearch) {
 947            list($ig, $currentOffset, $sens) = explode(',',$this->asCtrl->pagination);
 948            $this->_getSearchContext();
 949            $site = $this->asResults->groupResults[$ig]['site'];
 950            $subsite = $this->asResults->groupResults[$ig]['subsite'];
 951            $display = $this->asResults->groupResults[$ig]['display'];
 952            $nbrs = intval($this->asResults->groupResults[$ig]['length']);
 953            $ajaxMax = ($this->asCfg->cfg['ajaxMax'] > 0) ? $this->asCfg->cfg['ajaxMax'] : $nbrs;
 954            $pagingType = $this->asCfg->cfg['pagingType'];
 955
 956            // nb results displayed
 957            if ($pagingType == 1) {
 958                if ($sens == 1) {
 959                    $offset = $currentOffset + $ajaxMax;
 960                    $nbRes = ($offset + $ajaxMax > $nbrs) ? $nbrs - $offset : $ajaxMax;
 961                }
 962                else {
 963                    $offset = $currentOffset - $ajaxMax;
 964                    $offset = ($offset >= 0) ? $offset : 0;
 965                    $nbRes = $ajaxMax;
 966                }
 967            }
 968            elseif ($pagingType == 2) {
 969                if ($sens > 0) {
 970                    if ($currentOffset == 0) $currentNbRes = $ajaxMax;
 971                    else $currentNbRes = NB_MORE_RESULTS;
 972                    $offset = $currentOffset + $currentNbRes;
 973                    $nbRes = ($offset + NB_MORE_RESULTS > $nbrs) ? $nbrs - $offset : NB_MORE_RESULTS;
 974                }
 975                else {
 976                    if ($currentOffset == $ajaxMax) $previousNbRes = $ajaxMax;
 977                    else $previousNbRes = NB_MORE_RESULTS;
 978                    $offset = $currentOffset - $previousNbRes;
 979                    $offset = ($offset >= 0) ? $offset : 0;
 980                    $nbRes = $previousNbRes;
 981                }
 982            }
 983
 984            $searchResults = array_slice($this->asResults->groupResults[$ig]['results'], $offset, $nbRes);
 985
 986            $this->asCfg->chooseConfig($site, $subsite, $display);
 987            $this->_initDisplayVariables();
 988
 989            $jsonPairs = array();
 990            if ($pagingType == 1) {  // Prev / Next links
 991                $grpResult = $this->_displayGrpResult($ig, $site, $subsite, $display, $nbrs, $searchResults, $offset, $nbRes);
 992                $jsonPairs[] = $this->_getJsonPair('res',$grpResult);
 993            }
 994            elseif ($pagingType == 2) {
 995                $found = array();
 996                $this->chkGrpResult = new AsPhxParser($this->tplGrpRes);
 997
 998                $moreOffset = 0;
 999                $moreNbMax = $offset + $nbRes;
1000                $header = $this->_displayHeaderGrpResult($site, $subsite, $display, $nbrs, $searchResults, $moreOffset, $moreNbMax);
1001                $listResults = $this->_displayListResults($site, $subsite, $display, $nbrs, $searchResults, $found, $offset);
1002                $footer = $this->_displayFooterGrpResult($ig, $nbrs, $moreOffset, $moreNbMax);
1003
1004                $this->asResults->groupResults[$ig]['found'] = implode(' ',$found);
1005                $jsonPairs[] = $this->_getJsonPair('hdr',$header);
1006                $jsonPairs[] = $this->_getJsonPair('res',$listResults);
1007                $jsonPairs[] = $this->_getJsonPair('ftr',$footer);
1008            }
1009            $pgn = (string)$ig . ',' . (string)$offset;
1010            $jsonPairs[] = $this->_getJsonPair('pgn',$pgn);
1011
1012            $this->_updateAsfPaginate($ig, $jsonPairs);
1013
1014            $outputResults = $this->_getJson($jsonPairs);
1015
1016            $this->asCfg->restoreConfig(DEFAULT_SITE, DEFAULT_SUBSITE);
1017        }
1018        return $outputResults;
1019    }
1020    /*
1021    * Send back categories & tags
1022    */
1023    function _updateAsfPaginate($ig, & $jsonPairs) {
1024
1025        $resultsCateg = array();
1026        $resultsCateg = $this->asResults->getResultsCateg();
1027
1028        $ctgnm = array();
1029        $ctgnm[] = $resultsCateg['name'][$ig];
1030        if ($this->dbgRes) $this->asUtil->dbgRecord($resultsCateg, "getResultsCateg");
1031        $sctgnm = $this->_getJsonArray($ctgnm);
1032        $jsonPairs[] = $this->_getJsonPair('ctgnm',$sctgnm);
1033
1034        return;
1035    }
1036    /*
1037    * Send back categories
1038    */
1039    function _updateAsf( & $jsonPairs) {
1040
1041        $resultsCateg = array();
1042        $resultsCateg = $this->asResults->getResultsCateg();
1043        if ($this->dbgRes) $this->asUtil->dbgRecord($resultsCateg, "getResultsCateg");
1044
1045        $ctgnm = $this->_getJsonArray($resultsCateg['name']);
1046        $jsonPairs[] = $this->_getJsonPair('ctgnm',$ctgnm);
1047        $ctgnb = $this->_getJsonArray($resultsCateg['nb']);
1048        $jsonPairs[] = $this->_getJsonPair('ctgnb',$ctgnb);
1049
1050        return;
1051    }
1052    /*
1053    * Prepare json array of String
1054    * ["art","music","geography"]
1055    */
1056    function _getJsonArray($array) {
1057        $nbr = count($array);
1058        if ($nbr) $jsonArray = '[' . implode(',',$array) . ']';
1059        else $jsonArray = '';
1060        return $jsonArray;
1061    }
1062    /*
1063    * Prepare json pair key : value
1064    */
1065    function _getJsonPair($key,$value) {
1066        $value = addslashes($value);
1067        $value = str_replace(array("\r\n", "\r", "\n"), ' ', $value);
1068        $jsonPair = '"' . $key . '":"' . $value . '"';
1069        return $jsonPair;
1070    }
1071    /*
1072    * Prepare json string
1073    */
1074    function _getJson($pairs) {
1075        $json = '{' . implode(',',$pairs) . '}';
1076        return $json;
1077    }
1078}
1079?>