Модель - это PHP класс, который формирует данные, запрашиваемые контроллером, и реализует основные принципы бизнес-логики приложения - например, доступ пользователей к данным, логирование производимых над страницей действий и т.д.
PHP-платформа Wad-er допускает отсутствие модели у любой страницы приложения, т.е. технически данные страницы может формировать один контроллер - без модели. Это мы уже могли видеть в примере выше:
class forum_controllers_topics extends common_controller { public function index($name) { print 'Hello' . $name . '!'; } }
Вызов модели из контроллера. Вызов модели осуществляется путем создания экземпляра класса модели в контроллере:
class forum_controllers_topics extends common_controller { public function index($name) { $post = new forum_models_posts(); } }
Здесь происходит вызов модели posts модуля forum. Файл модели находится по адресу http://site.com/ext/forum/models/posts.php.
В одном контроллере может происходить вызов нескольких моделей, например:
class forum_controllers_topics extends common_controller { public function index($name) { $post = new forum_models_posts(); //… $model = new wforum_models_messages(); //… } }
Создание модели. Имена классов моделей должны быть в нижнем регистре и следовать общему правилу - «модуль_ models_название файла модели». Файл модели должен находиться в следующем каталоге: http://site.com/ext/название_модуля/models/.
Например:
class forum_models_index { //… }
Здесь forum - название модуля, index - название файла модели, который находится по пути http://site.com/ext/forum/models/index.php
Типы моделей. PHP-платформа Wad-er позволяет формировать данные для бизнес-логики разными способами. В одних случаях модель может брать данные из базы данных (БД), в других - модель может формировать данные без использования внешних хранилищ.
Формирование данных без БД. Это самый простой способ формирования данных, которые поступают в контроллер. Метод модели может возвращать строку, массив или объект. Например:
class forum_models_index { function getData() { $output = 'Data from model index'; return $output; } }
В контроллере можно использовать эти данные следующим образом:
class forum_controllers_index extends common_controller { public function index($pars = '') { $model = new forum_models_index($this->parser); $this->modeldata = $model->getData(); $this->render(); } }
Работа с БД через wPrototype. Если модель работает с БД, можно при объявлении класса модели сделать его наследником класса wPrototype - базового класса системы, который осуществляет работу с БД. Таким образом, мы можем использовать все свойства и методы wPrototype в классе модели. При этом специально подключаться к БД не нужно - подключение происходит автоматически внутри wPrototype. Достаточно в конструкторе класса модели указать тип объекта (название таблицы БД), с которым будет работать данная модель.
Например:
class forum_models_index extends wPrototype { protected $parser; public function __construct($objtype = '', $id = '') { global $parser; $this->parser = $parser; $this->id = $id; parent::__construct('forum_posts'); } //… protected function _onBeforeInsert() { $this->setFieldNewVal('createby', $this->parser->getUserId()); return ''; } }
Здесь при вызове конструктора родителя было указано, что модель будет работать с таблицей forum_posts. Далее в методе _onBeforeInsert() мы можем работать с этой таблицей, изменив в ней значение поля createby.
Работа с БД без wPrototype. Модель может и не наследовать класс wPrototype. И в этом случае специально подключаться к БД также не нужно - соединение можно получить через свойство conn парсера (class pageParser) - $parser->conn, где $parser - объект pageParser.
Например:
class forum_models_topics { protected $parser; public function __construct() { global $parser; $this->parser = $parser; } public function getPhotos($id = 0) { $res = array(); $sql = "SELECT * FROM wforum_posts_photo o WHERE (o.masterid=".$id.") ORDER BY o.sortorder, o.id"; $rs = $this->parser->conn->SelectLimit($sql, 100); while($row = $rs->FetchRow()) { $res[] = array('id' => $row[0], 'notes' => $row[2], 'url' => $row[3]); } return $res; } }
Здесь следует обратить внимание на конструкцию $this->parser->conn->SelectLimit - через открытое соединение в $this->parser->conn совершается запрос к БД.
Доступ из модели ко всем основным функциям системы. Кроме соединения с БД можно дать классу модели доступ к основным функциям системы. Для этого в конструкторе модели (function __construct) мы объявляем глобальную переменную $parser, которая содержит объект парсера (class pageParser) - экземпляр основного класса ядра платформы. Таким образом, внутри модели появляется возможность использовать все методы класса pageParser.
Например:
class forum_models_ index extends wPrototype { protected $parser; public function __construct($objtype = '', $id = '') { global $parser; $this->parser = $parser; $this->id = $id; parent::__construct('wforum_topics'); } protected function _onInsert() { //подключение css-стилей $this->parser->addCSS(SYS_BASE_URL."libs/js/fancybox/jquery.fancybox.css"); //подключение js $this->parser->addScript(SYS_BASE_URL."libs/js/fancybox/jquery.mousewheel.js"); //получение id текущего пользователя $usr = $this->parser->getUserId(); //запрос к БД $res = $this->parser->utils->getFieldsFromSql("SELECT ..."), 'num'); return $res; } }
Автозагрузка моделей. Все файлы моделей подключаются в PHP-платформе Wad-er автоматически при инициализации системы во фронтальном контроллере index.php при помощи встроенной php-функции __autoload ().
Реализация Active Record (AR) в моделях платформы Wad-er. Active Record (AR) — это шаблон проектирования, который используется для абстрагирования доступа к базе данных в объектно-ориентированной форме. В PHP-платформе Wad-er каждый объект AR является экземпляром класса, унаследованного от ADOdb_Active_Record или wPrototype, и представляет отдельную строку в таблице базы данных. Поля этой строки соответствуют свойствам AR-объекта.
Кроме этого, модифицируя стандартный AR, разработчики PHP-платформы Wad-er представили в виде класса со своими свойствами и методами каждое поле в записи БД (Active Field).
Подробнее с AR-моделью можно ознакомиться в разделе Active Record.