gocodebox/lifterlms

View on GitHub
assets/js/builder/Models/_Relationships.js

Summary

Maintainability
A
1 hr
Test Coverage
/**
 * 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 );
            }

        },

    };

} );