355 lines
14 KiB
PHP
355 lines
14 KiB
PHP
<?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']);
|
||
}
|
||
|
||
}
|