RSS   Twitter   Copiny   Copiny
Нашел ошибку? 

Выдели фрагмент текста с ошибкой или неточностью и нажми Ctrl+Enter!

Создание MVC компонента Joomla 1.5 - Шаг 6, добавляем действия к Модели

Создание, сохранение, удаление, обновление элементов базы данных - CRUD

Итак, наш контроллер выполняет только две задачи: создание и изменение. Однако у нас есть кнопки также для сохранения, удаления записей, и отмены. Нужно написать соответствующий код для выполнения этих задач.

Сохранение записи

Следующим шагом логично будет реализовать сохранение записи. Это потребует использование выбора для обработки различных ситуаций, например, различия между созданием новой записи (запрос INSERT), и обновлением существующей записи (запрос UPDATE). Также существует несколько нюансов, связанных с получением данных из формы и помещения их в запрос.

Фреймворк Joomla! облегчает выполнение многих задач. Класс JTable упрощает управление записями в базе данных без необходимости заботится о написании SQL-кода, лежащего в основе этих операций. Он также облегчает перенос данных из HTML-форм в базу данных.

Создание класса Table

Класс JTable является абстрактным классом, от которого можно получить производные классы для работы с конкретными таблицами. Для его использования нужно просто создать класс, расширяющий класс JTable, добавить поля вашей базы данных как свойства, и переназначить конструктор для указания имени таблицы и первичного ключа.

Вот как выглядит наш класс JTable:

<?php
/**
 * Hello World table class
 * 
 * @package    Joomla.Tutorials
 * @subpackage Components
 * @link http://dev.joomla.org/
 * @license        GNU/GPL
 */

// No direct access
defined('_JEXEC') or die('Доступ ограничен!');

/**
 * Hello Table class
 *
 * @package    Joomla.Tutorials
 * @subpackage Components
 */
class TableHello extends JTable
{
    /**
     * Primary Key
     *
     * @var int
     */
    var $id = null;

    /**
     * @var string
     */
    var $greeting = null;

    /**
     * Constructor
     *
     * @param object Database connector object
     */
    function TableHello($db) {
        parent::__construct('#__hello', 'id', $db);
    }
}
?>

Как видите, здесь мы определили два поля: идентификатор и приветствие. Затем был определен конструктор, вызывающий конструктор родительского класса и передающий ему имя таблицы (#__hello), имя поля, являющегося первичным ключом (id), и объект коннектора базы данных.

Этот файл следует назвать hello.php и поместить в каталог tables в администраторском разделе нашего компонента.

Реализация функций в нашей модели

Теперь мы готовы добавить метод в модель для сохранения записи. Назовем этот метод store. Метод store() будет выполнять три вещи: помещать данные из формы в объект TableHello, проверять корректность сформированной записи и сохранять запись в базе данных.

Метод будет выглядеть так:

/**
 * Method to store a record
 *
 * @access    public
 * @return    boolean    True on success
 */
function store()
{
    $row => $this->getTable();

    $data = JRequest::get( 'post' );
    // Bind the form fields to the hello table
    if (!$row->bind($data)) {
        $this->setError($this->_db->getErrorMsg());
        return false;
    }

    // Make sure the hello record is valid
    if (!$row->check()) {
        $this->setError($this->_db->getErrorMsg());
        return false;
    }

    // Store the web link table to the database
    if (!$row->store()) {
        $this->setError($this->_db->getErrorMsg());
        return false;
    }

    return true;
}

Этот метод добавляется в модель hello.

Метод получает один параметр, являющийся ассоциативным массивом данных, которые мы сохраняем в базу данных. Эти данные могут быть легко получены из запроса, как будет показано далее.

Первая строка получает ссылку на объект JTable. Если таблица названа правильно, мы можем не указывать это имя - класс JModel знает, где его искать. Как вы помните, мы назвали наш класс таблицы TableHello и поместили его в файл hello.php в каталоге tables. Если вы следовали этим рекомендациям, класс JModel создаст объект автоматически.

Вторая строка получает данные из формы. Класс JRequest делает эту операцию очень легкой. В данном случае мы получаем все переменные, переданные с помощью метода POST. Они возвращаются в виде ассоциативного массива.

Остальное просто - мы получаем, проверяем и сохраняем. Метод bind() копирует значения из массива в соответствующие свойства объекта таблицы. В данном случае он копирует значения идентификатора и приветствия в объект TableHello.

Метод check() выполняет проверку данных. В классе JTable() этот метод просто возвращает true. Пока он не представляет какого-либо значения, но в будущем он позволит проверять данные с помощью класса TableHello. Этот метод может быть переназначен в классе TableHello методом, выполняющим необходимые проверки.

Метод store() будет помещать данные из объекта в базу данных. Если id равно нулю, будет создана новая запись (INSERT), в противном случае он обновит существующую запись (UPDATE).

Добавление задачи в контроллер

Теперь все готово для добавления задачи в контроллер. Поскольку задача называется save, мы должны назвать метод "save". Это просто:

/**
 * save a record (and redirect to main page)
 * @return void
 */
function save()
{
    $model = $this->getModel('hello');

    if ($model->store()) {
        $msg = JText::_( 'Greeting Saved!' );
    } else {
        $msg = JText::_( 'Error Saving Greeting' );
    }

    // Check the table in so it can be edited.... we are done with it anyway
    $link = 'index.php?option=com_hello';
    $this->setRedirect($link, $msg);
}

Все, что нам нужно - вызвать метод store() модели. Затем следует использовать метод setRedirect() для перенаправления к списку приветствий. Также мы задаем сообщение, которое будет отображено вверху страницы.

Удаление записи

Реализация функции в модели

В модели мы получаем список ID для удаления и вызываем класс JTable для их удаления:

/**
 * Method to delete record(s)
 *
 * @access    public
 * @return    boolean    True on success
 */
function delete()
{
    $cids = JRequest::getVar( 'cid', array(0), 'post', 'array' );
    $row => $this->getTable();

    foreach($cids as $cid) {
        if (!$row->delete( $cid )) {
            $this->setError( $row->getErrorMsg() );
            return false;
        }
    }                        

    return true;
}

Мы вызываем метод JRequest::getVar() для получения данных из запроса, затем вызываем метод delete() для удаления каждой строки. Сохраняя ошибки в модели, мы обеспечиваем возможность получить их позже, если потребуется.

Выполнение задачи удаления в контроллере

Это очень похоже на метод save(), выполняющий сохранение:

/**
 * remove record(s)
 * @return void
 */
function remove()
{
    $model = $this->getModel('hello');
    if(!$model->delete()) {
        $msg = JText::_( 'Error: One or More Greetings Could not be Deleted' );
    } else {
        $msg = JText::_( 'Greeting(s) Deleted' );
    }

    $this->setRedirect( 'index.php?option=com_hello', $msg );
}

Отмена операции редактирования

Все, что нужно для прерывания операции редактирования - перенаправление на главное представление:

/**
 * cancel editing a record
 * @return void
 */
function cancel()
{
    $msg = JText::_( 'Operation Cancelled' );
    $this->setRedirect( 'index.php?option=com_hello', $msg );
}

Заключение

Мы реализовали простой механизм для нашего компонента. Теперь у нас есть возможность редактировать элементы, отображаемые в представлении. Мы продемонстрировали взаимодействие между моделями, представлениями и контроллерами. Также мы показали, как класс JTable можно расширить для предоставления простого доступа к таблицам в базе данных. Также можно увидеть использование класса JToolBarHelper для создание панелей кнопок в компоненте для предоставления стандартного вида для различных компонентов.

Прикрепленные файлы:
com_hello_6.zip
Объем: 14.84 KB; Тип: zip; Загрузок: 1794; в сутки: ~1; Обновлен: 14:19, 24 Июля 2011;
Смотрите также:
Комментарии (12) Добавить комментарий
  • andrey
    andrey
    04 Августа 2011, 02:47
     ↑  0  ↓     ответ

    Можно ли редактировать уже готовые компоненты? К примеру добавить или удалить поля в админке, ну и соответственно при выводе на экран.

    • smet.denis
      smet.denis (админ)
      04 Августа 2011, 03:37
       ↑  +3  ↓     ответ

      Да, без проблем, а что вам мешает?)

      • andrey
        andrey
        04 Августа 2011, 14:47
         ↑  0  ↓     ответ

        Незнание. Подскажите как добавить поле (старт.номер к примеру). Добавить поле в таблицу БД, а где еще что прописать?

  • Владимир
    Владимир
    31 Августа 2011, 04:36
     ↑  0  ↓     ответ

    В данном примере рассматривается добавление только одной записи в базу, а если нужно добавить сразу несколько полей? Подскажите какие файлы и как нужно поменять?

  • Андрей
    Андрей
    01 Сентября 2011, 01:41
     ↑  -2  ↓     ответ

    Привет,

    я тоже столкнулся с такой проблемой, нуждаюсь в вашей помощи если вы в силах помочь

  • Владимир
    Владимир
    09 Сентября 2011, 00:44
     ↑  0  ↓     ответ

    А почему когда создаешь пункт в меню он не отображается в списке типов пункта меню? Как его создать в меню???

  • Сергей
    Сергей
    11 Сентября 2011, 19:22
     ↑  0  ↓     ответ

    Почему-то не работает кнопка создания новой записи, выкидывает ошибку = Компонент не найден :(

    Что я не так сделал?

    • Сергей
      Сергей
      11 Сентября 2011, 20:26
       ↑  0  ↓     ответ

      Забыл поменять скрытое поле в шаблоне

      <input type="hidden" name="option" value="com_hello" />

      на свое значение, из-за это он не находил необходимого компонента :)

  • torrenthot
    torrenthot
    24 Ноября 2011, 03:05
     ↑  +2  ↓     ответ

    Благодарю за статью, однако стоит отметить что вы забыли про то как вызвать модуль из меню..

    ведь вы явно не хотите чтобы начинающие строители модулей для джумлы вставляли в меню ссылки типа... test.torrenthot.com/index.php?option=com_hello&view=hello

  • Андрей
    Андрей
    25 Ноября 2011, 19:35
     ↑  0  ↓     ответ

    Сергей, очень актуальный вопрос: как вызвать модуль из меню?

    Спасибо

    • startom
      startom
      29 Ноября 2011, 13:18
       ↑  0  ↓     ответ

      Вот здесь все четко написано:

      goldensites.su/articles-joomla-16/sozdanie-komponenta-joomla-16-chast-3-dobavlyaem-tip-punkta-menyu

  • Александр
    Александр
    12 Апреля 2012, 14:50
     ↑  +1  ↓     ответ

    А как проще можно сделать, чтоб элементы в админке сразу списком выводились, а не переходить для редактирования по ссылке? У меня что-то не получается.

Оставить комментарий




* обязательно для заполнения

1 введенный почтовый адрес используется только для обратной связи при ответах в комментариях и сервиса gravatar.com
.