Menschen kommen, scheitern und gehen. Der nächste wird besser sein. Es ist eine endlose Suche nach dem einen der diesen ewigen Kreislauf durchbricht. Wobei Suche der falsche Begriff ist. Es ist mehr ein warten. Ein passives Warten. Aber ganz sicher kommt irgendwann der eine oder die eine, die alles mitbringt was man haben will. Jemand der nicht auf die Hilfe der anderen angewiesen ist, die keine Zeit für sowas haben und somit das Scheitern für die meisten schon vorprogrammiert ist. Nein! Ein Mensch wird kommen und genau die Person sein, die man schon immer haben wollte.
Die anderen, die durch die Rotation gegangen sind, ziehen weiter. Zur nächsten Firma und durch den nächsten Rotationszyklus bis auch die Firma sie wieder ausspuckt. Diese Menschen sind das Rauschen, dass die gesuchten verdeckt, ihre Aufgabe ist es ausgesiebt zu werden oder bis sie sich ändern. Aber wenn sie sich ändern könnten, wären sie nicht da wo sie sind. Nicht gefangen in einen immer wieder kehrenden Zyklus von Kommen, Scheitern und Gehen gefangen.
Und somit.. mal gucken ob der nächste Projektmanager, die nächste Projektmanagerin ein weiter Zyklus in der Rotation ist oder diese Rotation durchbrechen kann.
Natürlich könnte man mehr Zeit in Auswahl, Förderung und Aufbau eigener Leute stecken.. aber das bezahlt einen eben niemand.
In HTML gibt es die Möglichkeit Inputs auch außerhalb einer Form zu haben und diese mit einer Form zu verknüpfen. Dazu nutzt man das form-Attribute. Gerade im Checkout von Shopware 6 ist es echt praktisch. Beim DatePicker besteht aber das Problem, dass das Input, dass man selbst definiert durch ein neues Input-Feld ersetzt wird, wenn Flatpickr sich initialisiert. Diesem neuen Input muss man auch das form-Attribute geben.
Tut man es nicht, funktioniert z.B. das required-Flag am DatePicker nicht.
Bei Deployments die ein per Composer erzeugtes Shopware 6 Projekt als Basis haben (was wohl alle neueren sind) muss man die JWT-Dateien immer noch zusätzlich erzeugen und sie müssen die richtigen Rechte haben.
Man kann auch Env-Variablen (JWT_PUBLIC_KEY und JWT_PRIVATE_KEY) verwenden, was bei mir aber irgendwie nicht korrekt funktionierte und beim Login in die Administration zu einer Exception führt.
Aber es gibt auch einen Weg ganz ohne JWT Keys und der verwendet das APP_SECRET aus der .env Datei.
Damit klappte auch ein Deployment auf platform.sh dann ohne Probleme.
Um z.B. in einer Gitlab Pipeline den AWS secretsmanager zu nutzen, um Passwörter oder Token abzufragen muss man erstmal den CLI Client installieren und konfigurieren. Das geht am Besten wenn man die Dateien direkt schreibt.
Eine Bestellung zu bearbeiten in dem man z.B. ein LineItem löscht benötigt die Nutzung von Versionen. Was an sich nicht schwer ist, wenn man weiß
wie man es machen muss. (Beispiel ist Shopware 6.4)
MySQL Dump bei Shopware haben manchmal das Problem, dass DEFINER und Datenbanknamen an Triggers mit exportiert werden, die nicht zur neuen Datenbank passen, wenn die Datenbank anders heißt und man einen anderen Benutzernamen hat.
Man kann dann mit einem Texteditor wie nano, vi oder Notepad++ die Datei durchsuchen und es per Hand fixen. Nur doof wenn die Datei 6GB groß ist und keiner der Editoren mehr so richtig performant mit der Datei arbeiten will.
Dafür gibt es dann in der Linux Kommandozeile sed:
mysqldump -u demouser -p demo_webshop > ./dump_for_65_update.sql
sed 's/`demo_webshop`.//g' dump_for_65_update.sql > dump_for_65_update_clean.sql
sed -i 's|/\*!50017 DEFINER=`demouser`@`localhost`\*/||g' dump_for_65_update_clean.sql
mysql --database=demo65_webshop --user=demouser65 -p < ./dump_for_65_update_clean.sql
Man kann da sicher noch allgemeine Ausdrücke für schreiben, aber das lag dieses mal außerhalb dem was der Kunde bezahlt hätte.
An sich geht es ganz einfach. In der Administration geht man auf Update, bestätigt alles, die Plugins werden deaktiviert (vielleicht auch das Language-Pack) und dann startet der Installer und .. läuft in einen Fehler und dann läuft garnichts mehr. Scheint jeden Falls öfters mal so zu passieren.
Ich hab mir ein Script gebastelt mit dem man sich eine Kopie des Shops auf die neue Version updaten kann und dann später auf diese Kopie switchen kann.
Man muss nicht alle Plugins deaktiveren, aber einfacher ist es. Also eine Kopie (Dateien und Datenbank) anlegen und da alles Plugins deaktiveren. Per SQL-Statement geht es recht schnell und einfach.
Der original Shop liegt in shop/ und der neue in shop65/. Die .env der Kopie (wegen DATABASE_URL) wird in shop_shared/ abgelegt und um LOCK_DSN="flock" und SHOPWARE_SKIP_WEBINSTALLER=1 ergänzen.
Dann das Script laufen lassen.. oder besser Zeile für Zeile per Hand ausführen.
cd ~/public_html/shop65 && composer update
cd ~/public_html/shop65 && bin/console system:update:finish
cd ~/public_html/shop65/vendor/shopware/administration/Resources/app/administration && npm install && cd ~/public_html/shop65
Ziel ist es wieder in die Administration zu kommen und dort alle Plugins zu aktualisieren. Wenn das gelungen ist, dann alle nach und nach wieder aktivieren und wieder die Themes in den SalesChannels einrichten.
Wenn Fehler auftreten immer mal wieder bin/console aufrufen, weil dann die Exceptions meistens ganz gut dargestellt wird.
So kommt man auch sehr gut ohne den Installer zu seinem aktuellen Shopware und räumt auch direkt noch etwas auf.
Arbeiten mit Dateien ist in Shopware 6 an sich recht einfach, gerade seit die Media-Entity und deren Thumbnails ein Path-Feld haben, in dem der relative Pfad direkt angegeben werden kann. Wenn man den hat muss man nur noch den absoluten Pfad bauen. Wenn man z.B. in das public/ Verzeichnis will um dort etwas zu hinterlegen oder ein Media-File zu lesen kann man sich die Umgebungsvariable mit Symfony Project Root per Dependency Injection direkt in den Constructor seines Services geben und von da aus dahin navigieren. Von der aktuellen PHP-Datei aus ist es nicht so toll, da man nicht immer weiß wo das Plugin sich befindet. Z.B: kann es im custom-Folder oder irgendwo in vendor/ sich befinden.
<argument>%kernel.project_dir%</argument>
Und was ist wenn man die Dateien in einem Cluster-Betrieb über ein S3-Bucket an die Cluster-Nodes verteilt? Shopware 6.5 hat zum Glück nicht nur Flysystem dabei, sondern nutzt es auch richtig. Man kann sich direkt per Dependency Injection das privater oder das öffentliche Dateisystem geben lassen und dann ist es egal ob es auf einem FTP, in einem S3 Bucket oder im lokalen Dateisystem liegt.
namespace HPr\FSTest\Services;
use League\Flysystem\FilesystemOperator;
use Shopware\Core\Content\Media\MediaEntity;
class MediaTest {
public function __construct(private FilesystemOperator $filesystem){}
/**
* @throws FilesystemException
*/
public function md5Media(MediaEntity $media): string {
return md5($this->filesystem->read($media->getPath()));
}
}
Um nun das passende Dateisystem zu bekommen ist nicht viel nötig.
Public ist das öffentliche Verzeichnis, das man für Product-Bilder, CMS-Media oder auch andere Downloads nutzen kann, die jeder sehen darf. Dann gibt es auch das private Dateisystem, wo man alles wie Rechnungen und Dinge ablegt, die nicht jeder sahen darf und wo man den Zugriff am besten durch einen eigenen Controller kapselt. Die MediaEntity hat einen private-Flag, um anzugeben in welchem Dateisystem man die Datei findet.
Das Dateisystem selbst kann man in einer YAML-Datei in config/packages/ definieren. Wie man da z.B. seine Dateien in einem MinIO S3 Bucket ablegen kann, habe ich in einem Post vorher schon erklärt.
Da man beim einfachen Entwickeln nicht ein AWS S3-Bucket für die Entwickler bereit stellen möchte, kann man hier sehr gut MinIO verwenden. Es lässt sich schnell in docker-compose einbinden und die FileSystems von Shopware können den normalen S3-Adapter verwenden.
Manchmal braucht einfach Imagick. Z. B. wenn man eine Bildvorschau einer PDF erzeugen will oder einfach mehr Power bei der Bildbearbeitung in PHP oder in Scripten braucht.
Während die Installation die meisten Anleitungen für Docker und Imagick mit den default PHP Docker-Image super funktionieren ist es bei Dockware anders, weil es eine volle Ubuntu-Umgebung mitbringt.
Zu beachten ist, dass man für alle PHP-Versionen die Erweiterung installieren muss.
Manchmal funktionieren ein paar Snippets nicht. Ich vermute es liegt daran wie ein Theme über nicht immer sehr gradlinige Wege überschrieben und erweitert wurde.
Z.B. steht dann "orion.footer.certificates" auf der Seite, obwohl die Snippets korrekt für alle Sprachen in der Administration gefunden werden. Also an sich sollte es dann ja funktionieren.
Lösung: Einmal den Übersetzungen ein 'X' anhängen, speichern, das 'X' wieder entfernen und erneut speichern. Dann sind sie in der Storefront auch richtig.
Weil sie dann aus der Datenbank geladen werden und nicht aus dem Theme/Plugin/App.
Zum 2024-01-01 hat One-DC Teile ihrer Dropshipping-Services abgeschaltet. Man kann immer noch Bestellungen dort per API aufgeben und diese direkt an seine Shopkunden senden, aber es gibt keine Feeds mit Produkten, Beständen und Preisen mehr. Der Sinne erschließt sich mir überhaupt nicht, da Dropshipping ja doch irgendwie weiterhin möglich ist und elektronische Katalogdaten auch für PIMs und Kassensysteme der Kunden wichtig ist. Hätte man den Versand an die Endkunden eingestellt würde ich es ja noch verstehen, aber so macht es für mich keinen Sinn. Falls jemand mehr Weiß oder eine Möglichkeit kennt Katalogdaten weiterhin zu erhalten, bitte sich per Email bei mir melden.
Import2Shop stellt deren Anbindung zu EDC auch ein und die Shops sitzen jetzt und versuchen möglichst schnell zu einem anderen Anbieter zu wechseln. Meine Plugins bleiben weiter online, erhalten aber keine Weiterentwicklung mehr und gelten ab sofort als EOL, wenn nicht sich doch noch was neues ergeben sollte.
Bei in Java bei XML ist die bekannteste Lösung manchmal nicht die Lösung, die man gerade braucht. Groß, komplex und kann alles. Dependencies machen dann aber Probleme und wenn man nur eine Datei schnell und einfach lesen möchte, braucht man nicht irgend eine HTML-Lib, die nur in ganz bestimmten Fällen nötig wäre.
Beim Lesen von Excel-Dateien in PHP ist es genau so. HTML-Lib machte Probleme beim Installieren über Composer, aber ich will ga rkeine HTML-Sachen damit machen. Cool das es gehen würde, aber ich will nur schnell und einfach die Daten der Tabelle auslesen. CSV hätte ja gereicht, aber es kommt eben eine Excel-Datei.