Sieht mir so aus, als ob du im IE9 den Seitenzoom an hast. Versuch mal Strg+0, um die Anzeige auf 100% zu setzen.
Seitenzoom ist nicht aktiviert. Strg+0 bringt keine Besserung. Ja, die Seite ist online. (Link nur für registrierte Nutzer sichtbar.) Der Fehler hat jedoch nur geringe Priorität, ich denke da gibt es wichtigere, wie z.B. das Problem mit der nicht funktionierenden Gzip Kompression! Habe soeben auch ein Ticket eröffnet!
Das ist komisch. Ich habe nochmal den Browsercache geleert, keine Verbesserung. Habe den Fehler schon an unterschiedlichen Rechnern gesehen. Wenn ich mich nicht täusche war es sogar auch mal der Firefox.... Ich bin mir aber nicht sicher.
Dieser Fehler ist weitaus kritischer. Heute habe ich 2 Kunden beobachtet, die beim Bestellvorgang 2 mal den gleichen Artikel im Warenkorb hatten und sich dann verabschiedet haben! Der Fehler ist für den Kunden sehr irreführend!
Hab bei dir auch die Warnung Code: Details zum Fehler auf der Webseite Benutzer-Agent: Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; WOW64; Trident/4.0; SIMBAR={7B51E300-A0AF-11DE-A853-0024216ADDCC}; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; .NET4.0C; InfoPath.3) Zeitstempel: Tue, 10 Jan 2012 12:14:33 UTC Meldung: Objekt erforderlich Zeile: 8 Zeichen: 5 Code: 0 URI: http://www.scout-schulranzen.de/javascript/ticker.js
Bei mir im IE9 wirds auch falsch dargestellt. Lösung (CSS): padding-bottom von "#menubox_categories_box .cat_icon" auf 3px setzen.
Danke, dass scheint an dem IFrame zu liegen welchen wir vom Hersteller eingebunden haben.. Leider kenne ich mich mit JavaScript nicht so gut aus..
schön wäre hier eine Übersicht die die Bugs auflistet und was so abgearbeitet ist. Dann könnten die Shopbetreiber besser planen, die das SP nicht selbst einspielen.
In http://www.gambio-forum.de/threads/...r-GX2-erschienen?p=19453&viewfull=1#post19453 hatte ich ja folgendes vorgeschlagen: Schon mal ganz gut, aber bei weitem nicht gut genug... Die richtige Lösung ist natürlich, dort eine User-Initialisierungs-Klasse zu verwenden, damit diese (durch Überladung) von beliebig vielen Zusatzanwendungen verwendet werden kann! Und man so, für alle Zeiten(!), keine Änderungen in der "application_top.php" mehr machen muss, um ein (oder viele) Modul(e) einzubinden. Und sehr einfach ist das zudem noch zu realisieren: 1. Im Verzeichnis "system\controls\" legen wir das Modul "UserInitControl.inc.php" an: PHP: <?php/* -------------------------------------------------------------- UserInitControl.inc.php 2012-01-12 avenger Copyright (c) 2011 Avenger, entwicklung@powertemplate.de Released under the GNU General Public License (Version 2) [http://www.gnu.org/licenses/gpl-2.0.html] --------------------------------------------------------------*//** * Description of UserInitControl * * Allow update-safe initializations in application_top.php * * @author Avenger */class UserInitControl{ function UserInitControl() { } function init() { /* Do Gambio standard inits (if any) */ }}?> Um jetzt die Klassenüberladung für eigene Initialisierungen zu nutzen, legt man im Verzeichnis "user_classes\overloads\UserInitControl\" ein Modul mit den eigenen Initialisierungen an (im Beispiel das Modul "pt_UserInitControl.php"): PHP: <?php/* -------------------------------------------------------------- pt_UserInitControl.inc.php 2011-01-12 avenger Copyright (c) 2011 Avenger, entwicklung@powertemplate.de Released under the GNU General Public License (Version 2) [http://www.gnu.org/licenses/gpl-2.0.html] --------------------------------------------------------------*//** * Description of pt_UserInitControl * * Do your update-safe application-specific initializations * * Now full(!) "XCOPY"-installation of modules becomes a reality! * * Just copy(!) a module's files into your shop, and you are done * (Of course only, if the module is structured according to the new Gambio GX2 standards.) * * So, you should not buy any modules from now on, which do not adhere to these standards any more. * Otherwise you will still be stuck with the old update problems! * * @author Avenger */class pt_UserInitControl extends pt_UserInitControl_parent{ function init() { //Be a good citizen, and make sure other inits are also done.... parent::init(); //Do your application-specific initializations.... //Define your own filenames. (Choose any name you like.) define('FILENAME_POWERTEMPLATE_SUPER_DUPER_MODULE', 'powertemplate_super_duper_module.php'); //Define your own table names. (Choose any name you like.) define('TABLE_POWERTEMPLATE_SUPER_DUPER_MODULE', 'powertemplate_super_duper_module_table'); //E.g., include your special include file(s). (Choose any name you like.) $file=DIR_FS_INC.'powertemplate_super_duper_module_includes.inc.php'; if (file_exists($file)) { include($file); } //E.g., include your special language file(s). (Choose any name you like.) $file=DIR_WS_LANGUAGES.$_SESSION['language'].'/'.'powertemplate_super_duper_module_language_file.php'; if (file_exists($file)) { include($file); } //Do whatever else needs to be done for initializing your module //You have access to any shop functionality here }}?> In diesem Verzeichnis kann man noch weitere Modul mit eigenen Initialisierungen anderer Anwendungen anlegen, z.B. "xyz_UserInitControl.php". Man kann hier beliebig viele solcher Module speichern, die dann alle die Original-Klasse "UserInitControl" beerben, und alle bei Initialisierung dieser Klasse abgearbeitet werden. Um das Ganze auch nutzen zu können, fügen wir an das Ende von "includes/application_top.php" folgendes ein: PHP: //Avenger$coo_init_control = MainFactory::create_object('UserInitControl');$coo_init_control->init();//Avenger Das war's schon, und wir sind ein weiteres großes Update-Problem los.... Mit den neuen Möglichkeiten der Klassenüberladung kann man wirklich sehr schnell sehr coole Sachen machen. Die verwendeten Dateien befinden sich im Anhang. (Die Änderung in "includes/application_top.php" muss manuell eingefügt werden.) Um das Ganze auch dort nutzen zu können, fügen wir an das Ende von "admin/includes/application_top.php" folgendes ein: PHP: //Avenger$coo_init_control = MainFactory::create_object('AdminUserInitControl');$coo_init_control->init();//Avenger Die Admin-Dateien sind auch schon im anhängenden Archiv enthalten.
In http://www.gambio-forum.de/threads/...r-GX2-erschienen?p=19498&viewfull=1#post19498 hatte ich ja folgendes vorgeschlagen Das mit den "cart_actions" ist mir dann doch etwas zu brutal, ich habe daher die "cart_actions.php" in eine Klasse konvertiert, und die einzelnen Funktionen als Klassenmethoden implementiert: So kann man dann einzelne Funktionen überladen, und muss nicht das ganze Modul immer im Auge haben. In "system\controls\" legen wir dazu das Modul "CartActions.php" an (ist im Anhang enthalten). Die wesentliche Steuerung sieht jetzt so aus: PHP: // Shopping cart actions function CartActions() { global $session_started,$econda; // //......... // $t_show_details=$this->switch_action($goto,$parameters,$econda); return $t_show_details; } function switch_action($goto,$parameters,$econda) { switch ($_GET['action']) { case 'update_product' : $t_show_details=$this->update_product($goto,$parameters,$econda); break; case 'update_wishlist' ; $t_show_details=$this->update_wishlist($goto,$parameters,$econda); break; case 'add_product' : $t_show_details=$this->add_product($goto,$parameters,$econda); break; break; case 'wishlist_to_cart' : $t_show_details=$this->wishlist_to_cart($goto,$parameters,$econda); break; case 'check_gift' : $t_show_details=$this->check_gift($goto,$parameters,$econda); break; case 'add_a_quickie' : $t_show_details=$this->add_a_quickie($goto,$parameters,$econda); break; case 'buy_now' : $t_show_details=$this->buy_now($goto,$parameters,$econda); break; case 'cust_order' : $t_show_details=$this->cust_order($goto,$parameters,$econda); break; case 'paypal_express_checkout' : $t_show_details=$this->paypal_express_checkout($goto,$parameters,$econda); break; } return $t_show_details; } So kann ich dann die einzelnen hier verwendeten Methoden einzeln überladen.... In einer überladenden Klasse kann ich sogar zusätzliche eigene Methoden einfügen! Dazu legen wir in "user_classes\overloads\CartActions\" wieder ein eigenes Modul (z.B. "pt_CartActions.php") an. PHP: class pt_CartActions extends pt_CartActions_parent{ // My private shopping cart actions function switch_action($goto,$parameters,$econda) { switch ($_GET['action']) { case 'my_function1': $t_show_details=$this->my_function1($goto,$parameters,$econda); break; case 'my_function2': $t_show_details=$this->my_function2($goto,$parameters,$econda); break; default: //Just use the original functions $t_show_details=parent::switch_action($goto,$parameters,$econda); } return $t_show_details; } function my_function1($goto,$parameters,$econda) { //....... return $t_show_details; } function my_function2($goto,$parameters,$econda) { //....... return $t_show_details; }} Darin wird geprüft, ob eine meiner neuen Funktionen gefordert ist. Wenn ja, wird diese ausgeführt, sonst die Funktionen der Originalklasse.... Um diese neue Klasse zu verwenden, müssen noch folgende Änderungen gemacht werden: In "includes/application_top.php": PHP: require (DIR_WS_INCLUDES.FILENAME_CART_ACTIONS); wird ersetzt mit: PHP: //Avengerif (isset ($_GET['action'])){ $t_show_details = MainFactory::create_object('CartActions');}//Avenger In "request_port.php": PHP: require (DIR_WS_INCLUDES.FILENAME_CART_ACTIONS); wird ersetzt mit: PHP: //Avenger$t_show_details = MainFactory::create_object('CartActions');//Avenger Damit habe ich, updatesicher, modular die volle Kontrolle über die "cart actions" erhalten, und ich kann die ohne Änderung im Standard-Code ändern und/oder erweitern. Ich denke, so langsam dürfte auch den Nicht-Fachleuten klar werden, was für ein gigantisches Potential in dieser Technik steckt! Und wie man damit die "Update-" und die "Modul-Installations"-Hölle vermeiden kann, ohne auf Systemänderungen zu verzichten. Es ist noch nicht 100% perfekt, weil wichtige Funktionen, die gerne mal geändert werden müssen ("shopping_cart", "checkout_xxxxx", "products_listing") noch nicht als Klassen vorliegen, aber alles schon 1000 Mal besser als bisher! (Wenn ich die SP-Roadmap gestern richtig verstanden habe, sind diese wichtigen Klassen aber in der Pipeline schon für dieses SP.) Programme im Anhang.
Es ist eine kleine Korrektur notwendig: in dem Overload-Modul werden andere Overloads nicht immer ausgeführt, so dass die Klassenkette evtl. unterbrochen wird. Das eigene Modul (z.B. "pt_CartActions.php") in "user_classes\overloads\CartActions\" sieht jetzt so aus. PHP: <?php/* --------------------------------------------------------------pt_CartActions.php 2012-01-12 AvengerCopyright (c) 2012 Avenger, entwicklungs@powertemplate.dePrivate methodes to modify CartActionsReleased under the GNU General Public License---------------------------------------------------------------------------------------*/class pt_CartActions extends pt_CartActions_parent{ // My private shopping cart actions function switch_action($goto,$parameters,$econda) { //Be a good citizen and allow other overloads to do their job... $t_show_details=parent::switch_action($goto,$parameters,$econda); if (!$t_show_details) { //The original class did not process any function, so try your own functions switch ($_GET['action']) { case 'my_function1': $t_show_details=$this->my_function1($goto,$parameters,$econda); break; case 'my_function2': $t_show_details=$this->my_function2($goto,$parameters,$econda); break; } } return $t_show_details; } function my_function1($goto,$parameters,$econda) { //Do whatever needs to be done....... return $t_show_details; } function my_function2($goto,$parameters,$econda) { //Do whatever needs to be done....... return $t_show_details; } //Replace method for original class function add_a_quickie($goto,$parameters,$econda) { //You might need to call the original method, but only if needed!. Not necessary, if you do a full replacement //$t_show_details=parent::add_a_quickie($goto,$parameters,$econda); //Do whatever needs to be done....... return $t_show_details; }}?> Geändertes Modul im Anhang enthalten...
Hallo Avenger, deine UserInitControl ist super, jedoch würde ich das jetzt für das SP als EventDispatcher realisieren, da das System bereits existiert und meiner Meinung genauso gut funktioniert. Sprich ich würde im Verzeichnis system/plugins/EventDispatcher eine Datei ApplicationTopEvenDispatcher.inc.php anlegen: PHP: <?php /* -------------------------------------------------------------- ApplicationTopEventDispatcher.inc.php 2012-01-13 gm Gambio GmbH http://www.gambio.de Copyright (c) 2012 Gambio GmbH Released under the GNU General Public License (Version 2) [http://www.gnu.org/licenses/gpl-2.0.html] -------------------------------------------------------------- */ MainFactory::load_class('PluginEventDispatcher'); class ApplicationTopEventDispatcher extends PluginEventDispatcher { function proceed() { $this->set_plugin_directory('ApplicationTop'); parent::proceed(); } } ?> Anschließend braucht man nur noch seine AvengerApplicationTopEventListener.inc.php: PHP: <?php /* -------------------------------------------------------------- AvengerApplicationTopEventListener.inc.php 2012-01-13 gm Gambio GmbH http://www.gambio.de Copyright (c) 2012 Gambio GmbH Released under the GNU General Public License (Version 2) [http://www.gnu.org/licenses/gpl-2.0.html] -------------------------------------------------------------- */ MainFactory::load_class('PluginEventListener'); class AvengerApplicationTopEventListener extends PluginEventListener { function proceed() { //Do your application-specific initializations.... //Define your own filenames. (Choose any name you like.) define('FILENAME_POWERTEMPLATE_SUPER_DUPER_MODULE', 'powertemplate_super_duper_module.php'); //Define your own table names. (Choose any name you like.) define('TABLE_POWERTEMPLATE_SUPER_DUPER_MODULE', 'powertemplate_super_duper_module_table'); //E.g., include your special include file(s). (Choose any name you like.) $file=DIR_FS_INC.'powertemplate_super_duper_module_includes.inc.php'; if (file_exists($file)) { include($file); } //E.g., include your special language file(s). (Choose any name you like.) $file=DIR_WS_LANGUAGES.$_SESSION['language'].'/'.'powertemplate_super_duper_module_language_file.php'; if (file_exists($file)) { include($file); } //Do whatever else needs to be done for initializing your module //You have access to any shop functionality here parent::proceed(); } } ?> Für den eigenen EventListener muss natürlich noch ein Verzeichnis im user_classes Verzeichnis her, der neben dem system/plugins/EventListener/ApplicationTop gescannt werden müsste. In die application_top.php kommt dann noch: PHP: $coo_application_top_event_dispatcher = MainFactory::create_object('ApplicationTopEventDispatcher'); $coo_application_top_event_dispatcher->proceed(); Spricht deiner Meinung nach etwas gegen meinen Lösungsvorschlag?
Wie das realisiert wird ist mir letzten Endes egal, wichtig ist nur, dass ein Mechanismus existiert, der für beliebig viele User updatesichere Initialisierungen erlaubt. Mit Eventdispatchern habe ich mich bisher nicht beschäftigt. Meine Lösung passte halt gut in das Konzept der überladbaren Klassen, ohne dass man am Shop etwas ändern müsste. Aber wie gesagt: wichtig ist nur dass ein solcher einfach handhabbarer Mechanismus überhaupt existiert, und man nicht unbdeingt noch ein anders Konzept verstehen muss. Funktioniert das auch für den Adminbereich? Habt Ihr Euch auch mal die "CartActions"-Geschichte angesehen? Das ist m.E. auch ein wichtiger Punkt, um dort bequem eingreifen zu können.
Ich habe mir das EventHandling, so weit schon etwas sichtbar ist, mal angesehen... Technisch ist das sicher äquivalent. Was mich aber dann doch daran stört, ist, dass man sich einfach noch ein weiteres Verfahren der Klassenüberladung merken muss.... Wobei ich mich auch frage, warum man ein solches zweites Verfahren überhaupt andenkt. Ich sehe, so auf die Schnelle (und ich mag mich täuschen), auch keine zusätzlichen Vorteile darin. Die Meisten werden sicher schon genügend damit zu tun haben, ein Verfahren zu verstehen und zu nutzen. Mein Vorschlag daher: macht es doch lieber so, wie ich das vorgeschlagen habe. "Klassenüberladung" und "Plugins/Event Dispatching" sind eigentlich auch 2 total unterschiedliche Konzepte, um das Gleiche zu erreichen... OXID verwendet das Konzept der "Klassenüberladung", wie es jetzt auch in GX3 kommen wird. Shopware hingegen ein "Plugin/Event Dispatching"-Konzept (allerdings ein total anderes, als ich jetzt in Gambio sehen kann). Und beide Systeme erfordern total unterschiedliche Vorgehensweisen für den Entwickler, Während das Konzept der "Klassenüberladung" noch einigermaßen verständlich ist, bin auch ich bei Shopware doch erst mal verstärkt in's Grübeln gekommen, bis ich das so einigermaßen verstanden habe.... Wie schon gesagt: ich sehe bei Gambio eigentlich keine Notwendigkeit und keinen Zusatznutzen durch das "Event Dispatching". Es ist, so weit ich sehen kann, auch "nur" eine andere Art der Klassenüberladung, und man muss das auch im Code gezielt aufrufen... Shopware geht da wesentlich weiter: Dort muss man nicht im Code irgendwelche "Hooks" haben, damit Plugins verwendet werden können. Vielmehr werden Plugins extern (mit einem Plugin-Installer) für beliebige Klassenmethoden in beliebigen Klassen definiert, und der interne Dispatcher prüft, ob für eine zu verwendende Funktion ein (oder mehrere) Plugins definiert sind. Hat Vor- und Nachteile...
Eine GROSSE Bitte hätte ich noch.... Da der Gambio Quellcode aussieht "wie Hund" (das xxCommerce-Erbe halt), möge die Gambio GmbH doch 15$ in den Erwerb von "Polystyle" investieren, um den Quellcode in ein konsistentes und besser lesbares Format zu konvertieren... http://polystyle.com/features/php-unformatted.jsp