2010-11-22 7 views
1

Ok meine Frage hier kommen, ich habe eine Datenbank mit einem solchen SchemaDRY: Ratschläge, wie man Code nicht dupliziert?

+-------------+ +------------+ +-----------+ 
+ Object  + + car  + + computer + 
+-------------+ +------------+ +-----------+ 
+ id   + + object_id + + object_id + 
+ some_col + + max_speed + + CPU_speed + 
+ type  + + n_gears + + memory + 
+-------------+ +------------+ +-----------+ 

So, wenn die Eingabe zum Beispiel ein Computer die Benutzer zusammenfassen, ich habe einen Objektdatensatz erstellen, die alle gemeinsam genutzten Felder in sie speichern und ich erstellen Computer-Datensatz mit allen spezifischen Daten für Computer gespeichert werden.

So weit so gut, hier kommt mein Problem, so dass ich jede Aktion (und Controller-Methoden-Ansicht für jeden Objekttyp) duplizieren müsste. So jetzt in meinem Controller, ich habe diese Aktionen:

+ new-car 
    + new-computer 
    + show-car 
    + show-computer 
    + edit-car 
    + edit-computer 
    + list-car 
    + list-computer 

Also für jeden Typen I im Grunde der gesamten Code kopieren und ändern Sie einige Zeilen von Codes (dh das Auto Mapper durch Computer-Mapper zu ersetzen, gleiche gilt für Datensatzobjekt) . Ich muss die Anwendung erwähnen Sie das Zend-Framework und ist in PHP.

Ich möchte etwas mehr tun "Wiederhole dich nicht" und muss nicht den ganzen Code kopieren. Irgendeine Idee, wie man es eleganter macht?

+0

{neu, anzeigen, bearbeiten, list} -Objekt, wo das Objekt von der Umgebung bestimmt wird, z. B. Verzeichnispfad, ODER übergeben Sie es als Parameter für die Methode – ajreal

+0

@AJreal das sind Controller-Aktionen, frage ich mich, ob tatsächlich Ich würde besser eine private Methode zu meinem Controller machen und versuchen, irgendeine Art von Template-Funktion zu machen, indem ich PHP magics zB $ className = 'Application_Model_' benutze. $ Objekttyp; $ o = new $ className(); – RageZ

Antwort

2

Ich teile mit Ihnen meine grundlegende CRUD-Klasse. Wird wie geliefert geliefert. Teste für dich selbst. Einige Fehler können sein;)

<?php 
abstract class Controller_Crud extends Controller 
{ 
/* definované v dalších třídách */ 
protected $_viewKey = ''; 
protected $_url = 'admin/'; 
protected $_modelClass; 
protected $_formClass; 
protected $_filterFormClass = null; 
protected $_title = 'Untitled'; 

/* pro vnitřní potřebu */ 
protected $_model; 
protected $_form; 
protected $_filterForm; 
private $_defaultViewKey = 'crud'; 

/* 
* Inicializace třídy, vytvoření instancí modelů a formulářů 
* @see Tul/Controller/Tul_Controller_Admin#init() 
*/ 
public function init() 
{ 
    parent::init(); 
    $this->_model = new $this->_modelClass(); 
    $this->_form = new $this->_formClass(); 
    $this->view->indexUrl = $this->_url; 
    $this->view->viewKey = $this->_viewKey; 
    $this->view->title = $this->_title; 
} 

public function postDispatch() 
{ 
    // Po provedení akce je nastaven titlek 
    $this->view->headTitle($this->_title); 
} 
/** 
* základní akce zabezpečující výpis záznamů a filtrování 
* @return void 
*/ 
public function indexAction() 
{ 
    if(null !== $this->_filterFormClass){ 
     $this->_filterForm = new $this->_filterFormClass; 
    } 
    $filter = null; 
    if(null !== $this->_filterFormClass){ 
     if($this->_getParam('filter') && $this->_filterForm->isValid($this->_getAllParams())){ 
      $filter = $this->_filterForm->getValues(); 
     } 
     $this->_filterForm->populate($this->_getAllParams()); 

    } 
    /* @var Tul_Paginator */ 
    $paginator = $this->_model->getAllPaginator($filter); 
    $paginator->setCurrentPageNumber($this->_getParam('page',1)); 
    $this->view->data = $paginator; 
    $this->view->form = $this->_filterForm; 
} 

/* 
* Načte ID záznamu a pokud není nalezeno přesměruje s chybovou hláškou na hlavní stránku 
* @see Tul/Controller/Tul_Controller_Admin#getId() 
*/ 
public function getId() 
{ 
    $id = $this->_getParam('id', false); 
    if(false === $id){ 
     $this->addFlashMessage('error','Neplatné ID.'); 
     $this->_gotoUrl($this->_url); 
    } 
    return $id; 
} 

/** 
* akce pro přidání nového záznamu 
* @return void 
*/ 
public function pridatAction() 
{ 
    $this->view->headTitle('Přidat'); 
    if ($this->_request->isPost()) { 
     if ($this->_form->isValid($_POST)) { 
      $data = $this->_form->getValues(); 
      try { 
       $this->_beforeAdd($data); 
       $result = $this->_model->insert($data); 
       $this->_afterAdd($data, $result); 
       $this->addFlashMessage('success','Úspěšně přidáno. '); 
      } catch (Exception $e){ 
       $this->addFlashMessage('error','Došlo k chybě při přidávání:<br />' . htmlspecialchars($e->getMessage())); 
      } 
      $this->_gotoUrl($this->_url); 
     } else { 
      $this->_form->populate($_POST); 
     } 
    } 
    $this->view->form = $this->_form; 
    $this->_renderView('pridat.phtml'); 
} 

/** 
* Akce pro smazání záznamu 
* @return void 
*/ 
public function smazatAction() 
{ 
    $id = $this->getId(); 
    try{ 
     $this->_beforeDelete($id); 
     $result = $this->_model->delete($this->_model->quoteInto('id = ?',$id)); 
     $this->_afterDelete($id, $result); 
     $this->addFlashMessage('success','Úspěšně smazáno. '); 
    } catch (Exception $e){ 
     $this->addFlashMessage('error','Došlo k chybě při mazání:<br />'.htmlspecialchars($e->getMessage())); 
    } 
    $this->_gotoUrl($this->_url); 
} 

/** 
* akce pro úpravu záznamu 
* @return void 
*/ 
public function upravitAction() 
{ 
    $this->view->headTitle('Upravit'); 
    $id = $this->getId(); 
    $item = $this->_model->getById($id); 
    if ($this->_request->isPost()) { 
     if ($this->_form->isValid($_POST)) { 
      $data = $this->_form->getValues(); 
      try { 
       $this->_beforeUpdate($data, $item); 
       $result = $this->_model->update($data, $this->_model->quoteInto('id = ?',$id)); 
       $this->_afterUpdate($data, $result); 
       $this->addFlashMessage('success','Úspěšně upraveno. '); 
      } catch (Exception $e){ 
       $this->addFlashMessage('error','Došlo k chybě při úpravě:<br />'.htmlspecialchars($e->getMessage())); 
      } 
      $this->_gotoUrl($this->_url); 
     } else { 
      $this->_form->populate($_POST); 
     } 
    } else { 
     $this->_form->populate((array)$item); 
    } 
    $this->view->form = $this->_form; 
    $this->_renderView('upravit.phtml'); 
} 

/** 
* Pokud existuje načte pohled zděděné třídy, pokud neexistuje použije interní 
* @param $name string název pohledu 
* @return void 
*/ 
private function _renderView($name) 
{ 
    $completeName = $this->_viewKey . '/' . $name; 
    /* @var Zend_View_Abstract */ 
    foreach ($this->view->getScriptPaths() as $dir) { 
     if (is_readable($dir . $completeName)) { 
      return $this->renderScript($completeName); 
     } 
    } 
    return $this->renderScript($this->_defaultViewKey . '/' . $name); 
} 

/** 
* Metoda, která je zavolaná těsně před přidáním záznamu. 
* Umožňuje upravit data podle potřeby před vložením do databáze. 
* Vyhozením vyjímky přidání záznamu skončí chybou 
* @param $data array data, která budou přidána 
* @return void 
*/ 
protected function _beforeAdd(&$data){} 
/** 
* Metoda, která je zavolaná těsně po přidání záznamu. 
* Umožňuje upravit data podle potřeby ještě po vložení do databáze. 
* Vyhozením vyjímky přidání záznamu skončí chybou 
* @param $data array data, která budou přidána 
* @param $result mixed primární klíč přidaného záznamu 
* @return void 
*/ 
protected function _afterAdd(&$data, $result){} 
/** 
* Metoda, která je zavolaná těsně před úpravou záznamu. 
* Umožňuje upravit data podle potřeby ještě před úpravou v databázi. 
* Vyhozením vyjímky uprava záznamu skončí chybou 
* @param $data array data, která budou upravena 
* @param $item mixed původní data 
* @return void 
*/ 
protected function _beforeUpdate(&$data,$item){} 
/** 
* Metoda, která je zavolaná těsně po úpravě záznamu. 
* Umožňuje upravit data podle potřeby po úpravě v databázi. 
* Vyhozením vyjímky uprava záznamu skončí chybou 
* @param $data array data, která budou upravena 
* @param $result integer počet ovlivněných záznamů 
* @return void 
*/ 
protected function _afterUpdate(&$data,$result){} 
/** 
* Metoda, která je zavolána před smazáním záznamu. 
* Vyhozením vyjímky smazání záznamu skončí chybou 
* @param $id id mazaného záznamu 
* @return void 
*/ 
protected function _beforeDelete($id){} 
/** 
* Metoda, která je zavolána po smazání záznamu. 
* Vyhozením vyjímky smazání záznamu skončí chybou 
* @param $id id mazaného záznamu 
* @param $result počet smazaných řádků 
* @return void 
*/ 
protected function _afterDelete($id, $result){} 

} 

Und dann eine konkrete Umsetzung:

<?php 
class FunkceController extends Controller_Crud 
{ 
    protected $_url = '/admin/funkce/'; 
    protected $_modelClass = 'Admin_Functions'; 
    protected $_formClass = 'Form_Admin_Functions'; 
    protected $_filterFormClass = 'Form_Admin_FilterFunctions'; 
    protected $_viewKey = 'funkce'; 
    protected $_title = 'Funkce'; 
} 

this helps;)

+0

Wer schreibt Methodennamen in nicht-Englisch? – raveren

+1

@ Raveren, wer Statements als Fragen stellt? –

+1

Jemand, der seine Kurse für akademische Umgebung schrieb (es war Teil meiner Bachelorarbeit), wo sie denken, dass die Verwendung der Muttersprache gut ist.Ich denke nicht, aber ich hatte nicht die Absicht, diese langjährigen Bräuche nur in der Zeit meiner Abschlussprüfungen zu ändern: D –

1

Sie müssen eine Meta-Tabelle mit Informationen über jeden Objekttyp erstellen, d. H. Welche Felder er hat, wie er sie anzeigen soll (Eingabe oder Auswahl zum Beispiel), ihre Reihenfolge und solche Sachen.

Dann können Sie auf den Hauptcontroller zugreifen, übergeben Sie nur den Objektnamen, und es sollte dann die entsprechenden CRUD-Formulare generieren.

+0

Sie haben also einige private Methoden und Sie verwenden sie in Aktionen. Zum Beispiel private Funktion _list ($ object_type). und in deiner Aktion tust du $ this -> _ list ('car'); Habe ich recht ? – RageZ

+0

Ja, das ist eines der gültigen Muster. Die '_list'-Methode würde Informationen der Spalten abrufen, die zum Anzeigen und Zeichnen einer Liste von Elementen erforderlich sind. – raveren

1

Ich habe etwas ähnliches zu Tomáš Fejfar ...

erstellen ein Basis-CRUD-Controller und eine Basismodellklasse mit CRUD-Methoden. Sie können sogar allgemeine Ansichtsskripts verwenden, die für alle Inhaltstypen für grundlegende CRUD-Vorlagen funktionieren.

In jedem Controller benötigen Sie nur ein paar Variablen oben, um Änderungen vorzunehmen.