← Назад к статьям

Каталог книг на основе сессий

M
miholeus
4 апреля 2010 г. · 4 мин чтения

В прошлый раз мы рассмотрели создание своих контроллеров и действий. Теперь настало время написать свое мини-приложение с CRUD (create-read-update-delete) функционалом. Так как вопросы работы с базой данных я оставлю на следующий раз, то работать мы будем с сессиями. Раз уж мы создали контроллер BookController, давайте продолжим и напишем мини-каталог книг. У каждой книги будет свое название, автор и краткое описание.

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

В папке application создадим каталог forms. Добавим класс Form_Book, экземпляры которого будут наследовать все свойства компонента Zend_Form, в файл Book.php:

class Form_Book extends Zend_Form
{
    public function init()
    {
        // name element
        $name = $this->createElement('text', 'name');
        $name->setLabel("Enter book's name:");
        $name->setRequired(true);
        $name->setAttrib('size', 40);
        $this->addElement($name);
        // author element
        $author = $this->createElement('text', 'author');
        $author->setLabel("Enter book's author:");
        $author->setRequired(true);
        $author->setAttrib('size', 40);
        $this->addElement($author);
        // description element
        $description = $this->createElement('textarea', 'description');
        $description->setLabel("Short description:");
        $description->setRequired(true);
        $description->setAttrib('cols', 50);
        $description->setAttrib('rows', 4);
        $this->addElement($description);
        // submit button
        $this->addElement('submit', 'submit', array('label' => 'Submit'));
    }
}

Мы добавили два текстовых поля, одну область и кнопку, также мы указали, что все поля являются обязательными для заполнения. В загрузчик Bootstrap.php добавим метод _initAutoload:

protected function _initAutoload()
    {
        $autoloader = Zend_Loader_Autoloader::getInstance();
        $resourceLoader = new Zend_Loader_Autoloader_Resource(array(
            'basePath' => APPLICATION_PATH,
            'namespace' => '',
            'resourceTypes' => array(
                'form' => array(
                    'path' => 'forms/',
                    'namespace' => 'Form_'
                )
            )
        ));
        return $autoloader;
    }

Теперь Zend_Framework знает, где искать наши формы. В файле BookController.php добавим действие createAction:

public function createAction()
    {
        $frmBook = new Form_Book();
        $frmBook->setMethod('post');

        $this->view->form = $frmBook;
    }

В папке views/scripts/book создадим представление для действия create. Добавим файл create.phtml:

<div id="_mcePaste"><h2>Create New Book</h2></div>
<div id="_mcePaste"><?php echo $this->form;?></div>

Как видите, чтобы отобразить форму надо всего лишь написать

$this->form

. Просто, не правда ли?

Перейдя по ссылке http://zf/book/create, вы увидите нашу форму. Теперь нам нужно инициализировать объект сессии, который будет выступать хранилищем книг, мы будем заносить очередную книгу в сессию после обработки пост запроса формы. Добавим метод preDispatch в BookController. Метод preDispatch() в контроллере выполняется до любого действия. В нашем случае очень удобно инициализировать сессию в этом методе, что мы и сделаем. Для работы с сессиями будем использовать компонент Zend_Framework, который называется Zend_Session. Нам понадобится класс Zend_Session_Namespace.

/**
     * session variable
     *
     * @var Zend_Session_Namespace
     */
    protected $session;

    public function preDispatch()
    {
	$this->session = new Zend_Session_Namespace('default');

	if(!$this->session->books) {

		$this->session->books = array();
                $this->session->currentItemId = 0;

	}
    }

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

public function createAction()
    {
        $frmBook = new Form_Book();
        $frmBook->setMethod('post');
	if($this->_request->isPost()) {
                if($frmBook->isValid($this->_request->getPost())) {
                        $this->session->currentItemId++;
                        $book = new stdClass();
                        $book->id = $this->session->currentItemId;
                        $book->name = $frmBook->getValue('name');
                        $book->author = $frmBook->getValue('author');
                        $book->description = $frmBook->getValue('description');
                        $this->session->books[$this->session->currentItemId] = $book;
                        $this->_redirect('/book');
                }
	}
        $this->view->form = $frmBook;
    }

А в indexAction добавим переменную, указывающую на список добавленных книг:

public function indexAction()
    {
        $this->view->books = $this->session->books;
    }

В файле views/scripts/book/index.phtml выведем список имеющихся книг:

<h2>List of all books</h2>
<?php
if(count($this->books)) {
    ?>
    <dl>
    <?php
    foreach($this->books as $book) {
        if(!$book instanceof stdClass) {
            continue;
        }
        ?>
        <dt>
            <?=$book->name?> | <small>author: <?=$book->author?></small> |
            <a href="/book/update/id/<?=$book->id?>">update</a>&nbsp;
            <a href="/book/delete/id/<?=$book->id?>">delete</a>
        </dt>
        <dd>
            <?=$book->description?>
        </dd>
        <?php
    }
    ?>
    </dl>
    <?php
}

Теперь у нас есть список книг! Можно создавать новые книги, и они будут добавляться в этот список. Осталось реализовать возможность редактирования и удаления книги из списка. Займемся сначала редактированием. В классе BookController добавим действие updateAction:

public function updateAction()
{
    if($this->getRequest()->getParam('id')) {
        $id = $this->getRequest()->getParam('id');
        $frmBook = new Form_Book();
        if(isset($this->session->books[$id])) {
            $book = $this->session->books[$id];
            $frmBook->populate(array(
                'name' => $book->name,
                'author' => $book->author,
                'description' => $book->description
            ));
        } else {
            throw new Zend_Exception('Update failed: book not found!');
        }
        $this->view->form = $frmBook;
    }
}

Добавим скрипт представления views/scripts/book/update.phtml:

<h2>Update Book</h2>
<?=$this->form?>

Перейдя по ссылке http://zf/book/update/id/1, можно увидеть содержимое выбранного элемента. Теперь напишем несколько строк для сохранения введенной информации.

public function updateAction() {
     if($this->getRequest()->getParam('id')) {
         $id = $this->getRequest()->getParam('id');
         $frmBook = new Form_Book();
         if(isset($this->session->books[$id])) {
             if($this->getRequest()->isPost()) {
                 if($frmBook->isValid($this->_request->getPost())) {
                         $book = new stdClass();
                         $book->id = $id;
                         $book->name = $frmBook->getValue('name');
                         $book->author = $frmBook->getValue('author');
                         $book->description = $frmBook->getValue('description');
                         $this->session->books[$id] = $book;
                         $this->_redirect('/book');
                 }
             } else {
                 $book = $this->session->books[$id];
                 $frmBook->populate(array(
                     'name' => $book->name,
                     'author' => $book->author,
                     'description' => $book->description
                 ));
              }
         } else {
                 throw new Zend_Exception('Update failed: book not found!');
         }
         $this->view->form = $frmBook;
     }
}

Мы снова проверяем, был ли выполнен пост запрос. Если это так, то получаем данные из формы, ищем книгу в массиве и сохраняем, используя уникальный номер книги. Осталось добавить лишь один метод для удаления книги из каталога. Это действие будет чрезвычайно простое. Добавляем deleteAction в контроллер BookController:

public function deleteAction() {
     if($this->getRequest()->getParam('id')) {
         if(isset($this->session->books[$this->getRequest()->getParam('id')])) {
             unset($this->session->books[$this->getRequest()->getParam('id')]);
             $this->_redirect('/book');
         } else {
             throw new Zend_Exception('Delete failed: book not found!');
         }
     }
}

Мы проверяем есть ли книга в каталоге, если есть - то удаляем элемент из нашего массива. Вот и все! Мы создали небольшое приложение, которое позволяет добавлять, редактировать и удалять элементы. Познакомились с сессиями. В следующий раз я покажу как на примере одной из библиотек строить ajax-приложения ^_^

P.S. Закончен перевод 4-й и 6-й глав документации Zend Framework. Zend Autoloading и Zend Layout теперь доступны на русском языке.

Комментарии 3

Комментарии проходят модерацию
Загрузка комментариев...