Плюшка CMS#26.04.2018

/* Создан для быстрой разработки приложений */
Скачать Демо

10.1. Контроллер

22.10.2015

Для общедоступной части скрипты контроллера расположены в директории /controller. Имя контроллера для какого-либо HTTP-запроса определяется первой частью ЧПУ-ссылки. Например, если запрошена страница «exmaple.com/article/blog/news/131229», то контроллер — это «article», его реализация должна находится в файле /controller/article.php. Если такого файла нет, то движок сгенерирует ошибку 404.

Типичный вид контроллера:

<?php class sController extends controller {
	function __construct() {
		parent::__construct();
	}

	public function actionBlog() {
		...
		$this->pageTitle=$this->metaTitle='some text';
		$this->metaKeyword=$this->metaDescription='some text';
		$this->script('some_script');
		$this->style('some_css');
		return 'Blog';
	}

	public function actionBlogSubmit($data) { ... }

	protected function breadcrumbBlog() {
		return array( ... );
	}

	protected function adminBlogLink() {
		return array( ... );
	}

	protected function adminBlogLink2($data) {
		return array( ... );
	}
} ?>

Контроллер должен иметь имя sController и быть унаследован от controller.

Каждый HTTP-запрос в рамках контроллера проходит через четыре этапа, каждый этап — это отдельная процедура:
- обработка запроса в конструкторе контроллера;
- обработка данных POST в submit-действии (если есть данные в $_POST);
- подготовка в процедуре дейстия данных для отображения;
- генерация хлебных крошек (если требуется);

После создания экземпляра класса контроллера движок вызовет действие — процедуру, осуществляющую обработку запроса. Имя действия берётся из второй части ЧПУ-ссылки (для приведённой выше ссылки — это «blog») с добавлением слова «action»: actionBlog. Если второй части ЧПУ-ссылки нет (например для такого URL: http://example.com/my_controller), то вместо неё будет подставлено действие «Index». Если процедуры с таким именем нет, то генерируется ошибка 404.

В конструкторе контроллера удобно проводить манипуляции с ЧПУ. Внутри конструктора необходимо первым делом вызвать parent::__construct(), который инициализирует переменную controller::$url, записав в неё массив, состоящий из частей запрошенной ЧПУ-ссылки (это копия $_GET['corePath'] — это переменную не рекомендуется изменять, т. к. её содержимое могут анализировать виджеты). Для ссылки «example.com/article/blog/news/131229» controller::$url будет содержать массив:

array('article','blog','news','131229')

После создания экземпляра класса контроллера движок вызовет действие, указанное в переменной $this->url[1]. Очевидно, что страница «example.com/article/blog/news» - это новостная лента, а «example.com/article/blog/news/131229» - это одна из новостей этой новостной ленты. Ленту новостей можно реализовать в процедуре actionBlog(), а одну новость в процедуре actionView(). Для такой реализации в конструкторе контроллера нужно посчитать количество элементов $this->url и, если их четыре, то выполнить «$this->url[1]='View';».

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

controller::$pageTitle — отображаемый на сайте заголовок, если не задан, то заголовок не выводится.

controller::$metaTitle — содержимое тега <title>.

controller::$metaKeyword и controller::$metaDescription — соответствующие метатеги страницы.

controller::js($name) — подключает указанный JavaScript или регистрирует указанную языковую константу (для последующего использования на стороне клиента). Имя файла js-скрипта указывается без директория и без расширения, например так:

$this->script('jquery.min');

(соответствует файлу /public/js/jquery.min.js). Эта функция также защищает от повторного подключения одного скрипта. Скрипт подключается в секции <head>...</head>. Этот метод, в свою очередь, вызывает core::js().

controller::style($name) — подключает файл стилей, указывается без директория и без расширения, например так: «blog» (соответствует файлу /public/css/blog.css). CSS подключается в секции <head>...</head>.

В конце работы действие должно вернуть строку, содержащую имя действия, например «Blog» (обязательно соблюдать регистр!). Реализация этого представления находится в файле /view/articleBlog.php. Как уже было сказано, действие контроллера может вернуть объект, который будет расценен как представление и движок вызовет процедуру render() этого объекта для генерации HTML-кода страницы. Особый случай - если действие вернёт строку "_empty": в этом случае в роли представления выступит универсальный файл /view/_empty.php (в нём будет выведено содержимое атрибута sController::$content, если такой задан).

Для генерации хлебных крошек необходимо использовать процедуру с именем breadcrumbИмяДействия. Если имя действия — это «blog», то хлебные крошки для этой страницы будут генерироваться в процедуре «breadcrumbBlog». Когда именно будет вызвана эта процедура зависит от того, в каком месте шаблона должны быть выведены хлебные крошки, однако можно с уверенностью сказать, что действие всегда выполняется раньше. Это позволяет в этой процедуре использовать данные, которые были подготовлены в действии.

Процедура, генерирующая хлебные крошки, должна возвратить массив, содержащий элементы «пути» к странице — это могут быть либо ссылки либо просто текст. В этот массив не должна входить главная страница и последняя (т. е. сама просматриваемая страница). Вот пример:

protected function breadcrumbBlog() {
	return array('<a href="'.core::link('article/blog').'">Статьи</a>');
}

Данный код сформирует примерно такую строку:
Главная » Статьи » Новости

Тут «новости» — это название страницы (controller::$pageTitle) и «главная» добавляются автоматически. Таким образом в самой процедуре нужно добавить только недостающие промежуточные элементы. Разумеется, процедуры, генерирующей хлебные крошки, может и не быть, тогда движок создаст их самостоятельно и они будут содержать только два элемента: «главная» и название раздела.

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

Разумеется, страницы сайта могут содержать HTML-формы и для обработки POST-запросов движок имеет внутренний простой, но достаточно эффективный механизм. Кроме действия контроллера есть ещё submit-действие — это процедура контроллера, которая вызывается в том случае, если в POST есть соответствующие данные. Имя процедуры submit-действия такое же как имя действия, но с добавлением слова «Submit», например:
public function actionBlogSubmit($data);

Для того, чтобы было вызвано submit-действие, данные в POST должны быть «обёрнуты» в массив, ключ которого совпадает с именем контроллера. То есть чтобы была вызвана процедура actionBlogSubmit() контроллера article, нужно чтобы данные в POST имели вид:

array('article'=>array(...));

Поле HTML-формы должно иметь вид:

<input name="article[someName]" type="text" />

Это нужно для того, чтобы контроллер обрабатывал только те данные, которые действительно к нему относятся и игнорировал какие-либо другие данные (например, если данные отправляет и обрабатывает какой-либо виджет, хотя это неправильно: данные должен получать контроллер).

В большинстве случаев удобно пользоваться конструктором HTML-форм, который берёт на себя заботу о правильности именования полей.

Submit-действие получает один параметр — это блок данных ($_POST['controllerName']). В этом блоке данных также присутствуют все загруженные файлы (информация из $_FILES).

Предполагается, что после обработки данных и в случае успешно выполненной операции, submit-действие в конце работы должно вызвать core::redirect() для редиректа на какую-либо страницу (выполнение редиректа после обработки формы полезно выполнять всегда). Если же операция успешно не выполнена, то нужно установить сообщение об ошибке в controller::$error, затем завершить процедуру выполнив «return» (возвращаемое значение игнорируется).

Если после submit-действия не был выполнен редирект, то движок запустит обычное действие, что приведёт к отображению соответствующей страницы (как правило она содержит HTML-форму, заполнение которой и привело к выполнению submit-действия). При этом, если ранее было установлено сообщение об ошибке в переменной controller::$error, то на экран будет выведено это сообщение.