Das MVC-Framework wächst!

Ich war heute mittag mal wieder fleißig am Programmieren und bin ziemlich weit gekommen. Ich habe mein Projekt (was für ein Projekt es ist, wird noch nicht verraten ;)) erweitert. Dazu war auch die Erweitern des Frameworks notwendig. Insbesondere wurden Models eingeführt. Auch die MySQL-Klasse kann sich sehen lassen.

Zuerst möchte ich euch die kleineren Änderungen vorstellen:

FW_HttpRequest wurde um Methoden und Attribute erweitert

Diese Änderung ist eigentlich nichts weltbewegendes.

private $MVC_Controller;
private $MVC_Action;

public function setControllerName($name)
{
   $this->MVC_Controller = $name;
}
  
public function getControllerName()
{
    return $this->MVC_Controller;
}
  
public function setActionName($name)
{
    $this->MVC_Action = $name;
}
  
public function getActionName()
{
    return $this->MVC_Action;
}

Man hat jetzt überall, wo eine Instanz von FW_HttpRequest zur Verfügung steht, die Möglichkeit, die Aktion oder den Controller zu ändern. So kann man z.B. auf Fehler aufmerksam machen (indem man setActionName(„Error“) und setControllerName(„Error“) ausführt).

Es gibt jetzt neue Möglichkeiten zur Ausgabe von URLs
Diese Möglichkeit habe ich als ViewHelper realisiert. Der Code sieht so aus:

/**
 * Liefert ohne Parameter einfach die URL zum WWW-Root
 * Mit Parametern baut sie eine URL zusammen, die dynamisch
 * mod_rewrite verwenden kann  
 */ 
class ViewHelper_URL implements FW_ViewHelperInterface
{
  public function run(array $params = array())
  {
    if(count($params) == 0)
    {
      return FW_config::getInstance()->get("www_root");
    }
    else
    {
      $mod_rewrite = (FW_Config::getInstance()->get("mod_rewrite") == 1);
      
      $url = FW_config::getInstance()->get("www_root");
      if(isset($params[0]))
      {
        $url .= "/".(($mod_rewrite) ? "" : "?module=").$params[0];
      }
      
      if(isset($params[1]))
      {
        $url .= ($mod_rewrite) ? "/" : "&action="; 
        $url .= $params[1].(($mod_rewrite) ? ".html" : "");
      }
      else
      {
        $url .= (($mod_rewrite) ? "/index.html" : "&action=index");
      }
      
      if(isset($params[2]) && is_array($params[2]))
      {
        $url .= ($mod_rewrite) ? "?" : "&";
        $counter = 1;
        foreach($params[2] as $params)
        {
          foreach((array)$params as $paramname => $paramval)
          {
            if($counter != 1)
            {
              $url .= "&";
            }
            $url .= $paramname."=".$paramval;
          }
          $counter++; 
        }      
      }
      
      return $url;
    }
  }
}

Wenn mod_rewrite verwendet wird, erkennt die Methode das und baut die URL entsprechend zusammen.

Seiten direkt umleiten, dynamisches mod_rewrite
Auch FW_HttpResponse hat eine neue Methode bekommen: FW_HttpResponse::redirect($controller, $action, array $additional_params = array())

Hiermit lässt sich eine Weiterleitung bewerkstelligen. Man muss nicht wissen, ob mod_rewrite verwendet wird. Das entscheidet die Methode selbst:

$mod_rewrite = (FW_Config::getInstance()->get("mod_rewrite") == "1") ? true : false;
    if($mod_rewrite)
    {
      $url = FW_Config::getInstance()->get("www_root")."/".$controller."/".$action.".html"; 
    }
    else
    {
      $url = FW_Config::getInstance()->get("www_root")."/?module=".$controller."&action=".$action."&".$additional_params;
    }
    
      if(count($additional_params) > 0)
      {
        if($mod_rewrite)
        {
          $url .= "?";
        }   
        else
        {
          $url .= "&";
        }
        
        $counter = 1;
        foreach($additional_params as $params)
        {
          foreach($params as $paramname => $paramval)
          {
            if($counter != 1)
            {
              $url .= "&";
            }
            $url .= $paramname."=".$paramval;
          }
          $counter++; 
        }      
      }    
      
    $this->redirectURL($url, true);

Wie man sieht, wird auch FW_HttpRequest::redirectURL() hier eingesetzt. Wer wissen will, wie diese aussieht, schaut einfach mal hier 😉

public function redirectURL($url, $immediately = false)
  {
    $this->addHeader("Location", $url);
    if($immediately === true)
    {
      $this->send();
      exit();
    }
  }

ViewFactory
Ob das die entgültige Lösung ist? Ich weiß es nicht! Ich denke aber ja. Weil sie das tut, was man von ihr erwartet. Ich habe das einfach so gemacht:

final class FW_View
{    
   /**
    * MUSS NOCH RICHTIG KOMMENTIERT WERDEN
    * 
    * Diese Methode soll das richtige View-Objekt liefern. Es dient also als
    * Factory für die Views. Das soll dazu führen, dass der Programmierer nicht
    * wissen muss, mit welchem View-Objekt er arbeitet.                
    */       
   public static function getView()
   {
     return call_user_func_array(array(FW_FrontController::$view,'getInstance'),array());
   }
}

Die Methode liefert einfac die View-Instanz der Klasse zurück, die in FW_Controller::$view festgelegt wurde. Hat jemand eine bessere Idee?

Das wichtigste: Es gibt jetzt Models
In meinem Projekt gibt es zwar erst eins, aber sie sind möglich 🙂 Wie genau, erfahrt ihr in einem späteren Artikel. Das Konzept ist noch nicht ganz ausgereift.

Hier könnt ihr euch ein Bild davon machen, wie man das Model aufgebaut ist (das hier ist zum Editieren eines Datenbankbasierten Menüs):

class Model_Menu extends FW_AbstractModel
{
  private $db = null;
  
  public function __construct()
  {
    $this->db = FW_MySQL::getInstance("db1");
  }
  
  public function getMenuEntries()
  {
    $result = $this->db->getRowset("SELECT * FROM menu ORDER BY position ASC");
    return $result;
  }
  
  public function getEntryPosition($id)
  {
    return (int)$this->db->getFieldValue("SELECT position FROM menu WHERE id=".(int)$this->db->escape($id), "position");
  }
  
  public function setEntryPosition($id, $pos)
  {
    return $this->db->updateTable("menu", array(
                                                 array("position" => (int)$this->db->escape($pos))
                                               ), "id=".(int)$this->db->escape($id)
                                 );
  }
  
  public function getLastPosition()
  {
    return (int)$this->db->getFieldValue("SELECT MAX(position) as maximal FROM menu", "maximal");
  }
  
  public function addEntry($title, $link, $position)
  {
    return $this->db->query("INSERT INTO menu (title, link, position) VALUES ('".$this->db->escape($title)."', 
                                                                              '".$this->db->escape($link)."', 
                                                                               ".(int)$this->db->escape($position).")");
  }
  
  public function deleteEntry($id)
  {
    return $this->db->deleteFromTable("menu", "id = ".(int)$this->db->escape($id));
  }
}

Und so wird es im Controller eingebunden:

class Controller_Admin_Menu extends FW_Controller
{
  private $model = null;
  private $view = null;
  public function __construct()
  {       
    $conf = FW_Config::GetInstance();
    $data["entries"] = array();
    $data["entries"][] = array("Übersicht",        $conf->get("www_root")."/admin_index/index.html");
    $data["entries"][] = array("Menü bearbeiten",  $conf->get("www_root")."/admin_menu/index.html");
    
    $this->view = FW_View::getView();
    $this->view->addTemplateContent("submenu", $data, "submenu.tpl.php");
    
    $this->model = new Model_Menu();
    
  }
  
  public function index_Action()
  { 
     $this->model->getMenuEntries();  
     $data = array("entries" => $this->model->getMenuEntries(),
                   "new_position" => $this->model->getLastPosition()+1);                      
     
     
     $this->view->addTemplateContent("content", $data, "admin/menu.tpl.php");
  }
  
  public function move_Action()
  {
    $id = (int)FW_HttpRequest::getInstance()->getGet("id");
    $dir = FW_HttpRequest::getInstance()->getGet("dir");
    
    
    switch($dir)
    {
      case "up":   $this->model->setEntryPosition($id, $this->model->getEntryPosition($id)+1); break;
      case "down": $this->model->setEntryPosition($id, $this->model->getEntryPosition($id)-1); break;
      default: break;
    }
    
    FW_HttpResponse::getInstance()->redirect("Admin_Menu", "index");
  }
  
  public function add_Action()
  {
    $title =    FW_HttpRequest::getInstance()->getPost("title");
    $position = FW_HttpRequest::getInstance()->getPost("position");
    $link =     FW_HttpRequest::getInstance()->getPost("link");
    
    if(!empty($position) && !empty($title) && !empty($link))
    {
      $this->model->addEntry($title, $link, $position);
    }
    FW_HttpResponse::getInstance()->redirect("Admin_Menu", "index");
  }
  
  public function delete_Action()
  {
    $id = (int)FW_HttpRequest::getInstance()->getGet("id");
    $this->model->deleteEntry($id);
    FW_HttpResponse::getInstance()->redirect("Admin_Menu", "index");
  }
  
  public function edit_Action()
  {
  
  }
}

Viel Spass damit!

1 Star2 Stars3 Stars4 Stars5 Stars (Wurde noch nicht bewertet)
Loading...


Ein Kommentar zu “Das MVC-Framework wächst!”

  1. Die aktuellste Version meines HMVC-Frameworks erhaltet ihr ab sofort immer hier: http://www.net-developers.de/blog/2011/02/13/download-info-shfw-hmvc-framework-in-php/

Hinterlasse einen Kommentar!

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.

Diese Website verwendet Akismet, um Spam zu reduzieren. Erfahre mehr darüber, wie deine Kommentardaten verarbeitet werden.

»Informationen zum Artikel

Autor: Simon
Datum: 10.12.2008
Zeit: 06:00 Uhr
Kategorien: Mein MVC-Framework
Gelesen: 6332x heute: 2x

Kommentare: RSS 2.0.
Diesen Artikel kommentieren oder einen Trackback senden.

»Meta