Starten eines neuen Projekts

composer create-project --prefer-dist laravel/laravel:^10.0 Projektname

Model (ORM)

Erstellen von Modellklassen

Model Configurieren

class Student extends Model {
            use HasFactory;
            protected $table = "students"; // <- Tabellenname
            protected $primaryKey = "id";  // <- Primärschlüssel
            public $incrementing = true;   // <- Automatisches Hochzählen
            protected $keyType = "integer"; // <- Datentyp des Primärschlüssels
            public $timestamps = true; // <- Einschalten von Created_at und Updated_at
          }

Model Relationships

1:n (Student n -> 1 Class)

Wir nehmen an, dass beim "Student" der FK mit dem Namen "classr_id" definiert ist.

class Student extends Model {
            use HasFactory;
            protected $table = "students";
          
            public function classr(): BelongsTo {
              return $this->belongsTo(Classr::class);
            }
          }
class Classr extends Model {
            use HasFactory;
            protected $table = "classr";
          
            public function students(): HasMany {
              return $this->hasMany(Student::class);
            }
          }

Wenn die Namen der Spalten frei gewählt werden sollen muss es ein bisschen anders geschrieben werden

class Student extends Model {
            use HasFactory;
            protected $table = "students";
          
            public function classr(): BelongsTo {
              return $this->belongsTo(Classr::class, 'foreign_key', 'owner_key');
            }
          }
class Classr extends Model {
            use HasFactory;
            protected $table = "classr";
          
            public function students(): HasMany {
              return $this->hasMany(Student::class, 'foreign_key', 'local_key');
            }
          }

m:n (Teacher n -> 1 Class)

// ERKLÄRUNG:
          return $this->belongsToMany(Modellklasse, 'Zwischentabelle', 'FK von der aktuellen Klasse in der Zwischentabelle', 'FK von der Verbindungstabelle in der Zwischentabelle');
class Teacher extends Model {
            use HasFactory;
            protected $table = "teachers";
          
            public function classrs(): BelongsToMany {
              return $this->belongsToMany(Classr::class, "timetable", "teacher_id", "classr_id");
            }
          }

Controller erstellen

php artisan make:controller <ControllerName>
          
          php artisan make:controller <ControllerName> -r
-r macht aus dem Controller einen Resource controller die schon vordefinierte funktionen hat

Datenbank Tabelle erstellen und Migrieren

Datenbank Tabelle erstellen

php artisan make:migration create_database_table

Migration mit Beziehungen

1:n (Student n -> Class)

public function up(): void {
            Schema::create('students', function (Blueprint $table) {
              $table->id();
              $table->string('vorname');
              $table->string('nachname');
              $table->bigInteger('classr_id')->unsigned();
              $table->foreign('classr_id')->references('id')->on('classrs');
              $table->timestamps();
            });
          }
public function up(): void {
            Schema::create('classrs', function (Blueprint $table) {
              $table->id();
              $table->string('name');
              $table->timestamps();
            });
          }

m:n (Teacher -> Class)

public function up(): void {
            Schema::create('teachers', function (Blueprint $table) {
              $table->id();
              $table->string('vorname');
              $table->string('nachname');
              $table->timestamps();
            });
          }
public function up(): void {
            Schema::create('classrs', function (Blueprint $table) {
              $table->id();
              $table->string('name');
              $table->timestamps();
            });
          }
// Zwischentabelle
          public function up(): void {
            Schema::create('timetable', function (Blueprint $table) {
              $table->id();
              $table->bigInteger('classr_id')->unsigned();
              $table->foreign('classr_id')->references('id')->on('classrs');
              $table->bigInteger('teacher_id')->unsigned();
              $table->foreign('teacher_id')->references('id')->on('teachers');
              $table->timestamps();
            });
          }

Datenbank migrieren

Wenn die Migrationen in der richtigen Reihenfolge (nach Abhängigkeit und Beziehungen) gemacht wurden

php artisan migrate
Sollte die Migration nicht passen, kann es im nachhinein noch mal verändert werden, indem man den timestamp im Migrationsnamen anpasst

Storage Link erstellen

php artisan storage:link

php run

php artisan serve

web.php

Route::resource('name', Controller::class);
          
          Route::redirect('/', '/name_der_neuen_seite');
Alt text

CRUD / Daten holen und bearbeiten

Daten lesen

Alle Daten Holen und die Klasse anzeigen

public function index() {
            $students = Student::all();
            return view('student.index', ['students' => $students]);
          }

            @foreach($students as $student)
             // Die Funktion "classr" in Student liefert das Objekt Classr. Somit kann man auf die Attribute von Classr zugreifen.
            
            @endforeach
          
ID Vorname Nachname Klasse
{{ $student->id }} {{ $student->vorname }} {{ $student->nachname }} {{ $student->classr->name }}

Bedingungen auf die Anfrage setzen

// Holt eine ganze Collection aus der Datenbank
          $students = Student::where('nachname', 'ABC')
                             ->orderBy('vorname')
                             ->get();

Ein Element holen

$student = Student::where('id', 1)
                             ->orderBy('vorname')
                             ->first();
          
          // Oder
          
          $student = Student::find(1);

Aggregatfunktionen

// Holt eine ganze Collection aus der Datenbank
          $students = Student::where('nachname', 'ABC')
                             ->count();

Daten lesen m:n

public function index() {
            $teachers = Teacher::all();
            return view('timetable.index', ['teachers' => $teachers]);
          }

            @foreach($teachers as $teacher)
              @foreach($teacher->classrs as $classr)
                
              @endforeach
            @endforeach
          
Lehrer Klasse
{{ $teacher->vorname }} {{ $teacher->nachname }} {{ $classr->name }}

man kann auch weiter gehen


            @foreach($teachers as $teacher)
              @foreach($teacher->classrs as $classr)
                @foreach($classr->students as $student)
                
                @endforeach
              @endforeach
            @endforeach
          
Lehrer Klasse Student
{{ $teacher->vorname }} {{ $teacher->nachname }} {{ $classr->name }} {{ $student->vorname }} {{ $student->nachname }}

Create

$student = new Student();
          $student->vorname = 'Andy';
          $student->nachname = 'Marx';
          $student->classr_id = 1;
          $student->save();
          
          // Get ID of inserted student
          $newID = $student->id;
          
          // Oder
          
          $student = Student::create([
            'vorname' => 'Andy',
            'nachname' => 'Marx',
            'classr_id' => 1,
          ]);

Update

// UPDATE
          $student = Student::find(4);
          $student->vorname = 'Peter';
          $student->classr_id = 2;
          $student->save();

Delete

// DELETE
          $student = Student::find(5);
          $student->delete();
          
          // Oder
          // DELETE many students
          $student = Student::where('classr_id', 1);
          $student->delete();

Daten ändern mit Beziehungen

// Add to relationship
          $teacher = Teacher::find(3);
          $teacher->classrs()->attach(1);
          
          // Add to relationship with data
          $teacher = Teacher::find(3);
          $teacher->classrs()->attach(1, ['von' => '18:00', 'bis' => '22:00']);
          
          // Remove from relationship
          $teacher = Teacher::find(3);
          $teacher->classrs()->detach(1);

Mail erstellen

Klasse 'Mailable'
php artisan make:mail SendMail

Email-Kopf definieren in der Funktion "envelope()" (im Ordner "Mail/SendMail")

public function envelope(): Envelope {
            return new Envelope(
              from: new Address('abc@abc.at', 'ABC ABC'), // Absender
              subject: 'Test Mail' // Betreff
            );
          }

Email-Inhalt definieren

public function content(): Content {
            return new Content(
              view: 'welcome'
            );
          }

Daten an die View übergeben

public string $name;
          
          public function __construct(string $name) {
            $this->name = $name;
          }
          
          // Verwendung in der View als Variable
          <div>
            {{ $name }}
          </div>

Anhang hinzufügen

public function attachments(): array {
            return [
              Attachment::fromPath('/path/to/file'),
            ];
          }

Serverkonfigurierung

MAIL_MAILER=smtp
          MAIL_HOST=smtp.gmail.com
          MAIL_PORT=587
          MAIL_USERNAME=XXXXXXXXXXXX // Gmail-Adresse
          MAIL_PASSWORD=XXXXXXXXXXXX // App-Passwort
          MAIL_ENCRYPTION=ssl
          
          https://support.google.com/mail/answer/185833?hl=en  // App-Passwort generieren

E-Mail senden

// ohne Daten
          public function sendMail() {
            Mail::to('abc@gmail.com')->send(new SendMail());
            return "Mail send";
          }
          
          // mit Daten
          public function sendMail() {
            $username = Auth::user()->name;
            Mail::to('abc@gmail.com')->send(new SendMail($username));
            return "Mail send";
          }

Logging

Authentifizierung

Guards

Benutzerauthentifizierung für jeden Request

Providers

Definieren wie Benutzer aus der Datenbank geholt werden

Konfiguration

config/auth.php
          'default' => [
            'guard' => 'web',
            'passwords' => 'users',
          ],
          
          'guards' => [
            'web' => [
              'driver' => 'session',
              'provider' => 'users',
            ],
          ],
          
          'providers' => [
            'users' => [
              'driver' => 'eloquent',
              'model' => App\Models\User::class,
            ],
          ]

Datenbank Vorbereitung

DB_CONNECTION=mysql
          DB_HOST=127.0.0.1
          DB_PORT=3306
          DB_DATABASE=onlineshop
          DB_USERNAME=laravel
          DB_PASSWORD=laravel

Routen schützen

Route::get('/flights', function() {
            // Nur angemeldete Benutzer können diese Route erreichen
          })->middleware('auth');
          
          // Benutzer umleiten, wenn nicht angemeldet
          // app/Http/Middleware/Authenticate.php
          protected function redirectTo(Request $request): string {
            return route('login');
          }

Autorisierung

Gates definieren

app/Providers/AuthServiceProvider.php

public function boot(): void {
            Gate::define('isAdmin', function($user) {
              return $user->role === 'ADMIN';
            });
          
            Gate::define('isUser', function($user) {
              return $user->role === 'USER';
            });
          }

Session

// Daten abfragen
          $value = $request->session()->get('key');
          
          // Daten abfragen mit einem Default value
          $value = $request->session()->get('key', 'default');
          
          // Alle Session-Informationen abfragen
          $data = $request->session()->all();
          
          // Abfragen, ob ein Eintrag vorhanden ist
          if ($request->session()->has('users')) {
            // ...
          }
          
          // Daten speichern
          $request->session()->put('key', 'value');
          
          // Daten löschen
          $request->session()->forget('name');
          
          // Alle Daten in der Session löschen
          $request->session()->flush();

Seeders

File upload

<form action="/upload" method="post" enctype="multipart/form-data">
            @csrf
            <label>Bild hochladen:</label>
            <input type="file" name="picture"/>
            <input type="submit" value="Speichern"/>
          </form>

Datei speichern und in die Datenbank eintragen

public function upload(Request $request) {
            // validate picture
            $request->validate([
              'picture' => 'required|mimes:jpeg,png'
            ]);
          
            // Hash the picture name
            $pictureName = $request->file('picture')->hashName();
          
            // Save file to storage folder
            $request->file('picture')->storeAs('public/images', $pictureName);
          
            // Add picture to database
            DB::table('pictures')->insert([
              'name' => 'Bild',
              'path' => $pictureName
            ]);
          
            return redirect('/');
          }

Bilder anzeigen

public function index() {
            $pictures = DB::table('pictures')->get();
            return view('welcome', ['pics' => $pictures]);
          }
<div>
            @foreach($pics as $pic)
              <img src="{{ asset('storage/images/'.$pic->path) }}" />
              <a href="delete/{{ $pic->id }}">DELETE</a>
            @endforeach
          </div>

Bilder löschen

public function delete($id) {
            $picture = DB::table('pictures')->find($id);
            Storage::delete('public/images/'.$picture->path);
            DB::table('pictures')->delete($id);
          
            return redirect('/');
          }

Bootstrap

composer require laravel/ui
          php artisan ui bootstrap
          npm i bootstrap@latest
          npm i

zur vite.config.js -> bootstrap hinzufügen

import { defineConfig } from 'vite';
          import laravel from 'laravel-vite-plugin';
          import path from 'path';
          
          export default defineConfig({
            plugins: [
              laravel([
                'resources/js/app.js'
              ])
            ],
            resolve: {
              alias: {
                '~bootstrap': 'node_modules/bootstrap'
              }
            }
          });

/resources/js/app.js -> Bootstrap hinzufügen

import './bootstrap';
          import '../sass/app.scss';

Einbinden in HTML

<head>
            @vite(['resources/js/app.js'])
            <meta charset="utf-8">
          </head>

Vite ausführen

npm run dev