Ich hatte es schon fertig und dachte ich könnte es später auch mal im Community Store anbieten.. aber dann kam mir schon jemand zu vor und dann auch noch kosten los.
Also hier einfach mein Plugin als Code für jeden:
<?php
namespace HPrExportAttrExtend;
use Doctrine\DBAL\Connection;
use Shopware\Components\Plugin;
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.
Jetzt können wir Shopware downloaden und installieren
Nun folgt die Netzwerk Konfiguration mit VirtualBox und die Anpassungen der hosts-Datei unter Windows.
Am Ende können wir mit dem Browser auf Shopware und mit WinSCP auf das System und das Shopware-Verzeichnis zugreifen.
So können wir unser lokalen Plugin-Verzeichnis mit dem auf dem Server synchron halten und Änderungen werden automatisch auf den Server gepusht.
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.
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.
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.
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.
.. 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.
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.
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:
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.
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));
$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.
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.
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.
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.
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 :-)
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.
Nun erstellen wir uns eine Kategorie für den Hersteller und wählen den Stream aus.
Im Frontend sind in der Kategorie nun alle Produkte des Herstellers zu finden, ohne dass wir nur einen Artikel per Hand einsortieren mussten.
Product-Streams sind sehr praktisch und nehmen einen viel Arbeit ab.
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.