Write to multiple tables in joomla component?

▼魔方 西西 提交于 2019-11-30 05:09:20

I finally made it. As I spent many hours on this and found that a lot of people where looking for an answer, here is how I did.

I suppose you know how to create a component, using the standard MVC structure:

  1. Component entry point
  2. Component controller
  3. Eventually component router
  4. Component view
  5. Component model
  6. Component controller

In model components\my_component\models\my_model.php create your own save function

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;
}

Of course, you need the getTable function called in the save function

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);
}

And it works! So simple! Of course, as I said in my question the whole $data is sent to the parent save() function to with data that are not necessary for table_one or table_two. It works this way with the standard joomla structure (no hack or direct query in the code).

Hope it helps.

There may be those out there who disagree with the way that the following method disrupts the MVC structure just a bit, but I've found it to be the simplest for me.

Typically, you have a model that fits one of the tables. In your example with pushing data to the users table as well as one in your component, I would add the following to the model for the table in your component:

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;
}

The first part of this function should save the data to the components table just like normal. But you can tack what you need on to the rest of the component to make whatever you like happen.

I would almost guarantee that there is a better way to chain models (and I've seen some of the changes happening in the Joomla Platform core that will lead to better ways in the future), but this should get you going for now.

In addition, for prompt 3, I would handle in the controller if you need to sometimes save just one table and sometimes save both. I've found that the save functions are pretty safe to run even when parts aren't loaded, so I usually just let it run.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!