* fix: breaking change in search component's public api
* fix: add setter
* feat: add deprecation warning helper
This reduces bundle size as a result of deprecation warning in our JS, as well as maintaining a consistent format across warnings.
* feat: fire deprecation warning on usage of `Search.state`
* chore: use consistent deprecation warning across core
* fix: `/pull` not `/issue`
* chore: format
* fix: replace throw with debug warning to fix breaking change
* Add link back to PR in warning
* fix: add missing `return null` for `!allowUnregistered` code path
* Clean up message -- move more info to PR comment
* Add setTimeout to delay call debug warning call until after `app.forum` is defined
* Add backticks around data type
Fixes https://github.com/flarum/core/issues/3169#issuecomment-979470794
- Restore wrapping `scope.render` results in a table cell tag. This was accidentially introduced in 924815b6e1, and caused the issue linked above
- Rename the `SettingDropdown` attr `key` to `setting` in order to avoid naming clashes with Mithril vnode keys. `key` still works, but is deprecated.
https://github.com/flarum/core/pull/3176 accidentially stopped adding a `key` attribute to wrappers of non-vnode inputs. This resulted in "all or no vnodes must have keys" errors.
* Centralize pagination/canonical meta URL generation in Document
* Apply fixes from StyleCI
[ci skip] [skip ci]
* Use translations for title template
* Apply fixes from StyleCI
[ci skip] [skip ci]
* Dont add translator to title driver interface
It's an implementation detail, and can be made available on specific implementations as needed.
Co-authored-by: Alexander Skvortsov <askvortsov1@users.noreply.github.com>
Fixes https://github.com/flarum/core/issues/3055
- On the frontend, accept only image types as a hint to the OS file picker.
- On the backend, add more robust validation to ensure only valid images make it through. This isn't necessary for security, but results in less confusing error mesages.
* Remove color validation in basics admin page & add color indicator
* Create ColorInput common component
* Revert 'formGroupAttrs' addition
* Rename component CSS classes
* Fix input type in ColorInput from AdminPage#buildSettingComponent
* Rename component to ColorPreviewInput, remove aliases in admin & export in compat
* Remove leftovers from rebase on master
* feat: add global type definition for a vnode element tag
* fix(a11y): add aria roles to color input
* chore: use new type
* chore: format
Co-authored-by: David Wheatley <hi@davwheat.dev>
* Add focus trap util
* Add focus trap to Modals
Fixes#2663
* Split tab press into `onTab` handler
* Remove deprecated code
* Use requestAnimationFrame instead of setTimeout
* Reduce code duplication
* Implement focus trap in nav drawer
Fixes#2665
* Hide drawer when window is resized to be bigger
Fixes issue where focus trap would remain on the drawer when it is
just the app header, if the drawer was opened then the window was
made larger.
* Simplify conditional function calls
* Fix modal focus trap
* Remove debug code
* Simplify resize handler conditional statements
* Add info about reasoning of resize handler
* Prefer native JS methods over jQuery
* Update conditional function call to handle `undefined`
* Expose screen sizes as CSS custom properties
* Use `window.matchMedia` rather than resize handler
* Fix spelling error
Co-authored-by: David Sevilla Martin <me@datitisev.me>
* Remove breaking change
Co-authored-by: David Sevilla Martin <me@datitisev.me>
By injecting the cache store into the queue, we allow queues to be
restarted using php flarum queue:restart and similar events dispatched
from within Laravelish classes.
* Enforce 65k limit when attempting to store setting values.
* Add space for style.
* Move setting validation into Saving event listener.
* Use consistent var names
* remove extra space
* Move settings validation into separate class.
* Remove unused class.
* Remove extra line.
* Move ValidateCustomLess to SettingsServiceProvider. Use existing convention for validator.
* Update src/Settings/SettingsValidator.php
Co-authored-by: Alexander Skvortsov <38059171+askvortsov1@users.noreply.github.com>
* Revert moving of ValidateCustomLess logic. Allow for attribute specific setting validation rules.
* Style fixes.
* Style fixes.
* Style fixes.
Co-authored-by: Alexander Skvortsov <38059171+askvortsov1@users.noreply.github.com>
* Improve typings for ItemList
* Add new `.replace()` syntax
* Update JSDoc
* Add missing `T` type
* Fix typo
Co-authored-by: Alexander Skvortsov <38059171+askvortsov1@users.noreply.github.com>
* Allow choice to not set `itemName` property when calling `toArray`
* Make `ItemList.items` read-only
* Modify `.replace()`; add `.changePriority()`
* Complete rename
* Update JSDoc
* Add `.toObject()` method; deprecate `.items`
* Rewrite `.toArray()` to use Proxy instead of modifying the item content
- Fixes#3030
- Fixes issue where setting `itemName` property could result in errors depending on the object type (e.g. proxies)
- Fixes unneeded duplication of item list
- Add option to disable setting `itemName` property on primitives
* Simplify condition
* Remove debug code
* Make proxying function protected instead of private
* Update a usage of ItemList as an example
* Make `itemName` property read-only
* Use correct capitalisation of `object`
* Invert `toArray` parameter function
* Simplify isEmpty check
* Update ItemList.ts
* Fix `merge()`
* Remove extra JSDoc comment
* Use `._items` directly for merging
* Rename methods: `replace` -> `set`; `changePriority` -> `setPriority`
This more closely matches our existing method names (`get()`)
* Change `items` getter
* Simplify proxying
* Update URL to source function
* Update compat
* Various changes to toObject
* Remove `Item.key`
* Make item content proxy method private
* Enforce merge typings
* Update TSDoc comments to use `{@link}` for references to methods
* Correct references to deprecated `.replace` method
* Throw error when setting content/priority of non-existent items
* Remove intermediary variable
* Update TSDoc block
* Update js/src/@types/global.d.ts
Co-authored-by: Alexander Skvortsov <38059171+askvortsov1@users.noreply.github.com>
* chore: migrate to Yarn package manager
* chore: bump deps, move `expose-loader` to correct deps section
* fix: remove package from old typescript shim
* feat: use Yarn Plug'n'Play
* chore: keep `node_modules` ignored for people who choose to use npm anyway
* Revert "feat: use Yarn Plug'n'Play"
This reverts commit 9781c8c8d5.
* feat: allow use of any tag in `listItems` helper
* fix: fix missing optional chaining
* chore: use more optional chaining
* fix: various typings errors
* chore: replace `Vnode[]` with `Children`
* Allow using file extension in core compat imports
Necessary for extend imports to have proper typings as we also have an unrelated extend/index.js file
* Add .ts file extension to extend imports for typings
* Fix changes to proxifyCompat regex breaking non-core import paths
* Move utility types to global types
Co-authored-by: David Wheatley <hi@davwheat.dev>
* Rename files
* Rewrite common Application to TS
* Improve DefaultResolver typings
* Convert mapRoutes to TS
* Fix incorrect JSDoc type
* Add missing default value
* Add debug button string to localisations
* WIP Forum application TS rewrite
* Use union and intersection to remove property duplication
* Address some review comments
Co-authored-by: Alexander Skvortsov <38059171+askvortsov1@users.noreply.github.com>
* Address some review comments
Co-authored-by: Alexander Skvortsov <38059171+askvortsov1@users.noreply.github.com>
* Fix build error
* Address some review comments
Co-authored-by: Alexander Skvortsov <38059171+askvortsov1@users.noreply.github.com>
* Add `type` import qualifier
Co-authored-by: Alexander Skvortsov <38059171+askvortsov1@users.noreply.github.com>
Needed for https://github.com/flarum/core/issues/3043.
Some posts are loaded dynamically, and won't be immediately available. In this case, we show a loading indicator instead of displaying content. In this PR:
- We redraw post content if loading state has chnaged
- We show a loading indicator while loading
* Add class to remove all UA styles from a button
* Improve classList utilisation
* Simplify JSX
* Use classlist instead of concatenation
* Fix reply count focusable when not acting as a button
* Add SR only class
* Add new reply count translations
* Use cleaner translations
* Remove unused import
* Add missing new line
* Delete Accessibility.less
* Use existing `.visually-hidden` class
* Format
* Fix locale formatting
Fixes#2492
* Added api/groups/{id} endpoint for retrieving a single group by its id
* Fixed GroupRepository incorrectly opening query to User instead of Group model
* Added filtering & paging abilities to GET api/groups endpoint
* Added test for sorting for GET api/groups endpoint
Co-authored-by: Alexander Skvortsov <38059171+askvortsov1@users.noreply.github.com>
Whether it's due to corrupted content, missing tags, caching issues, or other assorted reasons, post content can't be rendered. Currently, this results in an exception that crashes the entire forum and is hard to debug. Instead, we should log the error and show an indicator message that rendering has failed.
Co-authored-by: Sami Mazouz <sychocouldy@gmail.com>
Co-authored-by: David Wheatley <hi@davwheat.dev>
As a temporary fix it has been requested to disallow dashes in the database prefix. The installation process fails when the prefix does include a dash.
#3022
This PR forces the `Cache-Control: no-store, max-age=0` header to the response in the Admin Area. This forces cache to be ignored upon browsing back and forth between pages using the browser controls. Although absolutely no fail safe, it should provide better protection against serving cached pages once an admin has signed out.
https://github.com/flarum/core/pull/3068 accidentially broke the user discussions page, as up until this commit, `DiscussionListState`didn't accept any filter params.
By sorting alphabetically by extension ID before applying topological sort, we ensure that a given set of extensions will always be booted in the same order. This will make it easier to replicate issues caused by complex extension dependencies.
This PR introduces the ability to just override a LESS file's contents through an extender.
This is mainly useful for theme development, as there are times in extensively customized themes where overriding the actual file makes a huge difference vs overriding CSS styles which can turn into a maintenance hell real fast.
Overriding styles is more tedious than overriding files. When you're designing an element, you would normally rather start from a blank canvas, than a styled element. With an already styled element you have to first override and undo the styles you do not wish to have, only then can you start shaping it, but even then you'd always end up constantly undoing default styles. This mostly applies for more advanced themes. (example: 851c55516d/less/forum/DiscussionList.less)
* Add extra error handling for avatar file size & large payload
* Change error message to return 'upload failure' on most errors instead of 'no file' message
Extension admin pages are currently not working because of a JS error.
The settings record is never defined but directly used, it used to be defined as an empty object in oninit.
* Rewrite AdminPage.js into Typescript
* Export more interfaces and types
* Use Stream type
* Update js/src/admin/components/AdminPage.tsx
Co-authored-by: Sami Mazouz <sychocouldy@gmail.com>
* Move `HTMLInputTypes` type to global declarations
* Add missing app import
* Export options interface
* Remove unused method
* Add random element ID generator
* Add attrs for Page component
Full rewrite needed later
* Provide correct attrs
* Add missing a11y attributes for help text and labels
* Update TSDoc comment
* Allow Children to be passed for label/help text
* Extract setting types to arrays
* Make Page class abstract; fix incorrect Component generic call
* Mark AdminPage as abstract
* Mark `content` as abstract
* Revert "Move `HTMLInputTypes` type to global declarations"
This reverts commit c900cb3f6d.
* Restore TSDoc on HTMLInputTypes type
* Fix typo
Co-authored-by: Sami Mazouz <sychocouldy@gmail.com>
* Rename Button file
* Convert to TS
* Add debug warning helper
Fires `console.warn`, but only when the forum is in debug mode. Can help to inform extension developers of possible issues with their JS code.
* Simplify button content template
* Rewrite Button component
- Prefer `aria-label` over `title`
- Don't duplicate button content to `title` attribute
- Warn in debug mode if button has no accessible content
- Use modern JS/TS syntax (`||=`, spread, etc)
* Update to work with new Button component
* Update warning
Co-authored-by: Matt Kilgore <tankerkiller125@gmail.com>
* Fire warning in `oncreate`
* Format
* Make Button have extensible Attributes type via generics
* Update args type
* Update js/src/common/components/Button.tsx
Co-authored-by: Matt Kilgore <tankerkiller125@gmail.com>
Co-authored-by: David Sevilla Martin <me@datitisev.me>
Co-authored-by: Alexander Skvortsov <sasha.skvortsov109@gmail.com>
* refactor: Avatar classes refactor
* refactor: Badge classes refactor
* chore: Remove commented dead code
* chore: Remove SignUpModal dead CSS code
Flarum seem to have had some kind of user display in the sign up modal
on successful sign up, which no longer exists.
https://github.com/flarum/core/blob/v0.1.0-beta/js/forum/src/components/SignUpModal.js#L111
* chore: Deprecate unneeded vendor mixins
* chore: Normalize property values format
Co-authored-by: David Wheatley <hi@davwheat.dev>
* chore: Remove @-webkit-keyframes
* chore: Combine animation properties
* chore: Avoid `all` for transition
* chore: translate3d is no longer necessary for hardware acceleration
* fix: Lost cursor pointer to normalize update
* chore: Use CSS variables for more things
* chore: Remove unecessary overspecification
Co-authored-by: David Wheatley <hi@davwheat.dev>
* Add extra feature to a11y focusring mixin
* Add visually hidden CSS class and mixin
* Visually hide checkboxes (keep in focus/a11y tree)
* Place checkbox focus ring around display element
* Improve mobile checkbox/switch accessibility
* Start of conversion to CSS variables
* Use variable for Badge colors
* Use variable for avatar bg
* Use variable for user card bg
* Use css variables for hero
* Use css variables for buttons
* Use css variables for sidenav links
* Cleaner style attr
Co-authored-by: David Wheatley <hi@davwheat.dev>
* Limit height of code blocks
Users often post lengthy code or configuration listings which makes following the actual discussion difficult. Therefore we limit a code block by half a screen while still being able to scroll through the code listing itself.
* Define a minimal code block height for small screens
* Add max-height compatibility for browsers that don't support `max()`
See https://caniuse.com/css-math-functions
* Less has a built-in `max` function, so we need to escape this value
Co-authored-by: David Wheatley <hi@davwheat.dev>
* Add `Post-footer--empty` class if the post footer contains no items
* Hide post footer when it has class `Post-footer--empty`
* Swap to `:empty` pseudoselector
* Prefer ternary operator
* Fix typo
With remember from cookie, in certain edge cases, the middleware would
try to load a session which hasn't been instantiated as this middleware
is excluded for the client. Excluding the remember from cookie
middleware will resolve this as authentication is done using the
RequestUtil and ActorReference regardlessly.
The FilesystemManager has changed to also allow to override
the config while resolving a filesystem.
This PR adds the argument and applies it if provided.
Flarum doesn't fully use Laravel's cache system, but rather
creates and binds a single cache store.
See \Flarum\Foundation\InstalledSite::registerCache
Since certain config options (e.g. withoutOverlapping, onOneServer)
need the cache, we must override the cache factory we give to the scheduling
mutexes so it returns our single custom cache.
In dd8323ee36, insertText was modified from the original to work with reply mentioning. This was done due to a misunderstanding of the API: the selection range isn't the selection to replace, but rather the final selection state after replacing the *current* selection with the text. This commit restores the original, correct implementation of insertText and instead adjusts the `insertBetween`method of BasicEditorDriver to set selection state before executing `insertText`.
Fixes https://github.com/flarum/core/issues/2877
Currently, when groups are edited, the new groups flicker, but the UI soon reverts to the old groups. This is because the returned API response has the old group values. This, in turn, is because we eager load groups, and when we sync the new group relation, that doesn't update the groups saved in memory. By unsetting the relation, we make sure the right groups are returned (and also available to the GroupsChanged event).
See https://github.com/flarum/core/issues/2514
The textarea in the CustomFooterModal was much larger than in the other appearance page modals, and did not use a monospaced font. Turns out the other 2 were explicitly specified in the less. This commit adds a class that can be applied to all these modals for simpler maintenance.
Fixes https://github.com/flarum/core/issues/2865
In b2d053f686, I tried to be clever and create a new KeyboardNavigatable object as a return value for `when`. My approach to cloning was incorrect, and caused the util to break entirely.
My original intent for having this "clone"-based behavior is that a single KeyboardNavigatable instance could be created with multiple listeners, and then "cloned" like this with different "activators" registered via "then" calls. In hindsight, this change introduces more issues than it solves: outside of just not working, the cloned "KeyboardNavigatable" instances have shared internal state (the set of callbacks), and each has write access to this internal state. This is a recipe for unpredictable behavior and confusing bugs, so best to keep things simple for now, and maybe introduce more functional behavior in later releases.
Fixes https://github.com/flarum/QualityAssurance/issues/25
This fixes an error where an empty notification list wouldn't show the "empty" text.
It also simplifies flow of logic and breaks the component up a bit for readability.
* Extender docblocks cleanup
* Excplicit type hinting in extenders
* Bring method under constructor
* Mark some classes and methods as internal
* Remove beta references
Co-authored-by: Clark Winkelmann <clark.winkelmann@gmail.com>
* Update core to use new Webpack and TSConfig
* Bump webpack dep
* Update JS build action
* Copy custom `.d.ts` files to `dist-typings` folder on typings compile
* Run workflow against action v2
This allows us to have a moving tag, like first party actions have.
* Remove bundle analyzer from core
* Use webpack config 0.1.0-beta.16.2
* Add note about checking flarum-tsconfig
This naming is clearer as to the intended effect. Changes include:
- A migration to rename all permissions
- Updating the seed migration to use the original naming from the start
- Replacing usage of the old names with new names in code
- Throwing warnings when the old names are used.
- Convert KeyboardNavigatable to TypeScript, as that is used internally here.
- Convert search sources to TypeScript
- Convert Search component to TypeScript
- Convert Search States to Typescript
- Add `getInitialSearch` to `SearchState`
- Fix search disappearing on page reload / direct link
Data migrations (seed default groups, seed default permissions) are deliberately excluded.
This also allows us to remove a lot of now unnecessary public API from the migrator and migration repository.
- Change index files to ts
- Remove deprecated EditUserModal from forum compat
- Remove b14-specific error
- Remove transChoice method (ICU should be used instead)
- Translator to TypeScript
- Small JS => TS cleanup
* Trivial js => ts change
Co-authored-by: David Wheatley <hi@davwheat.dev>
* Add Tooltip component to common
Will be used to provide backwards compatibility when we switch to CSS tooltips.
All other methods of creating tooltips are deprecated and this component-based method should be used instead.
* Modify direct child instead of using container element
Instead of using a container to house the tooltip, we'll now modify the
first direct child of the Tooltip component.
The Tooltip component will ensure that:
- children are passed to it
- only one child is present
- that child is an actual HTML Element and not a text node, or similar
- that child is currently present in the DOM
Only after all of the above are satisfied, will the tooltip be created
on that element. We store a reference to the DOM node that the tooltip
should be created on, then use this to perform tooltip actions via
jQuery. If this element gets changes (e.g. the tooltip content is
updated to another element) then the tooltip will be recreated.
If any of the first 3 requirements are not satisfied, an error will
be thrown to alert the developer to their misuse of this component.
To make this work, we do need to overwrite the title attribute of
the element with the tooltip, but this is the only solution other than
specifying `title` as an option when making the tooltip, but this is
not accessible by screenreaders unless they simulate a hover on the
element.
* Add warning about component overwriting `title` attr
* Update previous uses of Tooltip component
Frontend extenders exist in a weird state of limbo, where they are technically defined, but aren't used or tested at all. In da5db714c2, we shifted from passing `extension.extend` to `flattenDeep` to calling `flat` on `extension.extend`. If an extension doesn't define extenders (as is the case for most extensions), the change breaks the forum. All we do here is add a null check.
* Remove `lodash-es` dependency
* Replace `escapeRegExp` with home-made util
* Replace `throttle` with `throttle-debounce` library
* Use native browser methods for `deepFlatten`
We need a polyfill for iOS 11 and below. I think using a native method with this polyfill is better than having our own function instead, even if the bundle size is ~150B more.
* Save a few bytes in `escapeRegExp`
* Fix typo in comment
* Undo import re-organisation
* Use spread instead of slice
* Use smaller Array.flat polyfill from MDN
* Export new utils in `compat.js`
* Add focus ring mixin
These mixins allow us to restore default browser focus rings on elements which no longer have them.
* Add info about custom outline styles; use `#private` namespace and fix mixin name
I just learned that Less has namespaces! https://lesscss.org/features/#mixins-feature-namespaces
- revisions now use <asset>.<type>?v=<revision> instead of <asset>-<revision>.<type>- remove deprecated filename for revision method
- reconsider use of cache differentiator and implement something that
prevents recompiling css every single time
- allow force recompilation
* Commit initial WIP code
* Fix squashed grid on mobile
* Add pagination support; rename to userList
* Improve grid sizing
* Improve grid row shading
* Move EditUserModal to common
* Add link to profile page in grid
* Use Less styling vars
* Move EditUserModal translations to lib
* Add edit user button to grid
* Fix incorrect profile link priority
* Update profile link translation key
* Add priorities to other columns
* Add group badges to grid
* Add username to profile link tooltip
* Organise imports
* Use variable for header border bottom color
* Fix broken export
* Add total user count to API payload's metadata
* Add new metadata to ApiPayload type
* Implement correct page number
* Remove debug code
* Use function to get the total pages
This allows us to use the raw count elsewhere in the component (pssst... check the next commit!)
* Center profile link in column
* Add profile link header
* Show total users above table
* Use ItemList's itemName property for column data attributes
* Add user email column, hidden by default
This column is hidden by default using a placeholder email and blur filter. These are then removed when the visibility toggle is pressed.
This prevents any over-the-shoulder accidental data leakage, as emails are classed as PII under GDPR.
* Fix incorrect tooltip translation keys
* Add extra padding between email and visibility toggle button
* Prevent selection of blurred email
* Fix incorrect icon state for email toggle
* Update API response type to include metadata (for now)
* Increase number of users per page to 50
* Update compat files with new locations
* Format
* Add @deprecated notices for forum compat export
* Use AdminPayload for user count instead of supplying as REST API metadata
* Make nav look less squashed using bottom margin
* Suppress TS warning
* StyleCI fixes
* Fix TS error
* Update based on review comments
* Rename user list -> users
* Rename internal instances of user_list to users
* Fix formatting
* Use CSS custom properties for the table column count
* Use .Button--icon instead of custom style
* Make fake email more realistic length
* Add a11y attributes
* Use padding bottom instead of margin bottom for page spacing
* Make compatible with new CSS LoadingIndicator
I won't let it break here! :P
* Integrate profile link into username column
* Don't force columns to be 300px
This made the grid look very bloated and intimidating -- lets instead increase the padding between items and make it only the width it needs to be.
* Center edit user button in column
* Increase spacing between email and visibility toggle button
* Rename `statistics` to `modelStatistics` in Admin payload
This prevents any possible conflicts with core and `flarum/statistics`. We might want to consider migrating the stats extension to extend this object in the future.
* Update comments, fix TS error
* Various translation key changes
* Change gmail.com -> example.com
* Stretch 'edit user' button to entire cell size
* Update translations
* Is the YAML formatted right this time? 🙈
* Remove email placeholder
Fixes an issue where the table would jump if an email was unhidden that was longer than the placeholder.
* Re-order lib translations
* Clicking blurred email now unblurs
* Correct header class
* Improve edit user button centring
* Improve vertical row item centering
* Fix incorrect column length in aria attribute
* Use .Button--text!
* Update Loading Indicator
- Fix mistake in LoadingIndicator Less
- Middle align the loading indicator when inline
- Fix Loading Indicator not correctly accepting container class names
- Add inline and block attributes
* Fix loading indicator in composer
* Fix loading indicator on notification list
* Fix loading indicator on discussion page
* Fix loading indicator on button
* Update more uses of loading indicator
* Fix loading indicator in Search box
* Fix AvatarEditor loading spinner
* Set default spinner props
* Replace "tiny" with "small" in Less
* Improve spinner vertical centring in buttons
* Reduce size specificity
* Use single attribute for block/inline
* Use new display attribute
* Use classes for different sizes
* Use `display=block` by default
#b62debf031f1d3aec9cb5e92d9df54cb8ab3a3b1 and #b6f0b01307884b11388eff1ae2d814b7f57715aa
both added/improved searching tests, but did so in separate files. As a result, the tests did not consider each other, and when both were merged, started failing. This commit combines the tests into one file that tests both order and search in titles.
* Fix searching titles in discussions
* Apply fixes from StyleCI
* Fix tests
* Distinct by discussion ID
* Replace distinct with groupBy
Co-authored-by: Alexander Skvortsov <askvortsov1@users.noreply.github.com>
* WIP: Use Laravel filesystem interface where possible
* Drop vendorFilesystem
* Support getting URL of cloud-based logo and favicon
* FilesystemAdapter should always be cloud
* Get base avatar URL from filesystem adapter
* Restore deleted getAsset method
Co-authored-by: Alexander Skvortsov <askvortsov1@users.noreply.github.com>
Identified as a potential issue in https://github.com/flarum/core/pull/2650
When typing, the keyboard generally obstructs half the screen. However, when the keyboard is closed, search results don't expand to take up full space.
This was originally introduced in 3612ca7aca, but has not seen usage, since usually when the session needs to be modified, the request is available.
It causes issues with certain queue drivers, as it can't be serialized.
It's also not entirely accurate, as a user can have multiple sessions at once. Therefore, a given session is a property of the request, not of the user.
The reason this causes issues in the Queue is that when a Job has payload that consists User(s), the Queue will try to serialize that. Serializing the User object will require serializing the session too; this causes a Serialization of Closure is not allowed error, see image.
One can circumvent that in many ways, the most obvious one is adding a __sleep and __wakeup implementation in the User class (or the session handler). But as we aren't really using the session on the User model anywhere in core, bundled or most community extensions it is best to simply detach this from the user.
* Add an ActorReference class to store the actor `$request->getAttribute('actorReference')->getActor()`
* Add a middleware to inject the actor reference
* Deprecate `$request->getAttribute('actor')`
- Adds a field to QueryCriteria that determines whether the sort provided is the controller's default sort
- Set this field to true iff sort not in query params. Default it to false
- Override $sort if a new default sort has been set on search state, and the param is true.
- Add tests!
* Add option to build with webpack bundle analyzer
* Bump npm to v7 as recommended in actions/setup-node#213
* Workaround for npm/cli#558
* Add missing dep
* Bump dependencies and add missing typing libraries
* Fix expose-loader breaking changes
* Expose jQuery using its own typings instead of ours
* Extend jQuery typings with our own custom $.fn helpers
* Use jQuery typings for Component's `this.$` attribute
* Format webpack config file
* Use Spin.js 3.1.0
* Add code scanning workflow to identify common issues
* Don't run CodeQL if the only changes in a push/PR are .less or .md files
* Change cron
* Change workflow name to include language
* Make indents consistent with other workflows
* Pin 3rd party action
* Pin GitHub-maintained actions to tag
* Bump Bundlewatch Node.js to v14 LTS
I have no clue what my thought process was when creating this workflow
initially. Thrown this in here as it's a minor change and it's silly to
make a PR just to update this number, in my opinion.
The ApiSerializerTest was added before the ApiController extender, so I used a workaround at the time to check for the existence of the relationships on the serializer.
It's a better implementation than declaring a second class in the same file, which can confuse IDEs. Furthermore, FakeApp shouldn't be used outside this file.
* Add AccountActivationMailerTrait and use in AccountActivationMailer and SendConfirmationEmailController
* Remove prefix
Co-authored-by: Alexander Skvortsov <38059171+askvortsov1@users.noreply.github.com>
* Install Prettier only, instead of all deps
* Allow running on workflow dispatch
Allows manually triggered CI runs by org members
* Update Node to latest LTS; update step descriptions
(Below steps already performed, but kept for future reference.)
Head here to get auth ID: https://service.bundlewatch.io/setup-github
Create repo secret called `BUNDLEWATCH_GITHUB_TOKEN` with the token inside
Core source code should contain things necessary for core to run. Development tooling like this belongs in external packages, like the upcoming Flarum CLI.
Implement custom accessible dropdown toggle labels for forum components
Making the a11y label more specific to the specific action it performs is critical for good UX with assistive technologies.
When the composer is opened while scrolled to the absolute bottom of the page (via hitting the "reply" button, `window.scrollTop` has a value of ~600px greater than it should. This doesn't seem to be the composer element's height (which appears to be 0 at the time). This incorrect scrollTop positions the composer off screen, which causes Safari to freak out and shake the element violently as it tries to scroll to the cursor (which is now off screen).
We can get around this by calculating scrollTop ourselves.
Fixes https://github.com/flarum/core/issues/2683
In the filterer refactor for ListPostsController, the filter key was changed to `author` for consistency with the AuthorFilterGambit used in discussions. This commit adds a deprecated `user` filter back in for a release to allow for a graceful transition
- update actions ci
- include json for 4 spaces tab
- provide output int for process code exit
- adhere to parent type hint of builder
- mailer instance now needs a name, multiple can be instantiated
- getOriginal now uses mutators in the model
- Temporarily loosen MailableInterface requirements. This avoids an immediate BC break for classes in extensions that implement this interface.
- Temporarily provide (and autoload) old symfony translator interface
- make queue exception handler compatible with the contract of L8
- Update phpunit schema for newer version
- Update phpunit assert calls for newer version
* Rename `app` helper to `resolve`, deprecate old version
* Rename $this->app to $this->container in service providers
We no longer couple Flarum\Foundation\Application to the Laravel container; instead, we use the container separately. Changing our naming to reflect that will make things clearer.
- Make session token-based instead of user-based
- Clear current session access tokens on logout
- Introduce increment ID so we can show tokens to moderators in the future without exposing secrets
- Switch to type classes to manage the different token types. New implementation fixes#2075
- Drop ability to customize lifetime per-token
- Add developer access keys that don't expire. These must be created from the database for now
- Add title in preparation for the developer token UI
- Add IP and user agent logging
- Delete all non-remember tokens in migration
Updated GroupFilterGambit to prevent hidden groups being visible where they shouldn't be and to ensure that only the selected groups are returned on a search. Fixes#2559
- Split user edit permision into edit attributes, edit credentials, and edit groups
- Only Admins can edit Admin Credentials
- Only Admins can Promote/Demote to/from Admin
Followup to https://github.com/flarum/core/pull/2524.
In that PR, we fixed infinite scroll for the panel, but accidentially used document.body. Since scrollTop on body is (almost always) 0, this means that new pages of notifications were loaded on every scroll, which quickly becomes overwhelming. Instead, we can use `document.documentElement` for getting scrollTop, which results in the expected behavior.
* Don't update scrubber while post pages loading
This alleviates the scrubber bouncing around when scrolling up on iOS
* Throttle loadMore loadPrevious
Throttle loadMore and loadPrevious functions to alleviate skipping over pages and pages of posts during one scroll. This sometimes happens on iOS
Adds a rule to the discussion list less file which targets touch devices whose primary way of interacting does not include a mouse / ability to hover. For those devices the toggle button is hidden which fixes the double tap issue.
It can be very annoying if we want to use something like boolval, but have to define an entire anonymous function to pass it in. This PR adds support for tpassing it in directly as a string, like is posible with User::registerPreference.
Model Visibility extender does not take into consideration missing
dependencies. For instance flarum/tags adds a policy on the Flag model
from flarum/flags. But because flarum/flags might as well not be
installed we need to check for the existence of that model. Otherwise
the exception is thrown or flarum fails to boot.
Since some boolean settings might be stored as string "0" or "1", the previous system no longer works, and it always sets the switch to true. The "no setting" check has been changed to reference `undefined`, so now the switch will only be defaulted to `true` if the setting truly hasn't been set.
Fixes https://github.com/flarum/core/issues/2574
Improves calculations for determining whether we are at the bottom of the notifications panel (which would trigger infinite scroll). This should be particularly effective in fixing issues on smaller screens.
We previously used the tobscure/m.attrs.bidi github repo, but that repo was recently taken offline. We decided to integrate it as a util instead of publishing it as a separate package since we seem to be the only project using it, and adopting it into a new project requires barneycarroll/mattr, which does not seem to be used anywhere.
The code added here was taken from https://github.com/askvortsov1/m.attrs.bidi, a fork (without changes) of the tobscure repo. Support for alternative module systems and ways of registering bidi were removed, and the file was formatted in compliance with our prettier config.
Historically, extensions using subscribers has caused problems because subscribers were constructed/applied at extension boot. This caused some classes (e.g. UrlGenerator) to be resolved early, breaking parts of Flarum. For this reason, subscriber support wasn't included in the initial version of the Event extender.
However, updating extensions has shown that there is a legitimate use case for subscribers in organizing clean code; for instance, core's own `DiscussionMetadataUpdater`.
This commit introduces support for subscribers, but only applies them after the app has booted, which avoids the early resolution issues. Since event listeners/subscribers are only intended to be used with domain events, which would never be dispatched during app boot, the late activation of subscribers should not cause issue.
Under InnoDB, database entries created in transactions are not processed by fulltext indexes until the transaction is committed. To work around this, cases that test fulltext search have been split off into a separate class that adds and removes seed discussions/posts outside of transactions during setUp/tearDown.
Some tests need to change settings, but since MemoryCacheSettingsRepository caches settings in-memory, those changes aren't reflected. The new `purgeSettingsCache` removes it from the container, eliminating that cache.
For UserTest, we also need to regenerate the display name driver, since that's set statically on boot, before we'll get a change to clear the settings cache.
Before transactions, each test class would need to explicitly state starting state for permissions, which made the initial permission configuration somewhat arbitrary. Now, we might as well use the initial state of the default installation.
One of the User show_test tests has been commented out until
Previously, the `prepareDatabase` method would directly modify the database, booting the app in the process. This would prevent any extenders from being applied, since `->extend()` has no effect once the app is booted.
Since the new implementation of `prepareDatabase` simply registers seed data to be applied during app boot, the workaround of sticking this seed data into `prepDb` is no longer necessary, and seed data common to all test cases in a class can be provided in `setUp`.
When needed, app boot is explicitly triggered in individual test cases by calling `$this->app()`.
Making the $user argument nullable prevents this unnecessary exception, and doesn't introduce any issues since we check that $user exists as part of the method.
Fixes https://github.com/flarum/core/issues/1959
These transform lines are known to cause issues on iOS, and were added to hack around chrome issues that have since been fixed upstream.
Due to a commit by @fabpot in october, the mimetypes symfony class
now re-orders the shortened mimetypes that are returned when looking
up based on header mimetype. Our validator uses the first key, pops
the prefix off and then matches against our hardcoded array.
I've added a constraint to symfony/mime ^5.2.0 which ships with this change.
This constraint is fully compatible with our current lineup. In addition
I changed the hardcoded array to use the first entry from symfony mime types
now `jpg` instead of `jpeg`.
- Anchor scroll when inserting post placeholders
- Indicate that pages are loading at start of `loadPage`, which allows `onscroll` to not request that multiple pages be loaded at the same time
These changes are particularly applicable to firefox, where previously, dozens of posts could be skipped at a time if scroll up was held while at the top of the viewport.
Policy application has also been refactored, so that policies return one of `allow`, `deny`, `forceAllow`, `forceDeny`. The result of a set of policies is no longer the first non-null result, but rather the highest priority result (forceDeny > forceAllow > deny > allow, so if a single forceDeny is present, that beats out all other returned results). This removes order in which extensions boot as a factor.
- Support slug drivers for core's sluggable models, easily extends to other models
- Add automated testing for affected single-model API routes
- Fix nickname selection UI
- Serialize slugs as `slug` attribute
- Make min search length a constant
Because invokable class objects are not directly called and instead it's the callback wrapper that calls these objects, it's currently not possible to receive arguments by reference on an invokable class.
To fix this we pass the arguments by reference by default when calling the object in the callback wrapper.
We are instantiating our own queue handling factory which returns the
flarum.queue.connection binding no matter what. The queue Worker and
other queue related code rely on this manager to get its thing going.
Therefor we need to re-use our own factory everywhere, including in
the worker.
Although native browser scroll restorations have become quite powerful, it interferes with Flarum's PostStream, so if we're on a DiscussionPage, we use manual scroll restoration.
In the PostStream, `this.visibleEnd` represents the index of the last post + 1, but `loadNearIndex` treated it as if it was the index of the last post. This means that executing `goToIndex` on the post stream's current `this.visiblePost` didn't load new posts, and as a result, the requested scrolling did not occur.
This prevents an edge case where `app.discussions` is considered empty while the new page is loading, and as a result, the side pane isn't set as "enabled". Then, if the pane has previously been pinned, when the page loads and the side pane appears, it covers up part of the discussion page.
Fixes https://github.com/flarum/core/issues/2471
- Extensions now have their own pages
- The API for extensions to register permissions and settings has been overhauled via the `flarum/admin/utils/ExtensionData` util
- An extension grid has been added as a widget to the Dashboard page
- Split DispatchRoute. This allows us to run middleware after we figure out which route we're on, but before we actually execute the controller for that route.
- By making the route name explicitly available to middlewares, applications like CSRF and floodgate can set patterns based on route names instead of the path, which is an implementation detail.
- Support using route name match for CSRF extender, deprecate path match
- Standardize signatures and variable names for extenders that take callbacks
- Adjust model extender docblock to clarify that default calue can't be an invokable class.
- Make invokable classes provided to Model->relationship
- Add integration tests to ensure Model->relationship and User->groupProcessor extenders accept callbacks
- Extract code for wrapping callbacks into central util
- Deprecated all events involved with Formatter
- Refactor ->configure() method on extender not to use events
- Add extender methods for ->render() and ->parse()
- Add integration tests
- Reintroduce cancellable scroll top on page change
- IndexPage: rely on browser to retain scroll position on page reload
- Remove obsolete browser hack
- Fix broken selector
- When on mobile, only retain scroll for IndexPage if we're coming from a discussion
- Move app.cache.scrollTop save into `onbeforeremove` so we make sure to do it before DOM is detached
The default first post number is '1', so we scroll to that if we're calling `m.route.set` without a `near` parameter, as that means we're scrolling to the top.
This was present in beta 13's implementation, but accidentially omitted in 988b6c9.
We also remove unnecessary typecasting for simpler logic and increased consistency with beta 13.
The current implementation for checking whether we are on a discussion page, and going to a discussion page, checks the route we are going to. This is problematic, because the route resolver represents the route being considered, not the route we are currently on. So, if we are currently using a DiscussionPageResolver, we must be going to a route handled by DiscussionPage. Instead, we need to check the route that we are currently on, which is done via `app.current.matches(DiscussionPage)`.
- mapRoutes: don't wrap components in resolvers if they are already resolvers
- Extract defaultResolver into its own class
- Allow either route resolver instances, or components with an optional resolverClass which should accept the component and route name in its constructor.
- Introduce a resolver for DiscussionPage, so that routing from one post to another on the same discussion triggers a scroll instead of rerendering
- Add an index to reply placeholder so we can scroll to it directly when replying.
- Stop pretending that the currently broken `bottom` scroll functionality works, and explicitly call it `reply` scrolling to be clearer
- Directly get target from state
- Explicitly scroll to placeholder on reply
- Clean up scrollToItem code a bit
- Account for edge case where index is undefined when scrolling to post
Co-authored-by: Wadim Kalmykov <36057469+w-4@users.noreply.github.com>
Essentially, whenever a route is loaded, we add a key to that component. If the key changes, the page completely rerenders. Switching between different routes handled by the same key triggers those rerenders.
- If the fadeIn animation is specified on the PostStream class itself, any time we add/remove another animation, it will redo fadeIn. To avoid this, we move fadeIn into it's own css class, which is applied, and then immediately removed after the animation is completed to ensure it only runs once.
- The "fix" for flashItem was actually broken, as it resulted in 'flash' never being removed, so we never went back to .PostStream's fadeIn. We adjust flashItem to ensure that '.flash' is removed. We also remove 'fadeIn' in case it hasn't yet been removed in oncreate.
Make header and navigation components redraw after page components. Page components manipulate the header (state), but the header redraws before the page on route change. By changing the mount order, we change also the redraw order.
If the error isn't a 409, we'll want to re-throw the error so it'll be handled by the default system (showing an alert).
For simplicity, we can also move 409-handling logic out of setTimeout.
Finally, we adjust the timeout to 300 milliseconds to match the modal transition animation length.
* Revert "Fix header contents moving when opening modal (#2131)"
* Fix header contents moving when modal opened/closed.
Conditionally apply the navbar-fixed-top class only when needed, so that we can take advantage of it without always having the navbar in position:fixed, as was done in the previous solution. That resulted in a clash with custom headers.
* Show header on refresh of scrolled page
Due to some magic in Mithril 0.1's context:retain flag, some DOM elements were cached across page reloads. Since that has been eliminated, if we refresh the page and we are scrolled down, the "affix" class which makes the header fixed (and as a result, visible) isn't applied until the first scroll. We fix this by running ScrollListener.update() immediately to set initial navbar state.
- rewrite the queue handling for illuminate 6+
- implement missing maintenance mode callable for queue Worker
- Ensure we resolve append the queue commands once the queue bindings are loaded
- Override WorkCommand because it needs the maintenance flag. It tries to use
the isDownForMaintenance method from the Container assuming it is a Laravel
Application. Circumvented this issue by resolving our Config from IOC instead.
When on a discussion page, the URL changing doesn't always mean we've moved to a different page. In our custom rerender logic, we only want to call `this.onNewRoute()` if the page has actually changed.
In v5.8, Laravel expanded email validation logic to closer match the RFC. This, however, allows emails that aren't conventional (for example, emails lacking a TLD). This commit changes Flarum's UserValidator to use the `email:filter` validator, which uses PHP's filter_var, and is the pre-5.8 behavior.
See https://laravel.com/docs/5.8/validation#rule-email
After we scroll to a post, we redraw to render post content. We then update the scrubber again so its height is accurate. This commit moves that update to AFTER our adjustment of scroll position, so that scrubber height is based on actual post heights. This fixes some subtle scrubber glitches.
Let's stay consistent with previous behavior, and run these on "internal route change" (same component handles different route) as well as on initial render of a page component.
Currently, the controls are on a new line due to the container div. We want to wrap ALL children of the alert, including the controls, in the container div.
We need to split it into a separate class so that we can add modify the alert vnode AFTER the alert component's `view` logic has been applied.
From using PhpStorm to try and see if the autocomplete works properly, it appears as it doesn't. The intention was to not have to import Mithril every time we wanted to type something with Mithril.*, but that doesn't seem to be possible - and it's not a big deal anyway
During the frontend rewrite, we introduced mithril patches for a `route` attr, and for `m.stream`. Later, we decided not to go that route, but not to remove the patches yet to avoid breaking extensions while we were finalizing the replacements. We can now remove these.
Other BC layers are for things from before beta 14, so those remain in place.
- Use Mithril.Attributes as base for ComponentAttrs, remove =any from class signature for Component
- Convert Alert to TypeScript, introduce AlertAttrs interface
- Convert AlertManagerState to TypeScript, add overload signatures for `show`, introduce AlertState interface for stored Alerts.
- Set ComponentAttrs as default T for Component
- Make attrs in AlertAttrs optional
- Add AlertIdentifier interface, simplify show type signature
- Remove mithril patch shim, as all patches onto m are now deprecated
- Use Mithril.Static for shim
- Ensure that the discussion list is cleared before it is updated with fetched results
- Rename `clear` to `deferClear`, improve documentation to make its purpose clearer.
- Call onNewRoute when page changed with same component in DiscussionPage and UserPage
- Make app.previous and app.current changed in onNewRoute, not in oninit. This way, when the route is changed, but still handled by the same component, a new PageState object will still be created.
While more pleasant from an FSM standpoint, comparing the current targetPost to the previous one does not work if goToNumber is called twice in a row for the same post. For instance, if a user clicks the mentions link to a post twice, the post stream breaks.
In some cases, such as if we've stickied a post, an event post
may have been added / removed.This means that `this.visibleEnd`
and`this.count()` will be out of sync by 1 post, but we are still
"viewing the end" of the post stream, so we should still reload
all posts up until the last one.
Because the Slidable class was always added on creation, it was lost every time the class list changed (in this case when the discussion was hidden/unhidden which added/removed DiscussionListItem--hidden class). So by determining the Slidable class's presence in elementAttrs() method, it guarantees it always properly set.
This extracts another real class for dealing with the configuration options stored in `config.php`. The idea is to reduce the scope of the `Application` class and make it easier to inject exactly what's needed (rather than an array, which is complicated, or the bloated `Application` class).
While seemingly correct, an onremove method in Modal that triggers animateHide is problematic, because if one modal is opened from another, the one currently open will be removed from the DOM, triggering animateHide, and closing the new modal.
To compensate, an onupdate method now closes a modal if one is open but shouldn't be; this supports the functionality of the old method when the modal is closed not from the modal instance itself (e.g. app.modal.close())
This is not ideal, but necessary. We should consider eventually expanding the modal system to support showing multiple modals at the same time (stacked over each other). Then, we can move this back to individual modals.
When the page is scrolled, goToIndex is called, or the page is loaded,
various listeners result in the scrubber being updated with a new
position and values. However, if goToNumber is called, the scrubber
will not be updated. Accordingly, we add logic to the scrubber's
onupdate to update itself, but only when needed, as indicated by this
This saves us a LOT of unnecessary calls, and makes scrubber movement smoother.
* Update frontend to Mithril 2
- Update Mithril version to v2.0.4
- Add Typescript typings for Mithril
- Rename "props" to "attrs"; "initProps" to "initAttrs"; "m.prop" to "m.stream"; "m.withAttr" to "utils/withAttr".
- Use Mithril 2's new lifecycle hooks
- SubtreeRetainer has been rewritten to be more useful for the new system
- Utils for forcing page re-initializations have been added (force attr in links, setRouteWithForcedRefresh util)
- Other mechanical changes, following the upgrade guide
- Remove some of the custom stuff in our Component base class
- Introduce "fragments" for non-components that control their own DOM
- Remove Mithril patches, introduce a few new ones (route attrs in <a>;
- Redesign AlertManagerState `show` with 3 overloads: `show(children)`, `show(attrs, children)`, `show(componentClass, attrs, children)`
- The `affixedSidebar` util has been replaced with an `AffixedSidebar` component
Challenges:
- `children` and `tag` are now reserved, and can not be used as attr names
- Behavior of links to current page changed in Mithril. If moving to a page that is handled by the same component, the page component WILL NOT be re-initialized by default. Additional code to keep track of the current url is needed (See IndexPage, DiscussionPage, and UserPage for examples)
- Native Promise rejections are shown on console when not handled
- Instances of components can no longer be stored. The state pattern should be used instead.
Refs #1821.
Co-authored-by: Alexander Skvortsov <sasha.skvortsov109@gmail.com>
Co-authored-by: Matthew Kilgore <tankerkiller125@gmail.com>
Co-authored-by: Franz Liedke <franz@develophp.org>
- This was accidentially introduced when an explicit z-index was added to reply-actions to prevent Post-footer from covering it
- Here, we revert that zindex, while making Post-footer inline-block to stop it from covering everything. We also set height=0 to stop implicitly added height
This is needed to have access to the newly created SuperTextarea
instance (app.composer.editor) directly after calling show().
Discovered when making ext-mentions work with the Composer state
changes. As far as I could reconstruct, a synchronous redraw was also
triggered in this situation before the changes in #2161.
This commit fixes the method `abbreviateNumber` so that it behaves as stated in the JSDoc.
Previously, an input of `1234` would have produced `1K`. With this change, the output will be `1.2K`.
* Fix closing the composer with ESC key
Regression from #2161.
* Remove obsolete method
Regression from #2162.
* Mark method as protected
* Fade in posts in post stream using CSS
This also avoids a double-fade from the JavaScript code, which was
probably introduced in #2160.
* Fix fadeIn for post stream items
Co-authored-by: Alexander Skvortsov <sasha.skvortsov109@gmail.com>
Like previous "state PRs", this moves app-wide logic relating to
our "composer" widget to its own "state" class, which can be
referenced and called from all parts of the app. This lets us
avoid storing component instances, which we cannot do any longer
once we update to Mithril v2.
This was not as trivial as some of the other state changes, as we
tried to separate DOM effects (e.g. animations) from actual state
changes (e.g. minimizing or opening the composer).
New features:
- A new `app.screen()` method returns the current responsive screen
mode. This lets us check what breakpoint we're on in JS land
without hardcoding / duplicating the actual breakpoints from CSS.
- A new `SuperTextarea` util exposes useful methods for directly
interacting with and manipulating the text contents of e.g. our
post editor.
- A new `ConfirmDocumentUnload` wrapper component encapsulates the
logic for asking the user for confirmation when trying to close
the browser window or navigating to another page. This is used in
the composer to prevent accidentally losing unsaved post content.
There is still potential for future cleanups, but we finally want
to unblock the Mithril update, so these will have to wait:
- Composer height change logic is very DOM-based, so should maybe
not sit in the state.
- I would love to experiment with using composition rather than
inheritance for the `ComposerBody` subclasses.
We have used this transitive dependency (via illuminate/support)
for a while, so let's make this explicit.
Incidentally, we now also explicitly require version 2.x - the
previous 1.x branch will no longer be supported after the
upcoming upgrade to Laravel 6.
Refs #2055.
As discussed in my initial review, it seems unlikely that we need
the ability to remove (or otherwise modify) namespaces again.
Therefore, it seems more consistent with other extenders to go
for a "View" extender with a "namespace" method.
Sorry for the back and forth. ;)
Refs #1891, #2134.
This file isn't used anywhere. We should be calling it at some point. It has existed for 5 years.
Renamed function because it makes more sense for name to match file name (not that it matters when building)
This allows us to get started with converting all Flarum JavaScript code to TypeScript.
In addition, we will have time to experiment to find the best Webpack configuration before integrating into flarum-webpack-config.
See flarum/flarum-webpack-config#3.
- Encapsulate app.current, app.previous in PageState objects
- Reorganize Page classes to use one central base class in common
Co-authored-by: Franz Liedke <franz@develophp.org>
* Write source map without creating temp file
Less I/O, and one less place where we access the global path helpers.
* Drop useless app_path() helper
This was probably taken straight from Laravel. There is no equivalent
concept in Flarum, so this should be safe to remove.
* Deprecate global path helpers
Developers using these helpers can inject the `Paths` class instead.
* Stop storing paths as strings in container
* Avoid using path helpers from Application class
* Deprecate path helpers from Application class
* Avoid using public_path() in prerequisite check
a) The comparison was already outdated, as a different path was passed.
b) We're trying to get rid of these global helpers.
* Don't store checkbox states in NotificaitonGrid, use props for loading in Checkbox and Switch, replace preferenceSaver with internal management of loading state
* - Add ID to fields searched in group gambit
- Use joins instead of looping in group gambit
* Add visibility scoping to group gambit
* call IDs userIds
* If group identifier is numerical, treat it as an ID
* Fixes#2157, Explicitly set SameSite value for cookies by making samesite a config option in config.php. Also contains an update for the cookie library dependency
* Deprecate GetDisplayName event
* Add interface for display name driver
* Add username driver as default
* Add code to register supported drivers / used driver as singletons
* Configured User class to use new driver-based system for display names
* Add extender for adding display name driver
* Add integration test for user display name driver
* Add frontend UI for selecting display name driver
* Don't use body as tooltip container, allow notification area overflow
Badge tooltips are using container: 'body', so they can overflow the
notification area. When the user navigates back while a badge tooltip is
showing, the tooltip remains visible.
This commit removes the body container attribute and instead allows the
notificationDropDown to overflow, so badge tooltips aren't cut off.
Instead, this adds overflow: hidden to NotificationList.
Fixes#2118.
* Remove newline
* Use decodeURI instead of unescape & don't close modals
* Add comment
* Don't use a try/catch, clean up the group log code
* Remove double negative
* Format; fix issues from rebasing
In Laravel 5.8, the `Container::tagged()` method was changed to return
an iterator [1].
We only use the result for iteration, or, in this case, to pass a bunch
of "reporters" to the error handler middleware, therefore we need to
accept an iterable here.
[1]: https://laravel.com/docs/5.8/upgrade#container-generators
Apparently, this code was from back when we had a special "extensions"
directory for Composer packages marked as Flarum extensions.
While we're at it, we now inject the Paths instance instead of using one
of the global helpers (which I am trying to get rid of).
Refs #2055.
- Stop trying to implement Laravel's Application contract, which
has no value for us.
- Stop inheriting from the Container, injecting one works equally
well and does not clutter up the interfaces.
- Inject the Paths collection instead of unwrapping it again, for
better encapsulation.
This brings us one step closer toward upgrading our Laravel
components (#2055), because we no longer need to adopt the changes
to the Application contract.
This ensures that default values, date attributes and relationships are properly inherited, when we have deeper model class hierarchies.
This also adds test cases to ensure that inheritance order is honored for relationship and default attribute extender. As there's no way to remove date attributes, the order of evaluation there doesn't matter.
Only users that have the new `viewHiddenGroups` permissions will be able to see these groups.
You might want this when you want to give certain users special permissions, but don't want to make your authorization scheme public to regular users.
Co-authored-by: luceos <daniel+github@klabbers.email>
- Inject contract, not implementation
- Do not dispatch event in test, let the core do that
- Ensure the relevant database tables are reset prior to the test
- Use correct parameter order for assertions
Refs #2097.
- Use private over protected
- Use "public" API for building requests in tests
- Add more assertions
- Formatting
- Use correct parameter order for assertions
Refs #2012.
The test from the previous commit proves this works as intended. :)
This is one more step in trying to avoid the widespread usage of the
`Application` godclass.
Refs #2055.
- Give them a fixed width (independent of font library)
- Center the icons in their column
- De-emphasize the icons by applying a muted color
Fixes#2016, closes#2018.
This avoids injecting the Application god class and assembling default
file locations in multiple places.
In addition, we no longer use the `MountManager` for these uploads. It
only added complexity (by moving tmp files around) and will not be
available in the next major release of Flysystem.
Note: Passing PSR upload streams to Intervention Image requires an
explicit upgrade of the library. (Very likely, users have already
updated to the newer versions, as the old constraint allowed it, but
we should be explicit for correctness' sake.)
Instead of converting the uploaded file object to an UploadedFile
instance from Symfony, because the latter is compatible with
Laravel's validation, let's re-implement the validation for the
three rules we were using.
The benefit: we can now avoid copying the uploaded file to a
temporary location just to do the wrapping.
In the next step, we will remove the temporary file and let the
uploader / Intervention Image handle the PSR stream directly.
* Made the console command system extender-friendly
* Added console extender
* Added ConsoleTestCase to integration tests
* Added integration tests for console extender
* Marked event-based console extension system as deprecated
* Moved trimming command output of whitespace into superclass
* Renamed 'add' to 'command'
* Added special processing for laravel commands
* Code style fixes
* More style fixes
* Fixed $this->container
No need for breaking backwards compatibility here - encapsulating the
logic for `getAttributes()` in one place turns out to be quite useful.
Refs #1931.
We need to get rid of this god class, as Laravel's Application contract
gets even bigger with 5.8. To avoid having to add all these methods, we
should try to stop using it where we can.
This gives extension authors time to add the new `getAttributes()`
method to their `BlueprintInterface` implementations.
The layer itself is easy to remove in beta.14.
This separates sending each individual mail, thus hardening the app.
There are still many improvements possible in this code, e.g. chaining
these commands, making emails just another notification type and
listening to the Notify event instead. We can postpone this to a later
stable release.
Forces notifications into a dedicated SendNotificationsJob and passed
to the queue.
- One static method re-used in the job ::getAttributes, is that okay or
use a trait?
- Do we want to use this solution and refactor into a better Hub after
stable, postpone this implementation or use it in b11?
The getEnabled method returns all extensions (previously) enabled, yet manually
uninstalled through composer. This does not reference the exact, current state
of the forum. getEnabledExtensions returns a list where the getEnabled list
is filtered on the extensions found in the composer installed.json file.
There are two more API integration tests that explicitly add the
"Authorization" header right now:
- `Flarum\Tests\integration\api\authentication\WithApiKeyTest`
- `Flarum\Tests\integration\api\csrf_protection\RequireCsrfTokenTest`
These two specifically test authentication, so in those cases the
explicitness seems desirable.
I feel this makes the parameters a bit more clear, does not rely on
inheritance (you can only inherit from one class, but we might want more
of these helpers in the future), and has less side effects (e.g. no
creation and, more importantly, deletion of users in the database).
Refs #2052.
* Updated PHP requirement to 7.2
* Set wikimedia less version to 1.8
* Indentation fix on composer json
* Revert "Set wikimedia less version to 1.8"
This reverts commit 22d862fd98.
This would be the only breaking change in beta.12. Let's stick to our
backwards compatibility promise / intentions as much as possible, even
if we assume the class has not been used anywhere.
This BC layer will be removed again for beta.13.
Refs #1975.
This extender implements several methods for extending the new error
handling stack implemented in #1843.
Most use-cases should be covered, but I expect some challenges for more
complex setups. We can tackle those once they come up, though. Basic
use-cases should be covered.
Fixes#1781.
The forum title is already used as the display name for the sender email address, so having it in the subject is just a duplication and waste of space.
Implements the remove, insertBefore, insertAfter and replace
functionality for middlewares.
The IoC container now holds one array of middleware (bindings) per
frontend stack - the extender operates on that array, before it is
wrapped in a middleware "pipe".
Fixes#1957, closes#1971.
By commenting out the new methods on the `DriverInterface` and checking
for these methods' existence before calling them, old implementations in
extensions will not break right away.
This will be removed after beta.12 is released, giving extension authors
about two months time to update their extensions.
This is better than the current system, as it adds transliteration rules
for special characters, rather than just throwing all of them away.
For languages that cannot be transliterated to ASCII in a reasonable
manner, more possible improvements are outlined in #194.
Test the request, not a controller (implementation detail). This also
focuses on the observable behavior instead of hacking our way into the
middleware pipeline in order to observe internal behavior.
The authenticated user is now determined by looking at the API response
to compare permissions and (non-)existing JSON keys.
Support the old format (a simple list of available fields), in addition
to the new format (a map from field names to their types + metadata).
This will be removed after beta.12 is released.
This extends our boot exception handling block to also catch and format
all exceptions that could be thrown while building our request handler,
i.e. the middleware stack handling requests.
The only exceptions that would now not be handled in this way could be
raised by Zend's `RequestHandlerRunner` and its delegates, which we
should be able to rely on.
Exceptions on request execution will be handled by the error handler in
the middleware stack.
Fixes#1607.
Adding a proxy callStatic on our simple implementation of the Manager class allows passing through calls like `forever()` to the underlying cache driver instance.
When users have external avatar urls (for instance: in a SSO environment where the avatar is provided by another domain), color thief fails to get the avatar dominant color because the canvas would be tainted.
Following the instructions here (https://lokeshdhakar.com/projects/color-thief/ on the "Does it work if the image is hosted on another domain?"), adding an `image.crossOrigin = 'Anonymous';` solves the issue.
Tested on my forum which before suffered from a JS error and works fine (without this fix, the canvas remain in the `body` while an script error is thrown by color thief)
We decided it is better to have a less intelligent search (that does not
match search terms in titles) for some people than a bad-performing
search for everyone.
We will revisit the search performance topic in the next release cycle,
possibly with larger changes around indexing.
Refs #1738, #1741, #1764.
We accept that this may be desired by forum owners and will offer an
extension to enable this feature. By default, we will not make any
assumptions and simply adopt the web's and browsers' default behavior.
Fixes#859.
- Extract a method for email address generation
- Consistent types
- No docblocks for types where superfluous
- Tweak console output
- Don't inherit from integration test's base class in unit test
- Fix base url when is appended with a script filename
- Add default base url http://flarum.local when CLI wizard used
- Remove some code duplication
- Add minor improvement to the UX when CLI wizard used
- Add tests
- Extract base url normalisation into its own value object
In flarum/core#1854, I changed the implementation of `assertCan()` to be
more aware of the user's log-in status. I came across this when unifying
our API's response status code when actors are not authenticated or not
authorized to do something.
@luceos rightfully had to tweak this again in ea84fc4, because the
behavior changed for one of the few API endpoints that checked for a
permission that even guests can have.
It turns out having this complex behavior in `assertCan()` is quite
misleading, because the name suggests a simple permission check and
nothing more.
Where we actually want to differ between HTTP 401 and 403, we can do
this using two method calls, and enforce it with our tests.
If this turns out to be problematic or extremely common, we can revisit
this and introduce a method with a different, better name in the future.
This commit restores the method's behavior in the last release, so we
also avoid another breaking change for extensions.
This test would have failed without commit ea84fc4. Next, I will revert
that commit and most of my PR #1854, so we need this test to ensure the
API continues to behave as desired.
This fixes a regression from #1843 and #1854. Now, the frontend again
shows the proper "Incorrect login details" message instead of "You
do not have permission to do that".
Refs #1788
TypeError: t.showDeletionAlert is not a function
at onSuccess(./src/forum/utils/UserControls.js:104:12)
Also, don't override 'this' param with user object for editAction
attempts to load the s9e Renderer from the wrong cache. It has
to be saved locally so that it can be properly loaded using
the spl auto register functionality.
* Add test job with PHP 7.3, MySQL & custom prefix
* Add prefix MariaDB test
* Add PHP 7.4 to tests
* Remove PHP 7.4 from tests
This reverts commit 270cba2f5f.
This will cause the right error (HTTP 401) to be thrown whenever
we're checking for a specific permission, but the user is not even
logged in. Authenticated users will still get HTTP 403.
HTTP 401 should be used when logging in (i.e. authenticating) would make
a difference; HTTP 403 is reserved for requests that fail because the
already authenticated user is not authorized (i.e. lacking permissions)
to do something.
...not based on status code.
To simplify this logic, we now use the same error "type" both when
routes are not found and specific models are not found. One exception is
ours, one is from Laravel, but for the purposes of error handling they
should be treated the same.
Fixesflarum/core#1641.
The error handling middleware now expects an array of reporters.
Extensions can register new reporters in the container like this:
use Flarum\Foundation\ErrorHandling\Reporter;
$container->tag(NewReporter::class, Reporter::class);
Note that this is just an implementation detail and will be hidden
behind an extender.
This separates the error registry (mapping exception types to status
codes) from actual handling (the middleware) as well as error formatting
(Whoops, pretty error pages or JSON-API?) and reporting (log? Sentry?).
The components can be reused in different places (e.g. the API client
and the error handler middleware both need the registry to understand
all the exceptions Flarum knows how to handle), while still allowing to
change only the parts that need to change (the API stack always uses the
JSON-API formatter, and the forum stack switches between Whoops and
pretty error pages based on debug mode).
Finally, this paves the way for some planned features and extensibility:
- A console error handler can build on top of the registry.
- Extensions can register new exceptions and how to handle them.
- Extensions can change how we report exceptions (e.g. Sentry).
- We can build more pretty error pages, even different ones for
exceptions having the same status code.
This reverts commit f8061bbca1.
We will keep this fallback in place, to avoid unnecessary breakage of
backwards compatibility for extension authors.
Removal is planned for the final 0.1 release.
- Use existing `selectRaw()` method to avoid using the global `app()`
helper as a service locator, which hides dependencies.
- Do the same for the join.
- The `Expression` is necessary to prevent the aliased column from being
prefixed with the database table prefix, if configured.
* Integration tests: Memoize request handler as well
This is useful to send HTTP requests (or their PSR-7 equivalents)
through the entire application's middleware stack (instead of
talking to specific controllers, which should be considered
implementation detail).
* Add tests for CSRF token check
* Integration tests: Configure vendor path
Now that this is possible, make the easy change...
* Implement middleware for CSRF token verification
This fixes a rather large oversight in Flarum's codebase, which was that
we had no explicit CSRF protection using the traditional token approach.
The JS frontend was actually sending these tokens, but the backend did
not require them.
* Accept CSRF token in request body as well
* Refactor tests to shorten HTTP requests
Multiple tests now provide JSON request bodies, and others copy cookies
from previous responses, so let's provide convenient helpers for these.
* Fixed issue with tmp/storage/views not existing, this caused tmpname to notice.
Fixed csrf test that assumed an access token allows application access, which is actually api token.
Improved return type hinting in the StartSession middleware
* Using a different setting key now, so that it won't break tests whenever you re-run them once smtp is set.
Fixed, badly, the test to create users etc caused by the prepareDatabase flushing all settings by default.
* added custom view, now needs translation
Fixed csrf test that assumed an access token allows application access, which is actually api token.
Improved return type hinting in the StartSession middleware
This fixes a rather large oversight in Flarum's codebase, which was that
we had no explicit CSRF protection using the traditional token approach.
The JS frontend was actually sending these tokens, but the backend did
not require them.
This is useful to send HTTP requests (or their PSR-7 equivalents)
through the entire application's middleware stack (instead of
talking to specific controllers, which should be considered
implementation detail).
This lets us or anyone modify the path from where dependencies (usually
installed into /vendor by Composer) are loaded. We need to be able to
tweak this in our integration tests, where the application code under
test needs access to certain dependencies.
Since these files are part of the same package, there is no need
to assume a Composer context to load these from. Instead, we can
just load them via the path relative to the current PHP file.
This assumption may break in certain environments, and it is
already broken when running (integration) tests.
custom_less is NULL or unavailable in the database. We cannot rely
on this value to exist or is incorrectly set to null and thus
completely bricking the app.
This includes an API endpoint for fetching the list of possible
drivers and their configuration fields. In the future, this can
be extended to include more meta information about each field.
This adds an interface for mail drivers to implement, defining several
methods that we need throughout Flarum to configure, validate and use
the various email drivers we can support through Laravel.
More mail drivers can be added by `extend()`ing the container binding
"mail.supported_drivers" with an arbitrary key and the name of a class
that implements our new `DriverInterface`.
This will ensure that drivers added by extensions can be properly built
and validated, even in the frontend.
Refactored to use the Capsule Database manager for setting up the
Flarum (mysql) connection.
This will introduce the reconnector automatically, fixing #1740
This creates a dedicated test suite for integration tests. All of them
can be run independently, and there is no order dependency - previously,
all integration tests needed the installer test to run first, and they
would fail if installation failed.
Now, the developer will have to set up a Flarum database to be used by
these tests. A setup script to make this simple will be added in the
next commit.
Small tradeoff: the installer is NOT tested in our test suite anymore,
only implicitly through the setup script. If we decide that this is a
problem, we can still set up separate, dedicated installer tests which
should probably test the web installer.
Since this is not strictly speaking a domain invariant, but rather
specific to the user interface where passwords are not displayed, and
should therefore be entered twice to prevent mistakes going unnoticed,
this stuff should be checked in the frontend, not in the install steps.
Next step: Ensure that all domain-specific validation is done in the
installer's domain layer. This will ensure these validations cannot be
forgotten, and keep the frontends DRY.
Since we do not provide a development VM anymore, it does not make sense
to have "default" credentials etc.
To reproduce something similar, I'd suggest using a YAML or JSON file
together with the `--file` option.
We are still testing the installation logic, but not testing the
actual CLI task. I would love to do that, but IMO we first need to
find a way to do this fully from the outside, by invoking and
talking to the installer through the shell.
Because acceptance tests are easier to do when fully decoupled from
the application. (After all, they are intended to save us from
breaking things when changing code; and we cannot prove that when
we change the tests at the same time.)
It might be easier to start with acceptance tests for the web
installer, though.
This is probably the most complicated way I could find to fix#1587.
Jokes aside, this was done with a few goals in mind:
- Reduce coupling between the installer and the rest of Flarum's
"Application", which we are building during installation.
- Move the installer logic to several smaller classes, which can then
be used by the web frontend and the console task, instead of the
former hacking its way into the latter to be "DRY".
- Separate installer infrastructure (the "pipeline", with the ability
to revert steps upon failure) from the actual steps being taken.
The problem was conceptual, and would certainly re-occur in a similar
fashion if we wouldn't tackle it at its roots.
It is fixed now, because we no longer use the ExtensionManager for
enabling extensions, but instead duplicate some of its logic. That is
fine because we don't want to do everything it does, e.g. omit
extenders' lifecycle hooks (which depend on the Application instance
being complete).
> for each desired change, make the change easy (warning: this may be
> hard), then make the easy change
- Kent Beck, https://twitter.com/kentbeck/status/250733358307500032Fixes#1587.
This is important because extensions may wish to render post content
differently depending on Request factors such as the actor. For example,
an attachments extension might wish to hide attachments from guests.
This solution is a bit of a hack-job for now, but soon when we refactor
the API layer to use tobscure/json-api-server, and also refactor the
Formatter layer, it can be revised.
The event subscriber approach means that dependencies have to be
injected (and thus instantiated, along with all *their* dependencies) at
the time of registering event listeners - even when events are never
fired within a request's lifecycle.
This is unnecessary and causes more classes than necessary to be loaded.
In this case, we can explicitly register event listeners that will
resolve their dependencies when the event is fired, not before.
Refs #1578.
We had added a `storage/locale` directory to our skeleton, but we had
forgotten to hook it up with the translator. Enabling caching saves
parsing that locale YAML files on every pageload which should be good
for performance.
The locale cache will be cleared whenever an extension that uses the
`Locales` or `LanguagePack` extenders is enabled/disabled. If debug
mode is ON, then the caching mechanism will automatically check if any
of the loaded YAML files are dirty and update accordingly.
Passing an array to dropForeign does not mean dropping multiple indices,
but rather dropping a key on multiple tables.
Passing a string means that this string will be interpreted as index
name, not as name of the indexed column. Passing an array with one
string is therefore correct, in order to benefit from automatic index
name generation.
wrap() only adds a table prefix when referencing a column with a table
name (such as `foo.bar`) - when only a single identifier is provided, it
is assumed to be a column name, which does not need a prefix.
Fixes#1659.
- Simpler class naming:
Frontend\CompilerFactory → Frontend\Assets
Frontend\HtmlDocumentFactory → Frontend\Frontend
Frontend\HtmlDocument → Frontend\Document
- Remove AssetInterface and simply collect callbacks in Frontend\Assets
instead
- Remove ContentInterface because it serves no purpose (never type-
hinted or type-checked)
- Commit and add asset URLs to the Document via a content callback
instead of in the Document factory class itself
- Add translations and locale assets to Assets separate to the assets
factory, as non-forum/admin asset bundles probably won't want them
- Update Frontend Extender to allow the creation of new asset bundles
- Make custom LESS validation listener a standalone class instead of
extending RecompileFrontendAssets
The previous approach of joining the posts table into the main search
query was not scaling well. Searches on discuss.flarum.org were taking
~1.5 seconds which – a significant improvement over the pre-beta 8
search, but still not acceptable.
This new approach uses a much more efficient subquery join. Searches
on discuss.flarum.org now take mere milliseconds. The search result
ranking strategy has been further refined as well so that discussions
are ranked by the collective relevance of their posts.
This is to be used for formatting buttons and the like. Although it is
displayed in the controls area at the moment, it is conceptually
different and may be relocated to the top of the text editor in the
future.
- Change preview icon to Font Awesome Regular instead of Solid
- Give the preview button a tooltip
- Change submit button icon to paper plane (shown on mobile)
- Tweak mobile header button touch target
- Scroll overflowing text editor controls horizontally
This takes place only in the FallbackExceptionHandler. Having a custom
exception handler implies that a friendly message is displayed in the
API response, in which case we can bet that the exception won't need to
be "debugged" per se.
Having a custom view implies that a friendly message is displayed to
the user, in which case we can bet that the exception won't need to be
"debugged" per se.
This will prevent a notification from being seen by a user if its
subject is deleted or undergoes some kind of permission change (eg.
a discussion is moved into a private tag)
ref #1380
* fixed not being able to use master token because id column no longer holds key
* added flexibility of user_id column
* added tests to confirm the api keys actually work as intended
Seems the created_at column has no default value. This was always the case, at least that's what I can tell from a clean install and no migrations changing that default value.
```
$table->timestamp('created_at');
```
* Allow admins to see last online text
* Use viewLastSeenAt permission
* Move permission to UserSerializer, removed from ForumSerializer
* Remove extra comma from ForumSerializer to keep diff clean
* Add permission to new seed migration
* Remove AbstractOAuth2Controller
There is no reason to provide an implementation for a specific oAuth2
library in core; it's not generic enough (eg. auth-twitter can't use it).
This code could be moved into another package which auth extensions
depend on, but it's a negligible amount of relatively simple code that
I don't think it's worth the trouble.
* Introduce login providers
Users can have many login providers (a combination of a provider name
and an identifier for that user, eg. their Facebook ID).
After retrieving user data from a provider (eg. Facebook), you pass the
login provider details into the Auth\ResponseFactory. If an associated
user is found, a response that logs them in will be returned. If not, a
registration token will be created so the user can proceed to sign up.
Once the token is fulfilled, the login provider will be associated with
the user.
Permission to rename/hide/edit one's own discussion/post is only granted
if the user has permission to reply to the discussion. This makes sense
if you think of these actions as forms of "replying" to a discussion.
Fixes#1419 because suspended users do not have permission to reply to
discussions, therefore they will not be granted these "own" permissions.
By not letting PHP render the stack trace, we prevent displaying
sensitive information (such as the database credentials). Instead,
we display a simple line with the exception message.
In the console, the full exception can still be shown, as that is
a tool only for forum admins anyway.
Fixes#1421.
This is in preparation for fixing #1421 - it allows us to
encapsulate the exception handling in the server classes, so that
we can keep the skeleton (flarum/flarum) lean.
When loading notifications, $this->type was null and thus array_get
was returning an array instead of null. I assume this issue was
introduced in a Laravel version upgrade? Anyway, this fixes it.
By moving the DispatchRoute middleware into an `afterResolving`
callback, this will allow a new Middleware extender to add a `resolving`
callback to the appropriate container binding, removing the need for the
ConfigureMiddleware event.
The ConfigureMiddleware event has been deprecated and should be removed
in beta 9.
This can be achieved using the Route extender, which is more
flexible, as it does not necessary connect the URL with the current
frontend's router.
(Example use-case: The ext-embed frontend will be a new frontend,
however any routes using this frontend will be part of the forum
route group.)
Refs #851.
By passing in just the frontend identifier, we can hide some of the
implementation details, in this case the identifier of the Frontend
instance in the IoC container.
Since we are already providing the first and only argument
manually, we might as well instantiate the object manually.
Same effect, same coupling, less code.
This lets us register the former during installation, where the
latter is not yet registered.
That, in turn, means we can finally re-enable the StartSession
middleware in the installer app, which we need to log in the new
admin user when installation is complete.
Most things we need, we can instantiate directly.
This means we have to do less tweaking in service providers that
are meant to provide services to a complete Flarum application
(that has already been installed properly), to make them work with
the uninstalled app.
The uninstalled app (the "installer") can now do only the
bootstrapping it needs to build a light-weight web and console
application, respectively.
These are not necessary to be available so broadly. In fact, they
seem to make it too easy to use them, which has lead to some sub-
optimal architecture decisions.
Their equivalents have been moved to the classes where used.
Depending on the state of the Flarum installation (installed, not
installed, currently upgrading, maintenance mode), we should enable
different sets of service providers.
For example, during installation we should not resolve a setting
repository from the container. This new architecture lets us do so,
but we can easily (and cleanly) register a different implementation
during installation.
This should prevent problems such as #1370 in the future.
These are completely distinct functionalities, toggled through the
system-wide debug flag. By moving the selection of the middleware
to use to the place where the middleware pipe is built, we make
the middleware itself be unaware of these flags. The two classes
are more focused on what they are doing, with the constructor
dependencies clearly representing their requirements.
In addition, this means we can just use the HandleErrorsWithWhoops
middleware in the installer, which means we do not need to worry
about how to inject a SettingsRepositoryInterface implementation
when flarum is not yet set up.
This method relies on the "view" being bound in the IoC container.
This is only guaranteed after all register() methods have run, thus
it should be done in boot().
Updating the Migration::addPermission helper table name means we need
to move the seed migration to after the table rename migration. We also
add a sanity check for each permission's group since the foreign key
will fail if the group doesn't exist. Of course, the only way to make
sure groups are seeded before permissions is to move them into another
migration.
I didn't think this change through and it's going to be too difficult
to implement right now. It can wait until we do the notifications
revamp. For now reverting back to the old structure, with the
`sender_id` column renamed to `from_user_id`.
* Make filenames and order more consistent
* Split foreign keys into their own migrations, add statements to ensure
data integrity prior to adding them
* Add renameColumns helper, use other helpers where possible
fixes#1480
This is a suggestion to improve clarification of what a feature request on our issue tracker should entail.
Changes made:
- uppercased "IMPORTANT" instead of a "Note" to clarify the importance of the comment
- removed the "serious" related information, because users often have no scale to rate seriousness against
- brought more attention to approval by a core developer or argumentation and implementation by moving that to the front
Refactor Frontend + Asset code
- Use Laravel's Filesystem component for asset IO, meaning theoretically
assets should be storable on S3 etc.
- More reliable checking for asset recompilation when debug mode is on,
so you don't have to constantly delete the compiled assets to force
a recompile. Should also fix issues with locale JS files being
recompiled with the same name and cached.
- Remove JavaScript minification, because it will be done by Webpack
(exception is for the TextFormatter JS).
- Add support for JS sourcemaps.
- Separate frontend view and assets completely. This is an important
distinction because frontend assets are compiled independent of a
request, whereas putting together a view depends on a request.
- Bind frontend view/asset factory instances to the container (in
service providers) rather than subclassing. Asset and content
populators can be added to these factories – these are simply objects
that populate the asset compilers or the view with information.
- Add RouteHandlerFactory functions that make it easy to hook up a
frontend controller with a frontend instance ± some content.
- Remove the need for "nojs"
- Fix cache:clear command
- Recompile assets when settings/enabled extensions change
Casting an object to an array does not have the intended effect of
wrapping the object in an array. Instead we need to explicitly check
if the returned value is an array or not.
* Run extenders exported by extensions
* Add some basic extenders
* Patch Mithril as the very first thing so extension code can run safely
* Load the payload into the app before booting extensions
* Setup default routes before booting extensions
In the future we may have multiple Formatters, so by moving the config
callback to its own instance method we can leave the constructor
available to specify which formatter (like Assets and Routes). This
format also allows for other methods to be added.
Additionally, this adds logic to automatically flush the Formatter cache
whenever the extension is enabled or disabled.
* Replace gulp with webpack and npm scripts for JS compilation
* Set up Travis CI to commit compiled JS
* Restructure `js` directory; only one instance of npm, forum/admin are "submodules"
* Refactor JS initializers into Application subclasses
* Maintain partial compatibility API (importing from absolute paths) for extensions
* Remove minification responsibility from PHP asset compiler
* Restructure `less` directory
Mostly, we only need a database connection, instead of one of
Laravel's "connection resolvers".
Again, this makes our life easier during installation, where
we already instantiate a database connection. We can now use
that to instantiate our own Migrator class, instead of using
the IoC container to build one.
This removes the funky auto-injection capability from migration
closures. While technically removing a feature, this means we do
not need a fully-wired IoC container e.g. during installation.
Instead, all migration closures simply receive a schema builder
object (which is what most of them were already doing anyway).
This finally adopts the new standardized interfaces instead of the
work-in-progress ones with the `Interop\` prefix.
Since we have now updated to PHP 7.1, we can also use Stratigility
3.0 as the middleware dispatcher.
This will be the last PHP requirement upgrade for a while, at least
until stable (and therefore until the next major release).
We have decided to do this now, for the following reasons:
- We want to support MariaDB (and the compatible release of
doctrine/dbal requires 7.1 as well).
- We prefer to upgrade to Laravel 5.6 sooner rather than later.
- Using the PSR-15 middleware standard is easier this way, as we do
not have to switch from zend-stratigility to another PSR-15
implementation. (Stratigility v3, which implements the final
standard, requires 7.1.)
* added CreatePostControllerTest
* added DeleteDiscussionControllerTest
* added ListDiscussionControllerTest
* added TokenControllerTest
* minor improvement to policy, no need for Carbon object there, added ShowDiscussionControllerTest
* added showDiscussionControllerTest but cant make Guests view the discussion created by a user
* viewing for guests tested, we might need factories
* part one of adding tests, updating core
* Apply fixes from StyleCI
[ci skip] [skip ci]
* we need xdebug for code coverage, and hhvm was already removed
* forgot about the sidecar for mysql completely 🤦
* gitignore removed this installed json we need to fake that we have extensions
* using reguarded closure
Without this, the new version of Stratigility complained about no
response being returned. Old versions were more graceful here, but
this is certainly more correct.
Now we have two extenders:
- `Extend\LanguagePack` is the "convention over configuration" loader
for complete language packs.
- `Extend\Locales` can be used to load files (by locale) from a given
directory - useful for extensions that bring along their own locales
in multiple different languages.
Refs #851.
With this change, session objects are no longer instantiated
globally, but instead created within a middleware during the
request lifecycle.
In addition, session garbage collection is integrated with
the already existing middleware for this purpose.
Symfony's component relies on PHP's native session functionality, which
is not ideal. It automatically sets its own cookie headers, resulting in
this issue: https://github.com/flarum/core/issues/1084#issuecomment-364569953
The Illuminate component is more powerful and has a simpler API for
extension with other drivers and such, and fits in nicely with other
components we use (the majority of which are from Illuminate).
The gathering and execution of extenders can actually be done here
in the `Extension` class. This way, the `ExtensionManager` only
deals with the question of which extensions are enabled, the
`Extension` class actually extends the core application, and the
service provider simply calls a method, without having to know
about internals.
* Update FontAwesome to v5.0.6
* Adapt DiscussionListItem-count icon to match FontAwesome 5 syntax
* Change icon name to match FontAwesome 5.0.6 fas icon
* Add font type prefix parameter to icon helper
* Add Enable Icon Prefix to show icon in Extension Page
* Fix invalid icon behavior
* Change icon name to match FontAwesome 5.0.6 far icon
* Use iconPrefix property on component
* Use full icon class name
* Update icon helper docblock
* Full icon class syntax
Exceptions thrown while attempting to dispatch routes are now informing the exact value that was incorrect; url for not found routes and the method when the method was invalid.
* Improve fulltext gambit
* Only search in visible posts
This change relies on the `visibility-scoping` branch to be merged.
* Change posts table to use InnoDB engine
Doing a JOIN between an InnoDB table (discussions) and a MyISAM table
(posts) is very very (very) bad for performance. FULLTEXT indexes are
fully supported in InnoDB now, and it is a superior engine in every
other way, so there is no longer any reason to be using MyISAM.
* Use ::class
* Only search for comment posts
* Add fulltext index to discussions.title
* Fix migration not working if there is a table prefix
* Update frontend appearance
* Apply fixes from StyleCI
[ci skip] [skip ci]
* Show search result excerpts on mobile
This fixes an issue where unapproved discussions (via
flarum-ext-approval) that were rejected became invisible to the user.
This solution is imperfect and some more substantial thought into how
flarum-ext-approval works is required in the future.
* Overhaul the way model visibility scoping works
- Previously post visibility scoping required concrete knowledge of the
parent discussion, ie. you needed a Discussion model on which you
would call `postsVisibleTo($actor)`. This meant that to fetch posts
from different discussions (eg. when listing user posts), it was a
convoluted process, ultimately causing #1333.
Now posts behave like any other model in terms of visibility scoping,
and you simply call `whereVisibleTo($actor)` on a Post query. This
scope will automatically apply a WHERE EXISTS clause that scopes the
query to only include posts whose discussions are visible too. Thus,
fetching posts from multiple discussions can now be done in a single
query, simplifying things greatly and fixing #1333.
- As such, the ScopePostVisibility event has been removed. Also, the
rest of the "Scope" events have been consolidated into a single event,
ScopeModelVisibility. This event is called whenever a user must have
a certain $ability in order to see a set of discussions. Typically
this ability is just "view". But in the case of discussions which have
been marked as `is_private`, it is "viewPrivate". And in the case of
discussions which have been hidden, it is "hide". etc.
The relevant API on AbstractPolicy has been refined, now providing
`find`, `findPrivate`, `findEmpty`, and `findWithPermission` methods.
This could probably do with further refinement and we can re-address
it once we get around to implementing more Extenders.
- An additional change is that Discussion::comments() (the relation
used to calculate the cached number of replies) now yields "comments
that are not private", where before it meant "comments that are
visible to Guests". This was flawed because eg. comments in non-public
tags are technically not visible to Guests.
Consequently, the Approval extension must adopt usage of `is_private`,
so that posts which are not approved are not included in the replies
count. Fundamentally, `is_private` now indicates that a discussion/
post should be hidden by default and should only be visible if it
meets certain criteria. This is in comparison to non-is_private
entities, which are visible by default and may be hidden if they don't
meet certain criteria.
Note that these changes have not been extensively tested, but I have
been over the logic multiple times and it seems to check out.
* Add event to determine whether a discussion `is_private`
See https://github.com/flarum/core/pull/1153#issuecomment-292693624
* Don't include hidden posts in the comments count
* Apply fixes from StyleCI (#1350)
Event priorities are no longer in Laravel - see dbbfc62bef
Updated the AbstractPolicy terminology to reflect the new behaviour,
which is that there is no guarantee that the catch-all methods will run
after all specific methods have run globally. This behaviour is only
guaranteed within the policy.
Turns out Container::call() does not work with invokable classes.
Thus, we need to wrap callables in a custom extender class to
support injecting any resolvable type-hint automatically.
Refs #851.
This simplifies the API and gives extension developers more
flexibility, for a) maintaining backwards compatibility, and
b) doing advanced stuff that extenders do not allow.
Note that only extenders are guaranteed to work across
different versions of Flarum (once the API surface is stable).
See the discussion in https://github.com/flarum/core/pull/1335.
This makes it more consistent with other existing extenders,
while also making registration of multiple routes more
comfortable for extension developers, and likely slightly
more performant. :-)
The change introduced in #1033 transformed any identification attribute returned from an OAuth provider to just a default value.
When the identification attribute used by the provider is the email or username, this allowed the user to supply a different email or username and still getting an already-enabled account with the credentials he entered.
Skipping attributes with an existing value makes no sense here because it's a always a fresh user and values from AbstractOAuth2Controller::getIdentification() should always be enforced.
* Add Custom Footer HTML
Straight copy from Custom Header HTML
* Move Custom Footer HTML to exactly before `</body>` tag.
* Fix invalid class name
* Append CustomFooterHTML when preparing the view.
* Some consistency in placing the variable
* Manage Composer height in a separate class with overridable methods
* Use a computed method
* Keep everything in Composer.js
* Drop usage of computed property for the Composer height
Because the Composer height also depends on the page height and is rarely called without position, height or page height changing anyway
Loading the activated extensions now means retrieving an array of
extenders (classes that implement a certain type of extension of a core
feature in Flarum).
For now, the only existing extender is the Compat extender which is used
to handle old-style bootstrappers that simply return a closure that
receives all of its dependencies via auto injection.
In the future, extensions will be able to return an array of extender
instances from their bootstrapper instead. These extender classes will
be implemented in the next step.
Using .dev as a TLD for local development is discouraged, as at
least Chrome now enforces HTTPS for these domains.
As far as I know, by default, the MySQL root user does not have
a password on many platforms. I use it this way on my local
machine, and this makes it convenient to setup a local copy.
This prevents garbage collection to randomly break the installer:
before installation, the models that are being accessed have no
database connection.
Now, the middleware is only mounted into the forum's middleware
stack. I want API requests to have stable performance, and the
forum middleware stack is only mounted when Flarum is installed.
* Prevent saving invalid custom less
* Fix formatting
* Fix formatting again
* Move custom less format check to its own listener
* Move listener to AdminServiceProvider
* Rename listener method
ref #1025#1238. This should prevent the frontend from crashing when
opening the notifications menu, but we still need to make sure
notifications are deleted properly when subjects are deleted.
Currently not user-customizable. Just needed to display statistics for a
client, so figured I'd make a start at this. Nothing too fancy for now,
but I'm sure some people will be happy to have this information at their
fingertips.
There is a Mithril bug which causes context.retain to be ineffective for
children nodes. https://github.com/MithrilJS/mithril.js/issues/1300
Thus, we have to assume that the children nodes (like the textarea)
may be recreated and thus we need to update its height on each redraw.
fixes#948
- Don't scroll to the bottom of the discussion when selecting "Reply"
from the menu if the composer is in full screen mode (ie. on mobile).
ref #1271
- After posting a reply, scroll to the end of the discussion
- Reduce the textarea height - previously it was 100vh, but this doesn't
account for the height of the iOS keyboard, so I've just arbitrarily
chosen 300px instead. There may be a better solution for this.
ref #1269
I believe the constant overlay of a loading div may be what's causing
the iOS cursor issues. This commit removes the fade animation so that
we can simply set display to none, which will hopefully fix the issue.
#1074 changed the input type for these fields to "color", but it turns
out the browser support for this input type sucks (they give you a very
limited color picker, and make it hard to input hex codes).
Not sure why this started happening now, but the admin navigation
dropdown wasn't receiving its children properly. This commit fixes a
flaw in our Mithril patch and allows an array of children to be passed
in the normal JSX way, rather than as an attribute.
* Returning the $default value if there's no config
This is especially important for the CookieFactory which accesses
the configuration before the application is installed
* Injecting the configuration values into the CookieFactory
I decided to put this in config.php because if cookie settings were to
be stored in the database and configured via admin UI, entering
incorrect settings could cause the admin session to be destroyed,
requiring manual database intervention to fix. But it's a good prompt
for discussion as to which kind of settings belong in config.php vs the
database. Thoughts?
<\/script> tags in post content would sometimes be recognized as
actually ending the script tag, even when escaped (not exactly sure
why). This is fixed by encoding the < > characters in unicode.
Here, the order is relevant, because at this
point, the application has already been booted.
Hence, all boot() methods are called immediately,
which might depend on other service providers'
register() methods having run.
In this case, the DiscussionServiceProvider
depends on the Gate class being registered in the
container by the UserServiceProvider.
This class holds all information relevant to a local Flarum site,
such as paths and local configuration. From this information, it
is able to instantiate a Flarum\Foundation\Application instance,
which represents a Flarum installation's runtime.
This will also be useful for setting up e.g. multi-tenant
environments.
The various middleware can be registered in the service provider,
and the rest of the logic can all go through one single front
controller (index.php in flarum/flarum, and Flarum\Http\Server in
flarum/core).
This will also simplify the necessary server setup, as only one
rewrite rule remains.
They will probably be refactored away at a later stage (when we get
rid of the command bus). Until then, this lets us remove the
Flarum\Core namespace and actually feels quite clean.
* Introduce user display names
It is not uncommon for forums to be intergrated with sites where users
don't have a unique "handle" - they might just have their first name,
or a full name, which is not guaranteed to be unique.
This commit introduces the concept of "display names" for users. By
default display names are the same as usernames, but extensions may
override this and set them to something different. The important thing
is that all code should use `display_name` whenever intending to output
a human-readable name - `username` is reserved for cases where you want
to output a unique identifier (which may or may not be human-friendly).
The new "GetDisplayName" API is probably sub-optimal, but I didn't worry
too much because we can come up with something better in `next-back`.
ref #557
* Apply fixes from StyleCI
[ci skip] [skip ci]
Currently all of a post's replies are loaded in full whenever the post
is loaded, which is kind of overkill - we really just need to know that
they exist (and who posted them) in order to render the "X replied to
this" line.
This is useful for forums integrating with an external website (eg. a
WordPress site), so they can reference existing avatars directly.
For alternative storage locations (eg. S3) the best practice will still
be to store a relative path and then configure an external base "assets
URL" (this is not currently possible - TODO).
Given this change, I think it would probably make sense to rename the
column to `avatar_url` in the upcoming batch of database naming changes
- then it can contain either a relative or an absolute URL -
@franzliedke do you agree?
Howdy! We're really excited that you are interested in contributing to Flarum. Before submitting your contribution, please take a moment and read through the [Contributing Guidelines](https://github.com/flarum/flarum/blob/master/CONTRIBUTING.md).
about: "I have a suggestion (and may want to implement it!)"
---
<!--
IMPORTANT: Feature requests on this GitHub issue tracker are only accepted in case they have been approved by a core developer or contain extensive argumentation and directions for implementation. For all other feature requests, ideas and feedback please post in the Flarum Community: https://discuss.flarum.org/t/feedback.
-->
## Feature Request
**Is your feature request related to a problem? Please describe.**
A clear and concise description of what the problem is. eg. I have an issue when [...]
**Describe the solution you'd like**
A detailed description of your proposed solution. Include:
- How the feature would work/behave
- Any potential drawbacks
- Maybe a screenshot, design, or example code
**Justify why this feature belongs in Flarum's core, rather than in a third-party extension**
Consider who this change will be useful to –most Flarum forums, or just a few?
**Describe alternatives you've considered**
A clear and concise description of any alternative solutions or features you've considered.
- Removed [forum] prefix from Request Password and Email Confirmation emails ([a4a81c0](https://github.com/flarum/core/commit/a4a81c0ec237476cd6e7ca00c1ed9465493af476))
- Adopt huntr.dev for handling our security vulnerability reports (https://github.com/flarum/core/pull/2918)
- Maintenance handler can now be replaced through the service container (ioc) ([4acff91](https://github.com/flarum/core/commit/4acff91f8063fcced9bf8c9a76fbb510d06823c0))
- The colors on the auto generated avatars are now based on the Display Name of the user (https://github.com/flarum/core/pull/2873)
### Fixed
- Avatar in notifications list are incorrectly aligned (https://github.com/flarum/core/pull/2906)
- FilesystemManager is not compatible with upstream Laravel implementation (https://github.com/flarum/core/pull/2936)
-`load()` method on `ApiController` extender to allow eager loading of relations (https://github.com/flarum/core/pull/2724)
- Installation supports enabling a set of extensions (https://github.com/flarum/core/pull/2757)
- RequestUtil helper class added to abstract the logic of the actor, session, locale and route name from the request (https://github.com/flarum/core/pull/2449)
- Code scanning action with GitHub CodeQL (https://github.com/flarum/core/pull/2744)
- The Formatter extender now has an `unparse` method to allow extensions to hook into the unparsing of content (https://github.com/flarum/core/pull/2780)
- A Filesystem extender allows direct modification and addition of filesystem disks (https://github.com/flarum/core/pull/2732)
- A slug driver based on the User ID was introduced (https://github.com/flarum/core/pull/2787)
- An extensible users list was added to the admin area (https://github.com/flarum/core/pull/2626)
- Headers hardened by adding Referer Policy, Xss Protection and Content type (https://github.com/flarum/core/pull/2721)
- Moved `insertText` and `styleSelectedText` from markdown to core (https://github.com/flarum/core/pull/2826)
- A squashed database schema install dump to speed up new installs (https://github.com/flarum/core/pull/2842)
- Pagination in the canonical URL for discussion pages (https://github.com/flarum/core/pull/2853)
- PaginatedListState for the DiscussionList and to support paginated lists in the frontend (https://github.com/flarum/core/pull/2781)
- Introduce the new webpack config and flarum-tsconfig for typehinting (https://github.com/flarum/core/pull/2856)
### Changed
- Now tracking bundle sizes to keep an eye on web performance (https://github.com/flarum/core/pull/2695)
- Eager load relations on ListPostsController to improve performance (https://github.com/flarum/core/pull/2717)
- Replace classList with clsx library (https://github.com/flarum/core/pull/2760)
- Replaced the javascript based loading spinner with a pure CSS version (https://github.com/flarum/core/pull/2764)
- Route names now have to be unique (https://github.com/flarum/core/pull/2771)
- ActorReference is now available from the error handler middleware (https://github.com/flarum/core/pull/2410)
- The `migrations` table now has an Auto Increment ID (https://github.com/flarum/core/pull/2794)
- Assets and avatars are now managed using Laravel filesystem disks (https://github.com/flarum/core/pull/2729)
- Extracted asset publishing (`php flarum assets:publish`) from migrating (https://github.com/flarum/core/pull/2731)
- Assets were compiled in the format `<asset>-<revision>.<js|css>`, this is now `<asset>.<js|css>?v=<revision>` (https://github.com/flarum/core/pull/2805)
- The powered by header can now be configured in the config under `headers` (https://github.com/flarum/core/pull/2777)
- Switched to the ICU format for translation files (https://github.com/flarum/core/pull/2759)
- Allow extend and override to apply to multiple methods in one call
- Notifications dropdown and list refactored (https://github.com/flarum/core/pull/2822)
- Updated validation locale strings based on Laravel 8 changes (https://github.com/flarum/core/pull/2829)
- Caching of permissions is now taken care of centrally, reducing code duplication (https://github.com/flarum/core/pull/2832)
- Replaced lodash-es by throttle-debounce to reduce bundle size (https://github.com/flarum/core/pull/2827)
- Internal API requests are now executed through middleware (https://github.com/flarum/core/pull/2783)
- Permission changes: `viewDiscussions` to `viewForum` and `viewUserList` to `searchUsers` (https://github.com/flarum/core/pull/2854)
### Fixes
- Javascript is shown when editing the title of a discussion (https://github.com/flarum/core/pull/2693)
- Canonical url logic uses request object which causes wrong URL's when a different page is default (https://github.com/flarum/core/pull/2674)
- Dropdown toggle has no aria label (https://github.com/flarum/core/pull/2668)
- Nav drawer is focusable when off-screen on small viewports (https://github.com/flarum/core/pull/2666)
- Search input has no aria-label and no role (https://github.com/flarum/core/pull/2669)
- Code duplication exists between SendConfirmationEmailController and AccountActivationMailer (https://github.com/flarum/core/pull/2493)
- When setting tags as homepage default, visiting a tag will show all posts (https://github.com/flarum/core/pull/2754)
- Locale cache is cleared twice when cache clearing (https://github.com/flarum/core/pull/2738)
- When cache clearing fails an exception can be thrown due to a partial flush (https://github.com/flarum/core/pull/2756)
- Database migrations rely on MyISAM even though the eventual migrated database does not use it (https://github.com/flarum/core/pull/2442)
- Discussion search result is not sorted by relevance by default (https://github.com/flarum/core/pull/2773)
- Split user edit permissions into permissions for editing of user credentials, username, groups and suspending (https://github.com/flarum/core/pull/2620)
- Reduced number of admin extension categories (https://github.com/flarum/core/pull/2604)
- Move search related classes to a dedicated Query namespace (https://github.com/flarum/core/pull/2645)
- Rewrite common helpers into typescript (https://github.com/flarum/core/pull/2541)
-`TextEditor` is moved to the common namespace for use in the admin frontend (https://github.com/flarum/core/pull/2649)
- Update Laravel/Illuminate components to 8 (https://github.com/flarum/core/pull/2576)
- Eager load relations in discussion listing to improve performance (https://github.com/flarum/core/pull/2639)
- Replace `user` gambit with `author` gambit ([612a57c](https://github.com/flarum/core/commit/612a57c4664415a3ea120103483645c32acc6f12))
- Posts page of on user profile loads posts using username instead of id ([30017ee](https://github.com/flarum/core/commit/30017eef09ae9e78640c4e2cacd4909fffa8d775))
- Composer header is hidden on mobile devices (https://github.com/flarum/core/pull/2279)
- Cannot delete a post or discussion of a deleted user (https://github.com/flarum/core/pull/2521)
- DiscussionListPane jumps around not keeping the scroll position (https://github.com/flarum/core/pull/2402)
- Infinite scroll on notifications dropdown broken (https://github.com/flarum/core/pull/2524)
- The show language selector switch remains toggled on ([9347b12](https://github.com/flarum/core/commit/9347b12b47bf4ab97ffb7ca92673604b237c1012))
- Model Visibility extender throws exception on extensions that aren't installed or enabled (https://github.com/flarum/core/pull/2580)
- Extensions are marked as enabled when enabling fails to unmet extension dependencies (https://github.com/flarum/core/pull/2558)
- Routes to admin extension pages without a valid ID break the admin page (https://github.com/flarum/core/pull/2584)
- Disabled fieldset use an incorrect CSS property `disallowed` (https://github.com/flarum/core/pull/2585)
- Scrolling to a post that is already loaded the Load More button shows and does not trigger (https://github.com/flarum/core/pull/2388)
- Opening discussions on some mobile devices require a double tap (https://github.com/flarum/core/pull/2607)
- iOS devices show erratic behavior in the post stream while updating (https://github.com/flarum/core/pull/2548)
- Small mobile screens partially hides the composer when the keyboard is open (https://github.com/flarum/core/pull/2631)
- Clearing cache does not clear the template cache in storage/views (https://github.com/flarum/core/pull/2648)
- Boot errors show critical information (https://github.com/flarum/core/pull/2633)
- List user endpoint discloses last online even if user choose against it (https://github.com/flarum/core/pull/2634)
- Group gambit disclosed hidden groups (https://github.com/flarum/core/pull/2657)
- Search results on small windows not fully visible (https://github.com/flarum/core/pull/2650)
- Composer goes off screen on Safari when starting to type (https://github.com/flarum/core/pull/2660)
- A search that has no results shows the search results dropdown ([b88a7cb](https://github.com/flarum/core/commit/b88a7cb33b56e318f11670e9e2d563aef94db039))
- The composer modal moves around when typing on Safari ([a64c398](https://github.com/flarum/core/commit/a64c39835aba43e831209609f4a9638ae589aa41))
### Removed
- Deprecated CSRF wildcard path match
- Deprecated policy and visibility scoping events
- Deprecated post types event
- Deprecated validation events
- Deprecated notification events
- Deprecated floodgate
- Deprecated user preferences event
- Deprecated formatting events
- Deprecated api events
- Deprecated bootstrap.php support
- PHP 7.2 support (https://github.com/flarum/core/pull/2507)
- Bidi attribute in the rendered HTML (https://github.com/flarum/core/pull/2602)
-`AccessToken::find`, use `AccessToken::findValid` instead (https://github.com/flarum/core/pull/2651)
-`Rememberer::remember` argument `$token` should receive an instance of `RememberAccessToken` with `AccessToken` being deprecated (https://github.com/flarum/core/pull/2651)
- Floodgate moved to middleware and extender added (https://github.com/flarum/core/pull/2170).
- DRY up image uploading logic (https://github.com/flarum/core/pull/2477).
- Process isolation on testing (https://github.com/flarum/core/commit/984f751c718c89501cc09857bc271efa2c7eea8c).
- Forum and admin javascript exports namespaced (https://github.com/flarum/core/pull/2488).
### Fixed
- Web updater does not take into account subfolder installations (https://github.com/flarum/core/pull/2426).
- Callables handling in extenders failed (https://github.com/flarum/core/pull/2423).
- Scrolling on mobile from PostSteam changes didn't work correctly (https://github.com/flarum/core/pull/2385).
- Side pane covers part of the discussion page due to `app.discussions` being empty (https://github.com/flarum/core/commit/102e76b084bf47fdfb4c73f95e1fbb322537f7aa).
- Change email modal keeps showing the previous error message even on success (https://github.com/flarum/core/pull/2467).
- Comment count not updated when discussions are deleted (https://github.com/flarum/core/pull/2472).
-`goToIndex` in PostStream does not trigger an xhr to retrieve new data (https://github.com/flarum/core/commit/09e2736cbcc267594b660beabbd001d9030f9880).
- On refresh the post number is reduced by one (https://github.com/flarum/core/pull/2476).
- Queue worker would instantiate a new Queue factory, not the bound one (https://github.com/flarum/core/pull/2481).
- Header accidentally has a border bottom (https://github.com/flarum/core/pull/2489).
- Namespace mentioned in docblock is incorrect (https://github.com/flarum/core/pull/2494).
- New `hasPermission()` helper method for `Group` objects ([9684fbc](https://github.com/flarum/core/commit/9684fbc4da07d32aa322d9228302a23418412cb9))
- Expose supported mail drivers in IoC container ([208bad3](https://github.com/flarum/core/commit/208bad393f37bfdb76007afcddfa4b7451563e9d))
- More test for some API endpoints ([1670590](https://github.com/flarum/core/commit/167059027e5a066d618599c90164ef1b5a509148))
- The `Formatter\Rendering` event now receives the HTTP request instance as well ([0ab9fac](https://github.com/flarum/core/commit/0ab9facc4bd59a260575e6fc650793c663e5866a))
- More and better validation in installer UIs
- Check and enforce minimum MariaDB ([7ff9a90](https://github.com/flarum/core/commit/7ff9a90204923293adc520d3c02dc984845d4f9f))
- Revert publication of assets when installation fails ([ed9591c](https://github.com/flarum/core/commit/ed9591c16fb2ea7a4be3387b805d855a53e0a7d5))
- Benefit from Laravel's database reconnection logic in long-running tasks ([e0becd0](https://github.com/flarum/core/commit/e0becd0c7bda939048923c1f86648793feee78d5))
- The "vendor path" (where Composer dependencies can be found) can now be configured ([5e1680c](https://github.com/flarum/core/commit/5e1680c458cd3ba274faeb92de3ac2053789131e))
### Changed
- Performance: Actually cache translations on disk ([0d16fac](https://github.com/flarum/core/commit/0d16fac001bb735ee66e82871183516aeac269b7))
- Allow per-site extenders to override extension extenders ([ba594de](https://github.com/flarum/core/commit/ba594de13a033480834d53d73f747b05fe9796f8))
- Do not resolve objects from the IoC container (in service providers and extenders) until they are actually used
- Replace event subscribers (that resolve objects from the IoC container) with listeners (that resolve lazily)
- Use custom service provider for Mail component ([ac5e26a](https://github.com/flarum/core/commit/ac5e26a254d89e21bd4c115b6cbd40338e2e4b4b))
- Update to Laravel 5.7, revert custom logic for building database index names
- Refactored installer, extracted Installation class and pipeline for reuse in CLI and web installers ([790d5be](https://github.com/flarum/core/commit/790d5beee5e283178716bc8f9901c758d9e5b6a0))
- Use whitelist for enabling pre-installed extensions during installation ([4585f03](https://github.com/flarum/core/commit/4585f03ee356c92942fbc2ae8c683c651b473954))
- Update minimum MySQL version ([7ff9a90](https://github.com/flarum/core/commit/7ff9a90204923293adc520d3c02dc984845d4f9f))
### Fixed
- Signing up via OAuth providers was broken ([67f9375](https://github.com/flarum/core/commit/67f9375d4745add194ae3249d526197c32fd5461))
- Group badges were overlapping ([16eb1fa](https://github.com/flarum/core/commit/16eb1fa63b6d7b80ec30c24c0e406a2b7ab09934))
- API: Endpoint for uninstalling extensions returned an error ([c761802](https://github.com/flarum/core/commit/c76180290056ddbab67baf5ede814fcedf1dcf14))
- Documentation links in installer were outdated ([b58380e](https://github.com/flarum/core/commit/b58380e224ee54abdade3d0a4cc107ef5c91c9a9))
- Event posts where counted when aggregating user posts ([671fdec](https://github.com/flarum/core/commit/671fdec8d0a092ccceb5d4d5f657d0f4287fc4c7))
- Admins could not reset user passwords ([c67fb2d](https://github.com/flarum/core/commit/c67fb2d4b6a128c71d65dc6703310c0b62f91be2))
- Several down migrations were invalid
- Validation errors on reset password page resulted in HTTP 404 ([4611abe](https://github.com/flarum/core/commit/4611abe5db8b94ca3dc7bf9c447fca7c67358ee3))
-`is:unread` gambit generated an invalid query ([e17bb0b](https://github.com/flarum/core/commit/e17bb0b4331f2c92459292195c6b7db8cde1f9f3))
- Entire forum was breaking when the `custom_less` setting was missing from the database ([bf2c5a5](https://github.com/flarum/core/commit/bf2c5a5564dff3f5ef13efe7a8d69f2617570ce6))
- Dropdown icon was not showing in user card when on user page ([12fdfc9](https://github.com/flarum/core/commit/12fdfc9b544a27f6fe59c82ad6bddd3420cc0181))
- Requests were missing the `original*` attributes, which broke installations in subfolders ([56fde28](https://github.com/flarum/core/commit/56fde28e436f52fee0c03c538f0a6049bc584b53))
- Special characters such as `%` and `_` could return incorrect results ([ee3640e](https://github.com/flarum/core/commit/ee3640e1605ff67fef4b3d5cd0596f14a6ae73c9))
- FontAwesome component package changed paths in version 5.9.0 ([5eb69e1](https://github.com/flarum/core/commit/5eb69e1f59fa73fdfd5badbf41a05a6a040e7426))
- Some server environments had problems accessing the system-wide tmp path for storing JS file maps ([54660eb](https://github.com/flarum/core/commit/54660ebd6311f9ea142f1b573263d0d907400786))
- Content length of posts.content was not migrated to mediumText in 2017 ([590b311](https://github.com/flarum/core/commit/590b3115708bf94a9c7f169d98c6126380c7056e))
- An error occurred when going to the previous route if there was no previous route found ([985b87da](https://github.com/flarum/core/commit/985b87da6c9942c568a1a192e2fdcfde72e030ee))
### Removed
-`php flarum install --defaults` - this was meant to be used in our old development VM ([44c9109](https://github.com/flarum/core/commit/44c91099cd77138bb5fc29f14fb1e81a9781272d))
- Obsolete `id` attributes in JSON-API responses ([ecc3b5e](https://github.com/flarum/core/commit/ecc3b5e2271f8d9b38d52cd54476d86995dbe32e) and [7a44086](https://github.com/flarum/core/commit/7a44086bf3a0e3ba907dceb13d07ac695eca05ea))
- Fix live output in `migrate:reset` command ([f591585](https://github.com/flarum/core/commit/f591585d02f8c4ff0211c5bf4413dd6baa724c05))
- Fix search with database prefix ([7705a2b](https://github.com/flarum/core/commit/7705a2b7d751943ef9d0c7379ec34f8530b99310))
- Fix invalid join time of admin user created by installer ([57f73c9](https://github.com/flarum/core/commit/57f73c9638eeb825f9e336ed3c443afccfd8995e))
- Ensure InnoDB engine is used for all tables ([fb6b51b](https://github.com/flarum/core/commit/fb6b51b1cfef0af399607fe038603c8240800b2b), [6370f7e](https://github.com/flarum/core/commit/6370f7ecffa9ea7d5fb64d9551400edbc63318db))
- Fix dropping foreign keys in `down` migrations ([57d5846](https://github.com/flarum/core/commit/57d5846b647881009d9e60f9ffca20b1bb77776e))
- Fix discussion list scroll position not being maintained when hero is not visible ([40dc6ac](https://github.com/flarum/core/commit/40dc6ac604c2a0973356b38217aa8d09352daae5))
- Fix empty meta description tag ([88e43cc](https://github.com/flarum/core/commit/88e43cc6940ee30d6529e9ce659471ec4fb1c474))
- Remove empty attributes on `<html>` tag ([796b577](https://github.com/flarum/core/commit/796b57753d34d4ea741dbebcbc550b17808f6c94))
**[Flarum](https://flarum.org/) is a delightfully simple discussion platform for your website.** It's fast and easy to use, with all the features you need to run a successful community. It is designed to be:
* **Fast and simple.** No clutter, no bloat, no complex dependencies. Flarum is built with PHP so it’s quick and easy to deploy. The interface is powered by Mithril, a performant JavaScript framework with a tiny footprint.
* **Beautiful and responsive.** This is forum software for humans. Flarum is carefully designed to be consistent and intuitive across platforms, out-of-the-box.
* **Powerful and extensible.** Customize, extend, and integrate Flarum to suit your community. Flarum’s architecture is amazingly flexible, with a powerful Extension API.

## Installation
This repository contains Flarum's core code. If you want to set up a forum, visit the [Flarum skeleton repository](https://github.com/flarum/flarum). For support, refer to the [documentation](https://docs.flarum.org/), and ask questions on [Flarum Discuss](https://discuss.flarum.org/) (our community forum) or [Discord server](https://flarum.org/discord/).
## Contributing
Flarum is open-source and we would love your help building it! Please read the [Contributing Guide](https://github.com/flarum/flarum/blob/master/CONTRIBUTING.md) to learn how you can help.
Thank you for considering contributing to Flarum! Please read the **[Contributing guide](https://docs.flarum.org/contributing)** to learn how you can help.
## Security Vulnerabilities
If you discover a security vulnerability within Flarum, please send an e-mail to [security@flarum.org](mailto:security@flarum.org). All security vulnerabilities will be promptly addressed. More details can be found in our [security policy](https://github.com/flarum/core/security/policy).
## License
Flarum is open-source software licensed under the [MIT License](https://github.com/flarum/flarum/blob/master/LICENSE).
Some files were not shown because too many files have changed in this diff
Show More
Reference in New Issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.