UNPKG

shopware-admin-api-client

Version:
526 lines (470 loc) 14.9 kB
import types from '../utils/types.utils.js'; import lodash from 'lodash'; export default class Criteria { constructor(page = 1, limit = 25) { this.page = page; this.limit = limit; this.term = null; this.filters = []; this.ids = []; this.queries = []; this.associations = []; this.postFilter = []; this.sortings = []; this.aggregations = []; this.totalCountMode = 1; this.includes = []; } static fromCriteria(criteria) { return lodash.cloneDeep(criteria); } /** * Parses the current criteria and generates an object which can be provided to the api * * @return {Object} */ parse() { const params = {}; if (this.ids.length > 0) { params.ids = this.ids.join('|'); } if (this.page !== null) { params.page = this.page; } if (this.limit !== null) { params.limit = this.limit; } if (this.term !== null) { params.term = this.term; } if (this.queries.length > 0) { params.query = this.queries; } if (this.filters.length > 0) { params.filter = this.filters; } if (this.postFilter.length > 0) { params['post-filter'] = this.postFilter; } if (this.sortings.length > 0) { params.sort = this.sortings; } if (this.aggregations.length > 0) { params.aggregations = this.aggregations; } if (this.associations.length > 0) { params.associations = {}; this.associations.forEach((item) => { params.associations[item.association] = item.criteria.parse(); }); } if (this.includes.length > 0) { params.includes = {}; this.includes.forEach((item) => { params.includes[item.includes] = item.fields; }); } if (this.totalCountMode !== null) { params['total-count-mode'] = this.totalCountMode; } return params; } /** * Allows to provide a list of ids which are used as a filter * @param {Array} ids */ setIds(ids) { this.ids = ids; return this; } /** * Allows to configure the total value of a search result. * 0 - no total count will be selected. Should be used if no pagination required (fastest) * 1 - exact total count will be selected. Should be used if an exact pagination is required (slow) * 2 - fetches limit * 5 + 1. Should be used if pagination can work with "next page exists" (fast) * * @param {int} mode */ setTotalCountMode(mode) { if (!types.isNumber(mode)) { this.totalCountMode = null; } this.totalCountMode = (mode < 0 || mode > 2) ? null : mode; return this; } /** * @param {int} page * @returns {Criteria} */ setPage(page) { this.page = page; return this; } /** * @param {int} limit * @returns {Criteria} */ setLimit(limit) { this.limit = limit; return this; } /** * @param {String} term * @returns {Criteria} */ setTerm(term) { this.term = term; return this; } /** * @param {Object} filter * @returns {Criteria} */ addFilter(filter) { this.filters.push(filter); return this; } /** * Adds the provided filter as post filter. * Post filter will be considered for the documents query but not for the aggregations. * * @param {Object} filter * @returns {Criteria} */ addPostFilter(filter) { this.postFilter.push(filter); return this; } /** * Allows to add different sortings for the criteria, to sort the entity result. * @param {Object} sorting * @returns {Criteria} */ addSorting(sorting) { this.sortings.push(sorting); return this; } /** * @see \Shopware\Core\Framework\DataAbstractionLayer\Search\Query\ScoreQuery. * These queries are used to search for documents and score them with a ranking * * @param {Object} filter - a filter object like equals, contains, ... * @param {int} score - defines a score if the filter field match * @param {string} scoreField - Allows to define a storage field for the scoring which is used instead of the score * * @returns {Criteria} */ addQuery(filter, score, scoreField = null) { const query = { score: score, query: filter }; if (scoreField) { query[scoreField] = scoreField; } this.queries.push(query); return this; } /** * @param {Object} aggregation */ addAggregation(aggregation) { this.aggregations.push(aggregation); return this; } /** * Ensures that a criterion is created for each segment of the passed path. * Existing Criteria objects are not overwritten. * Returns the own instance * @param {String} path * @returns {Criteria} - self */ addAssociation(path) { const parts = path.split('.'); let criteria = this; parts.forEach((part) => { criteria = criteria.getAssociation(part); }); return this; } /** * If you only want to include specific fields in the response instead of all fields. * @param {String} path * @param {Array} fields * @returns {Criteria} */ addInclude(path, fields) { let criteria = this; criteria.includes.push({ includes: path, fields: fields }); return this; } /** * Ensures that a criterion is created for each segment of the passed path. * Returns the criteria instance of the last path segment * * @param {String} path * @returns {Criteria} */ getAssociation(path) { const parts = path.split('.'); let criteria = this; parts.forEach((part) => { if (!criteria.hasAssociation(part)) { criteria.associations.push({ association: part, criteria: new Criteria(null, null) }); } criteria = criteria.getAssociationCriteria(part); }); return criteria; } /** * @internal * @param {String} part */ getAssociationCriteria(part) { let criteria = null; this.associations.forEach((association) => { if (association.association === part) { criteria = association.criteria; } }); return criteria; } /** * @param {String} property * @returns {boolean} */ hasAssociation(property) { let exists = false; this.associations.forEach((association) => { if (association.association === property) { exists = true; } }); return exists; } /** * Resets the sorting parameter */ resetSorting() { this.sortings = []; } /** * @see \Shopware\Core\Framework\DataAbstractionLayer\Search\Aggregation\Metric\AvgAggregation * Allows to calculate the avg value for the provided field * * @param {String} name * @param {String} field * @returns {{field: *, name: *, type: string}} */ static avg(name, field) { return { type: 'avg', name, field }; } /** * @see \Shopware\Core\Framework\DataAbstractionLayer\Search\Aggregation\Metric\CountAggregation * Allows to calculate the count value for the provided field * * @param {String} name * @param {String} field * @returns {{field: *, name: *, type: string}} */ static count(name, field) { return { type: 'count', name, field }; } /** * @see \Shopware\Core\Framework\DataAbstractionLayer\Search\Aggregation\Metric\MaxAggregation * Allows to calculate the max value for the provided field * * @param {String} name * @param {String} field * @returns {{field: *, name: *, type: string}} */ static max(name, field) { return { type: 'max', name, field }; } /** * @see \Shopware\Core\Framework\DataAbstractionLayer\Search\Aggregation\Metric\MinAggregation * Allows to calculate the min value for the provided field * * @param {String} name * @param {String} field * @returns {{field: *, name: *, type: string}} */ static min(name, field) { return { type: 'min', name, field }; } /** * @see \Shopware\Core\Framework\DataAbstractionLayer\Search\Aggregation\Metric\StatsAggregation * Allows to calculate the sum, max, min, avg, count values for the provided field * * @param {String} name * @param {String} field * @returns {{field: *, name: *, type: string}} */ static stats(name, field) { return { type: 'stats', name, field }; } /** * @see \Shopware\Core\Framework\DataAbstractionLayer\Search\Aggregation\Metric\SumAggregation * Allows to calculate the sum value for the provided field * * @param {String} name * @param {String} field * @returns {{field: *, name: *, type: string}} */ static sum(name, field) { return { type: 'sum', name, field }; } /** * @see \Shopware\Core\Framework\DataAbstractionLayer\Search\Aggregation\Bucket\TermsAggregation * Allows to fetch term buckets for the provided field * * @param {String} name * @param {String} field * @param {Integer|null} limit * @param {Object|null} sort * @param {Object|null} aggregation * @returns {Object} */ static terms(name, field, limit = null, sort = null, aggregation = null) { return { type: 'terms', name, field, limit, sort, aggregation }; } /** * @see \Shopware\Core\Framework\DataAbstractionLayer\Search\Aggregation\Bucket\FilterAggregation * Allows to filter an aggregation result * * @param {String} name * @param {Array} filter * @param {Object} aggregation * @returns {Object} */ static filter(name, filter, aggregation) { return { type: 'terms', filter, aggregation }; } /** * @see \Shopware\Core\Framework\DataAbstractionLayer\Search\Aggregation\Bucket\DateHistogramAggregation * Allows to fetch date buckets for the provided date interval * * @param {String} name * @param {String} field * @param {String|null} interval * @param {String|null} format * @param {Object|null} aggregation * @returns {Object} */ static histogram(name, field, interval, format, aggregation) { return { type: 'histogram', name, field, interval, format, aggregation }; } /** * @see \Shopware\Core\Framework\DataAbstractionLayer\Search\Sorting\FieldSorting. * Allows to sort the documents by the provided field * * @param {string} field * @param {string} order - ASC/DESC * @param {boolean} naturalSorting * * @returns {Object} */ static sort(field, order = 'ASC', naturalSorting = false) { return { field, order, naturalSorting }; } /** * @see \Shopware\Core\Framework\DataAbstractionLayer\Search\Sorting\FieldSorting. * Allows to sort the documents by the provided field naturally * * @param {string} field * @param {string} order - ASC/DESC * * @returns {Object} */ static naturalSorting(field, order = 'ASC') { return { field, order, naturalSorting: true }; } /** * @see \Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\ContainsFilter. * This allows to filter documents where the value are contained in the provided field. * * Sql representation: `{field} LIKE %{value}%` * * @param {string} field * @param {string} value * * @returns {Object} */ static contains(field, value) { return { type: 'contains', field, value }; } /** * @see \Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\EqualsAnyFilter. * This allows to filter documents where the field matches one of the provided values * * Sql representation: `{field} IN ({value}, {value})` * * @param {string} field * @param {array} value * @returns {Object}} */ static equalsAny(field, value) { return { type: 'equalsAny', field, value: value.join('|') }; } /** * @see \Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\RangeFilter. * This allows to filter documents where the field matches a defined range * * Sql representation: `{field} >= {value}`, `{field} <= {value}`, ... * * @param {string} field * @param {object} range * * @returns {Object}} */ static range(field, range) { return { type: 'range', field, parameters: range }; } /** * @see \Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\EqualsFilter. * This allows to filter documents where the field matches a defined range * * Sql representation: `{field} = {value}` * * @param {string} field * @param {string|number|boolean|null} value * * @returns {Object}} */ static equals(field, value) { return { type: 'equals', field, value }; } /** * @see \Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\NotFilter. * This allows to filter documents which not matches for the provided filters * All above listed queries can be provided (equals, equalsAny, range, contains) * * Sql representation: `NOT({query} {operator} {query} {operator} {query})` * * @param {string} operator - and/or * @param {array} queries * * @returns {Object}} */ static not(operator, queries = []) { return { type: 'not', operator: operator, queries: queries }; } /** * @see \Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\NotFilter. * This allows to filter documents which matches for the provided filters * All above listed queries can be provided (equals, equalsAny, range, contains) * * Sql representation: `({query} {operator} {query} {operator} {query})` * * @param {string} operator - and/or * @param {array} queries * * @returns {Object}} */ static multi(operator, queries = []) { return { type: 'multi', operator, queries }; } }