-
Notifications
You must be signed in to change notification settings - Fork 393
Refactor AlphabrowseController to an action. #5277
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: dev-12.0
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,11 +1,12 @@ | ||
| <?php | ||
|
|
||
| /** | ||
| * AlphaBrowse Module Controller. | ||
| * AlphaBrowse home action. | ||
| * | ||
| * PHP version 8 | ||
| * | ||
| * Copyright (C) Villanova University 2011. | ||
| * Copyright (C) The National Library of Finland 2026. | ||
| * | ||
| * This program is free software; you can redistribute it and/or modify | ||
| * it under the terms of the GNU General Public License version 2, | ||
|
|
@@ -21,38 +22,49 @@ | |
| * <https://www.gnu.org/licenses/>. | ||
| * | ||
| * @category VuFind | ||
| * @package Controller | ||
| * @package Action | ||
| * @author Mark Triggs <vufind-tech@lists.sourceforge.net> | ||
| * @author Chris Hallberg <challber@villanova.edu> | ||
| * @author Ere Maijala <ere.maijala@helsinki.fi> | ||
| * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License | ||
| * @link https://vufind.org/wiki/indexing:alphabetical_heading_browse Wiki | ||
| */ | ||
|
|
||
| namespace VuFind\Controller; | ||
| namespace VuFind\Action\Alphabrowse; | ||
|
|
||
| use Laminas\View\Model\ViewModel; | ||
| use VuFind\Config\Config; | ||
| use Psr\Http\Message\ResponseInterface; | ||
| use Psr\Http\Message\ServerRequestInterface; | ||
| use VuFind\Action\AbstractTemplateRenderingAction; | ||
| use VuFind\Exception\BadRequest; | ||
| use VuFind\ServiceManager\Factory\Autowire; | ||
| use VuFindSearch\Command\AlphabeticBrowseCommand; | ||
| use VuFindSearch\ParamBag; | ||
| use VuFindSearch\Service as SearchService; | ||
|
|
||
| use function in_array; | ||
| use function intval; | ||
|
|
||
| /** | ||
| * AlphabrowseController Class. | ||
| * AlphaBrowse home action. | ||
| * | ||
| * Controls the alphabetical browsing feature | ||
| * | ||
| * @category VuFind | ||
| * @package Controller | ||
| * @author Mark Triggs <vufind-tech@lists.sourceforge.net> | ||
| * @author Chris Hallberg <challber@villanova.edu> | ||
| * @author Ere Maijala <ere.maijala@helsinki.fi> | ||
| * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License | ||
| * @link https://vufind.org/wiki/indexing:alphabetical_heading_browse Wiki | ||
| */ | ||
| class AlphabrowseController extends AbstractBase | ||
| class HomeAction extends AbstractTemplateRenderingAction | ||
| { | ||
| use Feature\AlphaBrowseTrait; | ||
| /** | ||
| * The name of the backend providing alphabrowse services. | ||
| * | ||
| * @var string | ||
| */ | ||
| protected $alphabrowseBackend = 'Solr'; | ||
|
|
||
| /** | ||
| * Default browse types. | ||
|
|
@@ -77,6 +89,73 @@ class AlphabrowseController extends AbstractBase | |
| 'dewey' => 'title', | ||
| ]; | ||
|
|
||
| /** | ||
| * Constructor. | ||
| * | ||
| * @param SearchService $searchService Search service | ||
| * @param array $config VuFind configuration | ||
| */ | ||
| #[Autowire()] | ||
| public function __construct( | ||
| protected SearchService $searchService, | ||
| #[Autowire(config: 'config')] protected array $config, | ||
| ) { | ||
| parent::__construct(); | ||
| } | ||
|
|
||
| /** | ||
| * Display a particular tab. | ||
| * | ||
| * @param ServerRequestInterface $request Server request | ||
| * @param ResponseInterface $response Response | ||
| * | ||
| * @return ResponseInterface | ||
| */ | ||
| public function action( | ||
| ServerRequestInterface $request, | ||
| ResponseInterface $response, | ||
| ): ResponseInterface { | ||
| // Load config parameters: | ||
| $config = $this->config; | ||
| $rowsBefore = ctype_digit((string)($config['AlphaBrowse']['rows_before'] ?? '-')) | ||
| ? (int)$config['AlphaBrowse']['rows_before'] : 0; | ||
| $limit = ctype_digit((string)($config['AlphaBrowse']['page_size'] ?? '-')) | ||
| ? (int)$config['AlphaBrowse']['page_size'] : 20; | ||
|
|
||
| // Process incoming parameters: | ||
| $source = $this->getQueryParam('source', false); | ||
| $from = $this->getQueryParam('from', false); | ||
| $page = intval($this->getQueryParam('page', 0)); | ||
|
|
||
| // Load highlighting configuration while accounting for special case: | ||
| // highlighting is pointless if there's no user input: | ||
| $highlighting = empty($from) ? false : $config['AlphaBrowse']['highlighting'] ?? false; | ||
|
|
||
| // Set up any extra parameters to pass | ||
| $extras = $this->getExtras($config); | ||
|
|
||
| // Create template params: | ||
| $templateParams = [ | ||
| 'alphaBrowseTypes' => $this->getTypes($config), | ||
| 'from' => $from, | ||
| 'source' => $source, | ||
| 'extras' => array_filter(explode(':', $extras[$source] ?? '')), | ||
| ]; | ||
|
|
||
| // If required parameters are present, load results: | ||
| $this->addResultsToTemplateParams( | ||
| $templateParams, | ||
| $page, | ||
| $limit, | ||
| $rowsBefore, | ||
| $highlighting, | ||
| $extras | ||
| ); | ||
|
|
||
| // Render results: | ||
| return $this->renderTemplate($request, $response, $templateParams); | ||
| } | ||
|
|
||
| /** | ||
| * Get browse types from config file, or use defaults if unavailable. | ||
| * | ||
|
|
@@ -102,87 +181,84 @@ protected function getExtras(array $config): array | |
| } | ||
|
|
||
| /** | ||
| * Add alphabrowse results to the view model. | ||
| * Add alphabrowse results to the template params. | ||
| * | ||
| * @param ViewModel $view View model (must already contain source and | ||
| * from values) | ||
| * @param int $page Results page to load | ||
| * @param int $limit Page size | ||
| * @param int $rowsBefore Number of rows to display before highlighted | ||
| * row | ||
| * @param bool $highlighting Is row highlighting enabled? | ||
| * @param array $extras Extra fields to load in results | ||
| * @param array $templateParams Template params (must already contain source and from values) | ||
| * @param int $page Results page to load | ||
| * @param int $limit Page size | ||
| * @param int $rowsBefore Number of rows to display before highlighted row | ||
| * @param bool $highlighting Is row highlighting enabled? | ||
| * @param array $extras Extra fields to load in results | ||
| * | ||
| * @return void | ||
| */ | ||
| protected function addResultsToView( | ||
| ViewModel $view, | ||
| protected function addResultsToTemplateParams( | ||
| array &$templateParams, | ||
| int $page, | ||
| int $limit, | ||
| int $rowsBefore, | ||
| bool $highlighting, | ||
| array $extras | ||
| ): void { | ||
| $result = []; | ||
| if ($view->source && $view->from !== false) { | ||
| $source = $templateParams['source'] ?? null; | ||
| $from = $templateParams['from'] ?? null; | ||
| $alphaBrowseTypes = $templateParams['alphaBrowseTypes'] ?? []; | ||
| if ($source && $from !== false) { | ||
| // Validate source parameter: | ||
| if (!in_array($view->source, array_keys($view->alphaBrowseTypes))) { | ||
| if (!in_array($source, array_keys($alphaBrowseTypes))) { | ||
| throw new BadRequest( | ||
| "Unsupported alphabrowse type: {$view->source}" | ||
| "Unsupported alphabrowse type: $source" | ||
| ); | ||
| } | ||
|
|
||
| // Set up extra params: | ||
| $extraParams = new ParamBag(); | ||
| if (isset($extras[$view->source])) { | ||
| $extraParams->add('extras', $extras[$view->source]); | ||
| if (isset($extras[$source])) { | ||
| $extraParams->add('extras', $extras[$source]); | ||
| } | ||
|
|
||
| // Load Solr data or die trying: | ||
| $result = $this->alphabeticBrowse( | ||
| $view->source, | ||
| $view->from, | ||
| $command = new AlphabeticBrowseCommand( | ||
| $this->alphabrowseBackend, | ||
| $source, | ||
| $from, | ||
| $page, | ||
| $limit, | ||
| $extraParams, | ||
| 0 - $rowsBefore | ||
| ); | ||
| $result = $this->searchService->invoke($command)->getResult(); | ||
|
|
||
| // No results? Try the previous page just in case we've gone past | ||
| // the end of the list.... | ||
| // No results? Try the previous page just in case we've gone past the end of the list.... | ||
| if ($result['Browse']['totalCount'] == 0) { | ||
| $page--; | ||
| $result = $this->alphabeticBrowse( | ||
| $view->source, | ||
| $view->from, | ||
| $page, | ||
| $limit, | ||
| $extraParams, | ||
| 0 | ||
| ); | ||
| $command->setPage($page) | ||
| ->setOffsetDelta(0); | ||
| $result = $this->searchService->invoke($command)->getResult(); | ||
| if ($highlighting) { | ||
| $view->highlight_end = true; | ||
| $templateParams['highlight_end'] = true; | ||
| } | ||
| } | ||
|
|
||
| // Only display next/previous page links when applicable: | ||
| if ($result['Browse']['totalCount'] > $limit) { | ||
| $view->nextpage = $page + 1; | ||
| $templateParams['nextpage'] = $page + 1; | ||
| } | ||
| if ($result['Browse']['offset'] + $result['Browse']['startRow'] > 1) { | ||
| $view->prevpage = $page - 1; | ||
| $templateParams['prevpage'] = $page - 1; | ||
| } | ||
| } | ||
|
|
||
| if ($view->source === 'topic') { | ||
| if ($source === 'topic') { | ||
| $this->applyTopicDelimiters($result); | ||
| } | ||
|
|
||
| $view->result = $result; | ||
| $templateParams['result'] = $result; | ||
|
|
||
| // set up highlighting: page 0 contains match location | ||
| if ($highlighting && $page == 0 && isset($view->result['Browse'])) { | ||
| $this->applyHighlighting($view, $rowsBefore); | ||
| if ($highlighting && $page == 0 && isset($result['Browse'])) { | ||
| $this->applyHighlighting($templateParams, $rowsBefore); | ||
| } | ||
| } | ||
|
|
||
|
|
@@ -195,7 +271,7 @@ protected function addResultsToView( | |
| */ | ||
| protected function applyTopicDelimiters(&$result): void | ||
| { | ||
| $config = $this->getConfigArray(); | ||
| $config = $this->config; | ||
|
|
||
| foreach ($result['Browse']['items'] as &$item) { | ||
| $item['heading'] = str_replace( | ||
|
|
@@ -207,21 +283,21 @@ protected function applyTopicDelimiters(&$result): void | |
| } | ||
|
|
||
| /** | ||
| * Apply highlighting settings to the view based on the result set. | ||
| * Apply highlighting settings to the template params based on the result set. | ||
| * | ||
| * @param ViewModel $view View model to be updated (must already contain | ||
| * results) | ||
| * @param int $rowsBefore Number of rows to display before highlighted row | ||
| * @param array $templateParams Template params to be updated (must already contain results) | ||
| * @param int $rowsBefore Number of rows to display before highlighted row | ||
| * | ||
| * @return void | ||
| */ | ||
| protected function applyHighlighting(ViewModel $view, int $rowsBefore): void | ||
| protected function applyHighlighting(array &$templateParams, int $rowsBefore): void | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Would it make sense to have this function return the modified array instead of changing it by reference? I don't have a strong preference, but I try to avoid manipulation by reference when feasible since it can be a little less clear. (And, of course, same question applies to addResultsToTemplateParams above). |
||
| { | ||
| $startRow = $view->result['Browse']['startRow']; | ||
| $browseResult = $templateParams['result']['Browse']; | ||
| $startRow = $browseResult['startRow']; | ||
| // solr counts rows from 1; adjust to array position style | ||
| $startRow_adj = $startRow - 1; | ||
| $offset = $view->result['Browse']['offset']; | ||
| $totalRows = $view->result['Browse']['totalCount']; | ||
| $offset = $browseResult['offset']; | ||
| $totalRows = $browseResult['totalCount']; | ||
| $totalRows += $startRow + $offset > 0 ? $startRow_adj + $offset : 0; | ||
|
|
||
| // normal case: somewhere in the middle of the browse list | ||
|
|
@@ -233,58 +309,9 @@ protected function applyHighlighting(ViewModel $view, int $rowsBefore): void | |
| // special case: we've gone past the end | ||
| // only the rowsBefore records will have been returned | ||
| if ($startRow > $totalRows) { | ||
| $view->highlight_end = true; | ||
| $templateParams['highlight_end'] = true; | ||
| } | ||
| $view->highlight_row = $highlight_row; | ||
| $view->match_type = $view->result['Browse']['matchType']; | ||
| } | ||
|
|
||
| /** | ||
| * Gathers data for the view of the AlphaBrowser and does some initialization. | ||
| * | ||
| * @return ViewModel | ||
| */ | ||
| public function homeAction(): ViewModel | ||
| { | ||
| // Load config parameters | ||
| $config = $this->getConfigArray(); | ||
| $rowsBefore = ctype_digit((string)($config['AlphaBrowse']['rows_before'] ?? '-')) | ||
| ? (int)$config['AlphaBrowse']['rows_before'] : 0; | ||
| $limit = ctype_digit((string)($config['AlphaBrowse']['page_size'] ?? '-')) | ||
| ? (int)$config['AlphaBrowse']['page_size'] : 20; | ||
|
|
||
| // Process incoming parameters: | ||
| $source = $this->params()->fromQuery('source', false); | ||
| $from = $this->params()->fromQuery('from', false); | ||
| $page = intval($this->params()->fromQuery('page', 0)); | ||
|
|
||
| // Load highlighting configuration while accounting for special case: | ||
| // highlighting is pointless if there's no user input: | ||
| $highlighting = empty($from) ? false : $config['AlphaBrowse']['highlighting'] ?? false; | ||
|
|
||
| // Set up any extra parameters to pass | ||
| $extras = $this->getExtras($config); | ||
|
|
||
| // Create view model: | ||
| $view = $this->createViewModel( | ||
| [ | ||
| 'alphaBrowseTypes' => $this->getTypes($config), | ||
| 'from' => $from, | ||
| 'source' => $source, | ||
| 'extras' => array_filter(explode(':', $extras[$source] ?? '')), | ||
| ] | ||
| ); | ||
|
|
||
| // If required parameters are present, load results: | ||
| $this->addResultsToView( | ||
| $view, | ||
| $page, | ||
| $limit, | ||
| $rowsBefore, | ||
| $highlighting, | ||
| $extras | ||
| ); | ||
|
|
||
| return $view; | ||
| $templateParams['highlight_row'] = $highlight_row; | ||
| $templateParams['match_type'] = $browseResult['matchType']; | ||
| } | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe it's cleaner to just use
$this->configin line 279 below; this assignment doesn't really seem necessary.