docs: consolidate documentation into organized structure

- Move 12 markdown files from root to docs/ subdirectories
- Organize documentation by category:
  • docs/troubleshooting/ (1 file)  - Technical troubleshooting guides
  • docs/deployment/      (4 files) - Deployment and security documentation
  • docs/guides/          (3 files) - Feature-specific guides
  • docs/planning/        (4 files) - Planning and improvement proposals

Root directory cleanup:
- Reduced from 16 to 4 markdown files in root
- Only essential project files remain:
  • CLAUDE.md (AI instructions)
  • README.md (Main project readme)
  • CLEANUP_PLAN.md (Current cleanup plan)
  • SRC_STRUCTURE_IMPROVEMENTS.md (Structure improvements)

This improves:
 Documentation discoverability
 Logical organization by purpose
 Clean root directory
 Better maintainability
This commit is contained in:
2025-10-05 11:05:04 +02:00
parent 887847dde6
commit 5050c7d73a
36686 changed files with 196456 additions and 12398919 deletions

View File

@@ -4,6 +4,7 @@ declare(strict_types=1);
namespace App\Application\Admin;
use App\Application\Admin\Service\AdminLayoutProcessor;
use App\Domain\Media\Image;
use App\Domain\Media\ImageRepository;
use App\Domain\Media\ImageResizer;
@@ -14,66 +15,81 @@ use App\Framework\Auth\Auth;
use App\Framework\Core\PathProvider;
use App\Framework\Http\Method;
use App\Framework\Http\Request;
use App\Framework\Http\Session\FormIdGenerator;
use App\Framework\Http\UploadedFile;
use App\Framework\Router\Result\ViewResult;
use App\Framework\Router\Result\JsonResult;
use App\Framework\Meta\MetaData;
use App\Framework\Ulid\StringConverter;
use App\Framework\Ulid\Ulid;
use App\Framework\View\FormBuilder;
use App\Framework\View\RawHtml;
class ShowImageUpload
final readonly class ShowImageUpload
{
public function __construct(
private PathProvider $pathProvider,
private StringConverter $stringConverter,
private FormIdGenerator $formIdGenerator,
private AdminLayoutProcessor $layoutProcessor,
) {
}
#[Auth]
#[Route('/upload')]
public function __invoke(): void
public function __invoke(): ViewResult
{
$html = <<<HTML
<form action="/upload" method="post" enctype="multipart/form-data">
<label for="image">Bild hochladen:</label>
<input type="file" id="image" name="image" accept="image/*" required/>
<input type="submit" value="Upload" />
</form>
$form = FormBuilder::create('/upload', 'post', $this->formIdGenerator)
->withClass('upload-form')
->addFileInput('image', 'Bild hochladen:', true)
->addSubmitButton('Upload');
HTML;
// Set enctype for file upload
$formHtml = str_replace('<form', '<form enctype="multipart/form-data"', (string) $form);
echo $html;
die();
$data = [
'title' => 'Bild-Upload',
'description' => 'Laden Sie neue Bilder in das System hoch.',
'formHtml' => RawHtml::from($formHtml)
];
$finalData = $this->layoutProcessor->processLayoutFromArray($data);
$metaData = MetaData::create(
title: 'Bild-Upload | Admin Panel',
description: 'Upload new images to the system'
);
return new ViewResult('upload-form', $metaData, $finalData);
}
#[Auth]
#[Route('/upload', Method::POST)]
public function upload(Request $request, Ulid $ulid, ImageRepository $imageRepository, ImageVariantRepository $imageVariantRepository): void
public function upload(Request $request, Ulid $ulid, ImageRepository $imageRepository, ImageVariantRepository $imageVariantRepository): ViewResult
{
try {
/** @var UploadedFile $file */
$file = $request->files->get('image');
if (!$file || $file->error !== UPLOAD_ERR_OK) {
return $this->renderUploadError('Keine gültige Datei hochgeladen.');
}
$storageFolder = $this->pathProvider->resolvePath('/storage');
// Todo: Use Clock instead of date();
$uploadDirectory = sprintf('uploads/%s/%s/%s', date('Y'), date('m'), date('d'));
$ulid = (string)$ulid; //$this->stringConverter->encodeBase32($ulid);
$id = $ulid;
// Remove Timestamp
$id = substr($id, 10);
$ulid = (string)$ulid;
$id = substr($ulid, 10); // Remove Timestamp
$hash = hash_file('sha256', $file->tmpName);
// Prüfen, ob ein Bild mit diesem Hash bereits existiert
$existingImage = $imageRepository->findByHash($hash);
if ($existingImage !== null) {
echo "<h2>Bild bereits vorhanden</h2>";
echo "<p>Dieses Bild wurde bereits hochgeladen.</p>";
echo "<p>Bild-ID: " . htmlspecialchars($existingImage->ulid) . "</p>";
return;
return $this->renderUploadSuccess(
'Bild bereits vorhanden',
"Dieses Bild wurde bereits hochgeladen. Bild-ID: {$existingImage->ulid}"
);
}
$idStr = str_pad((string)$id, 9, '0', STR_PAD_LEFT);
@@ -85,20 +101,10 @@ class ShowImageUpload
);
$path = $storageFolder . '/' . $uploadDirectory . '/' . $filePathPattern . "/";
$filename = $idStr . '_' . $hash . "_";
#dd($path . $filename . 'variant.png');
$smallPath = $path . $filename . 'small.png';
[$width, $height] = getimagesize($file->tmpName);
$image = new Image(
ulid : $ulid,
filename : $filename . 'original.jpg',
@@ -109,37 +115,74 @@ class ShowImageUpload
height : $height,
hash : $hash,
path : $path,
altText : 'Some alt text',
altText : 'Uploaded image',
);
$imageRepository->save($image, $file->tmpName);
#$image = $imageRepository->findById("0197B2CD759501F08D60312AE62ACCFC");
#mkdir($path, 0755, true);
$variant = new ImageResizer()($image, 50, 50);
// Create thumbnail variant
$variant = new ImageResizer()($image, 150, 150);
$imageVariantRepository->save($variant);
;
$href = "/images/".$variant->filename;
echo "<a href='$href'>$href</a>";
#new SaveImageFile()($image, $file->tmpName);;
debug($variant->filename);
dd($image);
return $this->renderUploadSuccess(
'Upload erfolgreich!',
"Bild wurde erfolgreich hochgeladen.<br>" .
"Original: {$image->filename}<br>" .
"Thumbnail: {$variant->filename}<br>" .
"ULID: {$image->ulid}"
);
} catch (\Exception $e) {
echo "<h2>Fehler beim Upload:</h2>";
echo "<p>" . htmlspecialchars($e->getMessage()) . "</p>";
debug($e);
return $this->renderUploadError(
"Fehler beim Upload: " . $e->getMessage()
);
}
}
private function renderUploadError(string $message): ViewResult
{
$data = [
'title' => 'Upload Fehler',
'description' => $message,
'error' => true,
'formHtml' => $this->buildUploadForm()
];
$finalData = $this->layoutProcessor->processLayoutFromArray($data);
return new ViewResult(
'upload-form',
MetaData::create('Upload Fehler | Admin Panel', $message),
$finalData
);
}
private function renderUploadSuccess(string $title, string $message): ViewResult
{
$data = [
'title' => $title,
'description' => $message,
'success' => true,
'formHtml' => $this->buildUploadForm()
];
$finalData = $this->layoutProcessor->processLayoutFromArray($data);
return new ViewResult(
'upload-form',
MetaData::create($title . ' | Admin Panel', $message),
$finalData
);
}
private function buildUploadForm(): RawHtml
{
$form = FormBuilder::create('/upload', 'post', $this->formIdGenerator)
->withClass('upload-form')
->addFileInput('image', 'Bild hochladen:', true)
->addSubmitButton('Upload');
$formHtml = str_replace('<form', '<form enctype="multipart/form-data"', (string) $form);
return RawHtml::from($formHtml);
}
}