Skip to content

Commit

Permalink
Add team creation page
Browse files Browse the repository at this point in the history
  • Loading branch information
nanaya committed Feb 3, 2025
1 parent 88de194 commit 7736b6d
Show file tree
Hide file tree
Showing 12 changed files with 309 additions and 22 deletions.
35 changes: 35 additions & 0 deletions app/Http/Controllers/TeamsController.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

namespace App\Http\Controllers;

use App\Exceptions\ModelNotSavedException;
use App\Models\Team;
use App\Transformers\UserCompactTransformer;
use Symfony\Component\HttpFoundation\Response;
Expand All @@ -19,6 +20,19 @@ public function __construct()
$this->middleware('auth', ['only' => ['part']]);
}

public function create(): Response
{
$currentUser = \Auth::user();
$teamId = $currentUser?->team?->getKey() ?? $currentUser?->teamApplication?->team_id;
if ($teamId !== null) {
return ujs_redirect(route('teams.show', $teamId));
}

return ext_view('teams.create', [
'team' => new Team(),
]);
}

public function destroy(string $id): Response
{
$team = Team::findOrFail($id);
Expand Down Expand Up @@ -60,6 +74,27 @@ public function show(string $id): Response
return ext_view('teams.show', compact('team'));
}

public function store(): Reponse
{
priv_check('TeamStore')->ensureCan();

$params = get_params(\Request::all(), 'team', [
'name',
'short_name',
]);

$team = new Team([...$params, 'leader_id' => \Auth::user()->getKey()]);
try {
$team->saveOrExplode();
} catch (ModelNotSavedException) {
return ext_view('teams.create', compact('team'), status: 422);
}

\Session::flash('popup', osu_trans('teams.store.saved'));

return ujs_redirect(route('teams.show', $team));
}

public function update(string $id): Response
{
$team = Team::findOrFail($id);
Expand Down
18 changes: 13 additions & 5 deletions app/Libraries/UsernameValidation.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,17 @@

class UsernameValidation
{
public static function allowedName(string $username): bool
{
foreach (model_pluck(DB::table('phpbb_disallow'), 'disallow_username') as $check) {
if (preg_match('#^'.str_replace('%', '.*?', preg_quote($check, '#')).'$#i', $username)) {
return false;
}
}

return true;
}

public static function validateAvailability(string $username): ValidationErrors
{
$errors = new ValidationErrors('user');
Expand Down Expand Up @@ -72,11 +83,8 @@ public static function validateUsername($username)
$errors->add('username', '.username_no_space_userscore_mix');
}

foreach (model_pluck(DB::table('phpbb_disallow'), 'disallow_username') as $check) {
if (preg_match('#^'.str_replace('%', '.*?', preg_quote($check, '#')).'$#i', $username)) {
$errors->add('username', '.username_not_allowed');
break;
}
if (!static::allowedName($username)) {
$errors->add('username', '.username_not_allowed');
}

return $errors;
Expand Down
29 changes: 29 additions & 0 deletions app/Models/Team.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

use App\Libraries\BBCodeForDB;
use App\Libraries\Uploader;
use App\Libraries\UsernameValidation;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\HasMany;

Expand Down Expand Up @@ -106,6 +107,20 @@ public function isValid(): bool
{
$this->validationErrors()->reset();

$wordFilters = app('chat-filters');
foreach (['name', 'short_name'] as $field) {
$value = presence($this->$field);
if ($value === null) {
$this->validationErrors()->add($field, 'required');
} elseif ($this->isDirty($field)) {
if (!$wordFilters->isClean($value) || !UsernameValidation::allowedName($value)) {
$this->validationErrors()->add($field, '.word_not_allowed');
} elseif (static::whereNot('id', $this->getKey())->where($field, $value)->exists()) {
$this->validationErrors()->add($field, '.used');
}
}
}

if ($this->isDirty('url')) {
$url = $this->url;
if ($url !== null && !is_http($url)) {
Expand All @@ -131,4 +146,18 @@ public function logo(): Uploader
['image' => ['maxDimensions' => [512, 256]]],
);
}

public function save(array $options = [])
{
if (!$this->isValid()) {
return false;
}

return parent::save($options);
}

public function validationErrorsTranslationPrefix(): string
{
return 'team';
}
}
61 changes: 45 additions & 16 deletions app/Singletons/ChatFilters.php
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,30 @@ private static function combinedFilterRegex($filters): string
return "/{$regex}/iu";
}

public function isClean(string $text): bool
{
$filters = $this->filterRegexps();

foreach ($filters['non_whitespace_delimited_replaces'] as $search => $_replacement) {
if (stripos($text, $search) !== false) {
return false;
}
}

$patterns = [
$filters['block_regex'] ?? null,
...array_keys($filters['whitespace_delimited_replaces']),
];

foreach ($patterns as $pattern) {
if ($pattern !== null && preg_match($pattern, $text)) {
return false;
}
}

return true;
}

/**
* Applies all active chat filters to the provided text.
* @param string $text The text to filter.
Expand All @@ -38,7 +62,27 @@ private static function combinedFilterRegex($filters): string
*/
public function filter(string $text): string
{
$filters = $this->memoize(__FUNCTION__, function () {
$filters = $this->filterRegexps();

if (isset($filters['block_regex']) && preg_match($filters['block_regex'], $text)) {
throw new ContentModerationException();
}

$text = str_ireplace(
array_keys($filters['non_whitespace_delimited_replaces']),
array_values($filters['non_whitespace_delimited_replaces']),
$text
);
return preg_replace(
array_keys($filters['whitespace_delimited_replaces']),
array_values($filters['whitespace_delimited_replaces']),
$text
);
}

private function filterRegexps(): array
{
return $this->memoize(__FUNCTION__, function () {
$ret = [];

$allFilters = ChatFilter::all();
Expand All @@ -63,20 +107,5 @@ public function filter(string $text): string

return $ret;
});

if (isset($filters['block_regex']) && preg_match($filters['block_regex'], $text)) {
throw new ContentModerationException();
}

$text = str_ireplace(
array_keys($filters['non_whitespace_delimited_replaces']),
array_values($filters['non_whitespace_delimited_replaces']),
$text
);
return preg_replace(
array_keys($filters['whitespace_delimited_replaces']),
array_values($filters['whitespace_delimited_replaces']),
$text
);
}
}
17 changes: 17 additions & 0 deletions app/Singletons/OsuAuthorize.php
Original file line number Diff line number Diff line change
Expand Up @@ -1921,6 +1921,23 @@ public function checkTeamPart(?User $user, Team $team): ?string
return 'ok';
}

public function checkTeamStore(?User $user): ?string
{
$this->ensureLoggedIn($user);
$this->ensureCleanRecord($user);
$this->ensureHasPlayed($user);

if ($user->team !== null) {
return 'team.store.in_team';
}

if ($user->teamApplication !== null) {
return 'team.store.applying';
}

return 'ok';
}

public function checkTeamUpdate(?User $user, Team $team): ?string
{
$this->ensureLoggedIn($user);
Expand Down
9 changes: 9 additions & 0 deletions resources/css/bem/team-settings.less
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,12 @@
border-radius: @border-radius-large;
}

&__errors {
color: hsl(var(--hsl-red-1));
margin-top: 1em;
padding: 0 0 0 2em;
}

&__help {
color: hsl(var(--hsl-c2));
font-size: @font-size--normal;
Expand All @@ -34,6 +40,7 @@
}

&__item {
--align-items-desktop: start;
--grid-rows: none;
--grid-rows-desktop: none;
--grid-columns: 1fr;
Expand All @@ -46,13 +53,15 @@
@media @desktop {
--grid-columns: var(--grid-columns-desktop);
--grid-rows: var(--grid-rows-desktop);
align-items: var(--align-items-desktop);
}

&--buttons {
--grid-columns-desktop: 1fr auto;
}

&--description {
--align-items-desktop: stretch;
--grid-columns-desktop: 1fr 1fr;
--grid-rows: calc(var(--vh, 1vh) * 70) auto;
}
Expand Down
10 changes: 10 additions & 0 deletions resources/lang/en/model_validation.php
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,16 @@
],
],

'team' => [
'used' => 'This :attribute choice is already used.',
'word_not_allowed' => 'This :attribute choice is not allowed.',

'attributes' => [
'name' => 'name',
'short_name' => 'short name',
],
],

'user' => [
'contains_username' => 'Password may not contain username.',
'email_already_used' => 'Email address already used.',
Expand Down
1 change: 1 addition & 0 deletions resources/lang/en/page_title.php
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,7 @@
],
'teams_controller' => [
'_' => 'teams',
'create' => 'create team',
'show' => 'team info',
],
'tournaments_controller' => [
Expand Down
17 changes: 17 additions & 0 deletions resources/lang/en/teams.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,23 @@
// See the LICENCE file in the repository root for full licence text.

return [
'create' => [
'submit' => 'Create Team',

'form' => [
'name' => 'Team Name',
'name_help' => 'Your team name. No changey',
'short_name' => 'Short Name',
'short_name_help' => 'What',
'title' => "Let's set up a new team",
],

'intro' => [
'description' => "Play together with friends; existing or new. You're not currently in a team. Join an existing team by visiting their team page or create your own team from this page.",
'title' => 'Team!',
],
],

'destroy' => [
'ok' => 'Team removed',
],
Expand Down
Loading

0 comments on commit 7736b6d

Please sign in to comment.