Kategorien
Symfony

Sonata 4 Admin Variablen im Template

In Sonata 4 stehen verschiedene Sonata-spezifische Variablen in den Templates zur Verfügung. Hier sind einige der häufig verwendeten Variablen:

  1. admin: Diese Variable repräsentiert das aktuelle Admin-Objekt und ermöglicht den Zugriff auf verschiedene Admin-spezifische Informationen und Methoden. Sie kann verwendet werden, um beispielsweise den Admin-Titel oder die Routen zu erhalten.
  2. object: Diese Variable repräsentiert das aktuelle Objekt oder die aktuelle Entität, mit der das Template arbeitet. Sie ermöglicht den Zugriff auf Eigenschaften und Methoden des Objekts, um dynamische Inhalte im Template zu generieren.
  3. id: Diese Variable enthält die ID des aktuellen Objekts. Sie ist besonders nützlich in Templates, die auf einzelne Objekte angewendet werden, um spezifische Daten abzurufen oder Aktionen durchzuführen.
  4. form: Wenn das Template ein Formular darstellt, steht die form Variable zur Verfügung. Diese Variable ermöglicht den Zugriff auf das Formularobjekt und dessen Felder, um beispielsweise Validierungen durchzuführen oder Daten zu verarbeiten.
  5. base_template: Diese Variable definiert das Basis-Template, das von einem spezifischen Sonata Template erweitert wird. Sie ermöglicht es Entwicklern, das Standardverhalten von Sonata anzupassen, indem sie ein benutzerdefiniertes Basis-Template festlegen.
  6. admin_pool: Diese Variable stellt den Admin-Pool dar und bietet Zugriff auf den gesamten verfügbaren Admin-Bereich. Sie ermöglicht den Zugriff auf Informationen über alle registrierten Admin-Klassen und kann zum Beispiel verwendet werden, um eine Liste der verfügbaren Admin-Objekte anzuzeigen.

In Sonata 4 stehen neben den zuvor genannten Variablen auch die value-Variable zur Verfügung. Diese Variable repräsentiert den aktuellen Wert eines bestimmten Feldes oder einer Eigenschaft des Objekts.

Hier ist ein Beispiel, wie die value-Variable im Template array.html.twig verwendet werden kann:

{% extends '@SonataAdmin/CRUD/base_show_field.html.twig' %}

{% block field %}
    {% if value is not empty %}
        {{ value | join(', ') }}
    {% endif %}
{% endblock %}
protected function configureShowFields(ShowMapper $show): void
{
	$show->add('my_attrbute', null, [
		'label' => 'Array Attribute Example',
		'template' => 'array.html.twig',
		]
	)
}
Kategorien
PHP Symfony

SQL vs. Doctrine Migrations

In Symfony und Doctrine stehen Ihnen zwei Optionen zur Verfügung, um Datenbankmigrationen zu verwalten: SQL und Doctrine-Objekte.

  1. SQL-Migrationen: Mit SQL-Migrationen schreiben Sie die Datenbankänderungen als SQL-Skripte. Dies gibt Ihnen die volle Kontrolle über den genauen SQL-Code, der ausgeführt wird. Sie können spezifische Datenbankfunktionen und -funktionen nutzen, die möglicherweise nicht direkt von Doctrine unterstützt werden. SQL-Migrationen können auch einfacher sein, wenn Sie bereits über umfangreiche SQL-Kenntnisse verfügen.

Einige Vorteile der SQL-Migrationen sind:

  • Direkte Kontrolle über den SQL-Code.
  • Nutzung spezifischer Datenbankfunktionen.
  • Einfacher für Entwickler mit umfangreichen SQL-Kenntnissen.

Einige Nachteile der SQL-Migrationen sind:

  • Möglicherweise weniger portabel, da der SQL-Code an eine bestimmte Datenbank-Engine gebunden sein kann.
  • Weniger objektorientiert und weniger Integration mit dem Doctrine ORM.
  1. Doctrine-Objekt-Migrationen: Mit Doctrine-Objekt-Migrationen verwenden Sie Doctrine-Migrationsklassen, um Ihre Datenbankänderungen zu definieren. Dies ermöglicht eine objektorientierte Herangehensweise an die Migrationen und eine bessere Integration mit dem Doctrine ORM. Sie können auf die Funktionen von Doctrine zugreifen und beispielsweise Änderungen an Ihren Datenbanktabellen über die Objektmodelle vornehmen.

Einige Vorteile der Doctrine-Objekt-Migrationen sind:

  • Objektorientierte Herangehensweise an Migrationen.
  • Bessere Integration mit dem Doctrine ORM.
  • Portabler, da Doctrine den generierten SQL-Code an die spezifische Datenbank-Engine anpasst.

Der entscheidende Nachteil von Doctrine-Objekt-Migrationen

Ein wichtiger Nachteil bei der Verwendung von Doctrine-Objekt-Migrationen besteht darin, dass bei der Erstellung der Entitäten ein Fehler auftritt, wenn ein Attribut in der Datenbank nicht vorhanden ist. Dies kann insbesondere dann zum Problem werden, wenn Sie vorhandene Datenbanktabellen haben und Änderungen an den Entitäten vornehmen, die zu Spalten hinzufügen oder entfernen.

Wenn Sie beispielsweise eine Entität mit einem bestimmten Attribut definieren und versuchen, die Datenbanktabellen basierend auf dieser Entität zu erstellen, wird Doctrine einen Fehler werfen, wenn das entsprechende Attribut in der Datenbanktabelle nicht vorhanden ist. Dies liegt daran, dass Doctrine die Entitäten und die Datenbanktabellen synchron halten möchte.

Aufgrund meiner Erfahrungen mit Migrationen würde ich immer empfehlen SQL-Migrationen zu verwenden, weil beim hinzufügen von Attributen ansonsten immer Fehler geworfen werden.

Kategorien
Webdeveloper Tools

PHPStorm Klassenhierachie anzeigen

Mit der Tastenkombination STRG + ALT + U kann man sich zu einer beliebigen Klassse ein Diagramm über die Vererbungen und Interfaces aufrufen lassen in der IDE.

Beispiel:

Klassendiagramm der Klasse User in PHP
Klassendiagramm der Klasse User in TypeScript
Kategorien
Symfony

GuzzleHttp loggen aller Requests nach Monolog

Um alle Requests und Responses zu loggen, die mittels Guzzle in einer Symfony Applikation getätigt werden, kann man Guzzle folger Maßen konfigurieren:

    guzzle.handler_stack_log:
      class: 'GuzzleHttp\HandlerStack'
      factory: [ GuzzleHttp\HandlerStack, create ]
      calls:
        - [ push, [ '@guzzle.middleware_log', 'log_default' ] ]

    guzzle.middleware_log:
      class: callback
      factory: [ GuzzleHttp\Middleware, log ]
      arguments:
        - '@monolog.logger.my_guzzle_log'
        - '@GuzzleHttp\MessageFormatter'

    GuzzleHttp\MessageFormatter:
      - "Request:\n{request}\nDuration: {req_time}\nResponse:\n{response}\nError:\n{error}"

Damit werden alle Logs nach zum Monolog Service monolog.logger.my_guzzle_log weitergeleitet.

Der MessageFormatter unterstützt verschiedene Formatzeichenfolgen, die Sie in Ihren Protokollen verwenden können. Hier sind fünf nützliche GuzzleHttp\MessageFormatter-Formate:

  1. Log-Eintrag, der die URL, Methode, und Status-Code umfasst: Format: "Request: {method} {uri}, Response: {code}"

Beispiel Output: "Request: GET http://example.com, Response: 200"

  1. Log-Eintrag, der die Anforderungsdauer und den Antwortstatus beinhaltet: Format: "Duration: {req_time}, Response: {code}"

Beispiel Output: "Duration: 1.123, Response: 200"

  1. Log-Eintrag, der die Anfrage, Antwort und etwaige Fehler anzeigt: Format: "Request:\n{request}\nResponse:\n{response}\nError:\n{error}"

Beispiel Output:

Request:
GET / HTTP/1.1
Host: example.com

Response:
HTTP/1.1 200 OK
Content-Length: 348
Content-Type: text/html

Error:
None

Der GuzzleHttp\MessageFormatter unterstützt eine Vielzahl von Platzhaltern, die in den Formatstrings verwendet werden können. Hier ist eine Liste einiger der verfügbaren Platzhalter:

ParameterBeschreibungBeispiel Output
{request}Vollständige HTTP-Anforderungsnachricht„GET / HTTP/1.1\r\nHost: example.com\r\nAccept: */*\r\n“
{response}Vollständige HTTP-Antwortnachricht„HTTP/1.1 200 OK\r\nContent-Length: 348\r\nContent-Type: text/html\r\n“
{ts}Timestamp„1519211809.123456“
{date_iso_8601}Aktuelles Datum im ISO 8601 Format„2023-06-03T14:30:00Z“
{date_common_log}Aktuelles Datum im Common Log Format„03/Jun/2023:14:30:00 +0000“
{host}Der Host der Anforderung„example.com“
{method}HTTP-Methode der Anforderung„GET“
{uri}URI der Anforderung„http://example.com“
{version}HTTP-Version„1.1“
{target}Anforderungsziel (Pfad + Abfragestring der URI)„/path?query=example“
{hostname}Der Hostname des lokalen Rechners„localhost“
{code}Statuscode der Antwort„200“
{phrase}Statusphrase der Antwort„OK“
{error}Error message„Error: Connection refused“
{req_header_User-Agent}Einzelner Request-Header„GuzzleHttp/6.3.3 curl/7.54.0 PHP/7.2.7“
{res_header_Content-Type}Einzelner Response-Header„text/html“
{req_headers}Kopfzeilen der Anforderung„Host: example.com\r\nUser-Agent: GuzzleHttp/6.3.3 curl/7.54.0 PHP/7.2.7\r\n“
{res_headers}Kopfzeilen der Antwort„Content-Type: text/html\r\nContent-Length: 348\r\n“
{req_body}Anforderungskörper„name=John+Doe“
{res_body}Antwortkörper„Hello, John Doe!“
{req_body_size}Größe des Anforderungskörpers„13“
{res_body_size}Größe des Antwortkörpers„15“
{curl_err}Fehlermeldung von cURL (falls vorhanden)„Couldn’t resolve host name“
{curl_info}Information von cURL (falls vorhanden)„Array ( [url] => http://example.com [content_type] => text/html [http_code] => 200 [header_size] => 228 [request_size] => 78…)“
{curl_version}cURL-Version (falls verwendet)„7.54.0“
{handler_stats}Handler spezifische Statistiken (falls verfügbar)„Array ( [total_time] => 0.152404 [namelookup_time] => 0.02914 [connect_time] => 0.049718 )“

Kategorien
Symfony

Symfony monolog Logs auf der Konsole anzeigen

Um die Monolog-Logs in der Symfony-Konsole anzuzeigen, können Sie Folgendes tun:

  1. Sie müssen zuerst sicherstellen, dass Monolog so konfiguriert ist, dass es auf der Konsole loggt. Dazu müssen Sie die config/packages/dev/monolog.yaml-Datei bearbeiten und sicherstellen, dass eine Stream-Handler-Konfiguration für die Konsole vorhanden ist.
monolog:
    handlers:
        console:
            type:   stream
            path:   "php://stdout"
            level:  debug
            channels: ["!event"]
  1. Es empfiehlt ich auch beim ausführen der Tests den Consolen Logger zu aktivieren in config/packages/test/monolog.yaml. Damit erhält man wertvolle Loginformationen beim Ausführen seiner Tests.
  1. In Ihrem Konsolenbefehl können Sie dann das Logger-Interface injizieren und verwenden, um Meldungen zu loggen. Hier ist ein einfacher Konsolenbefehl, der dies demonstriert:
namespace App\Command;

use Psr\Log\LoggerInterface;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;

class YourCommand extends Command
{
    private $logger;

    public function __construct(LoggerInterface $logger)
    {
        $this->logger = $logger;

        parent::__construct();
    }

    protected function configure()
    {
        $this
            ->setName('app:your-command')
            ->setDescription('Description of your command.');
    }

    protected function execute(InputInterface $input, OutputInterface $output)
    {
        $this->logger->info('This is an info log entry.');

        // ...

        return Command::SUCCESS;
    }
}
  1. Starten Sie dann Ihren Befehl von der Konsole aus, und Sie sollten die Protokolle auf der Konsole sehen:
$ php bin/console app:your-command
[2023-06-02T12:34:56.789Z] info: This is an info log entry.

Bitte beachten Sie, dass die obige Konfiguration die Logs auf allen Kanälen außer „event“ auf „php://stdout“ ausgibt. Sie können die Kanäle an Ihre Bedürfnisse anpassen.

Ebenfalls beachten Sie bitte, dass die Protokolle nur ausgegeben werden, wenn der Log-Level Ihrer Meldung dem in der Monolog-Konfiguration festgelegten Level entspricht oder darüber liegt. Im obigen Beispiel wird alles auf „debug“-Level und darüber protokolliert.

Kategorien
Angular

Angular Relogin User on Wake Up

In einer Angular-App gibt es eine Möglichkeit, ein Ereignis auszulösen, wenn ein Benutzer den Browser-Tab wieder öffnet. Dies kann mithilfe des Page Visibility API erreicht werden, das vom Browser bereitgestellt wird.

Um auf das Ereignis zu reagieren, wenn der Benutzer den Tab wieder öffnet, kannst du das visibilitychange-Ereignis an das document-Objekt binden. Hier ist ein Beispiel, wie du dies in Angular umsetzen kannst:

import {Component, HostListener} from '@angular/core';
import {AuthService} from './shared/auth/auth.service';
import {Router} from '@angular/router';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  constructor(
    private authService: AuthService,
    private router: Router,
  ) {}

  // when user is reopening app, we check if the API session is expired and user nees to login again
  @HostListener('document:visibilitychange', ['$event'])
  visibilitychange() {
    console.log('visibilitychange event');
    if (!document.hidden) {
      console.log('check if user is logged in');
      if (!this.authService.checkTokenValidity()) {
        console.log('user token validity has expired. make logout');
        this.router.navigate(['/logout']);
      }
    }
  }
}

Zusammenfassend wird dieser Code verwendet, um zu überprüfen, ob die API-Sitzung des Benutzers abgelaufen ist, wenn der Benutzer die App erneut öffnet. Wenn das Benutzertoken abgelaufen ist, wird der Benutzer automatisch zur Logout-Seite weitergeleitet. Dadurch wird eine erneute Authentifizierung ermöglicht und der Benutzer aufgefordert, sich erneut anzumelden, um auf geschützte Funktionen der App zugreifen zu können.

Kategorien
JavaScript

NVM für Windows

Der Node Version Manager, auch bekannt als NVM, ist ein Open-Source-Tool, das es Entwicklern ermöglicht, mehrere Versionen von Node.js auf ihrem System zu installieren und zwischen ihnen zu wechseln. Mit NVM können Sie problemlos zwischen verschiedenen Node.js-Versionen wechseln, ohne manuelle Installationen oder Deinstallationen vornehmen zu müssen. Das bedeutet, dass Sie für jedes Projekt die optimale Node.js-Version auswählen können, abhängig von den Anforderungen und Kompatibilitätsfaktoren.

Die wichtigsten Befehler sind:

#install a version of Node
nvm install <node-version>

#see the versions of Node you have installed on your machine
nvm list

# list all available versions including not installed versions
nvm list available

#use a specific version of Node
nvm use <node-version>

#create alias fpr nvm version
nvm alias <name> <version>

Kategorien
PHP

OpenAI ChatGPT-3 PHP Client

Mit dem folgenden Code kann man per PHP auf GPT-3 via API zugreifen. Vorraussetzung ist ein valider API Key.

<?php


// Setzen Sie Ihren OpenAI API-Zugriffsschlüssel
$api_key = '';

// API-Anfrage senden
$response = send_api_request("Wer war Pablo Picasso?", $api_key);

print_r($response);

// Funktion zum Senden einer API-Anfrage
function send_api_request($prompt, $api_key)
{
    $data = array(
        'messages' => [
            [
                "role" => 'user',
                "content" => $prompt,
            ],
        ],
        'max_tokens' => 100,
        'temperature' => 0.7,
        'model' => 'gpt-3.5-turbo'
    );

    $headers = array(
        'Content-Type: application/json',
        'Authorization: Bearer ' . $api_key
    );

    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, 'https://api.openai.com/v1/chat/completions');
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_POST, true);
    curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
    curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);

    $response = curl_exec($ch);
    curl_close($ch);

    return $response;
}
Kategorien
Diverses

Power Arbeitszeit

Ich lebe und arbeite in einer digitalen Welt, in der Ablenkungen an der Tagesordnung sind. Ich fand, dass ich meine Tage oft mit ständigen Unterbrechungen und der Notwendigkeit, auf zahlreiche Anfragen zu reagieren, verbrachte. Daher begann ich, jeden Nachmittag eine Power Arbeitszeit einzuplanen, die sich als äußerst produktiv erwiesen hat.

Jeden Nachmittag plane ich zwei Stunden meiner Power Arbeitszeit ein. Dies ist eine Zeitspanne, in der ich meine Kommunikations-Apps deaktiviere, mein Handy auf stumm schalte und alle potenziellen Ablenkungen ausschalte. Während dieser Zeit sind keine Meetings erlaubt. Ich habe festgestellt, dass ich während dieser zwei Stunden tatsächlich etwa 80% meiner täglichen Arbeit erledigen kann.

Die Planung beginnt bereits vorher. Ich erstelle eine Prioritätenliste der Aufgaben, die ich erledigen muss. Diese Liste hilft mir, meine Zeit effektiv zu nutzen und zu gewährleisten, dass ich während meiner Power Arbeitszeit an den wichtigsten und dringendsten Aufgaben arbeite.

Pünktlich zum Start meiner Power Arbeitszeit schalte ich mein Handy auf stumm und lege es außer Sichtweite. Ich deaktiviere alle Benachrichtigungen auf meinem Computer und schließe alle Tabs und Anwendungen, die nicht für meine Arbeit erforderlich sind. Besonders wichtig ist, dass ich alle Funktionen von Microsoft Teams und anderen Kommunikationstools, die ich verwende, deaktiviere.

Während meiner Power Arbeitszeit arbeite ich in konzentrierten Blöcken. Ich versuche, 1 bis 2 Stunden ununterbrochen an einer Aufgabe zu arbeiten, abhängig von der Art der Aufgabe und meiner Konzentrationsfähigkeit. Nach jedem Block mache ich eine kurze Pause, um meine Konzentration wiederherzustellen und meine Augen und meinen Körper zu entspannen.

Die Power Arbeitszeit hat meine Arbeitsweise revolutioniert. Sie hat mir geholfen, produktiver und fokussierter zu arbeiten und die Qualität meiner Arbeit zu verbessern. Ich habe weniger Stress und mehr Kontrolle über meinen Arbeitstag. Ich empfehle jedem, der Schwierigkeiten hat, sich auf seine Arbeit zu konzentrieren oder produktiv zu sein, diese Methode auszuprobieren. Sie könnte die Antwort sein, die Sie suchen, um mehr aus Ihrem Arbeitstag herauszuholen.

Kategorien
Symfony

Symfony Logging Verzeichnis anpassen

Um das Verzeichnis, in dem die Logs von Symfony gespeichert werden, zu ändern, kann man die Konfigurationsoption kernel.logs_dir verwenden. Diese Option definiert standardmäßig das Verzeichnis var/log.

Um das Log-Verzeichnis zu ändern, kann man den folgenden Code in der Konfigurationsdatei hinzufügen:

parameters:
    kernel.logs_dir: '/foo/log'

In diesem Beispiel wird das Verzeichnis /foo/log als Log-Verzeichnis verwendet.

Wenn man kernel.logs_dir in der config/services.yaml überschreibt, fügt man den oben genannten Code in den parameters-Abschnitt der Konfigurationsdatei ein.

Nach der Änderung von kernel.logs_dir muss man den Cache löschen, damit die Änderungen wirksam werden:

php bin/console cache:clear