Verständnisfrage: Application Ordner

Hallo zusammen,

leider muss ich hier noch einmal nachfragen da ich bisher zu keiner Lösung gekommen bin. Ich habe die [B]Version CE 4.7.0[/B] des Shops und würde gerne wissen wie ich Smarty um eigene Variablen/Objekte erweitern kann. Ich habe ja an sich den “application” Ordner, in welchem ich dann Unterordner wie Views, Translations, Models, Controllers und Components finde.

Hier habe ich nun den Punkt das ich unter Views mein eigenes Template einfügen kann, aber wie kann ich z.B. eigene Controller/Models schreiben, das diese auch vom Shop akzeptiert werden und im Template ansprechbar sind? Und vor allem so, das sie nicht nach einem Update des Shop-Systems einfach weg sind weil Datein überschrieben worden sind.

Zum Beispiel würde ich so gerne eigene Datenbankabfragen machen usw.
Hat da vielleicht jemand Ahnung von? Wäre demjenigen wirklich dankbar wenn mir da weitergeholfen werden könnte.

Du kannst das alles über ein Modul lösen. Mithilfe der “neuen” Funktionen in der metadata.php eines Moduls kannst du im Modulordner selbst auch Templates erstellen und/oder Template-Blöcke erweitern.

Das Erstellen neuer Controller/Models machst du dann in dem Modul als Erweiterung.
Somit hast du alles in deinem Modul und es wird auch nichts bei einem Shop-Update gelöscht :slight_smile:

Gut gut, das ist schonmal gut zu wissen. Demnach werde ich es dann auch auf die Art und Weise machen. Vielen Dank!

Eine Frage hab ic hda nun noch zum Verständnis… im Unterordner application/models habe ich ja nun viele ox*.php Dateien… hier gibt es zum Beispiel die oxarticlelist.php welche die Methode loadActionArticles enthält. Gibt es hier im Template bereich auch iene Möglichkeit per Smarty eine Funktion aufzurufen mit welcher ich die Artikel auch wirklich in einer Liste bekomme? Und wie definiert sich das $oView Object? Hier scheint an sich ja auch schon eine ganze Menge drin zu sein, allerdings weiß ich nicht was nun wirklich drin ist und woher dieses Objekt kommt. Einfach zur zum allgemeinen Verständniss wie das mit Smarty und den jeweiligen Objekten noch funktioniert.

Die Variable $oView beinhaltet immer das Objekt des aktuellen Controllers. In der Artikelliste ist das z.B. “application/controller/alist.php”. In älteren Versionen waren die Dateien unter /views/ die Controller.
Über den Controller kannst du z.B. auch in der Render-Methode neue Variabeln an Smarty übergeben. Sobald du Model-Objekt an das Template übergibst, kann du damit auch ganz normal in Smarty arbeiten.

Vielleicht solltest du dir dazu auch mal das MVC-Pattern ein wenig verinnerlichen. OXID hat das zwar nicht immer gut umgesetzt, es aber zumindest versucht und die Ordner immerhin schon korrekt benannt im Gegensatz zu früher… g

Ahhh vielen Dank für deinen post nochmal. Dieser hat mir nun echt die Augen geöffnet und ich weiß endlich wie ich Views usw. erweitern kann um meine gewünschten Funktionen :smiley:

Ich bin jetzt dabei eine Funktion aus der [B]oxarticlelist.php[/B] zu kopieren und meinen Bedürfnissen anzupassen, allerdings erbt die Klasse [B]oxArticleList[/B] von [B]oxList[/B] und dies kann ich in meiner ja nicht durchsetzen. Dadurch fehlen mir Funktionen wie z.B. [B]parent::getBaseObject();[/B] ich habe nun schon versucht diese zu erhalten durch [B]$oList = oxNew(“oxlist”);[/B], allerdings weiß ich nicht wirklich wie ich dieses Objekt nun initialisieren muss. Gibt es hier evtl. wieder etwas, was ich übersehen habe? Meine bisherige Arbeit sieht dabei wie folgt aus.


<?php

class rj_start extends rj_start_parent {

	public function init() {
		return parent::init();
	}
	
	public function render() {
		// Do something
		
		return parent::render();
	}
	
	public function getActionArticleList() {
		
		$sShopID = $this->getConfig()->getShopId();
		
		$oBaseObject    = parent::getBaseObject();
        $sArticleTable  = $oBaseObject->getViewName();
        $sArticleFields = $oBaseObject->getSelectFields();
		
		$oBase = oxNew("oxactions");
        $sActiveSql = $oBase->getSqlActiveSnippet();
        $sViewName = $oBase->getViewName();

        $sLimit = ( $iLimit > 0 ) ? "limit " . $iLimit : '';
		
		$sSelect = "select $sArticleFields from oxactions2article
                    left join $sArticleTable on $sArticleTable.oxid = oxactions2article.oxartid
                    left join $sViewName on $sViewName.oxid = oxactions2article.oxactionid
                    where oxactions2article.oxshopid = '$sShopID' and oxactions2article.oxactionid = $sActionID and $sActiveSql
                    and $sArticleTable.oxid is not null and " .$oBaseObject->getSqlActiveSnippet(). "
					order by oxactions2article.oxsort $sLimit";
        
		$result = $this->selectString( $sSelect );
		
		var_dump($result);
	}
	
	public function selectString( $sSelect) {
        startProfile("loadinglists");
        $oRes = parent::selectString( $sSelect );
        stopProfile("loadinglists");

        return $oRes;
    }
}

?>

Dies funktioniert natürlich nicht. Hier vielleicht noch eine kurze Erklärung zu wäre nett. Danke schonmal! :slight_smile:

Wenn du eine Funktion aus oxarticlelist.php anpassen willst, solltest du oxarticlelist erweitern und nicht start. Ich versuche es mal mit einem Autovergleich: wenn du Autos hast (models) die von einem Fahrer gefahren werden (controller) und die willst jetzt dass statt einem Radio ein CD-Player im Auto ist, dann musst du als erstes das Auto umbauen.
Das kannst du machen indem du eine Funktion im Model ersetzt, also quasi statt dem Radio einen CD-Player einbaust, dann benutzen alle Fahrer statt dem Radio nun automatisch einen CD-Player.
Oder du schreibst eine neue Funktion, lässt also das Radio unverändert und baust zusätzlich einen CD-Player in das Auto ein, dann musst du zusätzlich noch den Fahrer so ändern dass er den neuen CD-Player auch benutzt.
Was aber nicht geht ist dem Fahrer den CD-Player einzubauen, weil der Fahrer ja keine Batterie eingebaut hat um den CD-Player zu betreiben und auch kein Kabel zu den Lautsprechern.

…coool :slight_smile:

jetzt muss ich erstmal zum Blödkaufhaus und mir nen Player zocken - irgendwie hats angesteckt

:stuck_out_tongue:

Danke für die sehr bildliche Erklärung! :slight_smile:
Okay, wenn ich das nun richtig verstanden habe muss ich dann am Besten wirklich die oxarticlelist erweitern… dann müsste ich aber dennoch die start.php erweitern um dann die oxarticlelist in der start.tpl verfügbar zu machen, richtig?

Ja genau du machst in oxarticlelist eine neue Methode ladMeineArtikel, und dann in start eine Methode holMeineArtikel in der eine neue oxarticlelist erstellt wird, dort ladMeineArtikel aufgerufen wird und dann die oxarticlelist zurückgegeben wird.
Im Template rufst du dann die Methode aus start auf ($oView->holMeineArtikel()), bekommst so die Artikelliste (oxarticlelist) und kannst mit foreach die Artikel darstellen. (alles natürlich nicht direkt in den Klassen sondern in Erweiterungen)

Okay, dann hab ich das Prinzip nun denke ich verstanden! Vielen Dank dafür!
Mein aktueller Versuch sieht nun prinzipiell so aus wie unten…

Leider funktioniert das ganze immernoch nicht, allerdings finde ich den Fehler nun nicht. Ich habe das ganze nun mit anderen Modulen vergleichen und das ganze eig. so gemacht wie andere auch, von daher bin ich nicht wirklich sicher woran das nun liegt. Ich habe auch schon versucht eine Instanz der pbarticlelists, welche von oxarticlelists erbt zu erstellen, aber das war scheinbar auch nicht richtig. Sieht vielleicht noch jemand meinen Fehler?

// Edit: Der Fehler liegt wohl daran das er die neue Methode die ich der oxarticlelist über mein Modul hinzufügen will nicht kennt.


<?php
/**
 * Metadata version
 */
$sMetadataVersion = '1.1';

/**
 * Module information
 */
$aModule = array(
    'id'	            => 'rj13',
    'title'             => 'Test2013',
	'author'			=> '',
    'extend'            => array(	'start' 		=> 'rj/rj_start', 
									'oxarticlelist' => 'rj/pbarticlelists'),
    'files' 			=> array(),
    'templates' 		=> array()
);


class rj_start extends rj_start_parent {
	/**
	  */
	public function init() {
		$ret =  parent::init();
		return $ret;
	}
	
	/**
	  */
	public function render() {		
		$ret = parent::render();
		return $ret;
	}
	
	/**
	  */
	public function getActionArticlelist( $sActionID, $iLimit = null ) {
		$list = oxNew('oxarticlelist');
		$list->dummy();
		
		return $list;
	}
}

<?php
/**
  *
  */
class pbarticlelists extends pbarticlelists_parent {	
	public function dummy() {
		echo 'Dummy';
	}

}
?>

Was heißt “geht nicht”? Wie rufst du das in welchem Template auf? Lässt sich das Modul ohne Fehler aktivieren? Stehen deine Klassen korrekt unter “Installierte Shop-Module”? Außerdem würde ich dir empfehlen, die Benamung konsistenter zu halten, z.B. erweiterte Klasse als modul-Prefix + Klasse, also rj_start und rj_oxarticlelist, die Variablennamen wie Oxid-Standard mit Type-Prefix, also z.B. $oArticlelist und nicht $list. Ansonsten schaut das auf den ersten Blick OK aus.

Okay, noch einmal ein bisschen genauer.
Also ich kann meine [B]getActionArticlelist[/B] welche in der rj_start definiert ist problemlos im Template aufrufen. Wenn ich nun allerdings versuche auf die für die oxarticlelist erweiterte Testmethode “dummy” aufrufen will, wird der Shop nicht mehr angezeigt (komplett weiße Seite). Wenn ich eine Standard-Funktion von oxarticleliste in meiner rj_start.php aufrufe funktioniert das Problemlos, aber wenn ich die neuen Funktionen, welche ich in pbarticlelists eingefügt habe, an dieser Stelle aufrufen will, wird mir der Shop einfach nicht mehr angezeigt. ich bekomme auch keine Fehlermeldung o.Ä.

Es scheint einfach so zu sein, das meine neue Methode an dieser Stelle noch nicht vorhanden ist.

Ich habe meine Dateiname usw. nun ein wenig angepasst. Hier sieht es nun wie folgt aus.


<?php
/**
 * Metadata version
 */
$sMetadataVersion = '1.1';

/**
 * Module information
 */
$aModule = array(
    'id'	            => 'rj2013',
    'title'             => 'RJ2013',
	'author'			=> '',
    'extend'            => array('oxarticlelist' 	=> 'rj2013/rj_articlelist',
								 'start' 			=> 'rj2013/rj_start'),
    'files' 			=> array(),
    'templates' 		=> array()
);
?>


<?php
class rj_articlelist extends rj_articlelist_parent {
	public function dummy() {
		echo "Dummy!<br>";
	}
}
?>


<?php
class rj_start extends rj_start_parent {

	public function init() {
		$ret =  parent::init();
		return $ret;
	}
	
	public function render() {
		$ret = parent::render();
		return $ret;
	}
	
	public function getActionArticlelist( $sActionID, $iLimit = null ) {
		$oArticlelist = oxNew('oxarticlelist');
		
		if(method_exists($oArticlelist, 'dummy')) {
			$oArticlelist->dummy();
		}
		
		return $oArticlelist;
	}
}
?>

Und der Templatecode ist wie und in welchem Template an welcher Stelle? Einträge in log/EXCEPTION_LOG.txt?

Okay, hab die Logdatei durchgeschaut und die sagt tatsächlich das was ich vermutet habe.


oxSystemComponentException-oxException (time: 2013-06-24 12:58:46): [0]: Function 'dummy' does not exist or is not accessible! (oxArticleList)
 
 Stack Trace: #0 [internal function]: oxSuperCfg->__call('dummy', Array)
#1 C:\xampp\sites\matthaes\shop2013\modules\ReiterJournal2013\rj_start.php(30): oxArticleList->dummy()
#2 C:\xampp\sites\matthaes\shop2013	mp\smarty\b5ccd3459c53d4954114764042d5b030^%%40^405^405277AF%%start.tpl.php(27): rj_start->getActionArticlelist('ee439ab4ef794f5...')
#3 C:\xampp\sites\matthaes\shop2013\core\smarty\Smarty.class.php(1263): include('C:\xampp...')
#4 C:\xampp\sites\matthaes\shop2013\core\oxshopcontrol.php(527): Smarty->fetch('page/shop/start...', 'ox|0|0|1|0')
#5 C:\xampp\sites\matthaes\shop2013\core\oxshopcontrol.php(395): oxShopControl->_render(Object(rj_start))
#6 C:\xampp\sites\matthaes\shop2013\core\oxshopcontrol.php(155): oxShopControl->_process('start', NULL, NULL, NULL)
#7 C:\xampp\sites\matthaes\shop2013\core\oxid.php(40): oxShopControl->start()
#8 C:\xampp\sites\matthaes\shop2013\index.php(27): Oxid::run()
#9 {main}

 Faulty component --> 
---------------------------------------------


Leider weiß ich allerdings nicht warum dies nicht so funktioniert. :confused:

Aufrufen tu ich das aktuell in der [B]start.tpl[/B] durch die Zeile


[{assign var='salesArticle' value=$oView->getActionArticlelist('ee439ab4ef794f5cef7a2a74cb0cf446') }]

Später will ich dann die Variable “salesArticle” halt ganz normal als Artikelliste nutzen. Ich hoffe meine Gedankengänge sind hier richtig. Danke übrigens für deine Hilfe!

Klick mal im Admin auf Erweiterungen/Module und wenn da was zm Löschen angeboten wird sag ja. Dann deaktiviere dein Modul nochmal und aktiviere es wieder, klick nochmal auf Erweiterungen/Module und schau was bei “Installierte Shop-Module” bei oxarticlelist steht.

Wunderbar! Vielen Dank, das wars! Nach deaktivieren und wieder neu aktivieren funktioniert es plötzlich. Das ist super, dann kann ich nun denke ich mal alles meinen Bedürfnissen anpassen! :slight_smile: