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

Здравствуйте дорогие читатели сегодня после довольно продолжительного периода простоя мы продолжаем работу над нашей cms =)

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

Первым делом начнем с регистрации ,в предыдущем уроке я допустил XSS — уязвимость ,логин нужно было очищать от html тегов. Каюсь ,пропустил =)
Также мы добавим новое правило валидации для логина. Согласно этому правилу логин не должен в себе содержать смешивание латиницы и кириллицы ,не допускается использование пробелов в начале и конце.

Для этого откроем нашу модель — /application/classes/model/user.php и добавим правило.

<br />
&lt;?php defined('SYSPATH') or die('No direct access allowed.');</p>
<p>class Model_User extends Model_Auth_User {</p>
<p>	public function labels()<br />
	{<br />
		return array(<br />
			'username'         =&gt; 'username',<br />
			'email'            =&gt; 'email',<br />
			'password'         =&gt; 'password',<br />
			'password_confirm'         =&gt; 'password_confirm',<br />
			'captcha'          =&gt; 'captcha',<br />
		);<br />
	}</p>
<p>	public static function captcha_valid($captcha)<br />
	{<br />
	  return (bool)Captcha::valid($captcha);<br />
	}</p>
<p>	public static function login_valid($login)<br />
	{<br />
		 // проверка на длину логина и возможные символы<br />
		 if (!preg_match(&quot;#^[a-zа-яё][a-zа-яё0-9\-\_\ ]{2,32}$#ui&quot;, $login))return false;<br />
		 // запрещаем одновременное использование русского и английского алфавилов<br />
		 if (preg_match(&quot;#[a-z]+#ui&quot;, $login) &amp;&amp; preg_match(&quot;#[а-яё]+#ui&quot;, $login))return false;<br />
		 // пробелы вначале или конце ника недопустимы<br />
		 if (preg_match(&quot;#(^\ )|(\ $)#ui&quot;, $login))return false;<br />
		return true;<br />
	}<br />
} // End User Model<br />

Теперь нужно это правило указать в нашем контроллере регистрации пользователей. +Исправить нашу маленькую уязвимость связанную с логином )
<br />
&lt;?php defined('SYSPATH') or die('No direct script access.');</p>
<p>class Controller_Registration extends Page {</p>
<p>	public function action_index()<br />
	{<br />
	$this-&gt;title = 'Регистрация';<br />
	$data = array();</p>
<p>	     if ($_POST) {<br />
		 $user = ORM::factory('user');</p>
<p>		 $data = Arr::extract($_POST, array('username', 'email', 'password', 'confirm_password', 'captcha'));</p>
<p>		 $data['username']=HTML::chars($data['username']);<br />
         $user-&gt;values($data,  array('username', 'email', 'password'));</p>
<p>		 $extra_validation = Validation::factory(<br />
         array('password' =&gt; $data['password'],<br />
               'password_confirm' =&gt; $data['confirm_password'],<br />
			   'captcha' =&gt; $data['captcha'],<br />
			   'username' =&gt; $data['username']));</p>
<p>         $extra_validation-&gt;rule('password' , 'not_empty')<br />
                          -&gt;rule('password' , 'min_length', array(':value', 4))<br />
                          -&gt;rule('password' , 'max_length', array(':value', 32))<br />
                          -&gt;rule('password_confirm', 'matches', array(':validation', 'password_confirm', 'password'))<br />
						  -&gt;rule('captcha' , 'not_empty')<br />
						  -&gt;rule('captcha' , 'Model_User::captcha_valid')<br />
						  -&gt;rule('username' , 'Model_User::login_valid');<br />
         try {<br />
         $user-&gt;save($extra_validation);<br />
         $user-&gt;add('roles', ORM::factory('role')-&gt;where('name', '=', 'login')-&gt;find());</p>
<p>		 $this-&gt;auth-&gt;login($data['username'], $data['password'], TRUE);</p>
<p>         $this-&gt;template-&gt;content =  View::factory('registration/ok',$data);</p>
<p>		 return TRUE;<br />
         } catch (ORM_Validation_Exception $e) {<br />
           page::error($e-&gt;errors('validation'));<br />
         }<br />
		}</p>
<p>    $this-&gt;template-&gt;content =  View::factory('registration/main');<br />
	}</p>
<p>} // End Registration<br />

Наши ошибки валидации выходят на английском языке ,а для некоторых правил выводится вообще только название функции. Нужно это немедленно исправить, негоже нам лицезреть буржуйские названия =)
Для этого скопируем файл с сообщениями — /system/messages/validation.php в аналогичную папку нашего приложения.
Теперь многие могут ринуться и переименовывать сообщения валидации ,предупрежу моих суровых товарищей это не совсем по феншую.
По феншую нужно создать файл перевода и уже в нем все переводить.
Создадим папку ru в — /application/i18n/ и файл с переводами ru.php
<br />
&lt;?php defined('SYSPATH') or die('No direct script access.');</p>
<p>return array(<br />
 ':field must contain only letters'                     =&gt; ':field должно содержать только буквы',<br />
 ':field must contain only numbers, letters and dashes' =&gt; ':field должно содержать только буквы, цифры и подчеркивания',<br />
 ':field must contain only letters and numbers'         =&gt; ':field должно содержать только буквы и цифры',<br />
 ':field must be a color'                               =&gt; ':field должно быть кодом цвета',<br />
 ':field must be a credit card number'                  =&gt; ':field должно быть номером кредитной карты',<br />
 ':field must be a date'                                =&gt; ':field должно быть датой',<br />
 ':field must be a decimal with :param2 places'  =&gt; ':field должно быть десятичным числом с :param2 количеством цифр',<br />
 ':field must be a digit'                               =&gt; ':field должно быть целым числом',<br />
 ':field must be a email address'                       =&gt; ':field должно быть адресом электронной почты',<br />
 ':field must contain a valid email domain'        =&gt; ':field должно быть существующим адресом электронной почты',<br />
 ':field must equal :param2'                            =&gt; ':field должно быть идентичным :param2',<br />
 ':field must be exactly :param2 characters long'       =&gt; ':field должно быть длиной :param2 символов',<br />
 ':field must be one of the available options'          =&gt; ':field должно быть одним из параметров',<br />
 ':field must be an ip address'                         =&gt; ':field должно быть ip-адресом',<br />
 ':field must be the same as :param2'                   =&gt; ':field должно равняться :param2',<br />
 ':field must be at least :param2 characters long'      =&gt; ':field не должно быть короче :param2 символов',<br />
 ':field must not exceed :param2 characters long'       =&gt; ':field не должно быть длиннее :param2 символов',<br />
 ':field must not be empty'                             =&gt; ':field не должно быть пустым',<br />
 ':field must be numeric'                               =&gt; ':field должно быть числом',<br />
 ':field must be a phone number'                        =&gt; ':field должно быть номером телефона',<br />
 ':field must be within the range of :param2 to :param3'=&gt; ':field должно находиться между :param2 и :param3',<br />
 ':field does not match the required format'            =&gt; ':field не соответствует требуемому формату',<br />
 ':field must be a url'                                 =&gt; ':field должно быть URL-адресом',<br />
 ':field incorrect login' 								=&gt; ':field неккоректен',<br />
 ':field incorrect captcha' 							=&gt; ':field неправильно введен код',<br />
 ':filed repeat'										=&gt; ':field уже есть в базе',</p>
<p> 'username'                                             =&gt; 'Поле Юзер',<br />
 'email'                                             	=&gt; 'Поле E-mail',<br />
 'password'                                             =&gt; 'Поле Пароль',<br />
 'password_confirm'                                     =&gt; 'Поле Повторение пароля',<br />
 'captcha'                                              =&gt; 'Поле Captcha',<br />
);<br />

Еще необходимо установить наш язык ,делается это в файл — application/bootstrap.php
Нужно изменить строчку
<br />
I18n::lang('en-en');<br />

на
<br />
I18n::lang('ru-ru');<br />

Теперь мы будем лицезреть

Приятно =)

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

Создадим новый роут ,для этого в файле — /application/bootstrap.php пропишем правила роутинга. Новые роуты нужно прописывать до роута default. Вот так =>

<br />
Route::set('apanel', 'apanel(/&lt;controller&gt;(/&lt;action&gt;(/&lt;id&gt;)))')<br />
            -&gt;defaults(array(<br />
            'directory'  =&gt; 'apanel',<br />
            'controller' =&gt; 'main',<br />
            'action'     =&gt; 'index',<br />
            ));</p>
<p>Route::set('default', '(&lt;controller&gt;(/&lt;action&gt;(/&lt;id&gt;)))')<br />
	-&gt;defaults(array(<br />
		'controller' =&gt; 'main',<br />
		'action'     =&gt; 'index',<br />
	));<br />

Перейдем к контроллерам ,создадим директорию — /apanel/ в папке контроллеров — /application/classes/controller/. В директории наш контроллер по умолчанию — main
<br />
&lt;?php defined('SYSPATH') or die('No direct script access.');</p>
<p>class Controller_Apanel_Main extends AdminPage {</p>
<p>	public function action_index()<br />
	{<br />
        $this-&gt;template-&gt;content = View::factory('/apanel/main');<br />
	}</p>
<p>} // End Main<br />

Заметим что мы наследуем наш контроллер уже не от Page ,а от нового базового контроллера AdminPage. О нем чуть попозже. Сейчас же, добавим файлы вида в нем напишем что-нить для примера )
<br />
&lt;h3&gt;Админ-панель&lt;/h3&gt;<br />
Директория  - &lt;?php echo Request::current()-&gt;directory(); ?&gt;&lt;br /&gt;<br />
Контроллер - &lt;?php echo Request::current()-&gt;controller(); ?&gt;&lt;br /&gt;<br />
Метод - &lt;?php echo Request::current()-&gt;action(); ?&gt;<br />

Теперь в папке — /application/classes/ напишем новые базовые контроллеры — GuestPage ,AdminPage,LoginPage.

GuestPage

<br />
&lt;?php defined('SYSPATH') or die('No direct script access.'); </p>
<p>abstract class GuestPage extends Page {  </p>
<p>    public function before()<br />
    {<br />
	if(Auth::instance()-&gt;logged_in())  Request::initial()-&gt;redirect(URL::site());</p>
<p>    return parent::before();<br />
    }<br />
}<br />

LoginPage
<br />
&lt;?php defined('SYSPATH') or die('No direct script access.'); </p>
<p>abstract class LoginPage extends Page {  </p>
<p>    public function before()<br />
    {<br />
	if(!Auth::instance()-&gt;logged_in())  Request::initial()-&gt;redirect(URL::site());</p>
<p>    return parent::before();<br />
    }<br />
}<br />

AdminPage
<br />
&lt;?php defined('SYSPATH') or die('No direct script access.'); </p>
<p>abstract class AdminPage extends Page {  </p>
<p>    public function before()<br />
    {<br />
	if(!Auth::instance()-&gt;logged_in('admin'))  Request::initial()-&gt;redirect(URL::site());</p>
<p>    return parent::before();<br />
    }<br />
}<br />

Теперь почти все готово директория — apanel открыта только для пользователей имеющих роль admin.
Для того чтобы стать админом нужно в базе данных в таблице roles_users добавить новую строку
<br />
INSERT INTO `kohanaf2`.`roles_users` (`user_id` ,<br />
`role_id`<br />
)<br />
VALUES ('1', '2'<br />
);<br />

Осталось для необходимых страниц изменить наследование базового контроллера. К примеру для страницы регистрации можно изменить с Page на GuestPage таким образом доступ к ней будут иметь только незарегистрированные пользователи. Для файлов же админки все файлы будем наследовать от AdminPage.

Все на сегодня =).
Сайт проекта http://cmspegas.ru

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

P.S Есть вопросы => пишем комментарии

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