mirror of
https://github.com/TryGhost/Ghost.git
synced 2024-12-25 03:44:29 +03:00
Merge pull request #2980 from jgable/lazyLoadDefaultSettings
Lazy load default settings
This commit is contained in:
commit
a3665cd917
@ -17,6 +17,8 @@ var _ = require('lodash'),
|
||||
readSettingsResult,
|
||||
settingsResult,
|
||||
canEditAllSettings,
|
||||
populateDefaultSetting,
|
||||
hasPopulatedDefaults = false,
|
||||
|
||||
/**
|
||||
* ## Cache
|
||||
@ -183,6 +185,38 @@ settingsResult = function (settings, type) {
|
||||
return result;
|
||||
};
|
||||
|
||||
/**
|
||||
* ### Populate Default Setting
|
||||
* @private
|
||||
* @param key
|
||||
* @param type
|
||||
* @returns Promise(Setting)
|
||||
*/
|
||||
populateDefaultSetting = function (key) {
|
||||
// Call populateDefault and update the settings cache
|
||||
return dataProvider.Settings.populateDefault(key).then(function (defaultSetting) {
|
||||
// Process the default result and add to settings cache
|
||||
var readResult = readSettingsResult(defaultSetting);
|
||||
|
||||
// Add to the settings cache
|
||||
return updateSettingsCache(readResult).then(function () {
|
||||
// Update theme with the new settings
|
||||
return config.theme.update(settings, config().url);
|
||||
}).then(function () {
|
||||
// Get the result from the cache with permission checks
|
||||
return defaultSetting;
|
||||
});
|
||||
}).otherwise(function (err) {
|
||||
// Pass along NotFoundError
|
||||
if (typeof err === errors.NotFoundError) {
|
||||
return when.reject(err);
|
||||
}
|
||||
|
||||
// TODO: Different kind of error?
|
||||
return when.reject(new errors.NotFoundError('Problem finding setting: ' + key));
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* ### Can Edit All Settings
|
||||
* Check that this edit request is allowed for all settings requested to be updated
|
||||
@ -191,21 +225,28 @@ settingsResult = function (settings, type) {
|
||||
* @returns {*}
|
||||
*/
|
||||
canEditAllSettings = function (settingsInfo, options) {
|
||||
var checks = _.map(settingsInfo, function (settingInfo) {
|
||||
var setting = settingsCache[settingInfo.key];
|
||||
var checkSettingPermissions = function (setting) {
|
||||
if (setting.type === 'core' && !(options.context && options.context.internal)) {
|
||||
return when.reject(
|
||||
new errors.NoPermissionError('Attempted to access core setting from external request')
|
||||
);
|
||||
}
|
||||
|
||||
if (!setting) {
|
||||
return when.reject(new errors.NotFoundError('Unable to find setting: ' + settingInfo.key));
|
||||
}
|
||||
return canThis(options.context).edit.setting(setting.key);
|
||||
},
|
||||
checks = _.map(settingsInfo, function (settingInfo) {
|
||||
var setting = settingsCache[settingInfo.key];
|
||||
|
||||
if (setting.type === 'core' && !(options.context && options.context.internal)) {
|
||||
return when.reject(
|
||||
new errors.NoPermissionError('Attempted to access core setting from external request')
|
||||
);
|
||||
}
|
||||
if (!setting) {
|
||||
// Try to populate a default setting if not in the cache
|
||||
return populateDefaultSetting(settingInfo.key).then(function (defaultSetting) {
|
||||
// Get the result from the cache with permission checks
|
||||
return checkSettingPermissions(defaultSetting);
|
||||
});
|
||||
}
|
||||
|
||||
return canThis(options.context).edit.setting(settingInfo.key);
|
||||
});
|
||||
return checkSettingPermissions(setting);
|
||||
});
|
||||
|
||||
return when.all(checks);
|
||||
};
|
||||
@ -223,6 +264,14 @@ settings = {
|
||||
* @returns {*}
|
||||
*/
|
||||
browse: function browse(options) {
|
||||
// First, check if we have populated the settings from default-settings yet
|
||||
if (!hasPopulatedDefaults) {
|
||||
return dataProvider.Settings.populateDefaults().then(function () {
|
||||
hasPopulatedDefaults = true;
|
||||
return settings.browse(options);
|
||||
});
|
||||
}
|
||||
|
||||
options = options || {};
|
||||
|
||||
var result = settingsResult(settingsCache, options.type);
|
||||
@ -253,30 +302,40 @@ settings = {
|
||||
options = { key: options };
|
||||
}
|
||||
|
||||
var setting = settingsCache[options.key],
|
||||
result = {};
|
||||
var getSettingsResult = function () {
|
||||
var setting = settingsCache[options.key],
|
||||
result = {};
|
||||
|
||||
if (!setting) {
|
||||
return when.reject(new errors.NotFoundError('Unable to find setting: ' + options.key));
|
||||
result[options.key] = setting;
|
||||
|
||||
if (setting.type === 'core' && !(options.context && options.context.internal)) {
|
||||
return when.reject(
|
||||
new errors.NoPermissionError('Attempted to access core setting from external request')
|
||||
);
|
||||
}
|
||||
|
||||
if (setting.type === 'blog') {
|
||||
return when(settingsResult(result));
|
||||
}
|
||||
|
||||
return canThis(options.context).read.setting(options.key).then(function () {
|
||||
return settingsResult(result);
|
||||
}, function () {
|
||||
return when.reject(new errors.NoPermissionError('You do not have permission to read settings.'));
|
||||
});
|
||||
};
|
||||
|
||||
// If the setting is not already in the cache
|
||||
if (!settingsCache[options.key]) {
|
||||
// Try to populate the setting from default-settings file
|
||||
return populateDefaultSetting(options.key).then(function () {
|
||||
// Get the result from the cache with permission checks
|
||||
return getSettingsResult();
|
||||
});
|
||||
}
|
||||
|
||||
result[options.key] = setting;
|
||||
|
||||
if (setting.type === 'core' && !(options.context && options.context.internal)) {
|
||||
return when.reject(
|
||||
new errors.NoPermissionError('Attempted to access core setting from external request')
|
||||
);
|
||||
}
|
||||
|
||||
if (setting.type === 'blog') {
|
||||
return when(settingsResult(result));
|
||||
}
|
||||
|
||||
return canThis(options.context).read.setting(options.key).then(function () {
|
||||
return settingsResult(result);
|
||||
}, function () {
|
||||
return when.reject(new errors.NoPermissionError('You do not have permission to read settings.'));
|
||||
});
|
||||
// Get the result from the cache with permission checks
|
||||
return getSettingsResult();
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -13,9 +13,7 @@ var _ = require('lodash'),
|
||||
function getDefaultDatabaseVersion() {
|
||||
if (!defaultDatabaseVersion) {
|
||||
// This be the current version according to the software
|
||||
defaultDatabaseVersion = _.find(defaultSettings.core, function (setting) {
|
||||
return setting.key === 'databaseVersion';
|
||||
}).defaultValue;
|
||||
defaultDatabaseVersion = defaultSettings.core.databaseVersion.defaultValue;
|
||||
}
|
||||
|
||||
return defaultDatabaseVersion;
|
||||
|
@ -215,9 +215,6 @@ function init(server) {
|
||||
return builtFilesExist().then(function () {
|
||||
// Initialise the models
|
||||
return models.init();
|
||||
}).then(function () {
|
||||
// Populate any missing default settings
|
||||
return models.Settings.populateDefaults();
|
||||
}).then(function () {
|
||||
// Initialize the settings cache
|
||||
return api.init();
|
||||
|
@ -25,7 +25,14 @@ function parseDefaultSettings() {
|
||||
|
||||
return defaultSettingsFlattened;
|
||||
}
|
||||
defaultSettings = parseDefaultSettings();
|
||||
|
||||
function getDefaultSettings() {
|
||||
if (!defaultSettings) {
|
||||
defaultSettings = parseDefaultSettings();
|
||||
}
|
||||
|
||||
return defaultSettings;
|
||||
}
|
||||
|
||||
// Each setting is saved as a separate row in the database,
|
||||
// but the overlying API treats them as a single key:value mapping
|
||||
@ -43,7 +50,7 @@ Settings = ghostBookshelf.Model.extend({
|
||||
validate: function () {
|
||||
var self = this;
|
||||
return when(validation.validateSchema(self.tableName, self.toJSON())).then(function () {
|
||||
return validation.validateSettings(defaultSettings, self);
|
||||
return validation.validateSettings(getDefaultSettings(), self);
|
||||
});
|
||||
},
|
||||
|
||||
@ -117,12 +124,31 @@ Settings = ghostBookshelf.Model.extend({
|
||||
});
|
||||
},
|
||||
|
||||
populateDefault: function (key) {
|
||||
if (!getDefaultSettings()[key]) {
|
||||
return when.reject(new errors.NotFoundError('Unable to find default setting: ' + key));
|
||||
}
|
||||
|
||||
// TOOD: databaseVersion and currentVersion special cases?
|
||||
|
||||
this.findOne({ key: key }).then(function (foundSetting) {
|
||||
if (foundSetting) {
|
||||
return foundSetting;
|
||||
}
|
||||
|
||||
var defaultSetting = _.clone(getDefaultSettings()[key]);
|
||||
defaultSetting.value = defaultSetting.defaultValue;
|
||||
|
||||
return Settings.forge(defaultSetting).save(null, {user: 1});
|
||||
});
|
||||
},
|
||||
|
||||
populateDefaults: function () {
|
||||
return this.findAll().then(function (allSettings) {
|
||||
var usedKeys = allSettings.models.map(function (setting) { return setting.get('key'); }),
|
||||
insertOperations = [];
|
||||
|
||||
_.each(defaultSettings, function (defaultSetting, defaultSettingKey) {
|
||||
_.each(getDefaultSettings(), function (defaultSetting, defaultSettingKey) {
|
||||
var isMissingFromDB = usedKeys.indexOf(defaultSettingKey) === -1;
|
||||
// Temporary code to deal with old databases with currentVersion settings
|
||||
if (defaultSettingKey === 'databaseVersion' && usedKeys.indexOf('currentVersion') !== -1) {
|
||||
|
Loading…
Reference in New Issue
Block a user