mirror of
https://github.com/flarum/framework.git
synced 2025-01-19 07:42:48 +08:00
Initial working extension
This commit is contained in:
parent
350ce11f17
commit
dbc67937ed
20
extensions/nicknames/.editorconfig
Normal file
20
extensions/nicknames/.editorconfig
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
|
||||||
|
# EditorConfig helps developers define and maintain consistent
|
||||||
|
# coding styles between different editors and IDEs
|
||||||
|
# editorconfig.org
|
||||||
|
|
||||||
|
root = true
|
||||||
|
|
||||||
|
[*]
|
||||||
|
end_of_line = lf
|
||||||
|
charset = utf-8
|
||||||
|
trim_trailing_whitespace = true
|
||||||
|
insert_final_newline = true
|
||||||
|
indent_style = space
|
||||||
|
indent_size = 2
|
||||||
|
|
||||||
|
[*.{diff,md}]
|
||||||
|
trim_trailing_whitespace = false
|
||||||
|
|
||||||
|
[*.php]
|
||||||
|
indent_size = 4
|
7
extensions/nicknames/.gitattributes
vendored
Normal file
7
extensions/nicknames/.gitattributes
vendored
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
.gitattributes export-ignore
|
||||||
|
.gitignore export-ignore
|
||||||
|
.travis.yml export-ignore
|
||||||
|
js/src export-ignore
|
||||||
|
.git* export-ignore
|
||||||
|
|
||||||
|
js/dist/*.js -diff
|
16
extensions/nicknames/.github/workflows/build.yml
vendored
Normal file
16
extensions/nicknames/.github/workflows/build.yml
vendored
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
name: Build JavaScript assets
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- master
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@master
|
||||||
|
- uses: flarum/action-build@master
|
||||||
|
env:
|
||||||
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
6
extensions/nicknames/.gitignore
vendored
Normal file
6
extensions/nicknames/.gitignore
vendored
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
/vendor
|
||||||
|
composer.phar
|
||||||
|
.DS_Store
|
||||||
|
Thumbs.db
|
||||||
|
node_modules
|
||||||
|
js/dist/*
|
14
extensions/nicknames/.styleci.yml
Normal file
14
extensions/nicknames/.styleci.yml
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
preset: recommended
|
||||||
|
|
||||||
|
enabled:
|
||||||
|
- logical_not_operators_with_successor_space
|
||||||
|
|
||||||
|
disabled:
|
||||||
|
- align_double_arrow
|
||||||
|
- blank_line_after_opening_tag
|
||||||
|
- multiline_array_trailing_comma
|
||||||
|
- new_with_braces
|
||||||
|
- phpdoc_align
|
||||||
|
- phpdoc_order
|
||||||
|
- phpdoc_separation
|
||||||
|
- phpdoc_types
|
1
extensions/nicknames/CHANGELOG.md
Normal file
1
extensions/nicknames/CHANGELOG.md
Normal file
|
@ -0,0 +1 @@
|
||||||
|
# Changelog
|
21
extensions/nicknames/LICENSE
Normal file
21
extensions/nicknames/LICENSE
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
The MIT License (MIT)
|
||||||
|
|
||||||
|
Copyright (c) 2020 Stichting Flarum (Flarum Foundation)
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
|
@ -1,23 +0,0 @@
|
||||||
# Nickname
|
|
||||||
|
|
||||||
![License](https://img.shields.io/badge/license-MIT-blue.svg) [![Latest Stable Version](https://img.shields.io/packagist/v/flarum/nickname.svg)](https://packagist.org/packages/flarum/nickname)
|
|
||||||
|
|
||||||
A [Flarum](http://flarum.org) extension.
|
|
||||||
|
|
||||||
### Installation
|
|
||||||
|
|
||||||
Use [Bazaar](https://discuss.flarum.org/d/5151-flagrow-bazaar-the-extension-marketplace) or install manually with composer:
|
|
||||||
|
|
||||||
```sh
|
|
||||||
composer require flarum/nickname
|
|
||||||
```
|
|
||||||
|
|
||||||
### Updating
|
|
||||||
|
|
||||||
```sh
|
|
||||||
composer update flarum/nickname
|
|
||||||
```
|
|
||||||
|
|
||||||
### Links
|
|
||||||
|
|
||||||
- [Packagist](https://packagist.org/packages/flarum/nickname)
|
|
32
extensions/nicknames/composer.json
Normal file
32
extensions/nicknames/composer.json
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
{
|
||||||
|
"name": "flarum/nicknames",
|
||||||
|
"description": "Use nicknames for users",
|
||||||
|
"type": "flarum-extension",
|
||||||
|
"keywords": ["nicknames"],
|
||||||
|
"license": "MIT",
|
||||||
|
"support": {
|
||||||
|
"issues": "https://github.com/flarum/core/issues",
|
||||||
|
"source": "https://github.com/flarum/nicknames"
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"flarum/core": "^0.1.0-beta.14"
|
||||||
|
},
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"Flarum\\Nicknames\\": "src/"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"extra": {
|
||||||
|
"branch-alias": {
|
||||||
|
"dev-master": "0.1.x-dev"
|
||||||
|
},
|
||||||
|
"flarum-extension": {
|
||||||
|
"title": "Nicknames",
|
||||||
|
"icon": {
|
||||||
|
"name": "fas fa-user-tag",
|
||||||
|
"backgroundColor": "#8E4529",
|
||||||
|
"color": "#ffffff"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
39
extensions/nicknames/extend.php
Normal file
39
extensions/nicknames/extend.php
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of flarum/nickname.
|
||||||
|
*
|
||||||
|
* Copyright (c) 2020 Flarum.
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE.md
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Flarum\Nicknames;
|
||||||
|
|
||||||
|
use Flarum\Event\ConfigureUserGambits;
|
||||||
|
use Flarum\Extend;
|
||||||
|
use Flarum\User\Event\Saving;
|
||||||
|
use Flarum\User\User;
|
||||||
|
|
||||||
|
return [
|
||||||
|
(new Extend\Frontend('forum'))
|
||||||
|
->js(__DIR__.'/js/dist/forum.js')
|
||||||
|
->css(__DIR__.'/resources/less/forum.less'),
|
||||||
|
|
||||||
|
(new Extend\Frontend('admin'))
|
||||||
|
->js(__DIR__.'/js/dist/admin.js')
|
||||||
|
->css(__DIR__.'/resources/less/admin.less'),
|
||||||
|
|
||||||
|
(new Extend\User())
|
||||||
|
->displayNameDriver('nickname', NicknameDriver::class),
|
||||||
|
|
||||||
|
(new Extend\ModelUrl(User::class))
|
||||||
|
->addSlugDriver('idOnly', IdOnlyUserSlugDriver::class),
|
||||||
|
|
||||||
|
(new Extend\Event())
|
||||||
|
->listen(Saving::class, SaveNicknameToDatabase::class)
|
||||||
|
->listen(ConfigureUserGambits::class, SetUserNicknameGambit::class),
|
||||||
|
|
||||||
|
new Extend\Locales(__DIR__ . '/resources/locale'),
|
||||||
|
];
|
1
extensions/nicknames/js/admin.js
Normal file
1
extensions/nicknames/js/admin.js
Normal file
|
@ -0,0 +1 @@
|
||||||
|
export * from './src/admin';
|
1
extensions/nicknames/js/forum.js
Normal file
1
extensions/nicknames/js/forum.js
Normal file
|
@ -0,0 +1 @@
|
||||||
|
export * from './src/forum';
|
4600
extensions/nicknames/js/package-lock.json
generated
Normal file
4600
extensions/nicknames/js/package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
14
extensions/nicknames/js/package.json
Normal file
14
extensions/nicknames/js/package.json
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
{
|
||||||
|
"name": "@flarum/nicknames",
|
||||||
|
"version": "0.0.0",
|
||||||
|
"private": true,
|
||||||
|
"dependencies": {
|
||||||
|
"flarum-webpack-config": "^0.1.0-beta.10",
|
||||||
|
"webpack": "^4.26.0",
|
||||||
|
"webpack-cli": "^3.0.7"
|
||||||
|
},
|
||||||
|
"scripts": {
|
||||||
|
"dev": "webpack --mode development --watch",
|
||||||
|
"build": "webpack --mode production"
|
||||||
|
}
|
||||||
|
}
|
3
extensions/nicknames/js/src/admin/index.js
Normal file
3
extensions/nicknames/js/src/admin/index.js
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
app.initializers.add('flarum/nickname', () => {
|
||||||
|
console.log('[flarum/nickname] Hello, admin!');
|
||||||
|
});
|
|
@ -0,0 +1,63 @@
|
||||||
|
import Modal from 'flarum/components/Modal';
|
||||||
|
import Button from 'flarum/components/Button';
|
||||||
|
import Stream from 'flarum/utils/Stream';
|
||||||
|
|
||||||
|
export default class NicknameModal extends Modal {
|
||||||
|
oninit(vnode) {
|
||||||
|
super.oninit(vnode);
|
||||||
|
this.nickname = Stream(app.session.user.displayName());
|
||||||
|
}
|
||||||
|
|
||||||
|
className() {
|
||||||
|
return 'NickameModal Modal--small';
|
||||||
|
}
|
||||||
|
|
||||||
|
title() {
|
||||||
|
return app.translator.trans('flarum-nicknames.forum.nickname.change');
|
||||||
|
}
|
||||||
|
|
||||||
|
content() {
|
||||||
|
return (
|
||||||
|
<div className="Modal-body">
|
||||||
|
<div className="Form Form--centered">
|
||||||
|
<div className="Form-group">
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
autocomplete="off"
|
||||||
|
name="nickname"
|
||||||
|
className="FormControl"
|
||||||
|
bidi={this.nickname}
|
||||||
|
disabled={this.loading} />
|
||||||
|
</div>
|
||||||
|
<div className="Form-group">
|
||||||
|
{Button.component({
|
||||||
|
className: 'Button Button--primary Button--block',
|
||||||
|
type: 'submit',
|
||||||
|
loading: this.loading,
|
||||||
|
}, app.translator.trans('flarum-nicknames.forum.nickname.submit_button'))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
onsubmit(e) {
|
||||||
|
e.preventDefault();
|
||||||
|
|
||||||
|
if (this.nickname() === app.session.user.displayName()) {
|
||||||
|
this.hide();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.loading = true;
|
||||||
|
|
||||||
|
app.session.user.save({ nickname: this.nickname() }, {
|
||||||
|
errorHandler: this.onerror.bind(this),
|
||||||
|
})
|
||||||
|
.then(this.hide.bind(this))
|
||||||
|
.catch(() => {
|
||||||
|
this.loading = false;
|
||||||
|
m.redraw();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
40
extensions/nicknames/js/src/forum/index.js
Normal file
40
extensions/nicknames/js/src/forum/index.js
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
import { extend } from 'flarum/extend';
|
||||||
|
import Button from 'flarum/components/Button';
|
||||||
|
import EditUserModal from 'flarum/components/EditUserModal';
|
||||||
|
import SettingsPage from 'flarum/components/SettingsPage';
|
||||||
|
import extractText from 'flarum/utils/extractText';
|
||||||
|
import Stream from 'flarum/utils/Stream';
|
||||||
|
import NickNameModal from './components/NicknameModal';
|
||||||
|
|
||||||
|
app.initializers.add('flarum/nicknames', () => {
|
||||||
|
extend(SettingsPage.prototype, 'accountItems', function (items) {
|
||||||
|
items.add('changeNickname',
|
||||||
|
<Button className="Button" onclick={() => app.modal.show(NickNameModal)}>
|
||||||
|
{app.translator.trans('flarum-nicknames.forum.settings.change_nickname_button')}
|
||||||
|
</Button>
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
extend(EditUserModal.prototype, 'oninit', function () {
|
||||||
|
this.nickname = Stream(this.attrs.user.displayName());
|
||||||
|
});
|
||||||
|
|
||||||
|
extend(EditUserModal.prototype, 'fields', function (items) {
|
||||||
|
items.add('nickname',
|
||||||
|
<div className="Form-group">
|
||||||
|
<label>{app.translator.trans('flarum-nicknames.forum.edit_user.password_heading')}</label>
|
||||||
|
<input className="FormControl"
|
||||||
|
placeholder={extractText(app.translator.trans('flarum-nicknames.forum.edit_user.password_text'))}
|
||||||
|
bidi={this.nickname} />
|
||||||
|
</div>, 100);
|
||||||
|
});
|
||||||
|
|
||||||
|
extend(EditUserModal.prototype, 'data', function (data) {
|
||||||
|
const user = this.attrs.user;
|
||||||
|
if (this.nickname() !== this.attrs.user.username()) {
|
||||||
|
data.nickname = this.nickname();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
});
|
1
extensions/nicknames/js/webpack.config.js
Normal file
1
extensions/nicknames/js/webpack.config.js
Normal file
|
@ -0,0 +1 @@
|
||||||
|
module.exports = require('flarum-webpack-config')();
|
0
extensions/nicknames/locale/.gitkeep
Normal file
0
extensions/nicknames/locale/.gitkeep
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Database\Schema\Builder;
|
||||||
|
|
||||||
|
return [
|
||||||
|
'up' => function(Builder $schema) {
|
||||||
|
if (!$schema->hasColumn('users', 'nickname')) {
|
||||||
|
$schema->table('users', function (Blueprint $table) use ($schema) {
|
||||||
|
$table->string('nickname', 150)->after('username')->index();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
'down' => function(Builder $schema) {
|
||||||
|
$schema->table('users', function (Blueprint $table) use ($schema) {
|
||||||
|
$table->dropColumn('nickname');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
];
|
21
extensions/nicknames/src/IdOnlyUserSlugDriver.php
Normal file
21
extensions/nicknames/src/IdOnlyUserSlugDriver.php
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
|
||||||
|
namespace Flarum\Nicknames;
|
||||||
|
|
||||||
|
use Flarum\Database\AbstractModel;
|
||||||
|
use Flarum\Http\SlugDriverInterface;
|
||||||
|
use Flarum\User\User;
|
||||||
|
|
||||||
|
class IdOnlyUserSlugDriver implements SlugDriverInterface {
|
||||||
|
|
||||||
|
public function toSlug(AbstractModel $instance): string
|
||||||
|
{
|
||||||
|
return $instance->id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function fromSlug(string $slug, User $actor): AbstractModel
|
||||||
|
{
|
||||||
|
return User::where('id', $slug)->whereVisibleTo($actor)->firstOrFail();
|
||||||
|
}
|
||||||
|
}
|
14
extensions/nicknames/src/NicknameDriver.php
Normal file
14
extensions/nicknames/src/NicknameDriver.php
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Flarum\Nicknames;
|
||||||
|
|
||||||
|
use Flarum\User\DisplayName\DriverInterface;
|
||||||
|
use Flarum\User\User;
|
||||||
|
|
||||||
|
class NicknameDriver implements DriverInterface {
|
||||||
|
|
||||||
|
public function displayName(User $user): string
|
||||||
|
{
|
||||||
|
return $user->nickname ? $user->nickname : $user->username;
|
||||||
|
}
|
||||||
|
}
|
57
extensions/nicknames/src/NicknameFullTextGambit.php
Normal file
57
extensions/nicknames/src/NicknameFullTextGambit.php
Normal file
|
@ -0,0 +1,57 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
|
||||||
|
namespace Flarum\Nicknames;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of Flarum.
|
||||||
|
*
|
||||||
|
* For detailed copyright and license information, please view the
|
||||||
|
* LICENSE file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
use Flarum\Search\AbstractSearch;
|
||||||
|
use Flarum\Search\GambitInterface;
|
||||||
|
use Flarum\User\UserRepository;
|
||||||
|
|
||||||
|
|
||||||
|
class NicknameFullTextGambit implements GambitInterface
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var UserRepository
|
||||||
|
*/
|
||||||
|
protected $users;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param \Flarum\User\UserRepository $users
|
||||||
|
*/
|
||||||
|
public function __construct(UserRepository $users)
|
||||||
|
{
|
||||||
|
$this->users = $users;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param $searchValue
|
||||||
|
* @return \Illuminate\Database\Eloquent\Builder
|
||||||
|
*/
|
||||||
|
private function getUserSearchSubQuery($searchValue)
|
||||||
|
{
|
||||||
|
return $this->users
|
||||||
|
->query()
|
||||||
|
->select('id')
|
||||||
|
->where('username', 'like', "{$searchValue}%")
|
||||||
|
->orWhere('nickname', 'like',"{$searchValue}%");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function apply(AbstractSearch $search, $searchValue)
|
||||||
|
{
|
||||||
|
$search->getQuery()
|
||||||
|
->whereIn(
|
||||||
|
'id',
|
||||||
|
$this->getUserSearchSubQuery($searchValue)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
27
extensions/nicknames/src/SaveNicknameToDatabase.php
Normal file
27
extensions/nicknames/src/SaveNicknameToDatabase.php
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Flarum\Nicknames;
|
||||||
|
|
||||||
|
use Flarum\User\Event\Saving;
|
||||||
|
use Illuminate\Support\Arr;
|
||||||
|
|
||||||
|
class SaveNicknameToDatabase {
|
||||||
|
public function handle(Saving $event)
|
||||||
|
{
|
||||||
|
$user = $event->user;
|
||||||
|
$data = $event->data;
|
||||||
|
$actor = $event->actor;
|
||||||
|
|
||||||
|
$isSelf = $actor->id === $user->id;
|
||||||
|
$canEdit = $actor->can('edit', $user);
|
||||||
|
$attributes = Arr::get($data, 'attributes', []);
|
||||||
|
|
||||||
|
if (isset($attributes['nickname'])) {
|
||||||
|
if (!$isSelf) {
|
||||||
|
$actor->assertPermission($canEdit);
|
||||||
|
}
|
||||||
|
$user->nickname = $attributes['nickname'];
|
||||||
|
$user->save();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
13
extensions/nicknames/src/SetUserNicknameGambit.php
Normal file
13
extensions/nicknames/src/SetUserNicknameGambit.php
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
|
||||||
|
namespace Flarum\Nicknames;
|
||||||
|
|
||||||
|
use Flarum\Event\ConfigureUserGambits;
|
||||||
|
|
||||||
|
class SetUserNicknameGambit
|
||||||
|
{
|
||||||
|
public function handle(ConfigureUserGambits $event) {
|
||||||
|
$event->gambits->setFulltextGambit(NicknameFullTextGambit::class);
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user