mirror of
https://github.com/flarum/framework.git
synced 2025-04-09 08:16:36 +08:00
Refactor the web app bootstrapping code
- All custom JS variables are now preloaded into the `app.data` object, rather than directly on the `app` object. This means that admin settings are available in `app.data.settings` rather than `app.settings`, etc. - Cleaner route handler generation - Renamed ConfigureClientView to ConfigureWebApp, though the former still exists and is deprecated - Partial fix for #881 (strips ?nojs=1 from URL if possible, so that refreshing will attempt to load JS version again)
This commit is contained in:
parent
e07b5eb8eb
commit
d2bce5d756
82
framework/core/js/admin/dist/app.js
vendored
82
framework/core/js/admin/dist/app.js
vendored
@ -16669,24 +16669,6 @@ System.register('flarum/App', ['flarum/utils/ItemList', 'flarum/components/Alert
|
|||||||
*/
|
*/
|
||||||
this.routes = {};
|
this.routes = {};
|
||||||
|
|
||||||
/**
|
|
||||||
* An object containing data to preload into the application.
|
|
||||||
*
|
|
||||||
* @type {Object}
|
|
||||||
* @property {Object} preload.data An array of resource objects to preload
|
|
||||||
* into the data store.
|
|
||||||
* @property {Object} preload.document An API response document to be used
|
|
||||||
* by the route that is first activated.
|
|
||||||
* @property {Object} preload.session A response from the /api/token
|
|
||||||
* endpoint containing the session's authentication token and user ID.
|
|
||||||
* @public
|
|
||||||
*/
|
|
||||||
this.preload = {
|
|
||||||
data: null,
|
|
||||||
document: null,
|
|
||||||
session: null
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An ordered list of initializers to bootstrap the application.
|
* An ordered list of initializers to bootstrap the application.
|
||||||
*
|
*
|
||||||
@ -16758,10 +16740,12 @@ System.register('flarum/App', ['flarum/utils/ItemList', 'flarum/components/Alert
|
|||||||
|
|
||||||
babelHelpers.createClass(App, [{
|
babelHelpers.createClass(App, [{
|
||||||
key: 'boot',
|
key: 'boot',
|
||||||
value: function boot() {
|
value: function boot(data) {
|
||||||
var _this = this;
|
var _this = this;
|
||||||
|
|
||||||
this.translator.locale = this.locale;
|
this.data = data;
|
||||||
|
|
||||||
|
this.translator.locale = data.locale;
|
||||||
|
|
||||||
this.initializers.toArray().forEach(function (initializer) {
|
this.initializers.toArray().forEach(function (initializer) {
|
||||||
return initializer(_this);
|
return initializer(_this);
|
||||||
@ -16770,9 +16754,9 @@ System.register('flarum/App', ['flarum/utils/ItemList', 'flarum/components/Alert
|
|||||||
}, {
|
}, {
|
||||||
key: 'preloadedDocument',
|
key: 'preloadedDocument',
|
||||||
value: function preloadedDocument() {
|
value: function preloadedDocument() {
|
||||||
if (app.preload.document) {
|
if (this.data.document) {
|
||||||
var results = app.store.pushPayload(app.preload.document);
|
var results = this.store.pushPayload(this.data.document);
|
||||||
app.preload.document = null;
|
this.data.document = null;
|
||||||
|
|
||||||
return results;
|
return results;
|
||||||
}
|
}
|
||||||
@ -17500,10 +17484,10 @@ System.register('flarum/components/AppearancePage', ['flarum/components/Page', '
|
|||||||
value: function init() {
|
value: function init() {
|
||||||
babelHelpers.get(Object.getPrototypeOf(AppearancePage.prototype), 'init', this).call(this);
|
babelHelpers.get(Object.getPrototypeOf(AppearancePage.prototype), 'init', this).call(this);
|
||||||
|
|
||||||
this.primaryColor = m.prop(app.settings.theme_primary_color);
|
this.primaryColor = m.prop(app.data.settings.theme_primary_color);
|
||||||
this.secondaryColor = m.prop(app.settings.theme_secondary_color);
|
this.secondaryColor = m.prop(app.data.settings.theme_secondary_color);
|
||||||
this.darkMode = m.prop(app.settings.theme_dark_mode === '1');
|
this.darkMode = m.prop(app.data.settings.theme_dark_mode === '1');
|
||||||
this.coloredHeader = m.prop(app.settings.theme_colored_header === '1');
|
this.coloredHeader = m.prop(app.data.settings.theme_colored_header === '1');
|
||||||
}
|
}
|
||||||
}, {
|
}, {
|
||||||
key: 'view',
|
key: 'view',
|
||||||
@ -17702,13 +17686,13 @@ System.register('flarum/components/BasicsPage', ['flarum/components/Page', 'flar
|
|||||||
this.fields = ['forum_title', 'forum_description', 'default_locale', 'default_route', 'welcome_title', 'welcome_message'];
|
this.fields = ['forum_title', 'forum_description', 'default_locale', 'default_route', 'welcome_title', 'welcome_message'];
|
||||||
this.values = {};
|
this.values = {};
|
||||||
|
|
||||||
var settings = app.settings;
|
var settings = app.data.settings;
|
||||||
this.fields.forEach(function (key) {
|
this.fields.forEach(function (key) {
|
||||||
return _this2.values[key] = m.prop(settings[key]);
|
return _this2.values[key] = m.prop(settings[key]);
|
||||||
});
|
});
|
||||||
|
|
||||||
this.localeOptions = {};
|
this.localeOptions = {};
|
||||||
var locales = app.locales;
|
var locales = app.data.locales;
|
||||||
for (var i in locales) {
|
for (var i in locales) {
|
||||||
this.localeOptions[i] = locales[i] + ' (' + i + ')';
|
this.localeOptions[i] = locales[i] + ' (' + i + ')';
|
||||||
}
|
}
|
||||||
@ -17795,7 +17779,7 @@ System.register('flarum/components/BasicsPage', ['flarum/components/Page', 'flar
|
|||||||
var _this4 = this;
|
var _this4 = this;
|
||||||
|
|
||||||
return this.fields.some(function (key) {
|
return this.fields.some(function (key) {
|
||||||
return _this4.values[key]() !== app.settings[key];
|
return _this4.values[key]() !== app.data.settings[key];
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}, {
|
}, {
|
||||||
@ -18212,7 +18196,7 @@ System.register('flarum/components/EditCustomCssModal', ['flarum/components/Moda
|
|||||||
babelHelpers.createClass(EditCustomCssModal, [{
|
babelHelpers.createClass(EditCustomCssModal, [{
|
||||||
key: 'init',
|
key: 'init',
|
||||||
value: function init() {
|
value: function init() {
|
||||||
this.customLess = m.prop(app.settings.custom_less || '');
|
this.customLess = m.prop(app.data.settings.custom_less || '');
|
||||||
}
|
}
|
||||||
}, {
|
}, {
|
||||||
key: 'className',
|
key: 'className',
|
||||||
@ -18495,8 +18479,8 @@ System.register('flarum/components/ExtensionsPage', ['flarum/components/Page', '
|
|||||||
m(
|
m(
|
||||||
'ul',
|
'ul',
|
||||||
{ className: 'ExtensionList' },
|
{ className: 'ExtensionList' },
|
||||||
Object.keys(app.extensions).map(function (id) {
|
Object.keys(app.data.extensions).map(function (id) {
|
||||||
var extension = app.extensions[id];
|
var extension = app.data.extensions[id];
|
||||||
var controls = _this2.controlItems(extension.id).toArray();
|
var controls = _this2.controlItems(extension.id).toArray();
|
||||||
|
|
||||||
return m(
|
return m(
|
||||||
@ -18576,7 +18560,7 @@ System.register('flarum/components/ExtensionsPage', ['flarum/components/Page', '
|
|||||||
}, {
|
}, {
|
||||||
key: 'isEnabled',
|
key: 'isEnabled',
|
||||||
value: function isEnabled(name) {
|
value: function isEnabled(name) {
|
||||||
var enabled = JSON.parse(app.settings.extensions_enabled);
|
var enabled = JSON.parse(app.data.settings.extensions_enabled);
|
||||||
|
|
||||||
return enabled.indexOf(name) !== -1;
|
return enabled.indexOf(name) !== -1;
|
||||||
}
|
}
|
||||||
@ -18970,7 +18954,7 @@ System.register('flarum/components/MailPage', ['flarum/components/Page', 'flarum
|
|||||||
this.fields = ['mail_driver', 'mail_host', 'mail_from', 'mail_port', 'mail_username', 'mail_password', 'mail_encryption'];
|
this.fields = ['mail_driver', 'mail_host', 'mail_from', 'mail_port', 'mail_username', 'mail_password', 'mail_encryption'];
|
||||||
this.values = {};
|
this.values = {};
|
||||||
|
|
||||||
var settings = app.settings;
|
var settings = app.data.settings;
|
||||||
this.fields.forEach(function (key) {
|
this.fields.forEach(function (key) {
|
||||||
return _this2.values[key] = m.prop(settings[key]);
|
return _this2.values[key] = m.prop(settings[key]);
|
||||||
});
|
});
|
||||||
@ -19086,7 +19070,7 @@ System.register('flarum/components/MailPage', ['flarum/components/Page', 'flarum
|
|||||||
var _this3 = this;
|
var _this3 = this;
|
||||||
|
|
||||||
return this.fields.some(function (key) {
|
return this.fields.some(function (key) {
|
||||||
return _this3.values[key]() !== app.settings[key];
|
return _this3.values[key]() !== app.data.settings[key];
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}, {
|
}, {
|
||||||
@ -19567,7 +19551,7 @@ System.register('flarum/components/PermissionDropdown', ['flarum/components/Drop
|
|||||||
|
|
||||||
this.props.children = [];
|
this.props.children = [];
|
||||||
|
|
||||||
var groupIds = app.permissions[this.props.permission] || [];
|
var groupIds = app.data.permissions[this.props.permission] || [];
|
||||||
var everyone = groupIds.indexOf(Group.GUEST_ID) !== -1;
|
var everyone = groupIds.indexOf(Group.GUEST_ID) !== -1;
|
||||||
var members = groupIds.indexOf(Group.MEMBER_ID) !== -1;
|
var members = groupIds.indexOf(Group.MEMBER_ID) !== -1;
|
||||||
var adminGroup = app.store.getById('groups', Group.ADMINISTRATOR_ID);
|
var adminGroup = app.store.getById('groups', Group.ADMINISTRATOR_ID);
|
||||||
@ -19626,7 +19610,7 @@ System.register('flarum/components/PermissionDropdown', ['flarum/components/Drop
|
|||||||
value: function save(groupIds) {
|
value: function save(groupIds) {
|
||||||
var permission = this.props.permission;
|
var permission = this.props.permission;
|
||||||
|
|
||||||
app.permissions[permission] = groupIds;
|
app.data.permissions[permission] = groupIds;
|
||||||
|
|
||||||
app.request({
|
app.request({
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
@ -19639,7 +19623,7 @@ System.register('flarum/components/PermissionDropdown', ['flarum/components/Drop
|
|||||||
value: function toggle(groupId) {
|
value: function toggle(groupId) {
|
||||||
var permission = this.props.permission;
|
var permission = this.props.permission;
|
||||||
|
|
||||||
var groupIds = app.permissions[permission] || [];
|
var groupIds = app.data.permissions[permission] || [];
|
||||||
|
|
||||||
var index = groupIds.indexOf(groupId);
|
var index = groupIds.indexOf(groupId);
|
||||||
|
|
||||||
@ -19843,7 +19827,7 @@ System.register('flarum/components/PermissionGrid', ['flarum/Component', 'flarum
|
|||||||
icon: 'i-cursor',
|
icon: 'i-cursor',
|
||||||
label: app.translator.trans('core.admin.permissions.allow_renaming_label'),
|
label: app.translator.trans('core.admin.permissions.allow_renaming_label'),
|
||||||
setting: function setting() {
|
setting: function setting() {
|
||||||
var minutes = parseInt(app.settings.allow_renaming, 10);
|
var minutes = parseInt(app.data.settings.allow_renaming, 10);
|
||||||
|
|
||||||
return SettingDropdown.component({
|
return SettingDropdown.component({
|
||||||
defaultLabel: minutes ? app.translator.transChoice('core.admin.permissions_controls.allow_some_minutes_button', minutes, { count: minutes }) : app.translator.trans('core.admin.permissions_controls.allow_indefinitely_button'),
|
defaultLabel: minutes ? app.translator.transChoice('core.admin.permissions_controls.allow_some_minutes_button', minutes, { count: minutes }) : app.translator.trans('core.admin.permissions_controls.allow_indefinitely_button'),
|
||||||
@ -19870,7 +19854,7 @@ System.register('flarum/components/PermissionGrid', ['flarum/Component', 'flarum
|
|||||||
icon: 'pencil',
|
icon: 'pencil',
|
||||||
label: app.translator.trans('core.admin.permissions.allow_post_editing_label'),
|
label: app.translator.trans('core.admin.permissions.allow_post_editing_label'),
|
||||||
setting: function setting() {
|
setting: function setting() {
|
||||||
var minutes = parseInt(app.settings.allow_post_editing, 10);
|
var minutes = parseInt(app.data.settings.allow_post_editing, 10);
|
||||||
|
|
||||||
return SettingDropdown.component({
|
return SettingDropdown.component({
|
||||||
defaultLabel: minutes ? app.translator.transChoice('core.admin.permissions_controls.allow_some_minutes_button', minutes, { count: minutes }) : app.translator.trans('core.admin.permissions_controls.allow_indefinitely_button'),
|
defaultLabel: minutes ? app.translator.transChoice('core.admin.permissions_controls.allow_some_minutes_button', minutes, { count: minutes }) : app.translator.trans('core.admin.permissions_controls.allow_indefinitely_button'),
|
||||||
@ -20399,7 +20383,7 @@ System.register('flarum/components/SettingDropdown', ['flarum/components/SelectD
|
|||||||
var value = _ref.value;
|
var value = _ref.value;
|
||||||
var label = _ref.label;
|
var label = _ref.label;
|
||||||
|
|
||||||
var active = app.settings[props.key] === value;
|
var active = app.data.settings[props.key] === value;
|
||||||
|
|
||||||
return Button.component({
|
return Button.component({
|
||||||
children: label,
|
children: label,
|
||||||
@ -20485,7 +20469,7 @@ System.register('flarum/components/SettingsModal', ['flarum/components/Modal', '
|
|||||||
value: function setting(key) {
|
value: function setting(key) {
|
||||||
var fallback = arguments.length <= 1 || arguments[1] === undefined ? '' : arguments[1];
|
var fallback = arguments.length <= 1 || arguments[1] === undefined ? '' : arguments[1];
|
||||||
|
|
||||||
this.settings[key] = this.settings[key] || m.prop(app.settings[key] || fallback);
|
this.settings[key] = this.settings[key] || m.prop(app.data.settings[key] || fallback);
|
||||||
|
|
||||||
return this.settings[key];
|
return this.settings[key];
|
||||||
}
|
}
|
||||||
@ -20499,7 +20483,7 @@ System.register('flarum/components/SettingsModal', ['flarum/components/Modal', '
|
|||||||
Object.keys(this.settings).forEach(function (key) {
|
Object.keys(this.settings).forEach(function (key) {
|
||||||
var value = _this2.settings[key]();
|
var value = _this2.settings[key]();
|
||||||
|
|
||||||
if (value !== app.settings[key]) {
|
if (value !== app.data.settings[key]) {
|
||||||
dirty[key] = value;
|
dirty[key] = value;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -21130,11 +21114,11 @@ System.register('flarum/initializers/humanTime', ['flarum/utils/humanTime'], fun
|
|||||||
System.register('flarum/initializers/preload', ['flarum/Session'], function (_export, _context) {
|
System.register('flarum/initializers/preload', ['flarum/Session'], function (_export, _context) {
|
||||||
var Session;
|
var Session;
|
||||||
function preload(app) {
|
function preload(app) {
|
||||||
app.store.pushPayload({ data: app.preload.data });
|
app.store.pushPayload({ data: app.data.resources });
|
||||||
|
|
||||||
app.forum = app.store.getById('forums', 1);
|
app.forum = app.store.getById('forums', 1);
|
||||||
|
|
||||||
app.session = new Session(app.store.getById('users', app.preload.session.userId), app.preload.session.csrfToken);
|
app.session = new Session(app.store.getById('users', app.data.session.userId), app.data.session.csrfToken);
|
||||||
}
|
}
|
||||||
|
|
||||||
_export('default', preload);
|
_export('default', preload);
|
||||||
@ -22977,16 +22961,16 @@ System.register("flarum/utils/RequestError", [], function (_export, _context) {
|
|||||||
|
|
||||||
System.register('flarum/utils/saveSettings', [], function (_export, _context) {
|
System.register('flarum/utils/saveSettings', [], function (_export, _context) {
|
||||||
function saveSettings(settings) {
|
function saveSettings(settings) {
|
||||||
var oldSettings = JSON.parse(JSON.stringify(app.settings));
|
var oldSettings = JSON.parse(JSON.stringify(app.data.settings));
|
||||||
|
|
||||||
babelHelpers.extends(app.settings, settings);
|
babelHelpers.extends(app.data.settings, settings);
|
||||||
|
|
||||||
return app.request({
|
return app.request({
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
url: app.forum.attribute('apiUrl') + '/settings',
|
url: app.forum.attribute('apiUrl') + '/settings',
|
||||||
data: settings
|
data: settings
|
||||||
}).catch(function (error) {
|
}).catch(function (error) {
|
||||||
app.settings = oldSettings;
|
app.data.settings = oldSettings;
|
||||||
throw error;
|
throw error;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -8,10 +8,10 @@ export default class AppearancePage extends Page {
|
|||||||
init() {
|
init() {
|
||||||
super.init();
|
super.init();
|
||||||
|
|
||||||
this.primaryColor = m.prop(app.settings.theme_primary_color);
|
this.primaryColor = m.prop(app.data.settings.theme_primary_color);
|
||||||
this.secondaryColor = m.prop(app.settings.theme_secondary_color);
|
this.secondaryColor = m.prop(app.data.settings.theme_secondary_color);
|
||||||
this.darkMode = m.prop(app.settings.theme_dark_mode === '1');
|
this.darkMode = m.prop(app.data.settings.theme_dark_mode === '1');
|
||||||
this.coloredHeader = m.prop(app.settings.theme_colored_header === '1');
|
this.coloredHeader = m.prop(app.data.settings.theme_colored_header === '1');
|
||||||
}
|
}
|
||||||
|
|
||||||
view() {
|
view() {
|
||||||
|
@ -22,11 +22,11 @@ export default class BasicsPage extends Page {
|
|||||||
];
|
];
|
||||||
this.values = {};
|
this.values = {};
|
||||||
|
|
||||||
const settings = app.settings;
|
const settings = app.data.settings;
|
||||||
this.fields.forEach(key => this.values[key] = m.prop(settings[key]));
|
this.fields.forEach(key => this.values[key] = m.prop(settings[key]));
|
||||||
|
|
||||||
this.localeOptions = {};
|
this.localeOptions = {};
|
||||||
const locales = app.locales;
|
const locales = app.data.locales;
|
||||||
for (const i in locales) {
|
for (const i in locales) {
|
||||||
this.localeOptions[i] = `${locales[i]} (${i})`;
|
this.localeOptions[i] = `${locales[i]} (${i})`;
|
||||||
}
|
}
|
||||||
@ -110,7 +110,7 @@ export default class BasicsPage extends Page {
|
|||||||
}
|
}
|
||||||
|
|
||||||
changed() {
|
changed() {
|
||||||
return this.fields.some(key => this.values[key]() !== app.settings[key]);
|
return this.fields.some(key => this.values[key]() !== app.data.settings[key]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -4,7 +4,7 @@ import saveSettings from 'flarum/utils/saveSettings';
|
|||||||
|
|
||||||
export default class EditCustomCssModal extends Modal {
|
export default class EditCustomCssModal extends Modal {
|
||||||
init() {
|
init() {
|
||||||
this.customLess = m.prop(app.settings.custom_less || '');
|
this.customLess = m.prop(app.data.settings.custom_less || '');
|
||||||
}
|
}
|
||||||
|
|
||||||
className() {
|
className() {
|
||||||
|
@ -27,9 +27,9 @@ export default class ExtensionsPage extends Page {
|
|||||||
<div className="ExtensionsPage-list">
|
<div className="ExtensionsPage-list">
|
||||||
<div className="container">
|
<div className="container">
|
||||||
<ul className="ExtensionList">
|
<ul className="ExtensionList">
|
||||||
{Object.keys(app.extensions)
|
{Object.keys(app.data.extensions)
|
||||||
.map(id => {
|
.map(id => {
|
||||||
const extension = app.extensions[id];
|
const extension = app.data.extensions[id];
|
||||||
const controls = this.controlItems(extension.id).toArray();
|
const controls = this.controlItems(extension.id).toArray();
|
||||||
|
|
||||||
return <li className={'ExtensionListItem ' + (!this.isEnabled(extension.id) ? 'disabled' : '')}>
|
return <li className={'ExtensionListItem ' + (!this.isEnabled(extension.id) ? 'disabled' : '')}>
|
||||||
@ -92,7 +92,7 @@ export default class ExtensionsPage extends Page {
|
|||||||
}
|
}
|
||||||
|
|
||||||
isEnabled(name) {
|
isEnabled(name) {
|
||||||
const enabled = JSON.parse(app.settings.extensions_enabled);
|
const enabled = JSON.parse(app.data.settings.extensions_enabled);
|
||||||
|
|
||||||
return enabled.indexOf(name) !== -1;
|
return enabled.indexOf(name) !== -1;
|
||||||
}
|
}
|
||||||
|
@ -21,7 +21,7 @@ export default class MailPage extends Page {
|
|||||||
];
|
];
|
||||||
this.values = {};
|
this.values = {};
|
||||||
|
|
||||||
const settings = app.settings;
|
const settings = app.data.settings;
|
||||||
this.fields.forEach(key => this.values[key] = m.prop(settings[key]));
|
this.fields.forEach(key => this.values[key] = m.prop(settings[key]));
|
||||||
|
|
||||||
this.localeOptions = {};
|
this.localeOptions = {};
|
||||||
@ -96,7 +96,7 @@ export default class MailPage extends Page {
|
|||||||
}
|
}
|
||||||
|
|
||||||
changed() {
|
changed() {
|
||||||
return this.fields.some(key => this.values[key]() !== app.settings[key]);
|
return this.fields.some(key => this.values[key]() !== app.data.settings[key]);
|
||||||
}
|
}
|
||||||
|
|
||||||
onsubmit(e) {
|
onsubmit(e) {
|
||||||
|
@ -21,7 +21,7 @@ export default class PermissionDropdown extends Dropdown {
|
|||||||
view() {
|
view() {
|
||||||
this.props.children = [];
|
this.props.children = [];
|
||||||
|
|
||||||
const groupIds = app.permissions[this.props.permission] || [];
|
const groupIds = app.data.permissions[this.props.permission] || [];
|
||||||
const everyone = groupIds.indexOf(Group.GUEST_ID) !== -1;
|
const everyone = groupIds.indexOf(Group.GUEST_ID) !== -1;
|
||||||
const members = groupIds.indexOf(Group.MEMBER_ID) !== -1;
|
const members = groupIds.indexOf(Group.MEMBER_ID) !== -1;
|
||||||
const adminGroup = app.store.getById('groups', Group.ADMINISTRATOR_ID);
|
const adminGroup = app.store.getById('groups', Group.ADMINISTRATOR_ID);
|
||||||
@ -87,7 +87,7 @@ export default class PermissionDropdown extends Dropdown {
|
|||||||
save(groupIds) {
|
save(groupIds) {
|
||||||
const permission = this.props.permission;
|
const permission = this.props.permission;
|
||||||
|
|
||||||
app.permissions[permission] = groupIds;
|
app.data.permissions[permission] = groupIds;
|
||||||
|
|
||||||
app.request({
|
app.request({
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
@ -99,7 +99,7 @@ export default class PermissionDropdown extends Dropdown {
|
|||||||
toggle(groupId) {
|
toggle(groupId) {
|
||||||
const permission = this.props.permission;
|
const permission = this.props.permission;
|
||||||
|
|
||||||
let groupIds = app.permissions[permission] || [];
|
let groupIds = app.data.permissions[permission] || [];
|
||||||
|
|
||||||
const index = groupIds.indexOf(groupId);
|
const index = groupIds.indexOf(groupId);
|
||||||
|
|
||||||
|
@ -119,7 +119,7 @@ export default class PermissionGrid extends Component {
|
|||||||
icon: 'i-cursor',
|
icon: 'i-cursor',
|
||||||
label: app.translator.trans('core.admin.permissions.allow_renaming_label'),
|
label: app.translator.trans('core.admin.permissions.allow_renaming_label'),
|
||||||
setting: () => {
|
setting: () => {
|
||||||
const minutes = parseInt(app.settings.allow_renaming, 10);
|
const minutes = parseInt(app.data.settings.allow_renaming, 10);
|
||||||
|
|
||||||
return SettingDropdown.component({
|
return SettingDropdown.component({
|
||||||
defaultLabel: minutes
|
defaultLabel: minutes
|
||||||
@ -151,7 +151,7 @@ export default class PermissionGrid extends Component {
|
|||||||
icon: 'pencil',
|
icon: 'pencil',
|
||||||
label: app.translator.trans('core.admin.permissions.allow_post_editing_label'),
|
label: app.translator.trans('core.admin.permissions.allow_post_editing_label'),
|
||||||
setting: () => {
|
setting: () => {
|
||||||
const minutes = parseInt(app.settings.allow_post_editing, 10);
|
const minutes = parseInt(app.data.settings.allow_post_editing, 10);
|
||||||
|
|
||||||
return SettingDropdown.component({
|
return SettingDropdown.component({
|
||||||
defaultLabel: minutes
|
defaultLabel: minutes
|
||||||
|
@ -12,7 +12,7 @@ export default class SettingDropdown extends SelectDropdown {
|
|||||||
props.defaultLabel = 'Custom';
|
props.defaultLabel = 'Custom';
|
||||||
|
|
||||||
props.children = props.options.map(({value, label}) => {
|
props.children = props.options.map(({value, label}) => {
|
||||||
const active = app.settings[props.key] === value;
|
const active = app.data.settings[props.key] === value;
|
||||||
|
|
||||||
return Button.component({
|
return Button.component({
|
||||||
children: label,
|
children: label,
|
||||||
|
@ -39,7 +39,7 @@ export default class SettingsModal extends Modal {
|
|||||||
}
|
}
|
||||||
|
|
||||||
setting(key, fallback = '') {
|
setting(key, fallback = '') {
|
||||||
this.settings[key] = this.settings[key] || m.prop(app.settings[key] || fallback);
|
this.settings[key] = this.settings[key] || m.prop(app.data.settings[key] || fallback);
|
||||||
|
|
||||||
return this.settings[key];
|
return this.settings[key];
|
||||||
}
|
}
|
||||||
@ -50,7 +50,7 @@ export default class SettingsModal extends Modal {
|
|||||||
Object.keys(this.settings).forEach(key => {
|
Object.keys(this.settings).forEach(key => {
|
||||||
const value = this.settings[key]();
|
const value = this.settings[key]();
|
||||||
|
|
||||||
if (value !== app.settings[key]) {
|
if (value !== app.data.settings[key]) {
|
||||||
dirty[key] = value;
|
dirty[key] = value;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -1,14 +1,14 @@
|
|||||||
export default function saveSettings(settings) {
|
export default function saveSettings(settings) {
|
||||||
const oldSettings = JSON.parse(JSON.stringify(app.settings));
|
const oldSettings = JSON.parse(JSON.stringify(app.data.settings));
|
||||||
|
|
||||||
Object.assign(app.settings, settings);
|
Object.assign(app.data.settings, settings);
|
||||||
|
|
||||||
return app.request({
|
return app.request({
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
url: app.forum.attribute('apiUrl') + '/settings',
|
url: app.forum.attribute('apiUrl') + '/settings',
|
||||||
data: settings
|
data: settings
|
||||||
}).catch(error => {
|
}).catch(error => {
|
||||||
app.settings = oldSettings;
|
app.data.settings = oldSettings;
|
||||||
throw error;
|
throw error;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
26
framework/core/js/forum/dist/app.js
vendored
26
framework/core/js/forum/dist/app.js
vendored
@ -18418,10 +18418,12 @@ System.register('flarum/App', ['flarum/utils/ItemList', 'flarum/components/Alert
|
|||||||
|
|
||||||
babelHelpers.createClass(App, [{
|
babelHelpers.createClass(App, [{
|
||||||
key: 'boot',
|
key: 'boot',
|
||||||
value: function boot() {
|
value: function boot(data) {
|
||||||
var _this = this;
|
var _this = this;
|
||||||
|
|
||||||
this.translator.locale = this.locale;
|
this.data = data;
|
||||||
|
|
||||||
|
this.translator.locale = data.locale;
|
||||||
|
|
||||||
this.initializers.toArray().forEach(function (initializer) {
|
this.initializers.toArray().forEach(function (initializer) {
|
||||||
return initializer(_this);
|
return initializer(_this);
|
||||||
@ -18430,9 +18432,9 @@ System.register('flarum/App', ['flarum/utils/ItemList', 'flarum/components/Alert
|
|||||||
}, {
|
}, {
|
||||||
key: 'preloadedDocument',
|
key: 'preloadedDocument',
|
||||||
value: function preloadedDocument() {
|
value: function preloadedDocument() {
|
||||||
if (app.preload.document) {
|
if (this.data.document) {
|
||||||
var results = app.store.pushPayload(app.preload.document);
|
var results = this.store.pushPayload(this.data.document);
|
||||||
app.preload.document = null;
|
this.data.document = null;
|
||||||
|
|
||||||
return results;
|
return results;
|
||||||
}
|
}
|
||||||
@ -22305,14 +22307,14 @@ System.register('flarum/components/HeaderSecondary', ['flarum/Component', 'flaru
|
|||||||
|
|
||||||
items.add('search', app.search.render(), 30);
|
items.add('search', app.search.render(), 30);
|
||||||
|
|
||||||
if (Object.keys(app.locales).length > 1) {
|
if (Object.keys(app.data.locales).length > 1) {
|
||||||
var locales = [];
|
var locales = [];
|
||||||
|
|
||||||
var _loop = function _loop(locale) {
|
var _loop = function _loop(locale) {
|
||||||
locales.push(Button.component({
|
locales.push(Button.component({
|
||||||
active: app.locale === locale,
|
active: app.data.locale === locale,
|
||||||
children: app.locales[locale],
|
children: app.data.locales[locale],
|
||||||
icon: app.locale === locale ? 'check' : true,
|
icon: app.data.locale === locale ? 'check' : true,
|
||||||
onclick: function onclick() {
|
onclick: function onclick() {
|
||||||
if (app.session.user) {
|
if (app.session.user) {
|
||||||
app.session.user.savePreferences({ locale: locale }).then(function () {
|
app.session.user.savePreferences({ locale: locale }).then(function () {
|
||||||
@ -22326,7 +22328,7 @@ System.register('flarum/components/HeaderSecondary', ['flarum/Component', 'flaru
|
|||||||
}));
|
}));
|
||||||
};
|
};
|
||||||
|
|
||||||
for (var locale in app.locales) {
|
for (var locale in app.data.locales) {
|
||||||
_loop(locale);
|
_loop(locale);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -28664,11 +28666,11 @@ System.register('flarum/initializers/humanTime', ['flarum/utils/humanTime'], fun
|
|||||||
System.register('flarum/initializers/preload', ['flarum/Session'], function (_export, _context) {
|
System.register('flarum/initializers/preload', ['flarum/Session'], function (_export, _context) {
|
||||||
var Session;
|
var Session;
|
||||||
function preload(app) {
|
function preload(app) {
|
||||||
app.store.pushPayload({ data: app.preload.data });
|
app.store.pushPayload({ data: app.data.resources });
|
||||||
|
|
||||||
app.forum = app.store.getById('forums', 1);
|
app.forum = app.store.getById('forums', 1);
|
||||||
|
|
||||||
app.session = new Session(app.store.getById('users', app.preload.session.userId), app.preload.session.csrfToken);
|
app.session = new Session(app.store.getById('users', app.data.session.userId), app.data.session.csrfToken);
|
||||||
}
|
}
|
||||||
|
|
||||||
_export('default', preload);
|
_export('default', preload);
|
||||||
|
@ -39,14 +39,14 @@ export default class HeaderSecondary extends Component {
|
|||||||
|
|
||||||
items.add('search', app.search.render(), 30);
|
items.add('search', app.search.render(), 30);
|
||||||
|
|
||||||
if (Object.keys(app.locales).length > 1) {
|
if (Object.keys(app.data.locales).length > 1) {
|
||||||
const locales = [];
|
const locales = [];
|
||||||
|
|
||||||
for (const locale in app.locales) {
|
for (const locale in app.data.locales) {
|
||||||
locales.push(Button.component({
|
locales.push(Button.component({
|
||||||
active: app.locale === locale,
|
active: app.data.locale === locale,
|
||||||
children: app.locales[locale],
|
children: app.data.locales[locale],
|
||||||
icon: app.locale === locale ? 'check' : true,
|
icon: app.data.locale === locale ? 'check' : true,
|
||||||
onclick: () => {
|
onclick: () => {
|
||||||
if (app.session.user) {
|
if (app.session.user) {
|
||||||
app.session.user.savePreferences({locale}).then(() => window.location.reload());
|
app.session.user.savePreferences({locale}).then(() => window.location.reload());
|
||||||
|
@ -40,24 +40,6 @@ export default class App {
|
|||||||
*/
|
*/
|
||||||
this.routes = {};
|
this.routes = {};
|
||||||
|
|
||||||
/**
|
|
||||||
* An object containing data to preload into the application.
|
|
||||||
*
|
|
||||||
* @type {Object}
|
|
||||||
* @property {Object} preload.data An array of resource objects to preload
|
|
||||||
* into the data store.
|
|
||||||
* @property {Object} preload.document An API response document to be used
|
|
||||||
* by the route that is first activated.
|
|
||||||
* @property {Object} preload.session A response from the /api/token
|
|
||||||
* endpoint containing the session's authentication token and user ID.
|
|
||||||
* @public
|
|
||||||
*/
|
|
||||||
this.preload = {
|
|
||||||
data: null,
|
|
||||||
document: null,
|
|
||||||
session: null
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An ordered list of initializers to bootstrap the application.
|
* An ordered list of initializers to bootstrap the application.
|
||||||
*
|
*
|
||||||
@ -125,8 +107,10 @@ export default class App {
|
|||||||
*
|
*
|
||||||
* @public
|
* @public
|
||||||
*/
|
*/
|
||||||
boot() {
|
boot(data) {
|
||||||
this.translator.locale = this.locale;
|
this.data = data;
|
||||||
|
|
||||||
|
this.translator.locale = data.locale;
|
||||||
|
|
||||||
this.initializers.toArray().forEach(initializer => initializer(this));
|
this.initializers.toArray().forEach(initializer => initializer(this));
|
||||||
}
|
}
|
||||||
@ -138,9 +122,9 @@ export default class App {
|
|||||||
* @public
|
* @public
|
||||||
*/
|
*/
|
||||||
preloadedDocument() {
|
preloadedDocument() {
|
||||||
if (app.preload.document) {
|
if (this.data.document) {
|
||||||
const results = app.store.pushPayload(app.preload.document);
|
const results = this.store.pushPayload(this.data.document);
|
||||||
app.preload.document = null;
|
this.data.document = null;
|
||||||
|
|
||||||
return results;
|
return results;
|
||||||
}
|
}
|
||||||
|
@ -13,12 +13,12 @@ import Session from 'flarum/Session';
|
|||||||
* @param {App} app
|
* @param {App} app
|
||||||
*/
|
*/
|
||||||
export default function preload(app) {
|
export default function preload(app) {
|
||||||
app.store.pushPayload({data: app.preload.data});
|
app.store.pushPayload({data: app.data.resources});
|
||||||
|
|
||||||
app.forum = app.store.getById('forums', 1);
|
app.forum = app.store.getById('forums', 1);
|
||||||
|
|
||||||
app.session = new Session(
|
app.session = new Session(
|
||||||
app.store.getById('users', app.preload.session.userId),
|
app.store.getById('users', app.data.session.userId),
|
||||||
app.preload.session.csrfToken
|
app.data.session.csrfToken
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -14,13 +14,11 @@ use Flarum\Event\ExtensionWasDisabled;
|
|||||||
use Flarum\Event\ExtensionWasEnabled;
|
use Flarum\Event\ExtensionWasEnabled;
|
||||||
use Flarum\Event\SettingWasSet;
|
use Flarum\Event\SettingWasSet;
|
||||||
use Flarum\Foundation\AbstractServiceProvider;
|
use Flarum\Foundation\AbstractServiceProvider;
|
||||||
use Flarum\Http\GenerateRouteHandlerTrait;
|
use Flarum\Http\Handler\RouteHandlerFactory;
|
||||||
use Flarum\Http\RouteCollection;
|
use Flarum\Http\RouteCollection;
|
||||||
|
|
||||||
class AdminServiceProvider extends AbstractServiceProvider
|
class AdminServiceProvider extends AbstractServiceProvider
|
||||||
{
|
{
|
||||||
use GenerateRouteHandlerTrait;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@inheritdoc}
|
* {@inheritdoc}
|
||||||
*/
|
*/
|
||||||
@ -44,9 +42,9 @@ class AdminServiceProvider extends AbstractServiceProvider
|
|||||||
|
|
||||||
$this->loadViewsFrom(__DIR__.'/../../views', 'flarum.admin');
|
$this->loadViewsFrom(__DIR__.'/../../views', 'flarum.admin');
|
||||||
|
|
||||||
$this->flushAssetsWhenThemeChanged();
|
$this->flushWebAppAssetsWhenThemeChanged();
|
||||||
|
|
||||||
$this->flushAssetsWhenExtensionsChanged();
|
$this->flushWebAppAssetsWhenExtensionsChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -56,42 +54,42 @@ class AdminServiceProvider extends AbstractServiceProvider
|
|||||||
*/
|
*/
|
||||||
protected function populateRoutes(RouteCollection $routes)
|
protected function populateRoutes(RouteCollection $routes)
|
||||||
{
|
{
|
||||||
$toController = $this->getHandlerGenerator($this->app);
|
$route = $this->app->make(RouteHandlerFactory::class);
|
||||||
|
|
||||||
$routes->get(
|
$routes->get(
|
||||||
'/',
|
'/',
|
||||||
'index',
|
'index',
|
||||||
$toController('Flarum\Admin\Controller\ClientController')
|
$route->toController(Controller\WebAppController::class)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function flushAssetsWhenThemeChanged()
|
protected function flushWebAppAssetsWhenThemeChanged()
|
||||||
{
|
{
|
||||||
$this->app->make('events')->listen(SettingWasSet::class, function (SettingWasSet $event) {
|
$this->app->make('events')->listen(SettingWasSet::class, function (SettingWasSet $event) {
|
||||||
if (preg_match('/^theme_|^custom_less$/i', $event->key)) {
|
if (preg_match('/^theme_|^custom_less$/i', $event->key)) {
|
||||||
$this->getClientController()->flushCss();
|
$this->getWebAppAssets()->flushCss();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function flushAssetsWhenExtensionsChanged()
|
protected function flushWebAppAssetsWhenExtensionsChanged()
|
||||||
{
|
{
|
||||||
$events = $this->app->make('events');
|
$events = $this->app->make('events');
|
||||||
|
|
||||||
$events->listen(ExtensionWasEnabled::class, [$this, 'flushAssets']);
|
$events->listen(ExtensionWasEnabled::class, [$this, 'flushWebAppAssets']);
|
||||||
$events->listen(ExtensionWasDisabled::class, [$this, 'flushAssets']);
|
$events->listen(ExtensionWasDisabled::class, [$this, 'flushWebAppAssets']);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function flushAssets()
|
public function flushWebAppAssets()
|
||||||
{
|
{
|
||||||
$this->getClientController()->flushAssets();
|
$this->getWebAppAssets()->flush();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return \Flarum\Admin\Controller\ClientController
|
* @return \Flarum\Http\WebApp\WebAppAssets
|
||||||
*/
|
*/
|
||||||
protected function getClientController()
|
protected function getWebAppAssets()
|
||||||
{
|
{
|
||||||
return $this->app->make('Flarum\Admin\Controller\ClientController');
|
return $this->app->make(WebApp::class)->getAssets();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -10,29 +10,23 @@
|
|||||||
|
|
||||||
namespace Flarum\Admin\Controller;
|
namespace Flarum\Admin\Controller;
|
||||||
|
|
||||||
use Flarum\Api\Client;
|
use Flarum\Admin\WebApp;
|
||||||
use Flarum\Core\Permission;
|
use Flarum\Core\Permission;
|
||||||
use Flarum\Event\PrepareUnserializedSettings;
|
use Flarum\Event\PrepareUnserializedSettings;
|
||||||
use Flarum\Extension\ExtensionManager;
|
use Flarum\Extension\ExtensionManager;
|
||||||
use Flarum\Foundation\Application;
|
use Flarum\Foundation\Application;
|
||||||
use Flarum\Http\Controller\AbstractClientController as BaseClientController;
|
use Flarum\Http\Controller\AbstractWebAppController;
|
||||||
use Flarum\Locale\LocaleManager;
|
use Flarum\Locale\LocaleManager;
|
||||||
use Flarum\Settings\SettingsRepositoryInterface;
|
use Flarum\Settings\SettingsRepositoryInterface;
|
||||||
use Illuminate\Contracts\Cache\Repository;
|
|
||||||
use Illuminate\Contracts\Events\Dispatcher;
|
use Illuminate\Contracts\Events\Dispatcher;
|
||||||
use Psr\Http\Message\ServerRequestInterface as Request;
|
use Psr\Http\Message\ServerRequestInterface;
|
||||||
|
|
||||||
class ClientController extends BaseClientController
|
class WebAppController extends AbstractWebAppController
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* {@inheritdoc}
|
* @var SettingsRepositoryInterface
|
||||||
*/
|
*/
|
||||||
protected $clientName = 'admin';
|
protected $settings;
|
||||||
|
|
||||||
/**
|
|
||||||
* {@inheritdoc}
|
|
||||||
*/
|
|
||||||
protected $translations = '/^[^\.]+\.(?:admin|lib)\./';
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var ExtensionManager
|
* @var ExtensionManager
|
||||||
@ -40,29 +34,25 @@ class ClientController extends BaseClientController
|
|||||||
protected $extensions;
|
protected $extensions;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@inheritdoc}
|
* @param WebApp $webApp
|
||||||
|
* @param Dispatcher $events
|
||||||
|
* @param SettingsRepositoryInterface $settings
|
||||||
|
* @param ExtensionManager $extensions
|
||||||
*/
|
*/
|
||||||
public function __construct(
|
public function __construct(WebApp $webApp, Dispatcher $events, SettingsRepositoryInterface $settings, ExtensionManager $extensions)
|
||||||
Application $app,
|
{
|
||||||
Client $apiClient,
|
$this->webApp = $webApp;
|
||||||
LocaleManager $locales,
|
$this->events = $events;
|
||||||
SettingsRepositoryInterface $settings,
|
$this->settings = $settings;
|
||||||
Dispatcher $events,
|
|
||||||
Repository $cache,
|
|
||||||
ExtensionManager $extensions
|
|
||||||
) {
|
|
||||||
BaseClientController::__construct($app, $apiClient, $locales, $settings, $events, $cache);
|
|
||||||
|
|
||||||
$this->layout = __DIR__.'/../../../views/admin.blade.php';
|
|
||||||
$this->extensions = $extensions;
|
$this->extensions = $extensions;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@inheritdoc}
|
* {@inheritdoc}
|
||||||
*/
|
*/
|
||||||
public function render(Request $request)
|
protected function getView(ServerRequestInterface $request)
|
||||||
{
|
{
|
||||||
$view = BaseClientController::render($request);
|
$view = parent::getView($request);
|
||||||
|
|
||||||
$settings = $this->settings->all();
|
$settings = $this->settings->all();
|
||||||
|
|
24
framework/core/src/Admin/WebApp.php
Normal file
24
framework/core/src/Admin/WebApp.php
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
<?php
|
||||||
|
/*
|
||||||
|
* This file is part of Flarum.
|
||||||
|
*
|
||||||
|
* (c) Toby Zerner <toby.zerner@gmail.com>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Flarum\Admin;
|
||||||
|
|
||||||
|
use Flarum\Http\WebApp\AbstractWebApp;
|
||||||
|
|
||||||
|
class WebApp extends AbstractWebApp
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
protected function getName()
|
||||||
|
{
|
||||||
|
return 'admin';
|
||||||
|
}
|
||||||
|
}
|
@ -16,7 +16,7 @@ use Flarum\Api\Serializer\NotificationSerializer;
|
|||||||
use Flarum\Event\ConfigureApiRoutes;
|
use Flarum\Event\ConfigureApiRoutes;
|
||||||
use Flarum\Event\ConfigureNotificationTypes;
|
use Flarum\Event\ConfigureNotificationTypes;
|
||||||
use Flarum\Foundation\AbstractServiceProvider;
|
use Flarum\Foundation\AbstractServiceProvider;
|
||||||
use Flarum\Http\GenerateRouteHandlerTrait;
|
use Flarum\Http\Handler\RouteHandlerFactory;
|
||||||
use Flarum\Http\RouteCollection;
|
use Flarum\Http\RouteCollection;
|
||||||
use Tobscure\JsonApi\ErrorHandler;
|
use Tobscure\JsonApi\ErrorHandler;
|
||||||
use Tobscure\JsonApi\Exception\Handler\FallbackExceptionHandler;
|
use Tobscure\JsonApi\Exception\Handler\FallbackExceptionHandler;
|
||||||
@ -24,8 +24,6 @@ use Tobscure\JsonApi\Exception\Handler\InvalidParameterExceptionHandler;
|
|||||||
|
|
||||||
class ApiServiceProvider extends AbstractServiceProvider
|
class ApiServiceProvider extends AbstractServiceProvider
|
||||||
{
|
{
|
||||||
use GenerateRouteHandlerTrait;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@inheritdoc}
|
* {@inheritdoc}
|
||||||
*/
|
*/
|
||||||
@ -101,27 +99,27 @@ class ApiServiceProvider extends AbstractServiceProvider
|
|||||||
*/
|
*/
|
||||||
protected function populateRoutes(RouteCollection $routes)
|
protected function populateRoutes(RouteCollection $routes)
|
||||||
{
|
{
|
||||||
$toController = $this->getHandlerGenerator($this->app);
|
$route = $this->app->make(RouteHandlerFactory::class);
|
||||||
|
|
||||||
// Get forum information
|
// Get forum information
|
||||||
$routes->get(
|
$routes->get(
|
||||||
'/forum',
|
'/forum',
|
||||||
'forum.show',
|
'forum.show',
|
||||||
$toController('Flarum\Api\Controller\ShowForumController')
|
$route->toController(Controller\ShowForumController::class)
|
||||||
);
|
);
|
||||||
|
|
||||||
// Retrieve authentication token
|
// Retrieve authentication token
|
||||||
$routes->post(
|
$routes->post(
|
||||||
'/token',
|
'/token',
|
||||||
'token',
|
'token',
|
||||||
$toController('Flarum\Api\Controller\TokenController')
|
$route->toController(Controller\TokenController::class)
|
||||||
);
|
);
|
||||||
|
|
||||||
// Send forgot password email
|
// Send forgot password email
|
||||||
$routes->post(
|
$routes->post(
|
||||||
'/forgot',
|
'/forgot',
|
||||||
'forgot',
|
'forgot',
|
||||||
$toController('Flarum\Api\Controller\ForgotPasswordController')
|
$route->toController(Controller\ForgotPasswordController::class)
|
||||||
);
|
);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -134,56 +132,56 @@ class ApiServiceProvider extends AbstractServiceProvider
|
|||||||
$routes->get(
|
$routes->get(
|
||||||
'/users',
|
'/users',
|
||||||
'users.index',
|
'users.index',
|
||||||
$toController('Flarum\Api\Controller\ListUsersController')
|
$route->toController(Controller\ListUsersController::class)
|
||||||
);
|
);
|
||||||
|
|
||||||
// Register a user
|
// Register a user
|
||||||
$routes->post(
|
$routes->post(
|
||||||
'/users',
|
'/users',
|
||||||
'users.create',
|
'users.create',
|
||||||
$toController('Flarum\Api\Controller\CreateUserController')
|
$route->toController(Controller\CreateUserController::class)
|
||||||
);
|
);
|
||||||
|
|
||||||
// Get a single user
|
// Get a single user
|
||||||
$routes->get(
|
$routes->get(
|
||||||
'/users/{id}',
|
'/users/{id}',
|
||||||
'users.show',
|
'users.show',
|
||||||
$toController('Flarum\Api\Controller\ShowUserController')
|
$route->toController(Controller\ShowUserController::class)
|
||||||
);
|
);
|
||||||
|
|
||||||
// Edit a user
|
// Edit a user
|
||||||
$routes->patch(
|
$routes->patch(
|
||||||
'/users/{id}',
|
'/users/{id}',
|
||||||
'users.update',
|
'users.update',
|
||||||
$toController('Flarum\Api\Controller\UpdateUserController')
|
$route->toController(Controller\UpdateUserController::class)
|
||||||
);
|
);
|
||||||
|
|
||||||
// Delete a user
|
// Delete a user
|
||||||
$routes->delete(
|
$routes->delete(
|
||||||
'/users/{id}',
|
'/users/{id}',
|
||||||
'users.delete',
|
'users.delete',
|
||||||
$toController('Flarum\Api\Controller\DeleteUserController')
|
$route->toController(Controller\DeleteUserController::class)
|
||||||
);
|
);
|
||||||
|
|
||||||
// Upload avatar
|
// Upload avatar
|
||||||
$routes->post(
|
$routes->post(
|
||||||
'/users/{id}/avatar',
|
'/users/{id}/avatar',
|
||||||
'users.avatar.upload',
|
'users.avatar.upload',
|
||||||
$toController('Flarum\Api\Controller\UploadAvatarController')
|
$route->toController(Controller\UploadAvatarController::class)
|
||||||
);
|
);
|
||||||
|
|
||||||
// Remove avatar
|
// Remove avatar
|
||||||
$routes->delete(
|
$routes->delete(
|
||||||
'/users/{id}/avatar',
|
'/users/{id}/avatar',
|
||||||
'users.avatar.delete',
|
'users.avatar.delete',
|
||||||
$toController('Flarum\Api\Controller\DeleteAvatarController')
|
$route->toController(Controller\DeleteAvatarController::class)
|
||||||
);
|
);
|
||||||
|
|
||||||
// send confirmation email
|
// send confirmation email
|
||||||
$routes->post(
|
$routes->post(
|
||||||
'/users/{id}/send-confirmation',
|
'/users/{id}/send-confirmation',
|
||||||
'users.confirmation.send',
|
'users.confirmation.send',
|
||||||
$toController('Flarum\Api\Controller\SendConfirmationEmailController')
|
$route->toController(Controller\SendConfirmationEmailController::class)
|
||||||
);
|
);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -196,21 +194,21 @@ class ApiServiceProvider extends AbstractServiceProvider
|
|||||||
$routes->get(
|
$routes->get(
|
||||||
'/notifications',
|
'/notifications',
|
||||||
'notifications.index',
|
'notifications.index',
|
||||||
$toController('Flarum\Api\Controller\ListNotificationsController')
|
$route->toController(Controller\ListNotificationsController::class)
|
||||||
);
|
);
|
||||||
|
|
||||||
// Mark all notifications as read
|
// Mark all notifications as read
|
||||||
$routes->post(
|
$routes->post(
|
||||||
'/notifications/read',
|
'/notifications/read',
|
||||||
'notifications.readAll',
|
'notifications.readAll',
|
||||||
$toController('Flarum\Api\Controller\ReadAllNotificationsController')
|
$route->toController(Controller\ReadAllNotificationsController::class)
|
||||||
);
|
);
|
||||||
|
|
||||||
// Mark a single notification as read
|
// Mark a single notification as read
|
||||||
$routes->patch(
|
$routes->patch(
|
||||||
'/notifications/{id}',
|
'/notifications/{id}',
|
||||||
'notifications.update',
|
'notifications.update',
|
||||||
$toController('Flarum\Api\Controller\UpdateNotificationController')
|
$route->toController(Controller\UpdateNotificationController::class)
|
||||||
);
|
);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -223,35 +221,35 @@ class ApiServiceProvider extends AbstractServiceProvider
|
|||||||
$routes->get(
|
$routes->get(
|
||||||
'/discussions',
|
'/discussions',
|
||||||
'discussions.index',
|
'discussions.index',
|
||||||
$toController('Flarum\Api\Controller\ListDiscussionsController')
|
$route->toController(Controller\ListDiscussionsController::class)
|
||||||
);
|
);
|
||||||
|
|
||||||
// Create a discussion
|
// Create a discussion
|
||||||
$routes->post(
|
$routes->post(
|
||||||
'/discussions',
|
'/discussions',
|
||||||
'discussions.create',
|
'discussions.create',
|
||||||
$toController('Flarum\Api\Controller\CreateDiscussionController')
|
$route->toController(Controller\CreateDiscussionController::class)
|
||||||
);
|
);
|
||||||
|
|
||||||
// Show a single discussion
|
// Show a single discussion
|
||||||
$routes->get(
|
$routes->get(
|
||||||
'/discussions/{id}',
|
'/discussions/{id}',
|
||||||
'discussions.show',
|
'discussions.show',
|
||||||
$toController('Flarum\Api\Controller\ShowDiscussionController')
|
$route->toController(Controller\ShowDiscussionController::class)
|
||||||
);
|
);
|
||||||
|
|
||||||
// Edit a discussion
|
// Edit a discussion
|
||||||
$routes->patch(
|
$routes->patch(
|
||||||
'/discussions/{id}',
|
'/discussions/{id}',
|
||||||
'discussions.update',
|
'discussions.update',
|
||||||
$toController('Flarum\Api\Controller\UpdateDiscussionController')
|
$route->toController(Controller\UpdateDiscussionController::class)
|
||||||
);
|
);
|
||||||
|
|
||||||
// Delete a discussion
|
// Delete a discussion
|
||||||
$routes->delete(
|
$routes->delete(
|
||||||
'/discussions/{id}',
|
'/discussions/{id}',
|
||||||
'discussions.delete',
|
'discussions.delete',
|
||||||
$toController('Flarum\Api\Controller\DeleteDiscussionController')
|
$route->toController(Controller\DeleteDiscussionController::class)
|
||||||
);
|
);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -264,35 +262,35 @@ class ApiServiceProvider extends AbstractServiceProvider
|
|||||||
$routes->get(
|
$routes->get(
|
||||||
'/posts',
|
'/posts',
|
||||||
'posts.index',
|
'posts.index',
|
||||||
$toController('Flarum\Api\Controller\ListPostsController')
|
$route->toController(Controller\ListPostsController::class)
|
||||||
);
|
);
|
||||||
|
|
||||||
// Create a post
|
// Create a post
|
||||||
$routes->post(
|
$routes->post(
|
||||||
'/posts',
|
'/posts',
|
||||||
'posts.create',
|
'posts.create',
|
||||||
$toController('Flarum\Api\Controller\CreatePostController')
|
$route->toController(Controller\CreatePostController::class)
|
||||||
);
|
);
|
||||||
|
|
||||||
// Show a single or multiple posts by ID
|
// Show a single or multiple posts by ID
|
||||||
$routes->get(
|
$routes->get(
|
||||||
'/posts/{id}',
|
'/posts/{id}',
|
||||||
'posts.show',
|
'posts.show',
|
||||||
$toController('Flarum\Api\Controller\ShowPostController')
|
$route->toController(Controller\ShowPostController::class)
|
||||||
);
|
);
|
||||||
|
|
||||||
// Edit a post
|
// Edit a post
|
||||||
$routes->patch(
|
$routes->patch(
|
||||||
'/posts/{id}',
|
'/posts/{id}',
|
||||||
'posts.update',
|
'posts.update',
|
||||||
$toController('Flarum\Api\Controller\UpdatePostController')
|
$route->toController(Controller\UpdatePostController::class)
|
||||||
);
|
);
|
||||||
|
|
||||||
// Delete a post
|
// Delete a post
|
||||||
$routes->delete(
|
$routes->delete(
|
||||||
'/posts/{id}',
|
'/posts/{id}',
|
||||||
'posts.delete',
|
'posts.delete',
|
||||||
$toController('Flarum\Api\Controller\DeletePostController')
|
$route->toController(Controller\DeletePostController::class)
|
||||||
);
|
);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -305,28 +303,28 @@ class ApiServiceProvider extends AbstractServiceProvider
|
|||||||
$routes->get(
|
$routes->get(
|
||||||
'/groups',
|
'/groups',
|
||||||
'groups.index',
|
'groups.index',
|
||||||
$toController('Flarum\Api\Controller\ListGroupsController')
|
$route->toController(Controller\ListGroupsController::class)
|
||||||
);
|
);
|
||||||
|
|
||||||
// Create a group
|
// Create a group
|
||||||
$routes->post(
|
$routes->post(
|
||||||
'/groups',
|
'/groups',
|
||||||
'groups.create',
|
'groups.create',
|
||||||
$toController('Flarum\Api\Controller\CreateGroupController')
|
$route->toController(Controller\CreateGroupController::class)
|
||||||
);
|
);
|
||||||
|
|
||||||
// Edit a group
|
// Edit a group
|
||||||
$routes->patch(
|
$routes->patch(
|
||||||
'/groups/{id}',
|
'/groups/{id}',
|
||||||
'groups.update',
|
'groups.update',
|
||||||
$toController('Flarum\Api\Controller\UpdateGroupController')
|
$route->toController(Controller\UpdateGroupController::class)
|
||||||
);
|
);
|
||||||
|
|
||||||
// Delete a group
|
// Delete a group
|
||||||
$routes->delete(
|
$routes->delete(
|
||||||
'/groups/{id}',
|
'/groups/{id}',
|
||||||
'groups.delete',
|
'groups.delete',
|
||||||
$toController('Flarum\Api\Controller\DeleteGroupController')
|
$route->toController(Controller\DeleteGroupController::class)
|
||||||
);
|
);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -339,32 +337,32 @@ class ApiServiceProvider extends AbstractServiceProvider
|
|||||||
$routes->patch(
|
$routes->patch(
|
||||||
'/extensions/{name}',
|
'/extensions/{name}',
|
||||||
'extensions.update',
|
'extensions.update',
|
||||||
$toController('Flarum\Api\Controller\UpdateExtensionController')
|
$route->toController(Controller\UpdateExtensionController::class)
|
||||||
);
|
);
|
||||||
|
|
||||||
// Uninstall an extension
|
// Uninstall an extension
|
||||||
$routes->delete(
|
$routes->delete(
|
||||||
'/extensions/{name}',
|
'/extensions/{name}',
|
||||||
'extensions.delete',
|
'extensions.delete',
|
||||||
$toController('Flarum\Api\Controller\UninstallExtensionController')
|
$route->toController(Controller\UninstallExtensionController::class)
|
||||||
);
|
);
|
||||||
|
|
||||||
// Update settings
|
// Update settings
|
||||||
$routes->post(
|
$routes->post(
|
||||||
'/settings',
|
'/settings',
|
||||||
'settings',
|
'settings',
|
||||||
$toController('Flarum\Api\Controller\SetSettingsController')
|
$route->toController(Controller\SetSettingsController::class)
|
||||||
);
|
);
|
||||||
|
|
||||||
// Update a permission
|
// Update a permission
|
||||||
$routes->post(
|
$routes->post(
|
||||||
'/permission',
|
'/permission',
|
||||||
'permission',
|
'permission',
|
||||||
$toController('Flarum\Api\Controller\SetPermissionController')
|
$route->toController(Controller\SetPermissionController::class)
|
||||||
);
|
);
|
||||||
|
|
||||||
$this->app->make('events')->fire(
|
$this->app->make('events')->fire(
|
||||||
new ConfigureApiRoutes($routes, $toController)
|
new ConfigureApiRoutes($routes, $route)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,117 +0,0 @@
|
|||||||
<?php
|
|
||||||
/*
|
|
||||||
* This file is part of Flarum.
|
|
||||||
*
|
|
||||||
* (c) Toby Zerner <toby.zerner@gmail.com>
|
|
||||||
*
|
|
||||||
* For the full copyright and license information, please view the LICENSE
|
|
||||||
* file that was distributed with this source code.
|
|
||||||
*/
|
|
||||||
|
|
||||||
namespace Flarum\Asset;
|
|
||||||
|
|
||||||
use DomainException;
|
|
||||||
|
|
||||||
class AssetManager
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* @var CompilerInterface
|
|
||||||
*/
|
|
||||||
protected $less;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @var CompilerInterface
|
|
||||||
*/
|
|
||||||
protected $js;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param CompilerInterface $js
|
|
||||||
* @param CompilerInterface $less
|
|
||||||
*/
|
|
||||||
public function __construct(CompilerInterface $js, CompilerInterface $less)
|
|
||||||
{
|
|
||||||
$this->js = $js;
|
|
||||||
$this->less = $less;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param $filename
|
|
||||||
*/
|
|
||||||
public function setFilename($filename)
|
|
||||||
{
|
|
||||||
$this->js->setFilename($filename.'.js');
|
|
||||||
$this->less->setFilename($filename.'.css');
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param string $file
|
|
||||||
*/
|
|
||||||
public function addFile($file)
|
|
||||||
{
|
|
||||||
$ext = pathinfo($file, PATHINFO_EXTENSION);
|
|
||||||
|
|
||||||
switch ($ext) {
|
|
||||||
case 'js':
|
|
||||||
$this->js->addFile($file);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'css':
|
|
||||||
case 'less':
|
|
||||||
$this->less->addFile($file);
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
throw new DomainException('Unsupported asset type: '.$ext);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param string[] $files
|
|
||||||
*/
|
|
||||||
public function addFiles(array $files)
|
|
||||||
{
|
|
||||||
array_walk($files, [$this, 'addFile']);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param callable $callback
|
|
||||||
*/
|
|
||||||
public function addLess(callable $callback)
|
|
||||||
{
|
|
||||||
$this->less->addString($callback);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param callable $callback
|
|
||||||
*/
|
|
||||||
public function addJs(callable $callback)
|
|
||||||
{
|
|
||||||
$this->js->addString($callback);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
public function getCssFile()
|
|
||||||
{
|
|
||||||
return $this->less->getFile();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
public function getJsFile()
|
|
||||||
{
|
|
||||||
return $this->js->getFile();
|
|
||||||
}
|
|
||||||
|
|
||||||
public function flushCss()
|
|
||||||
{
|
|
||||||
$this->less->flush();
|
|
||||||
}
|
|
||||||
|
|
||||||
public function flushJs()
|
|
||||||
{
|
|
||||||
$this->js->flush();
|
|
||||||
}
|
|
||||||
}
|
|
@ -10,9 +10,9 @@
|
|||||||
|
|
||||||
namespace Flarum\Debug\Console;
|
namespace Flarum\Debug\Console;
|
||||||
|
|
||||||
use Flarum\Admin\Controller\ClientController as AdminClient;
|
use Flarum\Admin\WebApp as AdminWebApp;
|
||||||
use Flarum\Console\Command\AbstractCommand;
|
use Flarum\Console\Command\AbstractCommand;
|
||||||
use Flarum\Forum\Controller\ClientController as ForumClient;
|
use Flarum\Forum\WebApp as ForumWebApp;
|
||||||
use Illuminate\Contracts\Cache\Store;
|
use Illuminate\Contracts\Cache\Store;
|
||||||
|
|
||||||
class CacheClearCommand extends AbstractCommand
|
class CacheClearCommand extends AbstractCommand
|
||||||
@ -23,16 +23,21 @@ class CacheClearCommand extends AbstractCommand
|
|||||||
protected $cache;
|
protected $cache;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var \Flarum\Forum\Controller\ClientController
|
* @var \Flarum\Forum\WebApp
|
||||||
*/
|
*/
|
||||||
protected $forum;
|
protected $forum;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var \Flarum\Admin\Controller\ClientController
|
* @var \Flarum\Admin\WebApp
|
||||||
*/
|
*/
|
||||||
protected $admin;
|
protected $admin;
|
||||||
|
|
||||||
public function __construct(Store $cache, ForumClient $forum, AdminClient $admin)
|
/**
|
||||||
|
* @param Store $cache
|
||||||
|
* @param ForumWebApp $forum
|
||||||
|
* @param AdminWebApp $admin
|
||||||
|
*/
|
||||||
|
public function __construct(Store $cache, ForumWebApp $forum, AdminWebApp $admin)
|
||||||
{
|
{
|
||||||
$this->cache = $cache;
|
$this->cache = $cache;
|
||||||
$this->forum = $forum;
|
$this->forum = $forum;
|
||||||
@ -58,8 +63,8 @@ class CacheClearCommand extends AbstractCommand
|
|||||||
{
|
{
|
||||||
$this->info('Clearing the cache...');
|
$this->info('Clearing the cache...');
|
||||||
|
|
||||||
$this->forum->flushAssets();
|
$this->forum->getAssets()->flush();
|
||||||
$this->admin->flushAssets();
|
$this->admin->getAssets()->flush();
|
||||||
|
|
||||||
$this->cache->flush();
|
$this->cache->flush();
|
||||||
}
|
}
|
||||||
|
@ -10,6 +10,7 @@
|
|||||||
|
|
||||||
namespace Flarum\Event;
|
namespace Flarum\Event;
|
||||||
|
|
||||||
|
use Flarum\Http\Handler\RouteHandlerFactory;
|
||||||
use Flarum\Http\RouteCollection;
|
use Flarum\Http\RouteCollection;
|
||||||
|
|
||||||
abstract class AbstractConfigureRoutes
|
abstract class AbstractConfigureRoutes
|
||||||
@ -20,18 +21,18 @@ abstract class AbstractConfigureRoutes
|
|||||||
public $routes;
|
public $routes;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var callable
|
* @var RouteHandlerFactory
|
||||||
*/
|
*/
|
||||||
protected $handlerGenerator;
|
protected $route;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param RouteCollection $routes
|
* @param RouteCollection $routes
|
||||||
* @param callable $handlerGenerator
|
* @param RouteHandlerFactory $route
|
||||||
*/
|
*/
|
||||||
public function __construct(RouteCollection $routes, callable $handlerGenerator)
|
public function __construct(RouteCollection $routes, RouteHandlerFactory $route)
|
||||||
{
|
{
|
||||||
$this->routes = $routes;
|
$this->routes = $routes;
|
||||||
$this->handlerGenerator = $handlerGenerator;
|
$this->route = $route;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -91,6 +92,6 @@ abstract class AbstractConfigureRoutes
|
|||||||
*/
|
*/
|
||||||
protected function toController($controller)
|
protected function toController($controller)
|
||||||
{
|
{
|
||||||
return call_user_func($this->handlerGenerator, $controller);
|
return $this->route->toController($controller);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -10,50 +10,9 @@
|
|||||||
|
|
||||||
namespace Flarum\Event;
|
namespace Flarum\Event;
|
||||||
|
|
||||||
use Flarum\Admin\Controller\ClientController as AdminClientAction;
|
|
||||||
use Flarum\Forum\Controller\ClientController as ForumClientAction;
|
|
||||||
use Flarum\Http\Controller\AbstractClientController;
|
|
||||||
use Flarum\Http\Controller\ClientView;
|
|
||||||
|
|
||||||
class ConfigureClientView
|
|
||||||
{
|
|
||||||
/**
|
/**
|
||||||
* @var AbstractClientController
|
* @deprecated
|
||||||
*/
|
*/
|
||||||
public $action;
|
class ConfigureClientView extends ConfigureWebApp
|
||||||
|
|
||||||
/**
|
|
||||||
* @var ClientView
|
|
||||||
*/
|
|
||||||
public $view;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param AbstractClientController $action
|
|
||||||
* @param ClientView $view
|
|
||||||
*/
|
|
||||||
public function __construct(AbstractClientController $action, ClientView $view)
|
|
||||||
{
|
{
|
||||||
$this->action = $action;
|
|
||||||
$this->view = $view;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function isForum()
|
|
||||||
{
|
|
||||||
return $this->action instanceof ForumClientAction;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function isAdmin()
|
|
||||||
{
|
|
||||||
return $this->action instanceof AdminClientAction;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function addAssets($files)
|
|
||||||
{
|
|
||||||
$this->view->getAssets()->addFiles((array) $files);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function addBootstrapper($bootstrapper)
|
|
||||||
{
|
|
||||||
$this->view->addBootstrapper($bootstrapper);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
72
framework/core/src/Event/ConfigureWebApp.php
Normal file
72
framework/core/src/Event/ConfigureWebApp.php
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
<?php
|
||||||
|
/*
|
||||||
|
* This file is part of Flarum.
|
||||||
|
*
|
||||||
|
* (c) Toby Zerner <toby.zerner@gmail.com>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Flarum\Event;
|
||||||
|
|
||||||
|
use Flarum\Admin\Controller\WebAppController as AdminClientController;
|
||||||
|
use Flarum\Forum\Controller\WebAppController as ForumClientController;
|
||||||
|
use Flarum\Http\Controller\AbstractWebAppController;
|
||||||
|
use Flarum\Http\WebApp\WebAppView;
|
||||||
|
|
||||||
|
class ConfigureWebApp
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var AbstractClientController
|
||||||
|
*/
|
||||||
|
public $controller;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var ClientView
|
||||||
|
*/
|
||||||
|
public $view;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param AbstractClientController $controller
|
||||||
|
* @param ClientView $view
|
||||||
|
*/
|
||||||
|
public function __construct(AbstractWebAppController $controller, WebAppView $view)
|
||||||
|
{
|
||||||
|
$this->controller = $controller;
|
||||||
|
$this->view = $view;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function isForum()
|
||||||
|
{
|
||||||
|
return $this->controller instanceof ForumClientController;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function isAdmin()
|
||||||
|
{
|
||||||
|
return $this->controller instanceof AdminClientController;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function addAssets($files)
|
||||||
|
{
|
||||||
|
foreach ((array) $files as $file) {
|
||||||
|
$ext = pathinfo($file, PATHINFO_EXTENSION);
|
||||||
|
|
||||||
|
switch ($ext) {
|
||||||
|
case 'js':
|
||||||
|
$this->view->getJs()->addFile($file);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'css':
|
||||||
|
case 'less':
|
||||||
|
$this->view->getCss()->addFile($file);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function addBootstrapper($bootstrapper)
|
||||||
|
{
|
||||||
|
$this->view->loadModule($bootstrapper);
|
||||||
|
}
|
||||||
|
}
|
@ -13,7 +13,7 @@ namespace Flarum\Forum\Controller;
|
|||||||
use Flarum\Core\Exception\PermissionDeniedException;
|
use Flarum\Core\Exception\PermissionDeniedException;
|
||||||
use Psr\Http\Message\ServerRequestInterface as Request;
|
use Psr\Http\Message\ServerRequestInterface as Request;
|
||||||
|
|
||||||
class AuthorizedClientController extends ClientController
|
class AuthorizedWebAppController extends WebAppController
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* {@inheritdoc}
|
* {@inheritdoc}
|
@ -1,70 +0,0 @@
|
|||||||
<?php
|
|
||||||
/*
|
|
||||||
* This file is part of Flarum.
|
|
||||||
*
|
|
||||||
* (c) Toby Zerner <toby.zerner@gmail.com>
|
|
||||||
*
|
|
||||||
* For the full copyright and license information, please view the LICENSE
|
|
||||||
* file that was distributed with this source code.
|
|
||||||
*/
|
|
||||||
|
|
||||||
namespace Flarum\Forum\Controller;
|
|
||||||
|
|
||||||
use Flarum\Api\Client;
|
|
||||||
use Flarum\Formatter\Formatter;
|
|
||||||
use Flarum\Foundation\Application;
|
|
||||||
use Flarum\Http\Controller\AbstractClientController;
|
|
||||||
use Flarum\Locale\LocaleManager;
|
|
||||||
use Flarum\Settings\SettingsRepositoryInterface;
|
|
||||||
use Illuminate\Contracts\Cache\Repository;
|
|
||||||
use Illuminate\Contracts\Events\Dispatcher;
|
|
||||||
|
|
||||||
class ClientController extends AbstractClientController
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* {@inheritdoc}
|
|
||||||
*/
|
|
||||||
protected $clientName = 'forum';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* {@inheritdoc}
|
|
||||||
*/
|
|
||||||
protected $translations = '/^[^\.]+\.(?:forum|lib)\./';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @var Formatter
|
|
||||||
*/
|
|
||||||
protected $formatter;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* {@inheritdoc}
|
|
||||||
*/
|
|
||||||
public function __construct(
|
|
||||||
Application $app,
|
|
||||||
Client $api,
|
|
||||||
LocaleManager $locales,
|
|
||||||
SettingsRepositoryInterface $settings,
|
|
||||||
Dispatcher $events,
|
|
||||||
Repository $cache,
|
|
||||||
Formatter $formatter
|
|
||||||
) {
|
|
||||||
parent::__construct($app, $api, $locales, $settings, $events, $cache);
|
|
||||||
|
|
||||||
$this->layout = __DIR__.'/../../../views/forum.blade.php';
|
|
||||||
$this->formatter = $formatter;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* {@inheritdoc}
|
|
||||||
*/
|
|
||||||
protected function getAssets()
|
|
||||||
{
|
|
||||||
$assets = parent::getAssets();
|
|
||||||
|
|
||||||
$assets->addJs(function () {
|
|
||||||
return $this->formatter->getJs();
|
|
||||||
});
|
|
||||||
|
|
||||||
return $assets;
|
|
||||||
}
|
|
||||||
}
|
|
@ -10,18 +10,43 @@
|
|||||||
|
|
||||||
namespace Flarum\Forum\Controller;
|
namespace Flarum\Forum\Controller;
|
||||||
|
|
||||||
|
use Flarum\Api\Client as ApiClient;
|
||||||
use Flarum\Core\User;
|
use Flarum\Core\User;
|
||||||
|
use Flarum\Forum\WebApp;
|
||||||
|
use Flarum\Forum\UrlGenerator;
|
||||||
use Flarum\Http\Exception\RouteNotFoundException;
|
use Flarum\Http\Exception\RouteNotFoundException;
|
||||||
|
use Illuminate\Contracts\Events\Dispatcher;
|
||||||
use Psr\Http\Message\ServerRequestInterface as Request;
|
use Psr\Http\Message\ServerRequestInterface as Request;
|
||||||
|
|
||||||
class DiscussionController extends ClientController
|
class DiscussionController extends WebAppController
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* @var ApiClient
|
||||||
|
*/
|
||||||
|
protected $api;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var UrlGenerator
|
||||||
|
*/
|
||||||
|
protected $url;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@inheritdoc}
|
* {@inheritdoc}
|
||||||
*/
|
*/
|
||||||
public function render(Request $request)
|
public function __construct(WebApp $webApp, Dispatcher $events, ApiClient $api, UrlGenerator $url)
|
||||||
{
|
{
|
||||||
$view = parent::render($request);
|
parent::__construct($webApp, $events);
|
||||||
|
|
||||||
|
$this->api = $api;
|
||||||
|
$this->url = $url;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
protected function getView(Request $request)
|
||||||
|
{
|
||||||
|
$view = parent::getView($request);
|
||||||
|
|
||||||
$queryParams = $request->getQueryParams();
|
$queryParams = $request->getQueryParams();
|
||||||
$page = max(1, array_get($queryParams, 'page'));
|
$page = max(1, array_get($queryParams, 'page'));
|
||||||
@ -35,7 +60,7 @@ class DiscussionController extends ClientController
|
|||||||
]
|
]
|
||||||
];
|
];
|
||||||
|
|
||||||
$document = $this->preload($request->getAttribute('actor'), $params);
|
$document = $this->getDocument($request->getAttribute('actor'), $params);
|
||||||
|
|
||||||
$getResource = function ($link) use ($document) {
|
$getResource = function ($link) use ($document) {
|
||||||
return array_first($document->included, function ($key, $value) use ($link) {
|
return array_first($document->included, function ($key, $value) use ($link) {
|
||||||
@ -47,8 +72,7 @@ class DiscussionController extends ClientController
|
|||||||
$newQueryParams = array_merge($queryParams, $newQueryParams);
|
$newQueryParams = array_merge($queryParams, $newQueryParams);
|
||||||
$queryString = http_build_query($newQueryParams);
|
$queryString = http_build_query($newQueryParams);
|
||||||
|
|
||||||
return app('Flarum\Forum\UrlGenerator')
|
return $this->url->toRoute('discussion', ['id' => $document->data->id]).
|
||||||
->toRoute('discussion', ['id' => $document->data->id]).
|
|
||||||
($queryString ? '?'.$queryString : '');
|
($queryString ? '?'.$queryString : '');
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -75,7 +99,7 @@ class DiscussionController extends ClientController
|
|||||||
* @return object
|
* @return object
|
||||||
* @throws RouteNotFoundException
|
* @throws RouteNotFoundException
|
||||||
*/
|
*/
|
||||||
protected function preload(User $actor, array $params)
|
protected function getDocument(User $actor, array $params)
|
||||||
{
|
{
|
||||||
$response = $this->api->send('Flarum\Api\Controller\ShowDiscussionController', $actor, $params);
|
$response = $this->api->send('Flarum\Api\Controller\ShowDiscussionController', $actor, $params);
|
||||||
$statusCode = $response->getStatusCode();
|
$statusCode = $response->getStatusCode();
|
||||||
|
@ -10,11 +10,19 @@
|
|||||||
|
|
||||||
namespace Flarum\Forum\Controller;
|
namespace Flarum\Forum\Controller;
|
||||||
|
|
||||||
|
use Flarum\Api\Client as ApiClient;
|
||||||
use Flarum\Core\User;
|
use Flarum\Core\User;
|
||||||
|
use Flarum\Forum\WebApp;
|
||||||
|
use Illuminate\Contracts\Events\Dispatcher;
|
||||||
use Psr\Http\Message\ServerRequestInterface as Request;
|
use Psr\Http\Message\ServerRequestInterface as Request;
|
||||||
|
|
||||||
class IndexController extends ClientController
|
class IndexController extends WebAppController
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* @var ApiClient
|
||||||
|
*/
|
||||||
|
protected $api;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A map of sort query param values to their API sort param.
|
* A map of sort query param values to their API sort param.
|
||||||
*
|
*
|
||||||
@ -30,9 +38,19 @@ class IndexController extends ClientController
|
|||||||
/**
|
/**
|
||||||
* {@inheritdoc}
|
* {@inheritdoc}
|
||||||
*/
|
*/
|
||||||
public function render(Request $request)
|
public function __construct(WebApp $webApp, Dispatcher $events, ApiClient $api)
|
||||||
{
|
{
|
||||||
$view = parent::render($request);
|
parent::__construct($webApp, $events);
|
||||||
|
|
||||||
|
$this->api = $api;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
protected function getView(Request $request)
|
||||||
|
{
|
||||||
|
$view = parent::getView($request);
|
||||||
|
|
||||||
$queryParams = $request->getQueryParams();
|
$queryParams = $request->getQueryParams();
|
||||||
|
|
||||||
@ -46,7 +64,7 @@ class IndexController extends ClientController
|
|||||||
'page' => ['offset' => ($page - 1) * 20, 'limit' => 20]
|
'page' => ['offset' => ($page - 1) * 20, 'limit' => 20]
|
||||||
];
|
];
|
||||||
|
|
||||||
$document = $this->preload($request->getAttribute('actor'), $params);
|
$document = $this->getDocument($request->getAttribute('actor'), $params);
|
||||||
|
|
||||||
$view->setDocument($document);
|
$view->setDocument($document);
|
||||||
$view->setContent(app('view')->make('flarum.forum::index', compact('document', 'page', 'forum')));
|
$view->setContent(app('view')->make('flarum.forum::index', compact('document', 'page', 'forum')));
|
||||||
@ -61,7 +79,7 @@ class IndexController extends ClientController
|
|||||||
* @param array $params
|
* @param array $params
|
||||||
* @return object
|
* @return object
|
||||||
*/
|
*/
|
||||||
protected function preload(User $actor, array $params)
|
private function getDocument(User $actor, array $params)
|
||||||
{
|
{
|
||||||
return json_decode($this->api->send('Flarum\Api\Controller\ListDiscussionsController', $actor, $params)->getBody());
|
return json_decode($this->api->send('Flarum\Api\Controller\ListDiscussionsController', $actor, $params)->getBody());
|
||||||
}
|
}
|
||||||
|
27
framework/core/src/Forum/Controller/WebAppController.php
Normal file
27
framework/core/src/Forum/Controller/WebAppController.php
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
<?php
|
||||||
|
/*
|
||||||
|
* This file is part of Flarum.
|
||||||
|
*
|
||||||
|
* (c) Toby Zerner <toby.zerner@gmail.com>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Flarum\Forum\Controller;
|
||||||
|
|
||||||
|
use Flarum\Forum\WebApp;
|
||||||
|
use Flarum\Http\Controller\AbstractWebAppController;
|
||||||
|
use Illuminate\Contracts\Events\Dispatcher;
|
||||||
|
|
||||||
|
class WebAppController extends AbstractWebAppController
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function __construct(WebApp $webApp, Dispatcher $events)
|
||||||
|
{
|
||||||
|
$this->webApp = $webApp;
|
||||||
|
$this->events = $events;
|
||||||
|
}
|
||||||
|
}
|
@ -15,13 +15,11 @@ use Flarum\Event\ExtensionWasDisabled;
|
|||||||
use Flarum\Event\ExtensionWasEnabled;
|
use Flarum\Event\ExtensionWasEnabled;
|
||||||
use Flarum\Event\SettingWasSet;
|
use Flarum\Event\SettingWasSet;
|
||||||
use Flarum\Foundation\AbstractServiceProvider;
|
use Flarum\Foundation\AbstractServiceProvider;
|
||||||
use Flarum\Http\GenerateRouteHandlerTrait;
|
use Flarum\Http\Handler\RouteHandlerFactory;
|
||||||
use Flarum\Http\RouteCollection;
|
use Flarum\Http\RouteCollection;
|
||||||
|
|
||||||
class ForumServiceProvider extends AbstractServiceProvider
|
class ForumServiceProvider extends AbstractServiceProvider
|
||||||
{
|
{
|
||||||
use GenerateRouteHandlerTrait;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@inheritdoc}
|
* {@inheritdoc}
|
||||||
*/
|
*/
|
||||||
@ -45,9 +43,9 @@ class ForumServiceProvider extends AbstractServiceProvider
|
|||||||
|
|
||||||
$this->loadViewsFrom(__DIR__.'/../../views', 'flarum.forum');
|
$this->loadViewsFrom(__DIR__.'/../../views', 'flarum.forum');
|
||||||
|
|
||||||
$this->flushAssetsWhenThemeChanged();
|
$this->flushWebAppAssetsWhenThemeChanged();
|
||||||
|
|
||||||
$this->flushAssetsWhenExtensionsChanged();
|
$this->flushWebAppAssetsWhenExtensionsChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -57,76 +55,76 @@ class ForumServiceProvider extends AbstractServiceProvider
|
|||||||
*/
|
*/
|
||||||
protected function populateRoutes(RouteCollection $routes)
|
protected function populateRoutes(RouteCollection $routes)
|
||||||
{
|
{
|
||||||
$toController = $this->getHandlerGenerator($this->app);
|
$route = $this->app->make(RouteHandlerFactory::class);
|
||||||
|
|
||||||
$routes->get(
|
$routes->get(
|
||||||
'/all',
|
'/all',
|
||||||
'index',
|
'index',
|
||||||
$toDefaultController = $toController('Flarum\Forum\Controller\IndexController')
|
$toDefaultController = $route->toController(Controller\IndexController::class)
|
||||||
);
|
);
|
||||||
|
|
||||||
$routes->get(
|
$routes->get(
|
||||||
'/d/{id:\d+(?:-[^/]*)?}[/{near:[^/]*}]',
|
'/d/{id:\d+(?:-[^/]*)?}[/{near:[^/]*}]',
|
||||||
'discussion',
|
'discussion',
|
||||||
$toController('Flarum\Forum\Controller\DiscussionController')
|
$route->toController(Controller\DiscussionController::class)
|
||||||
);
|
);
|
||||||
|
|
||||||
$routes->get(
|
$routes->get(
|
||||||
'/u/{username}[/{filter:[^/]*}]',
|
'/u/{username}[/{filter:[^/]*}]',
|
||||||
'user',
|
'user',
|
||||||
$toController('Flarum\Forum\Controller\ClientController')
|
$route->toController(Controller\WebAppController::class)
|
||||||
);
|
);
|
||||||
|
|
||||||
$routes->get(
|
$routes->get(
|
||||||
'/settings',
|
'/settings',
|
||||||
'settings',
|
'settings',
|
||||||
$toController('Flarum\Forum\Controller\AuthorizedClientController')
|
$route->toController(Controller\AuthorizedWebAppController::class)
|
||||||
);
|
);
|
||||||
|
|
||||||
$routes->get(
|
$routes->get(
|
||||||
'/notifications',
|
'/notifications',
|
||||||
'notifications',
|
'notifications',
|
||||||
$toController('Flarum\Forum\Controller\AuthorizedClientController')
|
$route->toController(Controller\AuthorizedWebAppController::class)
|
||||||
);
|
);
|
||||||
|
|
||||||
$routes->get(
|
$routes->get(
|
||||||
'/logout',
|
'/logout',
|
||||||
'logout',
|
'logout',
|
||||||
$toController('Flarum\Forum\Controller\LogOutController')
|
$route->toController(Controller\LogOutController::class)
|
||||||
);
|
);
|
||||||
|
|
||||||
$routes->post(
|
$routes->post(
|
||||||
'/login',
|
'/login',
|
||||||
'login',
|
'login',
|
||||||
$toController('Flarum\Forum\Controller\LogInController')
|
$route->toController(Controller\LogInController::class)
|
||||||
);
|
);
|
||||||
|
|
||||||
$routes->post(
|
$routes->post(
|
||||||
'/register',
|
'/register',
|
||||||
'register',
|
'register',
|
||||||
$toController('Flarum\Forum\Controller\RegisterController')
|
$route->toController(Controller\RegisterController::class)
|
||||||
);
|
);
|
||||||
|
|
||||||
$routes->get(
|
$routes->get(
|
||||||
'/confirm/{token}',
|
'/confirm/{token}',
|
||||||
'confirmEmail',
|
'confirmEmail',
|
||||||
$toController('Flarum\Forum\Controller\ConfirmEmailController')
|
$route->toController(Controller\ConfirmEmailController::class)
|
||||||
);
|
);
|
||||||
|
|
||||||
$routes->get(
|
$routes->get(
|
||||||
'/reset/{token}',
|
'/reset/{token}',
|
||||||
'resetPassword',
|
'resetPassword',
|
||||||
$toController('Flarum\Forum\Controller\ResetPasswordController')
|
$route->toController(Controller\ResetPasswordController::class)
|
||||||
);
|
);
|
||||||
|
|
||||||
$routes->post(
|
$routes->post(
|
||||||
'/reset',
|
'/reset',
|
||||||
'savePassword',
|
'savePassword',
|
||||||
$toController('Flarum\Forum\Controller\SavePasswordController')
|
$route->toController(Controller\SavePasswordController::class)
|
||||||
);
|
);
|
||||||
|
|
||||||
$this->app->make('events')->fire(
|
$this->app->make('events')->fire(
|
||||||
new ConfigureForumRoutes($routes, $toController)
|
new ConfigureForumRoutes($routes, $route)
|
||||||
);
|
);
|
||||||
|
|
||||||
$defaultRoute = $this->app->make('flarum.settings')->get('default_route');
|
$defaultRoute = $this->app->make('flarum.settings')->get('default_route');
|
||||||
@ -142,33 +140,33 @@ class ForumServiceProvider extends AbstractServiceProvider
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function flushAssetsWhenThemeChanged()
|
protected function flushWebAppAssetsWhenThemeChanged()
|
||||||
{
|
{
|
||||||
$this->app->make('events')->listen(SettingWasSet::class, function (SettingWasSet $event) {
|
$this->app->make('events')->listen(SettingWasSet::class, function (SettingWasSet $event) {
|
||||||
if (preg_match('/^theme_|^custom_less$/i', $event->key)) {
|
if (preg_match('/^theme_|^custom_less$/i', $event->key)) {
|
||||||
$this->getClientController()->flushCss();
|
$this->getWebAppAssets()->flushCss();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function flushAssetsWhenExtensionsChanged()
|
protected function flushWebAppAssetsWhenExtensionsChanged()
|
||||||
{
|
{
|
||||||
$events = $this->app->make('events');
|
$events = $this->app->make('events');
|
||||||
|
|
||||||
$events->listen(ExtensionWasEnabled::class, [$this, 'flushAssets']);
|
$events->listen(ExtensionWasEnabled::class, [$this, 'flushWebAppAssets']);
|
||||||
$events->listen(ExtensionWasDisabled::class, [$this, 'flushAssets']);
|
$events->listen(ExtensionWasDisabled::class, [$this, 'flushWebAppAssets']);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function flushAssets()
|
public function flushWebAppAssets()
|
||||||
{
|
{
|
||||||
$this->getClientController()->flushAssets();
|
$this->getWebAppAssets()->flush();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return \Flarum\Forum\Controller\ClientController
|
* @return \Flarum\Http\WebApp\WebAppAssets
|
||||||
*/
|
*/
|
||||||
protected function getClientController()
|
protected function getWebAppAssets()
|
||||||
{
|
{
|
||||||
return $this->app->make('Flarum\Forum\Controller\ClientController');
|
return $this->app->make(WebApp::class)->getAssets();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
63
framework/core/src/Forum/WebApp.php
Normal file
63
framework/core/src/Forum/WebApp.php
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
<?php
|
||||||
|
/*
|
||||||
|
* This file is part of Flarum.
|
||||||
|
*
|
||||||
|
* (c) Toby Zerner <toby.zerner@gmail.com>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Flarum\Forum;
|
||||||
|
|
||||||
|
use Flarum\Formatter\Formatter;
|
||||||
|
use Flarum\Http\WebApp\AbstractWebApp;
|
||||||
|
use Flarum\Http\WebApp\WebAppAssetsFactory;
|
||||||
|
use Flarum\Http\WebApp\WebAppViewFactory;
|
||||||
|
use Flarum\Locale\LocaleManager;
|
||||||
|
use Flarum\Settings\SettingsRepositoryInterface;
|
||||||
|
|
||||||
|
class WebApp extends AbstractWebApp
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var Formatter
|
||||||
|
*/
|
||||||
|
protected $formatter;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function __construct(
|
||||||
|
WebAppAssetsFactory $assets,
|
||||||
|
WebAppViewFactory $view,
|
||||||
|
SettingsRepositoryInterface $settings,
|
||||||
|
LocaleManager $locales,
|
||||||
|
Formatter $formatter
|
||||||
|
) {
|
||||||
|
parent::__construct($assets, $view, $settings, $locales);
|
||||||
|
|
||||||
|
$this->formatter = $formatter;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function getView()
|
||||||
|
{
|
||||||
|
$view = parent::getView();
|
||||||
|
|
||||||
|
$view->getJs()->addString(function () {
|
||||||
|
return $this->formatter->getJs();
|
||||||
|
});
|
||||||
|
|
||||||
|
return $view;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
protected function getName()
|
||||||
|
{
|
||||||
|
return 'forum';
|
||||||
|
}
|
||||||
|
}
|
@ -1,316 +0,0 @@
|
|||||||
<?php
|
|
||||||
/*
|
|
||||||
* This file is part of Flarum.
|
|
||||||
*
|
|
||||||
* (c) Toby Zerner <toby.zerner@gmail.com>
|
|
||||||
*
|
|
||||||
* For the full copyright and license information, please view the LICENSE
|
|
||||||
* file that was distributed with this source code.
|
|
||||||
*/
|
|
||||||
|
|
||||||
namespace Flarum\Http\Controller;
|
|
||||||
|
|
||||||
use Flarum\Api\Client;
|
|
||||||
use Flarum\Asset\AssetManager;
|
|
||||||
use Flarum\Asset\JsCompiler;
|
|
||||||
use Flarum\Asset\LessCompiler;
|
|
||||||
use Flarum\Event\ConfigureClientView;
|
|
||||||
use Flarum\Foundation\Application;
|
|
||||||
use Flarum\Locale\JsCompiler as LocaleJsCompiler;
|
|
||||||
use Flarum\Locale\LocaleManager;
|
|
||||||
use Flarum\Settings\SettingsRepositoryInterface;
|
|
||||||
use Illuminate\Contracts\Cache\Repository;
|
|
||||||
use Illuminate\Contracts\Events\Dispatcher;
|
|
||||||
use Psr\Http\Message\ServerRequestInterface as Request;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This action sets up a ClientView, and preloads it with the assets necessary
|
|
||||||
* to boot a Flarum client.
|
|
||||||
*
|
|
||||||
* Subclasses should set a $clientName, $layout, and $translationKeys. The
|
|
||||||
* client name will be used to locate the client assets (or alternatively,
|
|
||||||
* subclasses can overwrite the addAssets method), and set up asset compilers
|
|
||||||
* which write to the assets directory. Configured LESS customizations will be
|
|
||||||
* appended.
|
|
||||||
*
|
|
||||||
* A locale compiler is set up for the actor's locale, including the
|
|
||||||
* translations specified in $translationKeys. Additionally, an event is fired
|
|
||||||
* before the ClientView is returned, giving extensions an opportunity to add
|
|
||||||
* assets, translations, or alter the view.
|
|
||||||
*/
|
|
||||||
abstract class AbstractClientController extends AbstractHtmlController
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* The name of the client. This is used to locate assets within the js/
|
|
||||||
* and less/ directories. It is also used as the filename of the compiled
|
|
||||||
* asset files.
|
|
||||||
*
|
|
||||||
* @var string
|
|
||||||
*/
|
|
||||||
protected $clientName;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The name of the view to include as the page layout.
|
|
||||||
*
|
|
||||||
* @var string
|
|
||||||
*/
|
|
||||||
protected $layout;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A regex matching the keys of the translations that should be included in
|
|
||||||
* the compiled locale file.
|
|
||||||
*
|
|
||||||
* @var string
|
|
||||||
*/
|
|
||||||
protected $translations;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @var \Flarum\Foundation\Application
|
|
||||||
*/
|
|
||||||
protected $app;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @var Client
|
|
||||||
*/
|
|
||||||
protected $api;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @var LocaleManager
|
|
||||||
*/
|
|
||||||
protected $locales;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @var \Flarum\Settings\SettingsRepositoryInterface
|
|
||||||
*/
|
|
||||||
protected $settings;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @var Dispatcher
|
|
||||||
*/
|
|
||||||
protected $events;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @var Repository
|
|
||||||
*/
|
|
||||||
protected $cache;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param \Flarum\Foundation\Application $app
|
|
||||||
* @param Client $api
|
|
||||||
* @param LocaleManager $locales
|
|
||||||
* @param \Flarum\Settings\SettingsRepositoryInterface $settings
|
|
||||||
* @param Dispatcher $events
|
|
||||||
* @param Repository $cache
|
|
||||||
*/
|
|
||||||
public function __construct(
|
|
||||||
Application $app,
|
|
||||||
Client $api,
|
|
||||||
LocaleManager $locales,
|
|
||||||
SettingsRepositoryInterface $settings,
|
|
||||||
Dispatcher $events,
|
|
||||||
Repository $cache
|
|
||||||
) {
|
|
||||||
$this->app = $app;
|
|
||||||
$this->api = $api;
|
|
||||||
$this->locales = $locales;
|
|
||||||
$this->settings = $settings;
|
|
||||||
$this->events = $events;
|
|
||||||
$this->cache = $cache;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* {@inheritdoc}
|
|
||||||
*
|
|
||||||
* @return ClientView
|
|
||||||
*/
|
|
||||||
public function render(Request $request)
|
|
||||||
{
|
|
||||||
$actor = $request->getAttribute('actor');
|
|
||||||
$assets = $this->getAssets();
|
|
||||||
$locale = $this->locales->getLocale();
|
|
||||||
$localeCompiler = $locale ? $this->getLocaleCompiler($locale) : null;
|
|
||||||
|
|
||||||
$view = new ClientView(
|
|
||||||
$this->api,
|
|
||||||
$request,
|
|
||||||
$actor,
|
|
||||||
$assets,
|
|
||||||
$this->layout,
|
|
||||||
$localeCompiler
|
|
||||||
);
|
|
||||||
|
|
||||||
$view->setVariable('locales', $this->locales->getLocales());
|
|
||||||
$view->setVariable('locale', $locale);
|
|
||||||
|
|
||||||
$this->events->fire(
|
|
||||||
new ConfigureClientView($this, $view)
|
|
||||||
);
|
|
||||||
|
|
||||||
if ($localeCompiler) {
|
|
||||||
$translations = array_get($this->locales->getTranslator()->getMessages(), 'messages', []);
|
|
||||||
|
|
||||||
$translations = $this->filterTranslations($translations);
|
|
||||||
|
|
||||||
$localeCompiler->setTranslations($translations);
|
|
||||||
}
|
|
||||||
|
|
||||||
app('view')->share('translator', $this->locales->getTranslator());
|
|
||||||
|
|
||||||
return $view;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Flush the client's assets so that they will be regenerated from scratch
|
|
||||||
* on the next render.
|
|
||||||
*/
|
|
||||||
public function flushAssets()
|
|
||||||
{
|
|
||||||
$this->flushCss();
|
|
||||||
$this->flushJs();
|
|
||||||
}
|
|
||||||
|
|
||||||
public function flushCss()
|
|
||||||
{
|
|
||||||
$this->getAssets()->flushCss();
|
|
||||||
}
|
|
||||||
|
|
||||||
public function flushJs()
|
|
||||||
{
|
|
||||||
$this->getAssets()->flushJs();
|
|
||||||
|
|
||||||
$this->flushLocales();
|
|
||||||
}
|
|
||||||
|
|
||||||
public function flushLocales()
|
|
||||||
{
|
|
||||||
$locales = array_keys($this->locales->getLocales());
|
|
||||||
|
|
||||||
foreach ($locales as $locale) {
|
|
||||||
$this->getLocaleCompiler($locale)->flush();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set up the asset manager, preloaded with a JavaScript compiler and a LESS
|
|
||||||
* compiler. Automatically add the files necessary to boot a Flarum client,
|
|
||||||
* as well as any configured LESS customizations.
|
|
||||||
*
|
|
||||||
* @return AssetManager
|
|
||||||
*/
|
|
||||||
protected function getAssets()
|
|
||||||
{
|
|
||||||
$public = $this->getAssetDirectory();
|
|
||||||
$watch = $this->app->config('debug');
|
|
||||||
|
|
||||||
$assets = new AssetManager(
|
|
||||||
new JsCompiler($public, "$this->clientName.js", $watch, $this->cache),
|
|
||||||
new LessCompiler($public, "$this->clientName.css", $watch, $this->app->storagePath().'/less')
|
|
||||||
);
|
|
||||||
|
|
||||||
$this->addAssets($assets);
|
|
||||||
$this->addCustomizations($assets);
|
|
||||||
|
|
||||||
return $assets;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Add the assets necessary to boot a Flarum client, found within the
|
|
||||||
* directory specified by the $clientName property.
|
|
||||||
*
|
|
||||||
* @param AssetManager $assets
|
|
||||||
*/
|
|
||||||
protected function addAssets(AssetManager $assets)
|
|
||||||
{
|
|
||||||
$root = __DIR__.'/../../..';
|
|
||||||
|
|
||||||
$assets->addFile("$root/js/$this->clientName/dist/app.js");
|
|
||||||
$assets->addFile("$root/less/$this->clientName/app.less");
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Add any configured JS/LESS customizations to the asset manager.
|
|
||||||
*
|
|
||||||
* @param AssetManager $assets
|
|
||||||
*/
|
|
||||||
protected function addCustomizations(AssetManager $assets)
|
|
||||||
{
|
|
||||||
$assets->addLess(function () {
|
|
||||||
$less = '';
|
|
||||||
|
|
||||||
foreach ($this->getLessVariables() as $name => $value) {
|
|
||||||
$less .= "@$name: $value;";
|
|
||||||
}
|
|
||||||
|
|
||||||
$less .= $this->settings->get('custom_less');
|
|
||||||
|
|
||||||
return $less;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the values of any LESS variables to compile into the CSS, based on
|
|
||||||
* the forum's configuration.
|
|
||||||
*
|
|
||||||
* @return array
|
|
||||||
*/
|
|
||||||
protected function getLessVariables()
|
|
||||||
{
|
|
||||||
return [
|
|
||||||
'config-primary-color' => $this->settings->get('theme_primary_color') ?: '#000',
|
|
||||||
'config-secondary-color' => $this->settings->get('theme_secondary_color') ?: '#000',
|
|
||||||
'config-dark-mode' => $this->settings->get('theme_dark_mode') ? 'true' : 'false',
|
|
||||||
'config-colored-header' => $this->settings->get('theme_colored_header') ? 'true' : 'false'
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set up the locale compiler for the given locale.
|
|
||||||
*
|
|
||||||
* @param string $locale
|
|
||||||
* @return LocaleJsCompiler
|
|
||||||
*/
|
|
||||||
protected function getLocaleCompiler($locale)
|
|
||||||
{
|
|
||||||
$compiler = new LocaleJsCompiler(
|
|
||||||
$this->getAssetDirectory(),
|
|
||||||
"$this->clientName-$locale.js",
|
|
||||||
$this->app->config('debug'),
|
|
||||||
$this->cache
|
|
||||||
);
|
|
||||||
|
|
||||||
foreach ($this->locales->getJsFiles($locale) as $file) {
|
|
||||||
$compiler->addFile($file);
|
|
||||||
}
|
|
||||||
|
|
||||||
return $compiler;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the path to the directory where assets should be written.
|
|
||||||
*
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
protected function getAssetDirectory()
|
|
||||||
{
|
|
||||||
return public_path().'/assets';
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Take a selection of keys from a collection of translations.
|
|
||||||
*
|
|
||||||
* @param array $translations
|
|
||||||
* @return array
|
|
||||||
*/
|
|
||||||
protected function filterTranslations(array $translations)
|
|
||||||
{
|
|
||||||
if (! $this->translations) {
|
|
||||||
return [];
|
|
||||||
}
|
|
||||||
|
|
||||||
$filtered = array_filter(array_keys($translations), function ($id) {
|
|
||||||
return preg_match($this->translations, $id);
|
|
||||||
});
|
|
||||||
|
|
||||||
return array_only($translations, $filtered);
|
|
||||||
}
|
|
||||||
}
|
|
@ -24,7 +24,7 @@ abstract class AbstractHtmlController implements ControllerInterface
|
|||||||
$view = $this->render($request);
|
$view = $this->render($request);
|
||||||
|
|
||||||
$response = new Response;
|
$response = new Response;
|
||||||
$response->getBody()->write($view->render());
|
$response->getBody()->write($view);
|
||||||
|
|
||||||
return $response;
|
return $response;
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,52 @@
|
|||||||
|
<?php
|
||||||
|
/*
|
||||||
|
* This file is part of Flarum.
|
||||||
|
*
|
||||||
|
* (c) Toby Zerner <toby.zerner@gmail.com>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Flarum\Http\Controller;
|
||||||
|
|
||||||
|
use Flarum\Event\ConfigureWebApp;
|
||||||
|
use Flarum\Http\WebApp\AbstractWebApp;
|
||||||
|
use Illuminate\Contracts\Events\Dispatcher;
|
||||||
|
use Psr\Http\Message\ServerRequestInterface as Request;
|
||||||
|
|
||||||
|
abstract class AbstractWebAppController extends AbstractHtmlController
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var AbstractWebApp
|
||||||
|
*/
|
||||||
|
protected $webApp;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var Dispatcher
|
||||||
|
*/
|
||||||
|
protected $events;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function render(Request $request)
|
||||||
|
{
|
||||||
|
$view = $this->getView($request);
|
||||||
|
|
||||||
|
$this->events->fire(
|
||||||
|
new ConfigureWebApp($this, $view, $request)
|
||||||
|
);
|
||||||
|
|
||||||
|
return $view->render($request);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param Request $request
|
||||||
|
* @return \Flarum\Http\WebApp\WebAppView
|
||||||
|
*/
|
||||||
|
protected function getView(Request $request)
|
||||||
|
{
|
||||||
|
return $this->webApp->getView();
|
||||||
|
}
|
||||||
|
}
|
@ -1,371 +0,0 @@
|
|||||||
<?php
|
|
||||||
/*
|
|
||||||
* This file is part of Flarum.
|
|
||||||
*
|
|
||||||
* (c) Toby Zerner <toby.zerner@gmail.com>
|
|
||||||
*
|
|
||||||
* For the full copyright and license information, please view the LICENSE
|
|
||||||
* file that was distributed with this source code.
|
|
||||||
*/
|
|
||||||
|
|
||||||
namespace Flarum\Http\Controller;
|
|
||||||
|
|
||||||
use Flarum\Api\Client;
|
|
||||||
use Flarum\Asset\AssetManager;
|
|
||||||
use Flarum\Core\User;
|
|
||||||
use Flarum\Locale\JsCompiler;
|
|
||||||
use Illuminate\Contracts\Support\Renderable;
|
|
||||||
use Psr\Http\Message\ServerRequestInterface as Request;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This class represents a view which boots up Flarum's client.
|
|
||||||
*/
|
|
||||||
class ClientView implements Renderable
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* The user who is using the client.
|
|
||||||
*
|
|
||||||
* @var User
|
|
||||||
*/
|
|
||||||
protected $actor;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The title of the document, displayed in the <title> tag.
|
|
||||||
*
|
|
||||||
* @var null|string
|
|
||||||
*/
|
|
||||||
protected $title;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The SEO content of the page, displayed in <noscript> tags.
|
|
||||||
*
|
|
||||||
* @var string
|
|
||||||
*/
|
|
||||||
protected $content;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The path to the client layout view to display.
|
|
||||||
*
|
|
||||||
* @var string
|
|
||||||
*/
|
|
||||||
protected $layout;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* An API response that should be preloaded into the page.
|
|
||||||
*
|
|
||||||
* @var null|array|object
|
|
||||||
*/
|
|
||||||
protected $document;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Other variables to preload into the page.
|
|
||||||
*
|
|
||||||
* @var array
|
|
||||||
*/
|
|
||||||
protected $variables = [];
|
|
||||||
|
|
||||||
/**
|
|
||||||
* An array of JS modules to import before booting the app.
|
|
||||||
*
|
|
||||||
* @var array
|
|
||||||
*/
|
|
||||||
protected $bootstrappers = ['locale'];
|
|
||||||
|
|
||||||
/**
|
|
||||||
* An array of strings to append to the page's <head>.
|
|
||||||
*
|
|
||||||
* @var array
|
|
||||||
*/
|
|
||||||
protected $headStrings = [];
|
|
||||||
|
|
||||||
/**
|
|
||||||
* An array of strings to prepend before the page's </body>.
|
|
||||||
*
|
|
||||||
* @var array
|
|
||||||
*/
|
|
||||||
protected $footStrings = [];
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @var Client
|
|
||||||
*/
|
|
||||||
protected $api;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @var Request
|
|
||||||
*/
|
|
||||||
protected $request;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @var AssetManager
|
|
||||||
*/
|
|
||||||
protected $assets;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @var JsCompiler
|
|
||||||
*/
|
|
||||||
protected $localeJs;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param Client $api
|
|
||||||
* @param Request $request
|
|
||||||
* @param User $actor
|
|
||||||
* @param AssetManager $assets
|
|
||||||
* @param string $layout
|
|
||||||
* @param JsCompiler $localeJs
|
|
||||||
*/
|
|
||||||
public function __construct(
|
|
||||||
Client $api,
|
|
||||||
Request $request,
|
|
||||||
User $actor,
|
|
||||||
AssetManager $assets,
|
|
||||||
$layout,
|
|
||||||
JsCompiler $localeJs = null
|
|
||||||
) {
|
|
||||||
$this->api = $api;
|
|
||||||
$this->request = $request;
|
|
||||||
$this->actor = $actor;
|
|
||||||
$this->assets = $assets;
|
|
||||||
$this->layout = $layout;
|
|
||||||
$this->localeJs = $localeJs;
|
|
||||||
|
|
||||||
$this->addHeadString('<link rel="stylesheet" href="//fonts.googleapis.com/css?family=Open+Sans:400italic,700italic,400,700,600">', 'font');
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The title of the document, to be displayed in the <title> tag.
|
|
||||||
*
|
|
||||||
* @param null|string $title
|
|
||||||
*/
|
|
||||||
public function setTitle($title)
|
|
||||||
{
|
|
||||||
$this->title = $title;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the SEO content of the page, to be displayed in <noscript> tags.
|
|
||||||
*
|
|
||||||
* @param null|string $content
|
|
||||||
*/
|
|
||||||
public function setContent($content)
|
|
||||||
{
|
|
||||||
$this->content = $content;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the name of the client layout view to display.
|
|
||||||
*
|
|
||||||
* @param string $layout
|
|
||||||
*/
|
|
||||||
public function setLayout($layout)
|
|
||||||
{
|
|
||||||
$this->layout = $layout;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Add a string to be appended to the page's <head>.
|
|
||||||
*
|
|
||||||
* @param string $string
|
|
||||||
*/
|
|
||||||
public function addHeadString($string, $name = null)
|
|
||||||
{
|
|
||||||
if ($name) {
|
|
||||||
$this->headStrings[$name] = $string;
|
|
||||||
} else {
|
|
||||||
$this->headStrings[] = $string;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Add a string to be prepended before the page's </body>.
|
|
||||||
*
|
|
||||||
* @param string $string
|
|
||||||
*/
|
|
||||||
public function addFootString($string)
|
|
||||||
{
|
|
||||||
$this->footStrings[] = $string;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set an API response to be preloaded into the page. This should be a
|
|
||||||
* JSON-API document.
|
|
||||||
*
|
|
||||||
* @param null|array|object $document
|
|
||||||
*/
|
|
||||||
public function setDocument($document)
|
|
||||||
{
|
|
||||||
$this->document = $document;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set a variable to be preloaded into the app.
|
|
||||||
*
|
|
||||||
* @param string $name
|
|
||||||
* @param mixed $value
|
|
||||||
*/
|
|
||||||
public function setVariable($name, $value)
|
|
||||||
{
|
|
||||||
$this->variables[$name] = $value;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Add a JavaScript module to be imported before the app is booted.
|
|
||||||
*
|
|
||||||
* @param string $string
|
|
||||||
*/
|
|
||||||
public function addBootstrapper($string)
|
|
||||||
{
|
|
||||||
$this->bootstrappers[] = $string;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the view's asset manager.
|
|
||||||
*
|
|
||||||
* @return AssetManager
|
|
||||||
*/
|
|
||||||
public function getAssets()
|
|
||||||
{
|
|
||||||
return $this->assets;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the string contents of the view.
|
|
||||||
*
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
public function render()
|
|
||||||
{
|
|
||||||
$view = app('view')->file(__DIR__.'/../../../views/app.blade.php');
|
|
||||||
|
|
||||||
$forum = $this->getForumDocument();
|
|
||||||
$data = $this->getDataFromDocument($forum);
|
|
||||||
|
|
||||||
if ($this->actor->exists) {
|
|
||||||
$user = $this->getUserDocument();
|
|
||||||
$data = array_merge($data, $this->getDataFromDocument($user));
|
|
||||||
}
|
|
||||||
|
|
||||||
$view->app = [
|
|
||||||
'preload' => [
|
|
||||||
'data' => $data,
|
|
||||||
'session' => $this->getSession(),
|
|
||||||
'document' => $this->document
|
|
||||||
]
|
|
||||||
] + $this->variables;
|
|
||||||
$view->bootstrappers = $this->bootstrappers;
|
|
||||||
|
|
||||||
$noJs = array_get($this->request->getQueryParams(), 'nojs');
|
|
||||||
|
|
||||||
$view->title = ($this->title ? $this->title.' - ' : '').$forum->data->attributes->title;
|
|
||||||
$view->forum = $forum->data;
|
|
||||||
$view->layout = app('view')->file($this->layout, [
|
|
||||||
'forum' => $forum->data,
|
|
||||||
'content' => app('view')->file(__DIR__.'/../../../views/content.blade.php', [
|
|
||||||
'content' => $this->content,
|
|
||||||
'noJs' => $noJs,
|
|
||||||
'forum' => $forum->data
|
|
||||||
])
|
|
||||||
]);
|
|
||||||
$view->noJs = $noJs;
|
|
||||||
|
|
||||||
$view->styles = [$this->assets->getCssFile()];
|
|
||||||
$view->scripts = [$this->assets->getJsFile()];
|
|
||||||
|
|
||||||
if ($this->localeJs) {
|
|
||||||
$view->scripts[] = $this->localeJs->getFile();
|
|
||||||
}
|
|
||||||
|
|
||||||
$view->head = implode("\n", $this->headStrings);
|
|
||||||
$view->foot = implode("\n", $this->footStrings);
|
|
||||||
|
|
||||||
return $view->render();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the string contents of the view.
|
|
||||||
*
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
public function __toString()
|
|
||||||
{
|
|
||||||
return $this->render();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the result of an API request to show the forum.
|
|
||||||
*
|
|
||||||
* @return object
|
|
||||||
*/
|
|
||||||
protected function getForumDocument()
|
|
||||||
{
|
|
||||||
return json_decode($this->api->send('Flarum\Api\Controller\ShowForumController', $this->actor)->getBody());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the result of an API request to show the current user.
|
|
||||||
*
|
|
||||||
* @return object
|
|
||||||
*/
|
|
||||||
protected function getUserDocument()
|
|
||||||
{
|
|
||||||
// TODO: calling on the API here results in an extra query to get
|
|
||||||
// the user + their groups, when we already have this information on
|
|
||||||
// $this->actor. Can we simply run the CurrentUserSerializer
|
|
||||||
// manually? Or can we somehow inject this data into the ShowDiscussionController?
|
|
||||||
$document = json_decode($this->api->send(
|
|
||||||
'Flarum\Api\Controller\ShowUserController',
|
|
||||||
$this->actor,
|
|
||||||
['id' => $this->actor->id]
|
|
||||||
)->getBody());
|
|
||||||
|
|
||||||
return $document;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get an array of data by merging the 'data' and 'included' keys of a
|
|
||||||
* JSON-API document.
|
|
||||||
*
|
|
||||||
* @param object $document
|
|
||||||
* @return array
|
|
||||||
*/
|
|
||||||
protected function getDataFromDocument($document)
|
|
||||||
{
|
|
||||||
$data[] = $document->data;
|
|
||||||
|
|
||||||
if (isset($document->included)) {
|
|
||||||
$data = array_merge($data, $document->included);
|
|
||||||
}
|
|
||||||
|
|
||||||
return $data;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get information about the current session.
|
|
||||||
*
|
|
||||||
* @return array
|
|
||||||
*/
|
|
||||||
protected function getSession()
|
|
||||||
{
|
|
||||||
$session = $this->request->getAttribute('session');
|
|
||||||
|
|
||||||
return [
|
|
||||||
'userId' => $this->actor->id,
|
|
||||||
'csrfToken' => $session->get('csrf_token')
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return User
|
|
||||||
*/
|
|
||||||
public function getActor()
|
|
||||||
{
|
|
||||||
return $this->actor;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return Request
|
|
||||||
*/
|
|
||||||
public function getRequest()
|
|
||||||
{
|
|
||||||
return $this->request;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,41 +0,0 @@
|
|||||||
<?php
|
|
||||||
/*
|
|
||||||
* This file is part of Flarum.
|
|
||||||
*
|
|
||||||
* (c) Toby Zerner <toby.zerner@gmail.com>
|
|
||||||
*
|
|
||||||
* For the full copyright and license information, please view the LICENSE
|
|
||||||
* file that was distributed with this source code.
|
|
||||||
*/
|
|
||||||
|
|
||||||
namespace Flarum\Http;
|
|
||||||
|
|
||||||
use Flarum\Http\Controller\ControllerInterface;
|
|
||||||
use Illuminate\Contracts\Container\Container;
|
|
||||||
use InvalidArgumentException;
|
|
||||||
use Psr\Http\Message\ServerRequestInterface;
|
|
||||||
|
|
||||||
trait GenerateRouteHandlerTrait
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* @return \Closure
|
|
||||||
*/
|
|
||||||
protected function getHandlerGenerator(Container $container)
|
|
||||||
{
|
|
||||||
return function ($class) use ($container) {
|
|
||||||
return function (ServerRequestInterface $request, $routeParams) use ($class, $container) {
|
|
||||||
$controller = $container->make($class);
|
|
||||||
|
|
||||||
if (! ($controller instanceof ControllerInterface)) {
|
|
||||||
throw new InvalidArgumentException(
|
|
||||||
'Route handler must be an instance of '.ControllerInterface::class
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
$request = $request->withQueryParams(array_merge($request->getQueryParams(), $routeParams));
|
|
||||||
|
|
||||||
return $controller->handle($request);
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
71
framework/core/src/Http/Handler/ControllerRouteHandler.php
Normal file
71
framework/core/src/Http/Handler/ControllerRouteHandler.php
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
<?php
|
||||||
|
/*
|
||||||
|
* This file is part of Flarum.
|
||||||
|
*
|
||||||
|
* (c) Toby Zerner <toby.zerner@gmail.com>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Flarum\Http\Handler;
|
||||||
|
|
||||||
|
use Flarum\Http\Controller\ControllerInterface;
|
||||||
|
use Illuminate\Contracts\Container\Container;
|
||||||
|
use InvalidArgumentException;
|
||||||
|
use Psr\Http\Message\ResponseInterface;
|
||||||
|
use Psr\Http\Message\ServerRequestInterface;
|
||||||
|
|
||||||
|
class ControllerRouteHandler
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var Container
|
||||||
|
*/
|
||||||
|
protected $container;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $controller;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param Container $container
|
||||||
|
* @param string $controller
|
||||||
|
*/
|
||||||
|
public function __construct(Container $container, $controller)
|
||||||
|
{
|
||||||
|
$this->container = $container;
|
||||||
|
$this->controller = $controller;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param ServerRequestInterface $request
|
||||||
|
* @param array $routeParams
|
||||||
|
* @return ResponseInterface
|
||||||
|
*/
|
||||||
|
public function __invoke(ServerRequestInterface $request, array $routeParams)
|
||||||
|
{
|
||||||
|
$controller = $this->resolveController($this->controller);
|
||||||
|
|
||||||
|
$request = $request->withQueryParams(array_merge($request->getQueryParams(), $routeParams));
|
||||||
|
|
||||||
|
return $controller->handle($request);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $class
|
||||||
|
* @return ControllerInterface
|
||||||
|
*/
|
||||||
|
protected function resolveController($class)
|
||||||
|
{
|
||||||
|
$controller = $this->container->make($class);
|
||||||
|
|
||||||
|
if (! ($controller instanceof ControllerInterface)) {
|
||||||
|
throw new InvalidArgumentException(
|
||||||
|
'Controller must be an instance of '.ControllerInterface::class
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $controller;
|
||||||
|
}
|
||||||
|
}
|
38
framework/core/src/Http/Handler/RouteHandlerFactory.php
Normal file
38
framework/core/src/Http/Handler/RouteHandlerFactory.php
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
<?php
|
||||||
|
/*
|
||||||
|
* This file is part of Flarum.
|
||||||
|
*
|
||||||
|
* (c) Toby Zerner <toby.zerner@gmail.com>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Flarum\Http\Handler;
|
||||||
|
|
||||||
|
use Illuminate\Contracts\Container\Container;
|
||||||
|
|
||||||
|
class RouteHandlerFactory
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var Container
|
||||||
|
*/
|
||||||
|
protected $container;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param Container $container
|
||||||
|
*/
|
||||||
|
public function __construct(Container $container)
|
||||||
|
{
|
||||||
|
$this->container = $container;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $controller
|
||||||
|
* @return ControllerRouteHandler
|
||||||
|
*/
|
||||||
|
public function toController($controller)
|
||||||
|
{
|
||||||
|
return new ControllerRouteHandler($this->container, $controller);
|
||||||
|
}
|
||||||
|
}
|
188
framework/core/src/Http/WebApp/AbstractWebApp.php
Normal file
188
framework/core/src/Http/WebApp/AbstractWebApp.php
Normal file
@ -0,0 +1,188 @@
|
|||||||
|
<?php
|
||||||
|
/*
|
||||||
|
* This file is part of Flarum.
|
||||||
|
*
|
||||||
|
* (c) Toby Zerner <toby.zerner@gmail.com>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Flarum\Http\WebApp;
|
||||||
|
|
||||||
|
use Flarum\Http\Controller;
|
||||||
|
use Flarum\Locale\LocaleManager;
|
||||||
|
use Flarum\Settings\SettingsRepositoryInterface;
|
||||||
|
|
||||||
|
abstract class AbstractWebApp
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var WebAppAssetsFactory
|
||||||
|
*/
|
||||||
|
protected $assets;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var WebAppViewFactory
|
||||||
|
*/
|
||||||
|
protected $view;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var SettingsRepositoryInterface
|
||||||
|
*/
|
||||||
|
protected $settings;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var LocaleManager
|
||||||
|
*/
|
||||||
|
protected $locales;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param WebAppAssetsFactory $assets
|
||||||
|
* @param WebAppViewFactory $view
|
||||||
|
* @param SettingsRepositoryInterface $settings
|
||||||
|
* @param LocaleManager $locales
|
||||||
|
*/
|
||||||
|
public function __construct(WebAppAssetsFactory $assets, WebAppViewFactory $view, SettingsRepositoryInterface $settings, LocaleManager $locales)
|
||||||
|
{
|
||||||
|
$this->assets = $assets;
|
||||||
|
$this->view = $view;
|
||||||
|
$this->settings = $settings;
|
||||||
|
$this->locales = $locales;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return WebAppView
|
||||||
|
*/
|
||||||
|
public function getView()
|
||||||
|
{
|
||||||
|
$view = $this->view->make($this->getLayout(), $this->getAssets());
|
||||||
|
|
||||||
|
$this->addDefaultAssets($view);
|
||||||
|
$this->addCustomLess($view);
|
||||||
|
$this->addTranslations($view);
|
||||||
|
|
||||||
|
return $view;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return WebAppAssets
|
||||||
|
*/
|
||||||
|
public function getAssets()
|
||||||
|
{
|
||||||
|
return $this->assets->make($this->getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the name of the client.
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
abstract protected function getName();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the path to the client layout view.
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
protected function getLayout()
|
||||||
|
{
|
||||||
|
return __DIR__.'/../../../views/'.$this->getName().'.blade.php';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a regular expression to match against translation keys.
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
protected function getTranslationFilter()
|
||||||
|
{
|
||||||
|
return '/^[^\.]+\.(?:'.$this->getName().'|lib)\./';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param WebAppView $view
|
||||||
|
*/
|
||||||
|
private function addDefaultAssets(WebAppView $view)
|
||||||
|
{
|
||||||
|
$root = __DIR__.'/../../..';
|
||||||
|
$name = $this->getName();
|
||||||
|
|
||||||
|
$view->getJs()->addFile("$root/js/$name/dist/app.js");
|
||||||
|
$view->getCss()->addFile("$root/less/$name/app.less");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param WebAppView $view
|
||||||
|
*/
|
||||||
|
private function addCustomLess(WebAppView $view)
|
||||||
|
{
|
||||||
|
$css = $view->getCss();
|
||||||
|
$localeCss = $view->getLocaleCss();
|
||||||
|
|
||||||
|
$lessVariables = function () {
|
||||||
|
$less = '';
|
||||||
|
|
||||||
|
foreach ($this->getLessVariables() as $name => $value) {
|
||||||
|
$less .= "@$name: $value;";
|
||||||
|
}
|
||||||
|
|
||||||
|
return $less;
|
||||||
|
};
|
||||||
|
|
||||||
|
$css->addString($lessVariables);
|
||||||
|
$localeCss->addString($lessVariables);
|
||||||
|
|
||||||
|
$css->addString(function () {
|
||||||
|
return $this->settings->get('custom_less');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the values of any LESS variables to compile into the CSS, based on
|
||||||
|
* the forum's configuration.
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
private function getLessVariables()
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'config-primary-color' => $this->settings->get('theme_primary_color') ?: '#000',
|
||||||
|
'config-secondary-color' => $this->settings->get('theme_secondary_color') ?: '#000',
|
||||||
|
'config-dark-mode' => $this->settings->get('theme_dark_mode') ? 'true' : 'false',
|
||||||
|
'config-colored-header' => $this->settings->get('theme_colored_header') ? 'true' : 'false'
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param WebAppView $view
|
||||||
|
*/
|
||||||
|
private function addTranslations(WebAppView $view)
|
||||||
|
{
|
||||||
|
$translations = array_get($this->locales->getTranslator()->getMessages(), 'messages', []);
|
||||||
|
|
||||||
|
$translations = $this->filterTranslations($translations);
|
||||||
|
|
||||||
|
$view->getLocaleJs()->setTranslations($translations);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Take a selection of keys from a collection of translations.
|
||||||
|
*
|
||||||
|
* @param array $translations
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
private function filterTranslations(array $translations)
|
||||||
|
{
|
||||||
|
$filter = $this->getTranslationFilter();
|
||||||
|
|
||||||
|
if (! $filter) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
$filtered = array_filter(array_keys($translations), function ($id) use ($filter) {
|
||||||
|
return preg_match($filter, $id);
|
||||||
|
});
|
||||||
|
|
||||||
|
return array_only($translations, $filtered);
|
||||||
|
}
|
||||||
|
}
|
164
framework/core/src/Http/WebApp/WebAppAssets.php
Normal file
164
framework/core/src/Http/WebApp/WebAppAssets.php
Normal file
@ -0,0 +1,164 @@
|
|||||||
|
<?php
|
||||||
|
/*
|
||||||
|
* This file is part of Flarum.
|
||||||
|
*
|
||||||
|
* (c) Toby Zerner <toby.zerner@gmail.com>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Flarum\Http\WebApp;
|
||||||
|
|
||||||
|
use Flarum\Asset\JsCompiler;
|
||||||
|
use Flarum\Asset\LessCompiler;
|
||||||
|
use Flarum\Foundation\Application;
|
||||||
|
use Flarum\Locale\JsCompiler as LocaleJsCompiler;
|
||||||
|
use Flarum\Locale\LocaleManager;
|
||||||
|
use Illuminate\Contracts\Cache\Repository;
|
||||||
|
|
||||||
|
class WebAppAssets
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $name;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var Application
|
||||||
|
*/
|
||||||
|
protected $app;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var Repository
|
||||||
|
*/
|
||||||
|
protected $cache;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var LocaleManager
|
||||||
|
*/
|
||||||
|
protected $locales;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $name
|
||||||
|
* @param Application $app
|
||||||
|
* @param Repository $cache
|
||||||
|
* @param LocaleManager $locales
|
||||||
|
*/
|
||||||
|
public function __construct($name, Application $app, Repository $cache, LocaleManager $locales)
|
||||||
|
{
|
||||||
|
$this->name = $name;
|
||||||
|
$this->app = $app;
|
||||||
|
$this->cache = $cache;
|
||||||
|
$this->locales = $locales;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function flush()
|
||||||
|
{
|
||||||
|
$this->flushJs();
|
||||||
|
$this->flushCss();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function flushJs()
|
||||||
|
{
|
||||||
|
$this->getJs()->flush();
|
||||||
|
$this->flushLocaleJs();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function flushLocaleJs()
|
||||||
|
{
|
||||||
|
foreach ($this->locales->getLocales() as $locale => $info) {
|
||||||
|
$this->getLocaleJs($locale)->flush();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function flushCss()
|
||||||
|
{
|
||||||
|
$this->getCss()->flush();
|
||||||
|
$this->flushLocaleCss();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function flushLocaleCss()
|
||||||
|
{
|
||||||
|
foreach ($this->locales->getLocales() as $locale => $info) {
|
||||||
|
$this->getLocaleCss($locale)->flush();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return JsCompiler
|
||||||
|
*/
|
||||||
|
public function getJs()
|
||||||
|
{
|
||||||
|
return new JsCompiler(
|
||||||
|
$this->getDestination(),
|
||||||
|
"$this->name.js",
|
||||||
|
$this->shouldWatch(),
|
||||||
|
$this->cache
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return LessCompiler
|
||||||
|
*/
|
||||||
|
public function getCss()
|
||||||
|
{
|
||||||
|
return new LessCompiler(
|
||||||
|
$this->getDestination(),
|
||||||
|
"$this->name.css",
|
||||||
|
$this->shouldWatch(),
|
||||||
|
$this->getLessStorage()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param $locale
|
||||||
|
* @return LocaleJsCompiler
|
||||||
|
*/
|
||||||
|
public function getLocaleJs($locale)
|
||||||
|
{
|
||||||
|
return new LocaleJsCompiler(
|
||||||
|
$this->getDestination(),
|
||||||
|
"$this->name-$locale.js",
|
||||||
|
$this->shouldWatch(),
|
||||||
|
$this->cache
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param $locale
|
||||||
|
* @return LessCompiler
|
||||||
|
*/
|
||||||
|
public function getLocaleCss($locale)
|
||||||
|
{
|
||||||
|
return new LessCompiler(
|
||||||
|
$this->getDestination(),
|
||||||
|
"$this->name-$locale.css",
|
||||||
|
$this->shouldWatch(),
|
||||||
|
$this->getLessStorage()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function getDestination()
|
||||||
|
{
|
||||||
|
return $this->app->publicPath().'/assets';
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function shouldWatch()
|
||||||
|
{
|
||||||
|
return $this->app->config('debug');
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function getLessStorage()
|
||||||
|
{
|
||||||
|
return $this->app->storagePath().'/less';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $name
|
||||||
|
*/
|
||||||
|
public function setName($name)
|
||||||
|
{
|
||||||
|
$this->name = $name;
|
||||||
|
}
|
||||||
|
}
|
54
framework/core/src/Http/WebApp/WebAppAssetsFactory.php
Normal file
54
framework/core/src/Http/WebApp/WebAppAssetsFactory.php
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
<?php
|
||||||
|
/*
|
||||||
|
* This file is part of Flarum.
|
||||||
|
*
|
||||||
|
* (c) Toby Zerner <toby.zerner@gmail.com>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Flarum\Http\WebApp;
|
||||||
|
|
||||||
|
use Flarum\Foundation\Application;
|
||||||
|
use Flarum\Locale\LocaleManager;
|
||||||
|
use Illuminate\Contracts\Cache\Repository;
|
||||||
|
|
||||||
|
class WebAppAssetsFactory
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var Application
|
||||||
|
*/
|
||||||
|
protected $app;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var Repository
|
||||||
|
*/
|
||||||
|
protected $cache;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var LocaleManager
|
||||||
|
*/
|
||||||
|
protected $locales;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param Application $app
|
||||||
|
* @param Repository $cache
|
||||||
|
* @param LocaleManager $locales
|
||||||
|
*/
|
||||||
|
public function __construct(Application $app, Repository $cache, LocaleManager $locales)
|
||||||
|
{
|
||||||
|
$this->app = $app;
|
||||||
|
$this->cache = $cache;
|
||||||
|
$this->locales = $locales;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $name
|
||||||
|
* @return WebAppAssets
|
||||||
|
*/
|
||||||
|
public function make($name)
|
||||||
|
{
|
||||||
|
return new WebAppAssets($name, $this->app, $this->cache, $this->locales);
|
||||||
|
}
|
||||||
|
}
|
446
framework/core/src/Http/WebApp/WebAppView.php
Normal file
446
framework/core/src/Http/WebApp/WebAppView.php
Normal file
@ -0,0 +1,446 @@
|
|||||||
|
<?php
|
||||||
|
/*
|
||||||
|
* This file is part of Flarum.
|
||||||
|
*
|
||||||
|
* (c) Toby Zerner <toby.zerner@gmail.com>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Flarum\Http\WebApp;
|
||||||
|
|
||||||
|
use Flarum\Api\Client;
|
||||||
|
use Flarum\Api\Serializer\AbstractSerializer;
|
||||||
|
use Flarum\Api\Serializer\CurrentUserSerializer;
|
||||||
|
use Flarum\Asset\CompilerInterface;
|
||||||
|
use Flarum\Core\Exception\ValidationException;
|
||||||
|
use Flarum\Core\User;
|
||||||
|
use Flarum\Locale\JsCompiler;
|
||||||
|
use Flarum\Locale\LocaleManager;
|
||||||
|
use Illuminate\View\Factory;
|
||||||
|
use Psr\Http\Message\ServerRequestInterface as Request;
|
||||||
|
use Tobscure\JsonApi\Document;
|
||||||
|
use Tobscure\JsonApi\Resource;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class represents a view which boots up Flarum's client.
|
||||||
|
*/
|
||||||
|
class WebAppView
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* The title of the document, displayed in the <title> tag.
|
||||||
|
*
|
||||||
|
* @var null|string
|
||||||
|
*/
|
||||||
|
protected $title;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The description of the document, displayed in a <meta> tag.
|
||||||
|
*
|
||||||
|
* @var null|string
|
||||||
|
*/
|
||||||
|
protected $description;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The path to the client layout view to display.
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $layout;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The SEO content of the page, displayed within the layout in <noscript>
|
||||||
|
* tags.
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $content;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An API response to be preloaded into the page.
|
||||||
|
*
|
||||||
|
* @var null|array|object
|
||||||
|
*/
|
||||||
|
protected $document;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Other variables to preload into the page.
|
||||||
|
*
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
protected $variables = [];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An array of JS modules to load before booting the app.
|
||||||
|
*
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
protected $modules = ['locale'];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An array of strings to append to the page's <head>.
|
||||||
|
*
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
protected $head = [];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An array of strings to prepend before the page's </body>.
|
||||||
|
*
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
protected $foot = [];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var CompilerInterface
|
||||||
|
*/
|
||||||
|
protected $js;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var CompilerInterface
|
||||||
|
*/
|
||||||
|
protected $css;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var CompilerInterface
|
||||||
|
*/
|
||||||
|
protected $localeJs;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var CompilerInterface
|
||||||
|
*/
|
||||||
|
protected $localeCss;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var ClientAssets
|
||||||
|
*/
|
||||||
|
protected $assets;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var Client
|
||||||
|
*/
|
||||||
|
protected $api;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var Factory
|
||||||
|
*/
|
||||||
|
protected $view;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var LocaleManager
|
||||||
|
*/
|
||||||
|
protected $locales;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var AbstractSerializer
|
||||||
|
*/
|
||||||
|
protected $userSerializer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $layout
|
||||||
|
* @param ClientAssets $assets
|
||||||
|
* @param Client $api
|
||||||
|
* @param Factory $view
|
||||||
|
* @param LocaleManager $locales
|
||||||
|
* @param AbstractSerializer $userSerializer
|
||||||
|
*/
|
||||||
|
public function __construct($layout, WebAppAssets $assets, Client $api, Factory $view, LocaleManager $locales, AbstractSerializer $userSerializer)
|
||||||
|
{
|
||||||
|
$this->layout = $layout;
|
||||||
|
$this->api = $api;
|
||||||
|
$this->assets = $assets;
|
||||||
|
$this->view = $view;
|
||||||
|
$this->locales = $locales;
|
||||||
|
$this->userSerializer = $userSerializer;
|
||||||
|
|
||||||
|
$this->addHeadString('<link rel="stylesheet" href="//fonts.googleapis.com/css?family=Open+Sans:400italic,700italic,400,700,600">', 'font');
|
||||||
|
|
||||||
|
$this->js = $this->assets->getJs();
|
||||||
|
$this->css = $this->assets->getCss();
|
||||||
|
|
||||||
|
$locale = $this->locales->getLocale();
|
||||||
|
$this->localeJs = $this->assets->getLocaleJs($locale);
|
||||||
|
$this->localeCss = $this->assets->getLocaleCss($locale);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The title of the document, to be displayed in the <title> tag.
|
||||||
|
*
|
||||||
|
* @param null|string $title
|
||||||
|
*/
|
||||||
|
public function setTitle($title)
|
||||||
|
{
|
||||||
|
$this->title = $title;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the SEO content of the page, to be displayed in <noscript> tags.
|
||||||
|
*
|
||||||
|
* @param null|string $content
|
||||||
|
*/
|
||||||
|
public function setContent($content)
|
||||||
|
{
|
||||||
|
$this->content = $content;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the name of the client layout view to display.
|
||||||
|
*
|
||||||
|
* @param string $layout
|
||||||
|
*/
|
||||||
|
public function setLayout($layout)
|
||||||
|
{
|
||||||
|
$this->layout = $layout;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a string to be appended to the page's <head>.
|
||||||
|
*
|
||||||
|
* @param string $string
|
||||||
|
* @param null|string $name
|
||||||
|
*/
|
||||||
|
public function addHeadString($string, $name = null)
|
||||||
|
{
|
||||||
|
if ($name) {
|
||||||
|
$this->head[$name] = $string;
|
||||||
|
} else {
|
||||||
|
$this->head[] = $string;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a string to be prepended before the page's </body>.
|
||||||
|
*
|
||||||
|
* @param string $string
|
||||||
|
*/
|
||||||
|
public function addFootString($string)
|
||||||
|
{
|
||||||
|
$this->foot[] = $string;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set an API response to be preloaded into the page. This should be a
|
||||||
|
* JSON-API document.
|
||||||
|
*
|
||||||
|
* @param null|array|object $document
|
||||||
|
*/
|
||||||
|
public function setDocument($document)
|
||||||
|
{
|
||||||
|
$this->document = $document;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set a variable to be preloaded into the app.
|
||||||
|
*
|
||||||
|
* @param string $name
|
||||||
|
* @param mixed $value
|
||||||
|
*/
|
||||||
|
public function setVariable($name, $value)
|
||||||
|
{
|
||||||
|
$this->variables[$name] = $value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a JavaScript module to be imported before the app is booted.
|
||||||
|
*
|
||||||
|
* @param string $module
|
||||||
|
*/
|
||||||
|
public function loadModule($module)
|
||||||
|
{
|
||||||
|
$this->modules[] = $module;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the string contents of the view.
|
||||||
|
*
|
||||||
|
* @param Request $request
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function render(Request $request)
|
||||||
|
{
|
||||||
|
$forum = $this->getForumDocument($request);
|
||||||
|
|
||||||
|
$this->view->share('translator', $this->locales->getTranslator());
|
||||||
|
$this->view->share('allowJs', ! array_get($request->getQueryParams(), 'nojs'));
|
||||||
|
$this->view->share('forum', array_get($forum, 'data'));
|
||||||
|
$this->view->share('debug', array_get($forum, 'data.attributes.debug'));
|
||||||
|
|
||||||
|
$view = $this->view->file(__DIR__.'/../../../views/app.blade.php');
|
||||||
|
|
||||||
|
$view->title = $this->buildTitle(array_get($forum, 'data.attributes.title'));
|
||||||
|
$view->description = $this->description;
|
||||||
|
|
||||||
|
$view->modules = $this->modules;
|
||||||
|
$view->payload = $this->buildPayload($request, $forum);
|
||||||
|
|
||||||
|
$view->layout = $this->buildLayout();
|
||||||
|
|
||||||
|
$baseUrl = array_get($forum, 'data.attributes.baseUrl');
|
||||||
|
$view->cssUrls = $this->buildCssUrls($baseUrl);
|
||||||
|
$view->jsUrls = $this->buildJsUrls($baseUrl);
|
||||||
|
|
||||||
|
$view->head = implode("\n", $this->head);
|
||||||
|
$view->foot = implode("\n", $this->foot);
|
||||||
|
|
||||||
|
return $view->render();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function buildTitle($forumTitle)
|
||||||
|
{
|
||||||
|
return ($this->title ? $this->title.' - ' : '').$forumTitle;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function buildPayload(Request $request, $forum)
|
||||||
|
{
|
||||||
|
$data = $this->getDataFromDocument($forum);
|
||||||
|
|
||||||
|
if ($request->getAttribute('actor')->exists) {
|
||||||
|
$user = $this->getUserDocument($request);
|
||||||
|
$data = array_merge($data, $this->getDataFromDocument($user));
|
||||||
|
}
|
||||||
|
|
||||||
|
$payload = [
|
||||||
|
'resources' => $data,
|
||||||
|
'session' => $this->buildSession($request),
|
||||||
|
'document' => $this->document,
|
||||||
|
'locales' => $this->locales->getLocales(),
|
||||||
|
'locale' => $this->locales->getLocale()
|
||||||
|
];
|
||||||
|
|
||||||
|
return array_merge($payload, $this->variables);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function buildLayout()
|
||||||
|
{
|
||||||
|
$view = $this->view->file($this->layout);
|
||||||
|
|
||||||
|
$view->content = $this->buildContent();
|
||||||
|
|
||||||
|
return $view;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function buildContent()
|
||||||
|
{
|
||||||
|
$view = $this->view->file(__DIR__.'/../../../views/content.blade.php');
|
||||||
|
|
||||||
|
$view->content = $this->content;
|
||||||
|
|
||||||
|
return $view;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function buildCssUrls($baseUrl)
|
||||||
|
{
|
||||||
|
return $this->buildAssetUrls($baseUrl, [$this->css->getFile(), $this->localeCss->getFile()]);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function buildJsUrls($baseUrl)
|
||||||
|
{
|
||||||
|
return $this->buildAssetUrls($baseUrl, [$this->js->getFile(), $this->localeJs->getFile()]);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function buildAssetUrls($baseUrl, $files)
|
||||||
|
{
|
||||||
|
return array_map(function ($file) use ($baseUrl) {
|
||||||
|
return $baseUrl.str_replace(public_path(), '', $file);
|
||||||
|
}, $files);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return CompilerInterface
|
||||||
|
*/
|
||||||
|
public function getJs()
|
||||||
|
{
|
||||||
|
return $this->js;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return CompilerInterface
|
||||||
|
*/
|
||||||
|
public function getCss()
|
||||||
|
{
|
||||||
|
return $this->css;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return JsCompiler
|
||||||
|
*/
|
||||||
|
public function getLocaleJs()
|
||||||
|
{
|
||||||
|
return $this->localeJs;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return CompilerInterface
|
||||||
|
*/
|
||||||
|
public function getLocaleCss()
|
||||||
|
{
|
||||||
|
return $this->localeCss;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the result of an API request to show the forum.
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
protected function getForumDocument(Request $request)
|
||||||
|
{
|
||||||
|
$actor = $request->getAttribute('actor');
|
||||||
|
|
||||||
|
$response = $this->api->send('Flarum\Api\Controller\ShowForumController', $actor);
|
||||||
|
|
||||||
|
return json_decode($response->getBody(), true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the result of an API request to show the current user.
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
protected function getUserDocument(Request $request)
|
||||||
|
{
|
||||||
|
$actor = $request->getAttribute('actor');
|
||||||
|
|
||||||
|
$this->userSerializer->setActor($actor);
|
||||||
|
|
||||||
|
$resource = new Resource($actor, $this->userSerializer);
|
||||||
|
|
||||||
|
$document = new Document($resource->with('groups'));
|
||||||
|
|
||||||
|
return $document->toArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get information about the current session.
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
protected function buildSession(Request $request)
|
||||||
|
{
|
||||||
|
$actor = $request->getAttribute('actor');
|
||||||
|
$session = $request->getAttribute('session');
|
||||||
|
|
||||||
|
return [
|
||||||
|
'userId' => $actor->id,
|
||||||
|
'csrfToken' => $session->get('csrf_token')
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get an array of data by merging the 'data' and 'included' keys of a
|
||||||
|
* JSON-API document.
|
||||||
|
*
|
||||||
|
* @param array $document
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
private function getDataFromDocument(array $document)
|
||||||
|
{
|
||||||
|
$data[] = $document['data'];
|
||||||
|
|
||||||
|
if (isset($document['included'])) {
|
||||||
|
$data = array_merge($data, $document['included']);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $data;
|
||||||
|
}
|
||||||
|
}
|
63
framework/core/src/Http/WebApp/WebAppViewFactory.php
Normal file
63
framework/core/src/Http/WebApp/WebAppViewFactory.php
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
<?php
|
||||||
|
/*
|
||||||
|
* This file is part of Flarum.
|
||||||
|
*
|
||||||
|
* (c) Toby Zerner <toby.zerner@gmail.com>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Flarum\Http\WebApp;
|
||||||
|
|
||||||
|
use Flarum\Api\Client;
|
||||||
|
use Flarum\Api\Serializer\CurrentUserSerializer;
|
||||||
|
use Flarum\Locale\LocaleManager;
|
||||||
|
use Illuminate\Contracts\View\Factory;
|
||||||
|
|
||||||
|
class WebAppViewFactory
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var Client
|
||||||
|
*/
|
||||||
|
protected $api;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var Factory
|
||||||
|
*/
|
||||||
|
protected $view;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var LocaleManager
|
||||||
|
*/
|
||||||
|
protected $locales;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var CurrentUserSerializer
|
||||||
|
*/
|
||||||
|
protected $userSerializer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param Client $api
|
||||||
|
* @param Factory $view
|
||||||
|
* @param LocaleManager $locales
|
||||||
|
* @param CurrentUserSerializer $userSerializer
|
||||||
|
*/
|
||||||
|
public function __construct(Client $api, Factory $view, LocaleManager $locales, CurrentUserSerializer $userSerializer)
|
||||||
|
{
|
||||||
|
$this->api = $api;
|
||||||
|
$this->view = $view;
|
||||||
|
$this->locales = $locales;
|
||||||
|
$this->userSerializer = $userSerializer;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $layout
|
||||||
|
* @param WebAppAssets $assets
|
||||||
|
* @return WebAppView
|
||||||
|
*/
|
||||||
|
public function make($layout, WebAppAssets $assets)
|
||||||
|
{
|
||||||
|
return new WebAppView($layout, $assets, $this->api, $this->view, $this->locales, $this->userSerializer);
|
||||||
|
}
|
||||||
|
}
|
@ -23,16 +23,20 @@ class JsCompiler extends BaseJsCompiler
|
|||||||
|
|
||||||
public function compile()
|
public function compile()
|
||||||
{
|
{
|
||||||
$output = "System.register('locale', [], function() {
|
$output = "
|
||||||
|
System.register('locale', [], function(_export) {
|
||||||
return {
|
return {
|
||||||
execute: function() {
|
execute: function() {
|
||||||
|
_export('default', function(app) {
|
||||||
app.translator.translations = ".json_encode($this->translations).";\n";
|
app.translator.translations = ".json_encode($this->translations).";\n";
|
||||||
|
|
||||||
foreach ($this->files as $filename) {
|
foreach ($this->files as $filename) {
|
||||||
$output .= file_get_contents($filename);
|
$output .= file_get_contents($filename);
|
||||||
}
|
}
|
||||||
|
|
||||||
$output .= '}
|
$output .= '
|
||||||
|
});
|
||||||
|
}
|
||||||
};
|
};
|
||||||
});';
|
});';
|
||||||
|
|
||||||
|
@ -1,16 +1,16 @@
|
|||||||
<?php namespace {{namespace}}\Listener;
|
<?php namespace {{namespace}}\Listener;
|
||||||
|
|
||||||
use Flarum\Event\ConfigureClientView;
|
use Flarum\Event\ConfigureWebApp;
|
||||||
use Illuminate\Contracts\Events\Dispatcher;
|
use Illuminate\Contracts\Events\Dispatcher;
|
||||||
|
|
||||||
class AddClientAssets
|
class AddClientAssets
|
||||||
{
|
{
|
||||||
public function subscribe(Dispatcher $events)
|
public function subscribe(Dispatcher $events)
|
||||||
{
|
{
|
||||||
$events->listen(ConfigureClientView::class, [$this, 'addAssets']);
|
$events->listen(ConfigureWebApp::class, [$this, 'addAssets']);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function addAssets(ConfigureClientView $event)
|
public function addAssets(ConfigureWebApp $event)
|
||||||
{
|
{
|
||||||
if ($event->isForum()) {
|
if ($event->isForum()) {
|
||||||
$event->addAssets([
|
$event->addAssets([
|
||||||
|
@ -8,8 +8,8 @@
|
|||||||
<div id="header-navigation" class="Header-navigation"></div>
|
<div id="header-navigation" class="Header-navigation"></div>
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<h1 class="Header-title">
|
<h1 class="Header-title">
|
||||||
<a href="{{ $forum->attributes->baseUrl }}">
|
<a href="{{ array_get($forum, 'attributes.baseUrl') }}">
|
||||||
{{ $forum->attributes->title }}
|
{{ array_get($forum, 'attributes.title') }}
|
||||||
</a>
|
</a>
|
||||||
</h1>
|
</h1>
|
||||||
<div id="header-primary" class="Header-primary"></div>
|
<div id="header-primary" class="Header-primary"></div>
|
||||||
|
@ -2,14 +2,13 @@
|
|||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
|
||||||
<title>{{ $title }}</title>
|
<title>{{ $title }}</title>
|
||||||
<meta name="description" content="{{ $forum->attributes->description }}">
|
<meta name="description" content="{{ $description }}">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1">
|
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1">
|
||||||
<meta name="theme-color" content="{{ $forum->attributes->themePrimaryColor }}">
|
<meta name="theme-color" content="{{ array_get($forum, 'attributes.themePrimaryColor') }}">
|
||||||
|
|
||||||
@foreach ($styles as $file)
|
@foreach ($cssUrls as $url)
|
||||||
<link rel="stylesheet" href="{{ $forum->attributes->baseUrl . str_replace(public_path(), '', $file) }}">
|
<link rel="stylesheet" href="{{ $url }}">
|
||||||
@endforeach
|
@endforeach
|
||||||
|
|
||||||
{!! $head !!}
|
{!! $head !!}
|
||||||
@ -21,36 +20,40 @@
|
|||||||
<div id="modal"></div>
|
<div id="modal"></div>
|
||||||
<div id="alerts"></div>
|
<div id="alerts"></div>
|
||||||
|
|
||||||
@if (! $noJs)
|
@if ($allowJs)
|
||||||
<script>
|
<script>
|
||||||
document.getElementById('flarum-loading').style.display = 'block';
|
document.getElementById('flarum-loading').style.display = 'block';
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@foreach ($scripts as $file)
|
@foreach ($jsUrls as $url)
|
||||||
<script src="{{ $forum->attributes->baseUrl . str_replace(public_path(), '', $file) }}"></script>
|
<script src="{{ $url }}"></script>
|
||||||
@endforeach
|
@endforeach
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
document.getElementById('flarum-loading').style.display = 'none';
|
document.getElementById('flarum-loading').style.display = 'none';
|
||||||
@if (! $forum->attributes->debug)
|
@if (! $debug)
|
||||||
try {
|
try {
|
||||||
@endif
|
@endif
|
||||||
var app = System.get('flarum/app').default;
|
var app = System.get('flarum/app').default;
|
||||||
|
var modules = {!! json_encode($modules) !!};
|
||||||
|
|
||||||
babelHelpers.extends(app, {!! json_encode($app) !!});
|
for (var i in modules) {
|
||||||
|
var module = System.get(modules[i]);
|
||||||
|
if (module.default) module.default(app);
|
||||||
|
}
|
||||||
|
|
||||||
@foreach ($bootstrappers as $bootstrapper)
|
app.boot({!! json_encode($payload) !!});
|
||||||
System.get('{{ $bootstrapper }}');
|
@if (! $debug)
|
||||||
@endforeach
|
|
||||||
|
|
||||||
app.boot();
|
|
||||||
@if (! $forum->attributes->debug)
|
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
var nojs = window.location.search ? '&nojs=1' : '?nojs=1';
|
window.location += (window.location.search ? '&' : '?') + 'nojs=1';
|
||||||
window.location = window.location + nojs;
|
throw e;
|
||||||
}
|
}
|
||||||
@endif
|
@endif
|
||||||
</script>
|
</script>
|
||||||
|
@else
|
||||||
|
<script>
|
||||||
|
window.history.replaceState(null, null, window.location.toString().replace(/([&?]nojs=1$|nojs=1&)/, ''));
|
||||||
|
</script>
|
||||||
@endif
|
@endif
|
||||||
|
|
||||||
{!! $foot !!}
|
{!! $foot !!}
|
||||||
|
@ -2,16 +2,22 @@
|
|||||||
{{ $translator->trans('core.views.content.loading_text') }}
|
{{ $translator->trans('core.views.content.loading_text') }}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@if (! $noJs) <noscript> @endif
|
@if ($allowJs)
|
||||||
|
<noscript>
|
||||||
<div class="Alert">
|
<div class="Alert">
|
||||||
<div class="container">
|
<div class="container">
|
||||||
@if ($noJs)
|
|
||||||
{{ $translator->trans('core.views.content.load_error_message') }}
|
|
||||||
@else
|
|
||||||
{{ $translator->trans('core.views.content.javascript_disabled_message') }}
|
{{ $translator->trans('core.views.content.javascript_disabled_message') }}
|
||||||
@endif
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{!! $content !!}
|
{!! $content !!}
|
||||||
@if (! $noJs) </noscript> @endif
|
</noscript>
|
||||||
|
@else
|
||||||
|
<div class="Alert Alert--error">
|
||||||
|
<div class="container">
|
||||||
|
{{ $translator->trans('core.views.content.load_error_message') }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{!! $content !!}
|
||||||
|
@endif
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
/**
|
/**
|
||||||
* Forum Client Template
|
* Forum WebApp Template
|
||||||
*
|
*
|
||||||
* NOTE: You shouldn't edit this file directly. Your changes will be overwritten
|
* NOTE: You shouldn't edit this file directly. Your changes will be overwritten
|
||||||
* when you update Flarum. See flarum.org/docs/templates to learn how to
|
* when you update Flarum. See flarum.org/docs/templates to learn how to
|
||||||
@ -31,8 +31,8 @@
|
|||||||
<div id="header-navigation" class="Header-navigation"></div>
|
<div id="header-navigation" class="Header-navigation"></div>
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<h1 class="Header-title">
|
<h1 class="Header-title">
|
||||||
<a href="{{ $forum->attributes->baseUrl }}" id="home-link">
|
<a href="{{ array_get($forum, 'attributes.baseUrl') }}" id="home-link">
|
||||||
{{ $forum->attributes->title }}
|
{{ array_get($forum, 'attributes.title') }}
|
||||||
</a>
|
</a>
|
||||||
</h1>
|
</h1>
|
||||||
<div id="header-primary" class="Header-primary"></div>
|
<div id="header-primary" class="Header-primary"></div>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user