HEX
Server: Microsoft-IIS/8.5
System: Windows NT YDAWBH120 6.3 build 9600 (Windows Server 2012 R2 Standard Edition) AMD64
User: tentjecom_web (0)
PHP: 7.4.14
Disabled: NONE
Upload Files
File: D:/HostingSpaces/SBogers10/shop.komma.nl/resources/js/global/models/Model.js
let idCounter = -1;

export default class Model {
    constructor(srcObject) {
        this.hydrate(srcObject);
    }

    get state() {
        return this._state;
    }

    /**
     * Get all properties of an object, except those from the Objects constructor and
     * except those of this model class.
     *
     * @param obj
     * @param filter
     * @param filterPrivate
     * @return {*[]}
     */
    getAllProperties(obj, filter = [], filterPrivate = true){
        let filterProps = Object.getOwnPropertyNames(Object.getPrototypeOf({})) //Yields Properties like, constructor, __defineGetter__ etc.
        filterProps = filterProps.concat(['hydrate', 'initValue', 'toJSON', 'getAllProperties', 'proxy'])

        let allProps = []
        let curr = obj
        do {
            let props = Object.getOwnPropertyNames(curr)
            props.forEach(function(prop){
                if (allProps.indexOf(prop) === -1)
                    allProps.push(prop)
            })
        } while(curr = Object.getPrototypeOf(curr))

        if(Array.isArray(filter)) filterProps = filterProps.concat(filter);

        allProps = allProps.filter(
            prop => filterProps.indexOf(prop) === -1
        )

        if(filterPrivate) {
            allProps = allProps.filter(prop => prop.charAt(0) !== '_') //Remove the defacto "private" props that start with an underscore
        }

        return allProps
    }

    /**
     * Uses a source object to fill the current object "instance" using its settters.
     * When the src object does not have a certain property or is not given at all, setters will be called with a value of undefined.
     * This allows you to use the setters to initialize a new / default instance!
     *
     * @param srcObject
     */
    hydrate(srcObject) {
        if(
            typeof srcObject === 'undefined' ||
            srcObject === null
        ) srcObject = {};

        const propertyNames = this.getAllProperties(this);

        propertyNames.forEach((propertyName) => {
            let curr = this
            let descriptor = null
            do {
                descriptor = Object.getOwnPropertyDescriptor(curr, propertyName);
                if(descriptor && !descriptor.set) descriptor = null;
                if(descriptor) break;
            } while(curr = Object.getPrototypeOf(curr))

            if(descriptor) {
                this[propertyName] = srcObject.hasOwnProperty(propertyName) ? srcObject[propertyName] : undefined;
            }
        })
    }

    toJSON() {
        const propertyNames = this.getAllProperties(this);

        return propertyNames.reduce((dstObject, propertyName) => {
            dstObject[propertyName] = this[propertyName];
            return dstObject;
        }, {})
    }

    set state(value) {
        if(value >= 1 && value <= 4) {
            this._state = value;
        } else {
            this._state = (this.id && this.id > 0) ? States.PRISTINE: States.NEW;
        }
    }

    static newId() {
        return idCounter--;
    }


}

//Matches php property states
const States = {
    NEW: 1,
    PRISTINE: 2,
    DIRTY: 3,
    DELETED: 4,
}

export { States };