HomeHelpTrac

source: tags/6.1/search.php @ 10283

Revision 10283, 15.9 KB checked in by Andrey Prikaznov, 3 years ago (diff)
Line 
1<?php
2
3require_once( './inc/header.inc.php' );
4require_once( BX_DIRECTORY_PATH_INC     . 'admin.inc.php' );
5require_once( BX_DIRECTORY_PATH_INC     . 'db.inc.php' );
6require_once( BX_DIRECTORY_PATH_INC     . 'members.inc.php' );
7require_once( BX_DIRECTORY_PATH_CLASSES . 'BxDolProfileFields.php' );
8require_once( BX_DIRECTORY_PATH_CLASSES . 'BxDolProfilesController.php' );
9
10$bEnZipSearch = getParam("enable_zip_loc") == "on" ? 1 : 0;
11if ( $bEnZipSearch )
12    require_once( BX_DIRECTORY_PATH_INC . 'RadiusAssistant.inc' );
13
14$_page['name_index'] = 4;
15$_page['css_name']   = 'search.css';
16
17check_logged();
18
19
20// get search mode
21if( $_REQUEST['search_mode'] )
22    $sSearchMode = $_REQUEST['search_mode'];
23else
24    $sSearchMode = 'simple';
25
26switch( $_REQUEST['search_mode'] ) {
27    case 'quick':
28        $iPFArea = 10;
29        $_page['header_text'] = $sPageHeader = _t( '_Quick Search' );
30    break;
31   
32    case 'adv':
33        $iPFArea = 11;
34        $_page['header_text'] = $sPageHeader = _t( '_Advanced Search' );
35    break;
36   
37    default:
38        $iPFArea = 9;
39        $sSearchMode = 'simple';
40        $_page['header_text'] = $sPageHeader = _t( '_Simple Search' );
41}
42
43
44//collect inputs
45$oPF = new BxDolProfileFields($iPFArea);
46$aRequestParams = $oPF -> collectSearchRequestParams();
47
48if( isset( $_REQUEST['ID'] ) and (int)$_REQUEST['ID'] )
49    $aRequestParams['ID'] = (int)$_REQUEST['ID'];
50
51if( isset( $_REQUEST['NickName'] ) and trim( $_REQUEST['NickName'] ) )
52    $aRequestParams['NickName'] = trim( process_pass_data( $_REQUEST['NickName'] ) );
53
54if( isset( $_REQUEST['Tags'] ) and trim( $_REQUEST['Tags'] ) )
55    $aRequestParams['Tags'] = trim( process_pass_data( $_REQUEST['Tags'] ) );
56
57if( isset( $_REQUEST['distance'] ) and (int)$_REQUEST['distance'] )
58    $aRequestParams['distance'] = (int)$_REQUEST['distance'];
59
60// start page generation
61ob_start();
62
63$bShowForms = false;
64//echoDbg($aRequestParams);
65if( !empty( $aRequestParams ) or $_REQUEST['online_only'] )
66    PageCodeSearchResult( $aRequestParams );
67else {
68    PageCodeSearchForm();
69    $bShowForms = true;
70}
71
72
73$_ni = $_page['name_index'];
74
75$_page_cont[$_ni]['page_main_code']   = ob_get_clean();
76
77$_page_cont[$_ni]['search_by_id']     = $bShowForms ? PageCodeSearchByID()   : '';
78$_page_cont[$_ni]['search_by_nick']   = $bShowForms ? PageCodeSearchByNick() : '';
79$_page_cont[$_ni]['search_by_tag']    = $bShowForms ? PageCodeSearchByTag()  : '';
80
81PageCode();
82
83
84function PageCodeSearchForm() {
85    global $oPF;
86    global $sPageHeader;
87    global $sSearchMode;
88   
89    ob_start();
90    ?>
91<form method="GET" action="<?= $_SERVER['PHP_SELF'] ?>">
92    <table class="search_form" cellspacing="0">
93    <?
94   
95    foreach( $oPF -> aBlocks as $aBlock ) {
96        ?>
97        <tr class="search_form_block">
98            <th colspan="2"><?= _t( $aBlock['Caption'] ) ?></th>
99        </tr>
100        <?
101       
102        foreach( $aBlock['Items'] as $aItem ) {
103            ?>
104        <tr class="search_form_row">
105            <td class="search_form_caption"><?= _t( $aItem['Caption'] ) ?>:</td>
106            <td class="search_form_value">
107            <?
108       
109           
110            //draw the control
111            switch( $aItem['Type'] ) {
112                case 'text':
113                case 'area':
114                    ?>
115                    <input type="text" name="<?= $aItem['Name'] ?>" class="input_text" />
116                    <?
117                break;
118               
119                case 'date':
120                case 'range':
121                case 'num':
122                    echo _t( '_From' );
123                    ?>
124                    <input type="text" name="<?= $aItem['Name'] ?>[0]" class="input_date" />
125                    <?
126                    echo _t( '_To' );
127                    ?>
128                    <input type="text" name="<?= $aItem['Name'] ?>[1]" class="input_date" />
129                    <?
130                break;
131               
132                case 'select_one':
133                case 'select_set':
134                    switch ( $aItem['Control'] ) {
135                        case 'select':
136                            ?>
137                    <select name="<?= $aItem['Name'] ?>[]" multiple="multiple" class="input_select">
138                        <?= SelectOptions( $aItem['Name'] ) ?>
139                    </select>
140                            <?
141                        break;
142                       
143                        case 'radio':
144                        case 'checkbox':
145                            $aValues = getFieldValues( $aItem['Name'] );
146                           
147                            foreach( $aValues as $sKey => $sValue ) {
148                                ?>
149                    <input type="checkbox" name="<?= $aItem['Name'] ?>[]" value="<?= $sKey ?>" id="<?= $aItem['Name'] ?>_<?= $sKey ?>" />
150                    <label for="<?= $aItem['Name'] ?>_<?= $sKey ?>"><?= _t( $sValue ) ?></label>
151                                <?
152                            }
153                        break;
154                    }
155                break;
156               
157                case 'bool':
158                    ?>
159                    <input type="checkbox" name="<? $aItem['Name'] ?>" value="1" />
160                    <?
161                break;
162               
163                case 'system':
164                    switch( $aItem['Name'] ) {
165                        case 'Couple':
166                            ?>
167                    <input type="checkbox" name="Couple[0]" value="1" id="Couple_0" />
168                    <label for="Couple_0"><?= _t( '_Single' ) ?></label>
169                    <input type="checkbox" name="Couple[1]" value="1" id="Couple_1" />
170                    <label for="Couple_1"><?= _t( '_Couple' ) ?></label>
171                            <?
172                        break;
173                       
174                        case 'Keyword':
175                            ?>
176                    <input type="text" name="<?= $aItem['Name'] ?>" class="input_text" />
177                            <?
178                        break;
179                       
180                        case 'Location':
181                            //echo 'Not implemented yet';
182                            $sLivingWithinC = _t("_living within");
183                            $sMilesC = _t("_miles");
184                            $sKmC = _t("_kilometers");
185                            $sFromZipC = _t("_from zip/postal code");
186
187                            $sRet = <<<EOF
188<table class=small cellspacing=3 cellpadding=0 border="0">
189<tr>
190<td>
191    &nbsp;{$sLivingWithinC}&nbsp;
192    <input class=no type=text name="distance"  size=12 />
193<select name="metric">
194    <option selected="selected" value="miles">{$sMilesC}</option>
195    <option value="km">{$sKmC}</option>
196</select>
197    &nbsp;{$sFromZipC}&nbsp;
198    <input class=no type=text name=zip size=12 />
199</td>
200</tr>
201</table>
202EOF;
203                        echo $sRet;
204
205                        break;
206                    }
207                break;
208               
209            }
210
211           
212            ?>
213            </td>
214        </tr>
215            <?
216        }
217    }
218   
219    ?>
220        <tr>
221            <td class="search_form_submit_row" colspan="2">
222                <input type="checkbox" name="online_only" id="online_only" />
223                <label for="online_only"><?= _t( '_online only' ) ?></label>
224                <input type="checkbox" name="photos_only" id="photos_only" />
225                <label for="photos_only"><?= _t( '_With photos only' ) ?></label>
226                <input type="submit" value="<?= _t( '_Fetch' ) ?>" />
227            </td>
228        </tr>
229    </table>
230</form>
231    <?
232   
233    echo DesignBoxContentBorder( $sPageHeader, ob_get_clean() );
234}
235
236function PageCodeSearchByID()
237{
238    ob_start();
239    ?>
240    <div class="search_by_id">
241        <form method="GET" action="<?= $_SERVER['PHP_SELF'] ?>">
242            <input type="text" class="input_by_id" name="ID" />
243            <br />
244            <input type="submit" class="input_submit" value="<?= _t( '_Fetch' ) ?>" />
245        </form>
246    </div>
247    <?php
248
249    return DesignBoxContentBorder( _t( '_Search by ID' ), ob_get_clean() );
250}
251
252function PageCodeSearchByNick()
253{
254    ob_start();
255    ?>
256    <div class="search_by_nick">
257        <form method="GET" action="<?= $_SERVER['PHP_SELF'] ?>">
258            <input type="text" class="input_by_nick" name="NickName" />
259            <br />
260            <input type="submit" value="<?= _t( '_Fetch' ) ?>" />
261        </form>
262    </div>
263    <?php
264
265    return DesignBoxContentBorder( _t( '_Search by Nickname' ), ob_get_clean() );
266}
267
268function PageCodeSearchByTag()
269{
270    ob_start();
271    ?>
272    <div class="search_by_tag">
273        <form method="GET" action="<?= $_SERVER['PHP_SELF'] ?>">
274            <input type="text" class="input_by_tag" name="Tags" />
275            <br />
276            <input type="submit" value="<?= _t( '_Fetch' ) ?>" />
277        </form>
278    </div>
279    <?php
280
281    return DesignBoxContentBorder( _t( '_Search by Tag' ), ob_get_clean() );
282}
283
284function PageCodeSearchResult( $aParams ) {
285    global $oPF;
286    global $tmpl;
287    global $bEnZipSearch;
288
289    $sQuery = 'SELECT DISTINCT IF( `Profiles`.`Couple`=0, `Profiles`.`ID`, IF( `Profiles`.`Couple`>`Profiles`.`ID`, `Profiles`.`ID`, `Profiles`.`Couple` ) ) AS `ID` FROM `Profiles` ';
290    $sJoin  = '';
291    $aWhere = array();
292   
293   
294    $aMyBlocks = $oPF -> aBlocks;
295    $aMyBlocks['addSpecial'] = array( 'Items' => array(
296        $oPF -> aCache[100][0]['Items'][1], //add id
297        $oPF -> aCache[100][0]['Items'][2], //add nickname
298        $oPF -> aCache[100][0]['Items'][38] //add tags
299    ) );
300   
301    //collect where request array
302    foreach( $aMyBlocks as $iBlockID => $aBlock ) {
303        foreach( $aBlock['Items'] as $aItem ) {
304            if( !isset( $aParams[ $aItem['Name'] ] ) )
305                continue;
306           
307            if( $iBlockID != 'addSpecial' and ( $aItem['Name'] == 'ID' or $aItem['Name'] == 'NickName' or $aItem['Name'] == 'Tags' ) )
308                continue; // skip collecting id, nick and tags for regular blocks, only in special
309           
310            $sItemName = $aItem['Name'];
311            $mValue    = $aParams[$sItemName];
312           
313            switch( $aItem['Type'] ) {
314                case 'text':
315                case 'area':
316                    if( $sItemName == 'Tags' ) {
317                        $sJoin .= " INNER JOIN `Tags` ON (`Tags`.`Type` = 'profile' AND `Tags`.`ID` = `Profiles`.`ID`) ";
318                        $aWhere[] = "`Tags`.`Tag` = '" . addslashes($mValue) . "'";
319                    } else
320                        $aWhere[] = "`Profiles`.`$sItemName` LIKE '%" . addslashes($mValue) . "%'";
321                break;
322               
323                case 'num':
324                    $aWhere[] = "`Profiles`.`$sItemName` >= {$mValue[0]} AND `Profiles`.`$sItemName` <= {$mValue[1]}";
325                break;
326               
327                case 'date':
328                    $iMin = floor( $mValue[0] * 365.25 ); //for leap years
329                    $iMax = floor( $mValue[1] * 365.25 );
330                   
331                    $aWhere[] = "DATEDIFF( NOW(), `Profiles`.`$sItemName` ) >= $iMin AND DATEDIFF( NOW(), `Profiles`.`$sItemName` ) <= $iMax";
332                   
333                    //$aWhere[] = "DATE_ADD( `$sItemName`, INTERVAL {$mValue[0]} YEAR ) <= NOW() AND DATE_ADD( `$sItemName`, INTERVAL {$mValue[1]} YEAR ) >= NOW()"; //is it correct statement?
334                break;
335               
336                case 'select_one':
337                    $sValue = implode( ',', $mValue );
338                    $aWhere[] = "FIND_IN_SET( `Profiles`.`$sItemName`, '" . addslashes($sValue) . "' )";
339                break;
340               
341                case 'select_set':
342                    $aSet = array();
343                   
344                    foreach( $mValue as $sValue ) {
345                        $sValue = addslashes( $sValue );
346                        $aSet[] = "FIND_IN_SET( '$sValue', `Profiles`.`$sItemName` )";
347                    }
348                   
349                    $aWhere[] = '( ' . implode( ' OR ', $aSet ) . ' )';
350                break;
351               
352                case 'range':
353                    //impl
354                break;
355               
356                case 'bool':
357                    $aWhere[] = "`Profiles`.`$sItemName'";
358                break;
359               
360                case 'system':
361                    switch( $aItem['Name'] ) {
362                        case 'Couple':
363                            if($mValue == '-1') {
364                            }
365                            elseif( $mValue )
366                                $aWhere[] = "`Profiles`.`Couple` > `Profiles`.`ID`";
367                            else
368                                $aWhere[] = "`Profiles`.`Couple` = 0";
369                        break;
370                       
371                        case 'Keyword':
372                        case 'Location':
373                            $aFields = explode( "\n", $aItem['Extra'] );
374                            $aKeyw = array();
375                            $sValue = addslashes( $mValue );
376                           
377                            foreach( $aFields as $sField )
378                                $aKeyw[] = "`Profiles`.`$sField` LIKE '%$sValue%'";
379                           
380                            $aWhere[] = '( ' . implode( ' OR ', $aKeyw ) . ')';
381                        break;
382                       
383                        case 'ID':
384                            $aWhere[] = "`ID` = $mValue";
385                        break;
386                    }
387                break;
388            }
389        }
390    }
391
392    if ($bEnZipSearch && $aParams['distance'] > 0) {
393        $sZip = htmlspecialchars_adv($_REQUEST['zip']);
394        $iDistance = (int)$aParams['distance'];
395        $sMetric = htmlspecialchars_adv($_REQUEST['metric']);
396
397        $zip = process_db_input( strtoupper( str_replace(' ', '', $zip) ), 1);
398        $aZipInfo = db_arr("SELECT `Latitude`, `Longitude` FROM `ZIPCodes` WHERE REPLACE(`ZIPCode`,' ','') = '{$sZip}'");
399        //echoDbg($aZipInfo);
400        if ( $aZipInfo ) {
401            // ZIP code exists
402            $miles2km = 0.7; // miles/kilometers ratio
403
404            $Miles = $sMetric == "km" ? $iDistance * $miles2km : $iDistance;
405            $Latitude = $aZipInfo["Latitude"];
406            $Longitude = $aZipInfo["Longitude"];
407
408            $zcdRadius = new RadiusAssistant( $Latitude, $Longitude, $Miles );
409            //echoDbg($zcdRadius);
410            $minLat = $zcdRadius->MinLatitude();
411            $maxLat = $zcdRadius->MaxLatitude();
412            $minLong = $zcdRadius->MinLongitude();
413            $maxLong = $zcdRadius->MaxLongitude();
414
415            $sJoin .= " LEFT JOIN `ZIPCodes` ON UPPER( REPLACE(`Profiles`.`zip`, ' ', '') ) = REPLACE(`ZIPCodes`.`ZIPCode`,' ', '') ";
416            $aWhere[] = "`ZIPCodes`.`ZIPCode` IS NOT NULL AND `ZIPCodes`.`Latitude` >= {$minLat} AND `ZIPCodes`.`Latitude` <= {$maxLat} AND `ZIPCodes`.`Longitude` >= {$minLong} AND `ZIPCodes`.`Longitude` <= {$maxLong} ";
417        }
418    }
419
420    // collect query string
421    $aWhere[] = "`Profiles`.`Status` = 'Active'";
422   
423    // add online only
424    if( $_REQUEST['online_only'] ) {
425        $iOnlineTime = getParam( 'member_online_time' );
426        $aWhere[] = "DATE_ADD( `DateLastNav`, INTERVAL $iOnlineTime MINUTE ) >= NOW()";
427    }
428   
429    if( $_REQUEST['photos_only'] )
430        $aWhere[] = "`Profiles`.`PrimPhoto`";
431
432    $aWhere[] = "(`Profiles`.`Couple`='0' OR `Profiles`.`Couple`>`Profiles`.`ID`)";
433   
434    $sWhere = ' WHERE ' . implode( ' AND ', $aWhere );
435   
436    //collect the whole query string
437    $sQuery = $sQuery . $sJoin . $sWhere;
438
439    $sQueryCnt = 'SELECT COUNT(DISTINCT IF( `Profiles`.`Couple`=0, `Profiles`.`ID`, IF( `Profiles`.`Couple`>`Profiles`.`ID`, `Profiles`.`ID`, `Profiles`.`Couple` ) )) AS "Cnt" FROM `Profiles` ';
440    $sQueryCnt = $sQueryCnt . $sJoin . $sWhere;
441
442    $iCountProfiles = (int)(db_value($sQueryCnt));
443
444    if( $iCountProfiles < 1 ) {
445        echo '<div class="no_result"><div>' .  _t("_NO_RESULTS") . '</div></div>';
446    } else {
447        //collect pagination
448        $iCurrentPage    = isset( $_GET['page']         ) ? (int)$_GET['page']         : 1;
449        $iResultsPerPage = isset( $_GET['res_per_page'] ) ? (int)$_GET['res_per_page'] : 10;
450       
451        if( $iCurrentPage < 1 )
452            $iCurrentPage = 1;
453        if( $iResultsPerPage < 1 )
454            $iResultsPerPage = 10;
455       
456        $iTotalPages = ceil( $iCountProfiles / $iResultsPerPage );
457
458        if( $iTotalPages > 1 ) {
459            if( $iCurrentPage > $iTotalPages )
460                $iCurrentPage = $iTotalPages;
461
462            $sLimitFrom = ( $iCurrentPage - 1 ) * $iResultsPerPage;
463            $sQuery .= " LIMIT {$sLimitFrom}, {$iResultsPerPage}";
464
465            $iFromResults = ( ( $iCurrentPage - 1 ) * $iResultsPerPage ) + 1;
466           
467            $sPagination = genSearchPagination( $iTotalPages, $iCurrentPage, $iResultsPerPage );
468        } else {
469            $iFromResults = 1;
470            $sPagination = '';
471        }
472
473        //make search
474        //echo $sQuery;
475        $rProfiles = db_res( $sQuery );
476       
477        $aProfiles = array();
478        while ($aProfile = mysql_fetch_assoc($rProfiles)) {
479            $aProfiles[] = $aProfile['ID'];
480        }
481
482        $aOutputProfiles = $aProfiles;
483
484        $iCountOutputProfiles = count( $aOutputProfiles );
485       
486        $iToResults   = ( $iFromResults - 1 ) + $iCountOutputProfiles;
487       
488        $sShowingResults = '<div class="showingResults">' . _t( '_Showing results:', $iFromResults, $iToResults, $iCountProfiles ) . '</div>';
489       
490        echo $sPagination;
491        echo $sShowingResults;
492       
493        //output search results
494        $sTemplSearch = file_get_contents( BX_DIRECTORY_PATH_ROOT . "templates/tmpl_{$tmpl}/searchrow.html" );
495
496        foreach( $aOutputProfiles as $iProfID ) {
497            $aProfileInfo = getProfileInfo( $iProfID );
498           
499            if ($aProfileInfo['Couple'] > 0) {
500                $aProfileInfoC = getProfileInfo( $aProfileInfo['Couple'] );
501                echo PrintSearhResult( $aProfileInfo, $sTemplSearch, 1, true, $aProfileInfoC );
502            } else {
503                echo PrintSearhResult( $aProfileInfo, $sTemplSearch );
504            }
505        }
506       
507        echo $sShowingResults;
508        echo $sPagination;
509    }
510}
511
512function genSearchPagination( $iTotalPages, $iCurrentPage, $iResultsPerPage ) {
513    $aGetParams = $_GET;
514    unset( $aGetParams['page'] );
515    unset( $aGetParams['res_per_page'] );
516   
517    $sRequestString = collectRequestString( $aGetParams );
518    $sRequestString = $_SERVER['PHP_SELF'] . '?' . substr( $sRequestString, 1 );
519   
520    $sPaginTmpl      = $sRequestString . '&res_per_page=' . $iResultsPerPage . '&page={page}';
521    $sResPerPageTmpl = $sRequestString . '&res_per_page={res_per_page}';
522   
523    $sPagination = genResPerPage( array(10,20,50,100), $iResultsPerPage, $sResPerPageTmpl );
524    $sPagination .=  genPagination( $iTotalPages, $iCurrentPage, $sPaginTmpl );
525   
526    return $sPagination;
527}
528
529function collectRequestString( $aGetParams, $sKeyPref = '', $sKeyPostf = '' ) {
530    if( !is_array( $aGetParams ) )
531        return '';
532   
533    $sRet = '';
534    foreach( $aGetParams as $sKey => $sValue ) {
535        if( $sValue === '' )
536            continue;
537       
538        if( !is_array($sValue) ) {
539            $sRet .= '&' . urlencode( $sKeyPref . $sKey . $sKeyPostf ) . '=' . urlencode( process_pass_data( $sValue ) );
540        } else {
541            $sRet .= collectRequestString( $sValue, "{$sKeyPref}{$sKey}{$sKeyPostf}[", "]" ); //recursive call
542        }
543    }
544   
545    return $sRet;
546}
Note: See TracBrowser for help on using the repository browser.