Files
Fitnessblog/app/Http/Controllers/PostController.php
2026-01-07 15:46:00 +01:00

355 lines
14 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Models\ParentCategory;
use App\Models\Category;
use App\Models\Post;
use Intervention\Image\Laravel\Facades\Image;
use Illuminate\Support\Facades\File;
use App\Models\NewsletterSubscriber;
use App\Jobs\SendNewsletterJob;
class PostController extends Controller
{
/**
* Zeigt das Formular zum Erstellen eines neuen Blogbeitrags an.
*
* ROUTE: /admin/posts/create
* METHOD: GET
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\View\View
*/
public function addPost(Request $request) {
$categories_html = '';
$pcategories = ParentCategory::whereHas('children')->orderBy('name', 'asc')->get();
$categories = Category::where('parent', 0)->orderBy('name', 'asc')->get();
if(count($pcategories) > 0) {
foreach($pcategories as $item) {
$categories_html.='<optgroup label="'.$item->name.'">';
foreach($item->children as $category) {
$categories_html.='<option value="'.$category->id.'">'.$category->name.'</option>';
}
$categories_html.='</optgroup>';
}
}
if(count($categories) > 0) {
foreach($categories as $item) {
$categories_html.='<option value="'.$item->id.'">'.$item->name.'</option>';
}
}
$data = [
'pageTitle' => 'Add new Post',
'categories_html' => $categories_html
];
return view('back.pages.add_post', $data);
}
/**
* Erstellt einen neuen Blogbeitrag und speichert das Beitragsbild.
*
* ROUTE: /admin/posts
* METHOD: POST
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\JsonResponse
*/
public function createPost(Request $request)
{
$request->validate([
'title' => 'required|unique:posts,title',
'content' => 'required',
'category' => 'required|exists:categories,id',
'featured_image' => 'required|mimes:png,jpg,jpeg',
], [
'title.required' => 'Titel wird benötigt',
'title.unique' => 'Titel bereits vergeben',
'content.required' => 'Content wird benötigt',
'category.required' => 'Kategorie wird benötigt',
'category.exists' => 'Kategorie existiert nicht',
'featured_image.required' => 'Image wird benötigt',
'featured_image.mimes' => 'Es sind nur png,jpg,jpeg erlaubt',
]);
if ($request->hasFile('featured_image')) {
$relativePath = 'images/posts/'; // relativ zu /public
$basePath = public_path($relativePath); // absoluter Pfad
$file = $request->file('featured_image');
$filename = $file->getClientOriginalName();
$newFilename = time().'_'.$filename;
// Original speichern
if (!File::isDirectory($basePath)) {
File::makeDirectory($basePath, 0777, true, true);
}
$upload = $file->move($basePath, $newFilename);
if ($upload) {
$originalPath = $basePath.DIRECTORY_SEPARATOR.$newFilename;
$quality = 80;
// resized-Ordner
$resizedDir = $basePath.DIRECTORY_SEPARATOR.'resized'.DIRECTORY_SEPARATOR;
if (!File::isDirectory($resizedDir)) {
File::makeDirectory($resizedDir, 0777, true, true);
}
// 1) Thumbnail (250x250 aus Original)
$thumbPath = $resizedDir.'thumb_'.$newFilename;
Image::read($originalPath)
->cover(250, 250) // v3-Pendant zu fit(250,250)
->save($thumbPath, $quality);
// 2) Resized (512x320 aus Original)
$resizedPath = $resizedDir.'resized_'.$newFilename;
Image::read($originalPath)
->cover(512, 320) // v3-Pendant zu fit(512,320)
->save($resizedPath, $quality);
// Post speichern
$post = new Post();
$post->author_id = auth()->id();
$post->category = $request->category; // ggf. category_id
$post->title = $request->title;
$post->content = $request->content;
$post->featured_image = $newFilename;
$post->tags = $request->tags;
$post->meta_keywords = $request->meta_keywords;
$post->meta_description = $request->meta_description;
$post->visibility = $request->visibility;
$post->structured_data = $request->structured_data;
$saved = $post->save();
if ($saved) {
/**
* Send Email to Newsletter Subscribers
*/
if($request->visibility == 1) {
$latestPost = Post::latest()->first();
if(NewsletterSubscriber::count() > 0) {
$subscribers = NewsLetterSubscriber::pluck('email');
foreach($subscribers as $subscriber_email) {
SendNewsletterJob::dispatch($subscriber_email, $latestPost);
}
$latestPost->is_notified = true;
$latestPost->save();
}
}
return response()->json(['status' => 1, 'message' => 'Post wurde erfolgreich erstellt']);
}
return response()->json(['status' => 0, 'message' => 'Post konnte nicht erstellt werden'], 500);
}
return response()->json(['status' => 0, 'message' => 'Leider gab es ein Problem, versuch es später nochmal'], 500);
}
return response()->json(['status' => 0, 'message' => 'Kein Bild hochgeladen'], 400);
}
/**
* Zeigt die Übersichtsseite aller Blogbeiträge im Backend an.
*
* ROUTE: /admin/posts
* METHOD: GET
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\View\View
*/
public function allPosts(Request $request) {
$data = [
'pageTitle' => 'Posts'
];
return view('back.pages.posts', $data);
}
/**
* Zeigt das Formular zum Bearbeiten eines bestehenden Blogbeitrags an.
*
* ROUTE: /admin/posts/{id}/edit
* METHOD: GET
*
* @param \Illuminate\Http\Request $request
* @param int|null $id ID des Blogbeitrags
* @return \Illuminate\View\View
*/
public function editPost(Request $request, $id = null) {
$post = Post::findOrFail($id);
$categories_html = '';
$pcategories = ParentCategory::whereHas('children')->orderBy('name', 'asc')->get();
$categories = Category::where('parent', 0)->orderBy('name', 'asc')->get();
if(count($pcategories) > 0) {
foreach($pcategories as $item) {
$categories_html.='<optgroup label="'.$item->name.'">';
foreach($item->children as $category) {
$selected = $category->id == $post->category ? 'selected' : '';
$categories_html.='<option value="'.$category->id.'">'.$category->name.'</option>';
}
$categories_html.='</optgroup>';
}
}
if(count($categories) > 0) {
foreach($categories as $item) {
$selected = $item->id == $post->category ? 'selected' : '';
$categories_html.='<option value="'.$item->id.'" '.$selected.'>'.$item->name.'</option>';
}
}
$data = [
'pageTitle' => 'Post Bearbeiten',
'post'=> $post,
'categories_html' => $categories_html
];
return view('back.pages.edit_post', $data);
}
/**
* Aktualisiert einen bestehenden Blogbeitrag (inkl. optionalem Beitragsbild).
*
* ROUTE: /admin/posts/{id}
* METHOD: PUT/PATCH
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\JsonResponse
*/
public function updatePost(Request $request)
{
$post = Post::findOrFail($request->post_id);
$featured_image_name = $post->featured_image;
$request->validate([
'title' => 'required|unique:posts,title,' . $post->id,
'content' => 'required',
'category' => 'required|exists:categories,id',
'featured_image' => 'nullable|mimes:png,jpg,jpeg',
], [
'title.required' => 'Titel wird benötigt',
'title.unique' => 'Titel bereits vergeben',
'content.required' => 'Content wird benötigt',
'category.required' => 'Kategorie wird benötigt',
'category.exists' => 'Kategorie existiert nicht',
'featured_image.mimes' => 'Es sind nur png,jpg,jpeg erlaubt',
]);
if ($request->hasFile('featured_image')) {
$old_featured_image = $post->featured_image;
// Basis-Pfade
$relativePath = 'images/posts/'; // relativ zu /public
$basePath = public_path($relativePath); // absoluter Pfad
$file = $request->file('featured_image');
$filename = $file->getClientOriginalName();
$newFilename = time() . '_' . $filename;
// Ordner für Original sicherstellen
if (!File::isDirectory($basePath)) {
File::makeDirectory($basePath, 0777, true, true);
}
$upload = $file->move($basePath, $newFilename);
if ($upload) {
$originalPath = $basePath . DIRECTORY_SEPARATOR . $newFilename;
// resized-Ordner sicherstellen
$resizedDirRelative = $relativePath . 'resized/';
$resizedDir = public_path($resizedDirRelative);
if (!File::isDirectory($resizedDir)) {
File::makeDirectory($resizedDir, 0777, true, true);
}
// Thumbnail (1:1) v3: read + cover
$thumbPath = $resizedDir . DIRECTORY_SEPARATOR . 'thumb_' . $newFilename;
Image::read($originalPath)
->cover(250, 250)
->save($thumbPath);
// Resized (512x320)
$resizedPath = $resizedDir . DIRECTORY_SEPARATOR . 'resized_' . $newFilename;
Image::read($originalPath)
->cover(512, 320)
->save($resizedPath);
// Alte Bilder löschen
if ($old_featured_image) {
$oldOriginal = public_path($relativePath . $old_featured_image);
$oldResized = public_path($resizedDirRelative . 'resized_' . $old_featured_image);
$oldThumb = public_path($resizedDirRelative . 'thumb_' . $old_featured_image);
if (File::exists($oldOriginal)) {
File::delete($oldOriginal);
}
if (File::exists($oldResized)) {
File::delete($oldResized);
}
if (File::exists($oldThumb)) {
File::delete($oldThumb);
}
}
$featured_image_name = $newFilename;
} else {
return response()->json([
'status' => 0,
'message' => 'Leider gab es ein Fehler beim Hochladen von Image',
]);
}
}
$sendEmailToSubscribers = ($post->visibility == 0 && $post->is_notified == 0 && $request->visibility == 1) ? true : false;
// Post-Daten aktualisieren
$post->author_id = auth()->id();
$post->category = $request->category;
$post->title = $request->title;
$post->content = $request->content;
$post->featured_image = $featured_image_name;
$post->tags = $request->tags;
$post->meta_keywords = $request->meta_keywords;
$post->meta_description = $request->meta_description;
$post->visibility = $request->visibility;
$post->structured_data = $request->structured_data;
$saved = $post->save();
if ($saved) {
/**
* Send Mail Newsletter to Subscribers
*/
if($sendEmailToSubscribers) {
$currentPost = Post::findOrFail($request->post_id);
if(NewsletterSubscriber::count() > 0) {
$subscribers = NewsLetterSubscriber::pluck('email');
foreach($subscribers as $subscriber_email) {
SendNewsletterJob::dispatch($subscriber_email, $currentPost);
}
$currentPost->is_notified = true;
$currentPost->save();
}
}
return response()->json(['status' => 1, 'message' => 'Post wurde erfolgreich bearbeitet']);
}
return response()->json(['status' => 0, 'message' => 'Fehler beim Bearbeiten von Post']);
}
}