Heute gibt es an unserem CMS einiges zu tun, denn wir erstellen das Widget-System. Unser Dashboard zeigt ja bisher nur feste Widgets an. Das ganze wird heute dynamisch gemacht.

Der Aufbau der Widgets

Es gibt eine abstrakte Klasse namens WidgetBase. Wenn nun jemand ein Widget erstellen möchte, muss er von dieser Klasse erben. Die Basisklasse soll folgendes haben: Im Code sieht das ganze so aus(gespeichert unter /system/classes/widgetbase.php):
<?PHP
  abstract class WidgetBase{
    public $color    = "white";
    public $headline = "";
    public $content = "";
    
    public function display(){
      ?>
        <li class="widget color-<?PHP echo $this->color; ?>">
          <div class="widget-head">
            <h3><?PHP echo $this->headline; ?></h3>
          </div>
          <div class="widget-content">
            <?PHP echo $this->content; ?>
          </div>
        </li>
      <?PHP
    }
    
     public abstract function load();
  }
?>
Nun erstellen wir unser erstes Widget! Zur Einführung werden wir für alle neuen Benutzer das Rundgangs-Video des CMS anzeigen. Wer noch ein paar Plugin Vorschläge hat, kann sie hier einreichen. Der Code dafür ist nicht weiter schwer. Der HTML-Code kommt von YouTube. Mit extends erben wir hier von der Klasse WidgetBase. Dort wird einfach die Methode load überschrieben. Das kommt dabei raus Datei(\system\plugins\lookaround\widget.php):
<?PHP
  class LookAround extends WidgetBase{
    public function load(){
      $this->headline = "Rundgang durch CMS";
      $this->content = "<p style=\"text-align:center;\">
                        <object width=\"320\" height=\"265\">
                          <param name=\"movie\" 
                            value=\"http://www.youtube.com/v/MdpnMFZHbFc&hl=de_DE&fs=1&rel=0\">
                          </param>
                          <param name=\"allowFullScreen\" value=\"true\" />
                          <param name=\"allowscriptaccess\" value=\"always\" />
                          <embed 
                            src=\"http://www.youtube.com/v/MdpnMFZHbFc&hl=de_DE&fs=1&rel=0\" 
                            type=\"application/x-shockwave-flash\" 
                            allowscriptaccess=\"always\" 
                            allowfullscreen=\"true\" 
                            width=\"320\" 
                            height=\"265\" />
                        </object>
                        </p>";
    }
  }
?>

Datenbankanbindung

Die zu ladenen Plugins werden in der Datenbank gespeichert. Hierbei gibt es zwei Tabellen:
  1. cms_widgets: Speichert die einzelnen Widgets
  2. cms_dashboards: Speichert welche Widgets im Dashboard angezeigt werden.
Diese zwei Querys erstellen die Tabellen:
CREATE TABLE `cms_widgets` (
`path` VARCHAR( 255 ) NOT NULL ,
`name` VARCHAR( 50 ) NOT NULL ,
`class` VARCHAR( 50 ) NOT NULL ,
PRIMARY KEY ( `path` )
) TYPE = MYISAM ;
und
CREATE TABLE `cms_dashboards` (
`id` INT( 10 ) NOT NULL ,
`col` INT( 1 ) NOT NULL ,
`row` INT( 2 ) NOT NULL ,
`path` VARCHAR( 255 ) NOT NULL ,
PRIMARY KEY ( `id` , `col` , `row` )
) TYPE = MYISAM ;
Nun müssen wir noch unser LookAround Widget in die Tabellen eintragen. Das geht so:
INSERT INTO `cms_widgets` ( `path` , `name` , `class` )
VALUES (
'lookaround/widget.php', 'LookAround', 'LookAround'
);
INSERT INTO `cms_dashboards` ( `id` , `col` , `row` , `path` )
VALUES (
'1', '1', '1', 'lookaround/widget.php'
);

Der Widget Controller

Fahren wir fort mit der neuen WidgetController-Klasse (/system/classes/widgetcontroller.php). Diese Klasse steuert die Widgets. Das heißt, sie liefert die Widget-Objekte zurück und registriert neue Widgets. Zum Anfang gibt's erstmal nur die leere Klasse, die Methoden müsst ihr nach und nach reinschreiben ;-) <?PHP class WidgetController{ } ?> Fangen wir mit der Registrierung der Widgets an. Diese Methode werden wir aber erst demnächst brauchen. Sie führt einfach nur das Insert-Statement aus:
    function register($class,$name,$path){
      global $dbpraefix;
      $class = mysql_real_escape_string($class);
      $name      = mysql_real_escape_string($name);
      $path      = mysql_real_escape_string($path);
      return @mysql_query("INSERT ".$dbpraefix."widgets 
                                   (class       ,name       , path)
                             VALUES('".$class."','".$name."','".$path."')");
    }
Fahren wir fort. mit der Methode getAllWidgets liefern wir alle registrierten Widgets zurück. Das geht so:
function getAllWidgets(){
  global $dbpraefix;
  $widgetData = getAllWidgetData();
  if($widgetData){
    foreach($widgetData as $widget){
      $res[] = getWidget($widget);
    }
  }
  
  return $res;
}
Darin werden bereits zwei Funktionen aufgerufen, zu denen wir gleich erst kommen. Nun gibt's erstmal die Funktion getWidgetData die die Eigenschaften eines Widgets als Array zurückgibt:
function getWidgetData($path){
  global $dbpraefix;
  $path = mysql_real_escape_string($path);
  $res = mysql_query("SELECT class,path FROM ".$dbpraefix."widgets WHERE path = '".$path."'");
  return mysql_fetch_assoc($res);
}
Darf ich vorstellen: getWidget($data). Diese Funktion wandelt das Array mit den Widget-Eigenschaften in ein Widget Objekt um. Hier brauchte auch ich erstmal Hilfe. Diese bekam ich freundlicherweise hier. Nun ist die Funktion ein Zweizeiler:
function getWidget($data){
  include_once('../system/plugins/'.$data['path']);
  return new $data['class']();
}
Nun wollen wir die Widget-Eigenschaften aller Widgets bekommen. Dies geht über foglende Funktion:
function getAllWidgetData(){
  global $dbpraefix;
  $mysqlRes = mysql_query("SELECT class,path FROM ".$dbpraefix."widgets");
  while($row = mysql_fetch_assoc($mysqlRes)){
    $res[] = $row;
  }
  return $res;
}
Damit ist diese Klasse auch erstmal fertig.

Die Dashboard Klasse

Ja, das nimmt heute kein Ende mit den neuen Klassen! Kommen wir nun zur Dashboard-Klasse. Diese zeigt die zu ihm gespeicherten Widget ab. Ich hab sie so erstellt, dass es später auch mehrere Dashboards geben kann. Das könnte zum Beispiel für einen Userbereich ganz nützlich sein. Bei der Klasse bin ich mal so gnädig und gibt euch neben dem Grundgerüst auch noch 2 Eigenschaften mit auf dem Weg. $id ist die ID aus der cms_dashbaords und in $cols sind die Widgets der einzelnen Spalten aufgelistet. Datei: /system/classes/dashboard.php.
  class Dashboard{
    public $id;
    public $cols;
  }
?>
Und auch diese Klasse hat wundersamerweise auch Funktionen. Die erste Funktion die wir erstellen ist die loadWidgets. Sie lädt die Widgets in die $col variable:
function loadWidgets(){
  $this->cols[] = $this->loadWidgetsByColumn(1);
  $this->cols[] = $this->loadWidgetsByColumn(2);
  $this->cols[] = $this->loadWidgetsByColumn(3);  
}
Dort wird die Funktion loadWidgetsByColumn aufgerufen. Diese lädt die Widgets zu der jeweiligen Spalte. Das geht so:
function loadWidgetsByColumn($columnId){
  global $dbpraefix;
  $columnId = mysql_real_escape_string($columnId);
  $mysqlRes = mysql_query("SELECT path FROM ".$dbpraefix."dashboards 
                           WHERE col = '".$columnId."' AND id = '".$this->id."'
                           ORDER BY row");
  while($row = mysql_fetch_row($mysqlRes)){
    $widgetData = WidgetController::getWidgetData($row[0]);
    $widget = WidgetController::getWidget($widgetData);
    $widget->load();
    $res[] = $widget;
  }
      
  return $res;
}
Kommen wir zu der Funktion display. Sie zeigt das Dashboard an. Wegen einem Javascript-Fehler in meinem Syntaxhighlighting Tool ohne Highlighting. Hab überigens nen Wordpress-Plugin dafür gefunden, muss es aber noch testen.
function display(){
   echo "<div id=\"columns\">";
   $this->displayColumn(0);
   $this->displayColumn(1);
   $this->displayColumn(2);
   ?>
        <script type="text/javascript" src="http://jqueryjs.googlecode.com/files/jquery-1.2.6.min.js"></script>
        <script type="text/javascript" src="jquery-ui-personalized-1.6rc2.min.js"></script>
        <script type="text/javascript" src="inettuts.js"></script>
   <?PHP
    }
Mit displayColumn geben wir nun die einzelnen Spalten aus:
function displayColumn($id){
  ?>
    <ul id="column<?PHP echo $id; ?>" class="column">
      <?PHP
        if($this->cols[$id]){
          foreach($this->cols[$id] as $widget){
            $widget->display();
          }
        }
´     ?>
    </ul>
  <?PHP
}

Anzeigen des Dashboards im Admin-Bereich

Nun kommen wir auch schon zum Ende. Wir müssen unsere Dashboard-Klasse nun nur noch in der /admin/includes/dashboard.php benutzen das geht so:
<?PHP
  $dashboard = new Dashboard();
  $dashboard->id = 1;
  $dashboard->loadWidgets();
  $dashboard->display();
?>

Schaffen wir es bis zu dem 100. Beitrag?

Ziel ist es ja seit kurzem das CMS bis zum 100. Beitrag zu Ende zu bringen. Ich denke es wird schwer möglich, wenn man nicht alles in richtig langen Beiträgen schreibt. Wir haben nämlich noch ein bisschen zu tun (Installation von Widgets, Allgemeiner Installer, CSS-Optimierungen,...) Mal sehen, ob ich es trotzdem schaffe sie in sinnvoll zusammenhängende Beiträge zu packen. Und noch zum Schluss: Wer den heutigen Code per Copy & Paste kopiert hat, muss 3 Strafwidgets schreiben^^