Skip to content

Commit

Permalink
add stubs and install command
Browse files Browse the repository at this point in the history
  • Loading branch information
inmanturbo committed Feb 23, 2024
1 parent de9dcef commit 09aaec1
Show file tree
Hide file tree
Showing 38 changed files with 1,425 additions and 4 deletions.
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,9 @@ git checkout -b dev-package
hack hack hack
```bash
build.sh dev-package dev-package/one-app/stub
```
## Installation
Expand Down
6 changes: 5 additions & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,13 @@
"php": "^8.2",
"envor/laravel-datastore": "^1.2",
"envor/laravel-schema-macros": "^1.1",
"envor/platform": "^1.3",
"envor/platform": "^1.5",
"illuminate/contracts": "^11.0",
"inmanturbo/turbohx": "^1.1",
"laravel/jetstream": "^5.0@dev",
"laravel/sanctum": "^4.0@dev",
"laravel/tinker": "^2.9",
"livewire/livewire": "^3.4",
"livewire/volt": "^1.6",
"spatie/laravel-package-tools": "^1.16.2"
},
Expand Down
50 changes: 47 additions & 3 deletions src/Commands/OneAppCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,61 @@
namespace Envor\OneApp\Commands;

use Illuminate\Console\Command;
use Illuminate\Support\Facades\File;

class OneAppCommand extends Command
{
public $signature = 'one-app';
public $signature = 'one-app:install';

public $description = 'My command';

public function handle(): int
{
$this->comment('All done');
$this->info('Installing Jetstream...');

return self::SUCCESS;
$this->callSilent('jetstream:install', [
'stack' => 'livewire',
'--teams' => true,
'--dark' => true,
'--api' => true,
'--pest' => true,
'--no-interaction' => true,
]);

$this->info('Installing folio...');

$this->callSilent('folio:install');

$this->info('Installing volt');

$this->callSilent('volt:install');

$this->info('Publishing Stubs...');

$this->copyFiles();

$this->info('One App installed');

return 0;
}

protected function copyFiles()
{
$this->info('Copying files...');

$sourceDir = realpath(__DIR__.'/../../stubs/');
$destinationDir = base_path();

$files = File::allFiles($sourceDir);

foreach ($files as $file) {
$destinationFilePath = $destinationDir.'/'.$file->getRelativePathname();
File::ensureDirectoryExists(dirname($destinationFilePath));
File::copy($sourceFile = $file->getPathname(), $destinationFilePath);
// check verbosity
if ($this->output->isVerbose()) {
$this->line('<info>Copied</info> '.$sourceFile . ' <info>to</info> ' . $destinationFilePath);
}
}
}
}
66 changes: 66 additions & 0 deletions stubs/app/Actions/Fortify/CreateNewUser.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
<?php

namespace App\Actions\Fortify;

use App\Models\Team;
use App\Models\User;
use Envor\Platform\Concerns\UsesPlatformConnection;
use Illuminate\Database\DatabaseManager;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Validator;
use Laravel\Fortify\Contracts\CreatesNewUsers;
use Laravel\Jetstream\Jetstream;

class CreateNewUser implements CreatesNewUsers
{
use PasswordValidationRules;
use UsesPlatformConnection;

/**
* Create a newly registered user.
*
* @param array<string, string> $input
*/
public function create(array $input): User
{
return app(DatabaseManager::class)->usingConnection($this->getConnectionName(), fn () => $this->execute($input));
}

/**
* Create a newly registered user.
*
* @param array<string, string> $input
*/
protected function execute(array $input): User
{
Validator::make($input, [
'name' => ['required', 'string', 'max:255'],
'email' => ['required', 'string', 'email', 'max:255', 'unique:users'],
'password' => $this->passwordRules(),
'terms' => Jetstream::hasTermsAndPrivacyPolicyFeature() ? ['accepted', 'required'] : '',
])->validate();

return DB::transaction(function () use ($input) {
return tap(User::create([
'name' => $input['name'],
'email' => $input['email'],
'password' => Hash::make($input['password']),
]), function (User $user) {
$this->createTeam($user);
});
});
}

/**
* Create a personal team for the user.
*/
protected function createTeam(User $user): void
{
$user->ownedTeams()->save(Team::forceCreate([
'user_id' => $user->id,
'name' => explode(' ', $user->name, 2)[0]."'s Team",
'personal_team' => true,
]));
}
}
69 changes: 69 additions & 0 deletions stubs/app/Actions/Fortify/UpdateUserProfileInformation.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
<?php

namespace App\Actions\Fortify;

use App\Models\User;
use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Database\DatabaseManager;
use Illuminate\Support\Facades\Validator;
use Illuminate\Validation\Rule;
use Laravel\Fortify\Contracts\UpdatesUserProfileInformation;

class UpdateUserProfileInformation implements UpdatesUserProfileInformation
{
use \Envor\Platform\Concerns\UsesPlatformConnection;

/**
* Validate and update the given user's profile information.
*
* @param array<string, mixed> $input
*/
public function update(User $user, array $input): void
{
app(DatabaseManager::class)->usingConnection($this->getConnectionName(), fn () => $this->execute($user, $input));
}

/**
* Validate and update the given user's profile information.
*
* @param array<string, mixed> $input
*/
protected function execute(User $user, array $input): void
{
Validator::make($input, [
'name' => ['required', 'string', 'max:255'],
'email' => ['required', 'email', 'max:255', Rule::unique('users')->ignore($user->id)],
'photo' => ['nullable', 'mimes:jpg,jpeg,png', 'max:1024'],
])->validateWithBag('updateProfileInformation');

if (isset($input['photo'])) {
$user->updateProfilePhoto($input['photo']);
}

if ($input['email'] !== $user->email &&
$user instanceof MustVerifyEmail) {
$this->updateVerifiedUser($user, $input);
} else {
$user->forceFill([
'name' => $input['name'],
'email' => $input['email'],
])->save();
}
}

/**
* Update the given verified user's profile information.
*
* @param array<string, string> $input
*/
protected function updateVerifiedUser(User $user, array $input): void
{
$user->forceFill([
'name' => $input['name'],
'email' => $input['email'],
'email_verified_at' => null,
])->save();

$user->sendEmailVerificationNotification();
}
}
81 changes: 81 additions & 0 deletions stubs/app/Actions/Jetstream/AddTeamMember.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
<?php

namespace App\Actions\Jetstream;

use App\Models\Team;
use App\Models\User;
use Closure;
use Illuminate\Support\Facades\Gate;
use Illuminate\Support\Facades\Validator;
use Laravel\Jetstream\Contracts\AddsTeamMembers;
use Laravel\Jetstream\Events\AddingTeamMember;
use Laravel\Jetstream\Events\TeamMemberAdded;
use Laravel\Jetstream\Jetstream;
use Laravel\Jetstream\Rules\Role;

class AddTeamMember implements AddsTeamMembers
{
/**
* Add a new team member to the given team.
*/
public function add(User $user, Team $team, string $email, ?string $role = null): void
{
Gate::forUser($user)->authorize('addTeamMember', $team);

$this->validate($team, $email, $role);

$newTeamMember = Jetstream::findUserByEmailOrFail($email);

AddingTeamMember::dispatch($team, $newTeamMember);

$team->users()->attach(
$newTeamMember, ['role' => $role]
);

TeamMemberAdded::dispatch($team, $newTeamMember);
}

/**
* Validate the add member operation.
*/
protected function validate(Team $team, string $email, ?string $role): void
{
Validator::make([
'email' => $email,
'role' => $role,
], $this->rules(), [
'email.exists' => __('We were unable to find a registered user with this email address.'),
])->after(
$this->ensureUserIsNotAlreadyOnTeam($team, $email)
)->validateWithBag('addTeamMember');
}

/**
* Get the validation rules for adding a team member.
*
* @return array<string, \Illuminate\Contracts\Validation\Rule|array|string>
*/
protected function rules(): array
{
return array_filter([
'email' => ['required', 'email', 'exists:users'],
'role' => Jetstream::hasRoles()
? ['required', 'string', new Role]
: null,
]);
}

/**
* Ensure that the user is not already on the team.
*/
protected function ensureUserIsNotAlreadyOnTeam(Team $team, string $email): Closure
{
return function ($validator) use ($team, $email) {
$validator->errors()->addIf(
$team->hasUserWithEmail($email),
'email',
__('This user already belongs to the team.')
);
};
}
}
Loading

0 comments on commit 09aaec1

Please sign in to comment.