Hallo liebe Community,
habe mi einen eigenen Controller gebastelt, welcher auch ausgeführt wird.
Jetzt wollte ich gerne die kompletten Artikel laden und habe in der index action folgendes eingefügt:
$sArticle = Shopware()->Modules()->Articles()->sGetArticlesByCategory();
$this->View()->assign('sArticles', $sArticle);
Allerdings wird im Frontend nur etwas angezeigt, wenn ich folgenden Code einfüge:
{foreach $sArticles as $sArticle}
{$sArticle|@print_r}
{/foreach}
Möchte ich nur die Artikelnummern haben:
{foreach $sArticles as $sArticle}
{$sArticle.ordernumber}
{/foreach}
dann erhalte ich einen fatalen Fehler:
Fatal error: Uncaught Error: Cannot use object of type Shopware\Bundle\SearchBundle\Criteria as array in .....
Jetzt stellt sich mir natürlich die wichtige Frage:
Hole ich überhaupt die ganzen Artikel richtig ab?
Hatte mir dafür den Listing und Detail Controller angeschaut.
Und auch im Forum habe ich schon geschaut.
Um es ganz einfach zu machen, dann bitte nur EINE Frage beantworten:
Wie bekomme ich alle Artikel in meinem Controller ???
Wie ich sie dem View zur Verfügung stelle weiß ich.
Hoffe auf eine baldige Antwort.
L.G.
Wenn dein print_r passt, dann liegt es ja nur an der Ausgabe. Die von dir gepostete Fehlermeldung deutet ja auch darauf hin, dass du das Object falsch ansprichst. Vermutlich musst du dann einfach {$sArticle->get(“ordernumber”)} oder sowas in der Art machen.
Eventuell kannst du dir auch damit behelfen, dass du das Objekt in ein Array umwandelst, bevor du damit was machst. Das geht am einfachsten mit $sArticle = json_decode(json_encode($sArticle), true);
Was komischerweise funktioniert ist:
$sArticle = Shopware()->Modules()->Articles()->sGetArticlesByCategory()['sArticles'];
$this->View()->assign('sArticles', $sArticle);
und wenn ich das über eine foreach schleife laufen lasse, dann werden aber nicht ALLE Artikel ausgegeben.
Warum nur???
Hi hoppler,
Du musst noch das Limit via Criteria Object entfernen:
$criteria = new \Shopware\Bundle\SearchBundle\Criteria();
$criteria->limit(null);
$sArticle = Shopware()->Modules()->Articles()->sGetArticlesByCategory(null, $criteria)['sArticles'];
Hallo MrMDeluxe,
super, lieben Dank, hat auf Anhieb geklappt!!!
Jetzt werden mir Alle Artikel korrekt angezeigt.
Eine Frage hätte ich allerdings noch:
Gibt es auch eine “einfache Weise” im Controller das infinity scrolling mit zu aktivieren?
L.G.
Hoppler
Hey,
das infinite scrolling wird ja mit einem jquery plugin realisiert.
Du musst daher deine Templates auch mit den benötigten Data Attributen versehen.
Schau Dir mal den Block “frontend_listing_listing_content” in der listing.tpl an.
Danke! Danke! Danke!
Manchmal reicht schon ein kleiner Schubser in die richtige Richtung.
L.G.
Hoppler
Hallo nocheinmal.
Nun, ich habe mir die Daten in der Listing.tpl angeschaut:
{* Actual listing *}
{block name="frontend_listing_list_inline"}
{foreach $sArticles as $sArticle}
{include file="frontend/listing/box_article.tpl"}
{/foreach}
{/block}
Erst einmal passiert nichts. Doch wenn ich die Variable {$pages} fülle -> Aufgerundet (Artikelmenge geteilt durch Artikel_pro_Seite), dann steht in der Url /p=1
Wenn ich runterscrolle ändert sich nichts an der p=1.
Also schaute ich im infinity.js nach und sah, das der Wert “data-page-index” nicht gesetzt war. Ich setzte die Werte nun mit einem kleinen Javascript.
Wenn ich jetzt runterscrolle (ich habe 29 Artikel) änder sich p=1 auf p=2 und auf p=3.
beim hochscrollen, von p=3 auf p=2 und schließlich wieder auf p=1.
Wenn ich allerdings ganz runterscrolle, dann sehe ich das Ajax Lade Symbol und die Seitenzahlen in der Url ändern sich nicht mehr, beim hochscrollen.
Leider funktioniert das Nachladen immer noch nicht.
L.G.
Hoppler
Moin @hoppler,
das klingt ganz stark nach einem Javscript Fehler, der da am Ende auftaucht.
Hast du mal in die Konsole geschaut, was genau er da tut?
Ich schätze ja, dass der AJAX Request, der die Artikel für die jeweilige Seite laden will, ins Nichts läuft.
Da sollte dir aber wie gesagt die Browser Dev Konsole weiterhelfen.
Gruß,
Patrick
Hallo Patrick,
danke für Deine Antwort.
Was mich etwas irritiert ist der Umstand dass ich nicht genau weiß welche Variablen ich füllen muß, damit das infinity scrolling greift.
Ein kleiner Tip wäre super hilfreich.
L.G.
Hoppler
Vergessen: Ich beziehe mich da auf:
{* Actual listing *}
{block name="frontend_listing_list_inline"}
{foreach $sArticles as $sArticle}
{include file="frontend/listing/box_article.tpl"}
{/foreach}
{/block}
$pages habe ich befüllt - und es zählt auch auf, aber wie lädet er nach?.
Hey @hoppler,
hast du denn nun mal in die Dev Konsole des Browsers geschaut, ob da ein Javascript Fehler auftaucht?
Und wenn ja: Welcher?
Das wäre halt enorm hilfreich, um dir vernünftig weiterhelfen zu können.
Problematisch ist vermutlich die Tatsache, dass das Infinite Scrolling Plugin eine Kategorie braucht - und so wie ich deine Anfrage verstehe, hast du da keine Kategorie, oder?
Die benötigt er nämlich für die jeweiligen AJAX Requests.
Gruß,
Patrick
Hallo Patrick,
stimmt, ich habe keine Kategorie. Ich rufe meinen Controller über einen Click Event auf.
Müßte ich denn nun noch eine Kategoie anlegen?
Also, der Controller heißt, sagen wir mal: „Lister“.
Den controller rufe ich ja auch mit „Mein-Shop/lister“ auf.
Könnte ich die Kategorie im Subscriber erstellen, oder schon in der Install, wegen dem Deinstallieren - mmmmmh?
Und wenn ich die Kategorie programmisch erstellen möchte, wie mache ich das?
Eventuell noch mit der gewünschten Position?
Vielen Dank schon mal für Deine Hilfe - bin ein echter Fan von Dir.
L.G.
Hoppler
Guten Morgen @hoppler,
die Kategorie wird unter Anderem deshalb gebraucht, weil er anhand der Kategorie ID und anhand des „?p“ Query Parameters eben die nächsten Artikel raussucht, die geladen werden müssen.
Er greift dann auf eine Standard Funktion zu, die die Artikel einer Kategorie lädt - das funktioniert ja bei dir auch dann nicht, wenn du eine eigene Kategorie erstellst.
Du musst dich selbst um sowas kümmern, also:
- Eine eigene Action schreiben, die eben den „p“ Parameter annimmt und verwerten kann
- Das jQuery Plugin so umschreiben, dass die AJAX Requests nicht gegen einen Standard-Controller feuert, sondern gegen deinen eigenen Controller
Das passiert übrigens hier (Feuert ein Event „Hol mal Daten!“) und hier (Horcht auf das Event und feuert den AJAX Request).
Aber mal anders gefragt:
Wäre es nicht eine Option, einfach einen Product Stream anzulegen, der alle Artikel umfasst (Einfach einen Filter anlegen, der auf alle zutrifft, bspw. „Lagerstand > 10000000“), und dann eine Kategorie erstellen, die diesen Product Stream lädt?
Dann müsstest du garnichts programmieren und alles müsste Out of the box funktionieren - und du hast direkt eine vernünftige SEO URL!
Gruß,
Patrick
Hallo Patrick,
danke für Deine tolle Hilfe.
Habe eine neue Kategrie angelegt und alle Artikel mit dieser verknüpft.
Des weiteren habe ich es jetzt mit dem dekorieren des Services gemacht, nach der Anweisung hier:
https://developers.shopware.com/developers-guide/shopware-5-core-service-extensions/
Das funktioniert auch recht gut.
Selbst das infinity scrolling funktioniert.
Allerdings nicht richtig.
Verändere ich die Produktliste, z.B. möchte ich nur alle ungeraden Artikelnummern, dann geht das auch.
Da ich ja nun dadurch auch die Artikelmenge verändere passt das plötlich nicht mehr im infinity scrolling.
Denn dort schaltet „P=1“ auf „P=2“ schon nach 6 Artikeln um und nicht nach 12!
Wo muß ich dem infinity scrolling sagen das sich die Artikelmenge geändert hat?
Denn auch beim Filterergebnis steht immer noch die doppelte Anzahl an Artikeln.
Angeblich findet der Filter 100 Treffer, obwohl ich doch nur 50 Artikel über den Service habe.
Kannst Du mir bitte hier helfen?
Das mit dem Service dekorieren war eine super Idee. Ich wollte nach dem RedisProductService - Prinzip vorgehen - also meine Liste übernehmen -, aber auch das geht nicht.
L.G.
Hoppler
Moin!
Was meinst du mit “Verändere ich die Produktliste” - wo tätigst du diese Änderung?
Per Javascript?
Ich bin mir leider momentan nicht ganz sicher, was du da jetzt machst.
- Löst du es per Kategorie mitsamt Product Stream? Wenn ja: Warum hast du dann noch on top einen eigenen Service? Wäre dann eigentlich nicht notwendig, dann würde das der Core-Code alles automatisch übernehmen.
- Löst du es dann doch lieber per eigenen Listing Service? Wenn ja: Wo tätigst du die genannte “Veränderung der Produktliste”? Direkt beim Initialen Laden des Listings?
Per Javascript zwischendurch durch bspw. einen Knopfdruck o.Ä.?
Entschuldige, dass ich gerade leider nicht mehr ganz folgen kann, wie du das Thema jetzt angegangen bist und was jetzt wann passiert.
Aber, eine Frage möchte ich dennoch beantworten:
“Wo muß ich dem infinity scrolling sagen das sich die Artikelmenge geändert hat?”
Garnicht. Das Infinite Scrolling Plugin hat keine Ahnung über die Anzahl Artikel.
Alles, was es macht, ist:
“Frag den Service nach Artikeln auf Seite X” > Service liefert Artikel > “Zeige alle vom Service gelieferten Artikel an und, sobald der Scroll den letzten Artikel erreicht hat, frag den Service nach den Artikeln auf der nächsten Seite”
Wenn du dynamisch per Javascript Artikel zwischendrin entfernst, verwirrst du damit das Plugin.
Gruß,
Patrick
Hallo Patrick,
alles noch einmal auf Anfang.
Was möchte ich machen?
Ich möchte eine neue Kategorie (über ein Plugin) erstellen. sagen wir „2018“.
In dieser kategorie möchte ich gerne alle Artikel aus dem jahre 2018 haben.
Ich hatte es über einen eigenen Controller versucht - da klappt dann das infinity scrolling nicht - gab ja auch keine Kategorie.
Nun versuchte ich den Service zu dekorieren.
Was auch nur bedingt klappt, da ich dort keine Filterung machen kann. Ich verstand nicht, dass der dekorations service dafür da ist um Artikeln Atrribute hinzuzufügen o.ä.
Also wie kriege ich es hin, das in der neu angelegten Kategorie nur Artikel aus dem Jahr 2018 angezeigt werden?
Ein Tip wäre echt super, da ich schon langsam verzweifel.
L.G.
Hoppler
Moin @hoppler,
das würde ich dann aber wirklich über Product Streams lösen.
Leider gibt es keinen Filter, der sagt: “Nur Artikel, die im Jahr X eingestellt worden sind” oder “Nur Artikel, die vor Datum X eingestellt sind”.
Da fallen mir also zwei Wege ein:
-
Du legst ein neues Freitextfeld für alle Artikel an und pflegst diese Information dort. Alle Artikel, die du in 2018 sehen willst, bekommen also den Wert “2018” in eben jenes Freitextfeld. Anschließend wählst du den “Attributsfilter” und dort wählst du dein neues Freitextfeld aus. Als Operator stellst du “=” ein, als Wert “2018”. Diesen Product-Stream
weist du dann deiner Kategorie zu. Dann musst du halt drauf achten, dass alle neuen Artikel, die du auch in dieser Kategorie sehen willst, eben das Freitextfeld gefüllt bekommen müssen.
-
Du legst dir über ein Plugin einen neuen Product Stream Filter an. Wenn ich das richtig in Erinnerung habe, haben wir dafür aber leider keine Dokumentation und das ist für einen Laien (Entschuldige, falls du nicht in die Kategorie eines Programmierer Laien fällst!) eher extrem schwierig umzusetzen.
Auf jeden Fall könntest du die Logik deines eigenen Filters ja dann selbst bestimmen, also, dass er nur Artikel zulassen soll, die als “Einstelldatum” halt 2018 besitzen.
Diesen eigenen Filter nutzt du dann im Product Stream - et voila.
Falls das “2018” nur ein Beispiel war - im Normalfall kannst du solche Szenarien allgemein am Besten mit den Product Streams lösen.
Gibt es da einen Grund für dich, nicht Product Streams zu nutzen? Oder waren die dir einfach bislang unbekannt?
Gruß,
Patrick
Hallo Patrick,
nun Product Streams waren mir noch nicht bekannt - obwohl ich die schon einmal in den kategorien gesehen habe.
Wäre es da nicht einfacher mit einem eigenen Controller zu arbeiten?
Dort könnte ich ja selber die Produkte aus der DB holen und nach meinen Wünschen filtern.
Was ich ja eigentlich schon ganz am Anfang gemacht hatte.
Nur funktionierte dort das infinity scrolling nicht und es gab auch keine Shopware Standard Filter.
Geht das den nicht, dass ich einen eigenen Controller verwende, der die Artikel für eine bestimmte Kategorie manipuliert?
Denn die Artikel haben ja schon das Einstelldatum im Array.
Angenommer ich mache eine Kategorie „2018“ und erstelle einen Controller mit dem Namen „2018“, dann würde der Controller doch gefeuert wenn ich die Kategorie „2018“ aufrufe, oder nicht.
Wie gesagt, den Controller bekomme ich zum laufen und auch den Controller über ajax neu zu starten klappt (falls ich Artikel aus 2019 möchte).
Allerdings stellt sich hier die Frage für mich, wie bekomme ich das Ergebnis in ein sauberes Listing, mit infinity scrolling?
Ich weiß das es viel ist, was ich verlange, aber ich bin ein „Kernbeißer“ und möchte gerne dieses Problem lösen - weil ich es VERSTEHEN möchte und LERNEN.
L.G.
Hoppler
Moin @hoppler,
leider ist das nicht mal eben so erklärt, wie man programmatisch ein eigenes Listing aufbaut.
Ich habe dazu jetzt auch auf die Schnelle kein öffentlich zugängliches Beispiel dafür gefunden und leider auch nicht die Zeit, dir das jetzt hier zu erklären - da gehören einfach zuviele Facetten dazu.
Aber mal eine andere Frage:
Besitzt du zufällig eines unserer Premium Plugins “Bundle”, “Liveshopping” oder “Bonus-System” ?
Warum ich frage?
Weil wir das genau dort schon umgesetzt haben - die haben jeweils ein eigenes Listing und wenn du sowieso darüber verfügst, könntest du es dir dort abschauen.
Gruß,
Patrick