[ Index ] |
PHP Cross Reference of Phabricator |
[Summary view] [Print] [Text view]
1 <?php 2 3 final class PhabricatorApplicationSearchController 4 extends PhabricatorSearchBaseController { 5 6 private $searchEngine; 7 private $navigation; 8 private $queryKey; 9 private $preface; 10 11 public function setPreface($preface) { 12 $this->preface = $preface; 13 return $this; 14 } 15 16 public function getPreface() { 17 return $this->preface; 18 } 19 20 public function setQueryKey($query_key) { 21 $this->queryKey = $query_key; 22 return $this; 23 } 24 25 protected function getQueryKey() { 26 return $this->queryKey; 27 } 28 29 public function setNavigation(AphrontSideNavFilterView $navigation) { 30 $this->navigation = $navigation; 31 return $this; 32 } 33 34 protected function getNavigation() { 35 return $this->navigation; 36 } 37 38 public function setSearchEngine( 39 PhabricatorApplicationSearchEngine $search_engine) { 40 $this->searchEngine = $search_engine; 41 return $this; 42 } 43 44 protected function getSearchEngine() { 45 return $this->searchEngine; 46 } 47 48 protected function validateDelegatingController() { 49 $parent = $this->getDelegatingController(); 50 51 if (!$parent) { 52 throw new Exception( 53 'You must delegate to this controller, not invoke it directly.'); 54 } 55 56 $engine = $this->getSearchEngine(); 57 if (!$engine) { 58 throw new Exception( 59 'Call setEngine() before delegating to this controller!'); 60 } 61 62 $nav = $this->getNavigation(); 63 if (!$nav) { 64 throw new Exception( 65 'Call setNavigation() before delegating to this controller!'); 66 } 67 68 $engine->setViewer($this->getRequest()->getUser()); 69 70 $parent = $this->getDelegatingController(); 71 } 72 73 public function processRequest() { 74 $this->validateDelegatingController(); 75 76 $key = $this->getQueryKey(); 77 if ($key == 'edit') { 78 return $this->processEditRequest(); 79 } else { 80 return $this->processSearchRequest(); 81 } 82 } 83 84 private function processSearchRequest() { 85 $parent = $this->getDelegatingController(); 86 $request = $this->getRequest(); 87 $user = $request->getUser(); 88 $engine = $this->getSearchEngine(); 89 $nav = $this->getNavigation(); 90 91 if ($request->isFormPost()) { 92 $saved_query = $engine->buildSavedQueryFromRequest($request); 93 $engine->saveQuery($saved_query); 94 return id(new AphrontRedirectResponse())->setURI( 95 $engine->getQueryResultsPageURI($saved_query->getQueryKey()).'#R'); 96 } 97 98 $named_query = null; 99 $run_query = true; 100 $query_key = $this->queryKey; 101 if ($this->queryKey == 'advanced') { 102 $run_query = false; 103 $query_key = $request->getStr('query'); 104 } else if (!strlen($this->queryKey)) { 105 $found_query_data = false; 106 107 if ($request->isHTTPGet()) { 108 // If this is a GET request and it has some query data, don't 109 // do anything unless it's only before= or after=. We'll build and 110 // execute a query from it below. This allows external tools to build 111 // URIs like "/query/?users=a,b". 112 $pt_data = $request->getPassthroughRequestData(); 113 114 foreach ($pt_data as $pt_key => $pt_value) { 115 if ($pt_key != 'before' && $pt_key != 'after') { 116 $found_query_data = true; 117 break; 118 } 119 } 120 } 121 122 if (!$found_query_data) { 123 // Otherwise, there's no query data so just run the user's default 124 // query for this application. 125 $query_key = head_key($engine->loadEnabledNamedQueries()); 126 } 127 } 128 129 if ($engine->isBuiltinQuery($query_key)) { 130 $saved_query = $engine->buildSavedQueryFromBuiltin($query_key); 131 $named_query = idx($engine->loadEnabledNamedQueries(), $query_key); 132 } else if ($query_key) { 133 $saved_query = id(new PhabricatorSavedQueryQuery()) 134 ->setViewer($user) 135 ->withQueryKeys(array($query_key)) 136 ->executeOne(); 137 138 if (!$saved_query) { 139 return new Aphront404Response(); 140 } 141 142 $named_query = idx($engine->loadEnabledNamedQueries(), $query_key); 143 } else { 144 $saved_query = $engine->buildSavedQueryFromRequest($request); 145 146 // Save the query to generate a query key, so "Save Custom Query..." and 147 // other features like Maniphest's "Export..." work correctly. 148 $engine->saveQuery($saved_query); 149 } 150 151 $nav->selectFilter( 152 'query/'.$saved_query->getQueryKey(), 153 'query/advanced'); 154 155 $form = id(new AphrontFormView()) 156 ->setUser($user) 157 ->setAction($request->getPath()); 158 159 $engine->buildSearchForm($form, $saved_query); 160 161 $errors = $engine->getErrors(); 162 if ($errors) { 163 $run_query = false; 164 $errors = id(new AphrontErrorView()) 165 ->setTitle(pht('Query Errors')) 166 ->setErrors($errors); 167 } 168 169 $submit = id(new AphrontFormSubmitControl()) 170 ->setValue(pht('Execute Query')); 171 172 if ($run_query && !$named_query && $user->isLoggedIn()) { 173 $submit->addCancelButton( 174 '/search/edit/'.$saved_query->getQueryKey().'/', 175 pht('Save Custom Query...')); 176 } 177 178 // TODO: A "Create Dashboard Panel" action goes here somewhere once 179 // we sort out T5307. 180 181 $form->appendChild($submit); 182 $filter_view = id(new AphrontListFilterView())->appendChild($form); 183 184 if ($run_query && $named_query) { 185 if ($named_query->getIsBuiltin()) { 186 $description = pht( 187 'Showing results for query "%s".', 188 $named_query->getQueryName()); 189 } else { 190 $description = pht( 191 'Showing results for saved query "%s".', 192 $named_query->getQueryName()); 193 } 194 195 $filter_view->setCollapsed( 196 pht('Edit Query...'), 197 pht('Hide Query'), 198 $description, 199 $this->getApplicationURI('query/advanced/?query='.$query_key)); 200 } 201 202 if ($this->getPreface()) { 203 $nav->appendChild($this->getPreface()); 204 } 205 206 $nav->appendChild($filter_view); 207 208 if ($run_query) { 209 $nav->appendChild( 210 $anchor = id(new PhabricatorAnchorView()) 211 ->setAnchorName('R')); 212 213 $query = $engine->buildQueryFromSavedQuery($saved_query); 214 215 $pager = $engine->newPagerForSavedQuery($saved_query); 216 $pager->readFromRequest($request); 217 218 $objects = $engine->executeQuery($query, $pager); 219 220 // TODO: To support Dashboard panels, rendering is moving into 221 // SearchEngines. Move it all the way in and then get rid of this. 222 223 $interface = 'PhabricatorApplicationSearchResultsControllerInterface'; 224 if ($parent instanceof $interface) { 225 $list = $parent->renderResultsList($objects, $saved_query); 226 } else { 227 $engine->setRequest($request); 228 229 $list = $engine->renderResults( 230 $objects, 231 $saved_query); 232 } 233 234 $nav->appendChild($list); 235 236 // TODO: This is a bit hacky. 237 if ($list instanceof PHUIObjectItemListView) { 238 $list->setNoDataString(pht('No results found for this query.')); 239 $list->setPager($pager); 240 } else { 241 if ($pager->willShowPagingControls()) { 242 $pager_box = id(new PHUIBoxView()) 243 ->addPadding(PHUI::PADDING_MEDIUM) 244 ->addMargin(PHUI::MARGIN_LARGE) 245 ->setBorder(true) 246 ->appendChild($pager); 247 $nav->appendChild($pager_box); 248 } 249 } 250 } 251 252 if ($errors) { 253 $nav->appendChild($errors); 254 } 255 256 if ($named_query) { 257 $title = pht('Query: %s', $named_query->getQueryName()); 258 } else { 259 $title = pht('Advanced Search'); 260 } 261 262 $crumbs = $parent 263 ->buildApplicationCrumbs() 264 ->addTextCrumb($title); 265 266 $nav->setCrumbs($crumbs); 267 268 return $this->buildApplicationPage( 269 $nav, 270 array( 271 'title' => $title, 272 )); 273 } 274 275 private function processEditRequest() { 276 $parent = $this->getDelegatingController(); 277 $request = $this->getRequest(); 278 $user = $request->getUser(); 279 $engine = $this->getSearchEngine(); 280 $nav = $this->getNavigation(); 281 282 $named_queries = $engine->loadAllNamedQueries(); 283 284 $list_id = celerity_generate_unique_node_id(); 285 286 $list = new PHUIObjectItemListView(); 287 $list->setUser($user); 288 $list->setID($list_id); 289 290 Javelin::initBehavior( 291 'search-reorder-queries', 292 array( 293 'listID' => $list_id, 294 'orderURI' => '/search/order/'.get_class($engine).'/', 295 )); 296 297 foreach ($named_queries as $named_query) { 298 $class = get_class($engine); 299 $key = $named_query->getQueryKey(); 300 301 $item = id(new PHUIObjectItemView()) 302 ->setHeader($named_query->getQueryName()) 303 ->setHref($engine->getQueryResultsPageURI($key)); 304 305 if ($named_query->getIsBuiltin() && $named_query->getIsDisabled()) { 306 $icon = 'fa-plus'; 307 } else { 308 $icon = 'fa-times'; 309 } 310 311 $item->addAction( 312 id(new PHUIListItemView()) 313 ->setIcon($icon) 314 ->setHref('/search/delete/'.$key.'/'.$class.'/') 315 ->setWorkflow(true)); 316 317 if ($named_query->getIsBuiltin()) { 318 if ($named_query->getIsDisabled()) { 319 $item->addIcon('fa-times lightgreytext', pht('Disabled')); 320 $item->setDisabled(true); 321 } else { 322 $item->addIcon('fa-lock lightgreytext', pht('Builtin')); 323 } 324 } else { 325 $item->addAction( 326 id(new PHUIListItemView()) 327 ->setIcon('fa-pencil') 328 ->setHref('/search/edit/'.$key.'/')); 329 } 330 331 $item->setGrippable(true); 332 $item->addSigil('named-query'); 333 $item->setMetadata( 334 array( 335 'queryKey' => $named_query->getQueryKey(), 336 )); 337 338 $list->addItem($item); 339 } 340 341 $list->setNoDataString(pht('No saved queries.')); 342 343 $crumbs = $parent 344 ->buildApplicationCrumbs() 345 ->addTextCrumb(pht('Saved Queries'), $engine->getQueryManagementURI()); 346 347 $nav->selectFilter('query/edit'); 348 $nav->setCrumbs($crumbs); 349 $nav->appendChild($list); 350 351 return $parent->buildApplicationPage( 352 $nav, 353 array( 354 'title' => pht('Saved Queries'), 355 )); 356 } 357 358 protected function buildApplicationMenu() { 359 return $this->getDelegatingController()->buildApplicationMenu(); 360 } 361 362 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Sun Nov 30 09:20:46 2014 | Cross-referenced by PHPXref 0.7.1 |