Codeigniter. Модель для рейтинга, часть 2

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

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

При стандартной работе с моделью


$this->load->model(‘rating’);

Создается один объект и последующие вызовы возвращают указатель на этот объект.
В новой версии можно делать так:


$rating = new Rating();
$rating2 = new Rating();

И так изменённая модель Rating


Class Rating { /** * Ид оценки * @var int */ public $rating_id = NULL; /** * Общая оценка * @var float */ public $rate = NULL; /** * Кол-во проголосовавших * @var int */ public $voted = NULL; /** * Активна оценка или нет * @var bool */ public $active = NULL; /** * Имя нашей таблицы в бд * @var string */ private $_table_name; /** * Максимально возможная оценка * @var int */ private $_max_rate = 5; private $_CI; public function __construct() { $this->_CI = & get_instance(); $this->_CI->config->load(‘rating’); if (($this->_table_name = $this->_CI->config->item(‘table_name’, ‘rating_config’)) === FALSE) { //Если не получил имя таблицы, то выводим окно ошибки show_error(‘Не удалось получить имя таблицы в базе данных для системы оценок’); } $this->_max_rate = $this->_CI->config->item(‘max_rate’, ‘rating_config’); } /** * Создаем оценку * param float $rate - Оценка, по умолчанию 0 * param int $voted – Кол-во проголосовавших * param bool $active - Активировать оценку * return bool – результат создания объекта */ public function create($rate = 0, $voted = 0, $active = true) { $sql = “INSERT INTO “ . $this->_table_name . “ (rate,voted,active) VALUES;”; $this->_CI->db->query($sql, array($rate, $voted, $active)); if ($this->_CI->db->affected_rows() > 0) { $this->rating_id = $this->_CI->db->insert_id(); $this->rate = $rate; $this->voted = $voted; $this->active = $active; return TRUE; } else { $this->_clear_rate(); return FALSE; } } /** * Удаляем оценку * param type $id - ид оценки, если не указан ид, то пытается удалить текущий объект * return boolean – результат удаления */ public function delete($id = false) { if ($id !== false) { $this->_CI->db->delete($this->_table_name, array(‘rating_id’ => $id)); } else { if (is_numeric($this->rating_id)) { $this->_CI->db->delete($this->_table_name, array(‘rating_id’ => $this->rating_id)); } else { return FALSE; } } if ($this->_CI->db->affected_rows() > 0) { if (($id = false) || ($id $this->rating_id)) { $this->_clear_rate(); } return TRUE; } else { return FALSE; } } /** * Клас ищет оценку по ид * param type $id - ид оценки * param type $active – искать только активные * @return boolean – true если нашел, ну или false */ public function find_by_id($id, $active = true) { $sql = “SELECT rating_id,rate,voted,active FROM “ . $this->_table_name . “ WHERE rating_id=?”; $result = null; if ($active) { $sql .= “ AND active=?”; $result = $this->_CI->db->query($sql, array($id, $active)); } else { $result = $this->_CI->db->query($sql, array($id)); } if ($result->num_rows() > 0) { $tmp = $result->row(); $this->rating_id = $tmp->rating_id; $this->rate = $tmp->rate; $this->voted = $tmp->voted; $this->active = $tmp->active; return TRUE; } else { $this->_clear_rate(); return FALSE; } } /** * Редактируем данные * @return boolean результат обновления */ public function edit() { if (is_numeric($this->rating_id)) { $sql = “UPDATE “ . $this->_table_name . “ SET rate=?,voted=?,active=? WHERE rating_id=?”; $this->_CI->db->query($sql, array($this->rate, $this->voted, $this->active, $this->rating_id)); if ($this->_CI->db->affected_rows() > 0) { return TRUE; } else { return FALSE; } } else { return FALSE; } } /** * Добаляем оценку * param type $rate - оценка проголосовавшего * param type $id – ид оценки, если не указывать, то попытается использховать текущий объект * param type $ret - возращать обновленный объект или нет * return boolean если $ret=true, то вернет объект с новыми данными, если $ret=false, то просто вернет true */ public function add_rate($rate, $id = FALSE, $ret = TRUE) { $sql = “UPDATE “ . $this->_table_name . “ SET voted = voted+1, rate = ROUND)+?)/voted,1) WHERE rating_id=?”; if ($rate > $this->_max_rate) $rate = $this->_max_rate; if ($id !== FALSE) { $this->_CI->db->query($sql, array($rate, $id)); } else { if (is_numeric($this->rating_id)) { $this->_CI->db->query($sql, array($rate, $this->rating_id)); $id = $this->rating_id; } else { return FALSE; } } if ($this->_CI->db->affected_rows() > 0) { if ($ret) { return $this->find_by_id($id); } return TRUE; } else { return FALSE; } } /** * Возвращает максимальную оценку * @return int */ public function get_max_rate() { return $this->_max_rate; } /** * Удаляем значения */ private function _clear_rate() { $this->rating_id = NULL; $this->rate = NULL; $this->voted = NULL; $this->active = NULL; } } ?>

Теперь в папке application/controllers создадим два контроллера
ajax.php – для обработка ajax запросов
rate.php – для тестирования работы

код ajax.php


BASEPATH’)) exit(‘No direct script access allowed’); class Ajax extends CI_Controller { public function __construct() { parent::__construct(); } /** * Возращает результат добаления оценки * param type $id - id оценки * param type $rate – rate оценка */ public function rate($id = false, $rate = false) { if ($id !== false) { require_once APPPATH . ‘models/Rating.php’; $this->load->helper(‘rating’); $rating = new Rating(); $id = preg_replace(’/[^0-9]/’, ‘’, $id); if ($rate !== false) { $rate = preg_replace(’/[^0-9]/’, ‘’, $rate); $rating->add_rate($rate, $id); set_rating_cookie(1); $data[‘rating’] = $rating; $this->load->view(‘rate/result’, $data); } } } } ?>

код rate.php


BASEPATH’)) exit(‘No direct script access allowed’); class Rate extends CI_Controller { private $rating; public function __construct() { parent::__construct(); require_once APPPATH . ‘models/Rating.php’; } /** * * @param type $id – ид оценки */ public function view($id = false) { if($id!== false) { $id = preg_replace(’/[^0-9]/’, ‘’, $id);//оставляем только цифры $this->rating = new Rating(); if ($this->rating->find_by_id($id)) { $this->load->view(‘head’); $data[‘rating’] = $this->rating; $this->load->helper(‘rating’); $this->load->view(‘rate/result’, $data); if(!exist_rating_cookie($this->rating->rating_id)) { $this->load->view(‘rate/voted’, $data); } $this->load->view(‘foot’); } } else { $this->load->view(‘head’); echo ‘

No id rate

’; $this->load->view(‘foot’); } }
}
?>

Теперь создадим хелпер для работы с куками в папке application/helpers создаем rating_helper.php


BASEPATH’)) exit(‘No direct script access allowed’); /** * Проверяет и устанавливает куки * param type $rating_id - ид оценки * return boolean – результат добавления */
function set_rating_cookie($rating_id) { $CI = & get_instance(); $rating = $CI->input->cookie(‘rating’, TRUE); if ($rating !== false) { $rating = unserialize($rating); if (is_array($rating)) { if (array_search($rating_id, $rating) === false) { $rating[] = $rating_id; } else { return FALSE; } } else { $rating = array($rating_id); } } else { $rating = array($rating_id); } $cookie = array( ‘name’ => ‘rating’, ‘value’ => serialize($rating), ‘expire’ => ‘86500’, //24 часа ‘secure’ => false ); $CI->input->set_cookie($cookie); return TRUE; } /** * Функция проверяет существует ли заданая кука для оценки * param type $rating_id - ид оценки * return boolean – результат существования */
function exist_rating_cookie($rating_id) { $CI = & get_instance(); $rating = $CI->input->cookie(‘rating’, TRUE); if ($rating !== false) { $rating = unserialize($rating); if (is_array($rating)) { if (array_search($rating_id, $rating) !== false) { return TRUE; } else { return FALSE; } } else { return FALSE; } } else { return FALSE; }
} ?>

В контроллере rate у нас идет вызов 4 представлений
1. head – шапка сайта
2. rate/result – форма вывода результатов голосования
3. rate/voted – форма для голосования
4. foot – подвал сайт

Теперь создадим их в папке application/view создаем файл head.php












Там же foot.php




Теперь создадим папку rate и в ней 2 файла result.php и voted.php

result.php





Оценка: rate; ?>



Всего проголосовало: voted; ?>


voted.php





Оцените:
$max = $rating->get_max_rate();
for ($i = 1; $i <= $max; $i++) {
echo ‘rating_id . ‘,’ . $i . ‘);>’ . $i . ‘ ‘;
}
?>


Теперь если мы создадим тестовый рейтинг выполнив запрос к базе:
INSERT INTO rating (rate,voted,active) VALUES(0,0,TRUE);

И обратимся к нашему сайту http://ip-addres/путь-к-codeigniter/rate/view/1

Страница

Увидим следующую страницу, теперь проголосовав, нажав на одну из оценок, наша система обновит страницу по средствам ajax запроса

Результат

После чего в куках появится id оценки и на 24 часа вы не сможете больше голосовать.

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

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