Русскоязычный форум, посвященный фреймворку Kohana

Все о фреймворке Kohana. Обсуждение уроков, документации.
Текущее время: 28 апр 2024, 15:06

Часовой пояс: UTC + 4 часа [ Летнее время ]




Начать новую тему Ответить на тему  [ Сообщений: 11 ]  На страницу 1, 2  След.
Автор Сообщение
СообщениеДобавлено: 15 май 2013, 05:16 
Не в сети
Бывалый
Аватара пользователя

Зарегистрирован: 11 апр 2013, 14:09
Сообщения: 162
Наконец-то, благодаря урокам Морковина я таки разобрался с тем, как сделать авторизацию на кохане. Но теперь возникает другая проблема...
У меня есть контроллер Basic, который проверяет, авторизован пользователь или нет, он расширяет Controller_Template, вот его код:
Код:
<?php defined('SYSPATH') or die('No direct script access.');

abstract class Basic extends Controller_Template {

   public function before()
   {
      $session = Session::instance();
      $session->set('auth_redirect', $_SERVER['REQUEST_URI']);
      
      $auth = Auth::instance();
      if($auth->logged_in() == 0) HTTP::redirect(URL::base().'/auth');
      return parent::before();
   }
   
} // End Basic

По логике, этот контроллер наследуют все остальные контроллеры. Кроме того, у меня есть 2 части приложения: административная и пользовательская. Я делаю базовый контроллер для админки, вот его код:
Код:
<?php defined('SYSPATH') or die('No direct script access.');

abstract class Controller_Admin_Basic extends Basic {
   
   public $template = 'admin/basicview';
   
   public function before()
   {   
      $this->template->title = '1';
      $this->template->header = '1';
      $this->template->content = '1';
      $this->template->footer = '1';
      $this->template->styles = array('reset','style','admin_menu');
      $this->template->scripts = array('admin_menu');
      return parent::before();
   }
} // End Basic

Как вы видите, строка public $template = 'admin/basicview'; определяет базовый вид админки. Потому как базовые ВИДы админки и пользовательской части разные. По аналогии, делается и базовый контроллер пользовательской части:
Код:
<?php defined('SYSPATH') or die('No direct script access.');

abstract class Controller_Arm_Basic extends Basic {
   
   public $template = 'arm/basicview';
   
   public function before()
   {   
      $this->template->title = '1';
      $this->template->header = '1';
      $this->template->content = '1';
      $this->template->footer = '1';
      $this->template->styles = array('reset','style','admin_menu');
      $this->template->scripts = array('admin_menu');
      return parent::before();
   }
} // End Basic

Но почему-то возникает ошибка
Цитата:
ErrorException [ Warning ]: Attempt to assign property of non-object
APPPATH/classes/Controller/Admin/Basic.php [ 9 ]
4
5 public $template = 'admin/basicview';
6
7 public function before()
8 {
9 $this->template->title = '1';
10 $this->template->header = '1';
11 $this->template->content = '1';
12 $this->template->footer = '1';
13 $this->template->styles = array('reset','style','admin_menu');
14 $this->template->scripts = array('admin_menu');
APPPATH/classes/Controller/Admin/Basic.php [ 9 ] » Kohana_Core::error_handler(arguments)
SYSPATH/classes/Kohana/Controller.php [ 69 ] » Controller_Admin_Basic->before()
{PHP internal call} » Kohana_Controller->execute()
SYSPATH/classes/Kohana/Request/Client/Internal.php [ 97 ] » ReflectionMethod->invoke(arguments)
SYSPATH/classes/Kohana/Request/Client.php [ 114 ] » Kohana_Request_Client_Internal->execute_request(arguments)
SYSPATH/classes/Kohana/Request.php [ 990 ] » Kohana_Request_Client->execute(arguments)
DOCROOT/index.php [ 118 ] » Kohana_Request->execute()

Как буд-то объекта $this->template не существует вовсе. Что я делаю не так?

_________________
Они плакали и кололись, но продолжали есть кактус!


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: 15 май 2013, 05:42 
Не в сети
Бывалый
Аватара пользователя

Зарегистрирован: 11 апр 2013, 14:09
Сообщения: 162
Таки разобрался. Походу в самом начале нужно было ввести parent::before(); а не как у меня. Теперь код выглядит так:
Базовый контроллер Basic.php:
Код:
<?php defined('SYSPATH') or die('No direct script access.');

abstract class Basic extends Controller_Template {

   public function before()
   {
      parent::before();
      $session = Session::instance();
      $session->set('auth_redirect', $_SERVER['REQUEST_URI']);
      
      $auth = Auth::instance();
      if($auth->logged_in() == 0) HTTP::redirect(URL::base().'/auth');
   }
   
} // End Basic

Базовый контроллер админки Controller_Admin_Basic:
Код:
<?php defined('SYSPATH') or die('No direct script access.');

abstract class Controller_Admin_Basic extends Basic {
   
   public $template = 'admin/basicview';
   
   public function before()
   {   
      parent::before();
      $this->template->title = '1';
      $this->template->header = '1';
      $this->template->content = '1';
      $this->template->footer = '1';
      $this->template->styles = array('reset','style','admin_menu');
      $this->template->scripts = array('admin_menu');
   }
} // End Basic

Видите что теперь написано parent::before(); и все работает! Ведать у Морковина старая версия KO разжевывается. А в этом уроке черным по белому написано:
Цитата:
Теперь самое интересное — специальный метод before(). Этот метод не нужно вызывать. Он запускается автоматически самым первым при обращении к классу, в котором он прописан или к классам, которые наследуют этот класс. Следующая строка parent::before(); необходима, чтобы метод before() класса-родителя Controller_Template не перетирался (а он там есть, будьте уверены, как есть он и в классе Controller).

_________________
Они плакали и кололись, но продолжали есть кактус!


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: 15 май 2013, 11:44 
Не в сети
Бывалый
Аватара пользователя

Зарегистрирован: 02 апр 2013, 16:26
Сообщения: 474
Откуда: Сергиев Посад
сам то ты хоть понял почему нужно в данном случае parent::before(); в начале писать или опять методом тыка? В данном описании от твоего Морковина никаких ошибок нет, типичный пример полиформизма. кстати зачем тебе $session->set('auth_redirect', $_SERVER['REQUEST_URI']); ?

_________________
Майкл Джордан играет в баскетбол. Чарльз Мэнсон убивает людей. Я пишу код. У каждого свой талант.


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: 16 май 2013, 08:47 
Не в сети
Бывалый
Аватара пользователя

Зарегистрирован: 11 апр 2013, 14:09
Сообщения: 162
Вай молодец! Хороший вопрос задал. Заставляет мозгами пораскинуть. И честно говоря я это методом тыка допер, просто посмотрел как этот before() на нашем сайте делается. Может подскажешь, почему так работает, а как в первом случае (return parent::before(); в конце метода) нет? Позвольте предположить: метод before() как конструктор, вызывается автоматически, а следовательно, он выполняется "перетерев" before() из контроллера Basic и Template соответственно. Следовательно, before() от других классов не унаследован, а значит переменная $template в этом контексте ничего не значит. А если сказать БЕФОРУ, что перед тем как выполниться, нужно унаследовать родительские БЕФОРЫ, то переменной $template как раз и становиться объектом, через который можно обращаться к ВИДу. Так?
Код:
$session->set('auth_redirect', $_SERVER['REQUEST_URI']);

А это устанавливает в переменную сессии auth_redirect, куда обращался юзверь, что бы потом, после авторизации его на это же место и вернуть.

_________________
Они плакали и кололись, но продолжали есть кактус!


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: 16 май 2013, 16:30 
Не в сети
Бывалый
Аватара пользователя

Зарегистрирован: 02 апр 2013, 16:26
Сообщения: 474
Откуда: Сергиев Посад
nkl> так, но гадать и тыкаться можно долго, быстрее посмотреть всю цепочку кода от родительского класса controller до твоего класса, чтобы понимать цепочку действий.

пересмотри логику auth_redirect мне кажется ты не понимаешь, что делаешь. что произойдет если твой auth_redirect ведет на auth или на вызываемую страницу?

_________________
Майкл Джордан играет в баскетбол. Чарльз Мэнсон убивает людей. Я пишу код. У каждого свой талант.


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: 16 май 2013, 16:35 
Не в сети
Бывалый
Аватара пользователя

Зарегистрирован: 11 апр 2013, 14:09
Сообщения: 162
auth не от кого не наследуется, он сам по себе, поэтому в нем никаким образом значение переменной сессии auth_redirect не присваивается, а сразу же после того как отработал контроллер авторизации, auth_redirect удаляется.

_________________
Они плакали и кололись, но продолжали есть кактус!


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: 16 май 2013, 16:59 
Не в сети
Бывалый
Аватара пользователя

Зарегистрирован: 02 апр 2013, 16:26
Сообщения: 474
Откуда: Сергиев Посад
nkl> тогда ты еще пока не перестал быть, как ты выразился, быдлокодером т.к. данный код должен вызываться 1 раз в конкретном контроллере аутентификации, а не тащится по во всем контроллерам системы

_________________
Майкл Джордан играет в баскетбол. Чарльз Мэнсон убивает людей. Я пишу код. У каждого свой талант.


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: 17 май 2013, 00:22 
Не в сети
Бывалый
Аватара пользователя

Зарегистрирован: 11 апр 2013, 14:09
Сообщения: 162
А если так?
Код:
<?php defined('SYSPATH') or die('No direct script access.');

abstract class Basic extends Controller_Template {

   public function before()
   {
      parent::before();
      
      $auth = Auth::instance();
      if($auth->logged_in() == 0)
      {
         $session = Session::instance();
         $session->set('auth_redirect', $_SERVER['REQUEST_URI']);
         HTTP::redirect(URL::base().'/auth');
      }
   }
   
} // End Basic

_________________
Они плакали и кололись, но продолжали есть кактус!


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: 17 май 2013, 01:25 
Не в сети
Бывалый
Аватара пользователя

Зарегистрирован: 02 апр 2013, 16:26
Сообщения: 474
Откуда: Сергиев Посад
nkl> ой болбес.. если продолжишь гадать и не думать головой, то я прекращу тебе подсказывать
прекрати гадать постоянно, старайся всегда понять что ты пишешь и к каким результатам оно приводит.
ладно практика контрольных вопросов с тобой работает, продолжим её)
как сделать чтобы данный код выполнялся всего 1 раз на 1 странице сайта?

_________________
Майкл Джордан играет в баскетбол. Чарльз Мэнсон убивает людей. Я пишу код. У каждого свой талант.


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: 17 май 2013, 08:04 
Не в сети
Бывалый
Аватара пользователя

Зарегистрирован: 11 апр 2013, 14:09
Сообщения: 162
Что то я не совсем понял. Мне нужно унаследовать этот класс Basic, всеми контроллерами, в которых мне нужно проверить, авторизован ли пользователь. Что тут не правильно? Алгоритм простейший. Авторизовался? -> Да -> ОК. Нет ->Тогда авторизуйся. А права доступа уже на уровне наследников проверять. Я тут на форуме фразу одну не понял, которую Вы высказали. Что значит инкапсулировать действие?

_________________
Они плакали и кололись, но продолжали есть кактус!


Вернуться к началу
 Профиль  
 
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 11 ]  На страницу 1, 2  След.

Часовой пояс: UTC + 4 часа [ Летнее время ]


Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 51


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Перейти:  
cron
Все о фреймворке Kohana  | 
Powered by phpBB® Forum Software © phpBB Group