Plugin in CMS einbinden

Roin

Freier Denker
Registriert
22 Juli 2013
Beiträge
581
Hi Leute,

ich schreibe gerade ein kleines CMS.
Dabei gibt es einmal die "Standard"-Version und dann weitere Plugins, die die Seite um einige Funktionen erweitern soll.
Dabei würde auf bestehenden Seiten beispielsweise bei jedem Plugin eine weitere Spalte in einer Tabelle eingefügt und woanders eine entfernt.
Die Tabelle würde dynamisch aus einer Datenbank erzeugt werden.

Wie kann man das am besten umsetzen, sodass man auch 2 Plugins verwenden kann, ohne dass die sich sozusagen gegenseitig behindern.

Ich würde etwas wie folgt versuchen:

index.php
[src=php]<?php

//Standard-Werte
$val_arr = array(val1, val2, val3, val4);


if($existPlugin) {
foreach($pluginList as $plugin) {
include('/plugins/'.$plugin.'/'/*Dateiname*/);
}
}


$sql = "SELECT implode($val_arr, ',') FROM"/*...*/;


/*...*/
foreach($rows as $row) {
echo "\n<tr>\n";
foreach($row as $value) {
echo "\n\t<td>".$value."</td>\n";
}
echo "\n</tr>\n";
}
/*...*/
?>[/src]

plugins/PLUGIN//*Dateiname*/
[src=php]<?php
/*...*/
$val_arr = array_merge($val_arr, $plugin_val);
$key = array_search($bad_val, $val_arr);
if($key !== false) unset($val_arr[$key]);
/*...*/
?>[/src]

Doch was mache ich, wenn ich zwei Plugins habe, die entsprechend die Ausgabewerte in einer bestimmten Reihenfolge in die Tabelle schreiben sollen, also beispielsweise plugin_val-1 nach val2, val3 wird entfernt und plugin_val-2 nach val3.

Zudem: Muss ich für jede meiner "Standard-Dateien" eine eigene Datei schreiben, die ich dann einbinden lassen würde - oder ist es sinnvoller alles in eine Plugin-Datei zu schreiben und dann diese Datei (mit teils überflüssigen Sachen) in jede Standard-Datei einbinden zu lassen?

Ist der Ansatz überhaupt sinnvoll?

LG
 
Schonmal über einen Autoloader nachgedacht, dem du sagen kannst ob und was er zu laden hat?
So vermeidest du Datenmüll. Denn, wie du schon angemerkt hast, brauchst du in einem Gästebuch bswp. kein Plugin welches dir eine Shadowbox sonstworaus generiert. (nur als Beispiel)

Außerdem: ich würde nicht von null anfangen. Baue auf ein bestehendes Framework auf und erfinde nicht das Rad neu. (Es ist auch keine gute Übung, eine gute Übung wäre es mit einem bekannten Framework zu arbeiten, welches auch Zukunftssicher ist)
 
Wenn du objektorientiert arbeitest, kannst du wunderschön arbeiten:

Normales CMS mit Basiscode:

[src=php]<?php

class mySomethingStandard
{

public function __construct($in1, $in2){}
public function __execute()
{
/* do something strange */
return array($out1, $out2);
}

}

?>[/src]

Plugin:

[src=php]<?php

class mySomethingExtended extends mySomethingStandard
{

public function __construct($in1, $in2, $in3, $in4)
{
super($in1, $in2);
/* do something special extended with in3, in4 */
}


public function __execute()
{
/* do something very strange */
return array($out1, $out2, $out3);
}

}

?>[/src]


Beim Einbinden des Plugins wird dann in etwa sowas gemacht:

[src=php]
/* standard source */
$modulLoader->registerModul('Anything' => new mySomethingStandard('green', 'yellow'));

/* register modul */
$modulLoader->registerModul('Anything' => new mySomethingExtended('green', 'yellow', 'blue', 'red'));
[/src]

Intern als array kannst du dann einfach das objekt ['Anything'] "überschreiben". Wenn du dann auf deiner Seite irgendwo aufrufst:

[src=php]
$modulLoader->execute('Anything');
[/src]

würde der Modulloader das extended Objekt ansprechen und nicht mehr das Standard.
Natürlich wäre wichtig, dass solche "Umschreibungen" koordinationstechnisch korrekt aufgebaut sind. Es müssen erst alle Module final geladen sein, bevor du mit der Ausführung beginnen kannst.
Ggf. musst du auch Prioritäten beachten, etwa dass ein Modul kein anderes überschreiben kann. Dazu muss dann die Vererbung dynamisch erfolgen, also nicht etwa hard coded class mySomethingExtended extends mySomethingStandard sondern eben etwa class mySomethingExtended extends $basicParent
Für die genaue Implementierung gibt es sicherlich 1002 Wege, ich wollte dir hier nur eine Richtung aufzeigen, zumindest mir macht es da mehr Spaß selbst zu knobeln und eine Lösung zu finden, als einen vorgefertigten 1:1 Code zu bekommen, den ich nur copy&pasten muss. ;)
 
  • Thread Starter Thread Starter
  • #4
Schonmal über einen Autoloader nachgedacht, dem du sagen kannst ob und was er zu laden hat?
An sich ja klar. Ich wollte es aber lieber so umsetzen, dass man erstmal die Standardversion des Projekts hat und ggf Plugin-Dateien in einen Ordner schiebt und dann alles automatisch eingebunden wird. Vermutlich werde ich da noch eine Prüfung einbauen, ob das Plugin überhaupt zu dem Paket gehört - möchte das Projekt später ggf. verkaufen.

Außerdem: ich würde nicht von null anfangen. Baue auf ein bestehendes Framework auf und erfinde nicht das Rad neu. (Es ist auch keine gute Übung, eine gute Übung wäre es mit einem bekannten Framework zu arbeiten, welches auch Zukunftssicher ist)
Das alles dient auch nicht der Übung, allerdings ist mein Projekt nicht aufwändig genug, um mich dafür in ein bestehendes Framework einzuarbeiten. Zudem gehen einige Sachen, die ich schreiben möchte nicht allzugut mit bestehenden Frameworks. Manchmal braucht man einfach neue Lösung - Allein die Rechenarbeit mit den Abfragen usw. im Hintergrund sind schwierig in ein bestehendes Framework einzupflegen.

Wenn du objektorientiert arbeitest, kannst du wunderschön arbeiten
Ich hatte mir überlegt objektorientiert zu programmieren, allerdings kriege ich in meinem Projekt keine vernünftige Struktur zurecht, da nahezu keine Funktion mehr als ein einziges Mal verwendet wird (vielleicht zwei oder drei Stück, die ich immerhin in einzelne Funktionen auslagern kann).
Mir dafür Klassen mit entsprechenden Funktionen zu schreiben ist zu aufwendig für den Nutzen, da einfach kein (Mehr-)Nutzen da ist.


Wenn ich keine schöne Lösung finde, müsste ich halt ne Klasse mit 2 Funktionen schreiben
- Standardzeug was immer zum Einsatz kommt
- und Zeug was durch eventuelle Plugins ersetzt wird.

Schön ist das zwar immer noch nicht, doch ggf. besser als anders.

Ggf. musst du auch Prioritäten beachten, etwa dass ein Modul kein anderes überschreiben kann. Dazu muss dann die Vererbung dynamisch erfolgen, also nicht etwa hard coded class mySomethingExtended extends mySomethingStandard sondern eben etwa class mySomethingExtended extends $basicParent
Was würde in deinem Beispiel in $basicParent stehen? Irgendwie verstehe ich nach meinem Gedankengang gerade nicht den Unterschied zwischen dem dynamischen und dem "altmodischen" Weg zu vererben?

Die Plugins werden ausschließlich von mir geschrieben.
Ich habe in den letzten zwei oder drei Jahren ein Projekt für die Firma eines Verwandten umgesetzt. Über die Zeit hat es sich so stark erweitert und es wurden viele Änderungen von mir gemacht, dass ich es nun "neu" schreiben muss, da die Änderungen zwar zwingend erforderlich waren, doch ich keine Zeit hatte diese "schön" einzupflegen. Somit habe ich derzeit einen zusammengeworfenen Haufen hard-Code, der einfach nicht mehr nachzuvollziehen ist.
Nun ist dieses Projekt aber anscheinend auf dem Markt nahezu nicht vertreten und daher würde ich das gerne in den nächsten Monaten "kundenreif" machen.
Da allerdings viele Funktionen (meistens zusätzliche "Unterseiten", die eine Tabellenanpassung in der Datenbank benötigen; allerdings auch Funktionen, die die bestehende Seite einfach nur erweitern (beispielsweise um eine erweiterte Ausgabe der Daten)) enthalten sind, die für den späteren "normalen" Kunden meist nicht zu gebrauchen sind, möchte ich diese in Plugins auslagern und dann entsprechend in einem "Premium-Paket" anbieten.

Nun habe ich halt das Problem die Plugins sinnvoll einzubinden, ohne alles neu zu schreiben, was gar nicht verändert wird. Die Prüfung, ob das Plugin überhaupt zu dem Paket gehört, werde ich gesondert erledigen. Sozusagen den Kopierschutz umsetzten. Viel bringen wird der nicht, für jeden der sich damit etwas auskennt, doch besser als so ganz ohne.

Somit kann ich auch die entsprechenden Plugins beim Ausführen des Installationsskriptes (kleine gesonderte Datei mit domainspeziefischen Zugangsdaten) festlegen und beuge somit der Verwendung von unnötigen Daten vor.

Wie sieht es denn mit meinem Beispiel-Code-Schnipsel aus - Totaler Humbug oder auf dem richtigen Weg?
 
"Zudem gehen einige Sachen, die ich schreiben möchte nicht allzugut mit bestehenden Frameworks."

Alles geht mit bestehenden Frameworks.
Was genau möchtest du machen?
 
  • Thread Starter Thread Starter
  • #6
Wenn ich bestehende Frameworks nutzen möchte sollte ich auch in einem Stil programmieren, der sich an den der Frameworks richtet (zumindest etwas). Da die Abfragen und Berechnungen, die ich in dem Projekt umsetze allerdings sehr umfangreich und an vielen Stellen sehr chaotisch werden geht das nicht. Und wie bereits vorher erwähnt - eine Einarbeitung und ein entsprechendes Framework wäre einfach zu viel Aufwand für das Projekt, da es in den nächsten Jahren nicht in meinen Zeitplan passt noch neben dem eigentlichen Programmieren weitere Sachen zu lernen, wobei ich sowieso schon wie verrückt allen Mist lernen muss^^

Mir gehts lediglich darum, wie ich das mit dem Plugins am besten lösen kann. Da ich alle Plugins selber entwickel kann ich natürlich auch "Kombinationen" schreiben und dann einfach die entsprechenden Dateien aus meinen 1000 Versionen raussuchen, das wäre allerdings noch unschöner.
Ich habe gehofft hier kann mir einer sagen, wie mein Ansatz dafür ist und ob ich den so, oder so ähnlich, nutzen könnte.
Hier sind ja so viele Entwickler unterwegs, da wird ja wohl schon einer sowas mal selber versucht haben und da etwas Erfahrung mit haben.
 
Ich glaube nicht, dass sich dein Projekt nicht objektorientiert umsetzen lässt und dass du keine Objekte verwenden möchtest, weil es zu umständlich ist, kann bestenfalls die Aussage eines Programmieranfängers sein. Du wirst es dir selbst danken, wenn du das Projekt nach 2-3 Monaten noch mal öffnest und den Quellcode modifizieren möchtest.
 
  • Thread Starter Thread Starter
  • #8
Ich programmiere schon sehr lange, zwar alles nur als Hobby und zwischendurch als Nebenjob, bin also kein Vollprofi aber ich habe lange mit objektorientierter Programmierung gearbeitet.
Allerdings sehe ich nicht den Vorteil darin mehr Code zu schreiben, wenn ich dadruch einfach keinen anderen Code einsparen kann. Laufzeit spare ich dadurch auch nicht und durch schöne Kommentare kann man auch den prozedualen Code sehr schön aufbereiten. Ohne Kommentare geht ja sowieso nichts mehr.

Klar, das Problem mit den Plugins hätte ich dann durch den Beitrag oben wohl gelöst, doch das muss doch auch anders gehen.

Du musst doch zugeben, dass prozeduale Aufrufe effektiver sein können als oo-Aufrufe.
[src=php]/*Der von dir vorgeschlagene Fall*/
class tolleKlasse
{

public function __construct()
{ }


public function hallo()
{
echo "Hallo";
}

}
$class = new tolleKlasse();
$class->hallo();

/*mein Fall*/
echo "Hallo";[/src]

Für welchen Codeabschnitt habe ich wohl länger gebraucht? Welcher wird wohl schneller ausgeführt? Es ist ausnahmsweise einfach unnütz.
Ich mache sonst alles, relativ gerne, objektorientiert. In meinen Beispielfragen nutze ich meist prozeduale Strukturen, weil die einfach schneller zu tippen sind und in den meisten Fällen das Beispiel nicht verändern. Aber in diesem Fall ist das einfach nur unpraktisch.
 
" und dann weitere Plugins, die die Seite um einige Funktionen erweitern soll."

klingt für mich nach Klassen extenden und Vererbung und alles. Ich wüsste keinen Ansatz wie man das runterbrechen kann ohne Klassen, ehrlich gesagt.
Außer gleichnamige Funktionen, die sich dann aber immer überschreiben.
Auch wirst du dann das kotzen kriegen, wenn du irgendwo eine Funktion deines Plugins aufrufen möchtest: woher weißt du, dass gerade dieses Plugin "erreichbar" ist, wenn nicht ohne Klasse?

Das ist alles viel zu kompliziert. OOP und gut ist. Die Zeit die hier mit diskutieren verschwendet wurde, hättest du in deine App bringen können.

Gruß
 
Du willst aber eben nicht Hallo ausgeben, sondern du willst funktionelle Einheiten gegeneinander abkapseln und diese sinnvoll erweitern bzw. ersetzen.


Eine andere Möglichkeit wäre über Dateien zu gehen und dort etwas wie eine Vererbungshierarchie zu implementieren:

display_irgendwas_standard.php
display_irgendwas_extend_001.php // plugin 1
display_irgendwas_extend_010.php // plugin 2
display_irgendwas_extend_011.php // plugin 1 und 2
display_irgendwas_extend_100.php // plugin 3
display_irgendwas_extend_101.php // plugin 1 und 3
display_irgendwas_extend_110.php // plugin 1 und 2
display_irgendwas_extend_111.php // plugin 1, 2 und 3
...

Damit sparst du dir allerdings bestimmt nichts.. Erst recht, wenn du bedenken musst, dass du mit jedem Plugin mehr Kombinationen beachten musst.

Etwas anderes fällt mir spontan auch nicht ein.
 
Zurück
Oben