/**
* Filter methods that can be mixed in to a request constructor's prototype to
* allow that request to take advantage of top-level query parameters for
* collection endpoints. These are most relevant to posts, pages and CPTs, but
* pagination helpers are applicable to any collection.
*
* @module mixins/parameters
*/
'use strict';
/*jshint -W106 */// Disable underscore_case warnings in this file b/c WP uses them
var paramSetter = require( '../util/parameter-setter' );
var argumentIsNumeric = require( '../util/argument-is-numeric' );
/**
* @mixin parameters
*/
var parameterMixins = {};
var filters = require( './filters' );
// Needed for .author mixin, as author by ID is a parameter and by Name is a filter
var filter = filters.filter;
// Needed for .tag and .category mixin, for deprecated query-by-slug support
var taxonomy = filters.taxonomy;
// Parameter Methods
// =================
/**
* Query for posts by a specific author.
* This method will replace any previous 'author' query parameters that had been set.
*
* Note that this method will either set the "author" top-level query parameter,
* or else the "author_name" filter parameter (when querying by nicename): this is
* irregular as most parameter helper methods either set a top level parameter or a
* filter, not both.
*
* _Usage with the author nicename string is deprecated._ Query by author ID instead.
* If the "rest-filter" plugin is not installed, the name query will have no effect.
*
* @method author
* @chainable
* @param {String|Number} author The nicename or ID for a particular author
* @returns The request instance (for chaining)
*/
parameterMixins.author = function( author ) {
/* jshint validthis:true */
if ( author === undefined ) {
return this;
}
if ( typeof author === 'string' ) {
this.param( 'author', null );
return filter.call( this, 'author_name', author );
}
if ( typeof author === 'number' ) {
filter.call( this, 'author_name', null );
return this.param( 'author', author );
}
if ( author === null ) {
filter.call( this, 'author_name', null );
return this.param( 'author', null );
}
throw new Error( 'author must be either a nicename string or numeric ID' );
};
/**
* Search for hierarchical taxonomy terms that are children of the parent term
* indicated by the provided term ID
*
* @example
*
* wp.pages().parent( 3 ).then(function( pages ) {
* // console.log( 'all of these pages are nested below page ID#3:' );
* // console.log( pages );
* });
*
* wp.categories().parent( 42 ).then(function( categories ) {
* console.log( 'all of these categories are sub-items of cat ID#42:' );
* console.log( categories );
* });
*
* @method parent
* @chainable
* @param {Number} parentId The ID of a (hierarchical) taxonomy term
* @returns The request instance (for chaining)
*/
parameterMixins.parent = paramSetter( 'parent' );
/**
* Specify the post for which to retrieve terms (relevant for *e.g.* taxonomy
* and comment collection endpoints).
*
* @method post
* @chainable
* @param {String|Number} post The ID of the post for which to retrieve terms
* @returns The request instance (for chaining)
*/
parameterMixins.post = paramSetter( 'post' );
/**
* Specify the password to use to access the content of a password-protected post
*
* @method password
* @chainable
* @param {string} password A string password to access protected content within a post
* @returns The request instance (for chaining)
*/
parameterMixins.password = paramSetter( 'password' );
/**
* Specify for which post statuses to return posts in a response collection
*
* See https://codex.wordpress.org/Post_Status -- the default post status
* values in WordPress which are most relevant to the API are 'publish',
* 'future', 'draft', 'pending', 'private', and 'trash'. This parameter also
* supports passing the special value "any" to return all statuses.
*
* @method status
* @chainable
* @param {string|string[]} status A status name string or array of strings
* @returns The request instance (for chaining)
*/
parameterMixins.status = paramSetter( 'status' );
/**
* Specify whether to return only, or to completely exclude, sticky posts
*
* @method sticky
* @chainable
* @param {boolean} sticky A boolean value for whether ONLY sticky posts (true) or
* NO sticky posts (false) should be returned in the query
* @returns The request instance (for chaining)
*/
parameterMixins.sticky = paramSetter( 'sticky' );
// Taxonomy Term Filter Methods
// ============================
/**
* Retrieve only records associated with one of the provided categories
*
* @method categories
* @chainable
* @param {String|Number|Array} categories A term ID integer or numeric string, or array thereof
* @returns The request instance (for chaining)
*/
parameterMixins.categories = paramSetter( 'categories' );
/**
* Legacy wrapper for `.categories()` that uses `?filter` to query by slug if available
*
* @method tag
* @deprecated Use `.categories()` and query by category IDs
* @chainable
* @param {String|Number|Array} tag A category term slug string, numeric ID, or array of numeric IDs
* @returns The request instance (for chaining)
*/
parameterMixins.category = function( category ) {
/* jshint validthis:true */
if ( argumentIsNumeric( category ) ) {
return parameterMixins.categories.call( this, category );
}
return taxonomy.call( this, 'category', category );
};
/**
* Exclude records associated with any of the provided category IDs
*
* @method excludeCategories
* @chainable
* @param {String|Number|Array} category A term ID integer or numeric string, or array thereof
* @returns The request instance (for chaining)
*/
parameterMixins.excludeCategories = paramSetter( 'categories_exclude' );
/**
* Retrieve only records associated with one of the provided tag IDs
*
* @method tags
* @chainable
* @param {String|Number|Array} tags A term ID integer or numeric string, or array thereof
* @returns The request instance (for chaining)
*/
parameterMixins.tags = paramSetter( 'tags' );
/**
* Legacy wrapper for `.tags()` that uses `?filter` to query by slug if available
*
* @method tag
* @deprecated Use `.tags()` and query by term IDs
* @chainable
* @param {String|Number|Array} tag A tag term slug string, numeric ID, or array of numeric IDs
* @returns The request instance (for chaining)
*/
parameterMixins.tag = function( tag ) {
/* jshint validthis:true */
if ( argumentIsNumeric( tag ) ) {
return parameterMixins.tags.call( this, tag );
}
return taxonomy.call( this, 'tag', tag );
};
/**
* Exclude records associated with any of the provided tag IDs
*
* @method excludeTags
* @chainable
* @param {String|Number|Array} category A term ID integer or numeric string, or array thereof
* @returns The request instance (for chaining)
*/
parameterMixins.excludeTags = paramSetter( 'tags_exclude' );
// Date Methods
// ============
/**
* Retrieve only records published before a specified date
*
* @example <caption>Provide an ISO 8601-compliant date string</caption>
*
* wp.posts().before('2016-03-22')...
*
* @example <caption>Provide a JavaScript Date object</caption>
*
* wp.posts().before( new Date( 2016, 03, 22 ) )...
*
* @method before
* @chainable
* @param {String|Date} date An ISO 8601-compliant date string, or Date object
* @returns The request instance (for chaining)
*/
parameterMixins.before = function( date ) {
/* jshint validthis:true */
return this.param( 'before', new Date( date ).toISOString() );
};
/**
* Retrieve only records published after a specified date
*
* @example <caption>Provide an ISO 8601-compliant date string</caption>
*
* wp.posts().after('1986-03-22')...
*
* @example <caption>Provide a JavaScript Date object</caption>
*
* wp.posts().after( new Date( 1986, 03, 22 ) )...
*
* @method after
* @chainable
* @param {String|Date} date An ISO 8601-compliant date string, or Date object
* @returns The request instance (for chaining)
*/
parameterMixins.after = function( date ) {
/* jshint validthis:true */
return this.param( 'after', new Date( date ).toISOString() );
};
module.exports = parameterMixins;