1
0
mirror of https://github.com/flarum/core.git synced 2025-08-17 22:01:44 +02:00

Compare commits

..

4 Commits

Author SHA1 Message Date
Alexander Skvortsov
ce01822ff6 Add console test 2021-05-05 18:48:14 -04:00
Daniël Klabbers
7708be2fe6 Update src/Console/ConsoleServiceProvider.php 2021-05-06 00:36:20 +02:00
Daniël Klabbers
bddfb5605d Update src/Console/ConsoleServiceProvider.php 2021-05-06 00:35:05 +02:00
Daniel Klabbers
a56c748ad4 Fix unavailable translator catalogue for cli use
Fixes #2836

When there's no locale cache, cli cannot translate. This re-instantiates
that cache when needed.
2021-05-05 10:57:22 +02:00
24 changed files with 142 additions and 156 deletions

6
js/dist/admin.js generated vendored

File diff suppressed because one or more lines are too long

2
js/dist/admin.js.map generated vendored

File diff suppressed because one or more lines are too long

10
js/dist/forum.js generated vendored

File diff suppressed because one or more lines are too long

2
js/dist/forum.js.map generated vendored

File diff suppressed because one or more lines are too long

58
js/package-lock.json generated
View File

@@ -15,15 +15,16 @@
"expose-loader": "^1.0.3",
"jquery": "^3.6.0",
"jquery.hotkeys": "^0.1.0",
"lodash-es": "^4.17.21",
"mithril": "^2.0.4",
"punycode": "^2.1.1",
"spin.js": "^3.1.0",
"textarea-caret": "^3.1.0",
"throttle-debounce": "^3.0.1"
"textarea-caret": "^3.1.0"
},
"devDependencies": {
"@babel/preset-typescript": "^7.13.0",
"@types/jquery": "^3.5.5",
"@types/lodash-es": "^4.17.4",
"@types/mithril": "^2.0.7",
"@types/punycode": "^2.1.0",
"@types/textarea-caret": "^3.0.0",
@@ -1497,6 +1498,21 @@
"resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.7.tgz",
"integrity": "sha512-cxWFQVseBm6O9Gbw1IWb8r6OS4OhSt3hPZLkFApLjM8TEXROBuQGLAH2i2gZpcXdLBIrpXuTDhH7Vbm1iXmNGA=="
},
"node_modules/@types/lodash": {
"version": "4.14.168",
"resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.168.tgz",
"integrity": "sha512-oVfRvqHV/V6D1yifJbVRU3TMp8OT6o6BG+U9MkwuJ3U8/CsDHvalRpsxBqivn71ztOFZBTfJMvETbqHiaNSj7Q==",
"dev": true
},
"node_modules/@types/lodash-es": {
"version": "4.17.4",
"resolved": "https://registry.npmjs.org/@types/lodash-es/-/lodash-es-4.17.4.tgz",
"integrity": "sha512-BBz79DCJbD2CVYZH67MBeHZRX++HF+5p8Mo5MzjZi64Wac39S3diedJYHZtScbRVf4DjZyN6LzA0SB0zy+HSSQ==",
"dev": true,
"dependencies": {
"@types/lodash": "*"
}
},
"node_modules/@types/mithril": {
"version": "2.0.7",
"resolved": "https://registry.npmjs.org/@types/mithril/-/mithril-2.0.7.tgz",
@@ -4653,6 +4669,11 @@
"integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==",
"dev": true
},
"node_modules/lodash-es": {
"version": "4.17.21",
"resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.21.tgz",
"integrity": "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw=="
},
"node_modules/lodash.debounce": {
"version": "4.0.8",
"resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz",
@@ -6639,14 +6660,6 @@
"resolved": "https://registry.npmjs.org/textarea-caret/-/textarea-caret-3.1.0.tgz",
"integrity": "sha512-cXAvzO9pP5CGa6NKx0WYHl+8CHKZs8byMkt3PCJBCmq2a34YA9pO1NrQET5pzeqnBjBdToF5No4rrmkDUgQC2Q=="
},
"node_modules/throttle-debounce": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/throttle-debounce/-/throttle-debounce-3.0.1.tgz",
"integrity": "sha512-dTEWWNu6JmeVXY0ZYoPuH5cRIwc0MeGbJwah9KUNYSJwommQpCzTySTpEe8Gs1J23aeWEuAobe4Ag7EHVt/LOg==",
"engines": {
"node": ">=10"
}
},
"node_modules/through2": {
"version": "2.0.5",
"resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz",
@@ -8872,6 +8885,21 @@
"resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.7.tgz",
"integrity": "sha512-cxWFQVseBm6O9Gbw1IWb8r6OS4OhSt3hPZLkFApLjM8TEXROBuQGLAH2i2gZpcXdLBIrpXuTDhH7Vbm1iXmNGA=="
},
"@types/lodash": {
"version": "4.14.168",
"resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.168.tgz",
"integrity": "sha512-oVfRvqHV/V6D1yifJbVRU3TMp8OT6o6BG+U9MkwuJ3U8/CsDHvalRpsxBqivn71ztOFZBTfJMvETbqHiaNSj7Q==",
"dev": true
},
"@types/lodash-es": {
"version": "4.17.4",
"resolved": "https://registry.npmjs.org/@types/lodash-es/-/lodash-es-4.17.4.tgz",
"integrity": "sha512-BBz79DCJbD2CVYZH67MBeHZRX++HF+5p8Mo5MzjZi64Wac39S3diedJYHZtScbRVf4DjZyN6LzA0SB0zy+HSSQ==",
"dev": true,
"requires": {
"@types/lodash": "*"
}
},
"@types/mithril": {
"version": "2.0.7",
"resolved": "https://registry.npmjs.org/@types/mithril/-/mithril-2.0.7.tgz",
@@ -11371,6 +11399,11 @@
"integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==",
"dev": true
},
"lodash-es": {
"version": "4.17.21",
"resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.21.tgz",
"integrity": "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw=="
},
"lodash.debounce": {
"version": "4.0.8",
"resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz",
@@ -12983,11 +13016,6 @@
"resolved": "https://registry.npmjs.org/textarea-caret/-/textarea-caret-3.1.0.tgz",
"integrity": "sha512-cXAvzO9pP5CGa6NKx0WYHl+8CHKZs8byMkt3PCJBCmq2a34YA9pO1NrQET5pzeqnBjBdToF5No4rrmkDUgQC2Q=="
},
"throttle-debounce": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/throttle-debounce/-/throttle-debounce-3.0.1.tgz",
"integrity": "sha512-dTEWWNu6JmeVXY0ZYoPuH5cRIwc0MeGbJwah9KUNYSJwommQpCzTySTpEe8Gs1J23aeWEuAobe4Ag7EHVt/LOg=="
},
"through2": {
"version": "2.0.5",
"resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz",

View File

@@ -8,30 +8,31 @@
"clsx": "^1.1.1",
"color-thief-browser": "^2.0.2",
"dayjs": "^1.10.4",
"expose-loader": "^2.0.0",
"expose-loader": "^1.0.3",
"jquery": "^3.6.0",
"jquery.hotkeys": "^0.1.0",
"lodash-es": "^4.17.21",
"mithril": "^2.0.4",
"punycode": "^2.1.1",
"spin.js": "^3.1.0",
"textarea-caret": "^3.1.0",
"throttle-debounce": "^3.0.1"
"textarea-caret": "^3.1.0"
},
"devDependencies": {
"@babel/preset-typescript": "^7.13.0",
"@types/jquery": "^3.5.5",
"@types/lodash-es": "^4.17.4",
"@types/mithril": "^2.0.7",
"@types/punycode": "^2.1.0",
"@types/textarea-caret": "^3.0.0",
"bundlewatch": "^0.3.2",
"cross-env": "^7.0.3",
"flarum-webpack-config": "^1.0.0",
"flarum-webpack-config": "0.1.0-beta.10",
"husky": "^4.3.8",
"prettier": "^2.2.1",
"webpack": "^5.0.0",
"webpack-bundle-analyzer": "^4.4.1",
"webpack-cli": "^4.0.0",
"webpack-merge": "^4.0.0"
"webpack": "^4.46.0",
"webpack-bundle-analyzer": "^4.4.0",
"webpack-cli": "^3.3.12",
"webpack-merge": "^4.2.2"
},
"scripts": {
"dev": "webpack --mode development --watch",

View File

@@ -100,6 +100,8 @@ export default class AdminPage extends Page {
const { setting, help, ...componentAttrs } = entry;
delete componentAttrs.help;
const value = this.setting([setting])();
if (['bool', 'checkbox', 'switch', 'boolean'].includes(componentAttrs.type)) {
return (

View File

@@ -12,7 +12,6 @@ import mapRoutes from './utils/mapRoutes';
import RequestError from './utils/RequestError';
import ScrollListener from './utils/ScrollListener';
import liveHumanTimes from './utils/liveHumanTimes';
import patchMithril from './utils/patchMithril';
import { extend } from './extend';
import Forum from './models/Forum';
@@ -21,6 +20,7 @@ import Discussion from './models/Discussion';
import Post from './models/Post';
import Group from './models/Group';
import Notification from './models/Notification';
import { flattenDeep } from 'lodash-es';
import PageState from './states/PageState';
import ModalManagerState from './states/ModalManagerState';
import AlertManagerState from './states/AlertManagerState';
@@ -167,8 +167,6 @@ export default class Application {
}
boot() {
patchMithril(window);
this.initializers.toArray().forEach((initializer) => initializer(this));
this.store.pushPayload({ data: this.data.resources });
@@ -182,15 +180,11 @@ export default class Application {
this.initialRoute = window.location.href;
}
// TODO: This entire system needs a do-over for v2
bootExtensions(extensions) {
Object.keys(extensions).forEach((name) => {
const extension = extensions[name];
// If an extension doesn't define extenders, there's nothing more to do here.
if (!extension.extend) return;
const extenders = extension.extend.flat(Infinity);
const extenders = flattenDeep(extension.extend);
for (const extender of extenders) {
extender.extend(this, { name, exports: extension });

View File

@@ -1,60 +0,0 @@
interface ExportRegistry {
moduleExports: object;
onLoads: object;
/**
* Add an instance to the registry.
* This serves as the equivalent of `flarum.core.compat[id] = object`
*/
add(namespace: string, id: string, object: any): void;
/**
* Add a function to run when object of id "id" is added (or overriden).
* If such an object is already registered, the handler will be applied immediately.
*/
onLoad(namespace: string, id: string, handler: Function): void;
/**
* Retrieve an object of type `id` from the registry.
*/
get(namespace: string, id: string): any;
}
export default class FlarumRegistry implements ExportRegistry {
moduleExports = new Map<string, any>();
onLoads = new Map<string, Function[]>();
protected genKey(namespace: string, id: string): string {
return `${namespace};${id}`;
}
add(namespace: string, id: string, object: any) {
const key = this.genKey(namespace, id);
const onLoads = this.onLoads.get(key);
if (onLoads) {
onLoads.reduce((acc, handler) => handler(acc), object);
}
this.moduleExports.set(key, object);
}
onLoad(namespace: string, id: string, handler: Function) {
const key = this.genKey(namespace, id);
const loadedObject = this.moduleExports.get(key);
if (loadedObject) {
this.moduleExports[id] = handler(loadedObject);
} else {
const currOnLoads = this.onLoads.get(key);
this.onLoads.set(key, [...(currOnLoads || []), handler]);
}
}
get(namespace: string, id: string): any {
const key = this.genKey(namespace, id);
return this.moduleExports.get(key);
}
}

View File

@@ -12,9 +12,7 @@ import Drawer from './utils/Drawer';
import anchorScroll from './utils/anchorScroll';
import RequestError from './utils/RequestError';
import abbreviateNumber from './utils/abbreviateNumber';
import escapeRegExp from './utils/escapeRegExp';
import * as string from './utils/string';
import * as ThrottleDebounce from './utils/throttleDebounce';
import Stream from './utils/Stream';
import SubtreeRetainer from './utils/SubtreeRetainer';
import setRouteWithForcedRefresh from './utils/setRouteWithForcedRefresh';
@@ -93,7 +91,6 @@ export default {
'utils/abbreviateNumber': abbreviateNumber,
'utils/string': string,
'utils/SubtreeRetainer': SubtreeRetainer,
'utils/escapeRegExp': escapeRegExp,
'utils/extract': extract,
'utils/ScrollListener': ScrollListener,
'utils/stringToColor': stringToColor,
@@ -107,7 +104,6 @@ export default {
'utils/formatNumber': formatNumber,
'utils/mapRoutes': mapRoutes,
'utils/withAttr': withAttr,
'utils/throttleDebounce': ThrottleDebounce,
'models/Notification': Notification,
'models/User': User,
'models/Post': Post,

View File

@@ -1,5 +1,5 @@
// Expose jQuery, mithril and dayjs to the window browser object
import 'expose-loader?exposes=$,jQuery!jquery';
import 'expose-loader?exposes[]=$&exposes[]=jQuery!jquery';
import 'expose-loader?exposes=m!mithril';
import 'expose-loader?exposes=dayjs!dayjs';
@@ -16,12 +16,10 @@ import localizedFormat from 'dayjs/plugin/localizedFormat';
dayjs.extend(relativeTime);
dayjs.extend(localizedFormat);
import FlarumRegistry from './FlarumRegistry';
import patchMithril from './utils/patchMithril';
window.flreg = new FlarumRegistry();
patchMithril(window);
import * as Extend from './extend/index';
export { Extend };
import './utils/arrayFlatPolyfill';

View File

@@ -1,14 +0,0 @@
// Based off of the polyfill on MDN
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/flat#reduce_concat_isarray_recursivity
//
// Needed to provide support for Safari on iOS < 12
if (!Array.prototype['flat']) {
Array.prototype['flat'] = function flat(this: any[], depth: number = 1): any[] {
return depth > 0
? Array.prototype.reduce.call(this, (acc, val): any[] => acc.concat(Array.isArray(val) ? flat.call(val, depth - 1) : val), [])
: // If no depth is provided, or depth is 0, just return a copy of
// the array. Spread is supported in all major browsers (iOS 8+)
[...this];
};
}

View File

@@ -1,10 +0,0 @@
const specialChars = /[.*+?^${}()|[\]\\]/g;
/**
* Escapes the `RegExp` special characters in `input`.
*
* @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions#escaping
*/
export default function escapeRegExp(input: string): string {
return input.replace(specialChars, '\\$&');
}

View File

@@ -2,7 +2,7 @@
* The `evented` mixin provides methods allowing an object to trigger events,
* running externally registered event handlers.
*/
const evented = {
export default {
/**
* Arrays of registered event handlers, grouped by the event name.
*
@@ -79,5 +79,3 @@ const evented = {
}
},
};
export default evented;

View File

@@ -1,3 +0,0 @@
// Re-exports `throttle-debounce` to be used in `compat.js`.
export { throttle, debounce } from 'throttle-debounce';

View File

@@ -15,8 +15,8 @@ import slidable from '../utils/slidable';
import extractText from '../../common/utils/extractText';
import classList from '../../common/utils/classList';
import DiscussionPage from './DiscussionPage';
import escapeRegExp from '../../common/utils/escapeRegExp';
import { escapeRegExp } from 'lodash-es';
/**
* The `DiscussionListItem` component shows a single discussion in the
* discussion list.

View File

@@ -1,4 +1,4 @@
import { throttle } from 'throttle-debounce';
import { throttle } from 'lodash-es';
import anchorScroll from '../../common/utils/anchorScroll';
class PostStreamState {
@@ -50,8 +50,8 @@ class PostStreamState {
*/
this.forceUpdateScrubber = false;
this.loadNext = throttle(300, this._loadNext);
this.loadPrevious = throttle(300, this._loadPrevious);
this.loadNext = throttle(this._loadNext, 300);
this.loadPrevious = throttle(this._loadPrevious, 300);
this.show(includedPosts);
}

View File

@@ -11,7 +11,7 @@ import extractText from '../../common/utils/extractText';
* The `DiscussionControls` utility constructs a list of buttons for a
* discussion which perform actions on it.
*/
const DiscussionControls = {
export default {
/**
* Get a list of controls for a discussion.
*
@@ -259,5 +259,3 @@ const DiscussionControls = {
});
},
};
export default DiscussionControls;

View File

@@ -8,7 +8,7 @@ import extractText from '../../common/utils/extractText';
* The `PostControls` utility constructs a list of buttons for a post which
* perform actions on it.
*/
const PostControls = {
export default {
/**
* Get a list of controls for a post.
*
@@ -199,5 +199,3 @@ const PostControls = {
});
},
};
export default PostControls;

View File

@@ -8,7 +8,7 @@ import ItemList from '../../common/utils/ItemList';
* The `UserControls` utility constructs a list of buttons for a user which
* perform actions on it.
*/
const UserControls = {
export default {
/**
* Get a list of controls for a user.
*
@@ -141,5 +141,3 @@ const UserControls = {
app.modal.show(EditUserModal, { user });
},
};
export default UserControls;

View File

@@ -24,4 +24,4 @@ module.exports = merge(config(), {
});
module.exports['module'].rules[0].test = /\.(tsx?|js)$/;
module.exports['module'].rules[0].use[1].options.presets.push('@babel/preset-typescript');
module.exports['module'].rules[0].use.options.presets.push('@babel/preset-typescript');

View File

@@ -15,6 +15,7 @@ use Flarum\Foundation\AbstractServiceProvider;
use Flarum\Foundation\Console\AssetsPublishCommand;
use Flarum\Foundation\Console\CacheClearCommand;
use Flarum\Foundation\Console\InfoCommand;
use Flarum\Settings\SettingsRepositoryInterface;
use Illuminate\Console\Scheduling\Schedule as LaravelSchedule;
use Illuminate\Console\Scheduling\ScheduleListCommand;
use Illuminate\Console\Scheduling\ScheduleRunCommand;
@@ -65,5 +66,9 @@ class ConsoleServiceProvider extends AbstractServiceProvider
$event = $schedule->command($scheduled['command'], $scheduled['args']);
$scheduled['callback']($event);
}
$container->make('flarum.locales')->getTranslator()->getCatalogue(
$container->make(SettingsRepositoryInterface::class)->get('default_locale', 'en')
);
}
}

View File

@@ -97,11 +97,11 @@ class Frontend implements ExtenderInterface
if ($this->js) {
$assets->js(function (SourceCollector $sources) use ($moduleName) {
$sources->addString(function () {
return 'var module={};';
return 'var module={}';
});
$sources->addFile($this->js);
$sources->addString(function () use ($moduleName) {
return "flarum.extensions['$moduleName']=module.exports;";
return "flarum.extensions['$moduleName']=module.exports";
});
});
}

View File

@@ -0,0 +1,57 @@
<?php
/*
* This file is part of Flarum.
*
* For detailed copyright and license information, please view the
* LICENSE file that was distributed with this source code.
*/
namespace Flarum\Tests\integration\console;
use Flarum\Console\AbstractCommand;
use Flarum\Extend;
use Flarum\Locale\Translator;
use Flarum\Testing\integration\ConsoleTestCase;
class AbstractCommandTest extends ConsoleTestCase
{
/**
* @test
*/
public function scheduled_command_exists_when_added()
{
$this->extend(
(new Extend\Console())
->command(CustomEchoTranslationsCommand::class)
);
$input = [
'command' => 'customEchoTranslationsCommand'
];
// Arbitrary translation
$this->assertEquals('Flarum Email Test', $this->runCommand($input));
}
}
class CustomEchoTranslationsCommand extends AbstractCommand
{
/**
* {@inheritdoc}
*/
protected function configure()
{
$this->setName('customEchoTranslationsCommand');
}
/**
* {@inheritdoc}
*/
protected function fire()
{
$translator = resolve(Translator::class);
$this->info($translator->trans('core.emails.send_test.subject'));
}
}