. */ declare(strict_types=1); namespace FireflyIII\Http\Controllers; 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 Log; 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. * * @param Request $request * @param SearchInterface $searcher * * @return Factory|View */ public function index(Request $request, SearchInterface $searcher) { // 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: $query = $searcher->getWordsAsString(); $operators = $searcher->getOperators(); $invalidOperators = $searcher->getInvalidOperators(); $subTitle = (string)trans('breadcrumbs.search_result', ['query' => $fullQuery]); return prefixView('search.index', compact('query', 'operators', 'page', 'rule', 'fullQuery', 'subTitle', 'ruleId', 'ruleChanged', 'invalidOperators')); } /** * JSON request that does the work. * * @param Request $request * @param SearchInterface $searcher * * @return JsonResponse */ public function search(Request $request, SearchInterface $searcher): JsonResponse { $fullQuery = (string)$request->get('query'); $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 = prefixView('search.search', compact('groups', 'hasPages', 'searchTime'))->render(); } catch (Throwable $e) { // @phpstan-ignore-line Log::error(sprintf('Cannot render search.search: %s', $e->getMessage())); $html = 'Could not render view.'; } return response()->json(['count' => $groups->count(), 'html' => $html]); } }