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 };