. */ declare(strict_types=1); namespace FireflyIII\Http\Controllers; use Illuminate\Support\Facades\Log; use FireflyIII\Exceptions\FireflyException; use FireflyIII\Repositories\Rule\RuleRepositoryInterface; use FireflyIII\Support\Search\SearchInterface; use Illuminate\Contracts\View\Factory; use Illuminate\Http\JsonResponse; use Illuminate\Http\Request; use Illuminate\View\View; use Throwable; /** * Class SearchController. */ class SearchController extends Controller { /** * SearchController constructor. */ public function __construct() { parent::__construct(); app('view')->share('showCategory', true); $this->middleware( static function ($request, $next) { app('view')->share('mainTitleIcon', 'fa-search'); app('view')->share('title', (string) trans('firefly.search')); return $next($request); } ); } /** * Do the search. * * @return Factory|View */ public function index(Request $request, SearchInterface $searcher): Factory|\Illuminate\Contracts\View\View { // search params: $fullQuery = $request->get('search'); if (is_array($request->get('search'))) { $fullQuery = ''; } $fullQuery = (string) $fullQuery; $page = 0 === (int) $request->get('page') ? 1 : (int) $request->get('page'); $ruleId = (int) $request->get('rule'); $ruleChanged = false; // find rule, check if query is different, offer to update. $ruleRepository = app(RuleRepositoryInterface::class); $rule = $ruleRepository->find($ruleId); if (null !== $rule) { $originalQuery = $ruleRepository->getSearchQuery($rule); if ($originalQuery !== $fullQuery) { $ruleChanged = true; } } // parse search terms: $searcher->parseQuery($fullQuery); // words from query and operators: $words = $searcher->getWords(); $excludedWords = $searcher->getExcludedWords(); $operators = $searcher->getOperators(); $invalidOperators = $searcher->getInvalidOperators(); $subTitle = (string) trans('breadcrumbs.search_result', ['query' => $fullQuery]); return view('search.index', ['words' => $words, 'excludedWords' => $excludedWords, 'operators' => $operators, 'page' => $page, 'rule' => $rule, 'fullQuery' => $fullQuery, 'subTitle' => $subTitle, 'ruleId' => $ruleId, 'ruleChanged' => $ruleChanged, 'invalidOperators' => $invalidOperators]); } /** * JSON request that does the work. * * @throws FireflyException */ public function search(Request $request, SearchInterface $searcher): JsonResponse { $entry = $request->get('query'); if (!is_scalar($entry)) { $entry = ''; } $fullQuery = (string) $entry; $page = 0 === (int) $request->get('page') ? 1 : (int) $request->get('page'); $searcher->parseQuery($fullQuery); $searcher->setPage($page); $groups = $searcher->searchTransactions(); $hasPages = $groups->hasPages(); $searchTime = round($searcher->searchTime(), 3); // in seconds $parameters = ['search' => $fullQuery]; $url = route('search.index').'?'.http_build_query($parameters); $groups->setPath($url); try { $html = view('search.search', ['groups' => $groups, 'hasPages' => $hasPages, 'searchTime' => $searchTime])->render(); } catch (Throwable $e) { Log::error(sprintf('Cannot render search.search: %s', $e->getMessage())); Log::error($e->getTraceAsString()); $html = 'Could not render view.'; throw new FireflyException($html, 0, $e); } return response()->json(['count' => $groups->count(), 'html' => $html]); } }