2013-02-06 6 views
9

Ich versuche eine Komponente (Frontend) zu erstellen, die mehrere Tabellen verwendet. Ich habe 1 oder 2 Beiträge gefunden, die teilweise auf die Frage antworten, aber keine wirklich. Der Punkt scheint immer einfach und offensichtlich für denjenigen zu sein, der weiß, wie man es macht, aber es wird nie wirklich erklärt (oder ich habe den richtigen Beitrag verpasst).Schreiben an mehrere Tabellen in Joomla-Komponente?

In meiner Komponente gibt der Benutzer Daten in einer Ansicht, die in zwei Tabellen gespeichert werden müssen: die Standard Joomla User-Tabelle also # __users eine zusätzliche Tabellendaten zu speichern, die in Joomla dh # __users_complements nicht enthalten sind

Ich bin ein Anfänger, also vielleicht liege ich falsch, aber ich verstand, dass die Standardfunktionen von Joomla nur Ergebnisse eines Formulars in einer Tabelle speichern können. In meinem Fall muss ich die Standardfunktionen in meinem Modell überschreiben: com_component/model/my_model.php.

1) Ich bin verwirrt, weil ich nicht wirklich verstehe, welche Funktion muss übergangen werden: save()? Geschäft()? andere?

2) Sagen wir, ich überschreibe die save() - Funktion, sollte ich den gesamten Code neu schreiben, um Daten zu speichern (das Datenarray explodieren und alle Aktualisierungsabfragen erstellen) oder zwei Standardtabellenobjekte erstellen.

In diesem Fall (2 Objekte) scheint es seltsam, jedes Mal das gesamte Datenfeld an die Elternfunktion zu senden, da ich weiß, dass ein Teil für Tabelle 1 und der andere Teil für die Tabelle 2 ist vorher teilen, nicht wahr?

3) Sollte ich zwei Modelle erstellen und diese Modelle von meinem Controller aus verwalten, wenn ich Daten aus dem Formular zurückgeholt habe und die Speicherfunktion des Modells aufgerufen habe?

Können Sie mir helfen, zu klären, wie Sie dieses Speichern in mehreren Tabellen durchführen können? Ein Beispiel mit Code wird sehr geschätzt. Danke

Antwort

18

Ich habe es endlich geschafft. Da ich viele Stunden damit verbracht habe und festgestellt habe, dass viele Leute nach einer Antwort suchen, hier ist, wie ich es gemacht habe.

Ich nehme an Sie wissen, wie eine Komponente erstellen, die Standard-MVC-Struktur mit:

  1. Component Einstiegspunkt
  2. Component Controller
  3. Schließlich Komponente Router
  4. Komponentensicht
  5. Komponentenmodell
  6. Komponentensteuerung

Im Modell Komponenten \ My_Component \ models \ my_model.php erstellen Sie Ihre eigene Speicherfunktion

public function save($data) 
{ 
    // Initialise variables. 
    $userId = (!empty($data['id'])) ? $data['id'] : (int)$this->getState('user.id'); 
    $user = JFactory::getUser(); 

    $table_one = $this->getTable('TableOne', 'MyComponentTable', array()); 
    $table_two = $this->getTable('TableTwo', 'MyComponentTable', array()); 

    // Bind the data. 
    if (!$table_one->bind($data)) 
    { 
     $this->setError(JText::sprintf('USERS PROFILE BIND FAILED', $user->getError())); 
     return false; 
    } 

    if (!$table_two->bind($data)) 
    { 
     $this->setError(JText::sprintf('USERS PROFILE BIND FAILED', $user->getError())); 
     return false; 
    } 

    // Store the data. 
    if (!$table_one->save($data)) 
    { 
     $this->setError($user->getError()); 
     return false; 
    } 

    if (!$table_two->save($data)) 
    { 
     $this->setError($user->getError()); 
     return false; 
    } 

    return $user->id; 
} 

Natürlich müssen Sie die getTable Funktion in der Funktion speichern genannt

public function getTable($type = 'TableOne', $prefix = 'MyComponentTable', $config = array()) 
{ 
    // call the administrator\components\com_mycomponent\tables\__tablename__.php 
    $this->addTablePath(JPATH_COMPONENT_ADMINISTRATOR . '/tables'); 
    return JTable::getInstance($type, $prefix, $config); 
} 

Und Es klappt! So einfach! Natürlich, wie ich in meiner Frage sagte, die gesamten $ Daten werden an die Eltern save() - Funktion mit Daten gesendet, die nicht für Tabelle_ein oder Tabelle_zwei notwendig sind. Es funktioniert so mit der Standard-Joomla-Struktur (kein Hack oder direkte Abfrage im Code).

Ich hoffe, es hilft.

+0

Schön. Dies hat den Vorteil, zu prüfen, ob Sie beide Tabellen binden können, bevor Sie etwas speichern. –

+1

In Joomla 3 JTable speichern Methode mit Bind ($ Daten) innerhalb, so dass es keine Notwendigkeit, Daten vor der Verwendung der Speichermethode zu binden. – 3ehrang

2

Möglicherweise gibt es diejenigen, die nicht mit der Art und Weise übereinstimmen, dass die folgende Methode die MVC-Struktur nur ein wenig unterbricht, aber ich habe gefunden, dass es die einfachste für mich ist.

Normalerweise haben Sie ein Modell, das zu einer der Tabellen passt. In Ihrem Beispiel mit Daten an die Benutzer-Tabelle schieben sowie einen in Ihrer Komponente, würde ich folgende zum Modell für die Tabelle in Ihrer Komponente hinzufügen:

public function save($data) { 
    if (!parent::save($data)) { 
     return false; 
    } 

    // add necessary code to save to the users table, since there isn't a standard way to do this that I'm aware of 

    // sometimes I will grab another model even 
    require_once(JPATH_BASE . '/administrator/components/com_users/models/user.php'); 
    $other_model = $this->getInstance('user', 'UsersModel'); 
    $other_model->save($data); 

    return true; 
} 

Der erste Teil dieser Funktion soll die Daten speichern zur Komponenten-Tabelle wie normal. Aber du kannst das, was du brauchst, an den Rest der Komponente heften, um das zu machen, was du willst.

Ich würde fast garantieren, dass es eine bessere Möglichkeit gibt, Modelle zu verketten (und ich habe einige Veränderungen im Joomla Platform-Kern gesehen, die zu besseren Wegen in der Zukunft führen), aber das sollte Sie in Gang bringen zur Zeit.

Darüber hinaus, für die Eingabeaufforderung 3, würde ich in der Steuerung behandeln, wenn Sie manchmal nur eine Tabelle speichern und manchmal beide speichern müssen. Ich habe festgestellt, dass die Speicherfunktionen auch dann sicher ausgeführt werden können, wenn Teile nicht geladen sind. Daher lasse ich es normalerweise laufen.

+0

Dank David, bevorzugte ich eine andere Methode (siehe meine eigene Antwort). –