Контроллер новости

В этом уроке:

Мы разработаем контроллер новости
Добавим к нашей cms на CodeIgniter визуальный редактор FCKEditor
Встроим JQuery календарь Datepicker

В прошлых уроках я начал делать сайт в UTF-8 кодировке, но не везде придерживался этого. Поэтому получилось некоторое несоответствие. В конце урока будет ссылка на результат этого урока (там в архиве все в правильной кодировке). Для того чтобы сделать сайт в UTF-8 необходимо придерживаться трех правил:

кодировка в БД
кодировка всех страниц в UTF-8
Добавить AddDefaultCharset utf-8 в .htaccess
В разделе head указать
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
Начинаем с создания таблицы:

DROP TABLE IF EXISTS `cm_news`;
CREATE TABLE `cm_news` (
  `id` INT(10) NOT NULL AUTO_INCREMENT,
  `title` VARCHAR(255) DEFAULT NULL,
  `date` DATE DEFAULT NULL,
  `anons` text,
  `content` text,
  PRIMARY KEY  (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=10 DEFAULT CHARSET=utf8;

Создаем базовую модель CRUD.
В этой модели мы реализуем 4 основных функции:

Добавление в БД. (данные будут поступать из формы)
Редактирование записей в БД. (данные будут поступать из формы)
Удаление записей БД.
Вывод списка записей.
Вывод одной записи.
Плюс мне пришлось сделать 2 дополнительных функции. Т.к. я использовал календарь Datepicker, мне пришлось сделать преобразование (туда/обратно) даты из формата 01.10.2010 в формат MySQL 2010-10-01.
Листинг файла CRUD.php с комментариями.

<?php
 
/**
 * @author allexe
 * @copyright 2010
 * 26.8.2010
 * Описание файла: Общая модель для работы с БД
 */
 
if (!defined('BASEPATH'))  exit('No direct script access allowed');
 
class Crud extends Model
{
 
    var $table = ''; //Имя таблицы
    var $idkey = 'id'; //Ключ ID
    var $add_rules = array(); //Правила валидации для добавления
    var $edit_rules = array(); //Правила валидации для редактирования
 
    //Конструктор
    function Crud()
    {
        parent::Model();
    }
 
    /**
     * Функция для добавления 
     */
    function add()
    {
        //Проверяем прошли ли переданные формой данные правила валидации
        $this->form_validation->set_rules($this->add_rules);
        if ($this->form_validation->run()) {
            $data = array();
            foreach ($this->add_rules as $one) {
                //Для каждого поля описанного в правилах валидации получаем
                //значение. Имя поля в форме соответствует имю поля в БД.
                //Для даты выполняем преобразование.
                $f = $one['field'];
                if ($f == 'date') {
                    $date = $this->input->post($f);
                    $data[$f] = $this->date_to_mysql($date);
                } else {
                    $data[$f] = $this->input->post($f);
                }
            }
            //Вставляем массив с данными из формы в БД
            $this->db->insert($this->table, $data);
            return $this->db->insert_id(); //Возвращает номер
        } else {
            return false;
        }
    }
 
    /**
     * Функция для редактирования
     */
    function edit($id)
    {
        $this->form_validation->set_rules($this->edit_rules);
        if ($this->form_validation->run()) {
            $data = array();
            foreach ($this->edit_rules as $one) {
                $f = $one['field'];
                if ($f == 'date') {
                    $date = $this->input->post($f);
                    $data[$f] = $this->date_to_mysql($date);
                } else {
                    $data[$f] = $this->input->post($f);
                }
            }
            $this->db->where($this->idkey, $id);
            $this->db->update($this->table, $data);
            return $data; //Возвращает вставленные данные
        } else {
            return false;
        }
    }
 
    /**
     * Функция удаления
     */
    function del($id)
    {
        $this->db->where($this->idkey, $id);
        $this->db->delete($this->table);
    }
 
    /**
     * Получение данных
     */
    function get($id)
    {
        $this->db->where($this->idkey, $id);
        $query = $this->db->get($this->table);
        $rez = $query->row_array();
        foreach ($rez as $key => $value) {
            if ($key == 'date') {
                $rez['date'] = $this->mysql_to_date($value);
            }
        }
        return $rez;
    }
 
    /**
     * Получение списка
     * $start_from - выбирать с этой записи
     * $limit - количество выбираемых записей
     */
    function getlist($start_from = false, $limit = false)
    {
        if (($start_from) & ($limit)) {
            $this->db->limit($limit, $start_from);
        } elseif ($limit) {
            $this->db->limit($limit);
        }
        $query = $this->db->get($this->table);
        $rez = $query->result_array();
        for ($i = 0; $i < count($rez); $i++) {
            $one = $rez[$i];
            foreach ($one as $key => $value) {
                if ($key == 'date') {
                    $rez[$i]['date'] = $this->mysql_to_date($value);
                }
            }
        }
        return $rez;
    }
 
    /**
     * Преобразует дату в формат MySql
     */
    function date_to_mysql($str)
    {
        $day = substr($str, 0, strpos($str, '.'));
        $str = substr($str, strpos($str, '.') + 1);
        $month = substr($str, 0, strpos($str, '.'));
        $year = substr($str, strrpos($str, '.') + 1);
        $mysql_date = $year . '-' . $month . '-' . $day;
        return $mysql_date;
    }
 
    /**
     * Преобразует дату формате MySql в формат 01.10.2010
     */
    function mysql_to_date($str)
    {
        $year = substr($str, 0, strpos($str, '-'));
        $str = substr($str, strpos($str, '-') + 1);
        $month = substr($str, 0, strpos($str, '-'));
        $day = substr($str, strrpos($str, '-') + 1);
        $date = $day . '.' . $month . '.' . $year;
        return $date;
    }
}
 
?>

Основная работа с БД в CodeIgniter осуществляется через класс Database ($this->db->). Рекомендую прочитать более подробно про Класс Active Record.
Создаем модель mdl_news.
Эта модель будет включать всего несколько переменных для передачи их в родительскую модель CRUD. Это: название таблицы, название ключевого поля, массивы с правилами валидации при добавлении и редактировании.

<?php
 
/**
 * @author allexe
 * @copyright 2010
 * 26.8.2010
 * Описание файла: Модель для работы с таблицей новостей
 */
if (!defined('BASEPATH')) exit('No direct script access allowed');
 
class mdl_news extends CRUD
{
    var $table = 'news'; //Имя таблицы
    var $idkey = 'id';
 
    var $add_rules = array(array('field' => 'title', 'label' => 'Заголовок новости',
        'rules' => 'required|max_length[255]'), array('field' => 'date', 'label' =>
        'Дата новости', 'rules' => 'required'), array('field' => 'anons', 'label' =>
        'Анонс новости', 'rules' => 'required'), array('field' => 'content', 'label' =>
        'Текст новости', 'rules' => 'required'));
 
    var $edit_rules = array(array('field' => 'title', 'label' => 'Заголовок новости',
        'rules' => 'required|max_length[255]'), array('field' => 'date', 'label' =>
        'Дата новости', 'rules' => 'required'), array('field' => 'anons', 'label' =>
        'Анонс новости', 'rules' => 'required'), array('field' => 'content', 'label' =>
        'Текст новости', 'rules' => 'required'));  
}
?>

Про то, как работает валидации уже обсуждалось в Уроке 5.
Перейдем к созданию видов.
Вид admin/news (список новостей):
Просто выводим таблицу со списком заголовков новостей, датами и ссылкой на удаление новости. Каждый заголовок является ссылкой на редактирование новости.

<h2>Список новостей</h2>
<?=anchor(base_url().'admin/news/add','Добавить новость');?>
<table border="0" width="400" cellspacing="4">
<tr><td>Дата новости</td><td>Заголовок</td><td>Удалить</td></tr>
<?php foreach($list as $one):?>
<tr><td><?=$one['date'];?></td><td><?=anchor(base_url().'admin/news/edit/'.$one['id'],$one['title']);?></td><td><?=anchor(base_url().'admin/news/del/'.$one['id'],'X');?></td></tr>
<?endforeach;?>
</table>

base_url() и anchor() — это функции хелпера URL. Из формируемых ссылок видно, что добавление новостей будет происходить в функции add контроллера admin/news, редактирование edit, удаление del.
В файл вида передается массив с данными о новостях из контроллера news содержащийся в переменной list. Процесс обработки (когда пользователь заходит по адресу cms.ru/admin/news/ выглядит так:

Создание вида admin/one_news
Для редактирования и добавления новостей я использовал один вид. В файл вида передается переменная $type. В зависимости от ее значения несколько меняется отображение. Файл вида состоит из формы включающей 4 поля: 2 input (для даты и заголовка новости), 2 textarea для анонса и полного текста новости.
Содержание файла вида admin/one_news

<?=$validation_errors;?>
 
<?php if ($type=='add'): ?>
<?=form_open ('admin/news/add'); ?>
<?php elseif ($type=='edit'): ?>
<?=form_open ('admin/news/edit/'.$one['id']); ?>
<?php endif;?>
<table border="0" width="400" cellspacing="4">
<tr>
<td>Дата новости</td><td><input type="text" name="date" class="datepicker" value="<?=set_value ('date',($type == 'edit')? $one['date']: '')?>"></td>
</tr>
<tr>
<td>Заголовок</td><td><input type="text" name="title" value="<?=set_value ('title',($type == 'edit')? $one['title']: '')?>"></td>
</tr>
<tr>
<td colspan="2">Анонс</td>
</tr>
<tr>
<td colspan="2">
<?php if ($type=='add'): ?>
<textarea id="anons" name="anons" class="anons" cols="80" rows="5"><?=set_value ('anons')?></textarea>
<?php elseif ($type=='edit'): ?>
<textarea id="anons" name="anons" class="anons" cols="80" rows="5"><?=set_value ('anons',$one['anons'])?></textarea>
<?php endif;?>
</tr>
<tr>
<td colspan="2">Полный текст новости</td>
</tr>
<tr>
<td colspan="2">
<?php if ($type=='add'): ?>
<textarea id="content" name="content" class="content" cols="150" rows="50"><?=set_value ('content')?></textarea>
<?php elseif ($type=='edit'): ?>
<textarea id="content" name="content" class="content" cols="150" rows="50"><?=set_value ('content',$one['content'])?></textarea>
<?php endif;?>
</td>
</tr>
<tr>
<td align="left">
	<input type="submit" value="<?=($type == 'edit')? 'Изменить': 'Добавить';?>">
</td>
<td></td>
</tr>
</table>
</form>
<?=show_fckeditor ('anons')?>
<?=show_fckeditor ('content')?>

Конструкция вешает на textarea с id=»anons» визуальный редактор FCKEditor. class=»datepicker» — вешает на input календарь Datepicker.

Подробней прочитать про подключения календаря Datepicker иподключение FCKEditor к CodeIgniter.

Теперь перейдем к созданию контроллера admin/news. Ничего сложно в нем нет. Стандартно реализованы функции добавления, удаления, вывода списка новостей и одной новости.
Контроллер admin/news

<?php
 
/**
 * @author allexe
 * @copyright 2010
 * 26.8.2010
 * Описание файла: Контроллер Новости
 */
if (!defined('BASEPATH')) exit('No direct script access allowed');
 
class news extends Controller
{
 
    function news()
    {
        parent::Controller();
        if (!($this->userlib->logged_in())) {
            redirect(base_url() . 'users/login/');
        }
    }
 
    /**
     * Выводим список новостей для редактирования
     */
    function index()
    {
 
        $header_data['page_title'] = 'Раздел новости';
        $this->load->view('admin/header.php', $header_data);
        $CI = &get_instance(); //Доступ к CodeIgniter
        $CI->load->model('mdl_news');
        $data['list'] = $CI->mdl_news->getlist();
        $CI->load->view('admin/news.php', $data);
        $this->load->view('admin/footer.php');
    }
 
    /**
     * Добавление новости
     */
    function add()
    {
    	$this->load->helper('fckeditor');
        $CI = &get_instance();
        $CI->load->model('mdl_news'); //Загрузка модели
        if ($CI->mdl_news->add() !== false) {
            //Делаем редирект на список ссылок
            redirect('admin/news');
        } else {
            //Выводим форму добавления
            $header_data['page_title'] = 'Добавление новости';
            $this->load->view('admin/header.php', $header_data);
            //Теперь готовим вывод серединки
            $data = array();
            $data['validation_errors'] = validation_errors();
            $data['type'] = 'add';
            $this->load->view('admin/one_news', $data);
            //Здесь вывод футера
            $this->load->view('admin/footer.php');
        }
    }
 
    /**
     * Редактирование новости
     */
    function edit($id)
    {
    	$this->load->helper('fckeditor');
        $CI = &get_instance();
        $CI->load->model('mdl_news'); //Загрузка модели
        if ($CI->mdl_news->edit($id) !== false) {
            //Делаем редирект на список ссылок
            redirect('admin/news');
        } else {
            //Выводим форму добавления
            $header_data['page_title'] = 'Редактирование новости';
            $this->load->view('admin/header.php', $header_data);
            //Теперь готовим вывод серединки
            $data = array();
            $data['validation_errors'] = validation_errors();
            $data['type'] = 'edit';
            $CI->load->model('mdl_news');
            $data['one'] = $CI->mdl_news->get($id);
            $this->load->view('admin/one_news', $data);
            //Здесь вывод футера
            $this->load->view('admin/footer.php');
        }
    }    
 
    /**
     * Удаление новости
     */
    function del($id)
    {
        $CI = &get_instance();
        $CI->load->model('mdl_news'); //Загрузка модели
        $CI->mdl_news->del($id);
        redirect('admin/news');
    }
}
?>

$this->load->helper(‘fckeditor’); — необходимо для загрузки FCKEditor.
Разберем простую последовательность обработки на примере кода:

//Доступ к CodeIgniter
$CI = &get_instance(); 
//Загрузка модели
$CI->load->model('mdl_news'); 
//Обращение к функции getlist  модели mdl_news
//(сама функция находится в модели CRUD
//т.к. она является родительской mdl_news extends CRUD)
//которая возвращает список новостей
$data['list'] = $CI->mdl_news->getlist();
//Вызов файла вида с передачей ему массива с новостями
$CI->load->view('admin/news.php', $data);
//Дальнейшая обработка происходит в файле вида из которого
//происходит вывод на экран.
Теги:
Контроллер
Добавлено: 13 Апреля 2018 07:27:55 Добавил: Андрей Ковальчук Нравится 0
Добавить
Комментарии:
Нету комментариев для вывода...