/** * Set up filters based on VuFind settings. * * @param ParamBag $params Parameter collection to update * * @return void */ public function createBackendFilterParameters(ParamBag $params) { // flag our non-Standard checkbox filters: $foundIncludeNewspapers = false; # includeNewspapers $foundIncludeWithoutFulltext = false; # includeWithoutFulltext $filterList = $this->getFilterList(); // Which filters should be applied to our query? if (!empty($filterList)) { // Loop through all filters and add appropriate values to request: foreach ($filterList as $filterArray) { foreach ($filterArray as $filt) { $safeValue = SummonQuery::escapeParam($filt['value']); if ($filt['field'] == 'holdingsOnly') { // Special case -- "holdings only" is a separate parameter from // other facets. $params->set('holdings', strtolower(trim($safeValue)) == 'true'); } else { if ($filt['field'] == 'excludeNewspapers') { // support a checkbox for excluding newspapers: // this is now the default behaviour. } else { if ($filt['field'] == 'includeNewspapers') { // explicitly include newspaper articles $foundIncludeNewspapers = true; } else { if ($range = SolrUtils::parseRange($filt['value'])) { // Special case -- range query (translate [x TO y] syntax): $from = SummonQuery::escapeParam($range['from']); $to = SummonQuery::escapeParam($range['to']); $params->add('rangeFilters', "PublicationDate,{$from}:{$to}"); } else { if ($filt['field'] == 'includeWithoutFulltext') { $foundIncludeWithoutFulltext = true; } else { // Standard case: $params->add('filters', "{$filt['field']},{$safeValue}"); } } } } } } } } // special cases (apply also when filter list is empty) // newspaper articles if (!$foundIncludeNewspapers) { // this actually means: do *not* show newspaper articles $params->add('filters', "ContentType,Newspaper Article,true"); } // combined facet "with holdings/with fulltext" if (!$foundIncludeWithoutFulltext) { $params->set('holdings', true); $params->add('filters', 'IsFullText,true'); } else { $params->set('holdings', false); } }
/** * Test parseRange functionality. * * @return void */ public function testParseRange() { // basic range test: $result = Utils::parseRange("[1 TO 100]"); $this->assertEquals('1', $result['from']); $this->assertEquals('100', $result['to']); // test whitespace handling: $result = Utils::parseRange("[1 TO 100]"); $this->assertEquals('1', $result['from']); $this->assertEquals('100', $result['to']); // test invalid ranges: $this->assertFalse(Utils::parseRange('1 TO 100')); $this->assertFalse(Utils::parseRange('[not a range to me]')); }
/** * Get new items facets (facet titles) * * @return array */ public function getNewItemsFacets() { if (!isset($this->newItemsFacets)) { return []; } $filters = $this->results->getParams()->getFilters(); $result = []; foreach ($this->newItemsFacets as $current) { $from = ''; if (isset($filters[$current])) { foreach ($filters[$current] as $filter) { if ($range = SolrUtils::parseRange($filter)) { $from = $range['from'] == '*' ? '' : $range['from']; break; } } } $result[$current] = ['raw' => $from, 'date' => preg_match('/^\\d{4}-\\d{2}-\\d{2}/', $from) ? substr($from, 0, 10) : str_replace('/DAY', '', $from)]; } return $result; }
/** * Get the current settings for the specified range facet, if it is set: * * @param array $fields Fields to check * @param string $type Type of range to include in return value * @param object $savedSearch Saved search object (false if none) * * @return array */ protected function getRangeSettings($fields, $type, $savedSearch = false) { $parts = []; foreach ($fields as $field) { // Default to blank strings: $from = $to = ''; // Check to see if there is an existing range in the search object: if ($savedSearch) { $filters = $savedSearch->getParams()->getFilters(); if (isset($filters[$field])) { foreach ($filters[$field] as $current) { if ($range = SolrUtils::parseRange($current)) { $from = $range['from'] == '*' ? '' : $range['from']; $to = $range['to'] == '*' ? '' : $range['to']; $savedSearch->getParams()->removeFilter($field . ':' . $current); break; } } } } // Send back the settings: $parts[] = ['field' => $field, 'type' => $type, 'values' => [$from, $to]]; } return $parts; }
/** * Support function to get publication date range. Return string in the form * "YYYY-YYYY" * * @param string $field Name of filter field to check for * date limits * @param \VuFind\Search\Params\Base $params Search parameter object * @param \Zend\StdLib\Parameters $request Parameter object representing user * request. * * @return string */ protected function getPublishedDates($field, $params, $request) { // Try to extract range details from request parameters or SearchObject: $from = $request->get($field . 'from'); $to = $request->get($field . 'to'); if (!is_null($from) && !is_null($to)) { $range = ['from' => $from, 'to' => $to]; } else { if (is_object($params)) { $currentFilters = $params->getFilters(); if (isset($currentFilters[$field][0])) { $range = SolrUtils::parseRange($currentFilters[$field][0]); } } } // Normalize range if we found one: if (isset($range)) { if (empty($range['from']) || $range['from'] == '*') { $range['from'] = 0; } if (empty($range['to']) || $range['to'] == '*') { $range['to'] = date('Y') + 1; } return $range['from'] . '-' . $range['to']; } // No range found? Return empty string: return ''; }
/** * Format a single filter for use in getFilterList(). * * @param string $field Field name * @param string $value Field value * @param string $operator Operator (AND/OR/NOT) * @param bool $translate Should we translate the label? * * @return array */ protected function formatFilterListEntry($field, $value, $operator, $translate) { if (!in_array($field, $this->newItemsFacets) || !($range = Utils::parseRange($value))) { $result = parent::formatFilterListEntry($field, $value, $operator, $translate); return $this->formatDateRangeFilterListEntry($result, $field, $value); } $domain = $this->getOptions()->getTextDomainForTranslatedFacet($field); list($from, $fromDate) = $this->formatNewItemsDateForDisplay($range['from'], $domain); list($to, $toDate) = $this->formatNewItemsDateForDisplay($range['to'], $domain); $ndash = html_entity_decode('–', ENT_NOQUOTES, 'UTF-8'); if ($fromDate && $toDate) { $displayText = $from ? "{$from} {$ndash}" : $ndash; $displayText .= $to ? " {$to}" : ''; } else { $displayText = $from; $displayText .= $to ? " {$ndash} {$to}" : ''; } return compact('value', 'displayText', 'field', 'operator'); }
/** * Set up filters based on VuFind settings. * * @param ParamBag $params Parameter collection to update * * @return void */ public function createBackendFilterParameters(ParamBag $params) { // Which filters should be applied to our query? $filterList = $this->getFilterList(); if (!empty($filterList)) { $orFacets = []; // Loop through all filters and add appropriate values to request: foreach ($filterList as $filterArray) { foreach ($filterArray as $filt) { $safeValue = SummonQuery::escapeParam($filt['value']); // Special case -- "holdings only" is a separate parameter from // other facets. if ($filt['field'] == 'holdingsOnly') { $params->set('holdings', strtolower(trim($safeValue)) == 'true'); } else { if ($filt['field'] == 'queryExpansion') { // Special case -- "query expansion" is a separate parameter // from other facets. $params->set('expand', strtolower(trim($safeValue)) == 'true'); } else { if ($filt['field'] == 'excludeNewspapers') { // Special case -- support a checkbox for excluding // newspapers: $params->add('filters', "ContentType,Newspaper Article,true"); } else { if ($range = SolrUtils::parseRange($filt['value'])) { // Special case -- range query (translate [x TO y] syntax): $from = SummonQuery::escapeParam($range['from']); $to = SummonQuery::escapeParam($range['to']); $params->add('rangeFilters', "{$filt['field']},{$from}:{$to}"); } else { if ($filt['operator'] == 'OR') { // Special case -- OR facets: $orFacets[$filt['field']] = isset($orFacets[$filt['field']]) ? $orFacets[$filt['field']] : []; $orFacets[$filt['field']][] = $safeValue; } else { // Standard case: $fq = "{$filt['field']},{$safeValue}"; if ($filt['operator'] == 'NOT') { $fq .= ',true'; } $params->add('filters', $fq); } } } } } } // Deal with OR facets: foreach ($orFacets as $field => $values) { $params->add('groupFilters', $field . ',or,' . implode(',', $values)); } } } }
/** * Return range facet information in a format processed for use in the view. * * @param string $property Name of property containing active range facets * * @return array Array of from/to value arrays keyed by field. */ protected function getRangeFacets($property) { $filters = $this->results->getParams()->getFilters(); $result = []; if (isset($this->{$property}) && is_array($this->{$property})) { foreach ($this->{$property} as $current) { $from = $to = ''; if (isset($filters[$current])) { foreach ($filters[$current] as $filter) { if ($range = SolrUtils::parseRange($filter)) { $from = $range['from'] == '*' ? '' : $range['from']; $to = $range['to'] == '*' ? '' : $range['to']; break; } } } $result[$current] = [$from, $to]; } } return $result; }
/** * Set up filters based on VuFind settings. * * @param array $filterList Filter settings * * @return void */ public function initFilters($filterList) { // Which filters should be applied to our query? if (!empty($filterList)) { // Loop through all filters and add appropriate values to request: foreach ($filterList as $filterArray) { foreach ($filterArray as $filt) { $safeValue = self::escapeParam($filt['value']); // Special case -- "holdings only" is a separate parameter from // other facets. if ($filt['field'] == 'holdingsOnly') { $this->setHoldings(strtolower(trim($safeValue)) == 'true'); } else { if ($filt['field'] == 'excludeNewspapers') { // Special case -- support a checkbox for excluding // newspapers: $this->addFilter("ContentType,Newspaper Article,true"); } else { if ($range = SolrUtils::parseRange($filt['value'])) { // Special case -- range query (translate [x TO y] syntax): $from = self::escapeParam($range['from']); $to = self::escapeParam($range['to']); $this->addRangeFilter("{$filt['field']},{$from}:{$to}"); } else { // Standard case: $this->addFilter("{$filt['field']},{$safeValue}"); } } } } } } }
/** * Process the publicationd date range limiter widget * * @param object $searchObject Saved search object (false if none) * * @return array To and from dates */ protected function processPublicationDateRange($searchObject = false) { $from = $to = ''; if ($searchObject) { $filters = $searchObject->getParams()->getFilterList(); foreach ($filters as $key => $value) { if ('PublicationDate' == $key) { if ($range = SolrUtils::parseRange($value[0]['value'])) { $from = $range['from'] == '*' ? '11' : $range['from']; $to = $range['to'] == '*' ? '12' : $range['to']; } $searchObject->getParams()->removeFilter($key . ':' . $value[0]['value']); break; } } } return [$from, $to]; }
/** * Get the current settings for the date range facet, if it is set: * * @param object $savedSearch Saved search object (false if none) * * @return array Date range: Key 0 = from, Key 1 = to. */ protected function getDateRangeSettings($savedSearch = false) { // Default to blank strings: $from = $to = ''; // Check to see if there is an existing range in the search object: if ($savedSearch) { $filters = $savedSearch->getParams()->getFilters(); if (isset($filters['publishDate'])) { foreach ($filters['publishDate'] as $current) { if ($range = SolrUtils::parseRange($current)) { $from = $range['from'] == '*' ? '' : $range['from']; $to = $range['to'] == '*' ? '' : $range['to']; $savedSearch->getParams()->removeFilter('publishDate:' . $current); break; } } } } // Send back the settings: return array($from, $to); }
/** * Get new items facets (facet titles) * * @return array */ public function getNewItemsFacets() { $filters = $this->results->getParams()->getFilters(); $result = []; foreach ($this->newItemsFacets as $current) { $from = ''; if (isset($filters[$current])) { foreach ($filters[$current] as $filter) { if ($range = SolrUtils::parseRange($filter)) { $from = $range['from'] == '*' ? '' : $range['from']; break; } } } $translatable = ''; if (preg_match('/^NOW-(\\w+)/', $from, $matches)) { $translatable = 'new_items_' . strtolower($matches[1]); } $result[$current] = ['raw' => $from, 'translatable' => $translatable]; } return $result; }
/** * getDateFacets * * Return date facet information in a format processed for use in the view. * * @return array Array of from/to value arrays keyed by field. */ public function getDateFacets() { $filters = $this->results->getParams()->getFilters(); $result = array(); foreach ($this->dateFacets as $current) { $from = $to = ''; if (isset($filters[$current])) { foreach ($filters[$current] as $filter) { if ($range = SolrUtils::parseRange($filter)) { $from = $range['from'] == '*' ? '' : $range['from']; $to = $range['to'] == '*' ? '' : $range['to']; break; } } } $result[$current] = array($from, $to); } return $result; }