1
0
mirror of https://github.com/flarum/core.git synced 2025-08-04 15:37:51 +02:00

chore: handle deprecations from 1.x (#3909)

* chore: drop deprecated `post_number_index` column

* chore: remove deprecated `FlagsWillBeDeleted` event

* chore: `Migration::addSettings` can still be needed

* chore: `settings->get` default can still be needed

* chore: deprecated `$default` in `Settings::serializeToForum` extender

* chore: deprecated request `actor` attribute

* chore: already handled

* chore: remove `RecompileFrontendAssets::whenSettingsSaved`

* chore: remove `getReadIds`

* chore: `Model::dateAttribute` extender

* chore: `evented` js util

* chore: `WelcomeHero` js hidden prop

* chore: attributes pushData with relations

* chore: app request options `extract`

* chore: itemlist deprecations

* chore: `search` state

* chore: `getMentionText`

* chore: deprecated non-registered store type

* chore: `Button` title

* chore: `Modal` deprecations

* chore

* chore: deprecated `less` mixins

* Apply fixes from StyleCI

* fix

* fix: phpstan

* fix

* fix

---------

Co-authored-by: StyleCI Bot <bot@styleci.io>
This commit is contained in:
Sami Mazouz
2023-11-10 22:20:18 +01:00
committed by GitHub
parent d01c0e5210
commit e2281a2123
35 changed files with 48 additions and 633 deletions

View File

@@ -50,7 +50,7 @@
padding: 15px 15px;
.scrolled & {
.box-shadow(0 2px 6px var(--shadow-color));
box-shadow: 0 2px 6px var(--shadow-color);
}
}

View File

@@ -54,7 +54,7 @@ export default function () {
const controls = PostControls.destructiveControls(this.attrs.post);
Object.keys(controls.items).forEach((k) => {
Object.keys(controls.toObject()).forEach((k) => {
const attrs = controls.get(k).attrs;
attrs.className = 'Button';

View File

@@ -10,7 +10,6 @@
namespace Flarum\Flags\Command;
use Flarum\Flags\Event\Deleting;
use Flarum\Flags\Event\FlagsWillBeDeleted;
use Flarum\Post\Post;
use Flarum\Post\PostRepository;
use Illuminate\Events\Dispatcher;
@@ -31,9 +30,6 @@ class DeleteFlagsHandler
$actor->assertCan('viewFlags', $post->discussion);
// Deprecated, removed v2.0
$this->events->dispatch(new FlagsWillBeDeleted($post, $actor, $command->data));
foreach ($post->flags as $flag) {
$this->events->dispatch(new Deleting($flag, $actor, $command->data));
}

View File

@@ -1,27 +0,0 @@
<?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\Flags\Event;
use Flarum\Post\Post;
use Flarum\User\User;
/**
* @deprecated v2.0
* Listen for Flarum\Flags\Event\Deleting instead
*/
class FlagsWillBeDeleted
{
public function __construct(
public Post $post,
public User $actor,
public array $data = []
) {
}
}

View File

@@ -5,7 +5,6 @@ import './components/UserMentionedNotification';
import './fragments/AutocompleteDropdown';
import './fragments/PostQuoteButton';
import './utils/getCleanDisplayName';
import './utils/getMentionText';
import './utils/reply';
import './utils/selectedText';
import './utils/textFormatter';

View File

@@ -1,21 +0,0 @@
import app from 'flarum/forum/app';
/**
* Fetches the mention text for a specified user (and optionally a post ID for replies or group).
*
* Automatically determines which mention syntax to be used based on the option in the
* admin dashboard. Also performs display name clean-up automatically.
*
* @deprecated Use `app.mentionables.get('user').replacement(user)` instead. Will be removed in 2.0.
*/
export default function getMentionText(user, postId, group) {
if (user !== undefined && postId === undefined) {
return app.mentionables.get('user').replacement(user);
} else if (user !== undefined && postId !== undefined) {
return app.mentionables.get('post').replacement(app.store.getById('posts', postId));
} else if (group !== undefined) {
return app.mentionables.get('group').replacement(group);
}
throw 'No parameters were passed';
}

View File

@@ -44,7 +44,8 @@ return [
->default('flarum-nicknames.set_on_registration', true)
->default('flarum-nicknames.min', 1)
->default('flarum-nicknames.max', 150)
->serializeToForum('displayNameDriver', 'display_name_driver', null, 'username')
->default('display_name_driver', 'username')
->serializeToForum('displayNameDriver', 'display_name_driver')
->serializeToForum('setNicknameOnRegistration', 'flarum-nicknames.set_on_registration', 'boolval')
->serializeToForum('randomizeUsernameOnRegistration', 'flarum-nicknames.random_username', 'boolval'),

View File

@@ -4,10 +4,9 @@ import Modal, { IInternalModalAttrs } from '../../common/components/Modal';
export interface ILoadingModalAttrs extends IInternalModalAttrs {}
export default class LoadingModal<ModalAttrs extends ILoadingModalAttrs = ILoadingModalAttrs> extends Modal<ModalAttrs> {
/**
* @inheritdoc
*/
static readonly isDismissible: boolean = false;
protected static readonly isDismissibleViaCloseButton: boolean = false;
protected static readonly isDismissibleViaEscKey: boolean = false;
protected static readonly isDismissibleViaBackdropClick: boolean = false;
className() {
return 'LoadingModal Modal--small';

View File

@@ -45,13 +45,6 @@ export type FlarumGenericRoute = RouteItem<any, any, any>;
export interface FlarumRequestOptions<ResponseType> extends Omit<Mithril.RequestOptions<ResponseType>, 'extract'> {
errorHandler?: (error: RequestError) => void;
url: string;
// TODO: [Flarum 2.0] Remove deprecated option
/**
* Manipulate the response text before it is parsed into JSON.
*
* @deprecated Please use `modifyText` instead.
*/
extract?: (responseText: string) => string;
/**
* Manipulate the response text before it is parsed into JSON.
*
@@ -434,7 +427,7 @@ export default class Application {
}
protected transformRequestOptions<ResponseType>(flarumOptions: FlarumRequestOptions<ResponseType>): InternalFlarumRequestOptions<ResponseType> {
const { background, deserialize, extract, modifyText, ...tmpOptions } = { ...flarumOptions };
const { background, deserialize, modifyText, ...tmpOptions } = { ...flarumOptions };
// Unless specified otherwise, requests should run asynchronously in the
// background, so that they don't prevent redraws from occurring.
@@ -446,11 +439,6 @@ export default class Application {
const defaultDeserialize = (response: string) => response as ResponseType;
// When extracting the data from the response, we can check the server
// response code and show an error message to the user if something's gone
// awry.
const originalExtract = modifyText || extract;
const options: InternalFlarumRequestOptions<ResponseType> = {
background: background ?? defaultBackground,
deserialize: deserialize ?? defaultDeserialize,
@@ -474,11 +462,14 @@ export default class Application {
options.method = 'POST';
}
// When extracting the data from the response, we can check the server
// response code and show an error message to the user if something's gone
// awry.
options.extract = (xhr: XMLHttpRequest) => {
let responseText;
if (originalExtract) {
responseText = originalExtract(xhr.responseText);
if (modifyText) {
responseText = modifyText(xhr.responseText);
} else {
responseText = xhr.responseText;
}

View File

@@ -1,6 +1,5 @@
import app from '../common/app';
import { FlarumRequestOptions } from './Application';
import { fireDeprecationWarning } from './helpers/fireDebugWarning';
import Store, { ApiPayloadSingle, ApiResponseSingle, MetaInformation } from './Store';
export interface ModelIdentifier {
@@ -113,15 +112,11 @@ export default abstract class Model {
if ('attributes' in data) {
this.data.attributes ||= {};
// @deprecated
// Filter out relationships that got in by accident.
for (const key in data.attributes) {
const val = data.attributes[key];
if (val && val instanceof Model) {
fireDeprecationWarning('Providing models as attributes to `Model.pushData()` or `Model.pushAttributes()` is deprecated.', '3249');
delete data.attributes[key];
data.relationships ||= {};
data.relationships[key] = { data: Model.getIdentifier(val) };
}
}

View File

@@ -1,6 +1,5 @@
import app from '../common/app';
import { FlarumRequestOptions } from './Application';
import { fireDeprecationWarning } from './helpers/fireDebugWarning';
import Model, { ModelData, SavedModelData } from './Model';
export interface MetaInformation {
@@ -100,7 +99,7 @@ export default class Store {
pushPayload<M extends Model | Model[]>(payload: ApiPayload): ApiResponse<FlatArray<M, 1>> {
if (payload.included) payload.included.map(this.pushObject.bind(this));
const models = payload.data instanceof Array ? payload.data.map((o) => this.pushObject(o, false)) : this.pushObject(payload.data, false);
const models = payload.data instanceof Array ? payload.data.map((o) => this.pushObject(o)) : this.pushObject(payload.data);
const result = models as ApiResponse<FlatArray<M, 1>>;
// Attach the original payload to the model that we give back. This is
@@ -120,14 +119,11 @@ export default class Store {
* registered for this resource type.
*/
pushObject<M extends Model>(data: SavedModelData): M | null;
pushObject<M extends Model>(data: SavedModelData, allowUnregistered: false): M;
pushObject<M extends Model>(data: SavedModelData, allowUnregistered = true): M | null {
pushObject<M extends Model>(data: SavedModelData): M | null {
if (!this.models[data.type]) {
if (!allowUnregistered) {
setTimeout(() =>
fireDeprecationWarning(`Pushing object of type \`${data.type}\` not allowed, as type not yet registered in the store.`, '3206')
);
}
setTimeout(() => {
throw new Error(`Pushing object of type \`${data.type}\` not allowed, as type not yet registered in the store.`);
});
return null;
}

View File

@@ -27,18 +27,6 @@ export interface IButtonAttrs extends ComponentAttrs {
* Default: `false`
*/
loading?: boolean;
/**
* **DEPRECATED:** Please use the `aria-label` attribute instead. For tooltips, use
* the `<Tooltip>` component.
*
* Accessible text for the button. This should always be present if the button only
* contains an icon.
*
* The textual content of this attribute is passed to the DOM element as `aria-label`.
*
* @deprecated
*/
title?: string | Mithril.ChildArray;
/**
* Accessible text for the button. This should always be present if the button only
* contains an icon.
@@ -68,14 +56,11 @@ export interface IButtonAttrs extends ComponentAttrs {
*/
export default class Button<CustomAttrs extends IButtonAttrs = IButtonAttrs> extends Component<CustomAttrs> {
view(vnode: Mithril.VnodeDOM<CustomAttrs, this>) {
let { type, title, 'aria-label': ariaLabel, icon: iconName, disabled, loading, className, class: _class, ...attrs } = this.attrs;
let { type, 'aria-label': ariaLabel, icon: iconName, disabled, loading, className, class: _class, ...attrs } = this.attrs;
// If no `type` attr provided, set to "button"
type ||= 'button';
// Use `title` attribute as `aria-label` if none provided
ariaLabel ||= title;
// If given a translation object, extract the text.
if (typeof ariaLabel === 'object') {
ariaLabel = extractText(ariaLabel);

View File

@@ -17,10 +17,6 @@ export interface IInternalModalAttrs {
}
export interface IDismissibleOptions {
/**
* @deprecated Check specific individual attributes instead. Will be removed in Flarum 2.0.
*/
isDismissible: boolean;
viaCloseButton: boolean;
viaEscKey: boolean;
viaBackdropClick: boolean;
@@ -34,14 +30,6 @@ export default abstract class Modal<ModalAttrs extends IInternalModalAttrs = IIn
ModalAttrs,
CustomState
> {
// TODO: [Flarum 2.0] remove `isDismissible` static attribute
/**
* Determine whether or not the modal should be dismissible via an 'x' button.
*
* @deprecated Use the individual `isDismissibleVia...` attributes instead and remove references to this.
*/
static readonly isDismissible: boolean = true;
/**
* Can the model be dismissed with a close button (X)?
*
@@ -58,18 +46,7 @@ export default abstract class Modal<ModalAttrs extends IInternalModalAttrs = IIn
protected static readonly isDismissibleViaBackdropClick: boolean = true;
static get dismissibleOptions(): IDismissibleOptions {
// If someone sets this to `false`, provide the same behaviour as previous versions of Flarum.
if (!this.isDismissible) {
return {
isDismissible: false,
viaCloseButton: false,
viaEscKey: false,
viaBackdropClick: false,
};
}
return {
isDismissible: true,
viaCloseButton: this.isDismissibleViaCloseButton,
viaEscKey: this.isDismissibleViaEscKey,
viaBackdropClick: this.isDismissibleViaBackdropClick,
@@ -83,31 +60,6 @@ export default abstract class Modal<ModalAttrs extends IInternalModalAttrs = IIn
*/
alertAttrs: AlertAttrs | null = null;
oninit(vnode: Mithril.Vnode<ModalAttrs, this>) {
super.oninit(vnode);
// TODO: [Flarum 2.0] Remove the code below.
// This code prevents extensions which do not implement all abstract methods of this class from breaking
// the forum frontend. Without it, function calls would would error rather than returning `undefined.`
const missingMethods: string[] = [];
['className', 'title', 'content', 'onsubmit'].forEach((method) => {
if (!(this as any)[method]) {
(this as any)[method] = function (): void {};
missingMethods.push(method);
}
});
if (missingMethods.length > 0) {
fireDebugWarning(
`Modal \`${this.constructor.name}\` does not implement all abstract methods of the Modal super class. Missing methods: ${missingMethods.join(
', '
)}.`
);
}
}
oncreate(vnode: Mithril.VnodeDOM<ModalAttrs, this>) {
super.oncreate(vnode);

View File

@@ -26,24 +26,6 @@ export default class ItemList<T> {
*/
protected _items: Record<string, Item<T>> = {};
// TODO: [Flarum 2.0] Remove `.items` getter.
/**
* A **read-only copy** of items in the list.
*
* We don't allow adding new items to the ItemList via setting new properties,
* nor do we allow modifying existing items directly.
*
* @deprecated Use {@link ItemList.toObject} instead.
*/
get items(): DeepReadonly<Record<string, Item<T>>> {
return new Proxy(this._items, {
set() {
console.warn('Modifying `ItemList.items` is not allowed.');
return false;
},
});
}
/**
* Check whether the list is empty.
*/
@@ -86,44 +68,6 @@ export default class ItemList<T> {
return this;
}
// TODO: [Flarum 2.0] Remove deprecated `.replace()` method.
/**
* Replace an item and/or priority in the list, only if it is already present.
*
* If `content` or `priority` are `null`, these values will not be replaced.
*
* If the provided `key` is not present, nothing will happen.
*
* @deprecated Please use the {@link ItemList.setContent} and {@link ItemList.setPriority}
* methods to replace items and their priorities. This method will be removed in Flarum 2.0.
*
* @param key The key of the item in the list
* @param content The item's new content
* @param priority The item's new priority
*
* @example <caption>Replace priority and not content.</caption>
* items.replace('myItem', null, 10);
*
* @example <caption>Replace content and not priority.</caption>
* items.replace('myItem', <p>My new value.</p>);
*
* @example <caption>Replace content and priority.</caption>
* items.replace('myItem', <p>My new value.</p>, 10);
*/
replace(key: string, content: T | null = null, priority: number | null = null): this {
if (!this.has(key)) return this;
if (content !== null) {
this._items[key].content = content;
}
if (priority !== null) {
this._items[key].priority = priority;
}
return this;
}
/**
* Replaces an item's content, if the provided item key exists.
*
@@ -147,8 +91,11 @@ export default class ItemList<T> {
throw new Error(`[ItemList] Cannot set content of Item. Key \`${key}\` is not present.`);
}
// Saves on bundle size to call the deprecated method internally
return this.replace(key, content);
if (content !== null) {
this._items[key].content = content;
}
return this;
}
/**

View File

@@ -1,109 +0,0 @@
import { fireDeprecationWarning } from '../helpers/fireDebugWarning';
const deprecatedNotice = 'The `evented` util is deprecated and no longer supported.';
const deprecationIssueId = '2547';
/**
* The `evented` mixin provides methods allowing an object to trigger events,
* running externally registered event handlers.
*
* @deprecated v1.2, to be removed in v2.0
*/
export default {
/**
* Arrays of registered event handlers, grouped by the event name.
*
* @type {Record<string, unknown>}
* @protected
*
* @deprecated
*/
handlers: null,
/**
* Get all of the registered handlers for an event.
*
* @param {string} event The name of the event.
* @return {Function[]}
* @protected
*
* @deprecated
*/
getHandlers(event) {
fireDeprecationWarning(deprecatedNotice, deprecationIssueId);
this.handlers = this.handlers || {};
this.handlers[event] = this.handlers[event] || [];
return this.handlers[event];
},
/**
* Trigger an event.
*
* @param {string} event The name of the event.
* @param {any[]} args Arguments to pass to event handlers.
*
* @deprecated
*/
trigger(event, ...args) {
fireDeprecationWarning(deprecatedNotice, deprecationIssueId);
this.getHandlers(event).forEach((handler) => handler.apply(this, args));
},
/**
* Register an event handler.
*
* @param {string} event The name of the event.
* @param {Function} handler The function to handle the event.
*
* @deprecated
*/
on(event, handler) {
fireDeprecationWarning(deprecatedNotice, deprecationIssueId);
this.getHandlers(event).push(handler);
},
/**
* Register an event handler so that it will run only once, and then
* unregister itself.
*
* @param {string} event The name of the event.
* @param {Function} handler The function to handle the event.
*
* @deprecated
*/
one(event, handler) {
fireDeprecationWarning(deprecatedNotice, deprecationIssueId);
const wrapper = function () {
handler.apply(this, arguments);
this.off(event, wrapper);
};
this.getHandlers(event).push(wrapper);
},
/**
* Unregister an event handler.
*
* @param {string} event The name of the event.
* @param {Function} handler The function that handles the event.
*
* @deprecated
*/
off(event, handler) {
fireDeprecationWarning(deprecatedNotice, deprecationIssueId);
const handlers = this.getHandlers(event);
const index = handlers.indexOf(handler);
if (index !== -1) {
handlers.splice(index, 1);
}
},
};

View File

@@ -8,7 +8,6 @@ import KeyboardNavigatable from '../../common/utils/KeyboardNavigatable';
import SearchState from '../states/SearchState';
import DiscussionsSearchSource from './DiscussionsSearchSource';
import UsersSearchSource from './UsersSearchSource';
import { fireDeprecationWarning } from '../../common/helpers/fireDebugWarning';
import type Mithril from 'mithril';
import Icon from '../../common/components/Icon';
@@ -64,24 +63,6 @@ export default class Search<T extends SearchAttrs = SearchAttrs> extends Compone
*/
protected searchState!: SearchState;
/**
* The instance of `SearchState` for this component.
*
* @deprecated Replace with`this.searchState` instead.
*/
// TODO: [Flarum 2.0] Remove this.
// @ts-expect-error This is a get accessor, while superclass defines this as a property. This is needed to prevent breaking changes, however.
get state() {
fireDeprecationWarning('`state` property of the Search component is deprecated', '3212');
return this.searchState;
}
set state(state: SearchState) {
// Workaround to prevent triggering deprecation warnings due to Mithril
// setting state to undefined when creating components
state !== undefined && fireDeprecationWarning('`state` property of the Search component is deprecated', '3212');
this.searchState = state;
}
/**
* Whether or not the search input has focus.
*/

View File

@@ -13,11 +13,6 @@ const LOCAL_STORAGE_KEY = 'welcomeHidden';
* forum.
*/
export default class WelcomeHero extends Component<IWelcomeHeroAttrs> {
/**
* @deprecated Extend the `isHidden` method instead.
*/
hidden: boolean = false;
oninit(vnode: Mithril.Vnode<IWelcomeHeroAttrs, this>) {
super.oninit(vnode);
}
@@ -60,7 +55,6 @@ export default class WelcomeHero extends Component<IWelcomeHeroAttrs> {
isHidden(): boolean {
if (!app.forum.attribute<string>('welcomeTitle')?.trim()) return true;
if (localStorage.getItem(LOCAL_STORAGE_KEY)) return true;
if (this.hidden) return true;
return false;
}

View File

@@ -68,7 +68,7 @@
&:active,
&.active,
.open > &.Dropdown-toggle {
.box-shadow(inset 0 3px 5px rgba(0, 0, 0, .125));
box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125);
}
&.disabled,

View File

@@ -4,84 +4,6 @@
// The vendor presets below are to try to remain compatible with iOS 9+ and other
// major browsers (Chrome/Firefox/new Edge/Safari desktop).
// Animations
// These remain for backwards compatibility with existing styles.
/** @deprecated */
.animation(@animation) {
animation: @animation;
}
/** @deprecated */
.animation-name(@name) {
animation-name: @name;
}
.animation-duration(@duration) {
animation-duration: @duration;
}
/** @deprecated */
.animation-timing-function(@timing-function) {
animation-timing-function: @timing-function;
}
/** @deprecated */
.animation-delay(@delay) {
animation-delay: @delay;
}
/** @deprecated */
.animation-iteration-count(@iteration-count) {
animation-iteration-count: @iteration-count;
}
/** @deprecated */
.animation-direction(@direction) {
animation-direction: @direction;
}
/** @deprecated */
.animation-fill-mode(@fill-mode) {
animation-fill-mode: @fill-mode;
}
// Backface visibility
// Prevent browsers from flickering when using CSS 3D transforms.
// Default value is `visible`, but can be changed to `hidden`
/** @deprecated */
.backface-visibility(@visibility) {
// Safari
-webkit-backface-visibility: @visibility;
backface-visibility: @visibility;
}
// Drop shadows
// These remain for backwards compatibility with existing styles.
/** @deprecated */
.box-shadow(@shadow) {
box-shadow: @shadow;
}
// Box sizing
// These remain for backwards compatibility with existing styles.
/** @deprecated */
.box-sizing(@boxmodel) {
box-sizing: @boxmodel;
}
// CSS3 Content Columns
/** @deprecated */
.content-columns(@column-count; @column-gap: @grid-gutter-width) {
// Safari
-webkit-column-count: @column-count;
column-count: @column-count;
// Safari
-webkit-column-gap: @column-gap;
column-gap: @column-gap;
}
// Optional hyphenation
/** @deprecated */
.hyphens(@mode: auto) {
word-wrap: break-word;
// Safari
-webkit-hyphens: @mode;
hyphens: @mode;
}
// Placeholder text
.placeholder(@color) {
// Safari
@@ -91,88 +13,6 @@
}
}
// Transformations
// These remain for backwards compatibility with existing styles.
/** @deprecated */
.scale(@ratio) {
transform: scale(@ratio);
}
/** @deprecated */
.scale(@ratioX; @ratioY) {
transform: scale(@ratioX, @ratioY);
}
/** @deprecated */
.scaleX(@ratio) {
transform: scaleX(@ratio);
}
/** @deprecated */
.scaleY(@ratio) {
transform: scaleY(@ratio);
}
/** @deprecated */
.skew(@x; @y) {
transform: skewX(@x) skewY(@y);
}
/** @deprecated */
.translate(@x; @y) {
transform: translate(@x, @y);
}
/** @deprecated */
.translate3d(@x; @y; @z) {
transform: translate3d(@x, @y, @z);
}
/** @deprecated */
.rotate(@degrees) {
transform: rotate(@degrees);
}
/** @deprecated */
.rotateX(@degrees) {
transform: rotateX(@degrees);
}
/** @deprecated */
.rotateY(@degrees) {
transform: rotateY(@degrees);
}
/** @deprecated */
.perspective(@perspective) {
perspective: @perspective;
}
/** @deprecated */
.perspective-origin(@perspective) {
perspective-origin: @perspective;
}
/** @deprecated */
.transform-origin(@origin) {
transform-origin: @origin;
}
// Transitions
// These remain for backwards compatibility with existing styles.
/** @deprecated */
.transition(@transition) {
transition: @transition;
}
/** @deprecated */
.transition-property(@transition-property) {
transition-property: @transition-property;
}
/** @deprecated */
.transition-delay(@transition-delay) {
transition-delay: @transition-delay;
}
/** @deprecated */
.transition-duration(@transition-duration) {
transition-duration: @transition-duration;
}
/** @deprecated */
.transition-timing-function(@timing-function) {
transition-timing-function: @timing-function;
}
/** @deprecated */
.transition-transform(@transition) {
transition: transform @transition;
}
// User select
// For selecting text on the page
.user-select(@select) {

View File

@@ -0,0 +1,12 @@
<?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.
*/
use Flarum\Database\Migration;
return Migration::dropColumns('discussions', ['post_number_index' => '']);

View File

@@ -26,7 +26,6 @@ use Flarum\Http\RouteCollection;
use Flarum\Http\RouteHandlerFactory;
use Flarum\Http\UrlGenerator;
use Flarum\Locale\LocaleManager;
use Flarum\Settings\Event\Saved;
use Illuminate\Contracts\Container\Container;
use Laminas\Stratigility\MiddlewarePipe;
@@ -131,17 +130,6 @@ class AdminServiceProvider extends AbstractServiceProvider
$recompile->flush();
}
);
$events->listen(
Saved::class,
function (Saved $event) {
$recompile = new RecompileFrontendAssets(
$this->container->make('flarum.assets.admin'),
$this->container->make(LocaleManager::class)
);
$recompile->whenSettingsSaved($event);
}
);
}
protected function populateRoutes(RouteCollection $routes): void

View File

@@ -120,7 +120,7 @@ abstract class Migration
/**
* Add default values for config values.
*
* @deprecated Use the Settings extender's `default` method instead to register settings.
* You generally should use the Settings extender's `default` method instead to register settings.
* @see Settings::default()
*/
public static function addSettings(array $defaults): array

View File

@@ -36,7 +36,6 @@ use Illuminate\Support\Str;
* @property string $slug
* @property int $comment_count
* @property int $participant_count
* @property int $post_number_index !!DEPRECATED!!
* @property \Carbon\Carbon $created_at
* @property int|null $user_id
* @property int|null $first_post_id

View File

@@ -11,7 +11,6 @@ namespace Flarum\Discussion;
use Flarum\User\User;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Collection;
class DiscussionRepository
{
@@ -34,18 +33,6 @@ class DiscussionRepository
return $this->scopeVisibleTo($query, $user)->firstOrFail();
}
/**
* Get the IDs of discussions which a user has read completely.
*
* @param User $user
* @return Collection<int, Discussion>
* @deprecated 1.3 Use `getReadIdsQuery` instead
*/
public function getReadIds(User $user): Collection
{
return $this->getReadIdsQuery($user)->get();
}
/**
* Get a query containing the IDs of discussions which a user has read completely.
*

View File

@@ -23,7 +23,6 @@ use Flarum\Frontend\RecompileFrontendAssets;
use Flarum\Http\RouteCollection;
use Flarum\Http\RouteHandlerFactory;
use Flarum\Locale\LocaleManager;
use Flarum\Settings\Event\Saved;
use Illuminate\Contracts\Container\Container;
use Psr\Http\Message\ServerRequestInterface;
@@ -253,17 +252,6 @@ class Frontend implements ExtenderInterface
$recompile->flush();
}
);
$events->listen(
Saved::class,
function (Saved $event) use ($container, $abstract) {
$recompile = new RecompileFrontendAssets(
$container->make($abstract),
$container->make(LocaleManager::class)
);
$recompile->whenSettingsSaved($event);
}
);
}
}

View File

@@ -30,20 +30,6 @@ class Model implements ExtenderInterface
) {
}
/**
* Add an attribute to be treated as a date.
*
* @param string $attribute
* @return self
* @deprecated use `cast` instead. Will be removed in v2.
*/
public function dateAttribute(string $attribute): self
{
$this->cast($attribute, 'datetime');
return $this;
}
/**
* Add a custom attribute type cast. Should not be applied to non-extension attributes.
*

View File

@@ -36,13 +36,11 @@ class Settings implements ExtenderInterface
* The callable should return:
* - mixed $value: The modified value.
*
* @todo remove $default in 2.0
* @param mixed $default: Deprecated optional default serialized value. Will be run through the optional callback.
* @return self
*/
public function serializeToForum(string $attributeName, string $key, callable|string $callback = null, mixed $default = null): self
public function serializeToForum(string $attributeName, string $key, callable|string $callback = null): self
{
$this->settings[$key] = compact('attributeName', 'callback', 'default');
$this->settings[$key] = compact('attributeName', 'callback');
return $this;
}
@@ -108,7 +106,7 @@ class Settings implements ExtenderInterface
$attributes = [];
foreach ($this->settings as $key => $setting) {
$value = $settings->get($key, $setting['default']);
$value = $settings->get($key);
if (isset($setting['callback'])) {
$callback = ContainerUtil::wrapCallback($setting['callback'], $container);

View File

@@ -173,12 +173,6 @@ class ForumServiceProvider extends AbstractServiceProvider
$events->listen(
Saved::class,
function (Saved $event) use ($container) {
$recompile = new RecompileFrontendAssets(
$container->make('flarum.assets.forum'),
$container->make(LocaleManager::class)
);
$recompile->whenSettingsSaved($event);
$validator = new ValidateCustomLess(
$container->make('flarum.assets.forum'),
$container->make('flarum.locales'),

View File

@@ -10,7 +10,6 @@
namespace Flarum\Frontend;
use Flarum\Locale\LocaleManager;
use Flarum\Settings\Event\Saved;
/**
* @internal
@@ -23,14 +22,6 @@ class RecompileFrontendAssets
) {
}
public function whenSettingsSaved(Saved $event): void
{
// @deprecated 'theme_' check, to be removed in 2.0
if (preg_grep('/^theme_/i', array_keys($event->settings))) {
$this->flushCss();
}
}
public function flush(): void
{
$this->flushCss();

View File

@@ -30,9 +30,6 @@ class RequestUtil
$actorReference->setActor($actor);
// @deprecated in 1.0
$request = $request->withAttribute('actor', $actor);
return $request;
}
}

View File

@@ -21,8 +21,6 @@ class DefaultSettingsRepository implements SettingsRepositoryInterface
public function get(string $key, mixed $default = null): mixed
{
// Global default overrules local default because local default is deprecated,
// and will be removed in 2.0
return $this->inner->get($key, $this->defaults->get($key, $default));
}

View File

@@ -14,7 +14,11 @@ interface SettingsRepositoryInterface
public function all(): array;
/**
* @todo remove deprecated $default in 2.0
* You generally should use the Settings extender's `default` method instead to register default values.
* You may still need to use the `$default` parameters here in cases where you need to
* access the default value of a dynamic setting.
*
* @see Settings::default()
*/
public function get(string $key, mixed $default = null): mixed;

View File

@@ -112,7 +112,7 @@ if (! function_exists('event')) {
if (! function_exists('config')) {
/**
* @deprecated do not use, will be transferred to flarum/laravel-helpers.
* @deprecated
*/
function config(string $key, mixed $default = null): mixed
{

View File

@@ -118,52 +118,6 @@ class SettingsTest extends TestCase
$this->assertEquals('customValueModifiedByInvokable', $payload['data']['attributes']['customPrefix.customSetting2']);
}
/**
* @test
*/
public function custom_setting_falls_back_to_default()
{
$this->extend(
(new Extend\Settings())
->serializeToForum('customPrefix.noCustomSetting', 'custom-prefix.no_custom_setting', null, 'customDefault')
);
$response = $this->send(
$this->request('GET', '/api', [
'authenticatedAs' => 1,
])
);
$payload = json_decode($response->getBody()->getContents(), true);
$this->assertArrayHasKey('customPrefix.noCustomSetting', $payload['data']['attributes']);
$this->assertEquals('customDefault', $payload['data']['attributes']['customPrefix.noCustomSetting']);
}
/**
* @test
*/
public function custom_setting_default_passed_to_callback()
{
$this->extend(
(new Extend\Settings())
->serializeToForum('customPrefix.noCustomSetting', 'custom-prefix.no_custom_setting', function ($value) {
return $value.'Modified2';
}, 'customDefault')
);
$response = $this->send(
$this->request('GET', '/api', [
'authenticatedAs' => 1,
])
);
$payload = json_decode($response->getBody()->getContents(), true);
$this->assertArrayHasKey('customPrefix.noCustomSetting', $payload['data']['attributes']);
$this->assertEquals('customDefaultModified2', $payload['data']['attributes']['customPrefix.noCustomSetting']);
}
/**
* @test
*/

View File

@@ -32,7 +32,7 @@ class DiscussionPolicyTest extends TestCase
$this->prepareDatabase([
'discussions' => [
['id' => 1, 'title' => 'Editable discussion', 'created_at' => Carbon::parse('2021-11-01 13:00:00')->toDateTimeString(), 'user_id' => 2, 'first_post_id' => 1, 'comment_count' => 2, 'is_private' => 0, 'last_post_number' => 1, 'post_number_index' => 1, 'participant_count' => 1],
['id' => 1, 'title' => 'Editable discussion', 'created_at' => Carbon::parse('2021-11-01 13:00:00')->toDateTimeString(), 'user_id' => 2, 'first_post_id' => 1, 'comment_count' => 2, 'is_private' => 0, 'last_post_number' => 1, 'participant_count' => 1],
['id' => 2, 'title' => 'Editable discussion', 'created_at' => Carbon::parse('2021-11-01 13:00:00')->toDateTimeString(), 'user_id' => 2, 'first_post_id' => 2, 'comment_count' => 2, 'is_private' => 0, 'last_post_number' => 2, 'participant_count' => 2],
],
'posts' => [