2
1
Fork 0
mirror of https://github.com/TryGhost/Ghost.git synced 2023-12-13 21:00:40 +01:00

🎨 register events in base model (#7560)

refs #7432

- all models implemented it's own initialize fn to register events
- we can register all events in the base model
- important: we only listen on the event, if the model has defined a hook for it
- this is just a small clean up PR
- register more bookshelf events
This commit is contained in:
Katharina Irrgang 2016-10-14 14:37:01 +02:00 committed by Hannah Wolfe
parent 4411f8254f
commit 8cd5d9f6fe
9 changed files with 177 additions and 182 deletions

View file

@ -13,12 +13,8 @@ Accesstoken = Basetoken.extend({
events.emit('token' + '.' + event, this);
},
initialize: function initialize() {
ghostBookshelf.Model.prototype.initialize.apply(this, arguments);
this.on('created', function onCreated(model) {
model.emitChange('added');
});
onCreated: function onCreated(model) {
model.emitChange('added');
}
});

View file

@ -5,11 +5,11 @@ var ghostBookshelf = require('./base'),
App = ghostBookshelf.Model.extend({
tableName: 'apps',
saving: function saving(newPage, attr, options) {
onSaving: function onSaving(newPage, attr, options) {
/*jshint unused:false*/
var self = this;
ghostBookshelf.Model.prototype.saving.apply(this, arguments);
ghostBookshelf.Model.prototype.onSaving.apply(this, arguments);
if (this.hasChanged('slug') || !this.get('slug')) {
// Pass the new slug through the generator to strip illegal characters, detect duplicates

View file

@ -79,25 +79,41 @@ ghostBookshelf.Model = ghostBookshelf.Model.extend({
this.include = _.clone(options.include);
}
this.on('creating', this.creating, this);
this.on('saving', function onSaving(model, attributes, options) {
return Promise.resolve(self.saving(model, attributes, options)).then(function then() {
return self.validate(model, attributes, options);
['fetching', 'fetched', 'creating', 'created', 'updating', 'updated', 'destroying', 'destroyed', 'saved']
.forEach(function (eventName) {
var functionName = 'on' + eventName[0].toUpperCase() + eventName.slice(1);
if (!self[functionName]) {
return;
}
self.on(eventName, function eventTriggered() {
return this[functionName].apply(this, arguments);
});
});
this.on('saving', function onSaving() {
var self = this,
args = arguments;
return Promise.resolve(self.onSaving.apply(self, args))
.then(function validated() {
return Promise.resolve(self.onValidate.apply(self, args));
});
});
},
validate: function validate() {
onValidate: function onValidate() {
return validation.validateSchema(this.tableName, this.toJSON());
},
creating: function creating(newObj, attr, options) {
onCreating: function onCreating(newObj, attr, options) {
if (!this.get('created_by')) {
this.set('created_by', this.contextUser(options));
}
},
saving: function saving(newObj, attr, options) {
onSaving: function onSaving(newObj, attr, options) {
// Remove any properties which don't belong on the model
this.attributes = this.pick(this.permittedAttributes());
// Store the previous attributes so we can tell what was updated later

View file

@ -17,14 +17,11 @@ Basetoken = ghostBookshelf.Model.extend({
// override for base function since we don't have
// a created_by field for sessions
creating: function creating(newObj, attr, options) {
/*jshint unused:false*/
},
onCreating: function onCreating() {},
// override for base function since we don't have
// a updated_by field for sessions
saving: function saving(newObj, attr, options) {
/*jshint unused:false*/
onSaving: function onSaving() {
// Remove any properties which don't belong on the model
this.attributes = this.pick(this.permittedAttributes());
}

View file

@ -38,113 +38,106 @@ Post = ghostBookshelf.Model.extend({
};
},
initialize: function initialize() {
var self = this;
onSaved: function onSaved(model, response, options) {
return this.updateTags(model, response, options);
},
ghostBookshelf.Model.prototype.initialize.apply(this, arguments);
onCreated: function onCreated(model) {
var status = model.get('status');
model.emitChange('added');
this.on('saved', function onSaved(model, response, options) {
return self.updateTags(model, response, options);
});
if (['published', 'scheduled'].indexOf(status) !== -1) {
model.emitChange(status);
}
},
this.on('created', function onCreated(model) {
var status = model.get('status');
onUpdated: function onUpdated(model) {
model.statusChanging = model.get('status') !== model.updated('status');
model.isPublished = model.get('status') === 'published';
model.isScheduled = model.get('status') === 'scheduled';
model.wasPublished = model.updated('status') === 'published';
model.wasScheduled = model.updated('status') === 'scheduled';
model.resourceTypeChanging = model.get('page') !== model.updated('page');
model.publishedAtHasChanged = model.hasDateChanged('published_at');
model.needsReschedule = model.publishedAtHasChanged && model.isScheduled;
// Handle added and deleted for post -> page or page -> post
if (model.resourceTypeChanging) {
if (model.wasPublished) {
model.emitChange('unpublished', true);
}
if (model.wasScheduled) {
model.emitChange('unscheduled', true);
}
model.emitChange('deleted', true);
model.emitChange('added');
if (['published', 'scheduled'].indexOf(status) !== -1) {
model.emitChange(status);
if (model.isPublished) {
model.emitChange('published');
}
});
this.on('updated', function onUpdated(model) {
model.statusChanging = model.get('status') !== model.updated('status');
model.isPublished = model.get('status') === 'published';
model.isScheduled = model.get('status') === 'scheduled';
model.wasPublished = model.updated('status') === 'published';
model.wasScheduled = model.updated('status') === 'scheduled';
model.resourceTypeChanging = model.get('page') !== model.updated('page');
model.publishedAtHasChanged = model.hasDateChanged('published_at');
model.needsReschedule = model.publishedAtHasChanged && model.isScheduled;
// Handle added and deleted for post -> page or page -> post
if (model.resourceTypeChanging) {
if (model.isScheduled) {
model.emitChange('scheduled');
}
} else {
if (model.statusChanging) {
// CASE: was published before and is now e.q. draft or scheduled
if (model.wasPublished) {
model.emitChange('unpublished', true);
model.emitChange('unpublished');
}
if (model.wasScheduled) {
model.emitChange('unscheduled', true);
}
model.emitChange('deleted', true);
model.emitChange('added');
// CASE: was draft or scheduled before and is now e.q. published
if (model.isPublished) {
model.emitChange('published');
}
// CASE: was draft or published before and is now e.q. scheduled
if (model.isScheduled) {
model.emitChange('scheduled');
}
// CASE: from scheduled to something
if (model.wasScheduled && !model.isScheduled && !model.isPublished) {
model.emitChange('unscheduled');
}
} else {
if (model.statusChanging) {
// CASE: was published before and is now e.q. draft or scheduled
if (model.wasPublished) {
model.emitChange('unpublished');
}
// CASE: was draft or scheduled before and is now e.q. published
if (model.isPublished) {
model.emitChange('published');
}
// CASE: was draft or published before and is now e.q. scheduled
if (model.isScheduled) {
model.emitChange('scheduled');
}
// CASE: from scheduled to something
if (model.wasScheduled && !model.isScheduled && !model.isPublished) {
model.emitChange('unscheduled');
}
} else {
if (model.isPublished) {
model.emitChange('published.edited');
}
if (model.needsReschedule) {
model.emitChange('rescheduled');
}
if (model.isPublished) {
model.emitChange('published.edited');
}
// Fire edited if this wasn't a change between resourceType
model.emitChange('edited');
if (model.needsReschedule) {
model.emitChange('rescheduled');
}
}
});
this.on('destroying', function (model, options) {
return model.load('tags', options)
.then(function (response) {
if (!response.related || !response.related('tags') || !response.related('tags').length) {
return;
}
return Promise.mapSeries(response.related('tags').models, function (tag) {
return baseUtils.tagUpdate.detachTagFromPost(model, tag, options)();
});
})
.then(function () {
if (model.previous('status') === 'published') {
model.emitChange('unpublished');
}
model.emitChange('deleted');
});
});
// Fire edited if this wasn't a change between resourceType
model.emitChange('edited');
}
},
saving: function saving(model, attr, options) {
onDestroying: function onDestroying(model, options) {
return model.load('tags', options)
.then(function (response) {
if (!response.related || !response.related('tags') || !response.related('tags').length) {
return;
}
return Promise.mapSeries(response.related('tags').models, function (tag) {
return baseUtils.tagUpdate.detachTagFromPost(model, tag, options)();
});
})
.then(function () {
if (model.previous('status') === 'published') {
model.emitChange('unpublished');
}
model.emitChange('deleted');
});
},
onSaving: function onSaving(model, attr, options) {
options = options || {};
var self = this,
@ -207,7 +200,7 @@ Post = ghostBookshelf.Model.extend({
this.tagsToSave = tags;
}
ghostBookshelf.Model.prototype.saving.call(this, model, attr, options);
ghostBookshelf.Model.prototype.onSaving.call(this, model, attr, options);
if (mobiledoc) {
this.set('html', converter.render(JSON.parse(mobiledoc)).result);
@ -267,7 +260,7 @@ Post = ghostBookshelf.Model.extend({
}
},
creating: function creating(model, attr, options) {
onCreating: function onCreating(model, attr, options) {
options = options || {};
// set any dynamic default properties
@ -275,7 +268,7 @@ Post = ghostBookshelf.Model.extend({
this.set('author_id', this.contextUser(options));
}
ghostBookshelf.Model.prototype.creating.call(this, model, attr, options);
ghostBookshelf.Model.prototype.onCreating.call(this, model, attr, options);
},
/**

View file

@ -55,24 +55,22 @@ Settings = ghostBookshelf.Model.extend({
events.emit('settings' + '.' + event, this);
},
initialize: function initialize() {
ghostBookshelf.Model.prototype.initialize.apply(this, arguments);
this.on('created', function (model) {
model.emitChange('added');
model.emitChange(model.attributes.key + '.' + 'added');
});
this.on('updated', function (model) {
model.emitChange('edited');
model.emitChange(model.attributes.key + '.' + 'edited');
});
this.on('destroyed', function (model) {
model.emitChange('deleted');
model.emitChange(model.attributes.key + '.' + 'deleted');
});
onDestroyed: function onDestroyed(model) {
model.emitChange('deleted');
model.emitChange(model.attributes.key + '.' + 'deleted');
},
validate: function validate() {
onCreated: function onCreated(model) {
model.emitChange('added');
model.emitChange(model.attributes.key + '.' + 'added');
},
onUpdated: function onUpdated(model) {
model.emitChange('edited');
model.emitChange(model.attributes.key + '.' + 'edited');
},
onValidate: function onValidate() {
var self = this,
setting = this.toJSON();

View file

@ -13,23 +13,24 @@ Subscriber = ghostBookshelf.Model.extend({
emitChange: function emitChange(event) {
events.emit('subscriber' + '.' + event, this);
},
defaults: function defaults() {
return {
uuid: uuid.v4(),
status: 'subscribed'
};
},
initialize: function initialize() {
ghostBookshelf.Model.prototype.initialize.apply(this, arguments);
this.on('created', function onCreated(model) {
model.emitChange('added');
});
this.on('updated', function onUpdated(model) {
model.emitChange('edited');
});
this.on('destroyed', function onDestroyed(model) {
model.emitChange('deleted');
});
onCreated: function onCreated(model) {
model.emitChange('added');
},
onUpdated: function onUpdated(model) {
model.emitChange('edited');
},
onDestroyed: function onDestroyed(model) {
model.emitChange('deleted');
}
}, {

View file

@ -12,26 +12,23 @@ Tag = ghostBookshelf.Model.extend({
events.emit('tag' + '.' + event, this);
},
initialize: function initialize() {
ghostBookshelf.Model.prototype.initialize.apply(this, arguments);
this.on('created', function onCreated(model) {
model.emitChange('added');
});
this.on('updated', function onUpdated(model) {
model.emitChange('edited');
});
this.on('destroyed', function onDestroyed(model) {
model.emitChange('deleted');
});
onCreated: function onCreated(model) {
model.emitChange('added');
},
saving: function saving(newPage, attr, options) {
/*jshint unused:false*/
onUpdated: function onUpdated(model) {
model.emitChange('edited');
},
onDestroyed: function onDestroyed(model) {
model.emitChange('deleted');
},
onSaving: function onSaving(newPage, attr, options) {
/*jshint unused:false*/
var self = this;
ghostBookshelf.Model.prototype.saving.apply(this, arguments);
ghostBookshelf.Model.prototype.onSaving.apply(this, arguments);
if (this.hasChanged('slug') || !this.get('slug')) {
// Pass the new slug through the generator to strip illegal characters, detect duplicates

View file

@ -41,46 +41,43 @@ User = ghostBookshelf.Model.extend({
events.emit('user' + '.' + event, this);
},
initialize: function initialize() {
ghostBookshelf.Model.prototype.initialize.apply(this, arguments);
onDestroyed: function onDestroyed(model) {
if (_.includes(activeStates, model.previous('status'))) {
model.emitChange('deactivated');
}
this.on('created', function onCreated(model) {
model.emitChange('added');
// active is the default state, so if status isn't provided, this will be an active user
if (!model.get('status') || _.includes(activeStates, model.get('status'))) {
model.emitChange('activated');
}
});
this.on('updated', function onUpdated(model) {
model.statusChanging = model.get('status') !== model.updated('status');
model.isActive = _.includes(activeStates, model.get('status'));
if (model.statusChanging) {
model.emitChange(model.isActive ? 'activated' : 'deactivated');
} else {
if (model.isActive) {
model.emitChange('activated.edited');
}
}
model.emitChange('edited');
});
this.on('destroyed', function onDestroyed(model) {
if (_.includes(activeStates, model.previous('status'))) {
model.emitChange('deactivated');
}
model.emitChange('deleted');
});
model.emitChange('deleted');
},
saving: function saving(newPage, attr, options) {
/*jshint unused:false*/
onCreated: function onCreated(model) {
model.emitChange('added');
// active is the default state, so if status isn't provided, this will be an active user
if (!model.get('status') || _.includes(activeStates, model.get('status'))) {
model.emitChange('activated');
}
},
onUpdated: function onUpdated(model) {
model.statusChanging = model.get('status') !== model.updated('status');
model.isActive = _.includes(activeStates, model.get('status'));
if (model.statusChanging) {
model.emitChange(model.isActive ? 'activated' : 'deactivated');
} else {
if (model.isActive) {
model.emitChange('activated.edited');
}
}
model.emitChange('edited');
},
onSaving: function onSaving(newPage, attr, options) {
/*jshint unused:false*/
var self = this;
ghostBookshelf.Model.prototype.saving.apply(this, arguments);
ghostBookshelf.Model.prototype.onSaving.apply(this, arguments);
if (this.hasChanged('slug') || !this.get('slug')) {
// Generating a slug requires a db call to look for conflicting slugs
@ -95,7 +92,7 @@ User = ghostBookshelf.Model.extend({
// For the user model ONLY it is possible to disable validations.
// This is used to bypass validation during the credential check, and must never be done with user-provided data
// Should be removed when #3691 is done
validate: function validate() {
onValidate: function validate() {
var opts = arguments[1],
userData;