mirror of
https://github.com/flarum/core.git
synced 2025-08-08 01:16:52 +02:00
Merge branch 'master' into 1236-user-preferences
This commit is contained in:
3
.github/ISSUE_TEMPLATE/bug-report.md
vendored
3
.github/ISSUE_TEMPLATE/bug-report.md
vendored
@@ -3,9 +3,6 @@ name: "🐛 Bug Report"
|
|||||||
about: "If something isn't working as expected"
|
about: "If something isn't working as expected"
|
||||||
|
|
||||||
---
|
---
|
||||||
<!--
|
|
||||||
IMPORTANT: If you discover a security vulnerability within Flarum, please send an email to [security@flarum.org](mailto:security@flarum.org) instead. We will address these with the utmost urgency and it will prevent vulnerabilities, which may be abused, from popping up on our issue tracker.
|
|
||||||
-->
|
|
||||||
## Bug Report
|
## Bug Report
|
||||||
|
|
||||||
**Current Behavior**
|
**Current Behavior**
|
||||||
|
@@ -1,8 +0,0 @@
|
|||||||
---
|
|
||||||
name: "🔒 Security Vulnerability"
|
|
||||||
about: "When you discover a security issue"
|
|
||||||
---
|
|
||||||
|
|
||||||
If you discover a security vulnerability within Flarum, please send an email to [security@flarum.org](mailto:security@flarum.org) instead.
|
|
||||||
**DO NOT open an issue on this repository.**
|
|
||||||
We will address these with the utmost urgency and it will prevent vulnerabilities, which may be abused, from popping up on our issue tracker.
|
|
13
.github/SECURITY.md
vendored
Normal file
13
.github/SECURITY.md
vendored
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
# Security Policy
|
||||||
|
|
||||||
|
## Supported Versions
|
||||||
|
|
||||||
|
During the beta phase, we will only patch security vulnerabilities in the latest beta release.
|
||||||
|
|
||||||
|
## Reporting a Vulnerability
|
||||||
|
|
||||||
|
If you discover a security vulnerability within Flarum, please send an email to security@flarum.org so we can address it promptly.
|
||||||
|
|
||||||
|
We will get back to you as time allows.
|
||||||
|
Discussions may commence internally, so you may not hear back immediately.
|
||||||
|
When reporting a vulnerability, please provide your GitHub username (if available), so that we can invite you to collaborate on a [security advisory on GitHub](https://help.github.com/en/articles/about-maintainer-security-advisories).
|
12
.travis.yml
12
.travis.yml
@@ -45,6 +45,14 @@ jobs:
|
|||||||
- php: 7.2
|
- php: 7.2
|
||||||
env: DB=mysql PREFIX=forum_
|
env: DB=mysql PREFIX=forum_
|
||||||
|
|
||||||
|
- php: 7.4snapshot
|
||||||
|
env: DB=mysql
|
||||||
|
|
||||||
|
- php: 7.4snapshot
|
||||||
|
addons:
|
||||||
|
mariadb: '10.2'
|
||||||
|
env: DB=mariadb
|
||||||
|
|
||||||
- stage: build
|
- stage: build
|
||||||
language: generic
|
language: generic
|
||||||
if: branch = master AND type = push
|
if: branch = master AND type = push
|
||||||
@@ -53,3 +61,7 @@ jobs:
|
|||||||
-k $encrypted_678139e2bc67_key
|
-k $encrypted_678139e2bc67_key
|
||||||
-i $encrypted_678139e2bc67_iv
|
-i $encrypted_678139e2bc67_iv
|
||||||
after_success: skip
|
after_success: skip
|
||||||
|
|
||||||
|
matrix:
|
||||||
|
allow_failures:
|
||||||
|
- php: 7.4snapshot
|
||||||
|
13
CHANGELOG.md
13
CHANGELOG.md
@@ -1,6 +1,6 @@
|
|||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
## Unreleased
|
## [0.1.0-beta.9](https://github.com/flarum/core/compare/v0.1.0-beta.8.2...v0.1.0-beta.9)
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
- New `hasPermission()` helper method for `Group` objects ([9684fbc](https://github.com/flarum/core/commit/9684fbc4da07d32aa322d9228302a23418412cb9))
|
- New `hasPermission()` helper method for `Group` objects ([9684fbc](https://github.com/flarum/core/commit/9684fbc4da07d32aa322d9228302a23418412cb9))
|
||||||
@@ -11,6 +11,7 @@
|
|||||||
- Check and enforce minimum MariaDB ([7ff9a90](https://github.com/flarum/core/commit/7ff9a90204923293adc520d3c02dc984845d4f9f))
|
- 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))
|
- 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))
|
- 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
|
### Changed
|
||||||
- Performance: Actually cache translations on disk ([0d16fac](https://github.com/flarum/core/commit/0d16fac001bb735ee66e82871183516aeac269b7))
|
- Performance: Actually cache translations on disk ([0d16fac](https://github.com/flarum/core/commit/0d16fac001bb735ee66e82871183516aeac269b7))
|
||||||
@@ -32,9 +33,19 @@
|
|||||||
- Admins could not reset user passwords ([c67fb2d](https://github.com/flarum/core/commit/c67fb2d4b6a128c71d65dc6703310c0b62f91be2))
|
- Admins could not reset user passwords ([c67fb2d](https://github.com/flarum/core/commit/c67fb2d4b6a128c71d65dc6703310c0b62f91be2))
|
||||||
- Several down migrations were invalid
|
- Several down migrations were invalid
|
||||||
- Validation errors on reset password page resulted in HTTP 404 ([4611abe](https://github.com/flarum/core/commit/4611abe5db8b94ca3dc7bf9c447fca7c67358ee3))
|
- 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
|
### Removed
|
||||||
- `php flarum install --defaults` - this was meant to be used in our old development VM ([44c9109](https://github.com/flarum/core/commit/44c91099cd77138bb5fc29f14fb1e81a9781272d))
|
- `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))
|
||||||
|
|
||||||
## [0.1.0-beta.8.1](https://github.com/flarum/core/compare/v0.1.0-beta.8...v0.1.0-beta.8.1)
|
## [0.1.0-beta.8.1](https://github.com/flarum/core/compare/v0.1.0-beta.8...v0.1.0-beta.8.1)
|
||||||
|
|
||||||
|
@@ -1,3 +0,0 @@
|
|||||||
# Contributing to Flarum
|
|
||||||
|
|
||||||
Thank you for considering contributing to Flarum! Please read the **[Contributing guide](https://flarum.org/docs/contributing.html)** to learn how you can help.
|
|
@@ -22,7 +22,7 @@
|
|||||||
"require": {
|
"require": {
|
||||||
"php": ">=7.1",
|
"php": ">=7.1",
|
||||||
"axy/sourcemap": "^0.1.4",
|
"axy/sourcemap": "^0.1.4",
|
||||||
"components/font-awesome": "^5.4.2",
|
"components/font-awesome": "5.9.*",
|
||||||
"dflydev/fig-cookies": "^1.0.2",
|
"dflydev/fig-cookies": "^1.0.2",
|
||||||
"doctrine/dbal": "^2.7",
|
"doctrine/dbal": "^2.7",
|
||||||
"franzl/whoops-middleware": "^0.4.0",
|
"franzl/whoops-middleware": "^0.4.0",
|
||||||
@@ -63,8 +63,8 @@
|
|||||||
"zendframework/zend-stratigility": "^3.0"
|
"zendframework/zend-stratigility": "^3.0"
|
||||||
},
|
},
|
||||||
"require-dev": {
|
"require-dev": {
|
||||||
"mockery/mockery": "^0.9.4",
|
"mockery/mockery": "^1.0",
|
||||||
"phpunit/phpunit": "^6.0"
|
"phpunit/phpunit": "^7.0"
|
||||||
},
|
},
|
||||||
"autoload": {
|
"autoload": {
|
||||||
"psr-4": {
|
"psr-4": {
|
||||||
@@ -95,5 +95,11 @@
|
|||||||
"test:unit": "phpunit -c tests/phpunit.unit.xml",
|
"test:unit": "phpunit -c tests/phpunit.unit.xml",
|
||||||
"test:integration": "phpunit -c tests/phpunit.integration.xml",
|
"test:integration": "phpunit -c tests/phpunit.integration.xml",
|
||||||
"test:setup": "@php tests/integration/setup.php"
|
"test:setup": "@php tests/integration/setup.php"
|
||||||
|
},
|
||||||
|
"scripts-descriptions": {
|
||||||
|
"test": "Runs all tests.",
|
||||||
|
"test:unit": "Runs all unit tests.",
|
||||||
|
"test:integration": "Runs all integration tests.",
|
||||||
|
"test:setup": "Sets up a database for use with integration tests. Execute this only once."
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
22
js/dist/admin.js
vendored
22
js/dist/admin.js
vendored
File diff suppressed because one or more lines are too long
2
js/dist/admin.js.map
vendored
2
js/dist/admin.js.map
vendored
File diff suppressed because one or more lines are too long
24
js/dist/forum.js
vendored
24
js/dist/forum.js
vendored
File diff suppressed because one or more lines are too long
2
js/dist/forum.js.map
vendored
2
js/dist/forum.js.map
vendored
File diff suppressed because one or more lines are too long
6
js/package-lock.json
generated
6
js/package-lock.json
generated
@@ -3107,9 +3107,9 @@
|
|||||||
"integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8="
|
"integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8="
|
||||||
},
|
},
|
||||||
"jquery": {
|
"jquery": {
|
||||||
"version": "3.3.1",
|
"version": "3.4.1",
|
||||||
"resolved": "https://registry.npmjs.org/jquery/-/jquery-3.3.1.tgz",
|
"resolved": "https://registry.npmjs.org/jquery/-/jquery-3.4.1.tgz",
|
||||||
"integrity": "sha512-Ubldcmxp5np52/ENotGxlLe6aGMvmF4R8S6tZjsP6Knsaxd/xp3Zrh50cG93lR6nPXyUFwzN3ZSOQI0wRJNdGg=="
|
"integrity": "sha512-36+AdBzCL+y6qjw5Tx7HgzeGCzC81MDDgaUP8ld2zhx58HdqXGoBd+tHdrBMiyjGQs0Hxs/MLZTu/eHNJJuWPw=="
|
||||||
},
|
},
|
||||||
"jquery.hotkeys": {
|
"jquery.hotkeys": {
|
||||||
"version": "0.1.0",
|
"version": "0.1.0",
|
||||||
|
@@ -7,7 +7,7 @@
|
|||||||
"color-thief-browser": "^2.0.2",
|
"color-thief-browser": "^2.0.2",
|
||||||
"expose-loader": "^0.7.5",
|
"expose-loader": "^0.7.5",
|
||||||
"flarum-webpack-config": "0.1.0-beta.10",
|
"flarum-webpack-config": "0.1.0-beta.10",
|
||||||
"jquery": "^3.3.1",
|
"jquery": "^3.4.1",
|
||||||
"jquery.hotkeys": "^0.1.0",
|
"jquery.hotkeys": "^0.1.0",
|
||||||
"lodash-es": "^4.17.11",
|
"lodash-es": "^4.17.11",
|
||||||
"m.attrs.bidi": "github:tobscure/m.attrs.bidi",
|
"m.attrs.bidi": "github:tobscure/m.attrs.bidi",
|
||||||
|
@@ -2,36 +2,55 @@ import Page from './Page';
|
|||||||
import FieldSet from '../../common/components/FieldSet';
|
import FieldSet from '../../common/components/FieldSet';
|
||||||
import Button from '../../common/components/Button';
|
import Button from '../../common/components/Button';
|
||||||
import Alert from '../../common/components/Alert';
|
import Alert from '../../common/components/Alert';
|
||||||
|
import Select from '../../common/components/Select';
|
||||||
|
import LoadingIndicator from '../../common/components/LoadingIndicator';
|
||||||
import saveSettings from '../utils/saveSettings';
|
import saveSettings from '../utils/saveSettings';
|
||||||
|
|
||||||
export default class MailPage extends Page {
|
export default class MailPage extends Page {
|
||||||
init() {
|
init() {
|
||||||
super.init();
|
super.init();
|
||||||
|
|
||||||
this.loading = false;
|
this.loading = true;
|
||||||
|
this.saving = false;
|
||||||
|
|
||||||
this.fields = [
|
this.driverFields = {};
|
||||||
'mail_driver',
|
this.fields = ['mail_driver', 'mail_from'];
|
||||||
'mail_host',
|
|
||||||
'mail_from',
|
|
||||||
'mail_port',
|
|
||||||
'mail_username',
|
|
||||||
'mail_password',
|
|
||||||
'mail_encryption'
|
|
||||||
];
|
|
||||||
this.values = {};
|
this.values = {};
|
||||||
|
|
||||||
const settings = app.data.settings;
|
const settings = app.data.settings;
|
||||||
this.fields.forEach(key => this.values[key] = m.prop(settings[key]));
|
this.fields.forEach(key => this.values[key] = m.prop(settings[key]));
|
||||||
|
|
||||||
this.localeOptions = {};
|
app.request({
|
||||||
const locales = app.locales;
|
method: 'GET',
|
||||||
for (const i in locales) {
|
url: app.forum.attribute('apiUrl') + '/mail-drivers'
|
||||||
this.localeOptions[i] = `${locales[i]} (${i})`;
|
}).then(response => {
|
||||||
}
|
this.driverFields = response['data'].reduce(
|
||||||
|
(hash, driver) => ({...hash, [driver['id']]: driver['attributes']['fields']}),
|
||||||
|
{}
|
||||||
|
);
|
||||||
|
|
||||||
|
Object.keys(this.driverFields).flatMap(key => this.driverFields[key]).forEach(
|
||||||
|
key => {
|
||||||
|
this.fields.push(key);
|
||||||
|
this.values[key] = m.prop(settings[key]);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
this.loading = false;
|
||||||
|
m.redraw();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
view() {
|
view() {
|
||||||
|
if (this.loading) {
|
||||||
|
return (
|
||||||
|
<div className="MailPage">
|
||||||
|
<div className="container">
|
||||||
|
<LoadingIndicator />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="MailPage">
|
<div className="MailPage">
|
||||||
<div className="container">
|
<div className="container">
|
||||||
@@ -41,36 +60,6 @@ export default class MailPage extends Page {
|
|||||||
{app.translator.trans('core.admin.email.text')}
|
{app.translator.trans('core.admin.email.text')}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{FieldSet.component({
|
|
||||||
label: app.translator.trans('core.admin.email.server_heading'),
|
|
||||||
className: 'MailPage-MailSettings',
|
|
||||||
children: [
|
|
||||||
<div className="MailPage-MailSettings-input">
|
|
||||||
<label>{app.translator.trans('core.admin.email.driver_label')}</label>
|
|
||||||
<input className="FormControl" value={this.values.mail_driver() || ''} oninput={m.withAttr('value', this.values.mail_driver)} />
|
|
||||||
<label>{app.translator.trans('core.admin.email.host_label')}</label>
|
|
||||||
<input className="FormControl" value={this.values.mail_host() || ''} oninput={m.withAttr('value', this.values.mail_host)} />
|
|
||||||
<label>{app.translator.trans('core.admin.email.port_label')}</label>
|
|
||||||
<input className="FormControl" value={this.values.mail_port() || ''} oninput={m.withAttr('value', this.values.mail_port)} />
|
|
||||||
<label>{app.translator.trans('core.admin.email.encryption_label')}</label>
|
|
||||||
<input className="FormControl" value={this.values.mail_encryption() || ''} oninput={m.withAttr('value', this.values.mail_encryption)} />
|
|
||||||
</div>
|
|
||||||
]
|
|
||||||
})}
|
|
||||||
|
|
||||||
{FieldSet.component({
|
|
||||||
label: app.translator.trans('core.admin.email.account_heading'),
|
|
||||||
className: 'MailPage-MailSettings',
|
|
||||||
children: [
|
|
||||||
<div className="MailPage-MailSettings-input">
|
|
||||||
<label>{app.translator.trans('core.admin.email.username_label')}</label>
|
|
||||||
<input className="FormControl" value={this.values.mail_username() || ''} oninput={m.withAttr('value', this.values.mail_username)} />
|
|
||||||
<label>{app.translator.trans('core.admin.email.password_label')}</label>
|
|
||||||
<input className="FormControl" value={this.values.mail_password() || ''} oninput={m.withAttr('value', this.values.mail_password)} />
|
|
||||||
</div>
|
|
||||||
]
|
|
||||||
})}
|
|
||||||
|
|
||||||
{FieldSet.component({
|
{FieldSet.component({
|
||||||
label: app.translator.trans('core.admin.email.addresses_heading'),
|
label: app.translator.trans('core.admin.email.addresses_heading'),
|
||||||
className: 'MailPage-MailSettings',
|
className: 'MailPage-MailSettings',
|
||||||
@@ -82,11 +71,35 @@ export default class MailPage extends Page {
|
|||||||
]
|
]
|
||||||
})}
|
})}
|
||||||
|
|
||||||
|
{FieldSet.component({
|
||||||
|
label: app.translator.trans('core.admin.email.driver_heading'),
|
||||||
|
className: 'MailPage-MailSettings',
|
||||||
|
children: [
|
||||||
|
<div className="MailPage-MailSettings-input">
|
||||||
|
<label>{app.translator.trans('core.admin.email.driver_label')}</label>
|
||||||
|
<Select value={this.values.mail_driver()} options={Object.keys(this.driverFields).reduce((memo, val) => ({...memo, [val]: val}), {})} onchange={this.values.mail_driver} />
|
||||||
|
</div>
|
||||||
|
]
|
||||||
|
})}
|
||||||
|
|
||||||
|
{Object.keys(this.driverFields[this.values.mail_driver()]).length > 0 && FieldSet.component({
|
||||||
|
label: app.translator.trans(`core.admin.email.${this.values.mail_driver()}_heading`),
|
||||||
|
className: 'MailPage-MailSettings',
|
||||||
|
children: [
|
||||||
|
<div className="MailPage-MailSettings-input">
|
||||||
|
{this.driverFields[this.values.mail_driver()].flatMap(field => [
|
||||||
|
<label>{app.translator.trans(`core.admin.email.${field}_label`)}</label>,
|
||||||
|
<input className="FormControl" value={this.values[field]() || ''} oninput={m.withAttr('value', this.values[field])} />
|
||||||
|
])}
|
||||||
|
</div>
|
||||||
|
]
|
||||||
|
})}
|
||||||
|
|
||||||
{Button.component({
|
{Button.component({
|
||||||
type: 'submit',
|
type: 'submit',
|
||||||
className: 'Button Button--primary',
|
className: 'Button Button--primary',
|
||||||
children: app.translator.trans('core.admin.email.submit_button'),
|
children: app.translator.trans('core.admin.email.submit_button'),
|
||||||
loading: this.loading,
|
loading: this.saving,
|
||||||
disabled: !this.changed()
|
disabled: !this.changed()
|
||||||
})}
|
})}
|
||||||
</form>
|
</form>
|
||||||
@@ -102,9 +115,9 @@ export default class MailPage extends Page {
|
|||||||
onsubmit(e) {
|
onsubmit(e) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
|
|
||||||
if (this.loading) return;
|
if (this.saving) return;
|
||||||
|
|
||||||
this.loading = true;
|
this.saving = true;
|
||||||
app.alerts.dismiss(this.successAlert);
|
app.alerts.dismiss(this.successAlert);
|
||||||
|
|
||||||
const settings = {};
|
const settings = {};
|
||||||
@@ -117,7 +130,7 @@ export default class MailPage extends Page {
|
|||||||
})
|
})
|
||||||
.catch(() => {})
|
.catch(() => {})
|
||||||
.then(() => {
|
.then(() => {
|
||||||
this.loading = false;
|
this.saving = false;
|
||||||
m.redraw();
|
m.redraw();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@@ -86,6 +86,10 @@ export default class History {
|
|||||||
* @public
|
* @public
|
||||||
*/
|
*/
|
||||||
back() {
|
back() {
|
||||||
|
if (! this.canGoBack()) {
|
||||||
|
return this.home();
|
||||||
|
}
|
||||||
|
|
||||||
this.stack.pop();
|
this.stack.pop();
|
||||||
|
|
||||||
m.route(this.getCurrent().url);
|
m.route(this.getCurrent().url);
|
||||||
|
@@ -29,6 +29,10 @@
|
|||||||
margin-bottom: 7px;
|
margin-bottom: 7px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.Select {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
:last-child {
|
:last-child {
|
||||||
margin-bottom: 0;
|
margin-bottom: 0;
|
||||||
}
|
}
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
@import "fontawesome";
|
@import "fontawesome";
|
||||||
@import "fa-brands";
|
@import "brands";
|
||||||
@import "fa-regular";
|
@import "regular";
|
||||||
@import "fa-solid";
|
@import "solid";
|
||||||
@fa-font-path: "./fonts";
|
@fa-font-path: "./fonts";
|
||||||
|
|
||||||
@import "normalize";
|
@import "normalize";
|
||||||
|
@@ -1,10 +1,5 @@
|
|||||||
.UserPage {
|
.UserPage {
|
||||||
.UserCard-controls {
|
.UserHero .Dropdown-toggle .Button-icon {
|
||||||
float: right;
|
display: none;
|
||||||
|
|
||||||
.Dropdown-toggle .Button-icon {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -12,16 +12,17 @@
|
|||||||
use Illuminate\Database\Schema\Blueprint;
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
use Illuminate\Database\Schema\Builder;
|
use Illuminate\Database\Schema\Builder;
|
||||||
|
|
||||||
|
// https://github.com/doctrine/dbal/issues/2566#issuecomment-480217999
|
||||||
return [
|
return [
|
||||||
'up' => function (Builder $schema) {
|
'up' => function (Builder $schema) {
|
||||||
$schema->table('posts', function (Blueprint $table) {
|
$schema->table('posts', function (Blueprint $table) {
|
||||||
$table->mediumText('content')->change();
|
$table->mediumText('content')->comment(' ')->change();
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
'down' => function (Builder $schema) {
|
'down' => function (Builder $schema) {
|
||||||
$schema->table('posts', function (Blueprint $table) {
|
$schema->table('posts', function (Blueprint $table) {
|
||||||
$table->text('content')->change();
|
$table->text('content')->comment('')->change();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
];
|
];
|
@@ -61,6 +61,7 @@ class AdminServiceProvider extends AbstractServiceProvider
|
|||||||
$pipe->pipe($app->make(HttpMiddleware\StartSession::class));
|
$pipe->pipe($app->make(HttpMiddleware\StartSession::class));
|
||||||
$pipe->pipe($app->make(HttpMiddleware\RememberFromCookie::class));
|
$pipe->pipe($app->make(HttpMiddleware\RememberFromCookie::class));
|
||||||
$pipe->pipe($app->make(HttpMiddleware\AuthenticateWithSession::class));
|
$pipe->pipe($app->make(HttpMiddleware\AuthenticateWithSession::class));
|
||||||
|
$pipe->pipe($app->make(HttpMiddleware\CheckCsrfToken::class));
|
||||||
$pipe->pipe($app->make(HttpMiddleware\SetLocale::class));
|
$pipe->pipe($app->make(HttpMiddleware\SetLocale::class));
|
||||||
$pipe->pipe($app->make(Middleware\RequireAdministrateAbility::class));
|
$pipe->pipe($app->make(Middleware\RequireAdministrateAbility::class));
|
||||||
|
|
||||||
|
@@ -14,6 +14,7 @@ namespace Flarum\Api;
|
|||||||
use Carbon\Carbon;
|
use Carbon\Carbon;
|
||||||
use Flarum\Database\AbstractModel;
|
use Flarum\Database\AbstractModel;
|
||||||
use Flarum\User\User;
|
use Flarum\User\User;
|
||||||
|
use Illuminate\Support\Str;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @property int $id
|
* @property int $id
|
||||||
@@ -38,7 +39,7 @@ class ApiKey extends AbstractModel
|
|||||||
{
|
{
|
||||||
$key = new static;
|
$key = new static;
|
||||||
|
|
||||||
$key->key = str_random(40);
|
$key->key = Str::random(40);
|
||||||
|
|
||||||
return $key;
|
return $key;
|
||||||
}
|
}
|
||||||
|
@@ -57,6 +57,7 @@ class ApiServiceProvider extends AbstractServiceProvider
|
|||||||
$pipe->pipe($app->make(HttpMiddleware\RememberFromCookie::class));
|
$pipe->pipe($app->make(HttpMiddleware\RememberFromCookie::class));
|
||||||
$pipe->pipe($app->make(HttpMiddleware\AuthenticateWithSession::class));
|
$pipe->pipe($app->make(HttpMiddleware\AuthenticateWithSession::class));
|
||||||
$pipe->pipe($app->make(HttpMiddleware\AuthenticateWithHeader::class));
|
$pipe->pipe($app->make(HttpMiddleware\AuthenticateWithHeader::class));
|
||||||
|
$pipe->pipe($app->make(HttpMiddleware\CheckCsrfToken::class));
|
||||||
$pipe->pipe($app->make(HttpMiddleware\SetLocale::class));
|
$pipe->pipe($app->make(HttpMiddleware\SetLocale::class));
|
||||||
|
|
||||||
event(new ConfigureMiddleware($pipe, 'api'));
|
event(new ConfigureMiddleware($pipe, 'api'));
|
||||||
|
@@ -16,6 +16,7 @@ use Flarum\Discussion\Command\ReadDiscussion;
|
|||||||
use Flarum\Discussion\Command\StartDiscussion;
|
use Flarum\Discussion\Command\StartDiscussion;
|
||||||
use Flarum\Post\Floodgate;
|
use Flarum\Post\Floodgate;
|
||||||
use Illuminate\Contracts\Bus\Dispatcher;
|
use Illuminate\Contracts\Bus\Dispatcher;
|
||||||
|
use Illuminate\Support\Arr;
|
||||||
use Psr\Http\Message\ServerRequestInterface;
|
use Psr\Http\Message\ServerRequestInterface;
|
||||||
use Tobscure\JsonApi\Document;
|
use Tobscure\JsonApi\Document;
|
||||||
|
|
||||||
@@ -63,14 +64,14 @@ class CreateDiscussionController extends AbstractCreateController
|
|||||||
protected function data(ServerRequestInterface $request, Document $document)
|
protected function data(ServerRequestInterface $request, Document $document)
|
||||||
{
|
{
|
||||||
$actor = $request->getAttribute('actor');
|
$actor = $request->getAttribute('actor');
|
||||||
$ipAddress = array_get($request->getServerParams(), 'REMOTE_ADDR', '127.0.0.1');
|
$ipAddress = Arr::get($request->getServerParams(), 'REMOTE_ADDR', '127.0.0.1');
|
||||||
|
|
||||||
if (! $request->getAttribute('bypassFloodgate')) {
|
if (! $request->getAttribute('bypassFloodgate')) {
|
||||||
$this->floodgate->assertNotFlooding($actor);
|
$this->floodgate->assertNotFlooding($actor);
|
||||||
}
|
}
|
||||||
|
|
||||||
$discussion = $this->bus->dispatch(
|
$discussion = $this->bus->dispatch(
|
||||||
new StartDiscussion($actor, array_get($request->getParsedBody(), 'data', []), $ipAddress)
|
new StartDiscussion($actor, Arr::get($request->getParsedBody(), 'data', []), $ipAddress)
|
||||||
);
|
);
|
||||||
|
|
||||||
// After creating the discussion, we assume that the user has seen all
|
// After creating the discussion, we assume that the user has seen all
|
||||||
|
@@ -14,6 +14,7 @@ namespace Flarum\Api\Controller;
|
|||||||
use Flarum\Api\Serializer\GroupSerializer;
|
use Flarum\Api\Serializer\GroupSerializer;
|
||||||
use Flarum\Group\Command\CreateGroup;
|
use Flarum\Group\Command\CreateGroup;
|
||||||
use Illuminate\Contracts\Bus\Dispatcher;
|
use Illuminate\Contracts\Bus\Dispatcher;
|
||||||
|
use Illuminate\Support\Arr;
|
||||||
use Psr\Http\Message\ServerRequestInterface;
|
use Psr\Http\Message\ServerRequestInterface;
|
||||||
use Tobscure\JsonApi\Document;
|
use Tobscure\JsonApi\Document;
|
||||||
|
|
||||||
@@ -43,7 +44,7 @@ class CreateGroupController extends AbstractCreateController
|
|||||||
protected function data(ServerRequestInterface $request, Document $document)
|
protected function data(ServerRequestInterface $request, Document $document)
|
||||||
{
|
{
|
||||||
return $this->bus->dispatch(
|
return $this->bus->dispatch(
|
||||||
new CreateGroup($request->getAttribute('actor'), array_get($request->getParsedBody(), 'data', []))
|
new CreateGroup($request->getAttribute('actor'), Arr::get($request->getParsedBody(), 'data', []))
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -16,6 +16,7 @@ use Flarum\Discussion\Command\ReadDiscussion;
|
|||||||
use Flarum\Post\Command\PostReply;
|
use Flarum\Post\Command\PostReply;
|
||||||
use Flarum\Post\Floodgate;
|
use Flarum\Post\Floodgate;
|
||||||
use Illuminate\Contracts\Bus\Dispatcher;
|
use Illuminate\Contracts\Bus\Dispatcher;
|
||||||
|
use Illuminate\Support\Arr;
|
||||||
use Psr\Http\Message\ServerRequestInterface;
|
use Psr\Http\Message\ServerRequestInterface;
|
||||||
use Tobscure\JsonApi\Document;
|
use Tobscure\JsonApi\Document;
|
||||||
|
|
||||||
@@ -62,9 +63,9 @@ class CreatePostController extends AbstractCreateController
|
|||||||
protected function data(ServerRequestInterface $request, Document $document)
|
protected function data(ServerRequestInterface $request, Document $document)
|
||||||
{
|
{
|
||||||
$actor = $request->getAttribute('actor');
|
$actor = $request->getAttribute('actor');
|
||||||
$data = array_get($request->getParsedBody(), 'data', []);
|
$data = Arr::get($request->getParsedBody(), 'data', []);
|
||||||
$discussionId = array_get($data, 'relationships.discussion.data.id');
|
$discussionId = Arr::get($data, 'relationships.discussion.data.id');
|
||||||
$ipAddress = array_get($request->getServerParams(), 'REMOTE_ADDR', '127.0.0.1');
|
$ipAddress = Arr::get($request->getServerParams(), 'REMOTE_ADDR', '127.0.0.1');
|
||||||
|
|
||||||
if (! $request->getAttribute('bypassFloodgate')) {
|
if (! $request->getAttribute('bypassFloodgate')) {
|
||||||
$this->floodgate->assertNotFlooding($actor);
|
$this->floodgate->assertNotFlooding($actor);
|
||||||
|
@@ -16,6 +16,7 @@ use Flarum\User\Exception\PermissionDeniedException;
|
|||||||
use Flarum\User\UserRepository;
|
use Flarum\User\UserRepository;
|
||||||
use Illuminate\Contracts\Bus\Dispatcher as BusDispatcher;
|
use Illuminate\Contracts\Bus\Dispatcher as BusDispatcher;
|
||||||
use Illuminate\Contracts\Events\Dispatcher as EventDispatcher;
|
use Illuminate\Contracts\Events\Dispatcher as EventDispatcher;
|
||||||
|
use Illuminate\Support\Arr;
|
||||||
use Psr\Http\Message\ResponseInterface;
|
use Psr\Http\Message\ResponseInterface;
|
||||||
use Psr\Http\Message\ServerRequestInterface;
|
use Psr\Http\Message\ServerRequestInterface;
|
||||||
use Psr\Http\Server\RequestHandlerInterface;
|
use Psr\Http\Server\RequestHandlerInterface;
|
||||||
@@ -57,9 +58,9 @@ class CreateTokenController implements RequestHandlerInterface
|
|||||||
{
|
{
|
||||||
$body = $request->getParsedBody();
|
$body = $request->getParsedBody();
|
||||||
|
|
||||||
$identification = array_get($body, 'identification');
|
$identification = Arr::get($body, 'identification');
|
||||||
$password = array_get($body, 'password');
|
$password = Arr::get($body, 'password');
|
||||||
$lifetime = array_get($body, 'lifetime', 3600);
|
$lifetime = Arr::get($body, 'lifetime', 3600);
|
||||||
|
|
||||||
$user = $this->users->findByIdentification($identification);
|
$user = $this->users->findByIdentification($identification);
|
||||||
|
|
||||||
|
@@ -14,6 +14,7 @@ namespace Flarum\Api\Controller;
|
|||||||
use Flarum\Api\Serializer\CurrentUserSerializer;
|
use Flarum\Api\Serializer\CurrentUserSerializer;
|
||||||
use Flarum\User\Command\RegisterUser;
|
use Flarum\User\Command\RegisterUser;
|
||||||
use Illuminate\Contracts\Bus\Dispatcher;
|
use Illuminate\Contracts\Bus\Dispatcher;
|
||||||
|
use Illuminate\Support\Arr;
|
||||||
use Psr\Http\Message\ServerRequestInterface;
|
use Psr\Http\Message\ServerRequestInterface;
|
||||||
use Tobscure\JsonApi\Document;
|
use Tobscure\JsonApi\Document;
|
||||||
|
|
||||||
@@ -43,7 +44,7 @@ class CreateUserController extends AbstractCreateController
|
|||||||
protected function data(ServerRequestInterface $request, Document $document)
|
protected function data(ServerRequestInterface $request, Document $document)
|
||||||
{
|
{
|
||||||
return $this->bus->dispatch(
|
return $this->bus->dispatch(
|
||||||
new RegisterUser($request->getAttribute('actor'), array_get($request->getParsedBody(), 'data', []))
|
new RegisterUser($request->getAttribute('actor'), Arr::get($request->getParsedBody(), 'data', []))
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -14,6 +14,7 @@ namespace Flarum\Api\Controller;
|
|||||||
use Flarum\Api\Serializer\UserSerializer;
|
use Flarum\Api\Serializer\UserSerializer;
|
||||||
use Flarum\User\Command\DeleteAvatar;
|
use Flarum\User\Command\DeleteAvatar;
|
||||||
use Illuminate\Contracts\Bus\Dispatcher;
|
use Illuminate\Contracts\Bus\Dispatcher;
|
||||||
|
use Illuminate\Support\Arr;
|
||||||
use Psr\Http\Message\ServerRequestInterface;
|
use Psr\Http\Message\ServerRequestInterface;
|
||||||
use Tobscure\JsonApi\Document;
|
use Tobscure\JsonApi\Document;
|
||||||
|
|
||||||
@@ -43,7 +44,7 @@ class DeleteAvatarController extends AbstractShowController
|
|||||||
protected function data(ServerRequestInterface $request, Document $document)
|
protected function data(ServerRequestInterface $request, Document $document)
|
||||||
{
|
{
|
||||||
return $this->bus->dispatch(
|
return $this->bus->dispatch(
|
||||||
new DeleteAvatar(array_get($request->getQueryParams(), 'id'), $request->getAttribute('actor'))
|
new DeleteAvatar(Arr::get($request->getQueryParams(), 'id'), $request->getAttribute('actor'))
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -13,6 +13,7 @@ namespace Flarum\Api\Controller;
|
|||||||
|
|
||||||
use Flarum\Discussion\Command\DeleteDiscussion;
|
use Flarum\Discussion\Command\DeleteDiscussion;
|
||||||
use Illuminate\Contracts\Bus\Dispatcher;
|
use Illuminate\Contracts\Bus\Dispatcher;
|
||||||
|
use Illuminate\Support\Arr;
|
||||||
use Psr\Http\Message\ServerRequestInterface;
|
use Psr\Http\Message\ServerRequestInterface;
|
||||||
|
|
||||||
class DeleteDiscussionController extends AbstractDeleteController
|
class DeleteDiscussionController extends AbstractDeleteController
|
||||||
@@ -35,7 +36,7 @@ class DeleteDiscussionController extends AbstractDeleteController
|
|||||||
*/
|
*/
|
||||||
protected function delete(ServerRequestInterface $request)
|
protected function delete(ServerRequestInterface $request)
|
||||||
{
|
{
|
||||||
$id = array_get($request->getQueryParams(), 'id');
|
$id = Arr::get($request->getQueryParams(), 'id');
|
||||||
$actor = $request->getAttribute('actor');
|
$actor = $request->getAttribute('actor');
|
||||||
$input = $request->getParsedBody();
|
$input = $request->getParsedBody();
|
||||||
|
|
||||||
|
@@ -13,6 +13,7 @@ namespace Flarum\Api\Controller;
|
|||||||
|
|
||||||
use Flarum\Group\Command\DeleteGroup;
|
use Flarum\Group\Command\DeleteGroup;
|
||||||
use Illuminate\Contracts\Bus\Dispatcher;
|
use Illuminate\Contracts\Bus\Dispatcher;
|
||||||
|
use Illuminate\Support\Arr;
|
||||||
use Psr\Http\Message\ServerRequestInterface;
|
use Psr\Http\Message\ServerRequestInterface;
|
||||||
|
|
||||||
class DeleteGroupController extends AbstractDeleteController
|
class DeleteGroupController extends AbstractDeleteController
|
||||||
@@ -36,7 +37,7 @@ class DeleteGroupController extends AbstractDeleteController
|
|||||||
protected function delete(ServerRequestInterface $request)
|
protected function delete(ServerRequestInterface $request)
|
||||||
{
|
{
|
||||||
$this->bus->dispatch(
|
$this->bus->dispatch(
|
||||||
new DeleteGroup(array_get($request->getQueryParams(), 'id'), $request->getAttribute('actor'))
|
new DeleteGroup(Arr::get($request->getQueryParams(), 'id'), $request->getAttribute('actor'))
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -13,6 +13,7 @@ namespace Flarum\Api\Controller;
|
|||||||
|
|
||||||
use Flarum\Post\Command\DeletePost;
|
use Flarum\Post\Command\DeletePost;
|
||||||
use Illuminate\Contracts\Bus\Dispatcher;
|
use Illuminate\Contracts\Bus\Dispatcher;
|
||||||
|
use Illuminate\Support\Arr;
|
||||||
use Psr\Http\Message\ServerRequestInterface;
|
use Psr\Http\Message\ServerRequestInterface;
|
||||||
|
|
||||||
class DeletePostController extends AbstractDeleteController
|
class DeletePostController extends AbstractDeleteController
|
||||||
@@ -36,7 +37,7 @@ class DeletePostController extends AbstractDeleteController
|
|||||||
protected function delete(ServerRequestInterface $request)
|
protected function delete(ServerRequestInterface $request)
|
||||||
{
|
{
|
||||||
$this->bus->dispatch(
|
$this->bus->dispatch(
|
||||||
new DeletePost(array_get($request->getQueryParams(), 'id'), $request->getAttribute('actor'))
|
new DeletePost(Arr::get($request->getQueryParams(), 'id'), $request->getAttribute('actor'))
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -13,6 +13,7 @@ namespace Flarum\Api\Controller;
|
|||||||
|
|
||||||
use Flarum\User\Command\DeleteUser;
|
use Flarum\User\Command\DeleteUser;
|
||||||
use Illuminate\Contracts\Bus\Dispatcher;
|
use Illuminate\Contracts\Bus\Dispatcher;
|
||||||
|
use Illuminate\Support\Arr;
|
||||||
use Psr\Http\Message\ServerRequestInterface;
|
use Psr\Http\Message\ServerRequestInterface;
|
||||||
|
|
||||||
class DeleteUserController extends AbstractDeleteController
|
class DeleteUserController extends AbstractDeleteController
|
||||||
@@ -36,7 +37,7 @@ class DeleteUserController extends AbstractDeleteController
|
|||||||
protected function delete(ServerRequestInterface $request)
|
protected function delete(ServerRequestInterface $request)
|
||||||
{
|
{
|
||||||
$this->bus->dispatch(
|
$this->bus->dispatch(
|
||||||
new DeleteUser(array_get($request->getQueryParams(), 'id'), $request->getAttribute('actor'))
|
new DeleteUser(Arr::get($request->getQueryParams(), 'id'), $request->getAttribute('actor'))
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -14,6 +14,7 @@ namespace Flarum\Api\Controller;
|
|||||||
use Flarum\User\Command\RequestPasswordReset;
|
use Flarum\User\Command\RequestPasswordReset;
|
||||||
use Flarum\User\UserRepository;
|
use Flarum\User\UserRepository;
|
||||||
use Illuminate\Contracts\Bus\Dispatcher;
|
use Illuminate\Contracts\Bus\Dispatcher;
|
||||||
|
use Illuminate\Support\Arr;
|
||||||
use Psr\Http\Message\ResponseInterface;
|
use Psr\Http\Message\ResponseInterface;
|
||||||
use Psr\Http\Message\ServerRequestInterface;
|
use Psr\Http\Message\ServerRequestInterface;
|
||||||
use Psr\Http\Server\RequestHandlerInterface;
|
use Psr\Http\Server\RequestHandlerInterface;
|
||||||
@@ -46,7 +47,7 @@ class ForgotPasswordController implements RequestHandlerInterface
|
|||||||
*/
|
*/
|
||||||
public function handle(ServerRequestInterface $request): ResponseInterface
|
public function handle(ServerRequestInterface $request): ResponseInterface
|
||||||
{
|
{
|
||||||
$email = array_get($request->getParsedBody(), 'email');
|
$email = Arr::get($request->getParsedBody(), 'email');
|
||||||
|
|
||||||
$this->bus->dispatch(
|
$this->bus->dispatch(
|
||||||
new RequestPasswordReset($email)
|
new RequestPasswordReset($email)
|
||||||
|
@@ -16,6 +16,7 @@ use Flarum\Discussion\Discussion;
|
|||||||
use Flarum\Discussion\Search\DiscussionSearcher;
|
use Flarum\Discussion\Search\DiscussionSearcher;
|
||||||
use Flarum\Http\UrlGenerator;
|
use Flarum\Http\UrlGenerator;
|
||||||
use Flarum\Search\SearchCriteria;
|
use Flarum\Search\SearchCriteria;
|
||||||
|
use Illuminate\Support\Arr;
|
||||||
use Psr\Http\Message\ServerRequestInterface;
|
use Psr\Http\Message\ServerRequestInterface;
|
||||||
use Tobscure\JsonApi\Document;
|
use Tobscure\JsonApi\Document;
|
||||||
|
|
||||||
@@ -75,7 +76,7 @@ class ListDiscussionsController extends AbstractListController
|
|||||||
protected function data(ServerRequestInterface $request, Document $document)
|
protected function data(ServerRequestInterface $request, Document $document)
|
||||||
{
|
{
|
||||||
$actor = $request->getAttribute('actor');
|
$actor = $request->getAttribute('actor');
|
||||||
$query = array_get($this->extractFilter($request), 'q');
|
$query = Arr::get($this->extractFilter($request), 'q');
|
||||||
$sort = $this->extractSort($request);
|
$sort = $this->extractSort($request);
|
||||||
|
|
||||||
$criteria = new SearchCriteria($actor, $query, $sort);
|
$criteria = new SearchCriteria($actor, $query, $sort);
|
||||||
|
45
src/Api/Controller/ListMailDriversController.php
Normal file
45
src/Api/Controller/ListMailDriversController.php
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of Flarum.
|
||||||
|
*
|
||||||
|
* (c) Toby Zerner <toby.zerner@gmail.com>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Flarum\Api\Controller;
|
||||||
|
|
||||||
|
use Flarum\Api\Serializer\MailDriverSerializer;
|
||||||
|
use Flarum\User\AssertPermissionTrait;
|
||||||
|
use Psr\Http\Message\ServerRequestInterface;
|
||||||
|
use Tobscure\JsonApi\Document;
|
||||||
|
|
||||||
|
class ListMailDriversController extends AbstractListController
|
||||||
|
{
|
||||||
|
use AssertPermissionTrait;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public $serializer = MailDriverSerializer::class;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
protected function data(ServerRequestInterface $request, Document $document)
|
||||||
|
{
|
||||||
|
$this->assertAdmin($request->getAttribute('actor'));
|
||||||
|
|
||||||
|
$drivers = self::$container->make('mail.supported_drivers');
|
||||||
|
array_walk($drivers, function (&$driver, $key) {
|
||||||
|
$driver = [
|
||||||
|
'id' => $key,
|
||||||
|
'driver' => self::$container->make($driver),
|
||||||
|
];
|
||||||
|
});
|
||||||
|
|
||||||
|
return $drivers;
|
||||||
|
}
|
||||||
|
}
|
@@ -15,6 +15,8 @@ use Flarum\Api\Serializer\PostSerializer;
|
|||||||
use Flarum\Event\ConfigurePostsQuery;
|
use Flarum\Event\ConfigurePostsQuery;
|
||||||
use Flarum\Post\PostRepository;
|
use Flarum\Post\PostRepository;
|
||||||
use Illuminate\Database\Eloquent\Builder;
|
use Illuminate\Database\Eloquent\Builder;
|
||||||
|
use Illuminate\Support\Arr;
|
||||||
|
use Illuminate\Support\Str;
|
||||||
use Psr\Http\Message\ServerRequestInterface;
|
use Psr\Http\Message\ServerRequestInterface;
|
||||||
use Tobscure\JsonApi\Document;
|
use Tobscure\JsonApi\Document;
|
||||||
use Tobscure\JsonApi\Exception\InvalidParameterException;
|
use Tobscure\JsonApi\Exception\InvalidParameterException;
|
||||||
@@ -64,7 +66,7 @@ class ListPostsController extends AbstractListController
|
|||||||
$filter = $this->extractFilter($request);
|
$filter = $this->extractFilter($request);
|
||||||
$include = $this->extractInclude($request);
|
$include = $this->extractInclude($request);
|
||||||
|
|
||||||
if ($postIds = array_get($filter, 'id')) {
|
if ($postIds = Arr::get($filter, 'id')) {
|
||||||
$postIds = explode(',', $postIds);
|
$postIds = explode(',', $postIds);
|
||||||
} else {
|
} else {
|
||||||
$postIds = $this->getPostIds($request);
|
$postIds = $this->getPostIds($request);
|
||||||
@@ -86,7 +88,7 @@ class ListPostsController extends AbstractListController
|
|||||||
$limit = $this->extractLimit($request);
|
$limit = $this->extractLimit($request);
|
||||||
$filter = $this->extractFilter($request);
|
$filter = $this->extractFilter($request);
|
||||||
|
|
||||||
if (($near = array_get($queryParams, 'page.near')) > 1) {
|
if (($near = Arr::get($queryParams, 'page.near')) > 1) {
|
||||||
if (count($filter) > 1 || ! isset($filter['discussion']) || $sort) {
|
if (count($filter) > 1 || ! isset($filter['discussion']) || $sort) {
|
||||||
throw new InvalidParameterException(
|
throw new InvalidParameterException(
|
||||||
'You can only use page[near] with filter[discussion] and the default sort order'
|
'You can only use page[near] with filter[discussion] and the default sort order'
|
||||||
@@ -120,7 +122,7 @@ class ListPostsController extends AbstractListController
|
|||||||
$query->skip($offset)->take($limit);
|
$query->skip($offset)->take($limit);
|
||||||
|
|
||||||
foreach ((array) $sort as $field => $order) {
|
foreach ((array) $sort as $field => $order) {
|
||||||
$query->orderBy(snake_case($field), $order);
|
$query->orderBy(Str::snake($field), $order);
|
||||||
}
|
}
|
||||||
|
|
||||||
return $query->pluck('id')->all();
|
return $query->pluck('id')->all();
|
||||||
@@ -132,19 +134,19 @@ class ListPostsController extends AbstractListController
|
|||||||
*/
|
*/
|
||||||
private function applyFilters(Builder $query, array $filter)
|
private function applyFilters(Builder $query, array $filter)
|
||||||
{
|
{
|
||||||
if ($discussionId = array_get($filter, 'discussion')) {
|
if ($discussionId = Arr::get($filter, 'discussion')) {
|
||||||
$query->where('discussion_id', $discussionId);
|
$query->where('discussion_id', $discussionId);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($number = array_get($filter, 'number')) {
|
if ($number = Arr::get($filter, 'number')) {
|
||||||
$query->where('number', $number);
|
$query->where('number', $number);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($userId = array_get($filter, 'user')) {
|
if ($userId = Arr::get($filter, 'user')) {
|
||||||
$query->where('user_id', $userId);
|
$query->where('user_id', $userId);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($type = array_get($filter, 'type')) {
|
if ($type = Arr::get($filter, 'type')) {
|
||||||
$query->where('type', $type);
|
$query->where('type', $type);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -16,6 +16,7 @@ use Flarum\Http\UrlGenerator;
|
|||||||
use Flarum\Search\SearchCriteria;
|
use Flarum\Search\SearchCriteria;
|
||||||
use Flarum\User\Exception\PermissionDeniedException;
|
use Flarum\User\Exception\PermissionDeniedException;
|
||||||
use Flarum\User\Search\UserSearcher;
|
use Flarum\User\Search\UserSearcher;
|
||||||
|
use Illuminate\Support\Arr;
|
||||||
use Psr\Http\Message\ServerRequestInterface;
|
use Psr\Http\Message\ServerRequestInterface;
|
||||||
use Tobscure\JsonApi\Document;
|
use Tobscure\JsonApi\Document;
|
||||||
|
|
||||||
@@ -73,7 +74,7 @@ class ListUsersController extends AbstractListController
|
|||||||
throw new PermissionDeniedException;
|
throw new PermissionDeniedException;
|
||||||
}
|
}
|
||||||
|
|
||||||
$query = array_get($this->extractFilter($request), 'q');
|
$query = Arr::get($this->extractFilter($request), 'q');
|
||||||
$sort = $this->extractSort($request);
|
$sort = $this->extractSort($request);
|
||||||
|
|
||||||
$criteria = new SearchCriteria($actor, $query, $sort);
|
$criteria = new SearchCriteria($actor, $query, $sort);
|
||||||
|
@@ -18,6 +18,7 @@ use Flarum\User\EmailToken;
|
|||||||
use Flarum\User\Exception\PermissionDeniedException;
|
use Flarum\User\Exception\PermissionDeniedException;
|
||||||
use Illuminate\Contracts\Mail\Mailer;
|
use Illuminate\Contracts\Mail\Mailer;
|
||||||
use Illuminate\Mail\Message;
|
use Illuminate\Mail\Message;
|
||||||
|
use Illuminate\Support\Arr;
|
||||||
use Psr\Http\Message\ResponseInterface;
|
use Psr\Http\Message\ResponseInterface;
|
||||||
use Psr\Http\Message\ServerRequestInterface;
|
use Psr\Http\Message\ServerRequestInterface;
|
||||||
use Psr\Http\Server\RequestHandlerInterface;
|
use Psr\Http\Server\RequestHandlerInterface;
|
||||||
@@ -67,7 +68,7 @@ class SendConfirmationEmailController implements RequestHandlerInterface
|
|||||||
*/
|
*/
|
||||||
public function handle(ServerRequestInterface $request): ResponseInterface
|
public function handle(ServerRequestInterface $request): ResponseInterface
|
||||||
{
|
{
|
||||||
$id = array_get($request->getQueryParams(), 'id');
|
$id = Arr::get($request->getQueryParams(), 'id');
|
||||||
$actor = $request->getAttribute('actor');
|
$actor = $request->getAttribute('actor');
|
||||||
|
|
||||||
$this->assertRegistered($actor);
|
$this->assertRegistered($actor);
|
||||||
|
@@ -13,6 +13,7 @@ namespace Flarum\Api\Controller;
|
|||||||
|
|
||||||
use Flarum\Group\Permission;
|
use Flarum\Group\Permission;
|
||||||
use Flarum\User\AssertPermissionTrait;
|
use Flarum\User\AssertPermissionTrait;
|
||||||
|
use Illuminate\Support\Arr;
|
||||||
use Psr\Http\Message\ResponseInterface;
|
use Psr\Http\Message\ResponseInterface;
|
||||||
use Psr\Http\Message\ServerRequestInterface;
|
use Psr\Http\Message\ServerRequestInterface;
|
||||||
use Psr\Http\Server\RequestHandlerInterface;
|
use Psr\Http\Server\RequestHandlerInterface;
|
||||||
@@ -30,8 +31,8 @@ class SetPermissionController implements RequestHandlerInterface
|
|||||||
$this->assertAdmin($request->getAttribute('actor'));
|
$this->assertAdmin($request->getAttribute('actor'));
|
||||||
|
|
||||||
$body = $request->getParsedBody();
|
$body = $request->getParsedBody();
|
||||||
$permission = array_get($body, 'permission');
|
$permission = Arr::get($body, 'permission');
|
||||||
$groupIds = array_get($body, 'groupIds');
|
$groupIds = Arr::get($body, 'groupIds');
|
||||||
|
|
||||||
Permission::where('permission', $permission)->delete();
|
Permission::where('permission', $permission)->delete();
|
||||||
|
|
||||||
|
@@ -16,6 +16,8 @@ use Flarum\Discussion\Discussion;
|
|||||||
use Flarum\Discussion\DiscussionRepository;
|
use Flarum\Discussion\DiscussionRepository;
|
||||||
use Flarum\Post\PostRepository;
|
use Flarum\Post\PostRepository;
|
||||||
use Flarum\User\User;
|
use Flarum\User\User;
|
||||||
|
use Illuminate\Support\Arr;
|
||||||
|
use Illuminate\Support\Str;
|
||||||
use Psr\Http\Message\ServerRequestInterface;
|
use Psr\Http\Message\ServerRequestInterface;
|
||||||
use Tobscure\JsonApi\Document;
|
use Tobscure\JsonApi\Document;
|
||||||
|
|
||||||
@@ -73,7 +75,7 @@ class ShowDiscussionController extends AbstractShowController
|
|||||||
*/
|
*/
|
||||||
protected function data(ServerRequestInterface $request, Document $document)
|
protected function data(ServerRequestInterface $request, Document $document)
|
||||||
{
|
{
|
||||||
$discussionId = array_get($request->getQueryParams(), 'id');
|
$discussionId = Arr::get($request->getQueryParams(), 'id');
|
||||||
$actor = $request->getAttribute('actor');
|
$actor = $request->getAttribute('actor');
|
||||||
$include = $this->extractInclude($request);
|
$include = $this->extractInclude($request);
|
||||||
|
|
||||||
@@ -86,7 +88,7 @@ class ShowDiscussionController extends AbstractShowController
|
|||||||
}
|
}
|
||||||
|
|
||||||
$discussion->load(array_filter($include, function ($relationship) {
|
$discussion->load(array_filter($include, function ($relationship) {
|
||||||
return ! starts_with($relationship, 'posts');
|
return ! Str::startsWith($relationship, 'posts');
|
||||||
}));
|
}));
|
||||||
|
|
||||||
return $discussion;
|
return $discussion;
|
||||||
@@ -150,7 +152,7 @@ class ShowDiscussionController extends AbstractShowController
|
|||||||
$queryParams = $request->getQueryParams();
|
$queryParams = $request->getQueryParams();
|
||||||
$actor = $request->getAttribute('actor');
|
$actor = $request->getAttribute('actor');
|
||||||
|
|
||||||
if (($near = array_get($queryParams, 'page.near')) > 1) {
|
if (($near = Arr::get($queryParams, 'page.near')) > 1) {
|
||||||
$offset = $this->posts->getIndexForNumber($discussion->id, $near, $actor);
|
$offset = $this->posts->getIndexForNumber($discussion->id, $near, $actor);
|
||||||
$offset = max(0, $offset - $limit / 2);
|
$offset = max(0, $offset - $limit / 2);
|
||||||
} else {
|
} else {
|
||||||
|
@@ -13,6 +13,7 @@ namespace Flarum\Api\Controller;
|
|||||||
|
|
||||||
use Flarum\Api\Serializer\PostSerializer;
|
use Flarum\Api\Serializer\PostSerializer;
|
||||||
use Flarum\Post\PostRepository;
|
use Flarum\Post\PostRepository;
|
||||||
|
use Illuminate\Support\Arr;
|
||||||
use Psr\Http\Message\ServerRequestInterface;
|
use Psr\Http\Message\ServerRequestInterface;
|
||||||
use Tobscure\JsonApi\Document;
|
use Tobscure\JsonApi\Document;
|
||||||
|
|
||||||
@@ -52,6 +53,6 @@ class ShowPostController extends AbstractShowController
|
|||||||
*/
|
*/
|
||||||
protected function data(ServerRequestInterface $request, Document $document)
|
protected function data(ServerRequestInterface $request, Document $document)
|
||||||
{
|
{
|
||||||
return $this->posts->findOrFail(array_get($request->getQueryParams(), 'id'), $request->getAttribute('actor'));
|
return $this->posts->findOrFail(Arr::get($request->getQueryParams(), 'id'), $request->getAttribute('actor'));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -14,6 +14,7 @@ namespace Flarum\Api\Controller;
|
|||||||
use Flarum\Api\Serializer\CurrentUserSerializer;
|
use Flarum\Api\Serializer\CurrentUserSerializer;
|
||||||
use Flarum\Api\Serializer\UserSerializer;
|
use Flarum\Api\Serializer\UserSerializer;
|
||||||
use Flarum\User\UserRepository;
|
use Flarum\User\UserRepository;
|
||||||
|
use Illuminate\Support\Arr;
|
||||||
use Psr\Http\Message\ServerRequestInterface;
|
use Psr\Http\Message\ServerRequestInterface;
|
||||||
use Tobscure\JsonApi\Document;
|
use Tobscure\JsonApi\Document;
|
||||||
|
|
||||||
@@ -47,7 +48,7 @@ class ShowUserController extends AbstractShowController
|
|||||||
*/
|
*/
|
||||||
protected function data(ServerRequestInterface $request, Document $document)
|
protected function data(ServerRequestInterface $request, Document $document)
|
||||||
{
|
{
|
||||||
$id = array_get($request->getQueryParams(), 'id');
|
$id = Arr::get($request->getQueryParams(), 'id');
|
||||||
|
|
||||||
if (! is_numeric($id)) {
|
if (! is_numeric($id)) {
|
||||||
$id = $this->users->getIdForUsername($id);
|
$id = $this->users->getIdForUsername($id);
|
||||||
|
@@ -13,6 +13,7 @@ namespace Flarum\Api\Controller;
|
|||||||
|
|
||||||
use Flarum\Extension\ExtensionManager;
|
use Flarum\Extension\ExtensionManager;
|
||||||
use Flarum\User\AssertPermissionTrait;
|
use Flarum\User\AssertPermissionTrait;
|
||||||
|
use Illuminate\Support\Arr;
|
||||||
use Psr\Http\Message\ServerRequestInterface;
|
use Psr\Http\Message\ServerRequestInterface;
|
||||||
|
|
||||||
class UninstallExtensionController extends AbstractDeleteController
|
class UninstallExtensionController extends AbstractDeleteController
|
||||||
@@ -36,7 +37,7 @@ class UninstallExtensionController extends AbstractDeleteController
|
|||||||
{
|
{
|
||||||
$this->assertAdmin($request->getAttribute('actor'));
|
$this->assertAdmin($request->getAttribute('actor'));
|
||||||
|
|
||||||
$name = array_get($request->getQueryParams(), 'name');
|
$name = Arr::get($request->getQueryParams(), 'name');
|
||||||
|
|
||||||
if ($this->extensions->getExtension($name) == null) {
|
if ($this->extensions->getExtension($name) == null) {
|
||||||
return;
|
return;
|
||||||
|
@@ -16,6 +16,7 @@ use Flarum\Discussion\Command\EditDiscussion;
|
|||||||
use Flarum\Discussion\Command\ReadDiscussion;
|
use Flarum\Discussion\Command\ReadDiscussion;
|
||||||
use Illuminate\Contracts\Bus\Dispatcher;
|
use Illuminate\Contracts\Bus\Dispatcher;
|
||||||
use Illuminate\Database\Eloquent\Collection;
|
use Illuminate\Database\Eloquent\Collection;
|
||||||
|
use Illuminate\Support\Arr;
|
||||||
use Psr\Http\Message\ServerRequestInterface;
|
use Psr\Http\Message\ServerRequestInterface;
|
||||||
use Tobscure\JsonApi\Document;
|
use Tobscure\JsonApi\Document;
|
||||||
|
|
||||||
@@ -45,8 +46,8 @@ class UpdateDiscussionController extends AbstractShowController
|
|||||||
protected function data(ServerRequestInterface $request, Document $document)
|
protected function data(ServerRequestInterface $request, Document $document)
|
||||||
{
|
{
|
||||||
$actor = $request->getAttribute('actor');
|
$actor = $request->getAttribute('actor');
|
||||||
$discussionId = array_get($request->getQueryParams(), 'id');
|
$discussionId = Arr::get($request->getQueryParams(), 'id');
|
||||||
$data = array_get($request->getParsedBody(), 'data', []);
|
$data = Arr::get($request->getParsedBody(), 'data', []);
|
||||||
|
|
||||||
$discussion = $this->bus->dispatch(
|
$discussion = $this->bus->dispatch(
|
||||||
new EditDiscussion($discussionId, $actor, $data)
|
new EditDiscussion($discussionId, $actor, $data)
|
||||||
@@ -54,7 +55,7 @@ class UpdateDiscussionController extends AbstractShowController
|
|||||||
|
|
||||||
// TODO: Refactor the ReadDiscussion (state) command into EditDiscussion?
|
// TODO: Refactor the ReadDiscussion (state) command into EditDiscussion?
|
||||||
// That's what extensions will do anyway.
|
// That's what extensions will do anyway.
|
||||||
if ($readNumber = array_get($data, 'attributes.lastReadPostNumber')) {
|
if ($readNumber = Arr::get($data, 'attributes.lastReadPostNumber')) {
|
||||||
$state = $this->bus->dispatch(
|
$state = $this->bus->dispatch(
|
||||||
new ReadDiscussion($discussionId, $actor, $readNumber)
|
new ReadDiscussion($discussionId, $actor, $readNumber)
|
||||||
);
|
);
|
||||||
|
@@ -13,6 +13,7 @@ namespace Flarum\Api\Controller;
|
|||||||
|
|
||||||
use Flarum\Extension\ExtensionManager;
|
use Flarum\Extension\ExtensionManager;
|
||||||
use Flarum\User\AssertPermissionTrait;
|
use Flarum\User\AssertPermissionTrait;
|
||||||
|
use Illuminate\Support\Arr;
|
||||||
use Psr\Http\Message\ResponseInterface;
|
use Psr\Http\Message\ResponseInterface;
|
||||||
use Psr\Http\Message\ServerRequestInterface;
|
use Psr\Http\Message\ServerRequestInterface;
|
||||||
use Psr\Http\Server\RequestHandlerInterface;
|
use Psr\Http\Server\RequestHandlerInterface;
|
||||||
@@ -42,8 +43,8 @@ class UpdateExtensionController implements RequestHandlerInterface
|
|||||||
{
|
{
|
||||||
$this->assertAdmin($request->getAttribute('actor'));
|
$this->assertAdmin($request->getAttribute('actor'));
|
||||||
|
|
||||||
$enabled = array_get($request->getParsedBody(), 'enabled');
|
$enabled = Arr::get($request->getParsedBody(), 'enabled');
|
||||||
$name = array_get($request->getQueryParams(), 'name');
|
$name = Arr::get($request->getQueryParams(), 'name');
|
||||||
|
|
||||||
if ($enabled === true) {
|
if ($enabled === true) {
|
||||||
$this->extensions->enable($name);
|
$this->extensions->enable($name);
|
||||||
|
@@ -14,6 +14,7 @@ namespace Flarum\Api\Controller;
|
|||||||
use Flarum\Api\Serializer\GroupSerializer;
|
use Flarum\Api\Serializer\GroupSerializer;
|
||||||
use Flarum\Group\Command\EditGroup;
|
use Flarum\Group\Command\EditGroup;
|
||||||
use Illuminate\Contracts\Bus\Dispatcher;
|
use Illuminate\Contracts\Bus\Dispatcher;
|
||||||
|
use Illuminate\Support\Arr;
|
||||||
use Psr\Http\Message\ServerRequestInterface;
|
use Psr\Http\Message\ServerRequestInterface;
|
||||||
use Tobscure\JsonApi\Document;
|
use Tobscure\JsonApi\Document;
|
||||||
|
|
||||||
@@ -42,9 +43,9 @@ class UpdateGroupController extends AbstractShowController
|
|||||||
*/
|
*/
|
||||||
protected function data(ServerRequestInterface $request, Document $document)
|
protected function data(ServerRequestInterface $request, Document $document)
|
||||||
{
|
{
|
||||||
$id = array_get($request->getQueryParams(), 'id');
|
$id = Arr::get($request->getQueryParams(), 'id');
|
||||||
$actor = $request->getAttribute('actor');
|
$actor = $request->getAttribute('actor');
|
||||||
$data = array_get($request->getParsedBody(), 'data', []);
|
$data = Arr::get($request->getParsedBody(), 'data', []);
|
||||||
|
|
||||||
return $this->bus->dispatch(
|
return $this->bus->dispatch(
|
||||||
new EditGroup($id, $actor, $data)
|
new EditGroup($id, $actor, $data)
|
||||||
|
@@ -14,6 +14,7 @@ namespace Flarum\Api\Controller;
|
|||||||
use Flarum\Api\Serializer\NotificationSerializer;
|
use Flarum\Api\Serializer\NotificationSerializer;
|
||||||
use Flarum\Notification\Command\ReadNotification;
|
use Flarum\Notification\Command\ReadNotification;
|
||||||
use Illuminate\Contracts\Bus\Dispatcher;
|
use Illuminate\Contracts\Bus\Dispatcher;
|
||||||
|
use Illuminate\Support\Arr;
|
||||||
use Psr\Http\Message\ServerRequestInterface;
|
use Psr\Http\Message\ServerRequestInterface;
|
||||||
use Tobscure\JsonApi\Document;
|
use Tobscure\JsonApi\Document;
|
||||||
|
|
||||||
@@ -42,7 +43,7 @@ class UpdateNotificationController extends AbstractShowController
|
|||||||
*/
|
*/
|
||||||
protected function data(ServerRequestInterface $request, Document $document)
|
protected function data(ServerRequestInterface $request, Document $document)
|
||||||
{
|
{
|
||||||
$id = array_get($request->getQueryParams(), 'id');
|
$id = Arr::get($request->getQueryParams(), 'id');
|
||||||
$actor = $request->getAttribute('actor');
|
$actor = $request->getAttribute('actor');
|
||||||
|
|
||||||
return $this->bus->dispatch(
|
return $this->bus->dispatch(
|
||||||
|
@@ -14,6 +14,7 @@ namespace Flarum\Api\Controller;
|
|||||||
use Flarum\Api\Serializer\PostSerializer;
|
use Flarum\Api\Serializer\PostSerializer;
|
||||||
use Flarum\Post\Command\EditPost;
|
use Flarum\Post\Command\EditPost;
|
||||||
use Illuminate\Contracts\Bus\Dispatcher;
|
use Illuminate\Contracts\Bus\Dispatcher;
|
||||||
|
use Illuminate\Support\Arr;
|
||||||
use Psr\Http\Message\ServerRequestInterface;
|
use Psr\Http\Message\ServerRequestInterface;
|
||||||
use Tobscure\JsonApi\Document;
|
use Tobscure\JsonApi\Document;
|
||||||
|
|
||||||
@@ -50,9 +51,9 @@ class UpdatePostController extends AbstractShowController
|
|||||||
*/
|
*/
|
||||||
protected function data(ServerRequestInterface $request, Document $document)
|
protected function data(ServerRequestInterface $request, Document $document)
|
||||||
{
|
{
|
||||||
$id = array_get($request->getQueryParams(), 'id');
|
$id = Arr::get($request->getQueryParams(), 'id');
|
||||||
$actor = $request->getAttribute('actor');
|
$actor = $request->getAttribute('actor');
|
||||||
$data = array_get($request->getParsedBody(), 'data', []);
|
$data = Arr::get($request->getParsedBody(), 'data', []);
|
||||||
|
|
||||||
return $this->bus->dispatch(
|
return $this->bus->dispatch(
|
||||||
new EditPost($id, $actor, $data)
|
new EditPost($id, $actor, $data)
|
||||||
|
@@ -16,6 +16,7 @@ use Flarum\Api\Serializer\UserSerializer;
|
|||||||
use Flarum\User\Command\EditUser;
|
use Flarum\User\Command\EditUser;
|
||||||
use Flarum\User\Exception\PermissionDeniedException;
|
use Flarum\User\Exception\PermissionDeniedException;
|
||||||
use Illuminate\Contracts\Bus\Dispatcher;
|
use Illuminate\Contracts\Bus\Dispatcher;
|
||||||
|
use Illuminate\Support\Arr;
|
||||||
use Psr\Http\Message\ServerRequestInterface;
|
use Psr\Http\Message\ServerRequestInterface;
|
||||||
use Tobscure\JsonApi\Document;
|
use Tobscure\JsonApi\Document;
|
||||||
|
|
||||||
@@ -49,9 +50,9 @@ class UpdateUserController extends AbstractShowController
|
|||||||
*/
|
*/
|
||||||
protected function data(ServerRequestInterface $request, Document $document)
|
protected function data(ServerRequestInterface $request, Document $document)
|
||||||
{
|
{
|
||||||
$id = array_get($request->getQueryParams(), 'id');
|
$id = Arr::get($request->getQueryParams(), 'id');
|
||||||
$actor = $request->getAttribute('actor');
|
$actor = $request->getAttribute('actor');
|
||||||
$data = array_get($request->getParsedBody(), 'data', []);
|
$data = Arr::get($request->getParsedBody(), 'data', []);
|
||||||
|
|
||||||
if ($actor->id == $id) {
|
if ($actor->id == $id) {
|
||||||
$this->serializer = CurrentUserSerializer::class;
|
$this->serializer = CurrentUserSerializer::class;
|
||||||
@@ -60,7 +61,7 @@ class UpdateUserController extends AbstractShowController
|
|||||||
// Require the user's current password if they are attempting to change
|
// Require the user's current password if they are attempting to change
|
||||||
// their own email address.
|
// their own email address.
|
||||||
if (isset($data['attributes']['email']) && $actor->id == $id) {
|
if (isset($data['attributes']['email']) && $actor->id == $id) {
|
||||||
$password = array_get($request->getParsedBody(), 'meta.password');
|
$password = Arr::get($request->getParsedBody(), 'meta.password');
|
||||||
|
|
||||||
if (! $actor->checkPassword($password)) {
|
if (! $actor->checkPassword($password)) {
|
||||||
throw new PermissionDeniedException;
|
throw new PermissionDeniedException;
|
||||||
|
@@ -14,6 +14,7 @@ namespace Flarum\Api\Controller;
|
|||||||
use Flarum\Api\Serializer\UserSerializer;
|
use Flarum\Api\Serializer\UserSerializer;
|
||||||
use Flarum\User\Command\UploadAvatar;
|
use Flarum\User\Command\UploadAvatar;
|
||||||
use Illuminate\Contracts\Bus\Dispatcher;
|
use Illuminate\Contracts\Bus\Dispatcher;
|
||||||
|
use Illuminate\Support\Arr;
|
||||||
use Psr\Http\Message\ServerRequestInterface;
|
use Psr\Http\Message\ServerRequestInterface;
|
||||||
use Tobscure\JsonApi\Document;
|
use Tobscure\JsonApi\Document;
|
||||||
|
|
||||||
@@ -42,9 +43,9 @@ class UploadAvatarController extends AbstractShowController
|
|||||||
*/
|
*/
|
||||||
protected function data(ServerRequestInterface $request, Document $document)
|
protected function data(ServerRequestInterface $request, Document $document)
|
||||||
{
|
{
|
||||||
$id = array_get($request->getQueryParams(), 'id');
|
$id = Arr::get($request->getQueryParams(), 'id');
|
||||||
$actor = $request->getAttribute('actor');
|
$actor = $request->getAttribute('actor');
|
||||||
$file = array_get($request->getUploadedFiles(), 'avatar');
|
$file = Arr::get($request->getUploadedFiles(), 'avatar');
|
||||||
|
|
||||||
return $this->bus->dispatch(
|
return $this->bus->dispatch(
|
||||||
new UploadAvatar($id, $file, $actor)
|
new UploadAvatar($id, $file, $actor)
|
||||||
|
@@ -14,6 +14,7 @@ namespace Flarum\Api\Controller;
|
|||||||
use Flarum\Foundation\Application;
|
use Flarum\Foundation\Application;
|
||||||
use Flarum\Settings\SettingsRepositoryInterface;
|
use Flarum\Settings\SettingsRepositoryInterface;
|
||||||
use Flarum\User\AssertPermissionTrait;
|
use Flarum\User\AssertPermissionTrait;
|
||||||
|
use Illuminate\Support\Arr;
|
||||||
use Illuminate\Support\Str;
|
use Illuminate\Support\Str;
|
||||||
use Intervention\Image\ImageManager;
|
use Intervention\Image\ImageManager;
|
||||||
use League\Flysystem\Adapter\Local;
|
use League\Flysystem\Adapter\Local;
|
||||||
@@ -52,7 +53,7 @@ class UploadFaviconController extends ShowForumController
|
|||||||
{
|
{
|
||||||
$this->assertAdmin($request->getAttribute('actor'));
|
$this->assertAdmin($request->getAttribute('actor'));
|
||||||
|
|
||||||
$file = array_get($request->getUploadedFiles(), 'favicon');
|
$file = Arr::get($request->getUploadedFiles(), 'favicon');
|
||||||
|
|
||||||
$tmpFile = tempnam($this->app->storagePath().'/tmp', 'favicon');
|
$tmpFile = tempnam($this->app->storagePath().'/tmp', 'favicon');
|
||||||
$file->moveTo($tmpFile);
|
$file->moveTo($tmpFile);
|
||||||
|
@@ -14,6 +14,7 @@ namespace Flarum\Api\Controller;
|
|||||||
use Flarum\Foundation\Application;
|
use Flarum\Foundation\Application;
|
||||||
use Flarum\Settings\SettingsRepositoryInterface;
|
use Flarum\Settings\SettingsRepositoryInterface;
|
||||||
use Flarum\User\AssertPermissionTrait;
|
use Flarum\User\AssertPermissionTrait;
|
||||||
|
use Illuminate\Support\Arr;
|
||||||
use Illuminate\Support\Str;
|
use Illuminate\Support\Str;
|
||||||
use Intervention\Image\ImageManager;
|
use Intervention\Image\ImageManager;
|
||||||
use League\Flysystem\Adapter\Local;
|
use League\Flysystem\Adapter\Local;
|
||||||
@@ -52,7 +53,7 @@ class UploadLogoController extends ShowForumController
|
|||||||
{
|
{
|
||||||
$this->assertAdmin($request->getAttribute('actor'));
|
$this->assertAdmin($request->getAttribute('actor'));
|
||||||
|
|
||||||
$file = array_get($request->getUploadedFiles(), 'logo');
|
$file = Arr::get($request->getUploadedFiles(), 'logo');
|
||||||
|
|
||||||
$tmpFile = tempnam($this->app->storagePath().'/tmp', 'logo');
|
$tmpFile = tempnam($this->app->storagePath().'/tmp', 'logo');
|
||||||
$file->moveTo($tmpFile);
|
$file->moveTo($tmpFile);
|
||||||
|
@@ -12,6 +12,7 @@
|
|||||||
namespace Flarum\Api\Event;
|
namespace Flarum\Api\Event;
|
||||||
|
|
||||||
use Flarum\Api\Controller\AbstractSerializeController;
|
use Flarum\Api\Controller\AbstractSerializeController;
|
||||||
|
use Illuminate\Support\Arr;
|
||||||
|
|
||||||
class WillGetData
|
class WillGetData
|
||||||
{
|
{
|
||||||
@@ -64,7 +65,7 @@ class WillGetData
|
|||||||
*/
|
*/
|
||||||
public function removeInclude($name)
|
public function removeInclude($name)
|
||||||
{
|
{
|
||||||
array_forget($this->controller->include, $name);
|
Arr::forget($this->controller->include, $name);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -84,7 +85,7 @@ class WillGetData
|
|||||||
*/
|
*/
|
||||||
public function removeOptionalInclude($name)
|
public function removeOptionalInclude($name)
|
||||||
{
|
{
|
||||||
array_forget($this->controller->optionalInclude, $name);
|
Arr::forget($this->controller->optionalInclude, $name);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -124,7 +125,7 @@ class WillGetData
|
|||||||
*/
|
*/
|
||||||
public function removeSortField($field)
|
public function removeSortField($field)
|
||||||
{
|
{
|
||||||
array_forget($this->controller->sortFields, $field);
|
Arr::forget($this->controller->sortFields, $field);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -37,7 +37,6 @@ class BasicPostSerializer extends AbstractSerializer
|
|||||||
}
|
}
|
||||||
|
|
||||||
$attributes = [
|
$attributes = [
|
||||||
'id' => (int) $post->id,
|
|
||||||
'number' => (int) $post->number,
|
'number' => (int) $post->number,
|
||||||
'createdAt' => $this->formatDate($post->created_at),
|
'createdAt' => $this->formatDate($post->created_at),
|
||||||
'contentType' => $post->type
|
'contentType' => $post->type
|
||||||
|
49
src/Api/Serializer/MailDriverSerializer.php
Normal file
49
src/Api/Serializer/MailDriverSerializer.php
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of Flarum.
|
||||||
|
*
|
||||||
|
* (c) Toby Zerner <toby.zerner@gmail.com>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Flarum\Api\Serializer;
|
||||||
|
|
||||||
|
use Flarum\Mail\DriverInterface;
|
||||||
|
use InvalidArgumentException;
|
||||||
|
|
||||||
|
class MailDriverSerializer extends AbstractSerializer
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
protected $type = 'mail-drivers';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*
|
||||||
|
* @param \Flarum\Mail\DriverInterface $driver
|
||||||
|
* @throws InvalidArgumentException
|
||||||
|
*/
|
||||||
|
protected function getDefaultAttributes($driver)
|
||||||
|
{
|
||||||
|
if (! ($driver['driver'] instanceof DriverInterface)) {
|
||||||
|
throw new InvalidArgumentException(
|
||||||
|
get_class($this).' can only serialize instances of '.DriverInterface::class
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
$driver = $driver['driver'];
|
||||||
|
|
||||||
|
return [
|
||||||
|
'fields' => $driver->availableSettings(),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getId($model)
|
||||||
|
{
|
||||||
|
return $model['id'];
|
||||||
|
}
|
||||||
|
}
|
@@ -44,7 +44,6 @@ class NotificationSerializer extends AbstractSerializer
|
|||||||
}
|
}
|
||||||
|
|
||||||
return [
|
return [
|
||||||
'id' => (int) $notification->id,
|
|
||||||
'contentType' => $notification->type,
|
'contentType' => $notification->type,
|
||||||
'content' => $notification->data,
|
'content' => $notification->data,
|
||||||
'createdAt' => $this->formatDate($notification->created_at),
|
'createdAt' => $this->formatDate($notification->created_at),
|
||||||
|
@@ -308,4 +308,11 @@ return function (RouteCollection $map, RouteHandlerFactory $route) {
|
|||||||
'cache.clear',
|
'cache.clear',
|
||||||
$route->toController(Controller\ClearCacheController::class)
|
$route->toController(Controller\ClearCacheController::class)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// List available mail drivers and their configuration fields
|
||||||
|
$map->get(
|
||||||
|
'/mail-drivers',
|
||||||
|
'mailDrivers.index',
|
||||||
|
$route->toController(Controller\ListMailDriversController::class)
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
@@ -55,13 +55,13 @@ abstract class AbstractModel extends Eloquent
|
|||||||
{
|
{
|
||||||
parent::boot();
|
parent::boot();
|
||||||
|
|
||||||
static::saved(function (AbstractModel $model) {
|
static::saved(function (self $model) {
|
||||||
foreach ($model->releaseAfterSaveCallbacks() as $callback) {
|
foreach ($model->releaseAfterSaveCallbacks() as $callback) {
|
||||||
$callback($model);
|
$callback($model);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
static::deleted(function (AbstractModel $model) {
|
static::deleted(function (self $model) {
|
||||||
foreach ($model->releaseAfterDeleteCallbacks() as $callback) {
|
foreach ($model->releaseAfterDeleteCallbacks() as $callback) {
|
||||||
$callback($model);
|
$callback($model);
|
||||||
}
|
}
|
||||||
|
@@ -12,21 +12,26 @@
|
|||||||
namespace Flarum\Database\Console;
|
namespace Flarum\Database\Console;
|
||||||
|
|
||||||
use Flarum\Console\AbstractCommand;
|
use Flarum\Console\AbstractCommand;
|
||||||
use Illuminate\Contracts\Container\Container;
|
use Flarum\Database\Migrator;
|
||||||
|
use Flarum\Extension\ExtensionManager;
|
||||||
|
use Flarum\Foundation\Application;
|
||||||
|
use Flarum\Settings\SettingsRepositoryInterface;
|
||||||
|
use Illuminate\Database\ConnectionInterface;
|
||||||
|
use Illuminate\Database\Schema\Builder;
|
||||||
|
|
||||||
class MigrateCommand extends AbstractCommand
|
class MigrateCommand extends AbstractCommand
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* @var Container
|
* @var Application
|
||||||
*/
|
*/
|
||||||
protected $container;
|
protected $app;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param Container $container
|
* @param Application $application
|
||||||
*/
|
*/
|
||||||
public function __construct(Container $container)
|
public function __construct(Application $application)
|
||||||
{
|
{
|
||||||
$this->container = $container;
|
$this->app = $application;
|
||||||
|
|
||||||
parent::__construct();
|
parent::__construct();
|
||||||
}
|
}
|
||||||
@@ -55,16 +60,16 @@ class MigrateCommand extends AbstractCommand
|
|||||||
|
|
||||||
public function upgrade()
|
public function upgrade()
|
||||||
{
|
{
|
||||||
$this->container->bind('Illuminate\Database\Schema\Builder', function ($container) {
|
$this->app->bind(Builder::class, function ($app) {
|
||||||
return $container->make('Illuminate\Database\ConnectionInterface')->getSchemaBuilder();
|
return $app->make(ConnectionInterface::class)->getSchemaBuilder();
|
||||||
});
|
});
|
||||||
|
|
||||||
$migrator = $this->container->make('Flarum\Database\Migrator');
|
$migrator = $this->app->make(Migrator::class);
|
||||||
$migrator->setOutput($this->output);
|
$migrator->setOutput($this->output);
|
||||||
|
|
||||||
$migrator->run(__DIR__.'/../../../migrations');
|
$migrator->run(__DIR__.'/../../../migrations');
|
||||||
|
|
||||||
$extensions = $this->container->make('Flarum\Extension\ExtensionManager');
|
$extensions = $this->app->make(ExtensionManager::class);
|
||||||
$extensions->getMigrator()->setOutput($this->output);
|
$extensions->getMigrator()->setOutput($this->output);
|
||||||
|
|
||||||
foreach ($extensions->getEnabledExtensions() as $name => $extension) {
|
foreach ($extensions->getEnabledExtensions() as $name => $extension) {
|
||||||
@@ -75,13 +80,13 @@ class MigrateCommand extends AbstractCommand
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->container->make('Flarum\Settings\SettingsRepositoryInterface')->set('version', $this->container->version());
|
$this->app->make(SettingsRepositoryInterface::class)->set('version', $this->app->version());
|
||||||
|
|
||||||
$this->info('Publishing assets...');
|
$this->info('Publishing assets...');
|
||||||
|
|
||||||
$this->container->make('files')->copyDirectory(
|
$this->app->make('files')->copyDirectory(
|
||||||
base_path().'/vendor/components/font-awesome/webfonts',
|
$this->app->vendorPath().'/components/font-awesome/webfonts',
|
||||||
public_path().'/assets/fonts'
|
$this->app->publicPath().'/assets/fonts'
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -17,6 +17,7 @@ use Flarum\Discussion\Event\Saving;
|
|||||||
use Flarum\Foundation\DispatchEventsTrait;
|
use Flarum\Foundation\DispatchEventsTrait;
|
||||||
use Flarum\User\AssertPermissionTrait;
|
use Flarum\User\AssertPermissionTrait;
|
||||||
use Illuminate\Contracts\Events\Dispatcher;
|
use Illuminate\Contracts\Events\Dispatcher;
|
||||||
|
use Illuminate\Support\Arr;
|
||||||
|
|
||||||
class EditDiscussionHandler
|
class EditDiscussionHandler
|
||||||
{
|
{
|
||||||
@@ -54,7 +55,7 @@ class EditDiscussionHandler
|
|||||||
{
|
{
|
||||||
$actor = $command->actor;
|
$actor = $command->actor;
|
||||||
$data = $command->data;
|
$data = $command->data;
|
||||||
$attributes = array_get($data, 'attributes', []);
|
$attributes = Arr::get($data, 'attributes', []);
|
||||||
|
|
||||||
$discussion = $this->discussions->findOrFail($command->discussionId, $actor);
|
$discussion = $this->discussions->findOrFail($command->discussionId, $actor);
|
||||||
|
|
||||||
|
@@ -20,6 +20,7 @@ use Flarum\Post\Command\PostReply;
|
|||||||
use Flarum\User\AssertPermissionTrait;
|
use Flarum\User\AssertPermissionTrait;
|
||||||
use Illuminate\Contracts\Bus\Dispatcher as BusDispatcher;
|
use Illuminate\Contracts\Bus\Dispatcher as BusDispatcher;
|
||||||
use Illuminate\Contracts\Events\Dispatcher as EventDispatcher;
|
use Illuminate\Contracts\Events\Dispatcher as EventDispatcher;
|
||||||
|
use Illuminate\Support\Arr;
|
||||||
|
|
||||||
class StartDiscussionHandler
|
class StartDiscussionHandler
|
||||||
{
|
{
|
||||||
@@ -66,7 +67,7 @@ class StartDiscussionHandler
|
|||||||
// an opportunity to alter the discussion entity based on data in the
|
// an opportunity to alter the discussion entity based on data in the
|
||||||
// command they may have passed through in the controller.
|
// command they may have passed through in the controller.
|
||||||
$discussion = Discussion::start(
|
$discussion = Discussion::start(
|
||||||
array_get($data, 'attributes.title'),
|
Arr::get($data, 'attributes.title'),
|
||||||
$actor
|
$actor
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@@ -98,7 +98,7 @@ class Discussion extends AbstractModel
|
|||||||
{
|
{
|
||||||
parent::boot();
|
parent::boot();
|
||||||
|
|
||||||
static::deleting(function (Discussion $discussion) {
|
static::deleting(function (self $discussion) {
|
||||||
Notification::whereSubjectModel(Post::class)
|
Notification::whereSubjectModel(Post::class)
|
||||||
->whereIn('subject_id', function ($query) use ($discussion) {
|
->whereIn('subject_id', function ($query) use ($discussion) {
|
||||||
$query->select('id')->from('posts')->where('discussion_id', $discussion->id);
|
$query->select('id')->from('posts')->where('discussion_id', $discussion->id);
|
||||||
@@ -106,13 +106,13 @@ class Discussion extends AbstractModel
|
|||||||
->delete();
|
->delete();
|
||||||
});
|
});
|
||||||
|
|
||||||
static::deleted(function (Discussion $discussion) {
|
static::deleted(function (self $discussion) {
|
||||||
$discussion->raise(new Deleted($discussion));
|
$discussion->raise(new Deleted($discussion));
|
||||||
|
|
||||||
Notification::whereSubject($discussion)->delete();
|
Notification::whereSubject($discussion)->delete();
|
||||||
});
|
});
|
||||||
|
|
||||||
static::saving(function (Discussion $discussion) {
|
static::saving(function (self $discussion) {
|
||||||
$event = new GetModelIsPrivate($discussion);
|
$event = new GetModelIsPrivate($discussion);
|
||||||
|
|
||||||
$discussion->is_private = static::$dispatcher->until($event) === true;
|
$discussion->is_private = static::$dispatcher->until($event) === true;
|
||||||
|
@@ -49,8 +49,8 @@ class DiscussionRepository
|
|||||||
*/
|
*/
|
||||||
public function getReadIds(User $user)
|
public function getReadIds(User $user)
|
||||||
{
|
{
|
||||||
return Discussion::leftJoin('discussions_users', 'discussions_users.discussion_id', '=', 'discussions.id')
|
return Discussion::leftJoin('discussion_user', 'discussion_user.discussion_id', '=', 'discussions.id')
|
||||||
->where('user_id', $user->id)
|
->where('discussion_user.user_id', $user->id)
|
||||||
->whereColumn('last_read_post_number', '>=', 'last_post_number')
|
->whereColumn('last_read_post_number', '>=', 'last_post_number')
|
||||||
->pluck('id')
|
->pluck('id')
|
||||||
->all();
|
->all();
|
||||||
|
@@ -13,6 +13,7 @@ namespace Flarum\Event;
|
|||||||
|
|
||||||
use DirectoryIterator;
|
use DirectoryIterator;
|
||||||
use Flarum\Locale\LocaleManager;
|
use Flarum\Locale\LocaleManager;
|
||||||
|
use Illuminate\Support\Arr;
|
||||||
use RuntimeException;
|
use RuntimeException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -49,8 +50,8 @@ class ConfigureLocales
|
|||||||
throw new RuntimeException("Error parsing composer.json in $name: ".json_last_error_msg());
|
throw new RuntimeException("Error parsing composer.json in $name: ".json_last_error_msg());
|
||||||
}
|
}
|
||||||
|
|
||||||
$locale = array_get($json, 'extra.flarum-locale.code');
|
$locale = Arr::get($json, 'extra.flarum-locale.code');
|
||||||
$title = array_get($json, 'extra.flarum-locale.title', $title);
|
$title = Arr::get($json, 'extra.flarum-locale.title', $title);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (! isset($locale)) {
|
if (! isset($locale)) {
|
||||||
|
@@ -14,6 +14,7 @@ namespace Flarum\Extension;
|
|||||||
use Flarum\Extension\Event\Disabling;
|
use Flarum\Extension\Event\Disabling;
|
||||||
use Flarum\Http\Exception\ForbiddenException;
|
use Flarum\Http\Exception\ForbiddenException;
|
||||||
use Flarum\Settings\SettingsRepositoryInterface;
|
use Flarum\Settings\SettingsRepositoryInterface;
|
||||||
|
use Illuminate\Support\Arr;
|
||||||
|
|
||||||
class DefaultLanguagePackGuard
|
class DefaultLanguagePackGuard
|
||||||
{
|
{
|
||||||
@@ -34,7 +35,7 @@ class DefaultLanguagePackGuard
|
|||||||
}
|
}
|
||||||
|
|
||||||
$defaultLocale = $this->settings->get('default_locale');
|
$defaultLocale = $this->settings->get('default_locale');
|
||||||
$locale = array_get($event->extension->extra, 'flarum-locale.code');
|
$locale = Arr::get($event->extension->extra, 'flarum-locale.code');
|
||||||
|
|
||||||
if ($locale === $defaultLocale) {
|
if ($locale === $defaultLocale) {
|
||||||
throw new ForbiddenException('You cannot disable the default language pack!');
|
throw new ForbiddenException('You cannot disable the default language pack!');
|
||||||
|
@@ -257,9 +257,9 @@ class Extension implements Arrayable
|
|||||||
|
|
||||||
private function getExtenders(): array
|
private function getExtenders(): array
|
||||||
{
|
{
|
||||||
$extenderFile = $this->getExtenderFile();
|
$extenderFile = "{$this->path}/extend.php";
|
||||||
|
|
||||||
if (! $extenderFile) {
|
if (! file_exists($extenderFile)) {
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -285,24 +285,6 @@ class Extension implements Arrayable
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
private function getExtenderFile(): ?string
|
|
||||||
{
|
|
||||||
$filename = "{$this->path}/extend.php";
|
|
||||||
|
|
||||||
if (file_exists($filename)) {
|
|
||||||
return $filename;
|
|
||||||
}
|
|
||||||
|
|
||||||
// To give extension authors some time to migrate to the new extension
|
|
||||||
// format, we will also fallback to the old bootstrap.php name. Consider
|
|
||||||
// this feature deprecated.
|
|
||||||
$deprecatedFilename = "{$this->path}/bootstrap.php";
|
|
||||||
|
|
||||||
if (file_exists($deprecatedFilename)) {
|
|
||||||
return $deprecatedFilename;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests whether the extension has assets.
|
* Tests whether the extension has assets.
|
||||||
*
|
*
|
||||||
|
@@ -21,6 +21,8 @@ use Flarum\Foundation\Application;
|
|||||||
use Flarum\Settings\SettingsRepositoryInterface;
|
use Flarum\Settings\SettingsRepositoryInterface;
|
||||||
use Illuminate\Contracts\Container\Container;
|
use Illuminate\Contracts\Container\Container;
|
||||||
use Illuminate\Contracts\Events\Dispatcher;
|
use Illuminate\Contracts\Events\Dispatcher;
|
||||||
|
use Illuminate\Database\ConnectionInterface;
|
||||||
|
use Illuminate\Database\Schema\Builder;
|
||||||
use Illuminate\Filesystem\Filesystem;
|
use Illuminate\Filesystem\Filesystem;
|
||||||
use Illuminate\Support\Arr;
|
use Illuminate\Support\Arr;
|
||||||
use Illuminate\Support\Collection;
|
use Illuminate\Support\Collection;
|
||||||
@@ -67,11 +69,11 @@ class ExtensionManager
|
|||||||
*/
|
*/
|
||||||
public function getExtensions()
|
public function getExtensions()
|
||||||
{
|
{
|
||||||
if (is_null($this->extensions) && $this->filesystem->exists($this->app->basePath().'/vendor/composer/installed.json')) {
|
if (is_null($this->extensions) && $this->filesystem->exists($this->app->vendorPath().'/composer/installed.json')) {
|
||||||
$extensions = new Collection();
|
$extensions = new Collection();
|
||||||
|
|
||||||
// Load all packages installed by composer.
|
// Load all packages installed by composer.
|
||||||
$installed = json_decode($this->filesystem->get($this->app->basePath().'/vendor/composer/installed.json'), true);
|
$installed = json_decode($this->filesystem->get($this->app->vendorPath().'/composer/installed.json'), true);
|
||||||
|
|
||||||
foreach ($installed as $package) {
|
foreach ($installed as $package) {
|
||||||
if (Arr::get($package, 'type') != 'flarum-extension' || empty(Arr::get($package, 'name'))) {
|
if (Arr::get($package, 'type') != 'flarum-extension' || empty(Arr::get($package, 'name'))) {
|
||||||
@@ -227,8 +229,8 @@ class ExtensionManager
|
|||||||
*/
|
*/
|
||||||
public function migrate(Extension $extension, $direction = 'up')
|
public function migrate(Extension $extension, $direction = 'up')
|
||||||
{
|
{
|
||||||
$this->app->bind('Illuminate\Database\Schema\Builder', function ($container) {
|
$this->app->bind(Builder::class, function ($container) {
|
||||||
return $container->make('Illuminate\Database\ConnectionInterface')->getSchemaBuilder();
|
return $container->make(ConnectionInterface::class)->getSchemaBuilder();
|
||||||
});
|
});
|
||||||
|
|
||||||
$extension->migrate($this->migrator, $direction);
|
$extension->migrate($this->migrator, $direction);
|
||||||
@@ -293,7 +295,7 @@ class ExtensionManager
|
|||||||
*/
|
*/
|
||||||
public function getEnabled()
|
public function getEnabled()
|
||||||
{
|
{
|
||||||
return json_decode($this->config->get('extensions_enabled'), true);
|
return json_decode($this->config->get('extensions_enabled'), true) ?? [];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -326,6 +328,6 @@ class ExtensionManager
|
|||||||
*/
|
*/
|
||||||
protected function getExtensionsDir()
|
protected function getExtensionsDir()
|
||||||
{
|
{
|
||||||
return $this->app->basePath().'/vendor';
|
return $this->app->vendorPath();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -15,6 +15,7 @@ use Flarum\Http\Rememberer;
|
|||||||
use Flarum\User\LoginProvider;
|
use Flarum\User\LoginProvider;
|
||||||
use Flarum\User\RegistrationToken;
|
use Flarum\User\RegistrationToken;
|
||||||
use Flarum\User\User;
|
use Flarum\User\User;
|
||||||
|
use Illuminate\Support\Arr;
|
||||||
use Psr\Http\Message\ResponseInterface;
|
use Psr\Http\Message\ResponseInterface;
|
||||||
use Zend\Diactoros\Response\HtmlResponse;
|
use Zend\Diactoros\Response\HtmlResponse;
|
||||||
|
|
||||||
@@ -43,7 +44,7 @@ class ResponseFactory
|
|||||||
|
|
||||||
$provided = $registration->getProvided();
|
$provided = $registration->getProvided();
|
||||||
|
|
||||||
if (! empty($provided['email']) && $user = User::where(array_only($provided, 'email'))->first()) {
|
if (! empty($provided['email']) && $user = User::where(Arr::only($provided, 'email'))->first()) {
|
||||||
$user->loginProviders()->create(compact('provider', 'identifier'));
|
$user->loginProviders()->create(compact('provider', 'identifier'));
|
||||||
|
|
||||||
return $this->makeLoggedInResponse($user);
|
return $this->makeLoggedInResponse($user);
|
||||||
|
@@ -17,6 +17,7 @@ use Flarum\Http\Exception\RouteNotFoundException;
|
|||||||
use Flarum\Http\UrlGenerator;
|
use Flarum\Http\UrlGenerator;
|
||||||
use Flarum\User\User;
|
use Flarum\User\User;
|
||||||
use Illuminate\Contracts\View\Factory;
|
use Illuminate\Contracts\View\Factory;
|
||||||
|
use Illuminate\Support\Arr;
|
||||||
use Psr\Http\Message\ServerRequestInterface as Request;
|
use Psr\Http\Message\ServerRequestInterface as Request;
|
||||||
|
|
||||||
class Discussion
|
class Discussion
|
||||||
@@ -51,12 +52,12 @@ class Discussion
|
|||||||
public function __invoke(Document $document, Request $request)
|
public function __invoke(Document $document, Request $request)
|
||||||
{
|
{
|
||||||
$queryParams = $request->getQueryParams();
|
$queryParams = $request->getQueryParams();
|
||||||
$page = max(1, array_get($queryParams, 'page'));
|
$page = max(1, Arr::get($queryParams, 'page'));
|
||||||
|
|
||||||
$params = [
|
$params = [
|
||||||
'id' => (int) array_get($queryParams, 'id'),
|
'id' => (int) Arr::get($queryParams, 'id'),
|
||||||
'page' => [
|
'page' => [
|
||||||
'near' => array_get($queryParams, 'near'),
|
'near' => Arr::get($queryParams, 'near'),
|
||||||
'offset' => ($page - 1) * 20,
|
'offset' => ($page - 1) * 20,
|
||||||
'limit' => 20
|
'limit' => 20
|
||||||
]
|
]
|
||||||
@@ -65,7 +66,7 @@ class Discussion
|
|||||||
$apiDocument = $this->getApiDocument($request->getAttribute('actor'), $params);
|
$apiDocument = $this->getApiDocument($request->getAttribute('actor'), $params);
|
||||||
|
|
||||||
$getResource = function ($link) use ($apiDocument) {
|
$getResource = function ($link) use ($apiDocument) {
|
||||||
return array_first($apiDocument->included, function ($value) use ($link) {
|
return Arr::first($apiDocument->included, function ($value) use ($link) {
|
||||||
return $value->type === $link->type && $value->id === $link->id;
|
return $value->type === $link->type && $value->id === $link->id;
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
@@ -16,6 +16,7 @@ use Flarum\Api\Controller\ListDiscussionsController;
|
|||||||
use Flarum\Frontend\Document;
|
use Flarum\Frontend\Document;
|
||||||
use Flarum\User\User;
|
use Flarum\User\User;
|
||||||
use Illuminate\Contracts\View\Factory;
|
use Illuminate\Contracts\View\Factory;
|
||||||
|
use Illuminate\Support\Arr;
|
||||||
use Psr\Http\Message\ServerRequestInterface as Request;
|
use Psr\Http\Message\ServerRequestInterface as Request;
|
||||||
|
|
||||||
class Index
|
class Index
|
||||||
@@ -44,9 +45,9 @@ class Index
|
|||||||
{
|
{
|
||||||
$queryParams = $request->getQueryParams();
|
$queryParams = $request->getQueryParams();
|
||||||
|
|
||||||
$sort = array_pull($queryParams, 'sort');
|
$sort = Arr::pull($queryParams, 'sort');
|
||||||
$q = array_pull($queryParams, 'q');
|
$q = Arr::pull($queryParams, 'q');
|
||||||
$page = array_pull($queryParams, 'page', 1);
|
$page = Arr::pull($queryParams, 'page', 1);
|
||||||
|
|
||||||
$sortMap = $this->getSortMap();
|
$sortMap = $this->getSortMap();
|
||||||
|
|
||||||
|
@@ -16,6 +16,7 @@ use Flarum\Http\SessionAuthenticator;
|
|||||||
use Flarum\User\Command\ConfirmEmail;
|
use Flarum\User\Command\ConfirmEmail;
|
||||||
use Flarum\User\Exception\InvalidConfirmationTokenException;
|
use Flarum\User\Exception\InvalidConfirmationTokenException;
|
||||||
use Illuminate\Contracts\Bus\Dispatcher;
|
use Illuminate\Contracts\Bus\Dispatcher;
|
||||||
|
use Illuminate\Support\Arr;
|
||||||
use Psr\Http\Message\ResponseInterface;
|
use Psr\Http\Message\ResponseInterface;
|
||||||
use Psr\Http\Message\ServerRequestInterface as Request;
|
use Psr\Http\Message\ServerRequestInterface as Request;
|
||||||
use Psr\Http\Server\RequestHandlerInterface;
|
use Psr\Http\Server\RequestHandlerInterface;
|
||||||
@@ -58,7 +59,7 @@ class ConfirmEmailController implements RequestHandlerInterface
|
|||||||
public function handle(Request $request): ResponseInterface
|
public function handle(Request $request): ResponseInterface
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
$token = array_get($request->getQueryParams(), 'token');
|
$token = Arr::get($request->getQueryParams(), 'token');
|
||||||
|
|
||||||
$user = $this->bus->dispatch(
|
$user = $this->bus->dispatch(
|
||||||
new ConfirmEmail($token)
|
new ConfirmEmail($token)
|
||||||
|
@@ -18,6 +18,7 @@ use Flarum\Http\Rememberer;
|
|||||||
use Flarum\Http\SessionAuthenticator;
|
use Flarum\Http\SessionAuthenticator;
|
||||||
use Flarum\User\Event\LoggedIn;
|
use Flarum\User\Event\LoggedIn;
|
||||||
use Flarum\User\UserRepository;
|
use Flarum\User\UserRepository;
|
||||||
|
use Illuminate\Support\Arr;
|
||||||
use Psr\Http\Message\ResponseInterface;
|
use Psr\Http\Message\ResponseInterface;
|
||||||
use Psr\Http\Message\ServerRequestInterface as Request;
|
use Psr\Http\Message\ServerRequestInterface as Request;
|
||||||
use Psr\Http\Server\RequestHandlerInterface;
|
use Psr\Http\Server\RequestHandlerInterface;
|
||||||
@@ -65,7 +66,7 @@ class LogInController implements RequestHandlerInterface
|
|||||||
{
|
{
|
||||||
$actor = $request->getAttribute('actor');
|
$actor = $request->getAttribute('actor');
|
||||||
$body = $request->getParsedBody();
|
$body = $request->getParsedBody();
|
||||||
$params = array_only($body, ['identification', 'password']);
|
$params = Arr::only($body, ['identification', 'password']);
|
||||||
|
|
||||||
$response = $this->apiClient->send(CreateTokenController::class, $actor, [], $params);
|
$response = $this->apiClient->send(CreateTokenController::class, $actor, [], $params);
|
||||||
|
|
||||||
@@ -79,7 +80,7 @@ class LogInController implements RequestHandlerInterface
|
|||||||
|
|
||||||
event(new LoggedIn($this->users->findOrFail($data->userId), $token));
|
event(new LoggedIn($this->users->findOrFail($data->userId), $token));
|
||||||
|
|
||||||
if (array_get($body, 'remember')) {
|
if (Arr::get($body, 'remember')) {
|
||||||
$response = $this->rememberer->remember($response, $token);
|
$response = $this->rememberer->remember($response, $token);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -20,6 +20,7 @@ use Flarum\User\AssertPermissionTrait;
|
|||||||
use Flarum\User\Event\LoggedOut;
|
use Flarum\User\Event\LoggedOut;
|
||||||
use Illuminate\Contracts\Events\Dispatcher;
|
use Illuminate\Contracts\Events\Dispatcher;
|
||||||
use Illuminate\Contracts\View\Factory;
|
use Illuminate\Contracts\View\Factory;
|
||||||
|
use Illuminate\Support\Arr;
|
||||||
use Psr\Http\Message\ResponseInterface;
|
use Psr\Http\Message\ResponseInterface;
|
||||||
use Psr\Http\Message\ServerRequestInterface as Request;
|
use Psr\Http\Message\ServerRequestInterface as Request;
|
||||||
use Psr\Http\Server\RequestHandlerInterface;
|
use Psr\Http\Server\RequestHandlerInterface;
|
||||||
@@ -94,7 +95,7 @@ class LogOutController implements RequestHandlerInterface
|
|||||||
$session = $request->getAttribute('session');
|
$session = $request->getAttribute('session');
|
||||||
$actor = $request->getAttribute('actor');
|
$actor = $request->getAttribute('actor');
|
||||||
|
|
||||||
$url = array_get($request->getQueryParams(), 'return', $this->app->url());
|
$url = Arr::get($request->getQueryParams(), 'return', $this->app->url());
|
||||||
|
|
||||||
// If there is no user logged in, return to the index.
|
// If there is no user logged in, return to the index.
|
||||||
if ($actor->isGuest()) {
|
if ($actor->isGuest()) {
|
||||||
@@ -105,8 +106,8 @@ class LogOutController implements RequestHandlerInterface
|
|||||||
// allow the user to press a button to complete the log out process.
|
// allow the user to press a button to complete the log out process.
|
||||||
$csrfToken = $session->token();
|
$csrfToken = $session->token();
|
||||||
|
|
||||||
if (array_get($request->getQueryParams(), 'token') !== $csrfToken) {
|
if (Arr::get($request->getQueryParams(), 'token') !== $csrfToken) {
|
||||||
$return = array_get($request->getQueryParams(), 'return');
|
$return = Arr::get($request->getQueryParams(), 'return');
|
||||||
|
|
||||||
$view = $this->view->make('flarum.forum::log-out')
|
$view = $this->view->make('flarum.forum::log-out')
|
||||||
->with('url', $this->url->to('forum')->route('logout').'?token='.$csrfToken.($return ? '&return='.urlencode($return) : ''));
|
->with('url', $this->url->to('forum')->route('logout').'?token='.$csrfToken.($return ? '&return='.urlencode($return) : ''));
|
||||||
|
@@ -16,6 +16,7 @@ use Flarum\Http\Controller\AbstractHtmlController;
|
|||||||
use Flarum\User\Exception\InvalidConfirmationTokenException;
|
use Flarum\User\Exception\InvalidConfirmationTokenException;
|
||||||
use Flarum\User\PasswordToken;
|
use Flarum\User\PasswordToken;
|
||||||
use Illuminate\Contracts\View\Factory;
|
use Illuminate\Contracts\View\Factory;
|
||||||
|
use Illuminate\Support\Arr;
|
||||||
use Psr\Http\Message\ServerRequestInterface as Request;
|
use Psr\Http\Message\ServerRequestInterface as Request;
|
||||||
|
|
||||||
class ResetPasswordController extends AbstractHtmlController
|
class ResetPasswordController extends AbstractHtmlController
|
||||||
@@ -40,7 +41,7 @@ class ResetPasswordController extends AbstractHtmlController
|
|||||||
*/
|
*/
|
||||||
public function render(Request $request)
|
public function render(Request $request)
|
||||||
{
|
{
|
||||||
$token = array_get($request->getQueryParams(), 'token');
|
$token = Arr::get($request->getQueryParams(), 'token');
|
||||||
|
|
||||||
$token = PasswordToken::findOrFail($token);
|
$token = PasswordToken::findOrFail($token);
|
||||||
|
|
||||||
|
@@ -18,6 +18,7 @@ use Flarum\User\PasswordToken;
|
|||||||
use Flarum\User\UserValidator;
|
use Flarum\User\UserValidator;
|
||||||
use Illuminate\Contracts\Events\Dispatcher;
|
use Illuminate\Contracts\Events\Dispatcher;
|
||||||
use Illuminate\Contracts\Validation\Factory;
|
use Illuminate\Contracts\Validation\Factory;
|
||||||
|
use Illuminate\Support\Arr;
|
||||||
use Illuminate\Support\MessageBag;
|
use Illuminate\Support\MessageBag;
|
||||||
use Illuminate\Validation\ValidationException;
|
use Illuminate\Validation\ValidationException;
|
||||||
use Psr\Http\Message\ResponseInterface;
|
use Psr\Http\Message\ResponseInterface;
|
||||||
@@ -72,9 +73,9 @@ class SavePasswordController implements RequestHandlerInterface
|
|||||||
{
|
{
|
||||||
$input = $request->getParsedBody();
|
$input = $request->getParsedBody();
|
||||||
|
|
||||||
$token = PasswordToken::findOrFail(array_get($input, 'passwordToken'));
|
$token = PasswordToken::findOrFail(Arr::get($input, 'passwordToken'));
|
||||||
|
|
||||||
$password = array_get($input, 'password');
|
$password = Arr::get($input, 'password');
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// todo: probably shouldn't use the user validator for this,
|
// todo: probably shouldn't use the user validator for this,
|
||||||
|
@@ -68,6 +68,7 @@ class ForumServiceProvider extends AbstractServiceProvider
|
|||||||
$pipe->pipe($app->make(HttpMiddleware\StartSession::class));
|
$pipe->pipe($app->make(HttpMiddleware\StartSession::class));
|
||||||
$pipe->pipe($app->make(HttpMiddleware\RememberFromCookie::class));
|
$pipe->pipe($app->make(HttpMiddleware\RememberFromCookie::class));
|
||||||
$pipe->pipe($app->make(HttpMiddleware\AuthenticateWithSession::class));
|
$pipe->pipe($app->make(HttpMiddleware\AuthenticateWithSession::class));
|
||||||
|
$pipe->pipe($app->make(HttpMiddleware\CheckCsrfToken::class));
|
||||||
$pipe->pipe($app->make(HttpMiddleware\SetLocale::class));
|
$pipe->pipe($app->make(HttpMiddleware\SetLocale::class));
|
||||||
$pipe->pipe($app->make(HttpMiddleware\ShareErrorsFromSession::class));
|
$pipe->pipe($app->make(HttpMiddleware\ShareErrorsFromSession::class));
|
||||||
|
|
||||||
@@ -94,7 +95,7 @@ class ForumServiceProvider extends AbstractServiceProvider
|
|||||||
$assets->css(function (SourceCollector $sources) {
|
$assets->css(function (SourceCollector $sources) {
|
||||||
$sources->addFile(__DIR__.'/../../less/forum.less');
|
$sources->addFile(__DIR__.'/../../less/forum.less');
|
||||||
$sources->addString(function () {
|
$sources->addString(function () {
|
||||||
return $this->app->make(SettingsRepositoryInterface::class)->get('custom_less');
|
return $this->app->make(SettingsRepositoryInterface::class)->get('custom_less', '');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@@ -13,6 +13,7 @@ namespace Flarum\Foundation;
|
|||||||
|
|
||||||
use Flarum\Foundation\Event\Validating;
|
use Flarum\Foundation\Event\Validating;
|
||||||
use Illuminate\Contracts\Events\Dispatcher;
|
use Illuminate\Contracts\Events\Dispatcher;
|
||||||
|
use Illuminate\Support\Arr;
|
||||||
use Illuminate\Validation\Factory;
|
use Illuminate\Validation\Factory;
|
||||||
use Illuminate\Validation\ValidationException;
|
use Illuminate\Validation\ValidationException;
|
||||||
use Symfony\Component\Translation\TranslatorInterface;
|
use Symfony\Component\Translation\TranslatorInterface;
|
||||||
@@ -89,7 +90,7 @@ abstract class AbstractValidator
|
|||||||
*/
|
*/
|
||||||
protected function makeValidator(array $attributes)
|
protected function makeValidator(array $attributes)
|
||||||
{
|
{
|
||||||
$rules = array_only($this->getRules(), array_keys($attributes));
|
$rules = Arr::only($this->getRules(), array_keys($attributes));
|
||||||
|
|
||||||
$validator = $this->validator->make($attributes, $rules, $this->getMessages());
|
$validator = $this->validator->make($attributes, $rules, $this->getMessages());
|
||||||
|
|
||||||
|
@@ -25,7 +25,7 @@ class Application extends Container implements ApplicationContract
|
|||||||
*
|
*
|
||||||
* @var string
|
* @var string
|
||||||
*/
|
*/
|
||||||
const VERSION = '0.1.0-beta.8.1';
|
const VERSION = '0.1.0-beta.9';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The base path for the Flarum installation.
|
* The base path for the Flarum installation.
|
||||||
@@ -41,6 +41,20 @@ class Application extends Container implements ApplicationContract
|
|||||||
*/
|
*/
|
||||||
protected $publicPath;
|
protected $publicPath;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The custom storage path defined by the developer.
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $storagePath;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A custom vendor path to find dependencies in non-standard environments.
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $vendorPath;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Indicates if the application has "booted".
|
* Indicates if the application has "booted".
|
||||||
*
|
*
|
||||||
@@ -83,13 +97,6 @@ class Application extends Container implements ApplicationContract
|
|||||||
*/
|
*/
|
||||||
protected $deferredServices = [];
|
protected $deferredServices = [];
|
||||||
|
|
||||||
/**
|
|
||||||
* The custom storage path defined by the developer.
|
|
||||||
*
|
|
||||||
* @var string
|
|
||||||
*/
|
|
||||||
protected $storagePath;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new Flarum application instance.
|
* Create a new Flarum application instance.
|
||||||
*
|
*
|
||||||
@@ -120,7 +127,7 @@ class Application extends Container implements ApplicationContract
|
|||||||
*/
|
*/
|
||||||
public function config($key, $default = null)
|
public function config($key, $default = null)
|
||||||
{
|
{
|
||||||
return array_get($this->make('flarum.config'), $key, $default);
|
return Arr::get($this->make('flarum.config'), $key, $default);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -142,7 +149,7 @@ class Application extends Container implements ApplicationContract
|
|||||||
public function url($path = null)
|
public function url($path = null)
|
||||||
{
|
{
|
||||||
$config = $this->make('flarum.config');
|
$config = $this->make('flarum.config');
|
||||||
$url = array_get($config, 'url', array_get($_SERVER, 'REQUEST_URI'));
|
$url = Arr::get($config, 'url', Arr::get($_SERVER, 'REQUEST_URI'));
|
||||||
|
|
||||||
if (is_array($url)) {
|
if (is_array($url)) {
|
||||||
if (isset($url[$path])) {
|
if (isset($url[$path])) {
|
||||||
@@ -153,7 +160,7 @@ class Application extends Container implements ApplicationContract
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ($path) {
|
if ($path) {
|
||||||
$url .= '/'.array_get($config, "paths.$path", $path);
|
$url .= '/'.Arr::get($config, "paths.$path", $path);
|
||||||
}
|
}
|
||||||
|
|
||||||
return $url;
|
return $url;
|
||||||
@@ -178,7 +185,7 @@ class Application extends Container implements ApplicationContract
|
|||||||
|
|
||||||
$this->instance('app', $this);
|
$this->instance('app', $this);
|
||||||
|
|
||||||
$this->instance('Illuminate\Container\Container', $this);
|
$this->instance(Container::class, $this);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -226,7 +233,7 @@ class Application extends Container implements ApplicationContract
|
|||||||
*/
|
*/
|
||||||
protected function bindPathsInContainer()
|
protected function bindPathsInContainer()
|
||||||
{
|
{
|
||||||
foreach (['base', 'public', 'storage'] as $path) {
|
foreach (['base', 'public', 'storage', 'vendor'] as $path) {
|
||||||
$this->instance('path.'.$path, $this->{$path.'Path'}());
|
$this->instance('path.'.$path, $this->{$path.'Path'}());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -261,6 +268,16 @@ class Application extends Container implements ApplicationContract
|
|||||||
return $this->storagePath ?: $this->basePath.DIRECTORY_SEPARATOR.'storage';
|
return $this->storagePath ?: $this->basePath.DIRECTORY_SEPARATOR.'storage';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the path to the vendor directory where dependencies are installed.
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function vendorPath()
|
||||||
|
{
|
||||||
|
return $this->vendorPath ?: $this->basePath.DIRECTORY_SEPARATOR.'vendor';
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the storage directory.
|
* Set the storage directory.
|
||||||
*
|
*
|
||||||
@@ -276,6 +293,21 @@ class Application extends Container implements ApplicationContract
|
|||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the vendor directory.
|
||||||
|
*
|
||||||
|
* @param string $path
|
||||||
|
* @return $this
|
||||||
|
*/
|
||||||
|
public function useVendorPath($path)
|
||||||
|
{
|
||||||
|
$this->vendorPath = $path;
|
||||||
|
|
||||||
|
$this->instance('path.vendor', $path);
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get or check the current application environment.
|
* Get or check the current application environment.
|
||||||
*
|
*
|
||||||
@@ -680,7 +712,7 @@ class Application extends Container implements ApplicationContract
|
|||||||
public function registerCoreContainerAliases()
|
public function registerCoreContainerAliases()
|
||||||
{
|
{
|
||||||
$aliases = [
|
$aliases = [
|
||||||
'app' => [\Flarum\Foundation\Application::class, \Illuminate\Contracts\Container\Container::class, \Illuminate\Contracts\Foundation\Application::class, \Psr\Container\ContainerInterface::class],
|
'app' => [self::class, \Illuminate\Contracts\Container\Container::class, \Illuminate\Contracts\Foundation\Application::class, \Psr\Container\ContainerInterface::class],
|
||||||
'blade.compiler' => [\Illuminate\View\Compilers\BladeCompiler::class],
|
'blade.compiler' => [\Illuminate\View\Compilers\BladeCompiler::class],
|
||||||
'cache' => [\Illuminate\Cache\CacheManager::class, \Illuminate\Contracts\Cache\Factory::class],
|
'cache' => [\Illuminate\Cache\CacheManager::class, \Illuminate\Contracts\Cache\Factory::class],
|
||||||
'cache.store' => [\Illuminate\Cache\Repository::class, \Illuminate\Contracts\Cache\Repository::class],
|
'cache.store' => [\Illuminate\Cache\Repository::class, \Illuminate\Contracts\Cache\Repository::class],
|
||||||
|
@@ -22,6 +22,7 @@ use Illuminate\Contracts\Container\Container;
|
|||||||
use Middlewares\BasePath;
|
use Middlewares\BasePath;
|
||||||
use Middlewares\BasePathRouter;
|
use Middlewares\BasePathRouter;
|
||||||
use Middlewares\RequestHandler;
|
use Middlewares\RequestHandler;
|
||||||
|
use Zend\Stratigility\Middleware\OriginalMessages;
|
||||||
use Zend\Stratigility\MiddlewarePipe;
|
use Zend\Stratigility\MiddlewarePipe;
|
||||||
|
|
||||||
class InstalledApp implements AppInterface
|
class InstalledApp implements AppInterface
|
||||||
@@ -61,6 +62,7 @@ class InstalledApp implements AppInterface
|
|||||||
$pipe = new MiddlewarePipe;
|
$pipe = new MiddlewarePipe;
|
||||||
|
|
||||||
$pipe->pipe(new BasePath($this->basePath()));
|
$pipe->pipe(new BasePath($this->basePath()));
|
||||||
|
$pipe->pipe(new OriginalMessages);
|
||||||
$pipe->pipe(
|
$pipe->pipe(
|
||||||
new BasePathRouter([
|
new BasePathRouter([
|
||||||
$this->subPath('api') => 'flarum.api.middleware',
|
$this->subPath('api') => 'flarum.api.middleware',
|
||||||
@@ -89,7 +91,7 @@ class InstalledApp implements AppInterface
|
|||||||
/**
|
/**
|
||||||
* @return \Psr\Http\Server\RequestHandlerInterface
|
* @return \Psr\Http\Server\RequestHandlerInterface
|
||||||
*/
|
*/
|
||||||
public function getUpdaterHandler()
|
private function getUpdaterHandler()
|
||||||
{
|
{
|
||||||
$pipe = new MiddlewarePipe;
|
$pipe = new MiddlewarePipe;
|
||||||
$pipe->pipe(
|
$pipe->pipe(
|
||||||
|
@@ -23,6 +23,7 @@ use Flarum\Forum\ForumServiceProvider;
|
|||||||
use Flarum\Frontend\FrontendServiceProvider;
|
use Flarum\Frontend\FrontendServiceProvider;
|
||||||
use Flarum\Group\GroupServiceProvider;
|
use Flarum\Group\GroupServiceProvider;
|
||||||
use Flarum\Locale\LocaleServiceProvider;
|
use Flarum\Locale\LocaleServiceProvider;
|
||||||
|
use Flarum\Mail\MailServiceProvider;
|
||||||
use Flarum\Notification\NotificationServiceProvider;
|
use Flarum\Notification\NotificationServiceProvider;
|
||||||
use Flarum\Post\PostServiceProvider;
|
use Flarum\Post\PostServiceProvider;
|
||||||
use Flarum\Search\SearchServiceProvider;
|
use Flarum\Search\SearchServiceProvider;
|
||||||
@@ -99,6 +100,10 @@ class InstalledSite implements SiteInterface
|
|||||||
|
|
||||||
$laravel->useStoragePath($this->paths['storage']);
|
$laravel->useStoragePath($this->paths['storage']);
|
||||||
|
|
||||||
|
if (isset($this->paths['vendor'])) {
|
||||||
|
$laravel->useVendorPath($this->paths['vendor']);
|
||||||
|
}
|
||||||
|
|
||||||
$laravel->instance('env', 'production');
|
$laravel->instance('env', 'production');
|
||||||
$laravel->instance('flarum.config', $this->config);
|
$laravel->instance('flarum.config', $this->config);
|
||||||
$laravel->instance('config', $config = $this->getIlluminateConfig($laravel));
|
$laravel->instance('config', $config = $this->getIlluminateConfig($laravel));
|
||||||
|
@@ -1,83 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
/*
|
|
||||||
* This file is part of Flarum.
|
|
||||||
*
|
|
||||||
* (c) Toby Zerner <toby.zerner@gmail.com>
|
|
||||||
*
|
|
||||||
* For the full copyright and license information, please view the LICENSE
|
|
||||||
* file that was distributed with this source code.
|
|
||||||
*/
|
|
||||||
|
|
||||||
namespace Flarum\Foundation;
|
|
||||||
|
|
||||||
use Flarum\Settings\SettingsRepositoryInterface;
|
|
||||||
use Illuminate\Mail\Mailer;
|
|
||||||
use Illuminate\Mail\Transport\LogTransport;
|
|
||||||
use InvalidArgumentException;
|
|
||||||
use Psr\Log\LoggerInterface;
|
|
||||||
use Swift_Mailer;
|
|
||||||
use Swift_SendmailTransport;
|
|
||||||
use Swift_SmtpTransport;
|
|
||||||
use Swift_Transport;
|
|
||||||
|
|
||||||
class MailServiceProvider extends AbstractServiceProvider
|
|
||||||
{
|
|
||||||
public function register()
|
|
||||||
{
|
|
||||||
$this->app->singleton('mail.supported_drivers', function () {
|
|
||||||
return ['smtp', 'mail', 'log'];
|
|
||||||
});
|
|
||||||
|
|
||||||
$this->app->singleton('swift.mailer', function ($app) {
|
|
||||||
$settings = $app->make(SettingsRepositoryInterface::class);
|
|
||||||
|
|
||||||
return new Swift_Mailer(
|
|
||||||
$this->buildTransport($settings)
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
$this->app->singleton('mailer', function ($app) {
|
|
||||||
$mailer = new Mailer(
|
|
||||||
$app['view'], $app['swift.mailer'], $app['events']
|
|
||||||
);
|
|
||||||
|
|
||||||
if ($app->bound('queue')) {
|
|
||||||
$mailer->setQueue($app->make('queue'));
|
|
||||||
}
|
|
||||||
|
|
||||||
$settings = $app->make(SettingsRepositoryInterface::class);
|
|
||||||
$mailer->alwaysFrom($settings->get('mail_from'), $settings->get('forum_title'));
|
|
||||||
|
|
||||||
return $mailer;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private function buildTransport(SettingsRepositoryInterface $settings): Swift_Transport
|
|
||||||
{
|
|
||||||
switch ($settings->get('mail_driver')) {
|
|
||||||
case 'smtp':
|
|
||||||
return $this->buildSmtpTransport($settings);
|
|
||||||
case 'mail':
|
|
||||||
return new Swift_SendmailTransport;
|
|
||||||
case 'log':
|
|
||||||
return new LogTransport($this->app->make(LoggerInterface::class));
|
|
||||||
default:
|
|
||||||
throw new InvalidArgumentException('Invalid mail driver configuration');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private function buildSmtpTransport(SettingsRepositoryInterface $settings): Swift_Transport
|
|
||||||
{
|
|
||||||
$transport = new Swift_SmtpTransport(
|
|
||||||
$settings->get('mail_host'),
|
|
||||||
$settings->get('mail_port'),
|
|
||||||
$settings->get('mail_encryption')
|
|
||||||
);
|
|
||||||
|
|
||||||
$transport->setUsername($settings->get('mail_username'));
|
|
||||||
$transport->setPassword($settings->get('mail_password'));
|
|
||||||
|
|
||||||
return $transport;
|
|
||||||
}
|
|
||||||
}
|
|
@@ -11,6 +11,7 @@
|
|||||||
|
|
||||||
namespace Flarum\Foundation;
|
namespace Flarum\Foundation;
|
||||||
|
|
||||||
|
use Illuminate\Support\Str;
|
||||||
use Psr\Http\Message\ResponseInterface;
|
use Psr\Http\Message\ResponseInterface;
|
||||||
use Psr\Http\Message\ServerRequestInterface;
|
use Psr\Http\Message\ServerRequestInterface;
|
||||||
use Psr\Http\Server\RequestHandlerInterface;
|
use Psr\Http\Server\RequestHandlerInterface;
|
||||||
@@ -38,7 +39,7 @@ class MaintenanceModeHandler implements RequestHandlerInterface
|
|||||||
|
|
||||||
private function isApiRequest(ServerRequestInterface $request): bool
|
private function isApiRequest(ServerRequestInterface $request): bool
|
||||||
{
|
{
|
||||||
return str_contains(
|
return Str::contains(
|
||||||
$request->getHeaderLine('Accept'),
|
$request->getHeaderLine('Accept'),
|
||||||
'application/vnd.api+json'
|
'application/vnd.api+json'
|
||||||
);
|
);
|
||||||
|
@@ -59,6 +59,10 @@ class UninstalledSite implements SiteInterface
|
|||||||
|
|
||||||
$laravel->useStoragePath($this->paths['storage']);
|
$laravel->useStoragePath($this->paths['storage']);
|
||||||
|
|
||||||
|
if (isset($this->paths['vendor'])) {
|
||||||
|
$laravel->useVendorPath($this->paths['vendor']);
|
||||||
|
}
|
||||||
|
|
||||||
$laravel->instance('env', 'production');
|
$laravel->instance('env', 'production');
|
||||||
$laravel->instance('flarum.config', []);
|
$laravel->instance('flarum.config', []);
|
||||||
$laravel->instance('config', $config = $this->getIlluminateConfig());
|
$laravel->instance('config', $config = $this->getIlluminateConfig());
|
||||||
|
@@ -13,6 +13,7 @@ namespace Flarum\Frontend;
|
|||||||
|
|
||||||
use Flarum\Frontend\Compiler\Source\SourceCollector;
|
use Flarum\Frontend\Compiler\Source\SourceCollector;
|
||||||
use Flarum\Locale\LocaleManager;
|
use Flarum\Locale\LocaleManager;
|
||||||
|
use Illuminate\Support\Arr;
|
||||||
|
|
||||||
class AddTranslations
|
class AddTranslations
|
||||||
{
|
{
|
||||||
@@ -56,7 +57,7 @@ class AddTranslations
|
|||||||
{
|
{
|
||||||
$translations = $this->locales->getTranslator()->getCatalogue($locale)->all('messages');
|
$translations = $this->locales->getTranslator()->getCatalogue($locale)->all('messages');
|
||||||
|
|
||||||
return array_only(
|
return Arr::only(
|
||||||
$translations,
|
$translations,
|
||||||
array_filter(array_keys($translations), $this->filter)
|
array_filter(array_keys($translations), $this->filter)
|
||||||
);
|
);
|
||||||
|
@@ -58,7 +58,7 @@ class JsCompiler extends RevisionCompiler
|
|||||||
|
|
||||||
$this->assetsDir->put($file, implode("\n", $output));
|
$this->assetsDir->put($file, implode("\n", $output));
|
||||||
|
|
||||||
$mapTemp = tempnam(sys_get_temp_dir(), $mapFile);
|
$mapTemp = @tempnam(storage_path('tmp'), $mapFile);
|
||||||
$map->save($mapTemp);
|
$map->save($mapTemp);
|
||||||
$this->assetsDir->put($mapFile, file_get_contents($mapTemp));
|
$this->assetsDir->put($mapFile, file_get_contents($mapTemp));
|
||||||
@unlink($mapTemp);
|
@unlink($mapTemp);
|
||||||
|
@@ -14,6 +14,7 @@ namespace Flarum\Frontend\Compiler;
|
|||||||
use Flarum\Frontend\Compiler\Source\SourceCollector;
|
use Flarum\Frontend\Compiler\Source\SourceCollector;
|
||||||
use Flarum\Frontend\Compiler\Source\SourceInterface;
|
use Flarum\Frontend\Compiler\Source\SourceInterface;
|
||||||
use Illuminate\Contracts\Filesystem\Filesystem;
|
use Illuminate\Contracts\Filesystem\Filesystem;
|
||||||
|
use Illuminate\Support\Arr;
|
||||||
|
|
||||||
class RevisionCompiler implements CompilerInterface
|
class RevisionCompiler implements CompilerInterface
|
||||||
{
|
{
|
||||||
@@ -202,7 +203,7 @@ class RevisionCompiler implements CompilerInterface
|
|||||||
if ($this->assetsDir->has(static::REV_MANIFEST)) {
|
if ($this->assetsDir->has(static::REV_MANIFEST)) {
|
||||||
$manifest = json_decode($this->assetsDir->read(static::REV_MANIFEST), true);
|
$manifest = json_decode($this->assetsDir->read(static::REV_MANIFEST), true);
|
||||||
|
|
||||||
return array_get($manifest, $this->filename);
|
return Arr::get($manifest, $this->filename);
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
|
@@ -12,6 +12,7 @@
|
|||||||
namespace Flarum\Frontend\Content;
|
namespace Flarum\Frontend\Content;
|
||||||
|
|
||||||
use Flarum\Frontend\Document;
|
use Flarum\Frontend\Document;
|
||||||
|
use Illuminate\Support\Arr;
|
||||||
use Psr\Http\Message\ServerRequestInterface as Request;
|
use Psr\Http\Message\ServerRequestInterface as Request;
|
||||||
|
|
||||||
class Meta
|
class Meta
|
||||||
@@ -28,8 +29,8 @@ class Meta
|
|||||||
|
|
||||||
$meta = [
|
$meta = [
|
||||||
'viewport' => 'width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1',
|
'viewport' => 'width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1',
|
||||||
'description' => array_get($forumApiDocument, 'data.attributes.description'),
|
'description' => Arr::get($forumApiDocument, 'data.attributes.description'),
|
||||||
'theme-color' => array_get($forumApiDocument, 'data.attributes.themePrimaryColor')
|
'theme-color' => Arr::get($forumApiDocument, 'data.attributes.themePrimaryColor')
|
||||||
];
|
];
|
||||||
|
|
||||||
return $meta;
|
return $meta;
|
||||||
@@ -39,7 +40,7 @@ class Meta
|
|||||||
{
|
{
|
||||||
$head = [];
|
$head = [];
|
||||||
|
|
||||||
if ($faviconUrl = array_get($document->getForumApiDocument(), 'data.attributes.faviconUrl')) {
|
if ($faviconUrl = Arr::get($document->getForumApiDocument(), 'data.attributes.faviconUrl')) {
|
||||||
$head['favicon'] = '<link rel="shortcut icon" href="'.e($faviconUrl).'">';
|
$head['favicon'] = '<link rel="shortcut icon" href="'.e($faviconUrl).'">';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -14,6 +14,7 @@ namespace Flarum\Frontend;
|
|||||||
use Illuminate\Contracts\Support\Renderable;
|
use Illuminate\Contracts\Support\Renderable;
|
||||||
use Illuminate\Contracts\View\Factory;
|
use Illuminate\Contracts\View\Factory;
|
||||||
use Illuminate\Contracts\View\View;
|
use Illuminate\Contracts\View\View;
|
||||||
|
use Illuminate\Support\Arr;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A view which renders a HTML skeleton for Flarum's frontend app.
|
* A view which renders a HTML skeleton for Flarum's frontend app.
|
||||||
@@ -147,7 +148,7 @@ class Document implements Renderable
|
|||||||
*/
|
*/
|
||||||
public function render(): string
|
public function render(): string
|
||||||
{
|
{
|
||||||
$this->view->share('forum', array_get($this->forumApiDocument, 'data.attributes'));
|
$this->view->share('forum', Arr::get($this->forumApiDocument, 'data.attributes'));
|
||||||
|
|
||||||
return $this->makeView()->render();
|
return $this->makeView()->render();
|
||||||
}
|
}
|
||||||
@@ -174,7 +175,7 @@ class Document implements Renderable
|
|||||||
*/
|
*/
|
||||||
protected function makeTitle(): string
|
protected function makeTitle(): string
|
||||||
{
|
{
|
||||||
return ($this->title ? $this->title.' - ' : '').array_get($this->forumApiDocument, 'data.attributes.title');
|
return ($this->title ? $this->title.' - ' : '').Arr::get($this->forumApiDocument, 'data.attributes.title');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -30,7 +30,7 @@ class FrontendServiceProvider extends AbstractServiceProvider
|
|||||||
);
|
);
|
||||||
|
|
||||||
$assets->setLessImportDirs([
|
$assets->setLessImportDirs([
|
||||||
$this->app->basePath().'/vendor/components/font-awesome/less' => ''
|
$this->app->vendorPath().'/components/font-awesome/less' => ''
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$assets->css([$this, 'addBaseCss']);
|
$assets->css([$this, 'addBaseCss']);
|
||||||
@@ -72,8 +72,8 @@ class FrontendServiceProvider extends AbstractServiceProvider
|
|||||||
|
|
||||||
public function addBaseCss(SourceCollector $sources)
|
public function addBaseCss(SourceCollector $sources)
|
||||||
{
|
{
|
||||||
$sources->addFile(base_path().'/vendor/flarum/core/less/common/variables.less');
|
$sources->addFile(__DIR__.'/../../less/common/variables.less');
|
||||||
$sources->addFile(base_path().'/vendor/flarum/core/less/common/mixins.less');
|
$sources->addFile(__DIR__.'/../../less/common/mixins.less');
|
||||||
|
|
||||||
$this->addLessVariables($sources);
|
$this->addLessVariables($sources);
|
||||||
}
|
}
|
||||||
|
@@ -17,6 +17,7 @@ use Flarum\Group\Group;
|
|||||||
use Flarum\Group\GroupValidator;
|
use Flarum\Group\GroupValidator;
|
||||||
use Flarum\User\AssertPermissionTrait;
|
use Flarum\User\AssertPermissionTrait;
|
||||||
use Illuminate\Contracts\Events\Dispatcher;
|
use Illuminate\Contracts\Events\Dispatcher;
|
||||||
|
use Illuminate\Support\Arr;
|
||||||
|
|
||||||
class CreateGroupHandler
|
class CreateGroupHandler
|
||||||
{
|
{
|
||||||
@@ -51,10 +52,10 @@ class CreateGroupHandler
|
|||||||
$this->assertCan($actor, 'createGroup');
|
$this->assertCan($actor, 'createGroup');
|
||||||
|
|
||||||
$group = Group::build(
|
$group = Group::build(
|
||||||
array_get($data, 'attributes.nameSingular'),
|
Arr::get($data, 'attributes.nameSingular'),
|
||||||
array_get($data, 'attributes.namePlural'),
|
Arr::get($data, 'attributes.namePlural'),
|
||||||
array_get($data, 'attributes.color'),
|
Arr::get($data, 'attributes.color'),
|
||||||
array_get($data, 'attributes.icon')
|
Arr::get($data, 'attributes.icon')
|
||||||
);
|
);
|
||||||
|
|
||||||
$this->events->dispatch(
|
$this->events->dispatch(
|
||||||
|
@@ -19,6 +19,7 @@ use Flarum\Group\GroupValidator;
|
|||||||
use Flarum\User\AssertPermissionTrait;
|
use Flarum\User\AssertPermissionTrait;
|
||||||
use Flarum\User\Exception\PermissionDeniedException;
|
use Flarum\User\Exception\PermissionDeniedException;
|
||||||
use Illuminate\Contracts\Events\Dispatcher;
|
use Illuminate\Contracts\Events\Dispatcher;
|
||||||
|
use Illuminate\Support\Arr;
|
||||||
|
|
||||||
class EditGroupHandler
|
class EditGroupHandler
|
||||||
{
|
{
|
||||||
@@ -61,7 +62,7 @@ class EditGroupHandler
|
|||||||
|
|
||||||
$this->assertCan($actor, 'edit', $group);
|
$this->assertCan($actor, 'edit', $group);
|
||||||
|
|
||||||
$attributes = array_get($data, 'attributes', []);
|
$attributes = Arr::get($data, 'attributes', []);
|
||||||
|
|
||||||
if (isset($attributes['nameSingular']) && isset($attributes['namePlural'])) {
|
if (isset($attributes['nameSingular']) && isset($attributes['namePlural'])) {
|
||||||
$group->rename($attributes['nameSingular'], $attributes['namePlural']);
|
$group->rename($attributes['nameSingular'], $attributes['namePlural']);
|
||||||
|
@@ -62,7 +62,7 @@ class Group extends AbstractModel
|
|||||||
{
|
{
|
||||||
parent::boot();
|
parent::boot();
|
||||||
|
|
||||||
static::deleted(function (Group $group) {
|
static::deleted(function (self $group) {
|
||||||
$group->raise(new Deleted($group));
|
$group->raise(new Deleted($group));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@@ -14,6 +14,7 @@ namespace Flarum\Http;
|
|||||||
use Carbon\Carbon;
|
use Carbon\Carbon;
|
||||||
use Flarum\Database\AbstractModel;
|
use Flarum\Database\AbstractModel;
|
||||||
use Flarum\User\User;
|
use Flarum\User\User;
|
||||||
|
use Illuminate\Support\Str;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @property string $token
|
* @property string $token
|
||||||
@@ -47,7 +48,7 @@ class AccessToken extends AbstractModel
|
|||||||
{
|
{
|
||||||
$token = new static;
|
$token = new static;
|
||||||
|
|
||||||
$token->token = str_random(40);
|
$token->token = Str::random(40);
|
||||||
$token->user_id = $userId;
|
$token->user_id = $userId;
|
||||||
$token->created_at = Carbon::now();
|
$token->created_at = Carbon::now();
|
||||||
$token->last_activity_at = Carbon::now();
|
$token->last_activity_at = Carbon::now();
|
||||||
|
@@ -13,6 +13,7 @@ namespace Flarum\Http;
|
|||||||
|
|
||||||
use Dflydev\FigCookies\SetCookie;
|
use Dflydev\FigCookies\SetCookie;
|
||||||
use Flarum\Foundation\Application;
|
use Flarum\Foundation\Application;
|
||||||
|
use Illuminate\Support\Arr;
|
||||||
|
|
||||||
class CookieFactory
|
class CookieFactory
|
||||||
{
|
{
|
||||||
@@ -54,9 +55,9 @@ class CookieFactory
|
|||||||
|
|
||||||
// Get the cookie settings from the config or use the default values
|
// Get the cookie settings from the config or use the default values
|
||||||
$this->prefix = $app->config('cookie.name', 'flarum');
|
$this->prefix = $app->config('cookie.name', 'flarum');
|
||||||
$this->path = $app->config('cookie.path', array_get($url, 'path') ?: '/');
|
$this->path = $app->config('cookie.path', Arr::get($url, 'path') ?: '/');
|
||||||
$this->domain = $app->config('cookie.domain');
|
$this->domain = $app->config('cookie.domain');
|
||||||
$this->secure = $app->config('cookie.secure', array_get($url, 'scheme') === 'https');
|
$this->secure = $app->config('cookie.secure', Arr::get($url, 'scheme') === 'https');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -15,4 +15,8 @@ use Exception;
|
|||||||
|
|
||||||
class TokenMismatchException extends Exception
|
class TokenMismatchException extends Exception
|
||||||
{
|
{
|
||||||
|
public function __construct($message = null, $code = 419, Exception $previous = null)
|
||||||
|
{
|
||||||
|
parent::__construct($message, $code, $previous);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -14,6 +14,7 @@ namespace Flarum\Http\Middleware;
|
|||||||
use Flarum\Api\ApiKey;
|
use Flarum\Api\ApiKey;
|
||||||
use Flarum\Http\AccessToken;
|
use Flarum\Http\AccessToken;
|
||||||
use Flarum\User\User;
|
use Flarum\User\User;
|
||||||
|
use Illuminate\Support\Str;
|
||||||
use Psr\Http\Message\ResponseInterface as Response;
|
use Psr\Http\Message\ResponseInterface as Response;
|
||||||
use Psr\Http\Message\ServerRequestInterface as Request;
|
use Psr\Http\Message\ServerRequestInterface as Request;
|
||||||
use Psr\Http\Server\MiddlewareInterface as Middleware;
|
use Psr\Http\Server\MiddlewareInterface as Middleware;
|
||||||
@@ -29,7 +30,7 @@ class AuthenticateWithHeader implements Middleware
|
|||||||
|
|
||||||
$parts = explode(';', $headerLine);
|
$parts = explode(';', $headerLine);
|
||||||
|
|
||||||
if (isset($parts[0]) && starts_with($parts[0], self::TOKEN_PREFIX)) {
|
if (isset($parts[0]) && Str::startsWith($parts[0], self::TOKEN_PREFIX)) {
|
||||||
$id = substr($parts[0], strlen(self::TOKEN_PREFIX));
|
$id = substr($parts[0], strlen(self::TOKEN_PREFIX));
|
||||||
|
|
||||||
if ($key = ApiKey::where('key', $id)->first()) {
|
if ($key = ApiKey::where('key', $id)->first()) {
|
||||||
@@ -40,6 +41,7 @@ class AuthenticateWithHeader implements Middleware
|
|||||||
|
|
||||||
$request = $request->withAttribute('apiKey', $key);
|
$request = $request->withAttribute('apiKey', $key);
|
||||||
$request = $request->withAttribute('bypassFloodgate', true);
|
$request = $request->withAttribute('bypassFloodgate', true);
|
||||||
|
$request = $request->withAttribute('bypassCsrfToken', true);
|
||||||
} elseif ($token = AccessToken::find($id)) {
|
} elseif ($token = AccessToken::find($id)) {
|
||||||
$token->touch();
|
$token->touch();
|
||||||
|
|
||||||
|
48
src/Http/Middleware/CheckCsrfToken.php
Normal file
48
src/Http/Middleware/CheckCsrfToken.php
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of Flarum.
|
||||||
|
*
|
||||||
|
* (c) Toby Zerner <toby.zerner@gmail.com>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Flarum\Http\Middleware;
|
||||||
|
|
||||||
|
use Flarum\Http\Exception\TokenMismatchException;
|
||||||
|
use Psr\Http\Message\ResponseInterface as Response;
|
||||||
|
use Psr\Http\Message\ServerRequestInterface as Request;
|
||||||
|
use Psr\Http\Server\MiddlewareInterface as Middleware;
|
||||||
|
use Psr\Http\Server\RequestHandlerInterface as Handler;
|
||||||
|
|
||||||
|
class CheckCsrfToken implements Middleware
|
||||||
|
{
|
||||||
|
public function process(Request $request, Handler $handler): Response
|
||||||
|
{
|
||||||
|
if (in_array($request->getMethod(), ['GET', 'HEAD', 'OPTIONS'])) {
|
||||||
|
return $handler->handle($request);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($request->getAttribute('bypassCsrfToken', false)) {
|
||||||
|
return $handler->handle($request);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($this->tokensMatch($request)) {
|
||||||
|
return $handler->handle($request);
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new TokenMismatchException('CSRF token did not match');
|
||||||
|
}
|
||||||
|
|
||||||
|
private function tokensMatch(Request $request): bool
|
||||||
|
{
|
||||||
|
$expected = (string) $request->getAttribute('session')->token();
|
||||||
|
|
||||||
|
$provided = $request->getParsedBody()['csrfToken'] ??
|
||||||
|
$request->getHeaderLine('X-CSRF-Token');
|
||||||
|
|
||||||
|
return hash_equals($expected, $provided);
|
||||||
|
}
|
||||||
|
}
|
@@ -42,11 +42,19 @@ class HandleErrorsWithWhoops implements Middleware
|
|||||||
try {
|
try {
|
||||||
return $handler->handle($request);
|
return $handler->handle($request);
|
||||||
} catch (Throwable $e) {
|
} catch (Throwable $e) {
|
||||||
if ($e->getCode() !== 404) {
|
$status = 500;
|
||||||
|
$errorCode = $e->getCode();
|
||||||
|
|
||||||
|
if ($errorCode !== 404) {
|
||||||
$this->logger->error($e);
|
$this->logger->error($e);
|
||||||
}
|
}
|
||||||
|
|
||||||
return WhoopsRunner::handle($e, $request);
|
if (is_int($errorCode) && $errorCode >= 400 && $errorCode < 600) {
|
||||||
|
$status = $errorCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
return WhoopsRunner::handle($e, $request)
|
||||||
|
->withStatus($status);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -11,6 +11,7 @@
|
|||||||
|
|
||||||
namespace Flarum\Http\Middleware;
|
namespace Flarum\Http\Middleware;
|
||||||
|
|
||||||
|
use Illuminate\Support\Str;
|
||||||
use Psr\Http\Message\ResponseInterface as Response;
|
use Psr\Http\Message\ResponseInterface as Response;
|
||||||
use Psr\Http\Message\ServerRequestInterface as Request;
|
use Psr\Http\Message\ServerRequestInterface as Request;
|
||||||
use Psr\Http\Server\MiddlewareInterface as Middleware;
|
use Psr\Http\Server\MiddlewareInterface as Middleware;
|
||||||
@@ -20,7 +21,7 @@ class ParseJsonBody implements Middleware
|
|||||||
{
|
{
|
||||||
public function process(Request $request, Handler $handler): Response
|
public function process(Request $request, Handler $handler): Response
|
||||||
{
|
{
|
||||||
if (str_contains($request->getHeaderLine('content-type'), 'json')) {
|
if (Str::contains($request->getHeaderLine('content-type'), 'json')) {
|
||||||
$input = json_decode($request->getBody(), true);
|
$input = json_decode($request->getBody(), true);
|
||||||
|
|
||||||
$request = $request->withParsedBody($input ?: []);
|
$request = $request->withParsedBody($input ?: []);
|
||||||
|
@@ -13,6 +13,7 @@ namespace Flarum\Http\Middleware;
|
|||||||
|
|
||||||
use Flarum\Http\AccessToken;
|
use Flarum\Http\AccessToken;
|
||||||
use Flarum\Http\CookieFactory;
|
use Flarum\Http\CookieFactory;
|
||||||
|
use Illuminate\Support\Arr;
|
||||||
use Psr\Http\Message\ResponseInterface as Response;
|
use Psr\Http\Message\ResponseInterface as Response;
|
||||||
use Psr\Http\Message\ServerRequestInterface as Request;
|
use Psr\Http\Message\ServerRequestInterface as Request;
|
||||||
use Psr\Http\Server\MiddlewareInterface as Middleware;
|
use Psr\Http\Server\MiddlewareInterface as Middleware;
|
||||||
@@ -35,7 +36,7 @@ class RememberFromCookie implements Middleware
|
|||||||
|
|
||||||
public function process(Request $request, Handler $handler): Response
|
public function process(Request $request, Handler $handler): Response
|
||||||
{
|
{
|
||||||
$id = array_get($request->getCookieParams(), $this->cookie->getName('remember'));
|
$id = Arr::get($request->getCookieParams(), $this->cookie->getName('remember'));
|
||||||
|
|
||||||
if ($id) {
|
if ($id) {
|
||||||
$token = AccessToken::find($id);
|
$token = AccessToken::find($id);
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user