Написание CMS на Kohana 3.2 — 3 статья

Здравствуйте ,сегодня очередная статья из цикла — «Написание CMS на Kohana 3.2».

У проекта появился официальный адрес — http://cmspegas.ru
Перейдя по этому адресу можно будет ознакомиться с внешним видом ,функционалом ,а также помочь в разработке выявляя ошибки или баги ,кроме того скоро исходники можно будет скачивать оттуда.

Сегодня у нас в статье
1) Настройка и начало работы с базой
2) Подключение и использование модуля «auth» — Авторизация и написание регистрации

1. Настройка и начало работы с базой
Для работы с базой нужно подключить модуль «database» — в файле application/bootstrap.php. Модуль ORM мы будем использовать при работе ,там где нет «узких мест» в плане нагрузки скрипта. Еще так как мы сегодня займемся авторизацией то и освободим строку «auth» от комментариев.

/**
 * Enable modules. Modules are referenced by a relative or absolute path.
 */
Kohana::modules(array(
	'auth'       => MODPATH.'auth',       // Basic authentication
	// 'cache'      => MODPATH.'cache',      // Caching with multiple backends
	// 'codebench'  => MODPATH.'codebench',  // Benchmarking tool
	'database'   => MODPATH.'database',   // Database access
	// 'image'      => MODPATH.'image',      // Image manipulation
	'orm'        => MODPATH.'orm',        // Object Relationship Mapping
	// 'unittest'   => MODPATH.'unittest',   // Unit testing
	// 'userguide'  => MODPATH.'userguide',  // User guide and API documentation
	));

Далее необходимо прописать настройки для базы данных.
Настройки по умолчанию хранятся в папке с модулем «database» — modules/database/config/database.php. Править настройки там же это не очень удачное решение ,вообще лучше всегда выносить конфиги в папку вашего приложения —application/config.
Так мы и поступим скопируем файл modules/database/config/database.php в папку application/config/.
Дальше остается правильно его настроить.

<?php defined('SYSPATH') or die('No direct access allowed.');
return array
(
	'default' => array
	(
		'type'       => 'mysql',
		'connection' => array(
			/**
			 * The following options are available for MySQL:
			 *
			 * string   hostname     server hostname, or socket
			 * string   database     database name
			 * string   username     database username
			 * string   password     database password
			 * boolean  persistent   use persistent connections?
			 * array    variables    system variables as "key => value" pairs
			 *
			 * Ports and sockets may be appended to the hostname.
			 */
			'hostname'   => 'localhost',
			'database'   => 'kohanaf',
			'username'   => 'kohanaf',
			'password'   => 'kohanaf',
			'persistent' => 'kohanaf',
		),
		'table_prefix' => '',
		'charset'      => 'utf8',
		'caching'      => FALSE,
		'profiling'    => TRUE,
	),
	'alternate' => array(
		'type'       => 'pdo',
		'connection' => array(
			/**
			 * The following options are available for PDO:
			 *
			 * string   dsn         Data Source Name
			 * string   username    database username
			 * string   password    database password
			 * boolean  persistent  use persistent connections?
			 */
			'dsn'        => 'mysql:host=localhost;dbname=kohana',
			'username'   => 'root',
			'password'   => 'r00tdb',
			'persistent' => FALSE,
		),
		/**
		 * The following extra options are available for PDO:
		 *
		 * string   identifier  set the escaping identifier
		 */
		'table_prefix' => '',
		'charset'      => 'utf8',
		'caching'      => FALSE,
		'profiling'    => TRUE,
	),
);

2. Подключение и использование модуля «auth» — Авторизации
Необходимо в начале его настроить. Проведем аналогичные действия с настройками как в случае с базой данных. В поле «hash_key» — нужно вписать секретную фразу ,по сути это так называемая «соль» — используется для более лучшей устойчивости паролей к подбору.
Также лучше всего сразу прописать в bootstrap.php после подключения модулей следующий код

/**
 * Create cookie salt
 */
Cookie::$salt = 'secret_code';

Данные о пользователях хранятся в базе ,поэтому для работы модуля необходимо создать таблицы.
В Kohana 3.2 есть уже готовый файл с sql запросом ,найди его можно в папке modules/orm/
Выполните SQL запросы

Теперь настало время написать пару контроллеров — auth,и «registration» (файлы вида ,формы — в исходниках)
Контроллер — «auth». Отвечает за авторизацию пользователя

<?php defined('SYSPATH') or die('No direct script access.');
class Controller_Auth extends Page {
	public function action_index()
	{
	$this->title = 'Авторизация';
		if($this->auth->logged_in()) {
			Request::initial()->redirect('');
		} else {
			if ($_REQUEST) {
			$data = Arr::extract($_REQUEST, array('username', 'password', 'save'));
				if($this->auth->login($data['username'], $data['password'], $data['save'])) {
					Request::initial()->redirect('');
				} else {
					page::error('Ошибка авторизации');
				}
			}
		}
		$this->template->content =  View::factory('auth/main');
	}
	public function action_logout()
	{
	$this->auth->logout();
	$this->title = 'Завершение сессии';
    $this->template->content = View::factory('auth/logout');
	}
} // End Auth

Контроллер — «Registration». Регистрация пользователя

<?php defined('SYSPATH') or die('No direct script access.');
class Controller_Registration extends Page {
	public function action_index()
	{
	$this->title = 'Регистрация';
	$data = array();
	     if ($_POST) {
		 $user = ORM::factory('user');
		 $data = Arr::extract($_POST, array('username', 'email', 'password', 'confirm_password'));
         $user->values($data,  array('username', 'email', 'password'));
		 $extra_validation = Validation::factory(
         array('password' => $data['password'],
               'password_confirm' => $data['confirm_password']));
         $extra_validation->rule('password' , 'not_empty')
                          ->rule('password' , 'min_length', array(':value', 4))
                          ->rule('password' , 'max_length', array(':value', 32))
                          ->rule('password_confirm', 'matches', array(':validation', 'password_confirm', 'password'));
         try {
         $user->save($extra_validation);
         $user->add('roles', ORM::factory('role')->where('name', '=', 'login')->find());
		 $this->auth->login($data['username'], $data['password'], 1);
         $this->template->content =  View::factory('registration/ok',$data);
		 return TRUE;
         } catch (ORM_Validation_Exception $e) {
           //page::error($e->errors('validation'));
          print_r($e->errors('validation'));
         }
		}
    $this->template->content =  View::factory('registration/main');
	}
} // End Registration

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

Основные наши сценарии готовы ,нужно подправить наш базовый контроллер добавив в него новые переменные auth ,user. Это переменные хранящие информацию о авторизованных пользователях и их состояний

<?php defined('SYSPATH') or die('No direct script access.');
abstract class Page extends Controller_Template {
    public $template = 'default';
    public $main_config;
	public $title;
	public $keywords;
	public $description;
	protected $auth,$user;
    public function before()
    {
	/**
	* Идентификация пользователя
	*/
	$this->auth = Auth::instance();
	$this->user = $this->auth->get_user();
	/**
	* Получение основных настроек
	**/
	$this->main_config = Kohana::$config->load('main');
    Kohana::add_path('themes/'.$this->main_config->get('web_theme').'/');
    parent::before();
	$this->template->styles = array('main');
	//$this->template->scripts = '';
    }
	public function error($error)
	{
	}
	public function after()
	{
	View::set_global(array(
    'title' => !isset($this->title)?$this->main_config->get('title'):$this->title,
	'keywords' => !isset($this->keywords)?$this->main_config->get('keywords'):$this->keywords,
    'description' => !isset($this->description)?$this->main_config->get('description'):$this->description,
	'user' => $this->user
    ));
	parent::after();
	}
}

Функция error мы пока не написали ,это в следующем уроке.
Другие используемые функции в сценариях это функции встроенных модулей.

Регистрация и авторизация готова ). Не забудьте из исходников скопировать файлы видов с папки /themes/
Пока это черновый вариант ,нужно еще много чего доделать.

Пару скринов:

Исходники: Скачать исходники pegas_3

P.S Если есть вопросы и предложения задаем в комментариях.
Результат работы можно посмотреть на сайте проекта http://cmspegas.ru

Гиламов Данис

Приветствую вас уважаемый посетитель! Меня зовут Данис, на страницах дневника я пишу о том что мне интересно: программирование, саморазвитие, спорт, мои размышления, творчество. Надеюсь вы сможете найди для себя полезную информацию, если вы что-то заметили, захотели обсудить, прошу оставлять комментарии в статьях, в Журнале или Написать мне Для меня - это лучшая награда. Спасибо за внимание :)

Вам также может понравиться ...

  • Использовать отдельные контроллеры для авторизации и регистрации — это жесть…

  • Danis92

    Здравствуйте ,а чем плох подобный вариант? По идеи более четкое разделение двух различных операций.

  • Vetal

    Это же ООП. Нужен самодостаточный класс который выполняет функции авторизации. Зачем разделять то? )))

  • Потому что автор видать не умеет пользоваться bootstrap`ом, а ссылки типа /controller/login и /controller/register его не устраивает, поэтому он создает для каждой короткой ссылки свой контроллер /login, /register и т.п.

    • Danis92

      На тот момент имел смутное представление =)
      Со временем переделаю. Скоро будет гостевая там как раз работа с роутингом немного есть

  • > abstract class Page extends Controller_Template

    Почему просто Page? Это же контроллер.

    > $this->template->styles = array(‘main’);

    Очень неплохой способ затереть все добавленные ранее стили.

    Ну и мешанина кода в экшене регистрации — просто «отличное» пособие для начинащих. Во-первых, в модели User уже есть метод create_user(), в котором внешняя валидация имеется. Во-вторых, имеет смысл эту модель расширить, и вынести добавление роли Login во все тот же метод create_user(). В-третьих, даже если Вы решили после регистриции автоматически залогинить пользователя, зачем ему насильно кидать куку-запоминалку?

  • Danis92

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

  • Спасибо. Единственное место в рунете, где процесс регистрации пользователя расписан. 🙄

  • надо бы файлик auth.php из modules перетащить в application
    и в нем объявить hash_key иначе при валидации ошибки будут сыпаться..