: str_replace(): Passing null to parameter #2 ($replace) of type array|string is deprecated in
/******/ (() => { // webpackBootstrap
/******/ var __webpack_modules__ = ({
* wp.media.model.Attachment
* @memberOf wp.media.model
* @augments Backbone.Model
Attachment = Backbone.Model.extend(/** @lends wp.media.model.Attachment.prototype */{
* Triggered when attachment details change
* Overrides Backbone.Model.sync
* @param {wp.media.model.Attachment} model
* @param {Object} [options={}]
sync: function( method, model, options ) {
// If the attachment does not yet have an `id`, return an instantly
// rejected promise. Otherwise, all of our requests will fail.
if ( _.isUndefined( this.id ) ) {
return $.Deferred().rejectWith( this ).promise();
// Overload the `read` request so Attachment.fetch() functions correctly.
if ( 'read' === method ) {
options.data = _.extend( options.data || {}, {
action: 'get-attachment',
return wp.media.ajax( options );
// Overload the `update` request so properties can be saved.
} else if ( 'update' === method ) {
// If we do not have the necessary nonce, fail immediately.
if ( ! this.get('nonces') || ! this.get('nonces').update ) {
return $.Deferred().rejectWith( this ).promise();
// Set the action and ID.
options.data = _.extend( options.data || {}, {
action: 'save-attachment',
nonce: this.get('nonces').update,
post_id: wp.media.model.settings.post.id
// Record the values of the changed attributes.
if ( model.hasChanged() ) {
options.data.changes = {};
_.each( model.changed, function( value, key ) {
options.data.changes[ key ] = this.get( key );
return wp.media.ajax( options );
// Overload the `delete` request so attachments can be removed.
// This will permanently delete an attachment.
} else if ( 'delete' === method ) {
options.data = _.extend( options.data || {}, {
_wpnonce: this.get('nonces')['delete']
return wp.media.ajax( options ).done( function() {
// Otherwise, fall back to `Backbone.sync()`.
* Call `sync` directly on Backbone.Model
return Backbone.Model.prototype.sync.apply( this, arguments );
* Convert date strings into Date objects.
* @param {Object} resp The raw response object, typically returned by fetch()
* @return {Object} The modified response object, which is the attributes hash
* to be set on the model.
parse: function( resp ) {
resp.date = new Date( resp.date );
resp.modified = new Date( resp.modified );
* @param {Object} data The properties to be saved.
* @param {Object} options Sync options. e.g. patch, wait, success, error.
saveCompat: function( data, options ) {
// If we do not have the necessary nonce, fail immediately.
if ( ! this.get('nonces') || ! this.get('nonces').update ) {
return $.Deferred().rejectWith( this ).promise();
return wp.media.post( 'save-attachment-compat', _.defaults({
nonce: this.get('nonces').update,
post_id: wp.media.model.settings.post.id
}, data ) ).done( function( resp, status, xhr ) {
model.set( model.parse( resp, xhr ), options );
},/** @lends wp.media.model.Attachment */{
* Create a new model on the static 'all' attachments collection and return it.
* @return {wp.media.model.Attachment}
create: function( attrs ) {
var Attachments = wp.media.model.Attachments;
return Attachments.all.push( attrs );
* Create a new model on the static 'all' attachments collection and return it.
* If this function has already been called for the id,
* it returns the specified attachment.
* @param {string} id A string used to identify a model.
* @param {Backbone.Model|undefined} attachment
* @return {wp.media.model.Attachment}
get: _.memoize( function( id, attachment ) {
var Attachments = wp.media.model.Attachments;
return Attachments.all.push( attachment || { id: id } );
module.exports = Attachment;
* wp.media.model.Attachments
* A collection of attachments.
* This collection has no persistence with the server without supplying
* 'options.props.query = true', which will mirror the collection
* to an Attachments Query collection - @see wp.media.model.Attachments.mirror().
* @memberOf wp.media.model
* @augments Backbone.Collection
* @param {array} [models] Models to initialize with the collection.
* @param {object} [options] Options hash for the collection.
* @param {string} [options.props] Options hash for the initial query properties.
* @param {string} [options.props.order] Initial order (ASC or DESC) for the collection.
* @param {string} [options.props.orderby] Initial attribute key to order the collection by.
* @param {string} [options.props.query] Whether the collection is linked to an attachments query.
* @param {string} [options.observe]
* @param {string} [options.filters]
var Attachments = Backbone.Collection.extend(/** @lends wp.media.model.Attachments.prototype */{
* @type {wp.media.model.Attachment}
model: wp.media.model.Attachment,
* @param {Array} [models=[]] Array of models used to populate the collection.
* @param {Object} [options={}]
initialize: function( models, options ) {
this.props = new Backbone.Model();
this.filters = options.filters || {};
// Bind default `change` events to the `props` model.
this.props.on( 'change', this._changeFilteredProps, this );
this.props.on( 'change:order', this._changeOrder, this );
this.props.on( 'change:orderby', this._changeOrderby, this );
this.props.on( 'change:query', this._changeQuery, this );
this.props.set( _.defaults( options.props || {} ) );
this.observe( options.observe );
* Sort the collection when the order attribute changes.
_changeOrder: function() {
* Set the default comparator only when the `orderby` property is set.
* @param {Backbone.Model} model
* @param {string} orderby
_changeOrderby: function( model, orderby ) {
// If a different comparator is defined, bail.
if ( this.comparator && this.comparator !== Attachments.comparator ) {
if ( orderby && 'post__in' !== orderby ) {
this.comparator = Attachments.comparator;
* If the `query` property is set to true, query the server using
* the `props` values, and sync the results to this collection.
* @param {Backbone.Model} model
_changeQuery: function( model, query ) {
this.props.on( 'change', this._requery, this );
this.props.off( 'change', this._requery, this );
* @param {Backbone.Model} model
_changeFilteredProps: function( model ) {
// If this is a query, updating the collection will be handled by
if ( this.props.get('query') ) {
var changed = _.chain( model.changed ).map( function( t, prop ) {
var filter = Attachments.filters[ prop ],
term = model.get( prop );
if ( term && ! this.filters[ prop ] ) {
this.filters[ prop ] = filter;
} else if ( ! term && this.filters[ prop ] === filter ) {
delete this.filters[ prop ];
// If no `Attachments` model is provided to source the searches from,
// then automatically generate a source from the existing models.
this._source = new Attachments( this.models );
this.reset( this._source.filter( this.validator, this ) );
validateDestroyed: false,
* Checks whether an attachment is valid.
* @param {wp.media.model.Attachment} attachment
validator: function( attachment ) {
if ( ! this.validateDestroyed && attachment.destroyed ) {
return _.all( this.filters, function( filter ) {
return !! filter.call( this, attachment );
* Add or remove an attachment to the collection depending on its validity.
* @param {wp.media.model.Attachment} attachment
* @param {Object} options
* @return {wp.media.model.Attachments} Returns itself to allow chaining.
validate: function( attachment, options ) {
var valid = this.validator( attachment ),
hasAttachment = !! this.get( attachment.cid );
if ( ! valid && hasAttachment ) {
this.remove( attachment, options );
} else if ( valid && ! hasAttachment ) {
this.add( attachment, options );
* Add or remove all attachments from another collection depending on each one's validity.
* @param {wp.media.model.Attachments} attachments
* @param {Object} [options={}]
* @fires wp.media.model.Attachments#reset
* @return {wp.media.model.Attachments} Returns itself to allow chaining.
validateAll: function( attachments, options ) {
_.each( attachments.models, function( attachment ) {
this.validate( attachment, { silent: true });
if ( ! options.silent ) {
this.trigger( 'reset', this, options );
* Start observing another attachments collection change events
* and replicate them on this collection.
* @param {wp.media.model.Attachments} The attachments collection to observe.
* @return {wp.media.model.Attachments} Returns itself to allow chaining.
observe: function( attachments ) {
this.observers = this.observers || [];
this.observers.push( attachments );
attachments.on( 'add change remove', this._validateHandler, this );
attachments.on( 'add', this._addToTotalAttachments, this );
attachments.on( 'remove', this._removeFromTotalAttachments, this );
attachments.on( 'reset', this._validateAllHandler, this );
this.validateAll( attachments );
* Stop replicating collection change events from another attachments collection.
* @param {wp.media.model.Attachments} The attachments collection to stop observing.
* @return {wp.media.model.Attachments} Returns itself to allow chaining.
unobserve: function( attachments ) {
attachments.off( null, null, this );
this.observers = _.without( this.observers, attachments );
_.each( this.observers, function( attachments ) {
attachments.off( null, null, this );
* Update total attachment count when items are added to a collection.
_removeFromTotalAttachments: function() {
this.mirroring.totalAttachments = this.mirroring.totalAttachments - 1;
* Update total attachment count when items are added to a collection.
_addToTotalAttachments: function() {
this.mirroring.totalAttachments = this.mirroring.totalAttachments + 1;
* @param {wp.media.model.Attachments} attachment
* @param {wp.media.model.Attachments} attachments
* @param {Object} options
* @return {wp.media.model.Attachments} Returns itself to allow chaining.
_validateHandler: function( attachment, attachments, options ) {
// If we're not mirroring this `attachments` collection,
// only retain the `silent` option.
options = attachments === this.mirroring ? options : {
silent: options && options.silent
return this.validate( attachment, options );
* @param {wp.media.model.Attachments} attachments
* @param {Object} options
* @return {wp.media.model.Attachments} Returns itself to allow chaining.
_validateAllHandler: function( attachments, options ) {
return this.validateAll( attachments, options );
* Start mirroring another attachments collection, clearing out any models already
* @param {wp.media.model.Attachments} The attachments collection to mirror.
* @return {wp.media.model.Attachments} Returns itself to allow chaining.
mirror: function( attachments ) {
if ( this.mirroring && this.mirroring === attachments ) {
this.mirroring = attachments;
// Clear the collection silently. A `reset` event will be fired
// when `observe()` calls `validateAll()`.
this.reset( [], { silent: true } );
this.observe( attachments );
// Used for the search results.
this.trigger( 'attachments:received', this );
* Stop mirroring another attachments collection.