Teil 2 "Extender-Klassen" aus der Serie "updatesichere Anpassungen in GX2"

Thema wurde von Nonito (Gambio), 31. Januar 2012 erstellt.

  1. Nonito (Gambio)

    Nonito (Gambio) Administrator

    Registriert seit:
    21. April 2011
    Beiträge:
    279
    Danke erhalten:
    134
    Danke vergeben:
    52
    An verschiedenen Stellen im Shop werden Objekte vom Typ "ExtenderComponent" erzeugt. Diesen Objekten werden Daten übergeben, die für den jeweiligen Kontext relevant sind, z.B. wird nach Abschluss einer Bestellung in der checkout_success.php einem ExtenderComponent-Objekt die gerade erzeugte orders_id übergeben oder nach einem erfolgtem Userlogin die ermittelte customers_id.

    Diese Extender können mit Hilfe des ClassOverloadings (siehe Teil 1 "ClassOverloading") erweitert werden, so dass sich beliebige Plugins schreiben lassen, die etwa nach jeder ausgeführten Bestellung die aktuelle orders_id übergeben bekommen und ausgeführt werden.

    Beispiel eines Extenders in der checkout_success.php:
    Code:
    $coo_checkout_success_extender_component = MainFactory::create_object('CheckoutSuccessExtenderComponent');
    $coo_checkout_success_extender_component->set_event_data('orders_id', $last_order);
    $coo_checkout_success_extender_component->proceed();
    $t_dispatcher_result_array = $coo_checkout_success_extender_component->get_response();
    
    Dem Extender wird über die set_event_data()-Methode die aktuelle orders_id übergeben. Im Anschluss wird die proceed()-Methode aufgerufen und danach mit get_response() ein Array mit möglichen Rückgabenwerten abgerufen und dem Ausgabe-Template zur Verfügung gestellt.

    Beispiel eines Plugins für die checkout_success.php:

    Im Verzeichnis system/overloads/CheckoutSuccessExtenderComponent befindet sich die Definition einer Klasse TSWidgetCheckoutSuccessExtender, die die proceed-Methode des Extenders überladen soll, um einen order-spezifischen HTML-Code für die Ausgabe zu erzeugen:
    Code:
    class TSWidgetCheckoutSuccessExtender extends TSWidgetCheckoutSuccessExtender_parent
    {
    	function proceed()
    	{
    		$obj_widget = MainFactory::create_object('GMTSWidget', array($_SESSION['languages_id']));
    		$this->v_output_buffer['TS_RATING'] = $obj_widget->get_rating_link(
    			$this->v_event_data_array['orders_id'],
    			'GM_TRUSTED_SHOPS_WIDGET_SHOW_CHECKOUT'
    		);
    		parent::proceed();
    	}
    }
    
    Innerhalb der Klasse sind die zuvor per set_event_data() übergebenen Inhalte über das Array $this->v_event_data_array erreichbar. In diesem Beispiel wird die übergebene orders_id genutzt, um sich von einem weiteren Objekt ($obj_widget) ein Stück HTML-Code erzeugen zu lassen, welches wiederum in den Output-Buffer des Extenders geschrieben wird:
    Code:
    $this->v_output_buffer['TS_RATING'] = 'abc 123';
    
    Zu beachten ist, dass der Output-Buffer ein assoziatives Array ist, in das jedes Plugin in einen eigenen Index (hier 'TS_RATING') mit aussagekräftiger Bezeichnung schreiben sollte, um Kollisionen mit den Ausgaben anderer Plugins zu vermeiden.

    Weiter muss am Ende der proceed()-Methode des Plugins unbedingt die proceed()-Methode der parent-Instanz aufgerufen werden, damit die Ausführungskette ggf. mehrerer installerter Plugins nicht zu unterbrechen.

    Das Ergebnis dieses Plugins ist nun, dass in der Template-Datei "checkout_success.html" die Smarty-Variable {$TS_RATING} samt Inhalt zur Verfügung steht.

    Wie ihr updatesichere Anpassungen an Template-Dateien vornehmen könnt, erfahrt ihr in Teil 3 "Template-Usermods".

    Weitere Stellen, in denen ExtenderComponent-Objekte aufgerufen werden, findet ihr in folgenden Dateien:
    - admin/includes/application_top.php
    - includes/application_top.php
    - includes/application_bottom.php
    - includes/header.php
    - system/views/LoginContentView.inc.php
    - checkout_success.php
    - gm_javascript.js.php

    Eigene Overload-Klassen sollten unbedingt im dafür vorgesehenen Verzeichnis user_classes/overloads platziert werden, da der Inhalt des system-Verzeichnisses im Rahmen von Updates überschrieben werden kann und somit Änderungen verlorengehen könnten.
     
  2. Steffen (indiv-style.de)

    Steffen (indiv-style.de) G-WARD 2013/14/15/16

    Registriert seit:
    30. Juni 2011
    Beiträge:
    5.143
    Danke erhalten:
    1.466
    Danke vergeben:
    452
    Beruf:
    Systemadmin, Webentwickler bei Indiv-Style
    Ort:
    PhpStorm
    Wir es hier noch mehr dieser Extender geben???
     
  3. Steffen (indiv-style.de)

    Steffen (indiv-style.de) G-WARD 2013/14/15/16

    Registriert seit:
    30. Juni 2011
    Beiträge:
    5.143
    Danke erhalten:
    1.466
    Danke vergeben:
    452
    Beruf:
    Systemadmin, Webentwickler bei Indiv-Style
    Ort:
    PhpStorm
    stups stups!!!!

    ich finde das es viel mehr dieser Extender geben sollte! Kommen da noch welche???
    Kann man die nicht selbst machen?????
     
  4. HolgerNils (xycons.de)

    HolgerNils (xycons.de) G-WARD 2013/2014

    Registriert seit:
    29. Oktober 2011
    Beiträge:
    1.972
    Danke erhalten:
    456
    Danke vergeben:
    369
    Der Code von Noninto müsste doch passen...als Vorlage.
    Und Du hast Recht, das müsste weiter getrieben werden. Da stockt es leider.
     
  5. Steffen (indiv-style.de)

    Steffen (indiv-style.de) G-WARD 2013/14/15/16

    Registriert seit:
    30. Juni 2011
    Beiträge:
    5.143
    Danke erhalten:
    1.466
    Danke vergeben:
    452
    Beruf:
    Systemadmin, Webentwickler bei Indiv-Style
    Ort:
    PhpStorm
    Ist es möglich das beim Aufruf einer Contentseite, wo im Admin die /media/content/sitemap.php angegeben ist, eine Klassenüberladung nicht funktioniert???

    in dieser sitmap.php wird per require_once (DIR_FS_CATALOG . 'gm/classes/GMSitemap.php'); die Klasse geladen. Diese habe ich nun versucht zu überladen. Problem ist nun das beim aufruf der Sitemap, welche ja ein Content ist, die Überladung net greift! Codänderungen innerhalb der original-Klasse funzen!

    Denkfehler???


    Hab die so angelegt:

    • \user_classes\overloads\GMSitemap\Indiv_GMSitemap.inc.php
    Inhalt:


    PHP:
    <?php
    /* --------------------------------------------------------------
          Shop-Modul modified by indiv-style.de
          Blog V1.0 for Gambio GX2 V2.010g
          info@indiv-style.de 
      --------------------------------------------------------------
     */
    class Indiv_GMSitemap extends Indiv_GMSitemap_parent
    {
        
            var 
    $gmSEOBoost;
                    
            function 
    GMSitemap() {     
                
                
    $this->gmSEOBoost    MainFactory::create_object('GMSEOBoost');
                return;
            }

            function 
    get() {
                
                
    /*
                * get cats 
                */
                
    if     (GROUP_CHECK == 'true') {
                    
    $group_check " AND c.group_permission_".$_SESSION['customers_status']['customers_status_id']."=1 ";
                }

                
    $gm_query xtc_db_query("
                                            SELECT
                                                c.categories_id AS id, 
                                                cd.categories_name AS name,
                                                c.parent_id 
                                            FROM " 
    .
                                                
    TABLE_CATEGORIES " c 
                                            LEFT JOIN " 
    .
                                                
    TABLE_CATEGORIES_DESCRIPTION " cd 
                                            ON 
                                                c.categories_id = cd.categories_id 
                                            WHERE 
                                                cd.language_id = '" 
    . (int) $_SESSION['languages_id'] . "'
                                            AND 
                                                c.parent_id = '0' 
                                            AND 
                                                c.categories_status = '1' " 
    .
                                            
    $group_check "
                                            ORDER BY 
                                                c.sort_order, cd.categories_name
                                            "
    );

                
    $gm_tree '<ul>';
                while(
    $gm_array xtc_db_fetch_array($gm_query)) {

                    
    $gm_sub_tree $this->get_tree($gm_array['id']);
                    if(!empty(
    $gm_sub_tree)) {
                        
    $gm_help '<li class="parent"><h2>' $this->get_cat_link($gm_array['id'], $gm_array['name']) . '</h2>' $gm_sub_tree '</li>'
                    } else {
                        
    $gm_help '<li class="parent"><h2>' $this->get_cat_link($gm_array['id'], $gm_array['name']) . '</h2></li>'
                    }    
                    
    $gm_tree .= $gm_help;
                    
    $gm_help '';
                }            


                
    /*
                * get contents 
                */
                
    if (GROUP_CHECK == 'true') {
                    
    $group_check "and group_ids LIKE '%c_".$_SESSION['customers_status']['customers_status_id']."_group%'";
                }
                
                if(
    $this->gmSEOBoost->boost_content) { 
                    
    $group_query "content_id AS id,";
                } else {
                    
    $group_query "content_group AS id,";
                }
                
                
    $gm_query xtc_db_query(
                                        
    "SELECT
                                            " 
    $group_query "
                                            content_title,
                                            gm_link
                                        FROM " 

                                            
    TABLE_CONTENT_MANAGER "
                                        WHERE
                                            languages_id='" 
    . (int) $_SESSION['languages_id'] . "'
                                        AND 
                                            file_flag!=4 " 
    .
                                        
    $group_check 
                                        AND 
                                            content_status=1 
                                        ORDER BY 
                                            sort_order
                                        "
    );

                while (
    $content_data xtc_db_fetch_array($gm_query)) {
                    
                    
    $SEF_parameter '';
                    
                    
                    if(
    $this->gmSEOBoost->boost_content) {
                        
    $link xtc_href_link($this->gmSEOBoost->get_boosted_content_url($content_data['id'], $_SESSION['languages_id']));
                    } else {
                        if (
    SEARCH_ENGINE_FRIENDLY_URLS == 'true') {
                            
    $SEF_parameter '&content=' xtc_cleanName($content_data['content_title']);
                        }
                        
    $link xtc_href_link(FILENAME_CONTENT'coID=' $content_data['id'] . $SEF_parameter);
                    }

                    if(empty(
    $content_data['gm_link'])){
                        
    $gm_tree .= '<li><h2><a href="' $link '">'.htmlspecialchars($content_data['content_title']).'</a></h2></li>';
                    }    
                }
                

                            
              
    // categories

                
    $blogcat_query xtc_db_query("SELECT id, titel
                  FROM "
    .TABLE_BLOG_CATEGORIES.
                  WHERE status = 1 
                  AND language_id = '"
    .$_SESSION['languages_id']."'
                  ORDER BY position ASC"
    );

                while(
    $blogcat xtc_db_fetch_array($blogcat_query)){


                        if(
    $coo_seo_boost->boost_blog)
                        {
                            
    $t_blog_url xtc_href_link($coo_seo_boost->get_boosted_blog_url($blogcat['id'], $_SESSION['languages_id']));
                        }
                        else
                        {
                            
    $t_blog_url xtc_href_link(FILENAME_BLOG,'blog_cat='.$blogcat['id']);
                            
    //$t_blog_url = xtc_href_link($coo_seo_boost->get_boosted_blog_url($blogcat['id'], $_SESSION['languages_id']));
                        
    }
                        
    //$t_blog_string .= '<img src="templates/'.CURRENT_TEMPLATE.'/img/icon_arrow.gif" alt="" /> <a href="'.$t_blog_url.'">'.htmlspecialchars($blogcat['titel']).'</a><br />';

                        //if(strstr($t_blog_url, $_SERVER['REQUEST_URI']) !== false && $_SERVER['REQUEST_URI'] != DIR_WS_CATALOG) $t_selected = true; else $t_selected = false;
                                                 
    $blogcat_array[$blogc] = array(
                                                                                                    
    'CATEGORIE_ID'     => $blogcat['id'],
                                                                                                    
    'CATEGORIE_TITLE'  => $blogcat['titel'],
                                                                                                    
    'CATEGORIE_LINK'   => $t_blog_url,
                                                                                                    
    'ITEMS'            => '',
                                                                                                    
    'URL' => $t_blog_url);
                                            
    $gm_tree .= '<li><h2><a href="' $t_blog_url '">'.htmlspecialchars($blogcat['titel']).'</a></h2></li>';

                



                  
    // SHOW ITEMS
                      //if(is_numeric($_GET['blog_cat']) && (int)$_GET['blog_cat'] == $blogcat['id']){

                              
    $items_query xtc_db_query("SELECT id, title FROM ".TABLE_BLOG_ITEMS." WHERE status = 1 AND categories_id = '".$blogcat['id']."' AND language_id = '".$_SESSION['languages_id']."' ORDER BY position ASC");

                              while(
    $items xtc_db_fetch_array($items_query)){

                              if(
    $_GET['blog_item'] == $items['id']) {
                                      
    $blog_id_active ' blog_active';
                              }
                              else {
                                      
    $blog_id_active '';
                              }
                                     
                        if(
    $coo_seo_boost->boost_blog)
                        {
                            
    $t_item_url xtc_href_link($coo_seo_boost->get_boosted_item_url($items['id'], $_SESSION['languages_id']));
                        }
                        else
                        {
                            
    $t_item_url xtc_href_link(FILENAME_BLOG,'blog_cat='.$blogcat['id'].'&blog_item='.$items['id']);
                            
    //$t_item_url = xtc_href_link($coo_seo_boost->get_boosted_item_url($items['id'], $_SESSION['languages_id']));
                        
    }
                        
    //$t_blog_string .= '<img src="templates/'.CURRENT_TEMPLATE.'/img/icon_arrow.gif" alt="" /> <a href="'.$t_blog_url.'">'.htmlspecialchars($blogcat['titel']).'</a><br />';
                                             
    $gm_tree .= '<li><h2><a href="' $t_blog_url '">'.htmlspecialchars($items['title']).'</a></h2></li>';
                        
    //if(strstr($t_item_url, $_SERVER['REQUEST_URI']) !== false && $_SERVER['REQUEST_URI'] != DIR_WS_CATALOG) $t_selected = true; else $t_selected = false;
                                                
    $blogcat_array[$blogc]['ITEMS'][$item] = array(
                                              
    'ITEM_ID'     => $items['id'],
                                              
    'ITEM_TITLE'  => $items['title'],
                                              
    'ITEM_ACTIVE' => $blog_id_active,
                                              
    'ITEM_LINK'   => $t_item_url);                        
                              
                                      
    $item++;  
                              }
                      
    //}
                  
    $blogc++;
                } 
                
    $gm_tree .= '</ul>';                        
                return 
    $gm_tree;
            }


        
    }
    ?>


    die greift nicht!!!!
     
  6. Avenger

    Avenger G-WARD 2012/13/14/15

    Registriert seit:
    26. April 2011
    Beiträge:
    4.771
    Danke erhalten:
    1.478
    Danke vergeben:
    89
    Da gibt es wohl ein grundlegendes Problem:

    Die Klasse ist als
    PHP:
    class GMSitemap
    definiert, und somit nicht überladbar!

    Die müsste als
    PHP:
    class GMSitemap_ORIGIN
    definiert sein um überladbar zu sein.....

    Das trifft wohl auf alle Klassen in diesem Verzeichnis zu,,,,,
     
  7. Steffen (indiv-style.de)

    Steffen (indiv-style.de) G-WARD 2013/14/15/16

    Registriert seit:
    30. Juni 2011
    Beiträge:
    5.143
    Danke erhalten:
    1.466
    Danke vergeben:
    452
    Beruf:
    Systemadmin, Webentwickler bei Indiv-Style
    Ort:
    PhpStorm
    Guten Morgen Avenger,

    so ist es eben nicht! In diesem Verzeichnis liegt auch die GMSEOBoost.php welche wir schon überladen haben, und nach Auskunft von Nonito sind alle diese Klassen überladbar! Nur diese eine mag nicht. :mad:
     
  8. Avenger

    Avenger G-WARD 2012/13/14/15

    Registriert seit:
    26. April 2011
    Beiträge:
    4.771
    Danke erhalten:
    1.478
    Danke vergeben:
    89
    Jo, hast Recht....
     
  9. Steffen (indiv-style.de)

    Steffen (indiv-style.de) G-WARD 2013/14/15/16

    Registriert seit:
    30. Juni 2011
    Beiträge:
    5.143
    Danke erhalten:
    1.466
    Danke vergeben:
    452
    Beruf:
    Systemadmin, Webentwickler bei Indiv-Style
    Ort:
    PhpStorm
    #9 Steffen (indiv-style.de), 8. Februar 2013
    Zuletzt bearbeitet: 8. Februar 2013
    :mad:Ich kann machen was ich will, der überläd das net!!! [BLUTDRUCK NACH OBENSTEIG ON]:mad:
     
  10. Avenger

    Avenger G-WARD 2012/13/14/15

    Registriert seit:
    26. April 2011
    Beiträge:
    4.771
    Danke erhalten:
    1.478
    Danke vergeben:
    89
    Kein Wunder, denn das Verzeichnis "media/content" wird nicht nach Klassen durchsucht....
     
  11. Steffen (indiv-style.de)

    Steffen (indiv-style.de) G-WARD 2013/14/15/16

    Registriert seit:
    30. Juni 2011
    Beiträge:
    5.143
    Danke erhalten:
    1.466
    Danke vergeben:
    452
    Beruf:
    Systemadmin, Webentwickler bei Indiv-Style
    Ort:
    PhpStorm
    Naja, nun hab ich die sitmap.php im Mediaordner dupliziert und auf meine neue Klasse verwiesen. Geht auch. Nicht schön aber es funktioniert!
     
  12. Steffen (indiv-style.de)

    Steffen (indiv-style.de) G-WARD 2013/14/15/16

    Registriert seit:
    30. Juni 2011
    Beiträge:
    5.143
    Danke erhalten:
    1.466
    Danke vergeben:
    452
    Beruf:
    Systemadmin, Webentwickler bei Indiv-Style
    Ort:
    PhpStorm
    Schups Schups..... ;)

    ist es abzusehen ob irgendwann mal der product-listing-Bereich und der create-account-Bereich mit Extendern versehen werden? Und kommt da nur einer rein? Ich frage deshalb, da ja im z.B. creat-account-Bereich eigentlich 3 benötigt werden. Fehlerprüfung, Account-Erstellung, Anzeige........
    Kann man da etwas Einfluss darauf nehmen? (ist nur ne Frage!);)
    Mich stört es z.B. in der header.php, da gibts ja die HeaderExtenderComponent. Aber das geht ja in den head-Bereich. Wenn ich etwas genau am Anfang des Body packen möchte muss ich ja trotzdem in den Core eingreifen.
     
  13. Moritz (Gambio)

    Moritz (Gambio) Administrator

    Registriert seit:
    26. April 2011
    Beiträge:
    5.786
    Danke erhalten:
    2.692
    Danke vergeben:
    903
    Kommt mit dem 2.1 Master-Update.
     
  14. Steffen (indiv-style.de)

    Steffen (indiv-style.de) G-WARD 2013/14/15/16

    Registriert seit:
    30. Juni 2011
    Beiträge:
    5.143
    Danke erhalten:
    1.466
    Danke vergeben:
    452
    Beruf:
    Systemadmin, Webentwickler bei Indiv-Style
    Ort:
    PhpStorm
    Uiiii, das steigert meine Laune wieder nach oben..... ;)