first commit
This commit is contained in:
13
app/Http/Controllers/AdminDashboardController.php
Normal file
13
app/Http/Controllers/AdminDashboardController.php
Normal file
@@ -0,0 +1,13 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use Inertia\Inertia;
|
||||
|
||||
class AdminDashboardController extends Controller
|
||||
{
|
||||
public function index()
|
||||
{
|
||||
return Inertia::render('admin/dashboard');
|
||||
}
|
||||
}
|
||||
51
app/Http/Controllers/Auth/AuthenticatedSessionController.php
Normal file
51
app/Http/Controllers/Auth/AuthenticatedSessionController.php
Normal file
@@ -0,0 +1,51 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Auth;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Http\Requests\Auth\LoginRequest;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Support\Facades\Route;
|
||||
use Inertia\Inertia;
|
||||
use Inertia\Response;
|
||||
|
||||
class AuthenticatedSessionController extends Controller
|
||||
{
|
||||
/**
|
||||
* Show the login page.
|
||||
*/
|
||||
public function create(Request $request): Response
|
||||
{
|
||||
return Inertia::render('auth/login', [
|
||||
'canResetPassword' => Route::has('password.request'),
|
||||
'status' => $request->session()->get('status'),
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle an incoming authentication request.
|
||||
*/
|
||||
public function store(LoginRequest $request): RedirectResponse
|
||||
{
|
||||
$request->authenticate();
|
||||
|
||||
$request->session()->regenerate();
|
||||
|
||||
return redirect()->intended(route('dashboard', absolute: false));
|
||||
}
|
||||
|
||||
/**
|
||||
* Destroy an authenticated session.
|
||||
*/
|
||||
public function destroy(Request $request): RedirectResponse
|
||||
{
|
||||
Auth::guard('web')->logout();
|
||||
|
||||
$request->session()->invalidate();
|
||||
$request->session()->regenerateToken();
|
||||
|
||||
return redirect('/');
|
||||
}
|
||||
}
|
||||
41
app/Http/Controllers/Auth/ConfirmablePasswordController.php
Normal file
41
app/Http/Controllers/Auth/ConfirmablePasswordController.php
Normal file
@@ -0,0 +1,41 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Auth;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Validation\ValidationException;
|
||||
use Inertia\Inertia;
|
||||
use Inertia\Response;
|
||||
|
||||
class ConfirmablePasswordController extends Controller
|
||||
{
|
||||
/**
|
||||
* Show the confirm password page.
|
||||
*/
|
||||
public function show(): Response
|
||||
{
|
||||
return Inertia::render('auth/confirm-password');
|
||||
}
|
||||
|
||||
/**
|
||||
* Confirm the user's password.
|
||||
*/
|
||||
public function store(Request $request): RedirectResponse
|
||||
{
|
||||
if (! Auth::guard('web')->validate([
|
||||
'email' => $request->user()->email,
|
||||
'password' => $request->password,
|
||||
])) {
|
||||
throw ValidationException::withMessages([
|
||||
'password' => __('auth.password'),
|
||||
]);
|
||||
}
|
||||
|
||||
$request->session()->put('auth.password_confirmed_at', time());
|
||||
|
||||
return redirect()->intended(route('dashboard', absolute: false));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Auth;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class EmailVerificationNotificationController extends Controller
|
||||
{
|
||||
/**
|
||||
* Send a new email verification notification.
|
||||
*/
|
||||
public function store(Request $request): RedirectResponse
|
||||
{
|
||||
if ($request->user()->hasVerifiedEmail()) {
|
||||
return redirect()->intended(route('dashboard', absolute: false));
|
||||
}
|
||||
|
||||
$request->user()->sendEmailVerificationNotification();
|
||||
|
||||
return back()->with('status', 'verification-link-sent');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Auth;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Inertia\Inertia;
|
||||
use Inertia\Response;
|
||||
|
||||
class EmailVerificationPromptController extends Controller
|
||||
{
|
||||
/**
|
||||
* Show the email verification prompt page.
|
||||
*/
|
||||
public function __invoke(Request $request): Response|RedirectResponse
|
||||
{
|
||||
return $request->user()->hasVerifiedEmail()
|
||||
? redirect()->intended(route('dashboard', absolute: false))
|
||||
: Inertia::render('auth/verify-email', ['status' => $request->session()->get('status')]);
|
||||
}
|
||||
}
|
||||
69
app/Http/Controllers/Auth/NewPasswordController.php
Normal file
69
app/Http/Controllers/Auth/NewPasswordController.php
Normal file
@@ -0,0 +1,69 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Auth;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use Illuminate\Auth\Events\PasswordReset;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Hash;
|
||||
use Illuminate\Support\Facades\Password;
|
||||
use Illuminate\Support\Str;
|
||||
use Illuminate\Validation\Rules;
|
||||
use Illuminate\Validation\ValidationException;
|
||||
use Inertia\Inertia;
|
||||
use Inertia\Response;
|
||||
|
||||
class NewPasswordController extends Controller
|
||||
{
|
||||
/**
|
||||
* Show the password reset page.
|
||||
*/
|
||||
public function create(Request $request): Response
|
||||
{
|
||||
return Inertia::render('auth/reset-password', [
|
||||
'email' => $request->email,
|
||||
'token' => $request->route('token'),
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle an incoming new password request.
|
||||
*
|
||||
* @throws \Illuminate\Validation\ValidationException
|
||||
*/
|
||||
public function store(Request $request): RedirectResponse
|
||||
{
|
||||
$request->validate([
|
||||
'token' => 'required',
|
||||
'email' => 'required|email',
|
||||
'password' => ['required', 'confirmed', Rules\Password::defaults()],
|
||||
]);
|
||||
|
||||
// Here we will attempt to reset the user's password. If it is successful we
|
||||
// will update the password on an actual user model and persist it to the
|
||||
// database. Otherwise we will parse the error and return the response.
|
||||
$status = Password::reset(
|
||||
$request->only('email', 'password', 'password_confirmation', 'token'),
|
||||
function ($user) use ($request) {
|
||||
$user->forceFill([
|
||||
'password' => Hash::make($request->password),
|
||||
'remember_token' => Str::random(60),
|
||||
])->save();
|
||||
|
||||
event(new PasswordReset($user));
|
||||
}
|
||||
);
|
||||
|
||||
// If the password was successfully reset, we will redirect the user back to
|
||||
// the application's home authenticated view. If there is an error we can
|
||||
// redirect them back to where they came from with their error message.
|
||||
if ($status == Password::PasswordReset) {
|
||||
return to_route('login')->with('status', __($status));
|
||||
}
|
||||
|
||||
throw ValidationException::withMessages([
|
||||
'email' => [__($status)],
|
||||
]);
|
||||
}
|
||||
}
|
||||
41
app/Http/Controllers/Auth/PasswordResetLinkController.php
Normal file
41
app/Http/Controllers/Auth/PasswordResetLinkController.php
Normal file
@@ -0,0 +1,41 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Auth;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Password;
|
||||
use Inertia\Inertia;
|
||||
use Inertia\Response;
|
||||
|
||||
class PasswordResetLinkController extends Controller
|
||||
{
|
||||
/**
|
||||
* Show the password reset link request page.
|
||||
*/
|
||||
public function create(Request $request): Response
|
||||
{
|
||||
return Inertia::render('auth/forgot-password', [
|
||||
'status' => $request->session()->get('status'),
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle an incoming password reset link request.
|
||||
*
|
||||
* @throws \Illuminate\Validation\ValidationException
|
||||
*/
|
||||
public function store(Request $request): RedirectResponse
|
||||
{
|
||||
$request->validate([
|
||||
'email' => 'required|email',
|
||||
]);
|
||||
|
||||
Password::sendResetLink(
|
||||
$request->only('email')
|
||||
);
|
||||
|
||||
return back()->with('status', __('A reset link will be sent if the account exists.'));
|
||||
}
|
||||
}
|
||||
51
app/Http/Controllers/Auth/RegisteredUserController.php
Normal file
51
app/Http/Controllers/Auth/RegisteredUserController.php
Normal file
@@ -0,0 +1,51 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Auth;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\User;
|
||||
use Illuminate\Auth\Events\Registered;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Support\Facades\Hash;
|
||||
use Illuminate\Validation\Rules;
|
||||
use Inertia\Inertia;
|
||||
use Inertia\Response;
|
||||
|
||||
class RegisteredUserController extends Controller
|
||||
{
|
||||
/**
|
||||
* Show the registration page.
|
||||
*/
|
||||
public function create(): Response
|
||||
{
|
||||
return Inertia::render('auth/register');
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle an incoming registration request.
|
||||
*
|
||||
* @throws \Illuminate\Validation\ValidationException
|
||||
*/
|
||||
public function store(Request $request): RedirectResponse
|
||||
{
|
||||
$request->validate([
|
||||
'name' => 'required|string|max:255',
|
||||
'email' => 'required|string|lowercase|email|max:255|unique:'.User::class,
|
||||
'password' => ['required', 'confirmed', Rules\Password::defaults()],
|
||||
]);
|
||||
|
||||
$user = User::create([
|
||||
'name' => $request->name,
|
||||
'email' => $request->email,
|
||||
'password' => Hash::make($request->password),
|
||||
]);
|
||||
|
||||
event(new Registered($user));
|
||||
|
||||
Auth::login($user);
|
||||
|
||||
return to_route('dashboard');
|
||||
}
|
||||
}
|
||||
137
app/Http/Controllers/Auth/SanctumAuthController.php
Normal file
137
app/Http/Controllers/Auth/SanctumAuthController.php
Normal file
@@ -0,0 +1,137 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Auth;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\User;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Support\Facades\Hash;
|
||||
use Illuminate\Validation\Rules\Password;
|
||||
use Illuminate\Validation\ValidationException;
|
||||
|
||||
class SanctumAuthController extends Controller
|
||||
{
|
||||
/**
|
||||
* Register a new user and return a token
|
||||
*
|
||||
* @return \Illuminate\Http\JsonResponse
|
||||
*/
|
||||
public function register(Request $request)
|
||||
{
|
||||
try {
|
||||
$request->validate([
|
||||
'email' => ['required', 'string', 'email', 'max:255', 'unique:users'],
|
||||
'password' => ['required', 'confirmed', Password::defaults()],
|
||||
]);
|
||||
|
||||
$user = User::create([
|
||||
'email' => $request->email,
|
||||
'password' => Hash::make($request->password),
|
||||
]);
|
||||
|
||||
$token = $user->createToken('auth_token')->plainTextToken;
|
||||
|
||||
return response()->json([
|
||||
'success' => [
|
||||
'data' => [
|
||||
'token' => $token,
|
||||
'user' => $user,
|
||||
],
|
||||
'message' => 'Registration completed successfully.',
|
||||
],
|
||||
], 201);
|
||||
} catch (ValidationException $e) {
|
||||
return response()->json([
|
||||
'error' => [
|
||||
'data' => $e->errors(),
|
||||
'message' => 'Please review your inputs before submitting again.',
|
||||
],
|
||||
], 422);
|
||||
} catch (\Exception $e) {
|
||||
return response()->json([
|
||||
'error' => [
|
||||
'data' => [],
|
||||
'message' => $e->getMessage(),
|
||||
],
|
||||
], 500);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Login a user and return a token
|
||||
*
|
||||
* @return \Illuminate\Http\JsonResponse
|
||||
*/
|
||||
public function login(Request $request)
|
||||
{
|
||||
try {
|
||||
$request->validate([
|
||||
'email' => ['required', 'string', 'email'],
|
||||
'password' => ['required', 'string'],
|
||||
]);
|
||||
|
||||
if (! Auth::attempt($request->only('email', 'password'))) {
|
||||
return response()->json([
|
||||
'error' => [
|
||||
'data' => [],
|
||||
'message' => 'Invalid credentials provided.',
|
||||
],
|
||||
], 401);
|
||||
}
|
||||
|
||||
$user = User::where('email', $request->email)->firstOrFail();
|
||||
$token = $user->createToken('auth_token')->plainTextToken;
|
||||
|
||||
return response()->json([
|
||||
'success' => [
|
||||
'data' => [
|
||||
'token' => $token,
|
||||
'user' => $user,
|
||||
],
|
||||
'message' => 'Authentication successful.',
|
||||
],
|
||||
]);
|
||||
} catch (ValidationException $e) {
|
||||
return response()->json([
|
||||
'error' => [
|
||||
'data' => $e->errors(),
|
||||
'message' => 'Please review your inputs before submitting again.',
|
||||
],
|
||||
], 422);
|
||||
} catch (\Exception $e) {
|
||||
return response()->json([
|
||||
'error' => [
|
||||
'data' => [],
|
||||
'message' => $e->getMessage(),
|
||||
],
|
||||
], 500);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Logout the user (revoke the token)
|
||||
*
|
||||
* @return \Illuminate\Http\JsonResponse
|
||||
*/
|
||||
public function logout(Request $request)
|
||||
{
|
||||
try {
|
||||
$request->user()->currentAccessToken()->delete();
|
||||
|
||||
return response()->json([
|
||||
'success' => [
|
||||
'data' => [],
|
||||
'message' => 'Successfully signed out.',
|
||||
],
|
||||
]);
|
||||
} catch (\Exception $e) {
|
||||
return response()->json([
|
||||
'error' => [
|
||||
'data' => [],
|
||||
'message' => $e->getMessage(),
|
||||
],
|
||||
], 500);
|
||||
}
|
||||
}
|
||||
}
|
||||
30
app/Http/Controllers/Auth/VerifyEmailController.php
Normal file
30
app/Http/Controllers/Auth/VerifyEmailController.php
Normal file
@@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Auth;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use Illuminate\Auth\Events\Verified;
|
||||
use Illuminate\Foundation\Auth\EmailVerificationRequest;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
|
||||
class VerifyEmailController extends Controller
|
||||
{
|
||||
/**
|
||||
* Mark the authenticated user's email address as verified.
|
||||
*/
|
||||
public function __invoke(EmailVerificationRequest $request): RedirectResponse
|
||||
{
|
||||
if ($request->user()->hasVerifiedEmail()) {
|
||||
return redirect()->intended(route('dashboard', absolute: false).'?verified=1');
|
||||
}
|
||||
|
||||
if ($request->user()->markEmailAsVerified()) {
|
||||
/** @var \Illuminate\Contracts\Auth\MustVerifyEmail $user */
|
||||
$user = $request->user();
|
||||
|
||||
event(new Verified($user));
|
||||
}
|
||||
|
||||
return redirect()->intended(route('dashboard', absolute: false).'?verified=1');
|
||||
}
|
||||
}
|
||||
8
app/Http/Controllers/Controller.php
Normal file
8
app/Http/Controllers/Controller.php
Normal file
@@ -0,0 +1,8 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
abstract class Controller
|
||||
{
|
||||
//
|
||||
}
|
||||
18
app/Http/Controllers/FrontHomeController.php
Normal file
18
app/Http/Controllers/FrontHomeController.php
Normal file
@@ -0,0 +1,18 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App;
|
||||
use Inertia\Inertia;
|
||||
|
||||
class FrontHomeController extends Controller
|
||||
{
|
||||
public function index()
|
||||
{
|
||||
if (App::environment('local')) {
|
||||
return Inertia::render('welcome');
|
||||
}
|
||||
|
||||
return Inertia::render('comingsoon');
|
||||
}
|
||||
}
|
||||
377
app/Http/Controllers/RenderController.php
Normal file
377
app/Http/Controllers/RenderController.php
Normal file
@@ -0,0 +1,377 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Helpers\FirstParty\Render\RenderConstants;
|
||||
use App\Models\User;
|
||||
use App\Models\Video;
|
||||
use App\Models\VideoCaption;
|
||||
use App\Models\VideoElement;
|
||||
use App\Models\VideoRender;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Support\Facades\Http;
|
||||
use Illuminate\Support\Facades\Validator;
|
||||
use stdClass;
|
||||
use Str;
|
||||
|
||||
class RenderController extends Controller
|
||||
{
|
||||
public function getVideoElements(Request $request, string $uuid)
|
||||
{
|
||||
if (! Str::isUuid($uuid)) {
|
||||
return response()->json([
|
||||
'error' => [
|
||||
'message' => 'Invalid UUID format.',
|
||||
],
|
||||
], 400);
|
||||
}
|
||||
|
||||
$video = Video::with('video_elements')->where('uuid', $uuid)->first();
|
||||
|
||||
if (! $video) {
|
||||
return response()->json([
|
||||
'error' => [
|
||||
'message' => 'Video not found.',
|
||||
],
|
||||
]);
|
||||
}
|
||||
|
||||
return response()->json((object) [
|
||||
'success' => [
|
||||
'data' => [
|
||||
'video_elements' => $video->video_elements,
|
||||
],
|
||||
],
|
||||
]);
|
||||
|
||||
if (! $video_render) {
|
||||
return response()->json([
|
||||
'error' => [
|
||||
'message' => 'Video render not found.',
|
||||
],
|
||||
]);
|
||||
}
|
||||
|
||||
$video = Video::where('id', $video_render->video_id)->first();
|
||||
|
||||
if (! $video) {
|
||||
return response()->json([
|
||||
'error' => [
|
||||
'message' => 'Video not found.',
|
||||
],
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
public function startRender(Request $request)
|
||||
{
|
||||
|
||||
$video_render_request = array_to_object_2025($request->all());
|
||||
|
||||
$video_render_action = $this->saveUserVideoRenderRequest(Auth::user(), $video_render_request);
|
||||
|
||||
if (! $video_render_action->success) {
|
||||
$error_message = $video_render_action?->message ? $video_render_action->message : 'Unable to render, possibly because the video is already being rendered. Check external ID.';
|
||||
|
||||
return response()->json([
|
||||
'error' => [
|
||||
'message' => $error_message,
|
||||
|
||||
],
|
||||
]);
|
||||
}
|
||||
|
||||
// Create a video
|
||||
return response()->json((object) [
|
||||
'success' => [
|
||||
'data' => [
|
||||
'uuid' => $video_render_action->model->uuid,
|
||||
'status' => $video_render_action->model->status,
|
||||
],
|
||||
],
|
||||
]);
|
||||
}
|
||||
|
||||
public function renderStatus(Request $request, string $uuid)
|
||||
{
|
||||
if (! Str::isUuid($uuid)) {
|
||||
return response()->json([
|
||||
'error' => [
|
||||
'message' => 'Invalid UUID.',
|
||||
],
|
||||
]);
|
||||
}
|
||||
$video_render = VideoRender::where('uuid', $uuid)->first();
|
||||
|
||||
if (! $video_render) {
|
||||
return response()->json([
|
||||
'error' => [
|
||||
'message' => 'Video render not found.',
|
||||
],
|
||||
]);
|
||||
}
|
||||
|
||||
return response()->json((object) [
|
||||
'success' => [
|
||||
'data' => [
|
||||
'uuid' => $video_render->uuid,
|
||||
'status' => $video_render->status,
|
||||
],
|
||||
],
|
||||
]);
|
||||
}
|
||||
|
||||
public function allRenders(Request $request)
|
||||
{
|
||||
$user = Auth::user();
|
||||
|
||||
$video_renders = VideoRender::where('user_id', $user->id)
|
||||
->orderBy('id', 'desc')->get();
|
||||
|
||||
return response()->json((object) [
|
||||
'success' => [
|
||||
'data' => [
|
||||
'video_renders' => $video_renders,
|
||||
],
|
||||
],
|
||||
]);
|
||||
}
|
||||
|
||||
private function saveUserVideoRenderRequest(User $user, stdClass $video_render_request)
|
||||
{
|
||||
// check if there is an existing video render request with the same external id
|
||||
|
||||
$video_render_is_busy = VideoRender::where('user_id', $user->id)
|
||||
->where('external_id', $video_render_request->external_id)
|
||||
->whereIn('status', [
|
||||
RenderConstants::STATUS_PLANNED,
|
||||
RenderConstants::STATUS_WAITING,
|
||||
RenderConstants::STATUS_TRANSCRIBING,
|
||||
RenderConstants::STATUS_RENDERING,
|
||||
])->first();
|
||||
|
||||
if ($video_render_is_busy) {
|
||||
return (object) [
|
||||
'success' => false,
|
||||
'message' => 'Video is already in queue or rendering. Status: '.$video_render_is_busy->status,
|
||||
];
|
||||
}
|
||||
// dd($video_render_request);
|
||||
|
||||
$video = $this->getUserVideoByExternalId($user, $video_render_request->external_id);
|
||||
|
||||
$video = $this->updateVideoWithRenderRequest($video, $video_render_request);
|
||||
|
||||
$video = $this->saveUserVideo($video);
|
||||
|
||||
$this->saveVideoCaptions($video);
|
||||
|
||||
try {
|
||||
$this->saveVideoElements($video);
|
||||
} catch (\Exception $e) {
|
||||
return (object) [
|
||||
'success' => false,
|
||||
'message' => $e->getMessage(),
|
||||
];
|
||||
}
|
||||
|
||||
$new_video_render = VideoRender::create([
|
||||
'user_id' => $user->id,
|
||||
'video_id' => $video->id,
|
||||
'external_id' => $video_render_request->external_id,
|
||||
'payload' => $video_render_request,
|
||||
'status' => RenderConstants::STATUS_PLANNED,
|
||||
]);
|
||||
|
||||
return (object) [
|
||||
'success' => true,
|
||||
'model' => $new_video_render,
|
||||
];
|
||||
}
|
||||
|
||||
private function saveVideoCaptions(Video $video)
|
||||
{
|
||||
VideoCaption::where('video_id', $video->id)->delete();
|
||||
|
||||
if (isset($video->payload->captions)) {
|
||||
foreach ($video->payload->captions as $caption) {
|
||||
$video_caption = new VideoCaption;
|
||||
$video_caption->video_id = $video->id;
|
||||
$video_caption->time = $caption->time;
|
||||
$video_caption->duration = $caption->duration;
|
||||
$video_caption->text = $caption->text;
|
||||
|
||||
if (isset($caption->parameters)) {
|
||||
$video_caption->parameters = $caption->parameters;
|
||||
}
|
||||
|
||||
$video_caption->words = $caption->words;
|
||||
$video_caption->save();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function saveVideoElements(Video $video)
|
||||
{
|
||||
if (isset($video->payload->elements)) {
|
||||
$existing_video_elements = VideoElement::where('video_id', $video->id)->get();
|
||||
|
||||
// Create a lookup array of existing elements by asset hash, but keep ALL matching elements
|
||||
$existing_elements_by_hash = [];
|
||||
foreach ($existing_video_elements as $existing_element) {
|
||||
if (! isset($existing_elements_by_hash[$existing_element->asset_hash])) {
|
||||
$existing_elements_by_hash[$existing_element->asset_hash] = [];
|
||||
}
|
||||
$existing_elements_by_hash[$existing_element->asset_hash][] = $existing_element;
|
||||
}
|
||||
|
||||
// Track which elements we're keeping
|
||||
$kept_element_ids = [];
|
||||
// Track which hashes we've already processed to handle duplicates
|
||||
$processed_hashes = [];
|
||||
|
||||
// Validate element URL if exist
|
||||
foreach ($video->payload->elements as $element) {
|
||||
if (isset($element->url)) {
|
||||
if (! $this->validateElementUrl($element->url)) {
|
||||
throw new \Exception('Invalid URL: '.$element->url);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Save
|
||||
foreach ($video->payload->elements as $element) {
|
||||
$asset_hash = $this->getAssetHash($video, $element->url);
|
||||
|
||||
if (isset($existing_elements_by_hash[$asset_hash]) && count($existing_elements_by_hash[$asset_hash]) > 0) {
|
||||
// Get the next unused element with this hash
|
||||
$unused_elements = array_filter($existing_elements_by_hash[$asset_hash], function ($elem) use ($kept_element_ids) {
|
||||
return ! in_array($elem->id, $kept_element_ids);
|
||||
});
|
||||
|
||||
if (count($unused_elements) > 0) {
|
||||
// Use the first unused element
|
||||
$video_element = reset($unused_elements);
|
||||
$kept_element_ids[] = $video_element->id;
|
||||
} else {
|
||||
// All elements with this hash are already used, create a new one
|
||||
$video_element = new VideoElement;
|
||||
$video_element->video_id = $video->id;
|
||||
$video_element->asset_hash = $asset_hash;
|
||||
$video_element->original_asset_url = $element->url;
|
||||
}
|
||||
} else {
|
||||
// No elements with this hash, create a new one
|
||||
$video_element = new VideoElement;
|
||||
$video_element->video_id = $video->id;
|
||||
$video_element->asset_hash = $asset_hash;
|
||||
$video_element->original_asset_url = $element->url;
|
||||
}
|
||||
|
||||
if (isset($element->external_reference) && ! is_empty($element->external_reference)) {
|
||||
$video_element->external_reference = $element->external_reference;
|
||||
}
|
||||
$video_element->type = $element->type;
|
||||
$video_element->time = $element->time;
|
||||
$video_element->track = $element->track;
|
||||
$video_element->duration = $element->duration;
|
||||
|
||||
if (isset($element->parameters)) {
|
||||
$video_element->parameters = $element->parameters;
|
||||
}
|
||||
|
||||
$video_element->save();
|
||||
|
||||
// Add newly created ID to kept list if needed
|
||||
if (! in_array($video_element->id, $kept_element_ids)) {
|
||||
$kept_element_ids[] = $video_element->id;
|
||||
}
|
||||
}
|
||||
|
||||
// Delete elements that weren't in the payload
|
||||
if (count($existing_video_elements) > 0) {
|
||||
VideoElement::where('video_id', $video->id)
|
||||
->whereNotIn('id', $kept_element_ids)
|
||||
->delete();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function getAssetHash(Video $video, $url)
|
||||
{
|
||||
return hash('sha256', $video->id.'-'.$url);
|
||||
}
|
||||
|
||||
private function validateElementUrl(string $url)
|
||||
{
|
||||
// First check if it's a valid URL format
|
||||
$validator = Validator::make(['url' => $url], [
|
||||
'url' => 'required|url',
|
||||
]);
|
||||
|
||||
if ($validator->fails()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// validate url by making a http head request, return true | false boolean
|
||||
try {
|
||||
// Using Laravel's HTTP client to make a HEAD request
|
||||
$response = Http::withOptions([
|
||||
'timeout' => 10,
|
||||
'connect_timeout' => 5,
|
||||
'verify' => true,
|
||||
'http_errors' => false, // Don't throw exceptions for 4xx/5xx responses
|
||||
])->head($url);
|
||||
|
||||
// Check if the response is successful (2xx status code) or a redirect (3xx)
|
||||
return $response->successful();
|
||||
} catch (\Exception $e) {
|
||||
// Catch any exceptions (connection issues, invalid URLs, etc.)
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private function saveUserVideo(Video $video)
|
||||
{
|
||||
if ($video->isDirty()) {
|
||||
$video->save();
|
||||
}
|
||||
|
||||
return $video;
|
||||
}
|
||||
|
||||
private function updateVideoWithRenderRequest(Video $video, stdClass $video_render_request)
|
||||
{
|
||||
// dd($video_render_request);
|
||||
|
||||
$video->content_type = $video_render_request->content_type;
|
||||
$video->width = $video_render_request->width;
|
||||
$video->height = $video_render_request->height;
|
||||
$video->aspect_ratio = $video_render_request->aspect_ratio;
|
||||
$video->payload = $video_render_request;
|
||||
$video->render_settings = (object) [
|
||||
'video_bitrate' => $video_render_request->video_bitrate,
|
||||
'audio_bitrate' => $video_render_request->audio_bitrate,
|
||||
'fps' => $video_render_request->fps,
|
||||
];
|
||||
|
||||
return $video;
|
||||
}
|
||||
|
||||
private function getUserVideoByExternalId(User $user, string $external_id)
|
||||
{
|
||||
$video = Video::where('user_id', $user->id)
|
||||
->where('external_id', $external_id)
|
||||
->first();
|
||||
|
||||
if (! $video) {
|
||||
|
||||
$video = new Video;
|
||||
$video->user_id = $user->id;
|
||||
$video->external_id = $external_id;
|
||||
}
|
||||
|
||||
return $video;
|
||||
}
|
||||
}
|
||||
39
app/Http/Controllers/Settings/PasswordController.php
Normal file
39
app/Http/Controllers/Settings/PasswordController.php
Normal file
@@ -0,0 +1,39 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Settings;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Hash;
|
||||
use Illuminate\Validation\Rules\Password;
|
||||
use Inertia\Inertia;
|
||||
use Inertia\Response;
|
||||
|
||||
class PasswordController extends Controller
|
||||
{
|
||||
/**
|
||||
* Show the user's password settings page.
|
||||
*/
|
||||
public function edit(): Response
|
||||
{
|
||||
return Inertia::render('settings/password');
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the user's password.
|
||||
*/
|
||||
public function update(Request $request): RedirectResponse
|
||||
{
|
||||
$validated = $request->validate([
|
||||
'current_password' => ['required', 'current_password'],
|
||||
'password' => ['required', Password::defaults(), 'confirmed'],
|
||||
]);
|
||||
|
||||
$request->user()->update([
|
||||
'password' => Hash::make($validated['password']),
|
||||
]);
|
||||
|
||||
return back();
|
||||
}
|
||||
}
|
||||
63
app/Http/Controllers/Settings/ProfileController.php
Normal file
63
app/Http/Controllers/Settings/ProfileController.php
Normal file
@@ -0,0 +1,63 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Settings;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Http\Requests\Settings\ProfileUpdateRequest;
|
||||
use Illuminate\Contracts\Auth\MustVerifyEmail;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Inertia\Inertia;
|
||||
use Inertia\Response;
|
||||
|
||||
class ProfileController extends Controller
|
||||
{
|
||||
/**
|
||||
* Show the user's profile settings page.
|
||||
*/
|
||||
public function edit(Request $request): Response
|
||||
{
|
||||
return Inertia::render('settings/profile', [
|
||||
'mustVerifyEmail' => $request->user() instanceof MustVerifyEmail,
|
||||
'status' => $request->session()->get('status'),
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the user's profile settings.
|
||||
*/
|
||||
public function update(ProfileUpdateRequest $request): RedirectResponse
|
||||
{
|
||||
$request->user()->fill($request->validated());
|
||||
|
||||
if ($request->user()->isDirty('email')) {
|
||||
$request->user()->email_verified_at = null;
|
||||
}
|
||||
|
||||
$request->user()->save();
|
||||
|
||||
return to_route('profile.edit');
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete the user's account.
|
||||
*/
|
||||
public function destroy(Request $request): RedirectResponse
|
||||
{
|
||||
$request->validate([
|
||||
'password' => ['required', 'current_password'],
|
||||
]);
|
||||
|
||||
$user = $request->user();
|
||||
|
||||
Auth::logout();
|
||||
|
||||
$user->delete();
|
||||
|
||||
$request->session()->invalidate();
|
||||
$request->session()->regenerateToken();
|
||||
|
||||
return redirect('/');
|
||||
}
|
||||
}
|
||||
27
app/Http/Controllers/TestController.php
Normal file
27
app/Http/Controllers/TestController.php
Normal file
@@ -0,0 +1,27 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Jobs\RunVideoRenderPipelineJob;
|
||||
use App\Models\Video;
|
||||
|
||||
class TestController extends Controller
|
||||
{
|
||||
public function RunVideoRenderPipelineJob()
|
||||
{
|
||||
$dispatch_job = true;
|
||||
$video = Video::latest()->first();
|
||||
|
||||
if ($video) {
|
||||
|
||||
if ($dispatch_job) {
|
||||
RunVideoRenderPipelineJob::dispatch($video->id)->onQueue('render');
|
||||
} else {
|
||||
$job = new RunVideoRenderPipelineJob($video->id);
|
||||
$job->handle();
|
||||
}
|
||||
} else {
|
||||
echo 'NO VIDEO';
|
||||
}
|
||||
}
|
||||
}
|
||||
13
app/Http/Controllers/UserDashboardController.php
Normal file
13
app/Http/Controllers/UserDashboardController.php
Normal file
@@ -0,0 +1,13 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use Inertia\Inertia;
|
||||
|
||||
class UserDashboardController extends Controller
|
||||
{
|
||||
public function index()
|
||||
{
|
||||
return Inertia::render('dashboard');
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user