diff --git a/examples/getstarted/api/homepage/models/homepage.settings.json b/examples/getstarted/api/homepage/models/homepage.settings.json index 4cb7646c00..d386db54d3 100644 --- a/examples/getstarted/api/homepage/models/homepage.settings.json +++ b/examples/getstarted/api/homepage/models/homepage.settings.json @@ -34,4 +34,4 @@ "required": false } } -} \ No newline at end of file +} diff --git a/examples/getstarted/api/restaurant/models/Restaurant.settings.json b/examples/getstarted/api/restaurant/models/Restaurant.settings.json index 7445682e56..75a2daa437 100755 --- a/examples/getstarted/api/restaurant/models/Restaurant.settings.json +++ b/examples/getstarted/api/restaurant/models/Restaurant.settings.json @@ -10,6 +10,11 @@ "timestamps": ["created_at", "updated_at"], "comment": "" }, + "pluginOptions": { + "i18n": { + "enabled": true + } + }, "attributes": { "name": { "maxLength": 50, diff --git a/packages/strapi-plugin-i18n/config/functions/bootstrap.js b/packages/strapi-plugin-i18n/config/functions/bootstrap.js index 151fa2626d..537301543f 100644 --- a/packages/strapi-plugin-i18n/config/functions/bootstrap.js +++ b/packages/strapi-plugin-i18n/config/functions/bootstrap.js @@ -1,6 +1,7 @@ 'use strict'; -const { capitalize } = require('lodash/fp'); +const _ = require('lodash'); +const { capitalize, prop } = require('lodash/fp'); const actions = ['create', 'read', 'update', 'delete'].map(uid => ({ section: 'settings', @@ -14,4 +15,34 @@ const actions = ['create', 'read', 'update', 'delete'].map(uid => ({ module.exports = () => { const { actionProvider } = strapi.admin.services.permission; actionProvider.register(actions); + + // register custom permissions + + // register database mixin to modify model behaviours + + // update model lifecycles + + // create the localization of the object & link it to the other localizations it has + + Object.values(strapi.contentTypes).forEach(contentType => { + if (prop('pluginOptions.i18n.enabled')(contentType) === true) { + console.log('i18N is enabled for ', contentType.modelName); + + const model = strapi.getModel(contentType.uid); + + _.set(model, 'lifecycles.beforeCreate', async () => {}); + + _.set(model, 'lifecycles.afterCreate', async () => {}); + + _.set(model, 'lifecycles.beforeFind', async () => {}); + } + }); + + // wrap content manager routes + + strapi.plugin('content-manager').config.routes.forEach(() => { + // add a policy to the route we want to extend + }); + + // or overwrite controllers }; diff --git a/packages/strapi-plugin-i18n/config/functions/register.js b/packages/strapi-plugin-i18n/config/functions/register.js new file mode 100644 index 0000000000..6d7ae722e6 --- /dev/null +++ b/packages/strapi-plugin-i18n/config/functions/register.js @@ -0,0 +1,43 @@ +'use strict'; + +const _ = require('lodash'); + +// add a register function to do some stuff after the loading but before the boot +module.exports = () => { + // need to add some logic to the db layer so we can add fields to the models + + Object.values(strapi.models).forEach(model => { + if (_.get(model, 'pluginOptions.i18n.enabled', false) === true) { + // find a way to specify the id to use in the relations or compo relations + // model.relationalId = 'strapi_id'; + // model.attributes.compo.relationalId = 'strapi_id'; + + _.set(model.attributes, 'strapi_id', { + writable: true, + private: false, + configurable: false, + type: 'string', + }); + + _.set(model.attributes, 'localizations', { + writable: true, + private: false, + configurable: false, + type: 'json', + }); + + _.set(model.attributes, 'locale', { + writable: true, + private: false, + configurable: false, + type: 'string', + default: 'en-US', + }); + } + }); + + // strapi.database.migrations.push({ + // before() {}, + // after() {}, + // }); +}; diff --git a/packages/strapi-utils/lib/content-types.js b/packages/strapi-utils/lib/content-types.js index 02f15e4a61..e25b41f82d 100644 --- a/packages/strapi-utils/lib/content-types.js +++ b/packages/strapi-utils/lib/content-types.js @@ -67,7 +67,12 @@ const getWritableAttributes = (model = {}) => { }; const getNonVisibleAttributes = model => { - return _.uniq([model.primaryKey, ...getTimestamps(model), ...NON_VISIBLE_ATTRIBUTES]); + return _.uniq([ + model.primaryKey, + ...NON_VISIBLE_ATTRIBUTES, + ...getTimestamps(model), + ...getNonWritableAttributes(model), + ]); }; const getVisibleAttributes = model => { diff --git a/packages/strapi/lib/Strapi.js b/packages/strapi/lib/Strapi.js index caf34d144f..0eeb54489a 100644 --- a/packages/strapi/lib/Strapi.js +++ b/packages/strapi/lib/Strapi.js @@ -335,6 +335,8 @@ class Strapi { this.models['core_store'] = coreStoreModel(this.config); this.models['strapi_webhooks'] = webhookModel(this.config); + await this.runRegisterFunctions(); + this.db = createDatabaseManager(this); await this.db.initialize(); @@ -443,6 +445,35 @@ class Strapi { }); } + async runRegisterFunctions() { + const execRegister = async fn => { + if (!fn) return; + + return fn(); + }; + + // plugins bootstrap + const pluginBoostraps = Object.keys(this.plugins).map(plugin => { + return execRegister(_.get(this.plugins[plugin], 'config.functions.register')).catch(err => { + strapi.log.error(`Register function in plugin "${plugin}" failed`); + strapi.log.error(err); + strapi.stop(); + }); + }); + await Promise.all(pluginBoostraps); + + // // user bootstrap + // await execBootstrap(_.get(this.config, ['functions', 'bootstrap'])); + + // // admin bootstrap : should always run after the others + // const adminBootstrap = _.get(this.admin.config, 'functions.bootstrap'); + // return execBootstrap(adminBootstrap).catch(err => { + // strapi.log.error(`Bootstrap function in admin failed`); + // strapi.log.error(err); + // strapi.stop(); + // }); + } + async freeze() { Object.freeze(this.config); Object.freeze(this.dir); @@ -463,6 +494,14 @@ class Strapi { query(entity, plugin) { return this.db.query(entity, plugin); } + + plugin(name) { + if (!_.has(this.plugins, name)) { + throw new Error(`Undefined plugin ${name}`); + } + + return this.plugins[name]; + } } module.exports = options => {