Kohana 3.2 – Собственный блог шаг за шагом — Часть 3

users

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

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

Модифицирование видов

Вынос меню

Первое, что нам потребуется это вынести наше меню, которое располагается в файле application/views/admin/dashboard.php в отдельный вид для повторного использования, я перенес меню в файл application/views/admin/block/menu.php и немного модифицировал его, листинг файла представлен ниже:

<?php defined('SYSPATH') or die('No direct script access.');

/**
 * @var array      $config       Global blog configuration
 * @var Model_User $user         Global Kohana user object
 * @var string     $message      Global message
 * @var string     $message_type Global message type string
 *
 * @author     Novichkov Sergey(Radik) <novichkovsergey@yandex.ru>
 * @copyright  Copyrights (c) 2012 Novichkov Sergey
 */
?>
<div>
    <div>
        <div>
            <div>
                <div>
                    <a href="<?php echo URL::site('/admin') ?>"><?php echo __('Kohana 3.2 Blog') ?></a>

                    <ul>
                        <li>
                            <a href="#"  data-toggle="dropdown">
                                Security <i></i>
                            </a>
                            <ul>
                                <li><a href="<?php echo URL::site('/admin/users') ?>"><i></i> <?php echo __('Users List') ?></a></li>
                                <li><a href="<?php echo URL::site('/admin/users/new') ?>"><i></i> <?php echo __('New User') ?></a></li>
                                <li><a href="<?php echo URL::site('/admin/roles') ?>"><i></i> <?php echo __('Roles List') ?></a></li>
                                <li><a href="<?php echo URL::site('/admin/roles/new') ?>"><i></i> <?php echo __('New Role') ?></a></li>
                            </ul>
                        </li>
                    </ul>

                    <div>
                        <a href="<?php echo URL::site('/admin/users/edit/' . $user->id) ?>">
                            <?php echo __('Authorized as: :user', array(':user' => $user->username)) ?>
                        </a>
                        <a href="#" data-toggle="dropdown">
                            <i></i>
                        </a>
                        <ul>
                            <li><a href="<?php echo URL::site('/admin/auth/logout') ?>"><i></i> <?php echo __('Logout') ?></a></li>
                        </ul>
                    </div>
                </div>
            </div>
        </div>
    </div>
</div>

Как вы можете видеть я изменил внешнее оформление меню, а так же добавил в него несколько новых пунктов: Users List, New user, Roles List, New role, так же я создал ссылки на страницы которые мы будем реализовывать в этом уроке.

Создание вида подвала страницы

Для выполнения этого пункта я создал файл /application/views/admin/block/footer.php, листинг которого представлен ниже:

<?php defined('SYSPATH') or die('No direct script access.');

/**
 * @var array      $config       Global blog configuration
 * @var Model_User $user         Global Kohana user object
 * @var string     $message      Global message
 * @var string     $message_type Global message type string
 *
 *
 * @author     Novichkov Sergey(Radik) <novichkovsergey@yandex.ru>
 * @copyright  Copyrights (c) 2012 Novichkov Sergey
 */
?>
<div id="footer">
    <div>
        <div>
            <div>
                <?php echo __('&copy; :date Cyber Applications. Developer: Novichkov Sergey.', array(':date' => Date::formatted_time('now', 'Y'))) ?>
            </div>
        </div>
    </div>
</div>

Изменение стартовой страницы панели администратора

Первым делом я вынес стили из вида /application/views/admin/dashboard.php в внешний файл public/css/styles.css, а так же подключил внешний файл стилей в виде разметки /application/views/layout.php. Все это я сделал для нашего с вами удобства, а так же, что бы в дальнейшем мы могли изменять дизайн административной части системы с помощью изменения файла стилей страницы.

Следующим шагом я изменил верстку и содержание стартовой страницы, листинг файла /application/views/admin/dashboard.php представлен ниже:

<?php defined('SYSPATH') or die('No direct script access.');

/**
 * @var array      $config       Global blog configuration
 * @var Model_User $user         Global Kohana user object
 * @var string     $message      Global message
 * @var string     $message_type Global message type string
 *
 * @author     Novichkov Sergey(Radik) <novichkovsergey@yandex.ru>
 * @copyright  Copyrights (c) 2012 Novichkov Sergey
 */
?>
<?php echo View::factory('admin/block/menu') ?>

<div id="container">
    <div id="content">
        <div>
            <div>
                <h1><?php echo __('Dashboard') ?></h1>
                <div>
                    <div>
                        <h3><?php echo __('Security') ?></h3>
                        <table>
                            <tr>
                                <td><img src="<?php echo URL::site('/public/images/security.png') ?>" alt=""></td>
                                <td><i></i> <a href="<?php echo URL::site('/admin/users') ?>"><?php echo __('Users List') ?></a><br/>
                                    <i></i> <a href="<?php echo URL::site('/admin/users/new') ?>"><?php echo __('New User') ?></a><br/>
                                    <i></i> <a href="<?php echo URL::site('/admin/roles') ?>"><?php echo __('Roles List') ?></a><br/>
                                    <i></i> <a href="<?php echo URL::site('/admin/roles/new') ?>"><?php echo __('New Role') ?></a></td>
                            </tr>
                        </table>
                    </div>
                </div>
            </div>
        </div>

    </div>
</div>

<?php echo View::factory('admin/block/footer') ?>

Установка модуля Pagination

Установить модуль Pagionation можно несколькими способами

Установка с помощью git

Для этого в каталоге /modules выполните команду

git clone -b 3.2/develop https://github.com/shadowhand/pagination.git

Ручная установка

Скачайте архив тут и распакуйте содержимое архива в каталог /modules/pagination

Подключение модуля в проект

Для этого нужно чуть-чуть изменить файл /application/bootstrap.php, то что у меня получилось представлено ниже:

...

/**
 * 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
        'pagination' => MODPATH.'pagination', // Pagination module
));

...

Создание вида пагинации

Некоторые более опытные из вас которые работали до этого с модулем пагинации могут спросить: Зачем нам это нужно?! Ведь модуль пагинации уже имеет базовые шаблоны для отображения пагинации! … И я вам отвечу! Да это так! Но!:

  1. Мне не нравится принцип работы базовых шаблонов постраничной навигации
  2. Так же нам нужно изменить разметку для того, что бы наша пагинация гармонично считалась с Twitter Bootstrap

Для удовлетворения моей прихоти я создал шаблон /application/views/admin/block/pagination.php с следующим содержанием:

<?php defined('SYSPATH') or die('No direct script access.');

/**
 * @var array      $config             Global blog configuration
 * @var Model_User $user               Global Kohana user object
 * @var string     $message            Global message
 * @var string     $message_type       Global message type string
 * @var Pagination $page               Pagination object
 * @var int        $current_page       Pagiantion current page number
 * @var int        $total_items        Pagination items total count
 * @var int        $items_per_page     Pagiantion items per page count
 * @var int        $total_pages        Pagiantion pages totoal count
 * @var int        $current_first_item Pagination current first item
 * @var int        $current_last_item  Pagiantion current last item
 * @var int        $previous_page      Pagiantion previous page number
 * @var int        $next_page          Pagiantion next page number
 * @var int        $first_page         Pagiantion first page number
 * @var int        $last_page          Pagination last page number
 * @var int        $offset             Pagination offset number
 *
 * @author     Novichkov Sergey(Radik) <novichkovsergey@yandex.ru>
 * @copyright  Copyrights (c) 2012 Novichkov Sergey
 */

// Calculate variables
$pages_range = 10;
$pages_range_half = floor(10 / 2);
$page_start = ($current_page > $pages_range_half) ? $current_page - $pages_range_half : 1;
$page_start = ($current_page > $total_pages - $pages_range) ? $total_pages - $pages_range + 1 : $page_start;
$page_start = max(1, $page_start);
?>

<div>
    <ul>
        <?php if ($first_page !== FALSE): ?>
            <li><a href="<?php echo HTML::chars($page->url($first_page)) ?>"><?php echo __('First') ?></a></li>
        <?php endif ?>

        <?php if ($previous_page !== FALSE): ?>
            <li><a href="<?php echo HTML::chars($page->url($previous_page)) ?>"><?php echo __('Previous') ?></a></li>
        <?php endif ?>

        <?php for ($i = $page_start; $i < $total_pages + 1 && $i < $page_start + $pages_range; $i++) : ?>
            <li<?php if ($i == $current_page) : ?><?php endif; ?>>
                <a href="<?php echo HTML::chars($page->url($i)) ?>"><?php echo $i ?></a>
            </li>
        <?php endfor; ?>

        <?php if ($next_page !== FALSE): ?>
            <li><a href="<?php echo HTML::chars($page->url($next_page)) ?>"><?php echo __('Next') ?></a></li>
        <?php endif ?>

        <?php if ($last_page !== FALSE): ?>
            <li><a href="<?php echo HTML::chars($page->url($last_page)) ?>"><?php echo __('Last') ?></a></li>
        <?php endif ?>
    </ul>
</div>

Настройка модуля

Для этого скопируем файл /modules/pagination/config/pagination.php в каталог /application/config и отредактируем его примерно следующим образом:

<?php defined('SYSPATH') or die('No direct script access.');

return array(

    // Application defaults
    'default' => array(
        'current_page'      => array('source' => 'query_string', 'key' => 'page'), // source: "query_string" or "route"
        'total_items'       => 0,
        'items_per_page'    => 10,
        'view'              => 'pagination/basic',
        'auto_hide'         => TRUE,
        'first_page_in_url' => FALSE,
    ),

    // Administrator panel options
    'admin' => array(
        'current_page'      => array('source' => 'route', 'key' => 'id'), // source: "query_string" or "route"
        'total_items'       => 0,
        'items_per_page'    => 10,
        'view'              => 'admin/block/pagination',
        'auto_hide'         => TRUE,
        'first_page_in_url' => FALSE,
    ),

);

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

Страница списка пользователей (User List)

Создание контроллера

Для начала нам понадобится создать контроллер, класс которого будет располагаться в файле /application/classes/controller/admin/users.php. Код класса у меня выглядит примерно так:

<?php defined('SYSPATH') or die('No direct script access.');

class Controller_Admin_Users extends Controller_Admin_Layout_Secure {

    /**
     * Users List Action
     */
    public function action_index()
    {
        // Load users list query
        $users = ORM::factory('user')
            ->reset(FALSE);

        // Create pagination object
        $pagination = Pagination::factory(array(
            'group' => 'admin',
            'total_items' => $users->count_all(),
        ));

        // Modify users list query
        $users = $users
            ->order_by('username', 'ASC')
            ->order_by('email', 'ASC')
            ->offset($pagination->offset)
            ->limit($pagination->items_per_page)
            ->find_all();

        // Set content template
        $this->template->set('content', View::factory('admin/users/list', array(
            'items' => $users,
            'pagination' => $pagination,
        )));
    }

    /**
     * Delete user action
     */
    public function action_delete()
    {
        // Get user id
        $user_id = $this->request->param('id');
        if (!$user_id)
        {
            throw new HTTP_Exception_404('User not found.');
        }

        // Get user
        $user = ORM::factory('user', $user_id);
        if (!$user->loaded())
        {
            throw new HTTP_Exception_404('User not found.');
        }

        // Set message
        Session::instance()
            ->set('message', __('User :user deleted successfully.', array(':user' => $user->username)))
            ->set('message_type', 'success');

        // Delete user
        $user->delete();

        // Redirect to base page
        $this->request->redirect($this->request->referrer());
    }

    /**
     * Create user action
     */
    public function action_new()
    {
        // New user
        $user = ORM::factory('user');

        // Roles list
        $roles = ORM::factory('role')->order_by('name', 'ASC')->find_all();

        // Set content template
        $this->template->set('content', View::factory('admin/users/new', array(
            'item' => array_merge($user->as_array(), array('roles' => array())),
            'roles' => $roles,
        )));
    }

    /**
     * Edit user action
     *
     * @throws HTTP_Exception_404
     */
    public function action_edit()
    {
        // Get user id
        $user_id = $this->request->param('id');
        if (!$user_id)
        {
            throw new HTTP_Exception_404('User not found.');
        }

        // Get user
        $user = ORM::factory('user', $user_id);
        if (!$user->loaded())
        {
            throw new HTTP_Exception_404('User not found.');
        }

        // User roles
        $item['roles'] = array();
        foreach ($user->roles->find_all() as $role)
        {
            $item['roles'][] = $role->id;
        }

        // Roles list
        $roles = ORM::factory('role')->order_by('name', 'ASC')->find_all();

        // Set content template
        $this->template->set('content', View::factory('admin/users/edit', array(
            'item' => array_merge($user->as_array(), $item),
            'roles' => $roles,
        )));
    }

    /**
     * Save user action
     *
     * @throws HTTP_Exception_404
     */
    public function action_save()
    {
        // Protect page
        if ($this->request->method() !== Request::POST)
        {
            throw new HTTP_Exception_404('Page not found.');
        }

        // Back
        if ($this->request->post('back'))
        {
            $this->request->redirect('/admin/users');
        }

        // create and configure form validation
        $post = Validation::factory($this->request->post())
            ->labels(array(
                'username' => __('User name'),
                'email' => __('Email'),
            ))
            ->rule('username', 'not_empty')
            ->rule('email', 'not_empty')
            ->rule('email', 'email');

        if (!empty($post['password']))
        {
            $post
                ->labels(array(
                    'password' => __('Password'),
                    'password_confirm' => __('Password confirm'),
                ))
                ->rule('password', 'not_empty')
                ->rule('password_confirm', 'not_empty')
                ->rule('password_confirm', 'matches', array(':validation', 'password', 'password_confirm'));
        }

        // check validation
        if ($post->check())
        {
            // store
            $data = $post->data();

            /** @var Model_User $user **/
            $user = ORM::factory('user', Arr::get($data, 'id'));

            // remove password if empty
            if (empty($data['password']))
            {
                unset($data['password']);
            }

            // update user
            $user->values($data, array('username', 'email', 'password'))->save();

            // remove all roles
            $user->remove('roles');

            // add new roles
            foreach (Arr::get($post, 'roles', array()) as $role)
            {
                $user->add('roles', $role);
            }

            // message
            Session::instance()
                ->set('message', __(Arr::get($post->data(), 'id') ? 'User updated successfully.' : 'User created successfully.'))
                ->set('message_type', 'success');

            // redirect to list page
            $this->request->redirect(URL::site('/admin/users'));
        }

        // Roles list
        $roles = ORM::factory('role')->order_by('name', 'ASC')->find_all();

        // Errors list
        View::set_global('errors', $post->errors('validation'));

        // Set content template
        $this->template->set('content', View::factory('admin/users/' . (Arr::get($post->data(), 'id') ? 'edit' : 'new'),
            array(
                'item' => $post->data(),
                'roles' => $roles,
            )
        ));
    }
} // End Admin Users

Как вы ведите получившийся у меня контроллер имеет следующие действия:

  • index — Отображение списка пользователей
  • delete — Удаление конкретного пользователя из списка
  • new — Создание нового пользователя
  • edit — Изменение существующего пользователя
  • save — Сохранение пользователя

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

Создание видов

Следующим логичным шагом после создания контроллера и его действий будет создание видов для следующих действий index, new, edit.

Листинг вида index (application/views/admin/users/list.php):

<?php defined('SYSPATH') or die('No direct script access.');

/**
 * @var array           $config       Global blog configuration
 * @var Model_User      $user         Global Kohana user object
 * @var string          $message      Global message
 * @var string          $message_type Global message type string
 * @var Database_Result $items        Users list
 * @var Pagination      $pagination   Pagination object
 *
 * @author     Novichkov Sergey(Radik) <novichkovsergey@yandex.ru>
 * @copyright  Copyrights (c) 2012 Novichkov Sergey
 */
?>
<?php echo View::factory('admin/block/menu') ?>

<div id="container">
    <div id="content">
        <div>
            <div>
                <h1><?php echo __('Users list') ?></h1>
                <a
                   href="<?php echo URL::site('/admin/users/new') ?>"><i></i> <?php echo __('New') ?></a>
            </div>
        </div>

        <?php if ($message) : ?>
            <div>
                <div>
                    <div>
                        <a href="#" data-dismiss="alert">×</a>
                        <?php echo $message ?>
                    </div>
                </div>
            </div>
        <?php endif; ?>

        <div>
            <div>
                <table>
                    <thead>
                    <tr>
                        <th><?php echo __('ID') ?></th>
                        <th><?php echo __('User name') ?></th>
                        <th><?php echo __('Email') ?></th>
                        <th><?php echo __('Logins') ?></th>
                        <th><?php echo __('Last login') ?></th>
                        <th><?php echo __('Actions') ?></th>
                    </tr>
                    </thead>

                    <tbody>
                        <?php if ($items->count()) : ?>
                            <?php foreach ($items as $item) : ?>
                            <tr>
                                <td><?php echo $item->id ?></td>
                                <td><?php echo $item->username ?></td>
                                <td><?php echo $item->email ?></td>
                                <td><?php echo $item->logins ?></td>
                                <td><?php echo date('Y-m-d H:i:s', $item->last_login) ?></td>
                                <td>
                                    <div>
                                        <a href="<?php echo URL::site('admin/users/delete/' . $item->id) ?>"><i
                                               ></i> <?php echo __('Delete') ?></a>
                                        <a href="<?php echo URL::site('admin/users/edit/' . $item->id) ?>"><i
                                               ></i> <?php echo __('Edit') ?></a>
                                    </div>
                                </td>
                            </tr>
                            <?php endforeach; ?>
                        <?php else: ?>
                            <tr>
                                <td colspan="6"><?php echo __('No items') ?></td>
                            </tr>
                        <?php endif; ?>
                    </tbody>

                    <tfoot>
                        <tr>
                            <td colspan="5"><?php echo $pagination ?></td>
                            <td><?php echo __('Total: :count', array(':count' => $pagination->total_items)) ?></td>
                        </tr>
                    </tfoot>
                </table>
            </div>
        </div>
    </div>
</div>

<?php echo View::factory('admin/block/footer') ?>

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

Далее у нам нужно создать вид new и edit они можно сказать идентичны, поэтому я на них так же не буду заострять внимание:

Листинг вида new (application/views/admin/users/new.php):

<?php defined('SYSPATH') or die('No direct script access.');

/**
 * @var array           $config       Global blog configuration
 * @var Model_User      $user         Global Kohana user object
 * @var string          $message      Global message
 * @var string          $message_type Global message type string
 * @var array           $item         Current item data
 * @var Database_Result $roles        All roles list
 *
 * @author     Novichkov Sergey(Radik) <novichkovsergey@yandex.ru>
 * @copyright  Copyrights (c) 2012 Novichkov Sergey
 */
?>
<?php echo View::factory('admin/block/menu') ?>

<div id="container">
    <div id="content" class="container">
        <div class="row title">
            <div class="span12">
                <h1 class="pull-left"><?php echo __('New user') ?></h1>
            </div>
	</div>

         <?php echo View::factory('admin/users/form', array('item' => $item, 'roles' => $roles)) ?>
    </div>
</div>

<?php echo View::factory('admin/block/footer') ?>

Листинг вида edit (application/views/admin/users/edit.php):

<?php defined('SYSPATH') or die('No direct script access.');

/**
 * @var array           $config       Global blog configuration
 * @var Model_User      $user         Global Kohana user object
 * @var string          $message      Global message
 * @var string          $message_type Global message type string
 * @var array           $item         Current item data
 * @var Database_Result $roles        All roles list
 *
 * @author     Novichkov Sergey(Radik) <novichkovsergey@yandex.ru>
 * @copyright  Copyrights (c) 2012 Novichkov Sergey
 */
?>
<?php echo View::factory('admin/block/menu') ?>

<div id="container">
    <div id="content" class="container">
        <div class="row title">
	    <div class="span12">
                <h1 class="pull-left"><?php echo __('Edit user: :user', array(':user' => Arr::get($item, 'username'))) ?></h1>
	    </div>
        </div>

        <?php echo View::factory('admin/users/form', array('item' => $item, 'roles' => $roles)) ?>
    </div>
</div>

<?php echo View::factory('admin/block/footer') ?>

Ну и собственно листиг вида формы (application/views/admin/users/form.php):

<?php defined('SYSPATH') or die('No direct script access.');

/**
 * @var array           $config       Global blog configuration
 * @var Model_User      $user         Global Kohana user object
 * @var string          $message      Global message
 * @var string          $message_type Global message type string
 * @var array           $item         Current item data
 * @var array           $errors       Errors array
 * @var Database_Result $roles        All roles list
 *
 * @author     Novichkov Sergey(Radik) <novichkovsergey@yandex.ru>
 * @copyright  Copyrights (c) 2012 Novichkov Sergey
 */
?>
<form action="<?php echo URL::site('/admin/users/save') ?>" method="post" name="user-form">
    <div>
        <div>
            <fieldset>
                <legend><?php echo __('Common') ?></legend>

                <div>
                    <label for="username"><?php echo __('User name') ?>:</label>
                    <div>
                        <input type="text" name="username" id="username" value="<?php echo Arr::get($item, 'username') ?>"/>
                        <?php if (Arr::get($errors, 'username')) : ?>
                            <div><?php echo Arr::get($errors, 'username') ?></div>
                        <?php endif; ?>
                    </div>
                </div>

                <div>
                    <label for="email"><?php echo __('Email') ?>:</label>
                    <div>
                        <input type="text" name="email" id="email" value="<?php echo Arr::get($item, 'email') ?>"/>
                        <?php if (Arr::get($errors, 'email')) : ?>
                            <div><?php echo Arr::get($errors, 'email') ?></div>
                        <?php endif; ?>
                    </div>
                </div>

                <div>
                    <label for="password"><?php echo __('Password') ?>:</label>
                    <div>
                        <input type="password" name="password" id="password"/>
                        <?php if (Arr::get($errors, 'password')) : ?>
                            <div><?php echo Arr::get($errors, 'password') ?></div>
                        <?php endif; ?>
                    </div>
                </div>

                <div>
                    <label for="password_confirm"><?php echo __('Password confirm') ?>:</label>
                    <div>
                        <input type="password" name="password_confirm" id="password_confirm"/>
                        <?php if (Arr::get($errors, 'password_confirm')) : ?>
                            <div><?php echo Arr::get($errors, 'password_confirm') ?></div>
                        <?php endif; ?>
                    </div>
                </div>
            </fieldset>
        </div>
        <div>
            <fieldset>
                <legend><?php echo __('Access') ?></legend>
                <div>
                    <label><?php echo __('Roles') ?></label>
                    <?php foreach ($roles as $role) : ?>
                        <label>
                            <?php echo $role->name ?>
                            <input id="role<?php echo $role->id ?>" type="checkbox" name="roles[]" value="<?php echo $role->id ?>"
                                <?php if (in_array($role->id, Arr::get($item, 'roles',array()))) : ?> checked="checked" <?php endif ?>/>
                        </label>
                    <?php endforeach; ?>
                </div>
            </fieldset>
        </div>
    </div>
    <div>
        <div>
            <div>
                <input type="submit" name="back" value="<?php echo __('Back') ?>" />
                <input type="submit" name="save" value="<?php echo __('Save') ?>" />
            </div>
        </div>

        <input type="hidden" name="id" value="<?php echo Arr::get($item, 'id') ?>">
    </div>
</form>

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

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

Скачать исходные коды урока

Kohana 3.2 – Собственный блог шаг за шагом — Часть 3: 9 комментариев

  1. Из-за чего может ругаться Kohana 3.3.1?

    Ошибку на странице редактирования пользователя:
    ErrorException [ Notice ]: Undefined variable: errors

    Прописывал в контроллере array (пустой), не помогло, в чём может быть дело?

    1. И да, ругается именно на файл APPPATH/views/admin/users/form.php. Независимо от того, что редактируем — пользователя, роли и прочее.

  2. Мужииик!!! Ты лучший, 2 дня ломал мозг как прикрутить пагинатор, у других столько букаф что за ними теряется суть.

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

    1. Действительно… сразу сам не заметил. Судя по всему редактор сожерал атрибуты дивов. Исправлю чуточку по позже. Спасибо за замечание.

  3. Спасибо за интересные уроки. Только у меня не получается зайти в созданный блог под админом. Не могли бы вы выложить дамп базы данных в sql формате?

    1. По вашей просьбе в исходники добавлен дамп БД в SQL формате. Для входа в панель управления под администратором используйте следующие данные:
      — Имя пользователя admin
      — Пароль: admin

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *