assets/js/builder/Models/_Relationships.js
/**
* Model relationships mixin
*
* @since 3.16.0
* @version 3.16.11
*/
define( [], function() {
return {
/**
* Default relationship settings object
*
* @type {Object}
*/
relationship_defaults: {
parent: {},
children: {},
},
/**
* Relationship settings object
* Should be overridden in the model
*
* @type {Object}
*/
relationships: {},
/**
* Initialize all parent and child relationships
*
* @return void
* @since 3.16.0
* @version 3.16.0
*/
init_relationships: function( options ) {
var rels = this.get_relationships();
// initialize parent relationships
// useful when adding a model to ensure parent is initialized
if ( rels.parent && options && options.parent ) {
this.set_parent( options.parent );
}
// initialize all children relationships
_.each( rels.children, function( child_data, child_key ) {
if ( ! child_data.conditional || true === child_data.conditional( this ) ) {
var child_val = this.get( child_key ),
child;
if ( child_data.lookup ) {
child = child_data.lookup( child_val );
} else if ( 'model' === child_data.type ) {
child = window.llms_builder.construct.get_model( child_data.class, child_val );
} else if ( 'collection' === child_data.type ) {
child = window.llms_builder.construct.get_collection( child_data.class, child_val );
}
this.set( child_key, child );
// if the child defines a parent, save a reference to the parent on the child
if ( 'model' === child_data.type ) {
this._maybe_set_parent_reference( child );
// save directly to each model in the collection
} else if ( 'collection' === child_data.type ) {
child.parent = this;
child.each( function( child_model ) {
this._maybe_set_parent_reference( child_model );
}, this );
}
}
}, this );
},
/**
* Retrieve the property names for all children of the model
*
* @return array
* @since 3.16.11
* @version 3.16.11
*/
get_child_props: function() {
var props = [];
_.each( this.get_relationships().children, function( data, key ) {
if ( ! data.conditional || true === data.conditional( this ) ) {
props.push( key );
}
}, this );
return props;
},
/**
* Retrieve the model's parent (if set)
*
* @return obj|false
* @since 3.16.0
* @version 3.16.0
*/
get_parent: function() {
var rels = this.get_relationships();
if ( rels.parent ) {
return rels.parent.reference;
}
return false;
},
/**
* Retrieve relationships for the model
* Extends with defaults
*
* @return obj
* @since 3.16.0
* @version 3.16.0
*/
get_relationships: function() {
return $.extend( true, this.relationships, this.relationship_defaults );
},
/**
* Set the parent reference for the given model
*
* @param obj obj parent model obj
* @return void
* @since 3.16.0
* @version 3.16.0
*/
set_parent: function( obj ) {
this.relationships.parent.reference = obj;
},
/**
* Set up the parent relationships for qualifying children during relationship initialization
*
* @param obj model child model
* @return void
* @since 3.16.0
* @version 3.16.0
*/
_maybe_set_parent_reference: function( model ) {
if ( ! model || ! model.get_relationships ) {
return;
}
var rels = model.get_relationships();
if ( rels.parent && rels.parent.model === this.get( 'type' ) ) {
model.set_parent( this );
}
},
};
} );