3 * The SearchForm control is used to render a search form and search results.
5 * Copyright 2003 Mark O'Sullivan
6 * This file is part of Lussumo's Software Library.
7 * Lussumo's Software Library is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
8 * Lussumo's Software Library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
9 * You should have received a copy of the GNU General Public License along with Vanilla; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
10 * The latest source code is available at www.lussumo.com
11 * Contact Mark O'Sullivan at mark [at] lussumo [dot] com
13 * @author Mark O'Sullivan
14 * @copyright 2003 Mark O'Sullivan
15 * @license http://lussumo.com/community/gpl.txt GPL 2
22 * The SearchForm control is used to render a search form and search results.
25 class SearchForm
extends PostBackControl
{
26 var $FormName; // The name of this form
27 var $Search; // A search object (contains all parameters related to the search: keywords, etc)
28 var $SearchID; // The id of the search to load
29 var $Data; // Search result data
30 var $DataCount; // The number of records returned by a search
32 // Search form controls
38 function SearchForm(&$Context, $FormName = '') {
39 $this->Name
= 'SearchForm';
40 $this->ValidActions
= array('Search', 'SaveSearch');
41 $this->FormName
= $FormName;
42 $this->SearchID
= ForceIncomingInt('SearchID', 0);
44 $this->Constructor($Context);
45 if ($this->PostBackAction
== '') $this->IsPostBack
= 1;
46 $this->Context
->BodyAttributes
.= ' onload="Focus(\'txtKeywords\');"';
48 $CurrentPage = ForceIncomingInt('page', 1);
50 // Load a search object
51 $this->Search
= $this->Context
->ObjectFactory
->NewObject($this->Context
, 'Search');
52 $this->Search
->GetPropertiesFromForm();
54 $this->CallDelegate('PostDefineSearchFromForm');
58 $cm = $this->Context
->ObjectFactory
->NewContextObject($this->Context
, 'CategoryManager');
59 $CategorySet = $cm->GetCategories();
60 $this->CategorySelect
= $this->Context
->ObjectFactory
->NewObject($this->Context
, 'Select');
61 $this->CategorySelect
->Name
= 'Categories';
62 $this->CategorySelect
->CssClass
= 'SearchSelect';
63 $this->CategorySelect
->AddOption('', $this->Context
->GetDefinition('AllCategories'));
64 $this->CategorySelect
->AddOptionsFromDataSet($this->Context
->Database
, $CategorySet, 'Name', 'Name');
65 $this->CategorySelect
->SelectedValue
= $this->Search
->Categories
;
68 $this->OrderSelect
= $this->Context
->ObjectFactory
->NewObject($this->Context
, 'Select');
69 $this->OrderSelect
->Name
= 'UserOrder';
70 $this->OrderSelect
->CssClass
= 'SearchSelect';
71 $this->OrderSelect
->Attributes
= ' id="UserOrder"';
72 $this->OrderSelect
->AddOption('', $this->Context
->GetDefinition('Username'));
73 $this->OrderSelect
->AddOption('Date', $this->Context
->GetDefinition('DateLastActive'));
74 $this->OrderSelect
->SelectedValue
= $this->Search
->UserOrder
;
77 $this->TypeRadio
= $this->Context
->ObjectFactory
->NewObject($this->Context
, 'Radio');
78 $this->TypeRadio
->Name
= 'Type';
79 $this->TypeRadio
->CssClass
= 'SearchType';
80 $this->TypeRadio
->AddOption('Topics', $this->Context
->GetDefinition('Topics'));
81 $this->TypeRadio
->AddOption('Comments', $this->Context
->GetDefinition('Comments'));
82 $this->TypeRadio
->AddOption('Users', $this->Context
->GetDefinition('Users'));
83 $this->TypeRadio
->SelectedID
= $this->Search
->Type
;
85 $rm = $this->Context
->ObjectFactory
->NewContextObject($this->Context
, 'RoleManager');
86 $RoleSet = $rm->GetRoles();
87 $this->RoleSelect
= $this->Context
->ObjectFactory
->NewObject($this->Context
, 'Select');
88 $this->RoleSelect
->Name
= 'Roles';
89 $this->RoleSelect
->CssClass
= 'SearchSelect';
90 $this->RoleSelect
->Attributes
= ' id="RoleFilter"';
91 $this->RoleSelect
->AddOption('', $this->Context
->GetDefinition('AllRoles'));
92 if ($this->Context
->Session
->User
->Permission('PERMISSION_APPROVE_APPLICANTS')) $this->RoleSelect
->AddOption($this->Context
->GetDefinition('Applicant'), $this->Context
->GetDefinition('Applicant'));
93 $this->RoleSelect
->AddOptionsFromDataSet($this->Context
->Database
, $RoleSet, 'Name', 'Name');
94 $this->RoleSelect
->SelectedValue
= $this->Search
->Roles
;
96 $this->CallDelegate('PreSearchQuery');
99 if ($this->PostBackAction
== 'Search') {
101 // Because of PHP's new handling of objects in PHP 5, when I passed
102 // in $this->Search directly, it passed by reference instead of
103 // byval. I DO NOT want this because the keywords get formatted for
104 // db input in the search query and it makes them display
105 // incorrectly on the screen later down the page. Hence this kludge:
106 $OriginalKeywords = $this->Search
->Keywords
;
107 $OriginalQuery = $this->Search
->Query
;
109 if ($this->Search
->Type
== 'Users') {
110 $um = $this->Context
->ObjectFactory
->NewContextObject($this->Context
, 'UserManager');
111 $this->Data
= $um->GetUserSearch($this->Search
, $this->Context
->Configuration
['SEARCH_RESULTS_PER_PAGE'], $CurrentPage);
112 $this->Search
->Keywords
= $OriginalKeywords;
113 $this->Search
->Query
= $OriginalQuery;
114 $this->Search
->FormatPropertiesForDisplay();
116 } else if ($this->Search
->Type
== 'Topics') {
117 $dm = $this->Context
->ObjectFactory
->NewContextObject($this->Context
, 'DiscussionManager');
118 $this->Data
= $dm->GetDiscussionSearch($this->Context
->Configuration
['SEARCH_RESULTS_PER_PAGE'], $CurrentPage, $this->Search
);
119 $this->Search
->Keywords
= $OriginalKeywords;
120 $this->Search
->Query
= $OriginalQuery;
121 $this->Search
->FormatPropertiesForDisplay();
123 } else if ($this->Search
->Type
== 'Comments') {
124 $cm = $this->Context
->ObjectFactory
->NewContextObject($this->Context
, 'CommentManager');
125 $this->Data
= $cm->GetCommentSearch($this->Context
->Configuration
['SEARCH_RESULTS_PER_PAGE'], $CurrentPage, $this->Search
);
126 $this->Search
->Keywords
= $OriginalKeywords;
127 $this->Search
->Query
= $OriginalQuery;
128 $this->Search
->FormatPropertiesForDisplay();
131 if ($this->Data
) $this->DataCount
= $this->Context
->Database
->RowCount($this->Data
);
133 $pl = $this->Context
->ObjectFactory
->NewContextObject($this->Context
, 'PageList');
134 $pl->NextText
= $this->Context
->GetDefinition('Next');
135 $pl->PreviousText
= $this->Context
->GetDefinition('Previous');
137 $pl->CssClass
= 'PageList';
138 $pl->TotalRecords
= $this->DataCount
;
139 $pl->PageParameterName
= 'page';
140 $pl->CurrentPage
= $CurrentPage;
141 $pl->RecordsPerPage
= $this->Context
->Configuration
['SEARCH_RESULTS_PER_PAGE'];
142 $pl->PagesToDisplay
= 10;
143 $this->PageList
= $pl->GetLiteralList();
144 if ($this->Search
->Query
!= '') {
145 $Query = $this->Search
->Query
;
147 $Query = $this->Context
->GetDefinition('nothing');
149 if ($this->DataCount
== 0) {
150 $this->PageDetails
= $this->Context
->GetDefinition('NoSearchResultsMessage');
152 $this->PageDetails
= str_replace(array('//1', '//2', '//3'), array($pl->FirstRecord
, $pl->LastRecord
, '<strong>'.$Query.'</strong>'), $this->Context
->GetDefinition('SearchResultsMessage'));
155 $this->CallDelegate('PostLoadData');
156 // Make sure to remove the FormPostBackKey from the form so that it isn't
157 // present in the querystring
158 $this->PostBackParams
->Remove('FormPostBackKey');
161 function Render_NoPostBack() {
162 $this->CallDelegate('PreSearchFormRender');
163 include(ThemeFilePath($this->Context
->Configuration
, 'search_form.php'));
165 if ($this->PostBackAction
== 'Search') {
167 $this->CallDelegate('PreSearchResultsRender');
169 include(ThemeFilePath($this->Context
->Configuration
, 'search_results_top.php'));
171 if ($this->DataCount
> 0) {
175 if ($this->Search
->Type
== 'Topics') {
176 $Discussion = $this->Context
->ObjectFactory
->NewContextObject($this->Context
, 'Discussion');
177 $CurrentUserJumpToLastCommentPref = $this->Context
->Session
->User
->Preference('JumpToLastReadComment');
178 $DiscussionList = '';
179 $ThemeFilePath = ThemeFilePath($this->Context
->Configuration
, 'discussion.php');
180 while ($Row = $this->Context
->Database
->GetRow($this->Data
)) {
181 $Discussion->Clear();
182 $Discussion->GetPropertiesFromDataSet($Row);
183 $Discussion->FormatPropertiesForDisplay();
184 if ($Counter < $this->Context
->Configuration
['SEARCH_RESULTS_PER_PAGE']) {
185 $this->DelegateParameters
['Discussion'] = &$Discussion;
186 $this->CallDelegate('PreSingleDiscussionRender');
187 include($ThemeFilePath);
191 $Alternate = FlipBool($Alternate);
193 echo($DiscussionList);
194 } elseif ($this->Search
->Type
== 'Comments') {
195 $Comment = $this->Context
->ObjectFactory
->NewContextObject($this->Context
, 'Comment');
196 $HighlightWords = ParseQueryForHighlighting($this->Context
, $this->Search
->Query
);
198 $ThemeFilePath = ThemeFilePath($this->Context
->Configuration
, 'search_results_comments.php');
199 while ($Row = $this->Context
->Database
->GetRow($this->Data
)) {
201 $Comment->GetPropertiesFromDataSet($Row, $this->Context
->Session
->UserID
);
202 $Comment->FormatPropertiesForSafeDisplay();
203 if ($Counter < $this->Context
->Configuration
['SEARCH_RESULTS_PER_PAGE']) {
204 include($ThemeFilePath);
208 $Alternate = FlipBool($Alternate);
211 } elseif ($this->Search
->Type
== 'Users') {
212 $u = $this->Context
->ObjectFactory
->NewContextObject($this->Context
, 'User');
214 $ThemeFilePath = ThemeFilePath($this->Context
->Configuration
, 'search_results_users.php');
215 while ($Row = $this->Context
->Database
->GetRow($this->Data
)) {
217 $u->GetPropertiesFromDataSet($Row);
218 $u->FormatPropertiesForDisplay();
220 $this->DelegateParameters
['User'] = &$u;
221 $this->CallDelegate('PreRenderUserSearch');
223 if ($Counter < $this->Context
->Configuration
['SEARCH_RESULTS_PER_PAGE']) {
224 include($ThemeFilePath);
228 $Alternate = FlipBool($Alternate);
232 $this->CallDelegate('MidSearchResultsRender');
235 include(ThemeFilePath($this->Context
->Configuration
, 'search_results_bottom.php'));
239 function Render_ValidPostBack() {