Commit 47e20abac975dfcb787251a6eb720e504989899b

Authored by Bryn Divey
1 parent 102db588

Per-User saved searches. Please test.


git-svn-id: https://kt-dms.svn.sourceforge.net/svnroot/kt-dms/trunk@5439 c91229c3-7414-0410-bfa2-8a42b809f60b
lib/search/savedsearch.inc.php
... ... @@ -146,6 +146,15 @@ class KTSavedSearch extends KTEntity {
146 146 ));
147 147 }
148 148  
  149 + function &getUserSearches($iUserId, $bNoSystem = false) {
  150 + $sQuery = sprintf('user_id = %d', $iUserId);
  151 + if(!$bNoSystem) {
  152 + $sQuery .= ' OR user_id IS NULL';
  153 + }
  154 +
  155 + return KTEntityUtil::getList2('KTSavedSearch', $sQuery, array('orderby' => 'user_id, name'));
  156 + }
  157 +
149 158 function &getConditions() {
150 159 return KTEntityUtil::getByDict('KTSavedSearch', array(
151 160 'is_condition' => true,
... ...
plugins/ktcore/KTPortlets.php
... ... @@ -40,15 +40,26 @@ class KTSearchPortlet extends KTPortlet {
40 40 $oTemplating =& KTTemplating::getSingleton();
41 41 $oTemplate = $oTemplating->loadTemplate("kt3/portlets/search_portlet");
42 42  
43   - $aSearches = KTSavedSearch::getSearches();
  43 + $iFolderId = KTUtil::arrayGet($_REQUEST, 'fFolderId', 1);
  44 + $iDocumentId = KTUtil::arrayGet($_REQUEST, 'fDocumentId');
  45 + if (!$iFolderId && !$iDocumentId) {
  46 + return null;
  47 + }
  48 +
  49 + $iUserId = $_SESSION['userID'];
  50 + $aSearches = KTSavedSearch::getUserSearches($iUserId);
  51 +
44 52 // empty on error.
45 53 if (PEAR::isError($aSearches)) {
46 54 $aSearches = array();
47 55 }
48 56  
  57 + $iFolderId = KTUtil::arrayGet($_REQUEST, 'fFolderId', 1);
49 58 $aTemplateData = array(
50 59 "context" => $this,
51 60 "saved_searches" => $aSearches,
  61 + "folder_id" => $iFolderId,
  62 + "document_id" => $iDocumentId,
52 63 );
53 64  
54 65 return $oTemplate->render($aTemplateData);
... ...
plugins/ktcore/admin/savedSearch.php
... ... @@ -149,7 +149,7 @@ class KTSavedSearchDispatcher extends KTAdminDispatcher {
149 149 $oSearch = KTSavedSearch::get($id);
150 150  
151 151 if (PEAR::isError($oSearch) || ($oSearch == false)) {
152   - $this->errorRedirectToMain('No Such search');
  152 + $this->errorRedirectToMain('No such search');
153 153 }
154 154  
155 155  
... ... @@ -212,6 +212,16 @@ class KTSavedSearchDispatcher extends KTAdminDispatcher {
212 212 ));
213 213 $this->successRedirectToMain(_kt('Search saved'));
214 214 }
  215 +
  216 + // helper for the template
  217 + function _getUserName($iUserId) {
  218 + $oUser = User::get($iUserId);
  219 + if(PEAR::isError($oUser)) {
  220 + return _kt('Error retrieving username');
  221 + }
  222 + return $oUser->getUserName();
  223 + }
  224 +
215 225 }
216 226  
217 227 //$oDispatcher = new KTSavedSearchDispatcher();
... ...
search/booleanSearch.php
... ... @@ -84,7 +84,7 @@ class BooleanSearchDispatcher extends KTStandardDispatcher {
84 84 }
85 85  
86 86 if (is_null(KTUtil::arrayGet($datavars["subgroup"][0], "values"))) {
87   - $this->errorRedirectToMain("No search parameters given");
  87 + $this->errorRedirectToMain(_kt("No search parameters given"));
88 88 }
89 89  
90 90 if (empty($datavars)) {
... ... @@ -96,6 +96,132 @@ class BooleanSearchDispatcher extends KTStandardDispatcher {
96 96 return $res;
97 97 }
98 98  
  99 + function do_saveSearch() {
  100 + $this->startTransaction();
  101 +
  102 + $iSearchId = KTUtil::arrayGet($_REQUEST, 'fSearchId', false);
  103 + $sName = KTUtil::arrayGet($_REQUEST, 'name', false);
  104 + $sSearch = KTUtil::arrayGet($_REQUEST, 'boolean_search');
  105 +
  106 + if($iSearchId === false && $sName === false) {
  107 + $this->errorRedirectTo('performSearch', _kt('Please either enter a name, or select a search to save over'), sprintf('boolean_search_id=%s', $sSearch));
  108 + exit(0);
  109 + }
  110 +
  111 + $datavars = $_SESSION['boolean_search'][$sSearch];
  112 + if (!is_array($datavars)) {
  113 + $datavars = unserialize($datavars);
  114 + }
  115 +
  116 + if (empty($datavars)) {
  117 + $this->errorRedirectToMain(_kt('You need to have at least 1 condition.'));
  118 + }
  119 +
  120 + if($iSearchId) {
  121 + $oSearch = KTSavedSearch::get($iSearchId);
  122 + if(PEAR::isError($oSearch) || $oSearch == false) {
  123 + $this->errorRedirectToMain(_kt('No such search'));
  124 + exit(0);
  125 + }
  126 + $oSearch->setSearch($datavars);
  127 + $oSearch = $oSearch->update();
  128 +
  129 + } else {
  130 + $sName = $this->oValidator->validateEntityName('KTSavedSearch',
  131 + KTUtil::arrayGet($_REQUEST, 'name'),
  132 + array('extra_condition' => 'not is_condition', 'redirect_to' => array('new')));
  133 +
  134 + $sNamespace = KTUtil::nameToLocalNamespace('Saved searches', $sName);
  135 +
  136 + $oSearch = KTSavedSearch::createFromArray(array('name' => $sName,
  137 + 'namespace' => $sNamespace,
  138 + 'iscondition' => false,
  139 + 'iscomplete' => true,
  140 + 'userid' => $this->oUser->getId(),
  141 + 'search' => $datavars,));
  142 + }
  143 +
  144 + $this->oValidator->notError($oSearch, array(
  145 + 'redirect_to' => 'main',
  146 + 'message' => _kt('Search not saved'),
  147 + ));
  148 +
  149 + $this->commitTransaction();
  150 + $this->successRedirectTo('performSearch', _kt('Search saved'), sprintf('boolean_search_id=%s', $sSearch));
  151 + }
  152 +
  153 +
  154 + function do_deleteSearch() {
  155 + $this->startTransaction();
  156 +
  157 + $iSearchId = KTUtil::arrayGet($_REQUEST, 'fSavedSearchId', false);
  158 + $oSearch = KTSavedSearch::get($iSearchId);
  159 + if(PEAR::isError($oSearch) || $oSearch == false) {
  160 + $this->errorRedirectToMain(_kt('No such search'));
  161 + exit(0);
  162 + }
  163 +
  164 + $res = $oSearch->delete();
  165 + $this->oValidator->notError($res, array(
  166 + 'redirect_to' => 'main',
  167 + 'message' => _kt('Error deleting search'),
  168 + ));
  169 +
  170 + $this->commitTransaction();
  171 +
  172 + $iFolderId = KTUtil::arrayGet($_REQUEST, 'fFolderId', false);
  173 + $iDocumentId = KTUtil::arrayGet($_REQUEST, 'fFolderId', false);
  174 +
  175 + if($iFolderId) {
  176 + controllerRedirect('browse', 'fFolderId=' . $iFolderId);
  177 + } else {
  178 + controllerRedirect('viewDocument', 'fDocumentId=' . $iDocumentId);
  179 + }
  180 + }
  181 +
  182 + function do_editSearch() {
  183 + $sSearch = KTUtil::arrayGet($_REQUEST, 'boolean_search');
  184 + $aSearch = $_SESSION['boolean_search'][$sSearch];
  185 + if (!is_array($aSearch)) {
  186 + $aSearch = unserialize($aSearch);
  187 + }
  188 +
  189 + if (empty($aSearch)) {
  190 + $this->errorRedirectToMain(_kt('You need to have at least 1 condition.'));
  191 + }
  192 +
  193 + $oTemplating =& KTTemplating::getSingleton();
  194 + $oTemplate = $oTemplating->loadTemplate("ktcore/boolean_search_change");
  195 +
  196 + $aCriteria = Criteria::getAllCriteria();
  197 +
  198 + // we need to help out here, since it gets unpleasant inside the template.
  199 +
  200 + foreach ($aSearch['subgroup'] as $isg => $as) {
  201 + $aSubgroup =& $aSearch['subgroup'][$isg];
  202 + if (is_array($aSubgroup['values'])) {
  203 + foreach ($aSubgroup['values'] as $iv => $t) {
  204 + $datavars =& $aSubgroup['values'][$iv];
  205 + $datavars['typename'] = $aCriteria[$datavars['type']]->sDisplay;
  206 + $datavars['widgetval'] = $aCriteria[$datavars['type']]->searchWidget(null, $datavars['data']);
  207 + }
  208 + }
  209 + }
  210 +
  211 + $aTemplateData = array(
  212 + "title" => _kt("Edit an existing condition"),
  213 + "aCriteria" => $aCriteria,
  214 + "searchButton" => _kt("Search"),
  215 + 'aSearch' => $aSearch,
  216 + 'context' => $this,
  217 + // 'iSearchId' => $oSearch->getId(),
  218 + // 'old_name' => $oSearch->getName(),
  219 + 'sNameTitle' => _kt('Edit Search'),
  220 + );
  221 + return $oTemplate->render($aTemplateData);
  222 + }
  223 +
  224 +
99 225 function handleCriteriaSet($aCriteriaSet, $iStartIndex, $sTitle=null) {
100 226  
101 227 if ($sTitle == null) {
... ... @@ -142,6 +268,22 @@ class BooleanSearchDispatcher extends KTStandardDispatcher {
142 268 $qObj = new BooleanSearchQuery($aCriteriaSet);
143 269 $collection->setQueryObject($qObj);
144 270  
  271 +
  272 + // form fields for saving the search
  273 + $save_fields = array();
  274 + $save_fields[] = new KTStringWidget(_kt('New search'), _kt('The name to save this search as'), 'name', null, $this->oPage, true);
  275 +
  276 + $aUserSearches = KTSavedSearch::getUserSearches($this->oUser->getId(), true);
  277 + if(count($aUserSearches)) {
  278 + $aVocab = array('' => ' ---- ');
  279 + foreach($aUserSearches as $oSearch) {
  280 + $aVocab[$oSearch->getId()] = $oSearch->getName();
  281 + }
  282 +
  283 + $aSelectOptions = array('vocab' => $aVocab);
  284 + $save_fields[] = new KTLookupWidget(_kt('Existing search'), _kt('To save over one of your existing searches, select it here.'), 'fSearchId', null, $this->oPage, true, null, null, $aSelectOptions);
  285 + }
  286 +
145 287 $collection->getResults();
146 288 $oTemplating =& KTTemplating::getSingleton();
147 289 $oTemplate = $oTemplating->loadTemplate("kt3/browse");
... ... @@ -149,6 +291,8 @@ class BooleanSearchDispatcher extends KTStandardDispatcher {
149 291 "context" => $this,
150 292 "collection" => $collection,
151 293 "custom_title" => $sTitle,
  294 + "save_fields" => $save_fields,
  295 + "boolean_search" => $sSearch,
152 296 );
153 297 return $oTemplate->render($aTemplateData);
154 298 }
... ...
templates/kt3/browse.smarty
... ... @@ -8,7 +8,8 @@
8 8 <h2>{$custom_title}</h2>
9 9 {/if}
10 10  
11   -<form action="{$smarty.server.PHP_SELF}" METHOD="POST">
  11 +
  12 +<form action="{$smarty.server.PHP_SELF}" method="post">
12 13 <input type="hidden" name="action" value="massaction" />
13 14 {if ($isEditable)}
14 15 <input type="hidden" name="fFolderId" value="{$context->oFolder->getId()}" />
... ... @@ -21,4 +22,36 @@
21 22 </div>
22 23 {/if}
23 24 </form>
  25 +
  26 +
  27 +
  28 +{if ($save_fields)}
  29 +<form action="{$smarty.server.PHP_SELF}" method="post">
  30 +<fieldset>
  31 +<legend>Edit search</legend>
  32 +<p class="descriptiveText">{i18n}To modify this search, press the 'Edit' button.{/i18n}</p>
  33 +<input type="hidden" name="action" value="editSearch" />
  34 +<input type="hidden" name="boolean_search" value="{$boolean_search}" />
  35 +<div class="form_actions">
  36 +<input type="submit" name="submit" value="{i18n}Edit{/i18n}" />
  37 +</div>
  38 +</fieldset>
  39 +</form>
  40 +
  41 +<form action="{$smarty.server.PHP_SELF}" method="post">
  42 +<fieldset>
  43 +<legend>{i18n}Save this search{/i18n}</legend>
  44 +<p class="descriptiveText">{i18n}To save this search permanently, so that you can run it again at any time, fill in a name below and click 'Save'.{/i18n}</p>
  45 +<input type="hidden" name="action" value="saveSearch" />
  46 +<input type="hidden" name="boolean_search" value="{$boolean_search}" />
  47 +{foreach item=oWidget from=$save_fields}
  48 + {$oWidget->render()}
  49 +{/foreach}
  50 +<div class="form_actions">
  51 +<input type="submit" name="submit" value="{i18n}Save{/i18n}" />
  52 +</div>
  53 +</fieldset>
  54 +</form>
  55 +{/if}
  56 +
24 57 {* we break encapsulation pretty badly here. *}
25 58 \ No newline at end of file
... ...
templates/kt3/portlets/search_portlet.smarty
... ... @@ -8,7 +8,9 @@
8 8 <h4>{i18n}Saved Searches{/i18n}</h4>
9 9 <ul class="actionlist">
10 10 {foreach item=oSearch from=$saved_searches}
11   -<li><a href="{"booleanSearch"|generateControllerUrl}&qs[action]=performSearch&qs[fSavedSearchId]={$oSearch->getId()}">{$oSearch->getName()}</a></li>
  11 +<li>
  12 +{if ($oSearch->getUserId())}<a class="ktInline ktAction ktDelete" href="{"booleanSearch"|generateControllerUrl}&qs[action]=deleteSearch&qs[fSavedSearchId]={$oSearch->getId()}&qs[fFolderId]={$folder_id}&qs[fDocumentId]={$document_id}">{i18n}Delete{/i18n}</a>{/if}<a href="{"booleanSearch"|generateControllerUrl}&qs[action]=performSearch&qs[fSavedSearchId]={$oSearch->getId()}">{$oSearch->getName()}</a>
  13 +</li>
12 14 {/foreach}
13 15 </ul>
14 16 <hr />
... ...
templates/ktcore/search/administration/savedsearches.smarty
... ... @@ -22,6 +22,7 @@ newsletters, etc.) based on a category or fieldset value.{/i18n}&lt;/p&gt;
22 22 <thead>
23 23 <tr>
24 24 <th>{i18n}Search Name{/i18n}</th>
  25 + <th>{i18n}User{/i18n}</th>
25 26 <th>{i18n}Edit{/i18n}</th>
26 27 <th>{i18n}Delete{/i18n}</th>
27 28 <th>{i18n}View Results{/i18n}</th>
... ... @@ -31,6 +32,8 @@ newsletters, etc.) based on a category or fieldset value.{/i18n}&lt;/p&gt;
31 32 {foreach item=oSearch from=$saved_searches}
32 33 <tr>
33 34 <td>{$oSearch->getName()}</td>
  35 + {capture assign=iUserId}{$oSearch->getUserId()}{/capture}
  36 + <td>{if ($iUserId === '')}Global{else}{$context->_getUserName($iUserId)}{/if}</td>
34 37 <td><a href="{addQS}action=edit&fSavedSearchId={$oSearch->getId()}{/addQS}" class="ktAction ktEdit">{i18n}Edit{/i18n}</a></td>
35 38 <td><a href="{addQS}action=delete&fSavedSearchId={$oSearch->getId()}{/addQS}" class="ktAction ktDelete">{i18n}Delete{/i18n}</a></td>
36 39 <td><a href="{"booleanSearch"|generateControllerUrl}&qs[action]=performSearch&qs[fSavedSearchId]={$oSearch->getId()}">Run Search</a></td>
... ...