import {Component, Input, Output, ViewChild} from '@angular/core'; import {Location} from '@angular/common'; import {ActivatedRoute, Router} from '@angular/router'; import {Meta, Title} from '@angular/platform-browser'; import {AdvancedField, Filter, Value} from './searchHelperClasses.class'; import {SearchCustomFilter, SearchUtilsClass} from './searchUtils.class'; import {ModalLoading} from '../../utils/modal/loading.component'; import {Dates, DOI, Identifier, StringUtils} from '../../utils/string-utils.class'; import {ErrorCodes} from '../../utils/properties/errorCodes'; import {RouterHelper} from '../../utils/routerHelper.class'; import {PiwikService} from '../../utils/piwik/piwik.service'; import {EnvProperties} from '../../utils/properties/env-properties'; import {SEOService} from '../../sharedComponents/SEO/SEO.service'; import {HelperService} from "../../utils/helper/helper.service"; import {SearchFields} from "../../utils/properties/searchFields"; import {RefineResultsUtils} from "../../services/servicesUtils/refineResults.class"; import {RangeFilter} from "../../utils/rangeFilter/rangeFilterHelperClasses.class"; import {ZenodoInformationClass} from "../../deposit/utils/zenodoInformation.class"; @Component({ selector: 'new-search-page', templateUrl: 'newSearchPage.component.html' }) export class NewSearchPageComponent { @Input() piwikSiteId = null; @Input() hasPrefix: boolean = true; @Input() pageTitle = ""; @Input() results = []; @Input() type; @Input() entityType; @Input() searchUtils: SearchUtilsClass = new SearchUtilsClass(); @Input() fieldIds: string[]; @Input() fieldIdsMap;//:{ [key:string]:{ name:string, operator:string, type:string, indexField:string, equalityOperator:string }} ; @Input() selectedFields: AdvancedField[]; @ViewChild(ModalLoading) loading: ModalLoading; @Input() csvParams: string; @Input() csvPath: string; @Input() simpleSearchLink: string = ""; @Input() advancedSearchLink: string = ""; @Input() disableForms: boolean = false; @Input() loadPaging: boolean = true; @Input() oldTotalResults: number = 0; @Input() openaireLink: string; @Input() customFilter: SearchCustomFilter = null; @Input() sort: boolean = false; @Input() searchFormClass: string = "searchForm"; //From simple: @Input() rangeFilters: RangeFilter[] = []; @Input() rangeFields: string[][] = []; @Input() refineFields = []; @Input() filters = []; selectedFilters: number = 0; selectedRangeFilters: number = 0; private searchFieldsHelper: SearchFields = new SearchFields(); @Input() newQueryButton: boolean = true; public showUnknownFilters: boolean = false; // when a filter exists in query but has no results, so no filters returned from the query URLCreatedFilters: Filter[] = []; URLCreatedRangeFilters: RangeFilter[] = []; @Input() showRefine: boolean = true; @Input() tableViewLink: string; @Input() usedBy: string = "search"; @Input() public zenodoInformation: ZenodoInformationClass = new ZenodoInformationClass(); @Input() showLastIndex: boolean = true; @Input() showResultCount: boolean = true; @Input() showMoreFilterValuesInline: boolean = true; @Input() filterValuesNum: number = 6; @Input() keywordFields = []; @Input() simpleView: boolean = true; @Input() formPlaceholderText = "Type Keywords..."; @Input() resultTypes = null; @Input() quickFilter: { filter: Filter, selected: boolean, filterId: string, value: string }; @Input() includeOnlyResultsAndFilter:boolean = false; piwiksub: any; public parameterNames: string[] = []; public parameterValues: string[] = []; public csvLimit: number = 0; public pagingLimit: number = 0; public resultsPerPage: number = 0; isPiwikEnabled = false; properties: EnvProperties; public pageContents = null; public divContents = null; public routerHelper: RouterHelper = new RouterHelper(); public errorCodes: ErrorCodes = new ErrorCodes(); url = null; @Input() entitiesSelection:boolean = true; @Input() showAdvancedSearchLink:boolean = true; constructor(private route: ActivatedRoute, private location: Location, private _meta: Meta, private _title: Title, private _piwikService: PiwikService, private router: Router, private seoService: SEOService, private helper: HelperService) { } ngOnInit() { this.route.data .subscribe((data: { envSpecific: EnvProperties }) => { this.properties = data.envSpecific; //this.getDivContents(); this.getPageContents(); this.pagingLimit = data.envSpecific.pagingLimit; this.resultsPerPage = data.envSpecific.resultsPerPage; this.csvLimit = data.envSpecific.csvLimit; this.isPiwikEnabled = data.envSpecific.enablePiwikTrack; if (typeof window !== 'undefined') { this.updateUrl(data.envSpecific.baseLink + location.pathname); this.url = data.envSpecific.baseLink + location.pathname } if (typeof document !== 'undefined' && this.isPiwikEnabled) { this.piwiksub = this._piwikService.trackView(this.properties, this.pageTitle, this.piwikSiteId).subscribe(); } }); var description = "Openaire, search, repositories, open access, type, content provider, funder, project, " + this.pageTitle; this.updateTitle(this.pageTitle); this.updateDescription(description); this.searchUtils.baseUrl = "/" + this.searchUtils.baseUrl; this.seoService.createLinkForCanonicalURL(this.properties.baseLink + this.router.url, false); } private getPageContents() { this.helper.getPageHelpContents(this.router.url, this.properties, (this.customFilter) ? this.customFilter.valueId : null).subscribe(contents => { this.pageContents = contents; }) } private getDivContents() { this.helper.getDivHelpContents(this.router.url, this.properties, (this.customFilter) ? this.customFilter.valueId : null).subscribe(contents => { this.divContents = contents; }) } ngOnDestroy() { if (this.piwiksub) { this.piwiksub.unsubscribe(); } } updateDescription(description: string) { this._meta.updateTag({content: description}, "name='description'"); this._meta.updateTag({content: description}, "property='og:description'"); } updateTitle(title: string) { var _prefix = ""; if (this.hasPrefix) { _prefix = "OpenAIRE | "; } var _title = _prefix + ((title.length > 50) ? title.substring(0, 50) : title); this._title.setTitle(_title); this._meta.updateTag({content: _title}, "property='og:title'"); } updateUrl(url: string) { this._meta.updateTag({content: url}, "property='og:url'"); } clearFilters() { for (var i = 0; i < this.filters.length; i++) { for (var j = 0; j < this.filters[i].countSelectedValues; j++) { if (this.filters[i].values[j].selected) { this.filters[i].values[j].selected = false; } this.filters[i].countSelectedValues = 0; } } this.selectedFilters = 0; for(let i = 0; i < this.rangeFilters.length; i++) { this.rangeFilters[i].selectedFromValue = null; this.rangeFilters[i].selectedToValue = null; } this.selectedRangeFilters = 0; if (this.quickFilter) { this.removeValueFromQuickFilter(); } this.goTo(1); // this.clearKeywords(); } goTo(page: number = 1) { this.searchUtils.page = page; this.buildPageURLParameters(this.filters, this.rangeFilters, true); this.router.navigate([this.searchUtils.baseUrl], {queryParams: this.routerHelper.createQueryParams(this.parameterNames, this.parameterValues)}); /* Code For Piwik*/ if (typeof localStorage !== 'undefined') { //console.log("In PreviousRouteRecorder : "+this.router.url ); localStorage.setItem('previousRoute', this.router.url); } if (this.isPiwikEnabled && (typeof document !== 'undefined')) { this.piwiksub = this._piwikService.trackView(this.properties, this.pageTitle, this.piwikSiteId).subscribe(); } /* End Piwik Code */ } queryChanged() { this.goTo(1); } sizeChanged($event) { this.searchUtils.size = $event.value; this.goTo(1); } sortByChanged($event) { this.searchUtils.sortBy = $event.value; this.goTo(1); } getOperatorParameter(parameter: string): string { for (let id of this.fieldIds) { if (this.fieldIdsMap[id]["param"] == parameter) { return this.fieldIdsMap[id]["operator"]; } } } /* * Get A sub-array of this.refineFields array, which contains the ids of the selected filters */ public getSelectedFilters(): string[] { var selected: string[] = []; for (var i = 0; i < this.filters.length; i++) { var filter: Filter = this.filters[i]; if (filter.countSelectedValues > 0) { selected.push(filter.filterId); } } return selected; } /* * Get A sub-array of this.refineFields array, which contains the ids of the selected parameters */ private getSelectedParameters(): string[] { var selected: string[] = []; for (var i = 0; i < this.refineFields.length; i++) { if (this.parameterNames.indexOf(this.refineFields[i]) != -1) { selected.push(this.refineFields[i]); } } return selected; } /* * Get A sub-array of this.refineFields array, which hides hidden fields (e.g Funding level 0,1,2,..), and contains those that depend on another fields (e.g Funding level 0 if Funder is selected ) */ public getFields(): string[] { var selected_filters: string[] = this.getSelectedFilters(); if (selected_filters.length == 0) { selected_filters = this.getSelectedParameters(); } var fields: string[] = []; for (var i = 0; i < this.refineFields.length; i++) { var dependentTo = this.searchFieldsHelper.DEPENDENT_FIELDS[this.refineFields[i]]; //if filter is not marked as hidden OR it is hidden but it is dependent to a field that it IS selected if (this.searchFieldsHelper.HIDDEN_FIELDS.indexOf(this.refineFields[i]) == -1 || (selected_filters.indexOf(dependentTo) != -1) || (selected_filters.indexOf(this.refineFields[i]) != -1)) { fields.push(this.refineFields[i]); } } return fields; } /* * Get a query string of all fields, that want to get from search (e.g. &fields=funderid&fields=projectstartyear&...)) */ public getRefineFieldsQuery(): string { var fields: string[] = this.getFields(); var fieldsStr = "" for (var i = 0; i < fields.length; i++) { fieldsStr += "&fields=" + fields[i]; } return "&refine=true" + fieldsStr; } /* * Mark as check the new filters that are selected, when you get them from search */ public checkSelectedFilters(filters: Filter[]) { this.filters = filters; for (var i = 0; i < filters.length; i++) { var filter: Filter = filters[i]; filter.countSelectedValues = 0; if (this.parameterNames.indexOf(filter.filterId) != -1) { let values = (decodeURIComponent(this.parameterValues[this.parameterNames.indexOf(filter.filterId)])).split(/,(?=(?:[^\"]*\"[^\"]*\")*[^\"]*$)/, -1); for (let filterValue of filter.values) { if (values.indexOf(StringUtils.quote(filterValue.id)) > -1) { filterValue.selected = true; filter.countSelectedValues++; } else { filterValue.selected = false; } } } else if (this.quickFilter && this.quickFilter.filterId == filter.filterId && this.quickFilter.selected) { for (let filterValue of filter.values) { if (filterValue.id == this.quickFilter.value) { filterValue.selected = true; filter.countSelectedValues++; } else { filterValue.selected = false; } } } else { for (let filterValue of filter.values) { filterValue.selected = false; } } if (this.quickFilter && filter.filterId == this.quickFilter.filterId) { this.quickFilter.filter = filter; } } this.filterFilterValues(this.filters); return filters; } /* * Mark as check the new range filters that are selected */ public checkSelectedRangeFilters(filters: RangeFilter[]) { //console.log("checkSelectedRangeFilters: parameterNames.length: "+this.parameterNames.length); this.rangeFilters = filters; for (let i = 0; i < filters.length; i++) { let filter: RangeFilter = filters[i]; if (this.parameterNames.indexOf(filter.filterId) != -1) { //console.log(filter.filterId + " "+this.parameterNames.indexOf(filter.filterId) ); let values = (decodeURIComponent(this.parameterValues[this.parameterNames.indexOf(filter.filterId)])).split(/,(?=(?:[^\"]*\"[^\"]*\")*[^\"]*$)/, -1); let operators: string [] = (StringUtils.URIDecode(this.parameterValues[this.parameterNames.indexOf(filter.filterId)])).split(/,(?=(?:[^\"]*\"[^\"]*\")*[^\"]*$)/, -1); if (values.length == operators.length) { for (let j = 0; j < values.length; j++) { if (this.fieldIdsMap[filter.originalFilterIdFrom+"-range-"+filter.originalFilterIdTo].filterType == "range") { let value: string = StringUtils.unquote(values[j]); let validDates: boolean = true; let years: string[] = (value.substring(5)).split(":"); let yearFrom: string = (Dates.isValidYear(years[0]) ? years[0] : null); let yearTo: string = (Dates.isValidYear(years[1]) ? years[1] : null); //console.log("checkSelectedRangeFilters: yearFrom: " + yearFrom + " - yearTo: "+yearTo); if(yearFrom) { filter.selectedFromValue = yearFrom; } if(yearTo) { filter.selectedToValue = yearTo; } if(yearFrom && yearTo) { filter.selectedFromAndToValues = yearFrom + "-" + yearTo; } else if(yearFrom) { filter.selectedFromAndToValues = "From " + yearFrom; } else if(yearTo) { filter.selectedFromAndToValues = "Until " + yearTo; } if(!yearFrom && !yearTo) { validDates = false; } // if (value.length < 14) { // validDates = false; // console.log("not valid (length<14)"); // } else { // if (!Dates.isValidYear(value.substring(5, 9)) || !Dates.isValidYear(value.substring(10, 14))) { // validDates = false; // console.log("not valid years"); // } else { // filter.selectedFromValue = value.substring(5, 9); // filter.selectedToValue = value.substring(10, 14); // console.log(filter); // } // } } } } } else { filter.selectedFromValue = null; filter.selectedToValue = null; } } return this.rangeFilters; } /* * For Funder filters - if funder selected */ public filterFilterValues(filters: Filter[]) { var funders = []; var funder_prefix = []; for (var i = 0; i < filters.length; i++) { var filter: Filter = filters[i]; // console.log(filter.filterId); if (filter.filterId.indexOf("funder") != -1 && this.parameterNames.indexOf(filter.filterId) != -1) { let funders = (decodeURIComponent(this.parameterValues[this.parameterNames.indexOf(filter.filterId)])).split(/,(?=(?:[^\"]*\"[^\"]*\")*[^\"]*$)/, -1); for (let funder of funders) { funder_prefix.push(StringUtils.unquote(funder).split("____")[0]); } // console.log(funder_prefix ); } else if (filter.filterId.indexOf("funding") != -1) { // console.log(" funding: "+filter.filterId ); var filteredValues = [] for (let filterValue of filter.values) { var value_prefix = filterValue.id.split("____")[0]; // console.log("Value prefix: "+value_prefix ); if (funder_prefix.indexOf(value_prefix) != -1) { // console.log("here" + value_prefix); filteredValues.push(filterValue); } } if (filteredValues.length > 0) { filter.values = filteredValues; } } } return filters; } public countSelectedFilters(filters: Filter[]): number { this.selectedFilters = 0; for (let filter of filters) { if (filter.countSelectedValues > 0) { this.selectedFilters += filter.countSelectedValues; } } return this.selectedFilters; } public countSelectedRangeFilters(rangeFilters: RangeFilter[]) : number { this.selectedRangeFilters = 0; for(let filter of rangeFilters) { if(filter.selectedFromValue || filter.selectedToValue) { this.selectedRangeFilters++; } } return this.selectedRangeFilters; } private clearKeywords() { if (this.searchUtils.keyword.length > 0) { this.searchUtils.keyword = ''; } this.goTo(1); } public removeFilter(value: Value, filter: Filter) { filter.countSelectedValues--; this.selectedFilters--; if (value.selected == true) { value.selected = false; } if (this.quickFilter && this.quickFilter.filterId == filter.filterId) { this.removeValueFromQuickFilter(); } this.goTo(1); } public removeRangeFilter(filter: RangeFilter) { filter.selectedFromValue = null; filter.selectedToValue = null; this.goTo(1); } getSelectedValues(filter): any { var selected = []; if (filter.countSelectedValues > 0) { for (var i = 0; i < filter.values.length; i++) { if (filter.values[i].selected) { selected.push(filter.values[i]); } } } return selected; } filterChanged($event) { if (this.quickFilter && this.quickFilter.filter) { this.removeValueFromQuickFilter(); } this.goTo(1); } /** * if there is a change in the values of the quick filter, this function has to be run, to also update the quickFilter */ removeValueFromQuickFilter() { if (this.quickFilter.filter.countSelectedValues == 0) { this.quickFilter.selected = false; } else { let isQuickEnabled = false; for (let filterValue of this.quickFilter.filter.values) { isQuickEnabled = (filterValue.name == this.quickFilter.value) } this.quickFilter.selected = (isQuickEnabled && this.quickFilter.filter.countSelectedValues == 1); } } // for loading public openLoading() { this.loading.open(); } public closeLoading() { this.loading.close(); } /** * Build advanced search Filters based on the URL parameters * @param params */ createAdvancedSearchSelectedFiltersFromNewURLParameters(params) { for (let i = 0; i < Object.keys(params).length; i++) { if(params["f"+i] && params["fv"+i] ) { let fieldId = params["f" + i].split(",")[0]; let operator = (params["f" + i].split(",").length >1 )?params["f" + i].split(",")[1]:"and"; let fieldparam = (this.fieldIdsMap[fieldId]) ? this.fieldIdsMap[fieldId].param : ""; if (!this.fieldIdsMap[fieldId]) { console.error("Field: " + fieldId + " not found in fieldIds map"); continue; } let value: string = StringUtils.URIDecode(params["fv"+i]); if (this.fieldIdsMap[fieldId].type == "date") { let validDates: boolean = true; let dateField: AdvancedField = new AdvancedField(fieldId, fieldparam, this.fieldIdsMap[fieldId].name, this.fieldIdsMap[fieldId].type, value, operator); if (value.indexOf("range") != -1) { dateField.dateValue.type = "range"; if (value.length < 26) { validDates = false; } else { if (!Dates.isValidDate(value.substring(5, 15)) || !Dates.isValidDate(value.substring(16, 26))) { validDates = false; } else { dateField.dateValue.from = Dates.getDateFromString(value.substring(5, 15)); dateField.dateValue.to = Dates.getDateFromString(value.substring(16, 26)); } } // "rangeYYYY-MM-DD:YYYY-MM-DD" } else { dateField.dateValue.setDatesByType(value); } if (validDates) { this.selectedFields.push(dateField); } } else { this.selectedFields.push(new AdvancedField(fieldId, fieldparam, this.fieldIdsMap[fieldId].name, this.fieldIdsMap[fieldId].type,value, operator)); } } } } /** * Build advanced search Filters based on the URL parameters * @param params */ createAdvancedSearchSelectedFiltersFromURLParameters(params) { this.createAdvancedSearchSelectedFiltersFromNewURLParameters(params); for (var i = 0; i < this.fieldIds.length; i++) { var fieldId = this.fieldIds[i]; var fieldparam = (this.fieldIdsMap[fieldId]) ? this.fieldIdsMap[fieldId].param : ""; if (!this.fieldIdsMap[fieldId]) { console.error("Field: " + fieldId + " not found in fieldIds map"); continue; } var operatorId = this.getOperatorParameter(fieldparam); if (params[fieldparam] != undefined && params[operatorId] != undefined) { var values: string [] = StringUtils.URIDecode(params[fieldparam]).split(/,(?=(?:[^\"]*\"[^\"]*\")*[^\"]*$)/, -1); var operators: string [] = (StringUtils.URIDecode(params[operatorId])).split(/,(?=(?:[^\"]*\"[^\"]*\")*[^\"]*$)/, -1); if (values.length == operators.length) { for (var j = 0; j < values.length; j++) { if (this.fieldIdsMap[fieldId].type == "date") { var value: string = StringUtils.unquote(values[j]); var validDates: boolean = true; var dateField: AdvancedField = new AdvancedField(fieldId, fieldparam, this.fieldIdsMap[fieldId].name, this.fieldIdsMap[fieldId].type, value, operators[j]); if (value.indexOf("range") != -1) { dateField.dateValue.type = "range"; if (value.length < 26) { validDates = false; } else { if (!Dates.isValidDate(value.substring(5, 15)) || !Dates.isValidDate(value.substring(16, 26))) { validDates = false; } else { dateField.dateValue.from = Dates.getDateFromString(value.substring(5, 15)); dateField.dateValue.to = Dates.getDateFromString(value.substring(16, 26)); } } // "rangeYYYY-MM-DD:YYYY-MM-DD" } else { dateField.dateValue.setDatesByType(value); } if (validDates) { this.selectedFields.push(dateField); } } else { this.selectedFields.push(new AdvancedField(fieldId, fieldparam, this.fieldIdsMap[fieldId].name, this.fieldIdsMap[fieldId].type, values[j], operators[j])); } } } } } if (params['keyword'] && params['keyword'].length > 0) { this.selectedFields.push(new AdvancedField(this.fieldIds[0], this.fieldIdsMap[this.fieldIds[0]].param, this.fieldIdsMap[this.fieldIds[0]].name, this.fieldIdsMap[this.fieldIds[0]].type, params['keyword'], "and")); } if (this.selectedFields.length == 0) { this.selectedFields.push(new AdvancedField(this.fieldIds[0], this.fieldIdsMap[this.fieldIds[0]].param, this.fieldIdsMap[this.fieldIds[0]].name, this.fieldIdsMap[this.fieldIds[0]].type, "", "and")); } } /** * Create Search API query based on the selected fields of the advanced form */ getSearchAPIQueryForAdvancedSearhFields() { var params = ""; var countParams = 0; for (var i = 0; i < this.selectedFields.length; i++) { if (this.fieldIdsMap[this.selectedFields[i].id] != undefined && (this.selectedFields[i].value != "" || this.selectedFields[i].type == "date")) { //console.log("createQueryParameters::"+this.selectedFields[i].type); if (this.selectedFields[i].type == "date") { if (this.selectedFields[i].dateValue.type != "any") { params += (countParams == 0 ? "" : this.selectedFields[i].operatorId) + " " + this.selectedFields[i].id + this.fieldIdsMap[this.selectedFields[i].id].equalityOperator + '"' + StringUtils.URIEncode(Dates.getDateToString(this.selectedFields[i].dateValue.from)) + " " + StringUtils.URIEncode(Dates.getDateToString(this.selectedFields[i].dateValue.to)) + '"' + " "; } } else { if (this.selectedFields[i].id == "q") { console.log(this.selectedFields[i].value) var op = ""; var doisParams = ""; if ((this.entityType == 'publication' || this.entityType == 'dataset' || this.entityType == 'software' || this.entityType == 'other' || this.entityType == "result")) { var DOIs: Identifier[] = Identifier.getIdentifiersFromString(this.selectedFields[i].value); for (let identifier of DOIs) { console.log(identifier) // pidclassid exact \"doi\" and pid exact \"10.1016/j.nima.2015.11.134\" //and (authorid exact \"0000-0001-7291-3210 \" )" if(identifier.class == "ORCID"){ doisParams += (doisParams.length > 0 ? " or " : "") +'(authorid="' + identifier.id + '")'; }else{ doisParams += (doisParams.length > 0 ? " or " : "") +'(pidclassid exact "' + identifier.class + '" and pid="' + identifier.id + '")'; } } } if (doisParams.length > 0) { params += this.createQuotedKeywordQuery(this.selectedFields[i].value, this.selectedFields[i].id, this.selectedFields[i].operatorId ,countParams,true, true) + " or " + doisParams; } else { params += this.createQuotedKeywordQuery(this.selectedFields[i].value, this.selectedFields[i].id, this.selectedFields[i].operatorId,countParams,true); } //TODO deposit case console.log(this.usedBy) console.log(this.keywordFields) if(this.usedBy == "deposit") { if(this.keywordFields.length > 0) { params += " or (" } for(let j=0; j< this.keywordFields.length ; j++) { if(j > 0) { params += " or " } params += this.createQuotedKeywordQuery(this.selectedFields[i].value, this.keywordFields[j].name, " or ", countParams,false); // let field = this.keywordFields[i]; //keywordQuery += field.name+field.equalityOperator+StringUtils.URIEncode(keyword); // params += field.name+field.equalityOperator+StringUtils.quote(StringUtils.URIEncode(keyword)); } if(this.keywordFields.length > 0) { params += " ) " } } } else if (countParams == 0 && this.selectedFields[i].operatorId == "not" && this.fieldIdsMap[this.selectedFields[i].id].equalityOperator != "=") { params += " " + this.selectedFields[i].id + " <> " + '"' + StringUtils.URIEncode(this.selectedFields[i].value) + '"' + " "; } else if(this.fieldIdsMap[this.selectedFields[i].id].equalityOperator == "=") { params+=this.createQuotedKeywordQuery(this.selectedFields[i].value, this.selectedFields[i].id, this.selectedFields[i].operatorId, countParams, false); }else{ params += (countParams == 0 ? "" : this.selectedFields[i].operatorId + " ") + this.selectedFields[i].id + this.fieldIdsMap[this.selectedFields[i].id].equalityOperator + '"' + encodeURIComponent(this.selectedFields[i].value) + '"' + " "; } } countParams++; } } if (this.customFilter) { params += (countParams == 0 ? "" : " and ") + this.customFilter.queryFieldName + " exact " + StringUtils.quote((this.customFilter.valueId)); } console.log("ParameterS:") console.log(params) return params; } createQuotedKeywordQuery(fieldValue, fieldId, fieldOperator, countParams:number, isSearchAll:boolean, forceQuotted:boolean=false){ let params = ""; let quotedParts = (fieldValue)?fieldValue.match(/(["'])(.*?)*?\1/g):[]; params+= (countParams == 0 ? "" : fieldOperator) + " ("; if(forceQuotted){ return this.getQuotedQueryPart(fieldId, '"'+ fieldValue+'"',isSearchAll); } if(quotedParts && quotedParts.length == 1 && quotedParts[0] == fieldValue ){ params+=this.getQuotedQueryPart(fieldId, fieldValue,isSearchAll); }else if( quotedParts && quotedParts.length > 0){ for(let i=0; i< quotedParts.length; i++){ params+=(i>0)?" and ":""; params+=this.getQuotedQueryPart(fieldId, quotedParts[i],isSearchAll); } let startPoint = 0; let endPoint = 0; for(let i=0; i< quotedParts.length; i++){ let index = fieldValue.indexOf(quotedParts[i]); endPoint = (i+1 0) { params += " and " + this.getNoQuotedQueryPart(fieldId, fieldValue.substring(startPoint, endPoint), isSearchAll); } // console.log("For "+i+" " +params+" SP "+ startPoint+" EP: "+endPoint); // startPoint = (i+1 0){ params+=" and " + this.getNoQuotedQueryPart(fieldId, fieldValue.substring(startPoint,fieldValue.length),isSearchAll); } }else{ params+=this.getNoQuotedQueryPart(fieldId, fieldValue,isSearchAll); } params += " )"; return params; } private getQuotedQueryPart(fieldId:string, value:string, isSearchAll:boolean){ return (isSearchAll?"__all":fieldId)+" exact "+StringUtils.URIEncode(value); } private getNoQuotedQueryPart(fieldId:string, value:string, isSearchAll:boolean){ if(isSearchAll){ return value ; }else{ return fieldId+"="+ StringUtils.URIEncode(value); } } /** * Create Search API query based on the filters of refine fields * @param URLparams * @param firstLoad */ getSearchAPIQueryForRefineFields(URLparams, firstLoad: boolean) { var allFqs = ""; console.log(this.refineFields) for (var i = 0; i < this.refineFields.length; i++) { var filterId = this.refineFields[i]; if (URLparams[filterId] != undefined) { let values = (StringUtils.URIDecode(StringUtils.URIDecode(URLparams[filterId]))).split(/,(?=(?:[^\"]*\"[^\"]*\")*[^\"]*$)/, -1); var countvalues = 0; var fq = ""; let filterOp: string = this.searchFieldsHelper.getFieldOperator(filterId); // console.info(filterId, filterOp); for (let value of values) { countvalues++; var paramId = this.fieldIdsMap[filterId].param; // parameters+='&' + paramId+ '='+ value;//+"&" + this.fieldIdsMap[paramId].operator + "="+((countvalues == 1)?"and":"or"); fq += (fq.length > 0 ? " " + filterOp + " " : "") + filterId + " exact " + (value); } if (countvalues > 0) { fq = "&fq=" + StringUtils.URIEncode(fq); } allFqs += fq; } } if (this.customFilter) { allFqs += "&fq=" + StringUtils.URIEncode(this.customFilter.queryFieldName + " exact " + StringUtils.quote((this.customFilter.valueId))); } if (this.quickFilter && this.entityType == "result") { if((firstLoad && URLparams[this.quickFilter.filterId] == undefined && URLparams["qf"] == undefined) || URLparams["qf"] == "true" || ((URLparams[this.quickFilter.filterId] != undefined && StringUtils.URIDecode(URLparams[this.quickFilter.filterId]).split(/,(?=(?:[^\"]*\"[^\"]*\")*[^\"]*$)/, -1).indexOf(StringUtils.quote(this.quickFilter.value)) != -1))) { this.quickFilter.selected = true; } else { this.quickFilter.selected = false; } if ((firstLoad && URLparams[this.quickFilter.filterId] == undefined && URLparams["qf"] == undefined) ||( URLparams[this.quickFilter.filterId] == undefined && URLparams["qf"] == "true")) { allFqs += "&fq=resultbestaccessright exact " + StringUtils.quote(this.quickFilter.value); } } if (this.entityType == "result") { if (URLparams["type"]) { for (let type of URLparams["type"].split(",")) { allFqs += "&type=" + type; } }else{ allFqs += "&type=publications&type=datasets&type=software&type=other"; } } else if (this.entityType == "publication") { allFqs += "&type=publications"; } else if (this.entityType == "dataset") { allFqs += "&type=datasets"; } else if (this.entityType == "software") { allFqs += "&type=software"; } else if (this.entityType == "other") { allFqs += "&type=other"; } else if(this.entityType == "project") { allFqs += "&type=projects"; } else if(this.entityType == "organization") { allFqs += "&type=organizations"; } else if(this.entityType == "dataprovider") { allFqs += "&type=datasources"; } console.log("AllFqs (check type): "+allFqs); console.log("type: "+this.entityType); // var keyword = URLparams['keyword']; // var doiQuery = ""; // var keywordQuery = ""; // if((keyword && keyword.length > 0)){ // if((this.type == 'publications' ||this.type == 'research data' || this.type == 'software' || this.type == 'other research products')){ // var DOIs:string[] = DOI.getDOIsFromString(keyword); // var doisParams = ""; // // for(var i =0 ;i < DOIs.length; i++){ // doisParams+=(doisParams.length > 0?"&":"")+'doi="'+ DOIs[i]+'"'; // } // if(doisParams.length > 0){ // doiQuery += "&"+doisParams; // }else { // keywordQuery += "&q="+StringUtils.URIEncode(keyword); // } // }else{ // if(this.usedBy == "deposit") { // if(this.keywordFields.length > 0) { // keywordQuery = "&fq="; // } // // for(let i=0; i< this.keywordFields.length ; i++) { // if(i > 0) { // keywordQuery += " or "; // } // let field = this.keywordFields[i]; // //keywordQuery += field.name+field.equalityOperator+StringUtils.URIEncode(keyword); // keywordQuery += field.name+field.equalityOperator+StringUtils.quote(StringUtils.URIEncode(keyword)); // } // } else { // keywordQuery += "&q=" + StringUtils.URIEncode(keyword); // } // // } // } //TODO add DOI? return allFqs; } /** * Create Search API query based on the filters of refine fields * @param URLparams */ getSearchAPIQueryForRangeFields(URLparams) { let allFqs = ""; for (let i = 0; i < this.rangeFields.length; i++) { let filterId = this.rangeFields[i][0]+"-range-"+this.rangeFields[i][1]; let filterParam = this.searchFieldsHelper.getFieldParam(filterId, this.entityType); if (URLparams[filterParam] != undefined) { let values = (StringUtils.URIDecode(StringUtils.URIDecode(URLparams[filterParam]))).split(/,(?=(?:[^\"]*\"[^\"]*\")*[^\"]*$)/, -1); var countvalues = 0; var fq = ""; var fqFrom = ""; var fqTo = ""; let filterOp: string = this.searchFieldsHelper.getFieldOperator(filterId); for (let value of values) { if (this.fieldIdsMap[filterId].filterType == "range") { let selectedFromValue; let selectedToValue; let years: string[] = (value.substring(5)).split(":"); let yearFrom: string = (Dates.isValidYear(years[0]) ? years[0] : null); //(Number.isInteger(parseInt(years[0], 10)) ? years[0] : null); let yearTo: string = (Dates.isValidYear(years[1]) ? years[1] : null); //console.log("getSearchAPIQueryForRangeFields: yearFrom: " + yearFrom + " - yearTo: "+yearTo); if(yearFrom) { selectedFromValue = yearFrom; } if(yearTo) { selectedToValue = yearTo; } if(yearFrom || yearTo) { // if (value.length <= 14) { // if(Dates.isValidYear(value.substring(5, 9))) { // selectedFromValue = value.substring(5, 9); // } // if(Dates.isValidYear(value.substring(10, 14))) { // selectedToValue = value.substring(10, 14); // } if(this.rangeFields[i][0] == this.rangeFields[i][1]) { //console.log(selectedFromValue + " - "+selectedToValue); if (selectedFromValue && selectedToValue) { let equalityOp = this.fieldIdsMap[filterId].equalityOperator; fq += (fq.length > 0 ? " " + filterOp + " " : "") + this.rangeFields[i][0] + equalityOp + "\"" + selectedFromValue + " " + selectedToValue + "\""; fq = "&fq=" + StringUtils.URIEncode(fq); } else if (selectedFromValue) { let equalityOp = this.fieldIdsMap[this.rangeFields[i][0]].equalityOperator; if(equalityOp == " = ") { equalityOp = " >= "; } fq += (fq.length > 0 ? " " + filterOp + " " : "") + this.rangeFields[i][0] + equalityOp + "\"" + selectedFromValue + "\""; fq = "&fq=" + StringUtils.URIEncode(fq); } else if (selectedToValue) { let equalityOp = this.fieldIdsMap[this.rangeFields[i][1]].equalityOperator; if(equalityOp == " = ") { equalityOp = " <= "; } fq += (fq.length > 0 ? " " + filterOp + " " : "") + this.rangeFields[i][0] + equalityOp + "\"" + selectedToValue + "\""; fq = "&fq=" + StringUtils.URIEncode(fq); } } else { let equalityOpFrom = this.fieldIdsMap[this.rangeFields[i][0]].equalityOperator; let equalityOpTo = this.fieldIdsMap[this.rangeFields[i][1]].equalityOperator; if (selectedFromValue) { fq += (fq.length > 0 ? " " + filterOp + " " : "") + this.rangeFields[i][0] + equalityOpFrom + "\"" + selectedFromValue + "\""; // fq = "&fq=" + StringUtils.URIEncode(fq); } if (selectedToValue) { fq += (fq.length > 0 ? " " + filterOp + " " : "") + this.rangeFields[i][1] + equalityOpTo + "\"" + selectedToValue + "\""; // fq = "&fq=" + StringUtils.URIEncode(fq); } if(selectedFromValue || selectedToValue) { fq = "&fq=" + StringUtils.URIEncode(fq); } } } } } allFqs += fq +fqFrom + fqTo; } } return allFqs; } /** * Sets parameterNames and parameterValues arrays * used in paging, advanced search link, Goto() * @param filters either query filters or filters defined by the URL parameters * @param rangeFilters defined by the URL parameters * @param includePage */ buildPageURLParameters(filters:Filter[], rangeFilters: RangeFilter[], includePage: boolean) { this.parameterNames.splice(0, this.parameterNames.length); this.parameterValues.splice(0, this.parameterValues.length); for (var i = 0; i < this.selectedFields.length; i++) { //default operator is and this.parameterNames.push("f"+i); this.parameterValues.push(this.selectedFields[i].id + (this.selectedFields[i].operatorId!='and'?(","+this.selectedFields[i].operatorId):'')); this.parameterNames.push("fv"+i); if (this.selectedFields[i].type == "date") { if (this.selectedFields[i].dateValue.type == "range") { this.parameterValues.push(StringUtils.URIEncode("range" + Dates.getDateToString(this.selectedFields[i].dateValue.from) + ":" + Dates.getDateToString(this.selectedFields[i].dateValue.to))); } else { this.parameterValues.push(StringUtils.URIEncode(this.selectedFields[i].dateValue.type)); } } else { console.log(this.selectedFields[i].value +" " + StringUtils.URIEncode(this.selectedFields[i].value)) this.parameterValues.push(StringUtils.URIEncode(this.selectedFields[i].value)); } } if (includePage && this.searchUtils.page != 1) { this.parameterNames.push("page"); this.parameterValues.push("" + this.searchUtils.page); } if (this.searchUtils.size != this.resultsPerPage) { this.parameterNames.push("size"); this.parameterValues.push("" + this.searchUtils.size); } if (this.sort && this.searchUtils.sortBy) { this.parameterNames.push("sortBy"); this.parameterValues.push(this.searchUtils.sortBy); } for (let filter of filters) { var filterLimits = ""; if (filter.countSelectedValues > 0) { for (let value of filter.values) { if (value.selected == true) { filterLimits += ((filterLimits.length == 0) ? '' : ',') + '"' + (value.id) + '"'; } } if (filterLimits.length > 0) { this.parameterNames.push(filter.filterId); this.parameterValues.push(filterLimits); } } } for (let filter of rangeFilters) { var filterLimits = ""; let yearFrom: string = (Dates.isValidYear(filter.selectedFromValue) ? filter.selectedFromValue : null); let yearTo: string = (Dates.isValidYear(filter.selectedToValue) ? filter.selectedToValue : null); if(yearFrom || yearTo) { this.parameterNames.push(filter.filterId); this.parameterValues.push("range" + (yearFrom ? yearFrom : "") + ":" + (yearTo ? yearTo : "")); } // if (filter.countSelectedValues > 0) { // for (let value of filter.values) { // if (value.selected == true) { // filterLimits += ((filterLimits.length == 0) ? '' : ',') + '"' + (value.id) + '"'; // } // } // if (filterLimits.length > 0) { // this.parameterNames.push(filter.filterId); // this.parameterValues.push(filterLimits); // } // } } if (this.searchUtils.keyword.length > 0) { this.parameterNames.push("keyword"); this.parameterValues.push(this.searchUtils.keyword); } if (this.resultTypes && this.entityType == "result") { let values = []; if (this.resultTypes.publication) { values.push("publications"); } if (this.resultTypes.dataset) { values.push("datasets"); } if (this.resultTypes.software) { values.push("software"); } if (this.resultTypes.other) { values.push("other"); } if (values.length > 0) { this.parameterNames.push("type"); this.parameterValues.push(values.join(",")); } if(this.quickFilter) { this.parameterNames.push("qf"); this.parameterValues.push("" + this.quickFilter.selected); } } // if (this.searchUtils.size != this.resultsPerPage) { // // allLimits += ((allLimits.length == 0) ? '?' : '&') + 'size=' + this.searchUtils.size; // this.parameterNames.push("size"); // this.parameterValues.push("" + this.searchUtils.size); // } // if (this.sort && this.searchUtils.sortBy) { // // allLimits += ((allLimits.length == 0) ? '?' : '&') + 'sortBy=' + this.searchUtils.sortBy; // this.parameterNames.push("sortBy"); // this.parameterValues.push(this.searchUtils.sortBy); // } // console.log(this.parameterNames) // console.log(this.parameterValues) } /** * create filters based on URL params * @param URLparams */ getRefineFiltersFromURL(URLparams) { let fields = new SearchFields(); let filters: Filter[] = []; for (let i = 0; i < this.refineFields.length; i++) { let filterId = this.refineFields[i]; if (URLparams[filterId] != undefined) { let filter = new Filter(); filter.title = fields.getFieldName(filterId, this.entityType); filter.filterId = filterId; filter.originalFilterId = filterId; filter.values = []; let values = StringUtils.URIDecode(URLparams[filterId]).split(/,(?=(?:[^\"]*\"[^\"]*\")*[^\"]*$)/, -1); for (let value of values) { let v: Value = new Value(); v.name = RefineResultsUtils.keepPartAfterCharacters(StringUtils.unquote(value), "||"); v.id = StringUtils.unquote(value); v.selected = true; filter.values.push(v); // console.log(v) filter.countSelectedValues++; } filters.push(filter) } } if (this.quickFilter) { if (this.entityType == "result" && (URLparams[this.quickFilter.filterId] == undefined) && (URLparams["qf"] == undefined || URLparams["qf"] == "true")) { let filter = new Filter(); filter.title = fields.getFieldName(this.quickFilter.filterId, this.entityType); filter.filterId = this.quickFilter.filterId; filter.originalFilterId = this.quickFilter.filterId; filter.values = []; let v: Value = new Value(); v.name = this.quickFilter.value; v.id = this.quickFilter.value; v.selected = true; filter.values.push(v); filter.countSelectedValues = 1; filters.push(filter) } } if (this.entityType == "result") { this.resultTypes = null; this.resultTypes = { }; if (URLparams["type"]) { this.resultTypes['publication'] = (URLparams["type"].split(",").indexOf("publications") != -1); this.resultTypes['dataset'] = (URLparams["type"].split(",").indexOf("datasets") != -1); this.resultTypes['software'] = (URLparams["type"].split(",").indexOf("software") != -1); this.resultTypes['other'] = (URLparams["type"].split(",").indexOf("other") != -1); } else { this.resultTypes['publication'] = true; this.resultTypes['dataset'] = true; this.resultTypes['software'] = true; this.resultTypes['other'] = true; } } this.URLCreatedFilters = filters; } /** * create range filters based on URL params * @param URLparams */ getRangeFiltersFromURL(URLparams) { let fields = new SearchFields(); let filters: RangeFilter[] = []; for (let i = 0; i < this.rangeFields.length; i++) { let filterId = this.rangeFields[i][0]+"-range-"+this.rangeFields[i][1]; let filterParam = fields.getFieldParam(filterId, this.entityType); //console.log("rangeFilter (from url): filterId - filterParam"); //console.log(filterId + " - "+ filterParam); if (URLparams[filterParam] != undefined) { let filter = new RangeFilter(); filter.title = fields.getFieldName(filterId, this.entityType); filter.filterId = filterParam; filter.originalFilterIdFrom = this.rangeFields[i][0]; filter.originalFilterIdTo = this.rangeFields[i][1]; let values = (decodeURIComponent(URLparams[filterParam])).split(/,(?=(?:[^\"]*\"[^\"]*\")*[^\"]*$)/, -1); for (let j = 0; j < values.length; j++) { if (this.fieldIdsMap[filterId].filterType == "range") { let value: string = StringUtils.unquote(values[j]); let validDates: boolean = true; // if (value.length < 14) { // validDates = false; // } else { // if (!Dates.isValidYear(value.substring(5, 9)) || !Dates.isValidYear(value.substring(10, 14))) { // validDates = false; // } else { // filter.selectedFromValue = value.substring(5, 9); // filter.selectedToValue = value.substring(10, 14); // } // } let years: string[] = (value.substring(5)).split(":"); let yearFrom: string = (Dates.isValidYear(years[0]) ? years[0] : null); let yearTo: string = (Dates.isValidYear(years[1]) ? years[1] : null); //console.log("getRangeFiltersFromURL: yearFrom: " + yearFrom + " - yearTo: "+yearTo); if(yearFrom) { filter.selectedFromValue = yearFrom; //filter.selectedFromAndToValues = yearFrom; } /*if(yearFrom && yearTo) { filter.selectedFromAndToValues += "-"; }*/ if(yearTo) { filter.selectedToValue = yearTo; //filter.selectedFromAndToValues += yearTo; } //console.log("filter.selectedFromAndToValues: "+filter.selectedFromAndToValues); if(!yearFrom && !yearTo) { validDates = false; } } } //console.log(filters); filters.push(filter) } } // console.log("Empty Filters"); // console.log(filters); this.URLCreatedRangeFilters = filters; // return filters; } /** * Checks if query has no results, display Filters from URL parameters * Mark checked the selected filters * Count the checked * @param filters */ public prepareFiltersToShow(filters: Filter[]): Filter[] { //console.log("prepareFiltersToShow"); if (this.URLCreatedFilters.length > 0 && this.searchUtils.totalResults == 0) { this.showUnknownFilters = true; this.filters = this.URLCreatedFilters; } else if (this.searchUtils.totalResults != 0) { this.showUnknownFilters = false; this.filters = filters; } this.buildPageURLParameters(this.URLCreatedFilters, this.URLCreatedRangeFilters, true); //this.checkSelectedRangeFilters(this.rangeFilters); this.checkSelectedFilters(this.filters); this.countSelectedFilters(this.filters); return this.filters; } /** * Mark checked the selected range filters */ public prepareRangeFiltersToShow() { this.rangeFilters = RangeFilter.parse(this.rangeFields, this.entityType); // OK //this.buildPageURLRangeParameters(this.rangeFilters, true); this.checkSelectedRangeFilters(this.rangeFilters); this.countSelectedRangeFilters(this.rangeFilters); return this.rangeFilters; } /** * Used to set the variables and search page, and prepare it before the getResults query * @param fieldIds * @param selectedFields * @param refineFields * @param rangeFields * @param fieldIdsMap * @param customFilter * @param params * @param entityType * @param quickFilter */ prepareSearchPage(fieldIds, selectedFields, refineFields, rangeFields, fieldIdsMap, customFilter, params, entityType, quickFilter=null){ console.log(this.refineFields); this.entityType = entityType; this.fieldIds = fieldIds; this.selectedFields = selectedFields; this.refineFields = refineFields; this.rangeFields = rangeFields; this.fieldIdsMap = fieldIdsMap; this.customFilter = customFilter; this.quickFilter = quickFilter; this.getRangeFiltersFromURL(params); this.getRefineFiltersFromURL(params); this.createAdvancedSearchSelectedFiltersFromURLParameters(params); } }