Контроллер используется для управления кодом определенной части вашего приложения. Чаще всего, контроллеры используются для управления кодом отдельной модели. Например, если вы создаете сайт, который управляет видео коллекцией, у вас есть Video Controller и Rental Controller для управления видео и прокатом соответственно. В Cake имена контроллеров всегда во множественном числе.
Контроллеры вашего приложения это классы которые расширяют класс App Controller, который в свою очередь расширяет класс центрального контроллера. Контроллеры могут включать любое количество действий: функции используемые в вашем веб-приложении для отображения.
Класс App Controller может быть объявлен в /app/app_controller.php и должен включать в себя методы, которые делятся между двумя или больше контроллерами. Сам по себе он расширяет класс контроллера, который находится в стандартной библиотеке Cake.
Действие это единица функциональности контроллера. Она автоматически запускается диспетчером (Dispatcher) если его запрашивают на странице. Возвращаясь к нашему примеру о видео-коллекции, наш Video Controller может включать в себя действия view(), rent() и search(). Контроллер будет находиться в /app/controllers/videos_controller.php и будет содержать в себе:
<? class VideosController extends AppController { function view($id) { //код действия здесь.. }
function rent($customer_id, $video_id) { //код действия здесь.. }
function search($query) { //код действия здесь.. } } ?>
Вы сможете получить доступ к этим действиям, переходя по ссылкам:
Как будут выглядить эти страницы? Вам понадобится создать отображение для каждого их этих действий – об этом в следующей главе, а пока оставайтесь с нами: следующие разделы покажут как управляться с мощью контроллеров Cake и использовать их для своей выгоды. Конкретнее, вы узнаете как отправить данные вашего контроллера в отображение, перенаправлять пользователей и многое другое.
Функции контроллера
В этой главе речь пойдет о наиболее часто используемых функция контроллера Cake. Для полной справки пройдите по ссылке http://api.cakephp.org.
Взаимодейсвие с вашими Отображениями
set
string $var
mixed $value
Это основной способ передать данные из контроллера в отображение. Вы можете использовать функцию для передачи всего: отдельных значений, целых масивов и т.п. Пример использования: set('color', 'blue') – создаст переменную $color, доступную в вашем отображении со значением 'blue'.
validateErrors
Возвращает количество ошибок сгенерированных неуспешным сохранением.
validate
Проверяет данные модели согласно правилам проверки данных модели. Больше о проверке (верификации) смотрите главу «Верификация данных»
render
string $action
string $layout
string $file
Быть может не часто вам будет нужна эта функция, поскольку рендер автоматически вызывается в конце каждого действия контроллера, но вы можете вызывать эту функцию для рендеринга отображения в любом месте кода вашего контроллера.
Перенаправление пользователей
redirect
string $url
Используя эту функцию вы сообщаете пользователю куда перенаправляться. Ссылка может быть как внутренней ссылкой Cake, так полной ссылкой (http://...).
flash
string $message
string $url
int $pause
Эта функция показывает $message на $pause внутри вашего флеш-слоя (можно найти в app/views/layouts/flash.thtml) потом перенаправляет пользователя по указанной $url.
Функции Cake redirect() и flash() не включают в себя запрос exit(). Если вы хотите, чтобы ваше приложение остановилось после redirect() или flash(), вам понадобится включить самостоятельно запрос exit(). В зависимости от ситуации вы можете использовать запрос return вместо exit() (например, если вам нужно выполнить какие-нибудь функции обратного вызова (callbacks)).
Функции обратного вызова контроллера (Callbacks)
Контроллеры Cake дают возможность использовать множество функций обратного вызова, которые можно вставлять в код до или после важной функции. Чтобы использовать эту функциональность, объявите эти функции в вашем контроллере, используя параметры и возвращенные значения, описанные здесь.
beforeFilter
Вызывается перед каждым действием контроллера. Полезно использовать для проверки активных сессий и ролей.
afterFilter
Вызывается после каждого действия контроллера.
beforeRender
Вызывается как после кода контроллера, так и перед рендерингом отображения.
Другие полезные функции
Пока эти функции являются частью класса Объект Cake, они также доступны и внутри контроллера:
requestAction
string $url
array $extra
Эта функция вызывает действие контроллера из любого места и возвращает отрендеренное отображение. $url это ссылка Cake (/controllername/actionname/params). Если масив $extra включает в себя ключ 'return', Auto Render автоматически устанавливается на значение true для действия контроллера.
Вы можете использовать requestAction, чтобы получить данные из другого действия контроллера, или получить полностью отрендеренное отображение из контроллера.
Первое, получение данных из контроллера – это просто, Вы просто используете requestAction в отображении где вам нужны данные.
<? // Здесь наш простой контроллер:
class UsersController extends AppController { function getUserList() { return $this->User->findAll(); } } ?>
Представьте, что нам нужно создать простую таблицу, показывающую пользователей в системе. Вместо копирования кода в другой контроллер, мы можем получить данные из Users Controller::getUserList() используя requestAction().
<? class ProductsController extends AppController { function showUserProducts() { $this->set('users', $this->requestAction('/users/getUserList'));
// Теперь переменная $users в отображении будет иметь данные из // UsersController::getUserList(). } } ?>
Если у вас есть нечасто-используемый элемент в вашем приложении, можете вы захотите воспользоваться requestAction(), чтобы внедрить его в ваши отображения. Скажем это лучше чем просто вставлять данные из Users Controller::getUserList, мы также хотим отрендерить отображение этого действия (которое может состоять из таблицы), в другой контроллер. Это спасет нас от копирование кода отображения.
<? class ProgramsController extends AppController { function viewAll() { $this->set('userTable', $this->requestAction('/users/getUserList', array('return')));
// Теперь мы можем отобразить $userTable в отображении действия // чтобы увидить отрендереное отображение, которое также доступно в /users/getUserList. } } ?>
Пожалуйста отметьте, что действие вызванное использованием requestAction() рендерится, используя пустое размещение – поэтому не стоит волноваться про размещение получая рендер в самом размещении.
Функция requestAction() также полезна в ситуации AJAX, где маленькие элементы отображения нужно заполнять до или во время обновления AJAX.
log
string $message
int $type = LOG_ERROR
Вы можете использовать эту функцию, чтобы записывать в лог разные события, которые произошли во время работы вашего веб-приложения. Логи можно найти в директории Cake /tmp.
Если $type равна PHP константе LOG_DEBUG, сообщение будет записано в лог как отладочное сообщение. Если не равна – как ошибка.
// В контроллере, можно использовать log():
<? $this->log('Mayday! Mayday!'); ?>
//Запись в лог:
06-03-28 08:06:22 Error: Mayday! Mayday!
<? $this->log("Look like {$_SESSION['user']} just logged in.", LOG_DEBUG); ?>
//Запись в лог:
06-03-28 08:06:22 Debug: Looks like Bobby just logged in.
postConditions
array $data
Метод в который вы можете вписать $this->data, и он будет возвращен в форматированном масиве условий модели.
Например, если у меня есть форма поиска человека:
// app/views/people/search.thtml:
<?php echo $html->input('Person/last_name'); ?>
Подтверждая форму с этим элементом, в результати будет $this->data масив:
На этом этапе мы можем использовать postConditions(), чтобы отформатировать эти данные и использовать в модели:
<? // app/controllers/people_controller.php:
$conditions = $this->postConditions($this->data);
// Выходной масив будет выглядить как:
Array ( [Person.last_name] => Anderson )
// Который может использоваться операцией поиска в модели:
$this->Person->findAll($conditions);
Переменные контроллера
Манипулирование несколькими специальными переменными в вашем контроллере позволит вам получить пользу от некоторой дополнительной функциональности Cake:
$name
PHP 4 не любит давать нам имя данного класса в Camel Class (ВерблюжийКласс – то есть слова без пробелов, каждое слово с большой буквы). Используйте эту переменную для установки коректного имени Camel Class вашего класса если у вас возникли проблемы.
$uses
Использует ли ваш контроллер больше одной модели? Ваш Fraggles Controller автоматически загрузит $this->Fraggle, но если вы также хотите получить доступ к $this->Smurf, попробуйте добавить что-то вроде следующего в ваш контроллер:
var $uses = array('Fraggle','Smurf');
Пожалуйста, отметьте что вам следует включить модель Fraggle в масив $uses, даже если она была автоматически доступна ранее.
$helpers
Используйте эту переменную, чтобы контроллер загрузил хелперы в свое отображение. HTML хелпер автоматически загружается, но вы можете использовать эту переменную, чтобы определить несколько других:
var $helpers = array('Html','Ajax','Javascript');
Помните, что вам будет нужно включить HTML Хелпер в масиве $helpers если вы собираетесь использовать его. Он обычно доступен по умолчанию, но если вы объявите $helpers без него, вы получите сообщение об ошибке в вашем отображении.
$layout
Установите этой переменной значение имени размещения, которое вы хотите использовать для контроллера.
$autoRender
Устанавливая false вы остановите автоматический рендеринг для ваших действий.
$beforeFilter
Если вам нужно чтобы кусок кода запускался каждый раз, когда вызвано действие (и перед тем, как запускается код этого действия), используйте $beforeFilter. Эта функциональность довольно полезна для контроля доступа – вы можете проверять привилегии пользователя до того как производить действие. Просто установите эту переменную используя масив состоящий из действий контроллера, которые вы хотите запускать:
<? class ProductsController extends AppController { var $beforeFilter = array('checkAccess');
function checkAccess() { //Код для проверки подлиности пользователя и доступа здесь.... }
function index() { //Когда вызывается это действие перед ним будет вызываться checkAccess(). } } ?>
$components
Также как $helpers и $uses, эта переменная используется для загрузки компонентов, которые вам понадобятся:
var $components = array('acl');
Параметры контроллера
Параметры контроллера доступны в $this->params в вашем контроллере Cake. Эта переменная используется для отправки данных в контроллер и предоставления доступа к информации о текущем запросе. Чаще всего $this->params используется для получание доступа к информации, которая была передана контроллеру через POST или GET операции.
$this->data
Используется для управления POST данными, передаными формой HTML Хелпера в контроллер.
$this->params['form']
Любые POST данные из формы, хранятся здесь, включая информацию из $_FILES.
$this->params['bare']
Хранит '1' если текущее размещение это bare, '0' если нет.
$this->params['ajax']
Хранит '1' если текущее размещение это ajax, '0' если нет.
$this->params['controller']
Хранит имя текущего контроллера управляющего запросом. Например, если была запрошена ссылка /posts/view/1, $this->params['controller'] будет равен posts.
$this->params['action']
Хранит имя текущего действия управляющего запросом. Например, если была запрошена ссылка /posts/view/1, $this->params['action'] будет равен view.
$this->params['pass']
Хранит строку запроса GET работающего с текущим запросом. Например, если была запрошена ссылка /posts/view/?var1=3&var2=4, $this->params['pass'] будет равен "?var1=3&var2=4".
$this->params['url']
Хранит текущую ссылку, которая была запрошена, вместе с парами значений ключей переменных get. Например, если была запрошена ссылка /posts/view/?var1=3&var2=4, $this->params['url'] будет выглядить так: