Blog: Latest Entries (15):


Shopware: In einer Ubuntu VM für Windows-Benutzer

Um unseren Shopware-Server aufzusetzen brauchen wir

- Apache (mit php7.0-mod)
- PHP7 (common,mysql,gd,xml,json,xsl,intl,gettext,mbstring,zip)
- MySQL Server
- OpenSSH Server
- PHPMyAdmin (wichtig hier Apache2 auszuwählen.. also mit Sternchen sichtbar nicht nur makiert)

Dann folgt die conf für den Apache und der Eintrag in die Host-Datei.

bbcode-image


Jetzt können wir Shopware downloaden und installieren

bbcode-image


Nun folgt die Netzwerk Konfiguration mit VirtualBox und die Anpassungen der hosts-Datei unter Windows.

bbcode-image


bbcode-image


bbcode-image


bbcode-image


Am Ende können wir mit dem Browser auf Shopware und mit WinSCP auf das System und das Shopware-Verzeichnis zugreifen.

bbcode-image


bbcode-image


So können wir unser lokalen Plugin-Verzeichnis mit dem auf dem Server synchron halten und Änderungen werden automatisch auf den Server gepusht.

Mein 1. Shopware Plugin verfügbar

Es ist soweit.. mein erstes Shopware Plugin ist im Community Store verfügbar.

bbcode-image


Kunden-Registrierung blockieren

Toll fand ich, dass man während des Freigabeprozesses wirklich mit Menschen zu tun hatte und einem auch wirklich von sich aus geholfen wurde.
Meine Erfahrungen beim Mozilla Store für Firefox OS waren da ganz anders. Da erhielt man eine Email mit sehr allgemeinen Punkten gegen was man verstoßen hätte und Hilfe was man noch müssen für die Freigabe gab es so gar nicht.
Deswegen werde ich mich dann jetzt daran machen weitere Plugins zu schreiben und zu veröffentlichen.

Erstmal Shopware mit Vagrant auf meiner Windows Workstation zum Laufen bekommen. Dann geht es sicher alles noch schneller und einfacher.

Oder ich richtige mir doch eine eigene Ubuntu VM ein... mal gucken.

Shopware-Plugin: Customer Register Handling 2.0

Auch wenn die erste Version noch nicht wirklich weiter ist, was die Freigabe betrifft, habe ich hier schon mal die ersten Test mit der 2.0 Version.

bbcode-image


Wenn man einen öffentlich erreichbaren Shop hat, den jeder ohne Umwege von zu hause aus erreichen kann, aber sich nur bestimmte Kunden, wie eigene Mitarbeiter oder Mitarbeiter von Partner Firmen, registrieren dürfen, kann man nun Black- und Whitelists verwenden.

bbcode-image


Darin kann man Email-Adressen oder Domains (z.B. "*@hannespries.de") angeben und invalide Email-Adressen, werden erst gar nicht zum Anmelden zugelassen und der Kunde mit einer Nachricht darüber informiert, dass seine Email-Adresse nicht den Anforderungen entspricht.

Wer also einen Mitarbeitershop hat, kann nun nur Anmeldungen mit der Firmen-Email-Adresse zulassen und muss keine Konten per Hand oder auf Verdacht per Job anlegen lassen.

Shopware: Erstes Plugin auf dem Weg

.. hoffentlich :-) Hat jetzt doch ein paar Monate länger gedauert, bis alles so weit war. Die nächste Version mit White- und Blacklists, die bestimmen, mit welchen Email-Adressen und Domains sich Kunden registrieren dürfen, ist auch schon halb fertig.

Ich hoffe mal, dass das Plugin ohne größere Probleme in einiger Zeit dann in den Store gehen kann und ich dann ein paar andere Ideen für Plugins umsetzen kann.

bbcode-image


Wäre auf jeden Fall toll damit etwas Geld verdienen zu können, da mir Shopware-Plugins sehr viel mehr zusagen als Apps zu Entwickeln oder zu versuchen mit Werbung meine Projekte wenigstens ohne Zuzahlung betreiben zu können.

Vielleicht kann ich dann ja auch https://www.mein-online-adventskalender.de/ als Shopware Einkaufswelt-Element etwas pushen.

Shopware: REST-API und Artikelbilder

Es fällt schnell auf, dass wenn man das Array mit den Bildern im Article-Model der REST-API ersetzt, die neuen Bilder nicht die alten ersetzen, sondern nur hinzugefügt werden. Das funktioniert auch super bei den selben Bildern, so das in einigen Fällen (wenn man nicht weiß, ob es neue Bilder sind oder nicht) sich doppelte Bilder im Artikel häufen.

Zum Glück bietet die REST-API den Merge Mode an. Dieser gilt für Bilder und Kategorien.

Man muss nur ein neues Feld in den Artikel einbauen:


{
"__options_images": {"replace": true},
"images": []
}


Damit wird dann einfach das alte Array geleert bevor die neuen Einträge hinzugefügt werden.

engine/Shopware/Components/Api/Resource/Artile.php (5.3.3)


Zeile 2373: $images = $this->checkDataReplacement($article->getImages(), $data, 'images', false);


Default ist hier false. True als Defaultwert hätte ich persönlich logischer gefunden, bzw. eine Einstellung dafür in den Grundeinstellungen, um den Default-Wert zu ändern.

Shopware: Legacy-Plugin Service dekorieren

Gehen wir mal davon aus wir hätten noch ein Legacy-Plugin mit einer Bootstrap-php, die einen Service registriert, den wir dekorieren wollen. Über die services.xml geht so etwas nicht.


class HprTest extends Plugin{
public static function getSubscribedEvents(){
return [
'Enlight_Bootstrap_AfterInitResource_hpr_legacy.the_service' => 'decorateService',
];
}

public function decorateService()
{
$coreService = Shopware()->Container()->get('hpr_legacy.the_service');
$refl = new \ReflectionClass(get_class($coreService));

$field = $refl->getProperty('config');
$field->setAccessible(true);
$config = $field->getValue($coreService);

$service = new TheNewService($config);
Shopware()->Container()->set('hpr_legacy.the_service', $service;
}
}


Sehr sehr unschön.. aber es funktioniert so. Der Weg über die XML ist natürlich sehr viel schöner, gerade weil die Injection der Constructor Arguments vom ursprünglichen Service übernommen werden man nicht diese per Reflections erst einmal wieder aus dem ursprünglichen Service heraus gepult werden müssen.

Shopware: Text-Snippets und Übersetzungen

Am Ende dachte ich mir nur: "ist an sich ja genau so wie in meinem Framework.."

Ok. Alle Sprachen in einer Datei und nicht wie bei den Properties-Dateien in Java, aber ansonsten. Im Grunde hat man eine ini-Datei die eingelesen wird. Sie hat einen Namespace, was es sehr viel einfacher macht auf Text-Snippets anderer Plugins oder des Core-Systems zuzugreifen.


custom/plugins/HPrTest/Resources/snippets/frontend/index/hpr_main.ini


Da kommen dann die Texte rein


[de_DE]
blubb = "Blubb"


Wenn man das Plugin nun installiert oder aktualisiert, kann man die Snippets im Template verwenden.


{s name="blubb" namespace="frontend/index/hpr_main"}{/s}


An sich ja wieder sehr einfach, wenn man erst einmal heraus gefunden hat, wie sich der Namespace bildet und wo man die Datei genau ablegen muss.


Java Time-API.. hart aber gut

Das Arbeiten mit der Time-API von Java ist teilweise echt nicht einfach. Auch gibt es vielmehr zu schreiben und ohne Hilfe aus dem Internet geht es einfach nicht. Wobei ich die ".from()"-Methoden schon wirklich nett finde.


DateTimeFormatter formatter = DateTimeFormatter.ofPattern(pattern);
LocalDateTime ldt = LocalDateTime.parse(value.trim(), formatter);

//Calendar
GregorianCalendar gc = GregorianCalendar.from(ldt.atZone(ZoneId.systemDefault()));

//SQL-Timestamp
preparedStatement.setTimestamp(1, Timestamp.from(ldt.atZone(ZoneId.systemDefault()).toInstant()));


Wenn man die letzten 2-3 Jahre fast nur PHP gemacht hat, erschlägt einen es fast schon, von der Fülle an Kombinationen und Klassen die man hier benötigt. Jeden Falls auf den ersten Blick. Auf den zweiten sieht es besser aus und auf den dritten gefällt es einen dann auch schon wirklich.

Und im Gegensatz zum guten alten Date mit SimpleDateFormat funktioniert es auch ohne Probleme.
Java tut auch hier was es am Besten kann: Es zwingt einen es richtig zu machen.. mit ZoneId und allem was man sonst der Bequemlichkeit halber oft lieber weg lässt.


"Das ist nun mal seine Art..."

Jeder der schon mal irgend etwas wie eine Teamleitung hat oder mit einer größeren Gruppe einen Konsens finden musste, weiß, dass jede Person gerade in Diskussionen besondere Eigenarten hat. Das kann sein, das jemand sich komplett aus der Diskussion verabschiedet, wenn er nicht Recht bekommt. Oder jemand sofort sagt er habe wohl sich geirrt und seine Argumente zurückzieht, wenn ein oder mehrere Gegenargumente auf den Tisch kommen. Aber auch Leute die lauter werden, um ihren Standpunkt Gewicht zu verleihen.
Alles davon kann nervig sein, aber so sind diese Personen nun mal.. es ist ihre Art. Wenn man das weiß, kann man gut damit umgehen, weil ja auch niemand dadurch angegriffen wird oder so.

Das jeder seine persönliche Art hat, ist ja auch schön. Weil auch erst so sieht man Argumente auf von verschiedenen Seiten und wenn jemand ein Argument falsch versteht, ist es auch gut zu wissen, dass man das Argument falsch verstehen kann.

Aber es gibt auch diese andere Art von Menschen und ihre Art. Die verstehen "Das ist nun mal meine Art" als eine Ausrede, warum ihr schlechtes Verhalten hinzunehmen ist. Denn sie stimmen eben dem voll und ganz zu, dass jeder nun mal seine Art habe und man das ja so hin nehmen muss. Die Person könne ja nun mal nichts für ihre Art.

Mit so einem Mensch zu diskutieren ist echt "lustig". Einige hören einen nicht zu und sobald sie ihre Position durch Argumente gefährdet sehen, kommen nur noch persönliche Angriffe. Oder Leute die einen doof anmachen, weil die es gerade nicht mochten wie man sie Angesprochen hat. Oder auch andere Leute mit vielen Schimpfworten belegen, weil die nur eben mal was anderes mögen und man dann selbst noch was abbekommt, weil man anmerkt, dass es doch gar nicht schlimm ist, eine andere Ansicht zu haben.

Wenn man dann diese Leute darauf anspricht (oder auch jemand vertrautes dieser Person) kommt oft: "Das ist nun mal meine/seine/ihre Art". Wenn man es dann eskalieren lassen will, muss man nur sagen: "Dann ändere deine Art"... ohhhh.. dann geht es los.. wie kann es wagen jemanden seine Art abzusprechen und jeder hätte en Recht so zu sein wie er ist .. bla ..bla.. bla.

Wenn mich jemand beleidigt oder scheiße behandelt und ich dann zu hören bekomme "Das ist..." .. ja.. wieder der alte Satz, dann muss man sich nicht wundern, wenn diese Person für mich gestorben und nicht mehr haltbar ist.
Ich als Teamleiter würde diese Person direkt aus dem Team entfernen. Niemand hat das Recht so mit jemanden umzugehen. Die Person darf natürlich gerne wieder kommen, wenn sie gelernt hat sich zu benehmen. Aber nicht so.

Die Art eines Menschen ordnet sich folgenden Dingen (und bestimmt noch vielen anderen Dingen mehr) unter:
- Respekt
- Benehmen
- Anstand
- Gesellschaftlichen Konventionen
- den elementaren Regeln des Zusammenlebens

Wenn ich nun keinen Respekt vor jemanden habe und meinen Anstand in einer Situation gerne mal vergessen möchte.. gerne.. aber dann muss man mit den Konsequenzen leben und nicht angekommen mit ... "Das ist nun mal meine Art".

PS: Das musste ich einfach mal aus aktuellen und privaten Anlass mir mal von der Seele schreiben :-)

Shopware: Product-Streams und Kategorien

Wie füllt man Kategorien in Shopware mit möglichst wenig Aufwand und weitestgehend automatisch?

Man kann könnte das im Import erledigen oder jemanden davor setzen, der alle Artikel in die entsprechenden Kategorien einsortiert. Wenn man aber nun eine neue Kategorie anlegt, müsste man durch alle Artikel gehen und gucken, ob man diese dort einsortieren muss.

Aber Product-Streams bieten hier eine tolle und einfache Lösung an. Weil hier kann man aus der Menge aller Produkte filtern. Einer Kategorie kann dann der Stream zugeordnet werden.

Als Beispiel nehmen wir Hersteller-Kategorien. Man will ja nicht jedes Produkt bei der Neuanlage der Kategorie zu ordnen müssen, die für den Hersteller existiert.

Wir erstellen uns einen Stream der nach unseren Hersteller filtert.

bbcode-image


Nun erstellen wir uns eine Kategorie für den Hersteller und wählen den Stream aus.

bbcode-image


Im Frontend sind in der Kategorie nun alle Produkte des Herstellers zu finden, ohne dass wir nur einen Artikel per Hand einsortieren mussten.

bbcode-image


Product-Streams sind sehr praktisch und nehmen einen viel Arbeit ab.


Ein kurzer Blick auf SAP OpenUI 5

Ich hab mich die letzten Jahre doch etwas schwer getan mit JavaScript-Frameworks, die sich stärker von AngularJS unterscheiden. Knockout gefiel mir sonst auch ganz gut, auch wenn ich es ansich nie produktiv genutzt habe. Es war eben MVVC mit Templating direkt im HTML. Mein eigenes kleines Framework war auch genau so konzipiert und funktioniert bis heute gut in MP4toGIF.com.

Angular 2 sah immer interessant aus, aber irgendwie habe ich es dann doch nicht geschafft mir es mir als anzusehen. Dabei schreckte mich eher Typescript ab, was aber auch ja optional ist. Andere Sprachen und dann alles zu kompilieren mag ich bei JavaScript nicht so sehr.. da waren meine Erfahrungen mit Coffee-Script zu.. ja.. ernüchternd. Die Umgebung zum Entwickeln auf zu setzen ist vergleichbar mit dem Aufwand bei Java oder PHP. Das Debugging ist mit nativen JavaScript sehr viel einfacher gewesen.

Mit Shopware kam dann Ext JS in mein Leben. Seit Groupware und Tine 2.0 habe ich alles versucht diesem Framework aus dem Weg zu gehen. Man kommt damit zu recht, aber es ist echt nicht einfach sich dort einzuarbeiten und mal schnell eine kleine UI zu basteln, ohne sich wirklich einmal mit dem Framework auseinander zu setzen. Angular JS ist da sehr viel einfacher, aber dafür hat man eben auch nicht diese komplexe UI.
Um ehrlich zu sein, würde ich dann aber bei solchen UIs das Ext JS-Framework anderen Frameworks aus dem Desktop-Bereich wie SWT, Swing oder JavaFX vorziehen.

Heute habe ich mich mal durch die Dokumentation und die Beispiele von SAP OpenUI 5
geklickt. Es sieht etwas nach Ext JS aus, aber irgendwie spricht es mich spontan eher an. Nicht wie das erste mal mit AngularJS.. gesehen.. verstanden .. und gleich erfolgreich eingesetzt.Aber mein Gefühl war besser als bei Ext JS .. so ungefähr auf Angular 2 Niveau.

Vielleicht habe ich ja mal die Gelegenheit was damit zu machen. Momentan habe ich weder Projekt noch Zeit dafür. Aber es sieht so interessant aus, dass ich gerne was dafür hätte... gerade der Planning Calendar sieht echt gut aus.

Xeon: "Das ist eine Server-CPU..."

Es begab sich gestern Abend, dass meine Frau gerne einen neuen PC haben wollte und diesmal auch gerne etwas modernes. Ich persönlich neige ja oft dazu die schon getragenen Sachen der letzten 4-5 Jahre noch mal neu aufzutragen, weil die eben günstig sind und meistens noch genug leisten, um alle Aufgaben gut bis sehr gut zu erledigen.

Mit dem Ryzen und dem Threadripper sind jetzt aber doch wieder CPUs am Markt, die wirklich gut und auch dabei durch aus bezahlbar sind.

Ein Threadripper ist trotzdem noch sehr teuer und oft braucht man diese Leistung und Anzahl an Kernen auch gar nicht. Aber es er stand zur Diskussion.

Und wie es nun mal ist, wenn man ein PC zusammenstellt, wurde die Zusammenstellung mit anderen Personen diskutiert. Als Alternative zum Threadripper nannte ich dann einen Xeon Silver mit 12 Kernen für einen leicht höheren Preis wie der Threadripper. Als Antwort kam:


Das ist eine Server-CPU, sie ist ......


bbcode-image


Das habe ich schon so oft gehört. Aber am Ende wird es nicht wahrer, nur weil viele Leute es immer wieder herunter beten. Das kommt aber auch hauptsächlich von Leuten, die ihrer PCs noch selbst zusammen bauen und damit Komplett-Systemen so wie so so entgegen treten, dass der Hersteller da Unsinn zusammen gebaut hat. Mit dieser Aussage hebt man sich also auch über Hersteller wie HP, Lenovo, Dell, etc (wie Apple) die noch echte Workstations bauen und eben auch für entsprechende Preise an bieten (wie gerade die HP Z8).
So ein System kostet in einem besseren Ausbau gerne mal schnell 6.000-8.000 Euro und es kann noch weiter hoch gehen.

Aber wer glaubt nur Idioten, die sich ja nicht mit PCs auskennen, würden solche Systeme kaufen, liegt wohl komplet daneben. Es geht um zertifizierte Treiber und Systeme, für die Software Hersteller eine Funktionsfähigkeit ihrer Produkte Garantieren.
Solche Systeme mit Medion oder MediaMarkt Systemen zu vergleichen ist einfach realitätsfremd. Niemand der meint im Internet surfen und Emails schreiben zu wollen, würde sich eine HP Z8 kaufen. Deswegen ist auch die Annahme vieler, die Leute bei z.B. HP hätten keine Ahnung und hätten deswegen falsche CPUs verbaut, mehr als überheblich und seltsam, denn wer ein Mainboard konstruieren kann (es sind keine Komponenten von der Stange dort verbaut), wird wohl genug Fachwissen haben auch die passende CPU zu wählen.

bbcode-image


Xeon wurden seit ihrer ersten Version (noch im Module für den Slot 2) in Workstations verwendet. Damals gab es sogar noch 4x CPU Workstation wie z.B. SGI VW 540. Die Nutzung in Workstations ist seit dem auch nicht abgebrochen, auch wenn gerne mal i7 in den kleineren Workstation Versionen verbaut werden. Aber es war nie so, dass Xeon ausschließlich für Server gebaut oder vermarktet wurden. Auch deren Feature-Set zeigt, dass zwar Server ein primäres Einsatzgebiet für Xeons sind, aber auch Workstations genau so wichtig sind. Außerdem unterscheiden sich die Anforderungen heut zu tage kaum noch zwischen Server und Desktop. Früher waren Server Multithreaded und Desktop-Anwendungen weniger.. heute ist alles so weit wie es geht Multithreaded.

Eine Ausnahme ist wohl die E7 Serie für Quad und Octa Systeme. So ein System ist aber auch nicht praktikabel als Desktop zu realisieren. Aber auch hier skaliert man heute lieber horizontal als vertikal und kauft dann lieber ein weiteres E5-System und lässt beide im Cluster laufen. Da sowie so meistens mehrere VMs darauf laufen, ist es auch egal ob diese auf dem selben Server laufen oder auf zwei Maschinen, was sogar die Ausfallgefahr reduziert.

Aber wäre weiterhin glauben will, man könne Xeons nur in Servern verbauen, beraubt sich selbst einer oft guten und manchmal auch kostengünstigen Alternative zu den Highend-Desktop CPUs wie ddem i7 oder i9. Besonders wenn man wirklich viele Dinge gleichzeitig macht, sind 2 CPUs oft besser und einfacher zu kühlen als eine einzige extrem hoch gezüchtete CPU.

Wer wirklich fast rein auf Serverbetrieb ausgelegt CPUs sehen möchte muss sich Sparc ansehen. Selbst für die Power-CPU von IBM gibt es Workstations.

Older posts: